import { Tool } from "../../forge"; import { type ToolGateFn } from "../tools/_shared/index"; import { type SandboxNarrator } from "./narrator"; import type { SandboxPolicy } from "./types"; import type { PathTranslator } from "./contracts/path_translator"; import type { SandboxPolicyEnforcer } from "./contracts/policy_enforcer"; /** Configuration for the streaming shell-command tool. */ export interface RunShellCommandOptions { /** Streaming policy enforcer; unlike BinaryExecutor this exposes live stdout/stderr. */ readonly sandbox: SandboxPolicyEnforcer; /** Policy applied to the spawned command. */ readonly policy: SandboxPolicy; /** Model-path translator for the working directory. */ readonly translator: PathTranslator; /** Required human/policy approval gate. */ readonly gate?: ToolGateFn; /** Optional command-name allow-list. */ readonly allowedCommands?: readonly string[]; /** * Environment variables to add to every command this tool spawns. * * @remarks * ADDITIVE, and applied LAST — over both the host variables the enforcer allow-listed and SRT's own * proxy/CA plumbing. It is not the host-inheritance control: the enforcer decides what the child * inherits (`envAllowList` / `inheritHostEnv` on the Node adapter), and this cannot re-admit a * variable the enforcer withheld except by supplying the value literally here. * * Anything put here is readable by the model — `run_shell_command` runs commands the model chose, * and `env` is one of them — so pass configuration, not credentials. */ readonly env?: Readonly>; /** Optional tool description override. */ readonly description?: string; /** Injectable model-facing outcome renderer. */ readonly narrate?: SandboxNarrator; } /** * Assemble the factory-style `run_shell_command` tool. It is intentionally not a bulk-registered * battery value. `cwd` is a model-supplied workspace-relative path and receives the complete * PathTranslator gauntlet, including symlink refusal; the default is the workspace root. * * The command spawns first, then stdout and stderr are drained concurrently and merged in arrival * order into one stream and one `storeRetrievableBytes` call. Diagnostics are polled while drains * run and written as `[sandbox] denied: …` at their observation point ("observed after", not * "caused by"). The command is never accumulated here. `timeout_seconds` defaults to 300 and is * a tool argument. Non-zero exits, violations, timeouts, and post-spawn I/O failures return the * singular artifact; failures meaning the command never ran throw instead. */ export declare const createRunShellCommandTool: (options: RunShellCommandOptions) => Tool;