import { VerifyReport } from '../verify/report.js'; /** The verify report as serialized by the CLI (the report plus the top-level `ok` verdict). */ export type SerializedReport = VerifyReport & { ok: boolean; }; /** Outcome of a sandboxed run. `completed` includes not-ok reports (the part built but failed checks). */ export type RunProgramResult = { outcome: 'completed'; report: SerializedReport; } | { outcome: 'timeout'; timeoutMs: number; } | { outcome: 'crashed'; exitCode: number | null; detail: string; }; /** Outcome of a sandboxed export. `completed` carries the written artifact paths and any errors. */ export type ExportProgramResult = { outcome: 'completed'; ok: boolean; written: string[]; errors: string[]; } | { outcome: 'timeout'; timeoutMs: number; } | { outcome: 'crashed'; exitCode: number | null; detail: string; }; export interface SandboxOptions { /** Wall-clock budget; the child is SIGKILLed past it. Default 30000. */ timeoutMs?: number; /** Child heap cap (`--max-old-space-size`), in MB. Default 2048. */ maxMemoryMb?: number; /** * CLI entry to spawn. Defaults to the in-repo TypeScript CLI (run via `tsx`), correct for * dev/test. Production callers pass the built `dist/cli/main.js` (run via `node`). The runner is * inferred from the extension: `.ts` → `npx tsx`, otherwise the current `node`. */ cliEntry?: string; /** Pass `--metrics` so the report carries body/interference metrics for the design judge. */ metrics?: boolean; } export type RunProgramOptions = SandboxOptions; export interface ExportFormats { step?: boolean; glb?: boolean; stl?: boolean; } /** * Clamp a caller-supplied limit to a positive, finite value, falling back to the default otherwise. * Critical for the timeout: Node's `execFile` treats `timeout: 0` (and it ignores negatives) as * "no timeout", which would silently disable the sandbox's only runaway protection. */ export declare function positiveOrDefault(value: number | undefined, fallback: number): number; /** SIGKILL every in-flight sandbox process group now. Exported so a host can reap explicitly. */ export declare function killActiveSandboxes(signal?: NodeJS.Signals): void; /** * Install process-shutdown hooks that reap any in-flight sandbox process groups when THIS process * (the host — e.g. the MCP server) terminates. Idempotent; call once at startup from an entrypoint. * * Rationale: the per-run timeout (`spawnCliOutcome`) only protects a run while the host is alive — * its timer dies with the host. If the host is stopped (the agent disconnects) before a run's * budget elapses, the `detached` sandbox group is in its own session and survives, burning a core * indefinitely. These hooks SIGKILL every tracked group on the way down so a dying host doesn't * leak its children. (A hard SIGKILL of the host can't be trapped — that residual needs the kernel's * PR_SET_PDEATHSIG, which Node doesn't expose.) */ export declare function installSandboxShutdownHandlers(): void; /** Execute `code` (an agent-authored `.brep.ts` module) in an isolated, resource-bounded child. */ export declare function runProgram(code: string, opts?: RunProgramOptions): Promise; /** Outcome of a sandboxed `--check --step` run. `completed` carries the report; `stepPath` is set * only when a valid solid produced a STEP. */ export type RunProgramWithStepResult = { outcome: 'completed'; report: SerializedReport; stepPath?: string; } | { outcome: 'timeout'; timeoutMs: number; } | { outcome: 'crashed'; exitCode: number | null; detail: string; }; /** * Execute `code` with `verify --check --step` in ONE bounded child process: a single spawn yields * both the `auto`-signal report (parsed from stdout) and the STEP the judge renders — one kernel * boot, not the two a `runProgram` + `exportProgram` pair would cost. The caller owns `stepOutPath`; * only the temp program dir is cleaned up. */ export declare function runProgramWithStep(code: string, stepOutPath: string, opts?: RunProgramOptions): Promise; /** * Execute `code` and export artifacts to `outDir`. Artifacts persist in `outDir` (the caller owns * it); only the temp program directory is cleaned up. Returns the written paths and any errors. */ export declare function exportProgram(code: string, outDir: string, formats?: ExportFormats, opts?: SandboxOptions): Promise;