import type { Sandbox, SandboxCreateConfig, SandboxEnvironment, SandboxIsolationControl, SandboxProvider } from '../../types/sandbox/index.js'; import type { Logger } from '../../utils/logger.js'; import type { PtyLoader } from '../terminal.js'; interface SpawnProbeObservation { readonly error?: unknown; readonly status: number | null; readonly signal: NodeJS.Signals | null; readonly stdout: string | null; } /** * A wrapper is usable only when the same direct-spawn shape as a real command * can execute and carry its output back through a pipe. * * Checking only the exit status is insufficient: a host policy can let a * shell launch a namespace helper while refusing or partially virtualising a * direct `spawn()` of that helper. In that state the old shell-string probe * selected the tier, but production commands returned exit zero with empty * output. Treat a spawn error, signal, or damaged pipe as an unavailable tier. */ export declare function acceptsSandboxSpawnProbe(observation: SpawnProbeObservation): boolean; /** * One output stream, accumulated under a byte cap that it reports hitting. * * The clipping was inline and the flag was not set, so a turn whose output * ran past the cap returned a result that looked whole. The tool layer * already renders `stdoutTruncated` when a backend sets it — this one * simply never did, which is the silent truncation the contract's own doc * says the kernel does not do. */ export declare class CappedStream { private readonly capBytes; private chunks; private bytes; constructor(capBytes: number); push(chunk: Buffer): void; get text(): string; /** True once more arrived than was kept. */ get truncated(): boolean; } export interface LimitedSpawnRequest { readonly environment: SandboxEnvironment; /** Canonical outer wrapper selected and probed by the provider. */ readonly wrapperCommand?: string; readonly command: string; readonly args: readonly string[]; readonly rootDir: string; /** Bound read-write beside the root; see `SandboxCreateConfig.additionalDirectories`. */ readonly additionalDirectories?: readonly string[]; readonly memoryLimitMb?: number; readonly maxProcesses?: number; } /** * How one command is spawned under a tier, with the resource caps applied. * * The caps used to live inside the unconfined tier's branch only, so a host * that asked for stronger isolation had its memory and process limits * silently dropped — a control failing in the one direction nobody checks. * They are the same shell builtin on every tier; the only difference is * that the stronger tiers apply them one level in, inside the wrapper they * already spawn through. */ export declare function buildLimitedSpawn(request: LimitedSpawnRequest): { spawnCommand: string; spawnArgs: string[]; }; /** * Build a macOS seatbelt (SBPL) profile for sandbox isolation. * * Key principle: (deny default) + explicit allows. Network always denied. */ /** * A mount table containing the sandbox and the system paths a binary needs, * and nothing else. * * The difference from the namespace tier is the whole point: that one unshares * a mount table and keeps the host's contents in it, so the child sees * everything and this file reports `filesystem: false` for it. Here each path * is bound in deliberately, so a path nobody listed is not unreadable — it is * absent. `ls /home` fails with ENOENT rather than EACCES, which is the * behaviour a caller relying on `filesystem` isolation is entitled to. * * `--unshare-all` covers the network and process controls in the same call, so * all three rows of this tier's isolation report come from one spawn rather * than from three mechanisms that could drift apart. * * The system paths are bound READ-ONLY and only when present: a distribution * with a merged `/usr` has no real `/lib`, and binding a path that does not * exist is a hard failure rather than a no-op. `/proc` and `/dev` get their * own fresh instances instead of a bind, so the child cannot read the host's * process table through them — a bound `/proc` would hand back the process * isolation the same flag just removed. */ export declare function buildBwrapArgs(sandboxRoot: string, additionalDirectories?: readonly string[]): string[]; export interface LocalSandboxProviderOptions { /** * Controls this turn relies on. Construction throws when the detected * environment cannot enforce one of them, rather than downgrading to * whatever the host happens to offer. */ readonly requireIsolation?: readonly SandboxIsolationControl[]; /** * Legacy test injection for the local backend's former terminal method. * * @deprecated The local backend cannot preserve its selected isolation * tier or own the complete terminal process tree, so it no longer exposes * `Sandbox.openTerminal`. Supplying this option now throws. Use the * host-scoped terminal helpers directly only when unconfined execution is * intentional, or provide a backend that owns confinement and teardown. */ readonly ptyLoader?: PtyLoader; } export declare class LocalSandboxProvider implements SandboxProvider { readonly id = "local"; readonly name = "Local Sandbox"; readonly workspaceModes: readonly ["ephemeral", "working-directory"]; readonly environment: SandboxEnvironment; private readonly log; private readonly wrapperCommand; constructor(log: Logger, options?: LocalSandboxProviderOptions); create(config?: SandboxCreateConfig): Promise; } export {}; //# sourceMappingURL=local.d.ts.map