/** * The sandbox contract: where an agent's commands and code run. A sandbox is a `Workspace` that can * also run commands, and says how it is isolated, so its files are the files its commands see. * * The package ships the contract and a conformance suite, not the isolation: a container, a VM, a * remote interpreter, or a hosted sandbox fills the `Sandbox` interface. `processSandbox()` is a * reference for development, which runs commands as ordinary processes; it says so in its * `isolation`, and is never a security boundary. */ import type { ToolDefinition } from '../types/messages.js'; import { type Workspace, type WorkspaceGlobOptions, type WorkspaceGrepOptions, type WorkspaceMatch, WorkspacePathError } from './workspace.js'; /** Options for one command. */ export interface SandboxExecOptions { /** The working directory, inside the sandbox. Defaults to its root. */ cwd?: string; /** Environment variables for the command. The host's own are never passed through. */ env?: Record; /** Sent to the command's standard input. */ stdin?: string; /** Stops the command after this many milliseconds. */ timeoutMs?: number; /** Stops the command when aborted. */ signal?: AbortSignal; } /** What a command did. */ export interface SandboxExecResult { /** Its exit code, or `null` when it was stopped. */ exitCode: number | null; /** What it wrote to standard output. */ stdout: string; /** What it wrote to standard error. */ stderr: string; /** True when it was stopped by its timeout. */ timedOut: boolean; /** How long it ran, in milliseconds. */ durationMs: number; } /** Options for `Sandbox.glob()`: a workspace's. */ export type SandboxGlobOptions = WorkspaceGlobOptions; /** Options for `Sandbox.grep()`: a workspace's. */ export type SandboxGrepOptions = WorkspaceGrepOptions; /** One line `Sandbox.grep()` matched: a workspace's match. */ export type SandboxMatch = WorkspaceMatch; /** What a sandbox claims to isolate. The conformance suite checks the claims it can observe. */ export interface SandboxIsolation { /** Commands cannot read or write the host's files. */ filesystem: boolean; /** Commands cannot reach the network, or only what the sandbox allows. */ network: boolean; /** Commands cannot see or signal the host's processes. */ processes: boolean; } /** * Where an agent's commands and code run: a workspace that can also run commands, and says what it * isolates. The application provides one. */ export interface Sandbox extends Workspace { /** What it isolates. */ readonly isolation: SandboxIsolation; /** Runs a command line in the sandbox, where its files are. */ exec(command: string, options?: SandboxExecOptions): Promise; /** Releases the sandbox. */ dispose?(): Promise; } /** Raised when a path would leave the sandbox: a `WorkspacePathError` whose code is `SANDBOX_PATH`. */ export declare class SandboxPathError extends WorkspacePathError { /** Always `SANDBOX_PATH`. */ readonly code = "SANDBOX_PATH"; constructor( /** The path that was refused. */ path: string); } /** Options for `processSandbox()`. */ export interface ProcessSandboxOptions { /** The directory commands run in and files live under. Created when missing. */ root: string; /** Environment variables every command gets, on top of a minimal `PATH`. */ env?: Record; /** Timeout for a command that sets none. Defaults to 30 seconds. */ timeoutMs?: number; /** Output kept per stream, in bytes. Defaults to 1 MB. */ maxOutputBytes?: number; } /** * A sandbox that runs commands as ordinary processes in a directory, for development and tests only. * * Its file methods refuse any path outside `root`, and commands get only `PATH` and the variables * given, never the host's environment. But a command it runs can read and write anything the user * can, and reach any host: `isolation` says so. Use a container or a VM in production. * * Its search skips `.git` and `node_modules`, walks at most 20,000 entries, and follows no links; * `grep()` skips files over 1 MB and binary files, reads at most 64 MB, and searches the first * 4,000 characters of each line. */ export declare function processSandbox(options: ProcessSandboxOptions): Sandbox; /** Options for `sandboxTools()`. */ export interface SandboxToolsOptions { /** Offer `run_command`. Defaults to true. */ shell?: boolean; /** * Offer the file tools: `read_file`, `write_file`, and, where the sandbox can, `list_files`, * `glob_files`, `grep_files`, and `read_media`. Defaults to true. */ files?: boolean; /** The largest file `read_media` sends to the model, in bytes. Defaults to 10 MB. */ maxMediaBytes?: number; /** * The path a permission policy sees the sandbox's files under. Defaults to `/workspace`, so a * policy granting `/workspace/**` grants the sandbox. */ mount?: string; /** Timeout for each command. */ timeoutMs?: number; } /** * Tools that act through a sandbox, each declaring exactly what one call does: `run_command` * declares `shell:`, and the file tools declare `filesystem:read` or * `filesystem:write` with the path under `mount`. A permission policy can therefore grant a * workspace, a few commands, and nothing else. */ export declare function sandboxTools(sandbox: Sandbox, options?: SandboxToolsOptions): ToolDefinition[]; /** One conformance check's result. */ export interface SandboxConformanceCheck { /** What was checked. */ name: string; /** Whether it held. */ ok: boolean; /** What went wrong, when it did not. */ detail?: string; } /** What `runSandboxConformance()` found. */ export interface SandboxConformanceReport { /** The sandbox's name. */ sandbox: string; /** True when every check held. */ passed: boolean; /** Every check, in order. */ checks: SandboxConformanceCheck[]; } /** Options for `runSandboxConformance()`. */ export interface SandboxConformanceOptions { /** The command that runs JavaScript inside the sandbox. Defaults to `node`. */ node?: string; /** The timeout the timeout check sets, in milliseconds. Defaults to 300. */ timeoutMs?: number; } /** * Checks a sandbox against the contract, without a test framework, so any sandbox — a container * runner, a VM, a hosted service — can prove itself the same way: * * - commands report their output, errors, and exit code, take standard input and the variables * given, and never see the host's environment; * - a command past its timeout is stopped and reported as timed out; * - commands run where the files are, and files round-trip; * - a path outside the sandbox is refused. * * Every check runs on a fresh sandbox from `create`, which is disposed afterwards. */ export declare function runSandboxConformance(create: () => Sandbox | Promise, options?: SandboxConformanceOptions): Promise;