@anvia/sandbox 1.1.1 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -0
- package/dist/{chunk-4D2GWLEH.js → chunk-D5XZQ2ES.js} +1 -1
- package/dist/chunk-D5XZQ2ES.js.map +1 -0
- package/dist/cli.js +1 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.js +53 -2
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/dist/chunk-4D2GWLEH.js.map +0 -1
package/README.md
CHANGED
|
@@ -37,6 +37,15 @@ explicit `dropCapabilities` and `addCapabilities` arrays, plus
|
|
|
37
37
|
`seccompProfile: { type: "path", path }` with an absolute host path. These options are used by
|
|
38
38
|
`@anvia/browser` to keep Chromium's own process sandbox enabled.
|
|
39
39
|
|
|
40
|
+
`createSandbox()` accepts `containerRuntime` — the runtime name registered in the Docker daemon (for
|
|
41
|
+
example `runsc` for gVisor). The runtime must already be registered (`runsc install` followed by a
|
|
42
|
+
daemon restart); creation fails with a `runtime_not_found` error otherwise. `resumeSandbox()` keeps
|
|
43
|
+
the container's original runtime. Under gVisor, workspace files persist through
|
|
44
|
+
`stop()`/`resumeSandbox()` because they live on a Docker volume, but changes to the container's
|
|
45
|
+
writable rootfs outside the workspace do not survive a resume, and `security.seccompProfile` is not
|
|
46
|
+
enforced the way it is on the default runtime because the gVisor sentry mediates application
|
|
47
|
+
syscalls itself.
|
|
48
|
+
|
|
40
49
|
Studio does not discover sandboxes through tool metadata. Register a read-only inspector explicitly:
|
|
41
50
|
|
|
42
51
|
```ts
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/docker-cli.ts"],"sourcesContent":["export type DockerSandboxErrorCode =\n | \"docker_unavailable\"\n | \"docker_command_failed\"\n | \"image_not_found\"\n | \"runtime_not_found\"\n | \"volume_not_found\"\n | \"sandbox_not_found\"\n | \"invalid_state\"\n | \"invalid_path\"\n | \"timeout\"\n | \"file_too_large\"\n | \"tool_policy\"\n | \"port\"\n | \"process\";\n\nexport class DockerSandboxError extends Error {\n constructor(\n message: string,\n readonly code: DockerSandboxErrorCode,\n readonly details?: unknown,\n options?: ErrorOptions,\n ) {\n super(message, options);\n this.name = \"DockerSandboxError\";\n }\n}\n\nexport function dockerSandboxError(\n message: string,\n code: DockerSandboxErrorCode,\n cause?: unknown,\n details?: unknown,\n): DockerSandboxError {\n return new DockerSandboxError(\n message,\n code,\n details,\n cause === undefined ? undefined : { cause },\n );\n}\n","import { spawn } from \"node:child_process\";\nimport { DockerSandboxError } from \"./errors\";\n\nexport interface DockerCliResult {\n stdout: Uint8Array;\n stderr: Uint8Array;\n exitCode: number;\n durationMs: number;\n timedOut: boolean;\n stdoutTruncated: boolean;\n stderrTruncated: boolean;\n}\n\nexport interface DockerCliOptions {\n dockerPath: string;\n timeoutMs?: number | undefined;\n maxOutputBytes?: number | undefined;\n input?: string | Uint8Array | undefined;\n signal?: AbortSignal | undefined;\n onStdout?: (chunk: Uint8Array) => void;\n onStderr?: (chunk: Uint8Array) => void;\n}\n\nconst defaultMaxOutputBytes = 1024 * 1024;\n\nexport async function runDockerCli(\n args: string[],\n options: DockerCliOptions,\n): Promise<DockerCliResult> {\n const startedAt = Date.now();\n const maxOutputBytes = options.maxOutputBytes ?? defaultMaxOutputBytes;\n const stdout = createOutputCollector(maxOutputBytes, options.onStdout);\n const stderr = createOutputCollector(maxOutputBytes, options.onStderr);\n\n return new Promise((resolve, reject) => {\n const child = spawn(options.dockerPath, args, {\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n\n let timedOut = false;\n let settled = false;\n\n const timeout =\n options.timeoutMs === undefined\n ? undefined\n : setTimeout(() => {\n timedOut = true;\n child.kill(\"SIGKILL\");\n }, options.timeoutMs);\n\n const abort = () => {\n child.kill(\"SIGKILL\");\n };\n\n if (options.signal?.aborted === true) {\n abort();\n } else {\n options.signal?.addEventListener(\"abort\", abort, { once: true });\n }\n\n child.stdout.on(\"data\", (chunk: Buffer) => stdout.accept(chunk));\n child.stderr.on(\"data\", (chunk: Buffer) => stderr.accept(chunk));\n\n child.on(\"error\", (error) => {\n if (settled) {\n return;\n }\n settled = true;\n clearTimeout(timeout);\n options.signal?.removeEventListener(\"abort\", abort);\n\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n reject(\n new DockerSandboxError(\"Docker CLI was not found.\", \"docker_unavailable\", undefined, {\n cause: error,\n }),\n );\n return;\n }\n\n reject(error);\n });\n\n child.on(\"close\", (code) => {\n if (settled) {\n return;\n }\n settled = true;\n clearTimeout(timeout);\n options.signal?.removeEventListener(\"abort\", abort);\n\n if (options.signal?.aborted === true) {\n reject(options.signal.reason ?? new DOMException(\"Aborted\", \"AbortError\"));\n return;\n }\n\n resolve({\n stdout: stdout.bytes(),\n stderr: stderr.bytes(),\n exitCode: code ?? 1,\n durationMs: Date.now() - startedAt,\n timedOut,\n stdoutTruncated: stdout.truncated,\n stderrTruncated: stderr.truncated,\n });\n });\n\n if (options.input !== undefined) {\n child.stdin.end(options.input);\n } else {\n child.stdin.end();\n }\n });\n}\n\nexport async function assertDockerCli(args: string[], options: DockerCliOptions): Promise<void> {\n const result = await runDockerCli(args, options);\n\n if (result.exitCode !== 0) {\n throw new DockerSandboxError(\n `Docker command failed: docker ${args.join(\" \")}`,\n \"docker_command_failed\",\n result,\n );\n }\n}\n\nfunction createOutputCollector(maxBytes: number, onChunk?: (chunk: Uint8Array) => void) {\n const chunks: Buffer[] = [];\n let length = 0;\n let truncated = false;\n\n return {\n get truncated() {\n return truncated;\n },\n accept(chunk: Buffer) {\n onChunk?.(chunk);\n\n if (length >= maxBytes) {\n truncated = true;\n return;\n }\n\n const remaining = maxBytes - length;\n const next = chunk.length > remaining ? chunk.subarray(0, remaining) : chunk;\n chunks.push(next);\n length += next.length;\n\n if (next.length < chunk.length) {\n truncated = true;\n }\n },\n bytes() {\n const bytes = Buffer.concat(chunks, length);\n return new Uint8Array(bytes.buffer, bytes.byteOffset, bytes.byteLength).slice();\n },\n };\n}\n\nexport function decodeUtf8(bytes: Uint8Array): string {\n return new TextDecoder(\"utf-8\", { fatal: true }).decode(bytes);\n}\n"],"mappings":"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","names":[]}
|
package/dist/cli.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -42,6 +42,11 @@ type CreateDockerSandboxOptions = Readonly<{
|
|
|
42
42
|
workdir?: string;
|
|
43
43
|
workspace: DockerSandboxWorkspace;
|
|
44
44
|
network: DockerSandboxNetwork;
|
|
45
|
+
/** Docker runtime used to run the container, as registered in the daemon
|
|
46
|
+
* (for example "runsc" for gVisor). The runtime must already be registered;
|
|
47
|
+
* createSandbox() fails with `runtime_not_found` otherwise. Omitted means
|
|
48
|
+
* the daemon default. resumeSandbox() keeps the container's runtime. */
|
|
49
|
+
containerRuntime?: string;
|
|
45
50
|
files?: Readonly<Record<string, string | Uint8Array>>;
|
|
46
51
|
directories?: readonly string[];
|
|
47
52
|
env?: Readonly<Record<string, string>>;
|
|
@@ -208,6 +213,7 @@ type DockerSandboxInspector = Readonly<{
|
|
|
208
213
|
id: string;
|
|
209
214
|
provider: "docker";
|
|
210
215
|
workdir: string;
|
|
216
|
+
containerRuntime: string;
|
|
211
217
|
listFiles?: DockerSandboxRuntime["listFiles"];
|
|
212
218
|
readFile?: DockerSandboxRuntime["readFile"];
|
|
213
219
|
publishedPorts?: readonly DockerSandboxPublishedPort[];
|
|
@@ -270,10 +276,11 @@ declare class DockerSandboxClient {
|
|
|
270
276
|
private assertImageExists;
|
|
271
277
|
private assertContainerDoesNotExist;
|
|
272
278
|
private assertVolumeExists;
|
|
279
|
+
private assertRuntimeAvailable;
|
|
273
280
|
private cliOptions;
|
|
274
281
|
}
|
|
275
282
|
|
|
276
|
-
type DockerSandboxErrorCode = "docker_unavailable" | "docker_command_failed" | "image_not_found" | "volume_not_found" | "sandbox_not_found" | "invalid_state" | "invalid_path" | "timeout" | "file_too_large" | "tool_policy" | "port" | "process";
|
|
283
|
+
type DockerSandboxErrorCode = "docker_unavailable" | "docker_command_failed" | "image_not_found" | "runtime_not_found" | "volume_not_found" | "sandbox_not_found" | "invalid_state" | "invalid_path" | "timeout" | "file_too_large" | "tool_policy" | "port" | "process";
|
|
277
284
|
declare class DockerSandboxError extends Error {
|
|
278
285
|
readonly code: DockerSandboxErrorCode;
|
|
279
286
|
readonly details?: unknown | undefined;
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
assertDockerCli,
|
|
4
4
|
decodeUtf8,
|
|
5
5
|
runDockerCli
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-D5XZQ2ES.js";
|
|
7
7
|
|
|
8
8
|
// src/docker-sandbox.ts
|
|
9
9
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
@@ -610,6 +610,7 @@ var labels = {
|
|
|
610
610
|
workspaceType: `${labelPrefix}workspace.type`,
|
|
611
611
|
workspaceVolume: `${labelPrefix}workspace.volume`,
|
|
612
612
|
networkMode: `${labelPrefix}network.mode`,
|
|
613
|
+
containerRuntime: `${labelPrefix}container-runtime`,
|
|
613
614
|
commandTimeoutMs: `${labelPrefix}runtime.command-timeout-ms`,
|
|
614
615
|
maxOutputBytes: `${labelPrefix}runtime.max-output-bytes`,
|
|
615
616
|
maxFileBytes: `${labelPrefix}runtime.max-file-bytes`,
|
|
@@ -650,6 +651,7 @@ var DockerSandboxClient = class {
|
|
|
650
651
|
assertSandboxId(id);
|
|
651
652
|
const containerName = containerNameFor(id);
|
|
652
653
|
const workdir = options.workdir ?? defaultWorkdir;
|
|
654
|
+
const containerRuntime = options.containerRuntime ?? "default";
|
|
653
655
|
const runtime = resolveRuntimeLimits(options.runtime);
|
|
654
656
|
const workspace = copyWorkspace(options.workspace);
|
|
655
657
|
const network = copyNetwork(options.network);
|
|
@@ -662,6 +664,7 @@ var DockerSandboxClient = class {
|
|
|
662
664
|
if (workspace.type === "docker-volume") {
|
|
663
665
|
await this.assertVolumeExists(workspace.name, options.abortSignal);
|
|
664
666
|
}
|
|
667
|
+
await this.assertRuntimeAvailable(containerRuntime, options.abortSignal);
|
|
665
668
|
let containerCreated = false;
|
|
666
669
|
let volumeCreated = false;
|
|
667
670
|
try {
|
|
@@ -678,6 +681,7 @@ var DockerSandboxClient = class {
|
|
|
678
681
|
containerName,
|
|
679
682
|
image: options.image,
|
|
680
683
|
workdir,
|
|
684
|
+
containerRuntime,
|
|
681
685
|
workspace,
|
|
682
686
|
volumeName,
|
|
683
687
|
env,
|
|
@@ -704,6 +708,7 @@ var DockerSandboxClient = class {
|
|
|
704
708
|
id,
|
|
705
709
|
containerName,
|
|
706
710
|
workdir,
|
|
711
|
+
containerRuntime,
|
|
707
712
|
workspace,
|
|
708
713
|
volumeName,
|
|
709
714
|
ownsVolume,
|
|
@@ -818,6 +823,37 @@ var DockerSandboxClient = class {
|
|
|
818
823
|
result
|
|
819
824
|
);
|
|
820
825
|
}
|
|
826
|
+
async assertRuntimeAvailable(name, abortSignal) {
|
|
827
|
+
if (name === "default") return;
|
|
828
|
+
const result = await runDockerCli(["info", "--format", "{{json .Runtimes}}"], {
|
|
829
|
+
...this.cliOptions(abortSignal),
|
|
830
|
+
maxOutputBytes: defaultMaxOutputBytes
|
|
831
|
+
});
|
|
832
|
+
if (result.exitCode !== 0) {
|
|
833
|
+
throw new DockerSandboxError(
|
|
834
|
+
"Unable to inspect Docker runtimes.",
|
|
835
|
+
"docker_command_failed",
|
|
836
|
+
result
|
|
837
|
+
);
|
|
838
|
+
}
|
|
839
|
+
let runtimes;
|
|
840
|
+
try {
|
|
841
|
+
runtimes = JSON.parse(decodeUtf8(result.stdout));
|
|
842
|
+
} catch (error) {
|
|
843
|
+
throw new DockerSandboxError(
|
|
844
|
+
"Docker returned invalid runtime metadata.",
|
|
845
|
+
"docker_command_failed",
|
|
846
|
+
void 0,
|
|
847
|
+
{ cause: error }
|
|
848
|
+
);
|
|
849
|
+
}
|
|
850
|
+
if (!isRecord(runtimes) || !(name in runtimes)) {
|
|
851
|
+
throw new DockerSandboxError(
|
|
852
|
+
`Docker runtime is not registered in the daemon: ${JSON.stringify(name)}. Install the runtime (for gVisor: runsc install) and restart the Docker daemon.`,
|
|
853
|
+
"runtime_not_found"
|
|
854
|
+
);
|
|
855
|
+
}
|
|
856
|
+
}
|
|
821
857
|
cliOptions(abortSignal) {
|
|
822
858
|
return { dockerPath: this.dockerPath, signal: abortSignal };
|
|
823
859
|
}
|
|
@@ -853,7 +889,8 @@ var DockerSandboxHandle = class {
|
|
|
853
889
|
let inspector = {
|
|
854
890
|
id: this.id,
|
|
855
891
|
provider: "docker",
|
|
856
|
-
workdir: this.configuration.workdir
|
|
892
|
+
workdir: this.configuration.workdir,
|
|
893
|
+
containerRuntime: this.configuration.containerRuntime
|
|
857
894
|
};
|
|
858
895
|
if (options.files === true) {
|
|
859
896
|
inspector = {
|
|
@@ -1370,6 +1407,7 @@ function createRunArgs(options) {
|
|
|
1370
1407
|
[labels.workspaceType]: options.workspace.type,
|
|
1371
1408
|
[labels.workspaceVolume]: options.volumeName,
|
|
1372
1409
|
[labels.networkMode]: options.network.mode,
|
|
1410
|
+
[labels.containerRuntime]: options.containerRuntime,
|
|
1373
1411
|
[labels.commandTimeoutMs]: `${options.runtime.commandTimeoutMs}`,
|
|
1374
1412
|
[labels.maxOutputBytes]: `${options.runtime.maxOutputBytes}`,
|
|
1375
1413
|
[labels.maxFileBytes]: `${options.runtime.maxFileBytes}`,
|
|
@@ -1385,6 +1423,9 @@ function createRunArgs(options) {
|
|
|
1385
1423
|
"-w",
|
|
1386
1424
|
options.workdir
|
|
1387
1425
|
];
|
|
1426
|
+
if (options.containerRuntime !== "default") {
|
|
1427
|
+
args.push("--runtime", options.containerRuntime);
|
|
1428
|
+
}
|
|
1388
1429
|
for (const [key, value] of Object.entries({ ...options.userLabels, ...runtimeLabels })) {
|
|
1389
1430
|
args.push("--label", `${key}=${value}`);
|
|
1390
1431
|
}
|
|
@@ -1464,6 +1505,9 @@ function validateCreateOptions(options) {
|
|
|
1464
1505
|
if (key.startsWith(labelPrefix)) throw new TypeError(`Docker label is reserved: ${key}`);
|
|
1465
1506
|
}
|
|
1466
1507
|
if (options.user !== void 0) assertNonEmptyString(options.user, "user");
|
|
1508
|
+
if (options.containerRuntime !== void 0) {
|
|
1509
|
+
assertNonEmptyString(options.containerRuntime, "containerRuntime");
|
|
1510
|
+
}
|
|
1467
1511
|
if (options.directories !== void 0 && !Array.isArray(options.directories)) {
|
|
1468
1512
|
throw new TypeError("directories must be an array.");
|
|
1469
1513
|
}
|
|
@@ -1606,6 +1650,9 @@ function snapshotCreateOptions(options) {
|
|
|
1606
1650
|
};
|
|
1607
1651
|
if (options.id !== void 0) snapshot = { ...snapshot, id: options.id };
|
|
1608
1652
|
if (options.workdir !== void 0) snapshot = { ...snapshot, workdir: options.workdir };
|
|
1653
|
+
if (options.containerRuntime !== void 0) {
|
|
1654
|
+
snapshot = { ...snapshot, containerRuntime: options.containerRuntime };
|
|
1655
|
+
}
|
|
1609
1656
|
if (options.files !== void 0) snapshot = { ...snapshot, files: Object.freeze(files) };
|
|
1610
1657
|
if (options.directories !== void 0) {
|
|
1611
1658
|
snapshot = { ...snapshot, directories: Object.freeze([...options.directories]) };
|
|
@@ -1664,6 +1711,9 @@ function configurationFromInspection(id, containerName, inspection) {
|
|
|
1664
1711
|
const workspaceType = requiredLabel(containerLabels, labels.workspaceType);
|
|
1665
1712
|
const volumeName = requiredLabel(containerLabels, labels.workspaceVolume);
|
|
1666
1713
|
const networkMode = requiredLabel(containerLabels, labels.networkMode);
|
|
1714
|
+
const labeledRuntime = containerLabels[labels.containerRuntime];
|
|
1715
|
+
const hostRuntime = inspection.HostConfig?.Runtime;
|
|
1716
|
+
const containerRuntime = labeledRuntime !== void 0 && labeledRuntime !== "" ? labeledRuntime : hostRuntime !== void 0 && hostRuntime !== "" ? hostRuntime : "default";
|
|
1667
1717
|
if (networkMode !== "none" && networkMode !== "bridge") invalidInspection("network mode");
|
|
1668
1718
|
const workspace = workspaceType === "ephemeral" ? { type: "ephemeral" } : workspaceType === "docker-volume" ? { type: "docker-volume", name: volumeName } : invalidInspection("workspace type");
|
|
1669
1719
|
const runtime = {
|
|
@@ -1675,6 +1725,7 @@ function configurationFromInspection(id, containerName, inspection) {
|
|
|
1675
1725
|
return {
|
|
1676
1726
|
id,
|
|
1677
1727
|
containerName,
|
|
1728
|
+
containerRuntime,
|
|
1678
1729
|
workdir,
|
|
1679
1730
|
workspace,
|
|
1680
1731
|
volumeName,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/docker-sandbox.ts","../src/docker-process.ts","../src/path.ts","../src/text-file.ts","../src/tools.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { lstat, mkdtemp, readFile, realpath, rm, writeFile } from \"node:fs/promises\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { assertDockerCli, decodeUtf8, runDockerCli } from \"./docker-cli\";\nimport { DockerProcessManager } from \"./docker-process\";\nimport { DockerSandboxError } from \"./errors\";\nimport { containerPath, normalizeSandboxPath, parentSandboxPath } from \"./path\";\nimport { createTextFilePage } from \"./text-file\";\nimport type {\n CreateDockerSandboxOptions,\n DockerSandbox,\n DockerSandboxClientOptions,\n DockerSandboxExecOptions,\n DockerSandboxExecResult,\n DockerSandboxExecStreamEvent,\n DockerSandboxFileEntry,\n DockerSandboxFileType,\n DockerSandboxInspectionOptions,\n DockerSandboxInspector,\n DockerSandboxListFilesOptions,\n DockerSandboxListProcessesOptions,\n DockerSandboxProcessInfo,\n DockerSandboxProcessLogs,\n DockerSandboxProcessStartOptions,\n DockerSandboxPublishedPort,\n DockerSandboxReadFileOptions,\n DockerSandboxReadProcessLogsOptions,\n DockerSandboxReadTextFilePageOptions,\n DockerSandboxRuntime,\n DockerSandboxRuntimeLimits,\n DockerSandboxState,\n DockerSandboxStopProcessOptions,\n DockerSandboxTextFilePage,\n DockerSandboxWaitForPortOptions,\n DockerSandboxWorkspace,\n DockerSandboxWriteFileOptions,\n DockerSandboxWriteTextFileOptions,\n PullDockerImageOptions,\n ResumeDockerSandboxOptions,\n} from \"./types\";\n\nconst schemaVersion = \"1\";\nconst labelPrefix = \"anvia.sandbox.\";\nconst defaultWorkdir = \"/workspace\";\nconst defaultCommandTimeoutMs = 30_000;\nconst defaultMaxOutputBytes = 1024 * 1024;\nconst defaultMaxFileBytes = 10 * 1024 * 1024;\nconst defaultMaxProcesses = 4;\nconst defaultTextFilePageLines = 500;\nconst defaultTextFilePageBytes = 64 * 1024;\nconst defaultPortWaitTimeoutMs = 30_000;\nconst defaultPortWaitIntervalMs = 100;\nconst idPattern = /^[a-z0-9](?:[a-z0-9_.-]{0,62})$/;\nconst envKeyPattern = /^[A-Za-z_][A-Za-z0-9_]*$/;\n\nconst labels = {\n schema: `${labelPrefix}schema`,\n id: `${labelPrefix}id`,\n workdir: `${labelPrefix}workdir`,\n workspaceType: `${labelPrefix}workspace.type`,\n workspaceVolume: `${labelPrefix}workspace.volume`,\n networkMode: `${labelPrefix}network.mode`,\n commandTimeoutMs: `${labelPrefix}runtime.command-timeout-ms`,\n maxOutputBytes: `${labelPrefix}runtime.max-output-bytes`,\n maxFileBytes: `${labelPrefix}runtime.max-file-bytes`,\n maxProcesses: `${labelPrefix}runtime.max-processes`,\n} as const;\n\nconst portProbeScript = [\n 'port=\"$(printf \\'%04X\\' \"$1\")\"',\n \"for table in /proc/net/tcp /proc/net/tcp6; do\",\n ' [ -r \"$table\" ] || continue',\n \" while read -r _ local _ state _; do\",\n ' case \"$local\" in',\n ' \"00000000:$port\"|\"00000000000000000000000000000000:$port\")',\n ' [ \"$state\" = \"0A\" ] && exit 0',\n \" ;;\",\n \" esac\",\n ' done < \"$table\"',\n \"done\",\n \"exit 1\",\n].join(\"\\n\");\n\ntype ResolvedRuntimeLimits = Required<DockerSandboxRuntimeLimits>;\n\ntype SandboxConfiguration = {\n id: string;\n containerName: string;\n workdir: string;\n workspace: DockerSandboxWorkspace;\n volumeName: string;\n ownsVolume: boolean;\n env: Record<string, string>;\n runtime: ResolvedRuntimeLimits;\n publishedPorts: DockerSandboxPublishedPort[];\n};\n\nexport class DockerSandboxClient {\n private readonly dockerPath: string;\n\n constructor(options: DockerSandboxClientOptions = {}) {\n if (!isRecord(options)) throw new TypeError(\"options must be an object.\");\n this.dockerPath = options.dockerPath ?? \"docker\";\n assertNonEmptyString(this.dockerPath, \"dockerPath\");\n }\n\n async pullImage(options: PullDockerImageOptions): Promise<void> {\n if (!isRecord(options)) throw new TypeError(\"options must be an object.\");\n assertNonEmptyString(options.image, \"image\");\n options.abortSignal?.throwIfAborted();\n await assertDockerCli([\"pull\", options.image], this.cliOptions(options.abortSignal));\n }\n\n async createSandbox(options: CreateDockerSandboxOptions): Promise<DockerSandbox> {\n validateCreateOptions(options);\n options = snapshotCreateOptions(options);\n options.abortSignal?.throwIfAborted();\n\n const id = options.id ?? randomUUID();\n assertSandboxId(id);\n const containerName = containerNameFor(id);\n const workdir = options.workdir ?? defaultWorkdir;\n const runtime = resolveRuntimeLimits(options.runtime);\n const workspace = copyWorkspace(options.workspace);\n const network = copyNetwork(options.network);\n const env = copyStringRecord(options.env, \"env\");\n const userLabels = copyStringRecord(options.labels, \"labels\");\n const volumeName =\n workspace.type === \"ephemeral\"\n ? `${containerName}-workspace-${randomUUID()}`\n : workspace.name;\n const ownsVolume = workspace.type === \"ephemeral\";\n\n await this.assertContainerDoesNotExist(containerName, options.abortSignal);\n await this.assertImageExists(options.image, options.abortSignal);\n if (workspace.type === \"docker-volume\") {\n await this.assertVolumeExists(workspace.name, options.abortSignal);\n }\n\n let containerCreated = false;\n let volumeCreated = false;\n try {\n if (workspace.type === \"ephemeral\") {\n await assertDockerCli(\n [\"volume\", \"create\", \"--label\", `${labels.id}=${id}`, volumeName],\n this.cliOptions(options.abortSignal),\n );\n volumeCreated = true;\n }\n await assertDockerCli(\n createRunArgs({\n id,\n containerName,\n image: options.image,\n workdir,\n workspace,\n volumeName,\n env,\n user: options.user,\n userLabels,\n resources: options.resources,\n runtime,\n security: options.security,\n network,\n }),\n {\n ...this.cliOptions(options.abortSignal),\n timeoutMs: runtime.commandTimeoutMs,\n },\n );\n containerCreated = true;\n\n const publishedPorts = await inspectPublishedPorts({\n dockerPath: this.dockerPath,\n containerName,\n ports: network.mode === \"bridge\" ? [...(network.ports ?? [])] : [],\n abortSignal: options.abortSignal,\n });\n const sandbox = this.createHandle({\n id,\n containerName,\n workdir,\n workspace,\n volumeName,\n ownsVolume,\n env,\n runtime,\n publishedPorts,\n });\n await applyInitialContent(sandbox.runtime, options);\n return sandbox;\n } catch (error) {\n const cleanupErrors: unknown[] = [];\n if (containerCreated) {\n try {\n await removeContainer(this.dockerPath, containerName);\n } catch (cleanupError) {\n cleanupErrors.push(cleanupError);\n }\n }\n if (ownsVolume && volumeCreated) {\n try {\n await removeVolume(this.dockerPath, volumeName);\n } catch (cleanupError) {\n cleanupErrors.push(cleanupError);\n }\n }\n if (cleanupErrors.length > 0) {\n throw new AggregateError([error, ...cleanupErrors], \"Sandbox creation and rollback failed\");\n }\n throw error;\n }\n }\n\n async resumeSandbox(options: ResumeDockerSandboxOptions): Promise<DockerSandbox> {\n if (!isRecord(options)) throw new TypeError(\"options must be an object.\");\n assertSandboxId(options.id);\n options.abortSignal?.throwIfAborted();\n const containerName = containerNameFor(options.id);\n const inspection = await inspectContainer(\n this.dockerPath,\n containerName,\n options.abortSignal,\n true,\n );\n const configuration = configurationFromInspection(options.id, containerName, inspection);\n\n if (inspection.State.Paused === true || inspection.State.Dead === true) {\n throw new DockerSandboxError(\n `Sandbox cannot be resumed from Docker state: ${inspection.State.Status ?? \"unknown\"}`,\n \"invalid_state\",\n );\n }\n if (inspection.State.Running === true) {\n await assertDockerCli([\"stop\", containerName], this.cliOptions(options.abortSignal));\n }\n await assertDockerCli([\"start\", containerName], this.cliOptions(options.abortSignal));\n configuration.publishedPorts = await inspectPublishedPorts({\n dockerPath: this.dockerPath,\n containerName,\n ports: configuredContainerPorts(inspection),\n abortSignal: options.abortSignal,\n });\n return this.createHandle(configuration);\n }\n\n private createHandle(configuration: SandboxConfiguration): DockerSandbox {\n return new DockerSandboxHandle({\n dockerPath: this.dockerPath,\n configuration,\n });\n }\n\n private async assertImageExists(image: string, abortSignal?: AbortSignal): Promise<void> {\n const result = await runDockerCli([\"image\", \"inspect\", image], this.cliOptions(abortSignal));\n if (result.exitCode === 0) return;\n const message = safeDecode(result.stderr);\n if (message.toLowerCase().includes(\"no such image\")) {\n throw new DockerSandboxError(\n `Docker image is not available locally: ${image}`,\n \"image_not_found\",\n );\n }\n throw new DockerSandboxError(\n \"Unable to inspect Docker image.\",\n \"docker_command_failed\",\n result,\n );\n }\n\n private async assertContainerDoesNotExist(\n containerName: string,\n abortSignal?: AbortSignal,\n ): Promise<void> {\n const result = await runDockerCli([\"container\", \"inspect\", containerName], {\n ...this.cliOptions(abortSignal),\n maxOutputBytes: defaultMaxOutputBytes,\n });\n if (result.exitCode === 0) {\n throw new DockerSandboxError(\n `A Docker container already exists for sandbox: ${containerName}`,\n \"invalid_state\",\n );\n }\n if (safeDecode(result.stderr).toLowerCase().includes(\"no such\")) return;\n throw new DockerSandboxError(\n \"Unable to check whether the Docker sandbox already exists.\",\n \"docker_command_failed\",\n result,\n );\n }\n\n private async assertVolumeExists(name: string, abortSignal?: AbortSignal): Promise<void> {\n const result = await runDockerCli([\"volume\", \"inspect\", name], this.cliOptions(abortSignal));\n if (result.exitCode === 0) return;\n const message = safeDecode(result.stderr);\n if (message.toLowerCase().includes(\"no such volume\")) {\n throw new DockerSandboxError(`Docker volume does not exist: ${name}`, \"volume_not_found\");\n }\n throw new DockerSandboxError(\n \"Unable to inspect Docker volume.\",\n \"docker_command_failed\",\n result,\n );\n }\n\n private cliOptions(abortSignal?: AbortSignal) {\n return { dockerPath: this.dockerPath, signal: abortSignal };\n }\n}\n\nclass DockerSandboxHandle implements DockerSandbox {\n readonly id: string;\n readonly runtime: DockerSandboxRuntime;\n\n private currentState: DockerSandboxState = \"running\";\n private readonly dockerPath: string;\n private readonly configuration: SandboxConfiguration;\n private readonly runtimeImpl: DockerSandboxRuntimeImpl;\n private stopPromise: Promise<void> | undefined;\n private destroyPromise: Promise<void> | undefined;\n\n constructor(options: { dockerPath: string; configuration: SandboxConfiguration }) {\n this.dockerPath = options.dockerPath;\n this.configuration = options.configuration;\n this.id = options.configuration.id;\n this.runtimeImpl = new DockerSandboxRuntimeImpl({\n configuration: options.configuration,\n dockerPath: options.dockerPath,\n state: () => this.currentState,\n });\n this.runtime = Object.freeze(this.runtimeImpl.publicRuntime());\n }\n\n get state(): DockerSandboxState {\n return this.currentState;\n }\n\n inspector(options: DockerSandboxInspectionOptions): DockerSandboxInspector {\n if (!isRecord(options)) throw new TypeError(\"options must be an object.\");\n if (options.files !== true && options.ports !== true && options.processes !== true) {\n throw new TypeError(\"Sandbox inspector must enable at least one capability.\");\n }\n let inspector: DockerSandboxInspector = {\n id: this.id,\n provider: \"docker\",\n workdir: this.configuration.workdir,\n };\n if (options.files === true) {\n inspector = {\n ...inspector,\n listFiles: this.runtime.listFiles.bind(this.runtime),\n readFile: this.runtime.readFile.bind(this.runtime),\n };\n }\n if (options.ports === true) {\n inspector = { ...inspector, publishedPorts: this.runtime.publishedPorts };\n }\n if (options.processes === true) {\n inspector = {\n ...inspector,\n listProcesses: this.runtime.listProcesses.bind(this.runtime),\n readProcessLogs: this.runtime.readProcessLogs.bind(this.runtime),\n };\n }\n return Object.freeze(inspector);\n }\n\n async stop(options: Readonly<{ abortSignal?: AbortSignal }> = {}): Promise<void> {\n if (!isRecord(options)) throw new TypeError(\"options must be an object.\");\n if (this.currentState === \"stopped\") return;\n if (this.currentState === \"destroyed\" || this.currentState === \"destroying\") {\n throw invalidState(this.id, this.currentState);\n }\n if (this.stopPromise !== undefined) return this.stopPromise;\n this.stopPromise = this.performStop(options.abortSignal);\n try {\n await this.stopPromise;\n } finally {\n this.stopPromise = undefined;\n }\n }\n\n private async performStop(abortSignal?: AbortSignal): Promise<void> {\n abortSignal?.throwIfAborted();\n this.currentState = \"stopping\";\n try {\n await this.runtimeImpl.closeActiveOperations(\"Sandbox is stopping.\");\n await this.runtimeImpl.disposeProcesses(abortSignal);\n await assertDockerCli([\"stop\", this.configuration.containerName], {\n dockerPath: this.dockerPath,\n signal: abortSignal,\n });\n this.currentState = \"stopped\";\n } catch (error) {\n this.currentState = \"error\";\n throw error;\n }\n }\n\n async destroy(): Promise<void> {\n if (this.currentState === \"destroyed\") return;\n if (this.destroyPromise !== undefined) return this.destroyPromise;\n this.destroyPromise = this.performDestroy();\n try {\n await this.destroyPromise;\n } finally {\n this.destroyPromise = undefined;\n }\n }\n\n private async performDestroy(): Promise<void> {\n if (this.stopPromise !== undefined) await this.stopPromise.catch(() => undefined);\n this.currentState = \"destroying\";\n const failures: unknown[] = [];\n try {\n await this.runtimeImpl.closeActiveOperations(\"Sandbox is being destroyed.\");\n } catch (error) {\n failures.push(error);\n }\n try {\n await this.runtimeImpl.disposeProcesses();\n } catch (error) {\n failures.push(error);\n }\n try {\n await removeContainer(this.dockerPath, this.configuration.containerName);\n } catch (error) {\n failures.push(error);\n }\n if (this.configuration.ownsVolume) {\n try {\n await removeVolume(this.dockerPath, this.configuration.volumeName);\n } catch (error) {\n failures.push(error);\n }\n }\n if (failures.length > 0) {\n this.currentState = \"error\";\n throw new AggregateError(failures, `Unable to destroy sandbox: ${this.id}`);\n }\n this.currentState = \"destroyed\";\n }\n\n async [Symbol.asyncDispose](): Promise<void> {\n await this.destroy();\n }\n}\n\nclass DockerSandboxRuntimeImpl {\n private readonly configuration: SandboxConfiguration;\n private readonly dockerPath: string;\n private readonly state: () => DockerSandboxState;\n private readonly processManager: DockerProcessManager;\n private readonly activeControllers = new Set<AbortController>();\n private readonly activeOperations = new Set<Promise<unknown>>();\n private processDisposed = false;\n\n constructor(options: {\n configuration: SandboxConfiguration;\n dockerPath: string;\n state: () => DockerSandboxState;\n }) {\n this.configuration = options.configuration;\n this.dockerPath = options.dockerPath;\n this.state = options.state;\n this.processManager = new DockerProcessManager({\n containerName: options.configuration.containerName,\n dockerPath: options.dockerPath,\n workdir: options.configuration.workdir,\n env: options.configuration.env,\n maxOutputBytes: options.configuration.runtime.maxOutputBytes,\n maxProcesses: options.configuration.runtime.maxProcesses,\n startupTimeoutMs: options.configuration.runtime.commandTimeoutMs,\n });\n }\n\n publicRuntime(): DockerSandboxRuntime {\n return {\n id: this.configuration.id,\n provider: \"docker\",\n workdir: this.configuration.workdir,\n publishedPorts: Object.freeze(\n this.configuration.publishedPorts.map((port) => Object.freeze({ ...port })),\n ),\n exec: (options) => this.exec(options),\n execStream: (options) => this.execStream(options),\n readFile: (options) => this.readFile(options),\n readTextFile: (options) => this.readTextFile(options),\n readTextFilePage: (options) => this.readTextFilePage(options),\n writeFile: (options) => this.writeFile(options),\n writeTextFile: (options) => this.writeTextFile(options),\n listFiles: (options) => this.listFiles(options),\n startProcess: (options) => this.startProcess(options),\n listProcesses: (options) => this.listProcesses(options),\n readProcessLogs: (options) => this.readProcessLogs(options),\n stopProcess: (options) => this.stopProcess(options),\n waitForPort: (options) => this.waitForPort(options),\n };\n }\n\n async exec(options: DockerSandboxExecOptions): Promise<DockerSandboxExecResult> {\n validateExecOptions(options);\n return this.runOperation(options.abortSignal, async (abortSignal) => {\n const result = await runDockerCli(this.execArgs(options), {\n dockerPath: this.dockerPath,\n timeoutMs: options.timeoutMs ?? this.configuration.runtime.commandTimeoutMs,\n maxOutputBytes: this.configuration.runtime.maxOutputBytes,\n input: options.input,\n signal: abortSignal,\n });\n return toExecResult(result);\n });\n }\n\n async *execStream(\n options: DockerSandboxExecOptions,\n ): AsyncIterable<DockerSandboxExecStreamEvent> {\n validateExecOptions(options);\n this.assertRunning();\n const streamAbort = new AbortController();\n const combined = combineSignals(options.abortSignal, streamAbort.signal);\n const queue: DockerSandboxExecStreamEvent[] = [];\n let queuedBytes = 0;\n let wake: (() => void) | undefined;\n let complete = false;\n let failure: unknown;\n const push = (event: DockerSandboxExecStreamEvent) => {\n if (event.type !== \"result\") {\n queuedBytes += event.data.byteLength;\n if (queuedBytes > this.configuration.runtime.maxOutputBytes) {\n streamAbort.abort(\n new DockerSandboxError(\"Sandbox stream consumer is too slow.\", \"docker_command_failed\"),\n );\n return;\n }\n }\n queue.push(event);\n wake?.();\n wake = undefined;\n };\n const run = this.runOperation(combined, async (abortSignal) => {\n const result = await runDockerCli(this.execArgs(options), {\n dockerPath: this.dockerPath,\n timeoutMs: options.timeoutMs ?? this.configuration.runtime.commandTimeoutMs,\n maxOutputBytes: this.configuration.runtime.maxOutputBytes,\n input: options.input,\n signal: abortSignal,\n onStdout: (data) => push({ type: \"stdout\", data: data.slice() }),\n onStderr: (data) => push({ type: \"stderr\", data: data.slice() }),\n });\n push({ type: \"result\", result: toExecResult(result) });\n });\n void run.then(\n () => {\n complete = true;\n wake?.();\n },\n (error) => {\n failure = error;\n complete = true;\n wake?.();\n },\n );\n\n try {\n while (!complete || queue.length > 0) {\n const event = queue.shift();\n if (event !== undefined) {\n if (event.type !== \"result\") queuedBytes -= event.data.byteLength;\n yield event;\n continue;\n }\n await new Promise<void>((resolve) => {\n wake = resolve;\n });\n }\n if (failure !== undefined) throw failure;\n } finally {\n if (!complete) streamAbort.abort(new DOMException(\"Stream closed\", \"AbortError\"));\n await run.catch(() => undefined);\n }\n }\n\n async readFile(options: DockerSandboxReadFileOptions): Promise<Uint8Array> {\n assertReadOptions(options);\n return this.runOperation(options.abortSignal, async (abortSignal) => {\n const normalized = normalizeSandboxPath(options.path);\n const tempDir = await mkdtemp(path.join(os.tmpdir(), \"anvia-sandbox-read-\"));\n const target = path.join(tempDir, path.basename(normalized));\n try {\n await assertDockerCli(\n [\n \"cp\",\n `${this.configuration.containerName}:${containerPath(this.configuration.workdir, normalized)}`,\n target,\n ],\n { dockerPath: this.dockerPath, signal: abortSignal },\n );\n await assertCopiedRegularFile(tempDir, target, normalized);\n const bytes = await readFile(target, { signal: abortSignal });\n this.assertFileSize(bytes.byteLength, normalized);\n return new Uint8Array(bytes.buffer, bytes.byteOffset, bytes.byteLength).slice();\n } finally {\n await rm(tempDir, { recursive: true, force: true });\n }\n });\n }\n\n async readTextFile(options: DockerSandboxReadFileOptions): Promise<string> {\n return decodeUtf8(await this.readFile(options));\n }\n\n async readTextFilePage(\n options: DockerSandboxReadTextFilePageOptions,\n ): Promise<DockerSandboxTextFilePage> {\n assertReadOptions(options);\n const startLine = options.startLine ?? 1;\n const lineCount = options.lineCount ?? defaultTextFilePageLines;\n const maxBytes = options.maxBytes ?? defaultTextFilePageBytes;\n assertPositiveSafeInteger(startLine, \"startLine\");\n assertPositiveSafeInteger(lineCount, \"lineCount\");\n assertPositiveSafeInteger(maxBytes, \"maxBytes\");\n let readOptions: DockerSandboxReadFileOptions = {\n path: options.path,\n };\n if (options.abortSignal !== undefined) {\n readOptions = { ...readOptions, abortSignal: options.abortSignal };\n }\n const text = await this.readTextFile(readOptions);\n return createTextFilePage(text, { startLine, lineCount, maxBytes });\n }\n\n async writeFile(options: DockerSandboxWriteFileOptions): Promise<void> {\n assertOptionsObject(options);\n if (!(options.data instanceof Uint8Array)) throw new TypeError(\"data must be a Uint8Array.\");\n const data = options.data.slice();\n await this.writeBytes(options.path, data, options.abortSignal);\n }\n\n async writeTextFile(options: DockerSandboxWriteTextFileOptions): Promise<void> {\n assertOptionsObject(options);\n if (typeof options.text !== \"string\") throw new TypeError(\"text must be a string.\");\n await this.writeBytes(\n options.path,\n new TextEncoder().encode(options.text),\n options.abortSignal,\n );\n }\n\n private async writeBytes(\n filePath: string,\n data: Uint8Array,\n abortSignal?: AbortSignal,\n ): Promise<void> {\n const normalized = normalizeSandboxPath(filePath);\n this.assertFileSize(data.byteLength, normalized);\n await this.runOperation(abortSignal, async (effectiveSignal) => {\n await this.mkdir(parentSandboxPath(normalized), effectiveSignal);\n const tempDir = await mkdtemp(path.join(os.tmpdir(), \"anvia-sandbox-write-\"));\n const source = path.join(tempDir, path.basename(normalized));\n try {\n await writeFile(source, data, { signal: effectiveSignal });\n await assertDockerCli(\n [\n \"cp\",\n source,\n `${this.configuration.containerName}:${containerPath(this.configuration.workdir, normalized)}`,\n ],\n { dockerPath: this.dockerPath, signal: effectiveSignal },\n );\n } finally {\n await rm(tempDir, { recursive: true, force: true });\n }\n });\n }\n\n async listFiles(\n options: DockerSandboxListFilesOptions = {},\n ): Promise<readonly DockerSandboxFileEntry[]> {\n assertOptionsObject(options);\n const requestedPath = options.path ?? \".\";\n const normalized = normalizeSandboxPath(requestedPath, { allowRoot: true });\n return this.runOperation(options.abortSignal, async (abortSignal) => {\n const result = await this.execCommand(\n {\n command: \"find\",\n args: [\n containerPath(this.configuration.workdir, normalized),\n \"-mindepth\",\n \"1\",\n \"-maxdepth\",\n \"1\",\n \"-printf\",\n \"%p\\t%y\\t%s\\n\",\n ],\n },\n abortSignal,\n );\n if (result.status !== \"exited\" || result.exitCode !== 0) {\n throw new DockerSandboxError(\n \"Unable to list sandbox files.\",\n \"docker_command_failed\",\n result,\n );\n }\n const output = decodeUtf8(result.stdout);\n return output\n .split(\"\\n\")\n .filter((line) => line.length > 0)\n .map((line) => parseFindEntry(line, this.configuration.workdir));\n });\n }\n\n async startProcess(options: DockerSandboxProcessStartOptions): Promise<DockerSandboxProcessInfo> {\n validateProcessStartOptions(options);\n return this.runOperation(options.abortSignal, async (abortSignal) =>\n this.processManager.start({ ...options, abortSignal }),\n );\n }\n\n async listProcesses(\n options: DockerSandboxListProcessesOptions = {},\n ): Promise<readonly DockerSandboxProcessInfo[]> {\n assertOptionsObject(options);\n return this.runOperation(options.abortSignal, async () => this.processManager.list());\n }\n\n async readProcessLogs(\n options: DockerSandboxReadProcessLogsOptions,\n ): Promise<DockerSandboxProcessLogs> {\n assertOptionsObject(options);\n assertNonEmptyString(options.processId, \"processId\");\n if (options.tailBytes !== undefined)\n assertNonNegativeSafeInteger(options.tailBytes, \"tailBytes\");\n return this.runOperation(options.abortSignal, async () =>\n this.processManager.logs(options.processId, options.tailBytes),\n );\n }\n\n async stopProcess(options: DockerSandboxStopProcessOptions): Promise<DockerSandboxProcessInfo> {\n assertOptionsObject(options);\n assertNonEmptyString(options.processId, \"processId\");\n if (options.gracePeriodMs !== undefined) {\n assertNonNegativeSafeInteger(options.gracePeriodMs, \"gracePeriodMs\");\n }\n return this.runOperation(options.abortSignal, async (abortSignal) =>\n this.processManager.stop(options.processId, options.gracePeriodMs, abortSignal),\n );\n }\n\n async waitForPort(options: DockerSandboxWaitForPortOptions): Promise<DockerSandboxPublishedPort> {\n assertOptionsObject(options);\n assertPort(options.containerPort);\n const publishedPort = this.configuration.publishedPorts.find(\n (candidate) => candidate.containerPort === options.containerPort,\n );\n if (publishedPort === undefined) {\n throw new DockerSandboxError(\n `Sandbox port is not published: ${options.containerPort}/tcp`,\n \"port\",\n );\n }\n const timeoutMs = options.timeoutMs ?? defaultPortWaitTimeoutMs;\n const intervalMs = options.intervalMs ?? defaultPortWaitIntervalMs;\n assertPositiveSafeInteger(timeoutMs, \"timeoutMs\");\n assertPositiveSafeInteger(intervalMs, \"intervalMs\");\n\n return this.runOperation(options.abortSignal, async (abortSignal) => {\n const deadline = Date.now() + timeoutMs;\n while (true) {\n const result = await this.execCommand(\n {\n command: \"sh\",\n args: [\"-c\", portProbeScript, \"anvia-port-probe\", `${options.containerPort}`],\n timeoutMs: Math.min(5_000, timeoutMs),\n },\n abortSignal,\n );\n if (result.status === \"exited\" && result.exitCode === 0) return { ...publishedPort };\n if (Date.now() >= deadline) {\n throw new DockerSandboxError(\n `Waiting for sandbox port timed out: ${options.containerPort}`,\n \"timeout\",\n );\n }\n await waitWithSignal(Math.min(intervalMs, deadline - Date.now()), abortSignal);\n }\n });\n }\n\n async closeActiveOperations(message: string): Promise<void> {\n const reason = new DockerSandboxError(message, \"invalid_state\");\n for (const controller of this.activeControllers) controller.abort(reason);\n await Promise.allSettled(this.activeOperations);\n }\n\n async disposeProcesses(abortSignal?: AbortSignal): Promise<void> {\n if (this.processDisposed) return;\n await this.processManager.dispose(abortSignal);\n this.processDisposed = true;\n }\n\n private async runOperation<T>(\n abortSignal: AbortSignal | undefined,\n operation: (abortSignal: AbortSignal) => Promise<T>,\n ): Promise<T> {\n this.assertRunning();\n abortSignal?.throwIfAborted();\n const controller = new AbortController();\n const effectiveSignal = combineSignals(abortSignal, controller.signal);\n const execution = operation(effectiveSignal);\n this.activeControllers.add(controller);\n this.activeOperations.add(execution);\n try {\n return await execution;\n } finally {\n this.activeControllers.delete(controller);\n this.activeOperations.delete(execution);\n }\n }\n\n private assertRunning(): void {\n const current = this.state();\n if (current !== \"running\") throw invalidState(this.configuration.id, current);\n }\n\n private execArgs(options: DockerSandboxExecOptions): string[] {\n const args = [\"exec\"];\n if (options.input !== undefined) args.push(\"-i\");\n args.push(\"-w\", containerPath(this.configuration.workdir, options.cwd ?? \".\"));\n for (const [key, value] of Object.entries(options.env ?? {}))\n args.push(\"-e\", `${key}=${value}`);\n args.push(this.configuration.containerName, options.command, ...(options.args ?? []));\n return args;\n }\n\n private async execCommand(\n options: Omit<DockerSandboxExecOptions, \"abortSignal\">,\n abortSignal: AbortSignal,\n ): Promise<DockerSandboxExecResult> {\n const result = await runDockerCli(this.execArgs(options), {\n dockerPath: this.dockerPath,\n timeoutMs: options.timeoutMs ?? this.configuration.runtime.commandTimeoutMs,\n maxOutputBytes: this.configuration.runtime.maxOutputBytes,\n input: options.input,\n signal: abortSignal,\n });\n return toExecResult(result);\n }\n\n private async mkdir(directory: string, abortSignal: AbortSignal): Promise<void> {\n if (directory === \".\") return;\n const result = await this.execCommand(\n { command: \"mkdir\", args: [\"-p\", containerPath(this.configuration.workdir, directory)] },\n abortSignal,\n );\n if (result.status !== \"exited\" || result.exitCode !== 0) {\n throw new DockerSandboxError(\n \"Unable to create sandbox directory.\",\n \"docker_command_failed\",\n result,\n );\n }\n }\n\n private assertFileSize(size: number, filePath: string): void {\n if (size > this.configuration.runtime.maxFileBytes) {\n throw new DockerSandboxError(\n `Sandbox file exceeds maxFileBytes (${size} > ${this.configuration.runtime.maxFileBytes}): ${filePath}`,\n \"file_too_large\",\n );\n }\n }\n}\n\nasync function applyInitialContent(\n runtime: DockerSandboxRuntime,\n options: CreateDockerSandboxOptions,\n): Promise<void> {\n for (const directory of options.directories ?? []) {\n const marker = path.posix.join(normalizeSandboxPath(directory), \".anvia-keep\");\n const abort = options.abortSignal === undefined ? {} : { abortSignal: options.abortSignal };\n await runtime.writeFile({ path: marker, data: new Uint8Array(), ...abort });\n const removed = await runtime.exec({ command: \"rm\", args: [marker], ...abort });\n if (removed.status !== \"exited\" || removed.exitCode !== 0) {\n throw new DockerSandboxError(\n `Unable to create initial sandbox directory: ${directory}`,\n \"docker_command_failed\",\n removed,\n );\n }\n }\n for (const [filePath, content] of Object.entries(options.files ?? {})) {\n if (typeof content === \"string\") {\n let writeOptions: DockerSandboxWriteTextFileOptions = {\n path: filePath,\n text: content,\n };\n if (options.abortSignal !== undefined) {\n writeOptions = { ...writeOptions, abortSignal: options.abortSignal };\n }\n await runtime.writeTextFile(writeOptions);\n } else {\n let writeOptions: DockerSandboxWriteFileOptions = {\n path: filePath,\n data: content,\n };\n if (options.abortSignal !== undefined) {\n writeOptions = { ...writeOptions, abortSignal: options.abortSignal };\n }\n await runtime.writeFile(writeOptions);\n }\n }\n}\n\nfunction createRunArgs(options: {\n id: string;\n containerName: string;\n image: string;\n workdir: string;\n workspace: DockerSandboxWorkspace;\n volumeName: string;\n env: Record<string, string>;\n user: string | undefined;\n userLabels: Record<string, string>;\n resources: CreateDockerSandboxOptions[\"resources\"] | undefined;\n runtime: ResolvedRuntimeLimits;\n security: CreateDockerSandboxOptions[\"security\"] | undefined;\n network: CreateDockerSandboxOptions[\"network\"];\n}): string[] {\n const runtimeLabels: Record<string, string> = {\n [labels.schema]: schemaVersion,\n [labels.id]: options.id,\n [labels.workdir]: options.workdir,\n [labels.workspaceType]: options.workspace.type,\n [labels.workspaceVolume]: options.volumeName,\n [labels.networkMode]: options.network.mode,\n [labels.commandTimeoutMs]: `${options.runtime.commandTimeoutMs}`,\n [labels.maxOutputBytes]: `${options.runtime.maxOutputBytes}`,\n [labels.maxFileBytes]: `${options.runtime.maxFileBytes}`,\n [labels.maxProcesses]: `${options.runtime.maxProcesses}`,\n };\n const args = [\n \"run\",\n \"-d\",\n \"--name\",\n options.containerName,\n \"--mount\",\n `type=volume,src=${options.volumeName},dst=${options.workdir}`,\n \"-w\",\n options.workdir,\n ];\n for (const [key, value] of Object.entries({ ...options.userLabels, ...runtimeLabels })) {\n args.push(\"--label\", `${key}=${value}`);\n }\n for (const [key, value] of Object.entries(options.env)) args.push(\"--env\", `${key}=${value}`);\n if (options.user !== undefined) args.push(\"--user\", options.user);\n if (options.network.mode === \"none\") {\n args.push(\"--network\", \"none\");\n } else {\n for (const port of options.network.ports ?? [])\n args.push(\"--publish\", `127.0.0.1::${port}/tcp`);\n }\n if (options.resources?.memoryMb !== undefined)\n args.push(\"--memory\", `${options.resources.memoryMb}m`);\n if (options.resources?.cpus !== undefined) args.push(\"--cpus\", `${options.resources.cpus}`);\n if (options.resources?.pidsLimit !== undefined) {\n args.push(\"--pids-limit\", `${options.resources.pidsLimit}`);\n }\n if (options.resources?.sharedMemoryMb !== undefined) {\n args.push(\"--shm-size\", `${options.resources.sharedMemoryMb}m`);\n }\n if (options.security?.readonlyRootfs === true) args.push(\"--read-only\");\n if (options.security?.noNewPrivileges ?? true)\n args.push(\"--security-opt\", \"no-new-privileges:true\");\n if (options.security?.seccompProfile !== undefined) {\n args.push(\"--security-opt\", `seccomp=${options.security.seccompProfile.path}`);\n }\n for (const capability of options.security?.dropCapabilities ?? [\"ALL\"]) {\n args.push(\"--cap-drop\", capability);\n }\n for (const capability of options.security?.addCapabilities ?? []) {\n args.push(\"--cap-add\", capability);\n }\n args.push(\n options.image,\n \"sh\",\n \"-c\",\n \"trap 'exit 0' TERM INT; while :; do sleep 3600 & wait $!; done\",\n );\n return args;\n}\n\nfunction validateCreateOptions(options: CreateDockerSandboxOptions): void {\n if (options === null || typeof options !== \"object\")\n throw new TypeError(\"options must be an object.\");\n assertNonEmptyString(options.image, \"image\");\n if (options.id !== undefined) assertSandboxId(options.id);\n const workdir = options.workdir ?? defaultWorkdir;\n if (!path.posix.isAbsolute(workdir) || workdir.includes(\"\\0\")) {\n throw new TypeError(\"workdir must be an absolute POSIX path.\");\n }\n if (!isRecord(options.workspace)) throw new TypeError(\"workspace must be an object.\");\n if (options.workspace.type === \"docker-volume\") assertDockerVolumeName(options.workspace.name);\n if (options.workspace.type !== \"ephemeral\" && options.workspace.type !== \"docker-volume\") {\n throw new TypeError(\"workspace must use type ephemeral or docker-volume.\");\n }\n if (options.workspace.type === \"ephemeral\" && \"name\" in options.workspace) {\n throw new TypeError(\"An ephemeral workspace cannot specify a Docker volume name.\");\n }\n if (!isRecord(options.network)) throw new TypeError(\"network must be an object.\");\n if (options.network.mode !== \"none\" && options.network.mode !== \"bridge\") {\n throw new TypeError(\"network must use mode none or bridge.\");\n }\n if (options.network.mode === \"none\" && \"ports\" in options.network) {\n throw new TypeError(\"Network mode none cannot publish ports.\");\n }\n if (options.network.mode === \"bridge\") {\n if (options.network.ports !== undefined && !Array.isArray(options.network.ports)) {\n throw new TypeError(\"network.ports must be an array.\");\n }\n validatePorts(options.network.ports ?? []);\n }\n validateRuntimeLimits(options.runtime);\n validateResources(options.resources);\n validateSecurity(options.security);\n copyStringRecord(options.env, \"env\");\n const userLabels = copyStringRecord(options.labels, \"labels\");\n for (const key of Object.keys(userLabels)) {\n if (key.startsWith(labelPrefix)) throw new TypeError(`Docker label is reserved: ${key}`);\n }\n if (options.user !== undefined) assertNonEmptyString(options.user, \"user\");\n if (options.directories !== undefined && !Array.isArray(options.directories)) {\n throw new TypeError(\"directories must be an array.\");\n }\n for (const directory of options.directories ?? []) {\n if (typeof directory !== \"string\") throw new TypeError(\"directories must contain strings.\");\n normalizeSandboxPath(directory);\n }\n if (options.files !== undefined && !isRecord(options.files)) {\n throw new TypeError(\"files must be an object.\");\n }\n for (const [filePath, content] of Object.entries(options.files ?? {})) {\n normalizeSandboxPath(filePath);\n if (typeof content !== \"string\" && !(content instanceof Uint8Array)) {\n throw new TypeError(`Initial file must be a string or Uint8Array: ${filePath}`);\n }\n const byteLength =\n typeof content === \"string\"\n ? new TextEncoder().encode(content).byteLength\n : content.byteLength;\n const maxFileBytes = options.runtime?.maxFileBytes ?? defaultMaxFileBytes;\n if (byteLength > maxFileBytes) {\n throw new DockerSandboxError(\n `Initial file exceeds maxFileBytes (${byteLength} > ${maxFileBytes}): ${filePath}`,\n \"file_too_large\",\n );\n }\n }\n}\n\nfunction validateRuntimeLimits(runtime?: DockerSandboxRuntimeLimits): void {\n if (runtime !== undefined && !isRecord(runtime)) {\n throw new TypeError(\"runtime must be an object.\");\n }\n if (runtime?.commandTimeoutMs !== undefined)\n assertPositiveSafeInteger(runtime.commandTimeoutMs, \"commandTimeoutMs\");\n if (runtime?.maxOutputBytes !== undefined)\n assertNonNegativeSafeInteger(runtime.maxOutputBytes, \"maxOutputBytes\");\n if (runtime?.maxFileBytes !== undefined)\n assertNonNegativeSafeInteger(runtime.maxFileBytes, \"maxFileBytes\");\n if (runtime?.maxProcesses !== undefined)\n assertNonNegativeSafeInteger(runtime.maxProcesses, \"maxProcesses\");\n}\n\nfunction validateResources(resources: CreateDockerSandboxOptions[\"resources\"]): void {\n if (resources !== undefined && !isRecord(resources)) {\n throw new TypeError(\"resources must be an object.\");\n }\n if (resources?.memoryMb !== undefined) assertPositiveSafeInteger(resources.memoryMb, \"memoryMb\");\n if (resources?.pidsLimit !== undefined)\n assertPositiveSafeInteger(resources.pidsLimit, \"pidsLimit\");\n if (resources?.sharedMemoryMb !== undefined)\n assertPositiveSafeInteger(resources.sharedMemoryMb, \"sharedMemoryMb\");\n if (resources?.cpus !== undefined && (!Number.isFinite(resources.cpus) || resources.cpus <= 0)) {\n throw new RangeError(\"cpus must be a positive finite number.\");\n }\n}\n\nfunction validateSecurity(security: CreateDockerSandboxOptions[\"security\"]): void {\n if (security !== undefined && !isRecord(security)) {\n throw new TypeError(\"security must be an object.\");\n }\n if (security?.dropCapabilities !== undefined && !Array.isArray(security.dropCapabilities)) {\n throw new TypeError(\"dropCapabilities must be an array.\");\n }\n if (security?.addCapabilities !== undefined && !Array.isArray(security.addCapabilities)) {\n throw new TypeError(\"addCapabilities must be an array.\");\n }\n if (security?.readonlyRootfs !== undefined && typeof security.readonlyRootfs !== \"boolean\") {\n throw new TypeError(\"readonlyRootfs must be a boolean.\");\n }\n if (security?.noNewPrivileges !== undefined && typeof security.noNewPrivileges !== \"boolean\") {\n throw new TypeError(\"noNewPrivileges must be a boolean.\");\n }\n if (security?.seccompProfile !== undefined) {\n if (!isRecord(security.seccompProfile) || security.seccompProfile.type !== \"path\") {\n throw new TypeError('seccompProfile must be a { type: \"path\", path } object.');\n }\n assertNonEmptyString(security.seccompProfile.path, \"seccompProfile.path\");\n if (\n !path.isAbsolute(security.seccompProfile.path) ||\n security.seccompProfile.path.includes(\"\\0\")\n ) {\n throw new TypeError(\"seccompProfile.path must be an absolute host path.\");\n }\n }\n const seen = new Set<string>();\n for (const capability of security?.dropCapabilities ?? []) {\n assertNonEmptyString(capability, \"dropCapabilities value\");\n if (seen.has(capability))\n throw new TypeError(`dropCapabilities contains a duplicate: ${capability}`);\n seen.add(capability);\n }\n seen.clear();\n for (const capability of security?.addCapabilities ?? []) {\n assertNonEmptyString(capability, \"addCapabilities value\");\n if (seen.has(capability))\n throw new TypeError(`addCapabilities contains a duplicate: ${capability}`);\n seen.add(capability);\n }\n}\n\nfunction validateExecOptions(options: DockerSandboxExecOptions): void {\n assertOptionsObject(options);\n assertNonEmptyString(options.command, \"command\");\n if (\n options.args !== undefined &&\n (!Array.isArray(options.args) || !options.args.every((value) => typeof value === \"string\"))\n ) {\n throw new TypeError(\"args must contain only strings.\");\n }\n if (options.cwd !== undefined) normalizeSandboxPath(options.cwd, { allowRoot: true });\n copyStringRecord(options.env, \"env\");\n if (options.timeoutMs !== undefined) assertPositiveSafeInteger(options.timeoutMs, \"timeoutMs\");\n if (\n options.input !== undefined &&\n typeof options.input !== \"string\" &&\n !(options.input instanceof Uint8Array)\n ) {\n throw new TypeError(\"input must be a string or Uint8Array.\");\n }\n}\n\nfunction validateProcessStartOptions(options: DockerSandboxProcessStartOptions): void {\n assertOptionsObject(options);\n assertNonEmptyString(options.command, \"command\");\n if (\n options.args !== undefined &&\n (!Array.isArray(options.args) || !options.args.every((value) => typeof value === \"string\"))\n ) {\n throw new TypeError(\"args must contain only strings.\");\n }\n if (options.cwd !== undefined) normalizeSandboxPath(options.cwd, { allowRoot: true });\n copyStringRecord(options.env, \"env\");\n}\n\nfunction assertReadOptions(options: DockerSandboxReadFileOptions): void {\n assertOptionsObject(options);\n normalizeSandboxPath(options.path);\n}\n\nfunction assertOptionsObject(value: unknown): asserts value is Record<string, unknown> {\n if (!isRecord(value)) throw new TypeError(\"options must be an object.\");\n}\n\nfunction resolveRuntimeLimits(runtime?: DockerSandboxRuntimeLimits): ResolvedRuntimeLimits {\n return {\n commandTimeoutMs: runtime?.commandTimeoutMs ?? defaultCommandTimeoutMs,\n maxOutputBytes: runtime?.maxOutputBytes ?? defaultMaxOutputBytes,\n maxFileBytes: runtime?.maxFileBytes ?? defaultMaxFileBytes,\n maxProcesses: runtime?.maxProcesses ?? defaultMaxProcesses,\n };\n}\n\nfunction snapshotCreateOptions(options: CreateDockerSandboxOptions): CreateDockerSandboxOptions {\n const files: Record<string, string | Uint8Array> = {};\n for (const [filePath, content] of Object.entries(options.files ?? {})) {\n files[filePath] = typeof content === \"string\" ? content : content.slice();\n }\n const workspace = copyWorkspace(options.workspace);\n const network = copyNetwork(options.network);\n let snapshot: CreateDockerSandboxOptions = {\n image: options.image,\n workspace,\n network,\n };\n if (options.id !== undefined) snapshot = { ...snapshot, id: options.id };\n if (options.workdir !== undefined) snapshot = { ...snapshot, workdir: options.workdir };\n if (options.files !== undefined) snapshot = { ...snapshot, files: Object.freeze(files) };\n if (options.directories !== undefined) {\n snapshot = { ...snapshot, directories: Object.freeze([...options.directories]) };\n }\n if (options.env !== undefined) {\n snapshot = { ...snapshot, env: Object.freeze({ ...options.env }) };\n }\n if (options.user !== undefined) snapshot = { ...snapshot, user: options.user };\n if (options.labels !== undefined) {\n snapshot = { ...snapshot, labels: Object.freeze({ ...options.labels }) };\n }\n if (options.resources !== undefined) {\n snapshot = { ...snapshot, resources: Object.freeze({ ...options.resources }) };\n }\n if (options.runtime !== undefined) {\n snapshot = { ...snapshot, runtime: Object.freeze({ ...options.runtime }) };\n }\n if (options.security !== undefined) {\n let security: NonNullable<CreateDockerSandboxOptions[\"security\"]> = {\n ...options.security,\n };\n if (options.security.seccompProfile !== undefined) {\n security = {\n ...security,\n seccompProfile: Object.freeze({ ...options.security.seccompProfile }),\n };\n }\n if (options.security.dropCapabilities !== undefined) {\n security = {\n ...security,\n dropCapabilities: Object.freeze([...options.security.dropCapabilities]),\n };\n }\n if (options.security.addCapabilities !== undefined) {\n security = {\n ...security,\n addCapabilities: Object.freeze([...options.security.addCapabilities]),\n };\n }\n snapshot = { ...snapshot, security: Object.freeze(security) };\n }\n if (options.abortSignal !== undefined) {\n snapshot = { ...snapshot, abortSignal: options.abortSignal };\n }\n return Object.freeze(snapshot);\n}\n\nfunction configurationFromInspection(\n id: string,\n containerName: string,\n inspection: DockerContainerInspection,\n): SandboxConfiguration {\n const containerLabels = inspection.Config.Labels ?? {};\n if (containerLabels[labels.schema] !== schemaVersion || containerLabels[labels.id] !== id) {\n throw new DockerSandboxError(\n `Container is not an Anvia sandbox: ${containerName}`,\n \"sandbox_not_found\",\n );\n }\n const workdir = requiredLabel(containerLabels, labels.workdir);\n const workspaceType = requiredLabel(containerLabels, labels.workspaceType);\n const volumeName = requiredLabel(containerLabels, labels.workspaceVolume);\n const networkMode = requiredLabel(containerLabels, labels.networkMode);\n if (networkMode !== \"none\" && networkMode !== \"bridge\") invalidInspection(\"network mode\");\n const workspace: DockerSandboxWorkspace =\n workspaceType === \"ephemeral\"\n ? { type: \"ephemeral\" }\n : workspaceType === \"docker-volume\"\n ? { type: \"docker-volume\", name: volumeName }\n : invalidInspection(\"workspace type\");\n const runtime = {\n commandTimeoutMs: parseLabelInteger(containerLabels, labels.commandTimeoutMs, true),\n maxOutputBytes: parseLabelInteger(containerLabels, labels.maxOutputBytes, false),\n maxFileBytes: parseLabelInteger(containerLabels, labels.maxFileBytes, false),\n maxProcesses: parseLabelInteger(containerLabels, labels.maxProcesses, false),\n };\n return {\n id,\n containerName,\n workdir,\n workspace,\n volumeName,\n ownsVolume: workspace.type === \"ephemeral\",\n env: {},\n runtime,\n publishedPorts: [],\n };\n}\n\ntype DockerContainerInspection = {\n Config: { Labels?: Record<string, string>; WorkingDir?: string };\n HostConfig?: {\n PortBindings?: Record<string, Array<{ HostIp?: string; HostPort?: string }> | null>;\n };\n State: { Running?: boolean; Paused?: boolean; Dead?: boolean; Status?: string };\n NetworkSettings?: {\n Ports?: Record<string, Array<{ HostIp?: string; HostPort?: string }> | null>;\n };\n};\n\nasync function inspectContainer(\n dockerPath: string,\n containerName: string,\n abortSignal: AbortSignal | undefined,\n notFoundAsSandboxError: boolean,\n): Promise<DockerContainerInspection> {\n const result = await runDockerCli([\"container\", \"inspect\", containerName], {\n dockerPath,\n signal: abortSignal,\n });\n if (result.exitCode !== 0) {\n const message = safeDecode(result.stderr);\n if (notFoundAsSandboxError && message.toLowerCase().includes(\"no such\")) {\n throw new DockerSandboxError(`Sandbox does not exist: ${containerName}`, \"sandbox_not_found\");\n }\n throw new DockerSandboxError(\n \"Unable to inspect Docker sandbox.\",\n \"docker_command_failed\",\n result,\n );\n }\n let value: unknown;\n try {\n value = JSON.parse(decodeUtf8(result.stdout));\n } catch (error) {\n throw new DockerSandboxError(\n \"Docker returned invalid container metadata.\",\n \"docker_command_failed\",\n undefined,\n { cause: error },\n );\n }\n if (!Array.isArray(value) || value.length !== 1 || !isInspection(value[0])) {\n throw new DockerSandboxError(\n \"Docker returned invalid container metadata.\",\n \"docker_command_failed\",\n );\n }\n return value[0];\n}\n\nfunction isInspection(value: unknown): value is DockerContainerInspection {\n return isRecord(value) && isRecord(value.Config) && isRecord(value.State);\n}\n\nasync function inspectPublishedPorts(options: {\n dockerPath: string;\n containerName: string;\n ports: readonly number[];\n abortSignal?: AbortSignal | undefined;\n}): Promise<DockerSandboxPublishedPort[]> {\n if (options.ports.length === 0) return [];\n const inspection = await inspectContainer(\n options.dockerPath,\n options.containerName,\n options.abortSignal,\n false,\n );\n const mappings = inspection.NetworkSettings?.Ports ?? {};\n return options.ports.map((containerPort) => {\n const entries = mappings[`${containerPort}/tcp`];\n const entry = entries?.find((candidate) => candidate.HostIp === \"127.0.0.1\");\n const hostPort = Number(entry?.HostPort);\n if (!isPort(hostPort)) {\n throw new DockerSandboxError(`Docker did not publish port: ${containerPort}`, \"port\");\n }\n return { containerPort, host: \"127.0.0.1\", hostPort, protocol: \"tcp\" };\n });\n}\n\nfunction configuredContainerPorts(inspection: DockerContainerInspection): number[] {\n return Object.keys(inspection.HostConfig?.PortBindings ?? {}).flatMap((key) => {\n const match = /^(\\d+)\\/tcp$/.exec(key);\n if (match?.[1] === undefined) return [];\n const value = Number(match[1]);\n return isPort(value) ? [value] : [];\n });\n}\n\nasync function assertCopiedRegularFile(\n temporaryDirectory: string,\n target: string,\n sandboxPath: string,\n): Promise<void> {\n const metadata = await lstat(target);\n if (metadata.isSymbolicLink() || !metadata.isFile()) {\n throw new DockerSandboxError(\n `Sandbox path is not a regular file: ${sandboxPath}`,\n \"invalid_path\",\n );\n }\n const resolvedTarget = await realpath(target);\n const relativeTarget = path.relative(temporaryDirectory, resolvedTarget);\n if (\n relativeTarget === \"\" ||\n relativeTarget === \"..\" ||\n relativeTarget.startsWith(`..${path.sep}`) ||\n path.isAbsolute(relativeTarget)\n ) {\n throw new DockerSandboxError(\n `Sandbox file escaped its temporary read boundary: ${sandboxPath}`,\n \"invalid_path\",\n );\n }\n}\n\nasync function removeContainer(dockerPath: string, containerName: string): Promise<void> {\n const result = await runDockerCli([\"rm\", \"-f\", containerName], { dockerPath });\n if (result.exitCode === 0 || safeDecode(result.stderr).toLowerCase().includes(\"no such\")) return;\n throw new DockerSandboxError(\"Unable to remove Docker sandbox.\", \"docker_command_failed\", result);\n}\n\nasync function removeVolume(dockerPath: string, volumeName: string): Promise<void> {\n const result = await runDockerCli([\"volume\", \"rm\", volumeName], { dockerPath });\n if (result.exitCode === 0 || safeDecode(result.stderr).toLowerCase().includes(\"no such\")) return;\n throw new DockerSandboxError(\n \"Unable to remove Docker sandbox volume.\",\n \"docker_command_failed\",\n result,\n );\n}\n\nfunction parseFindEntry(line: string, workdir: string): DockerSandboxFileEntry {\n const [absolutePath, rawType, rawSize] = line.split(\"\\t\");\n if (absolutePath === undefined || rawType === undefined || rawSize === undefined) {\n throw new DockerSandboxError(\"Docker returned invalid file metadata.\", \"docker_command_failed\");\n }\n const relativePath = path.posix.relative(workdir, absolutePath);\n const size = Number(rawSize);\n const type = mapFindType(rawType);\n let entry: DockerSandboxFileEntry = {\n path: normalizeSandboxPath(relativePath),\n type,\n };\n if (type === \"file\" && Number.isSafeInteger(size) && size >= 0) {\n entry = { ...entry, size };\n }\n return entry;\n}\n\nfunction mapFindType(value: string): DockerSandboxFileType {\n if (value === \"f\") return \"file\";\n if (value === \"d\") return \"directory\";\n if (value === \"l\") return \"symlink\";\n return \"other\";\n}\n\nfunction toExecResult(result: Awaited<ReturnType<typeof runDockerCli>>): DockerSandboxExecResult {\n const common = {\n stdout: result.stdout.slice(),\n stderr: result.stderr.slice(),\n durationMs: result.durationMs,\n stdoutTruncated: result.stdoutTruncated,\n stderrTruncated: result.stderrTruncated,\n };\n return result.timedOut\n ? { ...common, status: \"timed_out\" }\n : { ...common, status: \"exited\", exitCode: result.exitCode };\n}\n\nfunction copyWorkspace(workspace: DockerSandboxWorkspace): DockerSandboxWorkspace {\n return workspace.type === \"ephemeral\"\n ? Object.freeze({ type: \"ephemeral\" })\n : Object.freeze({ type: \"docker-volume\", name: workspace.name });\n}\n\nfunction copyNetwork(\n network: CreateDockerSandboxOptions[\"network\"],\n): CreateDockerSandboxOptions[\"network\"] {\n return network.mode === \"none\"\n ? Object.freeze({ mode: \"none\" })\n : Object.freeze({ mode: \"bridge\", ports: Object.freeze([...(network.ports ?? [])]) });\n}\n\nfunction copyStringRecord(\n value: Readonly<Record<string, string>> | undefined,\n name: string,\n): Record<string, string> {\n if (value === undefined) return {};\n if (!isRecord(value)) throw new TypeError(`${name} must be an object.`);\n const copy: Record<string, string> = {};\n for (const [key, item] of Object.entries(value)) {\n if (typeof item !== \"string\") throw new TypeError(`${name}.${key} must be a string.`);\n if (name === \"env\" && !envKeyPattern.test(key))\n throw new TypeError(`Invalid environment variable name: ${key}`);\n copy[key] = item;\n }\n return copy;\n}\n\nfunction requiredLabel(containerLabels: Record<string, string>, name: string): string {\n const value = containerLabels[name];\n if (value === undefined || value.length === 0) invalidInspection(name);\n return value;\n}\n\nfunction parseLabelInteger(\n containerLabels: Record<string, string>,\n name: string,\n positive: boolean,\n): number {\n const value = Number(requiredLabel(containerLabels, name));\n if (!Number.isSafeInteger(value) || (positive ? value <= 0 : value < 0)) invalidInspection(name);\n return value;\n}\n\nfunction invalidInspection(field: string): never {\n throw new DockerSandboxError(`Sandbox metadata is invalid: ${field}`, \"invalid_state\");\n}\n\nfunction validatePorts(ports: readonly number[]): void {\n if (!Array.isArray(ports)) throw new TypeError(\"ports must be an array.\");\n const seen = new Set<number>();\n for (const port of ports) {\n assertPort(port);\n if (seen.has(port)) throw new DockerSandboxError(`Sandbox port is duplicated: ${port}`, \"port\");\n seen.add(port);\n }\n}\n\nfunction assertPort(port: number): void {\n if (!isPort(port))\n throw new DockerSandboxError(\n `Sandbox port must be an integer from 1 to 65535: ${port}`,\n \"port\",\n );\n}\n\nfunction isPort(port: number): boolean {\n return Number.isInteger(port) && port >= 1 && port <= 65_535;\n}\n\nfunction assertSandboxId(id: string): void {\n if (typeof id !== \"string\" || !idPattern.test(id)) {\n throw new TypeError(\n \"Sandbox id must be 1-63 lowercase letters, numbers, dots, underscores, or hyphens.\",\n );\n }\n}\n\nfunction assertDockerVolumeName(name: string): void {\n assertNonEmptyString(name, \"workspace.name\");\n if (name.includes(\",\") || name.includes(\"\\0\"))\n throw new TypeError(\"workspace.name is not a valid Docker volume name.\");\n}\n\nfunction assertNonEmptyString(value: unknown, name: string): asserts value is string {\n if (typeof value !== \"string\" || value.length === 0)\n throw new TypeError(`${name} must be a non-empty string.`);\n}\n\nfunction assertPositiveSafeInteger(value: number, name: string): void {\n if (!Number.isSafeInteger(value) || value <= 0)\n throw new RangeError(`${name} must be a positive safe integer.`);\n}\n\nfunction assertNonNegativeSafeInteger(value: number, name: string): void {\n if (!Number.isSafeInteger(value) || value < 0)\n throw new RangeError(`${name} must be a non-negative safe integer.`);\n}\n\nfunction invalidState(id: string, state: DockerSandboxState): DockerSandboxError {\n return new DockerSandboxError(`Sandbox ${id} is not running (${state}).`, \"invalid_state\", {\n state,\n });\n}\n\nfunction containerNameFor(id: string): string {\n return `anvia-sandbox-${id}`;\n}\n\nfunction combineSignals(first: AbortSignal | undefined, second: AbortSignal): AbortSignal {\n return first === undefined ? second : AbortSignal.any([first, second]);\n}\n\nasync function waitWithSignal(timeoutMs: number, abortSignal: AbortSignal): Promise<void> {\n abortSignal.throwIfAborted();\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n abortSignal.removeEventListener(\"abort\", abort);\n resolve();\n }, timeoutMs);\n const abort = () => {\n clearTimeout(timeout);\n reject(abortSignal.reason ?? new DOMException(\"Aborted\", \"AbortError\"));\n };\n abortSignal.addEventListener(\"abort\", abort, { once: true });\n });\n}\n\nfunction safeDecode(bytes: Uint8Array): string {\n try {\n return decodeUtf8(bytes);\n } catch {\n return \"\";\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n","import { type ChildProcessWithoutNullStreams, spawn } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport { decodeUtf8, runDockerCli } from \"./docker-cli\";\nimport { DockerSandboxError } from \"./errors\";\nimport { containerPath } from \"./path\";\nimport type {\n DockerSandboxProcessInfo,\n DockerSandboxProcessLogs,\n DockerSandboxProcessStartOptions,\n} from \"./types\";\n\nconst processMarkerPrefix = \"ANVIA_PROCESS\";\n// Establish a killable process group and report it before starting the user command. The wrapper\n// waits for a host acknowledgement, so cancelling startup before the marker is accepted can only\n// leave an idle wrapper that exits when Docker closes stdin, never an untracked user process.\nconst processLauncher = [\n 'wrapper=\"$1\"',\n \"shift\",\n // GNU setsid forks when it is already a process-group leader. `-w` keeps that launcher alive\n // until the new session exits, so Docker does not detach from a still-running managed process.\n \"if command -v setsid >/dev/null 2>&1 && setsid -w true >/dev/null 2>&1; then\",\n ' exec setsid -w sh -c \"$wrapper\" \"$@\"',\n \"fi\",\n 'exec sh -c \"$wrapper\" \"$@\"',\n].join(\"\\n\");\n\nconst processWrapper = [\n 'marker=\"$1\"',\n \"shift\",\n \"group=$$\",\n `printf '\\\\036%s:%s:%s\\\\036' \"$marker\" \"$$\" \"$group\"`,\n \"IFS= read -r ready || exit 125\",\n '[ \"$ready\" = \"start\" ] || exit 125',\n '\"$@\" &',\n \"child=$!\",\n \"terminate() {\",\n ' wait \"$child\" 2>/dev/null || true',\n \" exit 143\",\n \"}\",\n \"trap terminate TERM INT\",\n 'wait \"$child\"',\n \"exit $?\",\n].join(\"\\n\");\n\ninterface DockerProcessManagerOptions {\n containerName: string;\n dockerPath: string;\n workdir: string;\n env: Record<string, string>;\n maxOutputBytes: number;\n maxProcesses: number;\n startupTimeoutMs: number;\n}\n\ntype MutableProcessInfo = {\n id: string;\n command: string;\n args: string[];\n cwd?: string;\n status: \"running\" | \"exited\" | \"stopped\";\n exitCode?: number;\n startedAt: string;\n endedAt?: string;\n};\n\ninterface ManagedProcessRecord {\n info: MutableProcessInfo;\n child: ChildProcessWithoutNullStreams;\n stdout: TailOutputCollector;\n stderr: TailOutputCollector;\n markerStart: Buffer;\n markerBuffer: Buffer;\n supervisorPid?: number;\n processGroupId?: number;\n spawnFailed: boolean;\n stopRequested: boolean;\n startResolved: boolean;\n resolveStarted: () => void;\n rejectStarted: (error: unknown) => void;\n started: Promise<void>;\n resolveClosed: () => void;\n closed: Promise<void>;\n}\n\nexport class DockerProcessManager {\n private readonly records = new Map<string, ManagedProcessRecord>();\n private disposed = false;\n\n constructor(private readonly options: DockerProcessManagerOptions) {\n if (!Number.isInteger(options.maxProcesses) || options.maxProcesses < 0) {\n throw processError(\"Sandbox maxProcesses must be a non-negative integer.\");\n }\n if (!Number.isInteger(options.maxOutputBytes) || options.maxOutputBytes < 0) {\n throw processError(\"Sandbox maxOutputBytes must be a non-negative integer.\");\n }\n if (!Number.isInteger(options.startupTimeoutMs) || options.startupTimeoutMs <= 0) {\n throw processError(\"Sandbox process startup timeout must be a positive integer.\");\n }\n }\n\n async start(options: DockerSandboxProcessStartOptions): Promise<DockerSandboxProcessInfo> {\n this.assertActive();\n assertStartOptions(options);\n options.abortSignal?.throwIfAborted();\n await this.pruneCompletedRecords(options.abortSignal);\n\n const trackedCount = this.records.size;\n if (trackedCount >= this.options.maxProcesses) {\n throw processError(\n `Sandbox process limit reached (${trackedCount} >= ${this.options.maxProcesses}).`,\n );\n }\n\n const id = randomUUID();\n const marker = `${processMarkerPrefix}:${id}`;\n const dockerArgs = this.createExecArgs(options, marker);\n const child = spawn(this.options.dockerPath, dockerArgs, {\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n\n let resolveStarted!: () => void;\n let rejectStarted!: (error: unknown) => void;\n const started = new Promise<void>((resolve, reject) => {\n resolveStarted = resolve;\n rejectStarted = reject;\n });\n let resolveClosed!: () => void;\n const closed = new Promise<void>((resolve) => {\n resolveClosed = resolve;\n });\n\n const info: MutableProcessInfo = {\n id,\n command: options.command,\n args: [...(options.args ?? [])],\n status: \"running\",\n startedAt: new Date().toISOString(),\n };\n if (options.cwd !== undefined) info.cwd = options.cwd;\n\n const record: ManagedProcessRecord = {\n info,\n child,\n stdout: new TailOutputCollector(this.options.maxOutputBytes),\n stderr: new TailOutputCollector(this.options.maxOutputBytes),\n markerStart: Buffer.from(`\\u001e${marker}:`),\n markerBuffer: Buffer.alloc(0),\n spawnFailed: false,\n stopRequested: false,\n startResolved: false,\n resolveStarted,\n rejectStarted,\n started,\n resolveClosed,\n closed,\n };\n this.records.set(id, record);\n this.observe(record);\n\n try {\n await this.waitForStart(record, options.abortSignal);\n record.startResolved = true;\n return copyProcessInfo(record.info);\n } catch (error) {\n if (await this.cleanupFailedStart(record)) this.records.delete(id);\n throw error;\n }\n }\n\n list(): DockerSandboxProcessInfo[] {\n this.assertActive();\n return [...this.records.values()].map((record) => copyProcessInfo(record.info));\n }\n\n logs(processId: string, tailBytes?: number): DockerSandboxProcessLogs {\n this.assertActive();\n const record = this.getRecord(processId);\n const stdout = record.stdout.snapshot(tailBytes);\n const stderr = record.stderr.snapshot(tailBytes);\n return {\n stdout: stdout.bytes,\n stderr: stderr.bytes,\n stdoutTruncated: stdout.truncated,\n stderrTruncated: stderr.truncated,\n };\n }\n\n async stop(\n processId: string,\n gracePeriodMs = 5_000,\n abortSignal?: AbortSignal,\n ): Promise<DockerSandboxProcessInfo> {\n this.assertActive();\n const record = this.getRecord(processId);\n if (!Number.isInteger(gracePeriodMs) || gracePeriodMs < 0) {\n throw processError(\"Process gracePeriodMs must be a non-negative integer.\");\n }\n\n try {\n if (!(await this.terminateRecord(record, gracePeriodMs, abortSignal))) {\n throw processError(`Sandbox process did not stop: ${processId}`);\n }\n } catch (error) {\n if (record.info.status === \"running\") record.stopRequested = false;\n throw error;\n }\n\n return copyProcessInfo(record.info);\n }\n\n async dispose(abortSignal?: AbortSignal): Promise<void> {\n if (this.disposed) return;\n abortSignal?.throwIfAborted();\n\n await Promise.all(\n [...this.records.values()].map(async (record) => {\n if (!(await this.terminateRecord(record, 1_000, abortSignal))) {\n throw processError(`Sandbox process did not stop: ${record.info.id}`);\n }\n }),\n );\n this.disposed = true;\n }\n\n private createExecArgs(options: DockerSandboxProcessStartOptions, marker: string): string[] {\n const args = [\"exec\", \"-i\", \"-w\", containerPath(this.options.workdir, options.cwd ?? \".\")];\n for (const [key, value] of Object.entries({ ...this.options.env, ...options.env })) {\n args.push(\"-e\", `${key}=${value}`);\n }\n args.push(\n this.options.containerName,\n \"sh\",\n \"-c\",\n processLauncher,\n \"anvia-process-launcher\",\n processWrapper,\n \"anvia-managed-process\",\n marker,\n options.command,\n ...(options.args ?? []),\n );\n return args;\n }\n\n private observe(record: ManagedProcessRecord): void {\n record.child.stdout.on(\"data\", (chunk: Buffer) => this.acceptStdout(record, chunk));\n record.child.stderr.on(\"data\", (chunk: Buffer) => record.stderr.accept(chunk));\n\n record.child.on(\"error\", (error) => {\n record.spawnFailed = true;\n const normalized =\n (error as NodeJS.ErrnoException).code === \"ENOENT\"\n ? new DockerSandboxError(\"Docker CLI was not found.\", \"docker_unavailable\", undefined, {\n cause: error,\n })\n : error;\n record.rejectStarted(normalized);\n });\n\n record.child.on(\"close\", (code) => {\n if (record.markerBuffer.length > 0) {\n record.stdout.accept(record.markerBuffer);\n record.markerBuffer = Buffer.alloc(0);\n }\n record.info.status = record.stopRequested ? \"stopped\" : \"exited\";\n record.info.exitCode = code ?? 1;\n record.info.endedAt = new Date().toISOString();\n record.rejectStarted(\n processError(`Sandbox process exited before startup completed: ${record.info.id}`),\n );\n record.resolveClosed();\n });\n }\n\n private acceptStdout(record: ManagedProcessRecord, chunk: Buffer): void {\n if (record.supervisorPid !== undefined) {\n record.stdout.accept(chunk);\n return;\n }\n\n record.markerBuffer = Buffer.concat([record.markerBuffer, chunk]);\n const start = record.markerBuffer.indexOf(record.markerStart);\n if (start < 0) {\n const retainedBytes = Math.max(0, record.markerStart.length - 1);\n if (record.markerBuffer.length > retainedBytes) {\n const split = record.markerBuffer.length - retainedBytes;\n record.stdout.accept(record.markerBuffer.subarray(0, split));\n record.markerBuffer = record.markerBuffer.subarray(split);\n }\n return;\n }\n\n const end = record.markerBuffer.indexOf(0x1e, start + record.markerStart.length);\n if (end < 0) {\n if (start > 0) {\n record.stdout.accept(record.markerBuffer.subarray(0, start));\n record.markerBuffer = record.markerBuffer.subarray(start);\n }\n return;\n }\n\n const rawPids = decodeUtf8(\n record.markerBuffer.subarray(start + record.markerStart.length, end),\n ).split(\":\");\n const supervisorPid = Number(rawPids[0]);\n const processGroupId = Number(rawPids[1]);\n if (!isProcessId(supervisorPid) || !isProcessId(processGroupId) || rawPids.length !== 2) {\n record.rejectStarted(processError(\"Sandbox process returned invalid process IDs.\"));\n return;\n }\n\n if (start > 0) record.stdout.accept(record.markerBuffer.subarray(0, start));\n if (end + 1 < record.markerBuffer.length) {\n record.stdout.accept(record.markerBuffer.subarray(end + 1));\n }\n record.markerBuffer = Buffer.alloc(0);\n record.supervisorPid = supervisorPid;\n record.processGroupId = processGroupId;\n // Keep stdin attached for the lifetime of `docker exec -i`. Closing it makes the Docker CLI\n // return successfully while the in-container process keeps running, which would orphan the\n // process from status, logs, and lifecycle management.\n record.child.stdin.write(\"start\\n\");\n record.resolveStarted();\n }\n\n private async waitForStart(\n record: ManagedProcessRecord,\n abortSignal: AbortSignal | undefined,\n ): Promise<void> {\n let timeout: ReturnType<typeof setTimeout> | undefined;\n let abort: (() => void) | undefined;\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeout = setTimeout(() => {\n reject(new DockerSandboxError(\"Starting sandbox process timed out.\", \"timeout\"));\n }, this.options.startupTimeoutMs);\n timeout.unref?.();\n });\n\n try {\n const abortPromise = new Promise<never>((_, reject) => {\n if (abortSignal === undefined) return;\n abort = () => reject(abortSignal.reason ?? new DOMException(\"Aborted\", \"AbortError\"));\n if (abortSignal.aborted) abort();\n else abortSignal.addEventListener(\"abort\", abort, { once: true });\n });\n await Promise.race([record.started, timeoutPromise, abortPromise]);\n } finally {\n if (timeout !== undefined) clearTimeout(timeout);\n if (abort !== undefined) abortSignal?.removeEventListener(\"abort\", abort);\n }\n }\n\n private async cleanupFailedStart(record: ManagedProcessRecord): Promise<boolean> {\n record.stopRequested = true;\n if (record.processGroupId === undefined && record.info.status === \"running\") {\n record.child.stdin.destroy();\n record.child.kill(\"SIGKILL\");\n await waitForPromise(record.closed, 1_000);\n }\n\n try {\n return await this.terminateRecord(record, 1_000);\n } catch {\n return false;\n }\n }\n\n private async terminateRecord(\n record: ManagedProcessRecord,\n gracePeriodMs: number,\n abortSignal?: AbortSignal,\n ): Promise<boolean> {\n abortSignal?.throwIfAborted();\n record.stopRequested = true;\n\n if (record.processGroupId === undefined) {\n if (record.info.status === \"running\") {\n await waitForPromise(record.closed, Math.min(gracePeriodMs, 250), abortSignal);\n }\n if (record.processGroupId === undefined) {\n return record.info.status !== \"running\";\n }\n }\n\n if (!(await this.isProcessGroupRunning(record, abortSignal))) {\n return this.finishAfterGroupExit(record, abortSignal);\n }\n\n await this.signal(record, \"TERM\", abortSignal);\n if (await this.waitForRecordExit(record, gracePeriodMs, abortSignal)) return true;\n\n await this.signal(record, \"KILL\", abortSignal);\n if (await this.waitForRecordExit(record, 1_000, abortSignal)) return true;\n\n return false;\n }\n\n private async waitForRecordExit(\n record: ManagedProcessRecord,\n timeoutMs: number,\n abortSignal?: AbortSignal,\n ): Promise<boolean> {\n const deadline = Date.now() + timeoutMs;\n while (true) {\n abortSignal?.throwIfAborted();\n if (!(await this.isProcessGroupRunning(record, abortSignal))) {\n return this.finishAfterGroupExit(record, abortSignal);\n }\n\n const remainingMs = deadline - Date.now();\n if (remainingMs <= 0) return false;\n const intervalMs = Math.min(50, remainingMs);\n if (record.info.status === \"running\") {\n await waitForPromise(record.closed, intervalMs, abortSignal);\n } else {\n await waitForDelay(intervalMs, abortSignal);\n }\n }\n }\n\n private async finishAfterGroupExit(\n record: ManagedProcessRecord,\n abortSignal?: AbortSignal,\n ): Promise<boolean> {\n if (record.info.status !== \"running\") return true;\n record.child.kill(\"SIGKILL\");\n return waitForPromise(record.closed, 1_000, abortSignal);\n }\n\n private async isProcessGroupRunning(\n record: ManagedProcessRecord,\n abortSignal?: AbortSignal,\n ): Promise<boolean> {\n if (record.processGroupId === undefined) return false;\n const result = await runDockerCli(\n [\n \"exec\",\n this.options.containerName,\n \"sh\",\n \"-c\",\n 'kill -0 \"-$1\" 2>/dev/null',\n \"anvia-process-group-check\",\n `${record.processGroupId}`,\n ],\n {\n dockerPath: this.options.dockerPath,\n timeoutMs: 5_000,\n maxOutputBytes: this.options.maxOutputBytes,\n signal: abortSignal,\n },\n );\n return result.exitCode === 0;\n }\n\n private async signal(\n record: ManagedProcessRecord,\n dockerSignal: \"TERM\" | \"KILL\",\n abortSignal?: AbortSignal,\n ): Promise<void> {\n if (record.processGroupId === undefined) return;\n const result = await runDockerCli(\n [\n \"exec\",\n this.options.containerName,\n \"sh\",\n \"-c\",\n 'kill \"-$2\" \"-$1\" 2>/dev/null || ! kill -0 \"-$1\" 2>/dev/null',\n \"anvia-process-signal\",\n `${record.processGroupId}`,\n dockerSignal,\n ],\n {\n dockerPath: this.options.dockerPath,\n timeoutMs: 5_000,\n maxOutputBytes: this.options.maxOutputBytes,\n signal: abortSignal,\n },\n );\n if (result.exitCode !== 0) {\n throw new DockerSandboxError(\n `Unable to stop sandbox process: ${record.info.id}`,\n \"docker_command_failed\",\n result,\n );\n }\n }\n\n private getRecord(processId: string): ManagedProcessRecord {\n const record = this.records.get(processId);\n if (record === undefined) {\n throw processError(`Unknown sandbox process: ${processId}`);\n }\n return record;\n }\n\n private async pruneCompletedRecords(abortSignal?: AbortSignal): Promise<void> {\n for (const [id, record] of this.records) {\n if (this.records.size < this.options.maxProcesses) return;\n const cleanupConfirmed =\n record.processGroupId === undefined\n ? record.spawnFailed\n : !(await this.isProcessGroupRunning(record, abortSignal));\n if (record.info.status !== \"running\" && cleanupConfirmed) {\n this.records.delete(id);\n }\n }\n }\n\n private assertActive(): void {\n if (this.disposed) {\n throw processError(\"Sandbox process manager has been disposed.\");\n }\n }\n}\n\nclass TailOutputCollector {\n private chunks: Buffer[] = [];\n private length = 0;\n private didTruncate = false;\n\n constructor(private readonly maxBytes: number) {}\n\n accept(chunk: Buffer): void {\n if (chunk.length === 0) return;\n if (this.maxBytes <= 0) {\n this.didTruncate = true;\n return;\n }\n\n if (chunk.length >= this.maxBytes) {\n this.chunks = [chunk.subarray(chunk.length - this.maxBytes)];\n this.length = this.maxBytes;\n this.didTruncate = true;\n return;\n }\n\n this.chunks.push(chunk);\n this.length += chunk.length;\n while (this.length > this.maxBytes) {\n const first = this.chunks[0];\n if (first === undefined) break;\n const overflow = this.length - this.maxBytes;\n if (first.length <= overflow) {\n this.chunks.shift();\n this.length -= first.length;\n } else {\n this.chunks[0] = first.subarray(overflow);\n this.length -= overflow;\n }\n this.didTruncate = true;\n }\n }\n\n snapshot(tailBytes?: number): { bytes: Uint8Array; truncated: boolean } {\n if (tailBytes !== undefined && (!Number.isInteger(tailBytes) || tailBytes < 0)) {\n throw processError(\"Process tailBytes must be a non-negative integer.\");\n }\n const bytes = Buffer.concat(this.chunks, this.length);\n const selected =\n tailBytes === 0\n ? Buffer.alloc(0)\n : tailBytes === undefined || bytes.length <= tailBytes\n ? bytes\n : bytes.subarray(bytes.length - tailBytes);\n return {\n bytes: new Uint8Array(selected.buffer, selected.byteOffset, selected.byteLength).slice(),\n truncated: this.didTruncate || selected.length < bytes.length,\n };\n }\n}\n\nfunction processError(message: string): DockerSandboxError {\n return new DockerSandboxError(message, \"process\");\n}\n\nfunction assertStartOptions(options: DockerSandboxProcessStartOptions): void {\n if (options.command.trim().length === 0) {\n throw processError(\"Sandbox process command cannot be empty.\");\n }\n}\n\nfunction isProcessId(value: number): boolean {\n return Number.isSafeInteger(value) && value > 0;\n}\n\nfunction copyProcessInfo(info: DockerSandboxProcessInfo): DockerSandboxProcessInfo {\n let copy: DockerSandboxProcessInfo = {\n id: info.id,\n command: info.command,\n args: [...info.args],\n status: info.status,\n startedAt: info.startedAt,\n };\n if (info.cwd !== undefined) copy = { ...copy, cwd: info.cwd };\n if (info.exitCode !== undefined) copy = { ...copy, exitCode: info.exitCode };\n if (info.endedAt !== undefined) copy = { ...copy, endedAt: info.endedAt };\n return copy;\n}\n\nasync function waitForPromise(\n promise: Promise<void>,\n timeoutMs: number,\n abortSignal?: AbortSignal,\n): Promise<boolean> {\n abortSignal?.throwIfAborted();\n let timeout: ReturnType<typeof setTimeout> | undefined;\n let abort: (() => void) | undefined;\n try {\n return await Promise.race([\n promise.then(() => true),\n new Promise<boolean>((resolve) => {\n timeout = setTimeout(() => resolve(false), timeoutMs);\n timeout.unref?.();\n }),\n new Promise<boolean>((_, reject) => {\n if (abortSignal === undefined) return;\n abort = () => reject(abortSignal.reason ?? new DOMException(\"Aborted\", \"AbortError\"));\n if (abortSignal.aborted) abort();\n else abortSignal.addEventListener(\"abort\", abort, { once: true });\n }),\n ]);\n } finally {\n if (timeout !== undefined) clearTimeout(timeout);\n if (abort !== undefined) abortSignal?.removeEventListener(\"abort\", abort);\n }\n}\n\nasync function waitForDelay(timeoutMs: number, abortSignal?: AbortSignal): Promise<void> {\n await waitForPromise(\n new Promise<void>((resolve) => {\n const timeout = setTimeout(resolve, timeoutMs);\n timeout.unref?.();\n }),\n timeoutMs,\n abortSignal,\n );\n}\n","import path from \"node:path\";\nimport { DockerSandboxError } from \"./errors\";\n\nexport function normalizeSandboxPath(input: string, options: { allowRoot?: boolean } = {}): string {\n if (input.length === 0) {\n throw new DockerSandboxError(\"Sandbox path cannot be empty.\", \"invalid_path\");\n }\n\n if (input.includes(\"\\0\")) {\n throw new DockerSandboxError(\"Sandbox path cannot contain null bytes.\", \"invalid_path\");\n }\n\n const normalized = path.posix.normalize(input.replaceAll(\"\\\\\", \"/\"));\n\n if (path.posix.isAbsolute(normalized)) {\n throw new DockerSandboxError(`Sandbox path must be relative: ${input}`, \"invalid_path\");\n }\n\n if (normalized === \"..\" || normalized.startsWith(\"../\")) {\n throw new DockerSandboxError(\n `Sandbox path cannot leave the workspace: ${input}`,\n \"invalid_path\",\n );\n }\n\n if (normalized === \".\" && options.allowRoot !== true) {\n throw new DockerSandboxError(\n \"Sandbox path must refer to a file or directory inside the workspace.\",\n \"invalid_path\",\n );\n }\n\n return normalized;\n}\n\nexport function containerPath(workdir: string, relativePath: string): string {\n const normalizedWorkdir = path.posix.normalize(workdir);\n const normalizedPath = normalizeSandboxPath(relativePath, { allowRoot: true });\n return normalizedPath === \".\"\n ? normalizedWorkdir\n : path.posix.join(normalizedWorkdir, normalizedPath);\n}\n\nexport function parentSandboxPath(relativePath: string): string {\n const normalized = normalizeSandboxPath(relativePath);\n const parent = path.posix.dirname(normalized);\n return parent === \".\" ? \".\" : parent;\n}\n","import type { DockerSandboxTextFilePage } from \"./types\";\n\ninterface CreateTextFilePageOptions {\n startLine: number;\n lineCount: number;\n maxBytes: number;\n contentStartLine?: number;\n}\n\nexport function createTextFilePage(\n text: string,\n options: CreateTextFilePageOptions,\n): DockerSandboxTextFilePage {\n const contentStartLine = options.contentStartLine ?? 1;\n const relativeStart = Math.max(0, options.startLine - contentStartLine);\n const lines = splitLines(text).slice(relativeStart, relativeStart + options.lineCount + 1);\n const hasMoreLines = lines.length > options.lineCount;\n const selectedLines = lines.slice(0, options.lineCount);\n const selectedContent = selectedLines.join(\"\");\n const selectedBytes = Buffer.from(selectedContent);\n\n if (selectedBytes.byteLength > options.maxBytes) {\n const content = decodeCompleteUtf8(selectedBytes.subarray(0, options.maxBytes));\n const lineBreaks = countLineBreaks(content);\n const endedAtLineBoundary = content.endsWith(\"\\n\");\n return {\n content,\n startLine: options.startLine,\n endLine:\n content.length === 0\n ? null\n : options.startLine + lineBreaks - (endedAtLineBoundary ? 1 : 0),\n nextStartLine: endedAtLineBoundary ? options.startLine + lineBreaks : null,\n truncated: true,\n truncatedBy: \"bytes\",\n };\n }\n\n return {\n content: selectedContent,\n startLine: options.startLine,\n endLine: selectedLines.length === 0 ? null : options.startLine + selectedLines.length - 1,\n nextStartLine: hasMoreLines ? options.startLine + selectedLines.length : null,\n truncated: hasMoreLines,\n truncatedBy: hasMoreLines ? \"lines\" : null,\n };\n}\n\nfunction splitLines(text: string): string[] {\n return text.match(/[^\\n]*\\n|[^\\n]+$/g) ?? [];\n}\n\nfunction countLineBreaks(text: string): number {\n let count = 0;\n for (const character of text) {\n if (character === \"\\n\") count += 1;\n }\n return count;\n}\n\nfunction decodeCompleteUtf8(bytes: Uint8Array): string {\n return new TextDecoder().decode(bytes, { stream: true });\n}\n","import { type AnyTool, createTool } from \"@anvia/core/tool\";\nimport { z } from \"zod\";\nimport { decodeUtf8 } from \"./docker-cli\";\nimport { DockerSandboxError } from \"./errors\";\nimport type {\n CreateDockerSandboxToolsOptions,\n DockerSandboxCommandPolicy,\n DockerSandboxExecOptions,\n DockerSandboxExecResult,\n DockerSandboxProcessInfo,\n DockerSandboxRuntime,\n DockerSandboxToolName,\n} from \"./types\";\n\nconst allToolNames = [\n \"exec_command\",\n \"read_file\",\n \"write_file\",\n \"list_files\",\n \"list_ports\",\n \"start_process\",\n \"list_processes\",\n \"read_process_logs\",\n \"stop_process\",\n \"wait_for_port\",\n] as const satisfies readonly DockerSandboxToolName[];\n\nconst execCommandInput = z.object({\n command: z.string().min(1),\n args: z.array(z.string()).optional(),\n cwd: z.string().optional(),\n env: z.record(z.string(), z.string()).optional(),\n timeoutMs: z.number().int().positive().max(300_000).optional(),\n input: z.string().optional(),\n});\n\nconst execResultOutput = z.discriminatedUnion(\"status\", [\n z.object({\n status: z.literal(\"exited\"),\n exitCode: z.number().int(),\n stdout: z.string(),\n stderr: z.string(),\n durationMs: z.number().nonnegative(),\n stdoutTruncated: z.boolean(),\n stderrTruncated: z.boolean(),\n }),\n z.object({\n status: z.literal(\"timed_out\"),\n stdout: z.string(),\n stderr: z.string(),\n durationMs: z.number().nonnegative(),\n stdoutTruncated: z.boolean(),\n stderrTruncated: z.boolean(),\n }),\n]);\n\nconst readFileInput = z.object({\n path: z.string().min(1),\n startLine: z.number().int().positive().optional(),\n lineCount: z.number().int().positive().max(10_000).optional(),\n});\n\nconst readFileOutput = z.object({\n content: z.string(),\n startLine: z.number().int().positive(),\n endLine: z.number().int().positive().nullable(),\n nextStartLine: z.number().int().positive().nullable(),\n truncated: z.boolean(),\n truncatedBy: z.enum([\"lines\", \"bytes\"]).nullable(),\n});\n\nconst writeFileInput = z.object({\n path: z.string().min(1),\n content: z.string(),\n});\n\nconst writeFileOutput = z.object({\n path: z.string(),\n bytesWritten: z.number().int().nonnegative(),\n});\n\nconst listFilesInput = z.object({ path: z.string().optional() });\nconst fileEntryOutput = z.object({\n path: z.string(),\n type: z.enum([\"file\", \"directory\", \"symlink\", \"other\"]),\n size: z.number().int().nonnegative().optional(),\n});\nconst listFilesOutput = z.object({\n path: z.string(),\n entries: z.array(fileEntryOutput),\n});\n\nconst emptyInput = z.object({});\nconst publishedPortOutput = z.object({\n containerPort: z.number().int(),\n host: z.literal(\"127.0.0.1\"),\n hostPort: z.number().int(),\n protocol: z.literal(\"tcp\"),\n});\nconst listPortsOutput = z.object({ ports: z.array(publishedPortOutput) });\n\nconst startProcessInput = z.object({\n command: z.string().min(1),\n args: z.array(z.string()).optional(),\n cwd: z.string().optional(),\n env: z.record(z.string(), z.string()).optional(),\n});\nconst processInfoOutput = z.object({\n id: z.string(),\n command: z.string(),\n args: z.array(z.string()),\n cwd: z.string().optional(),\n status: z.enum([\"running\", \"exited\", \"stopped\"]),\n exitCode: z.number().int().optional(),\n startedAt: z.string(),\n endedAt: z.string().optional(),\n});\nconst listProcessesOutput = z.object({ processes: z.array(processInfoOutput) });\n\nconst processIdInput = z.object({ processId: z.string().min(1) });\nconst readProcessLogsInput = processIdInput.extend({\n tailBytes: z\n .number()\n .int()\n .nonnegative()\n .max(1024 * 1024)\n .optional(),\n});\nconst processLogsOutput = z.object({\n processId: z.string(),\n stdout: z.string(),\n stderr: z.string(),\n stdoutTruncated: z.boolean(),\n stderrTruncated: z.boolean(),\n});\n\nconst waitForPortInput = z.object({\n containerPort: z.number().int().min(1).max(65_535),\n timeoutMs: z.number().int().positive().max(300_000).optional(),\n});\nconst waitForPortOutput = z.object({ port: publishedPortOutput });\n\nconst defaultReadFileLineCount = 500;\nconst defaultReadFileMaxLineCount = 2_000;\nconst defaultReadFileMaxBytes = 64 * 1024;\nconst maxToolReadFileLines = 10_000;\nconst maxToolBytes = 1024 * 1024;\nconst maxToolTimeoutMs = 300_000;\n\nexport function createDockerSandboxTools(\n options: CreateDockerSandboxToolsOptions,\n): readonly AnyTool[] {\n validateFactoryOptions(options);\n options = snapshotFactoryOptions(options);\n const selected = new Set(options.tools);\n const tools: AnyTool[] = [];\n\n for (const name of options.tools) {\n if (name === \"exec_command\") tools.push(createExecCommandTool(options));\n else if (name === \"read_file\") tools.push(createReadFileTool(options));\n else if (name === \"write_file\") tools.push(createWriteFileTool(options));\n else if (name === \"list_files\") tools.push(createListFilesTool(options.sandbox));\n else if (name === \"list_ports\") tools.push(createListPortsTool(options.sandbox));\n else if (name === \"start_process\") tools.push(createStartProcessTool(options));\n else if (name === \"list_processes\") tools.push(createListProcessesTool(options.sandbox));\n else if (name === \"read_process_logs\") tools.push(createReadProcessLogsTool(options));\n else if (name === \"stop_process\") tools.push(createStopProcessTool(options));\n else if (name === \"wait_for_port\") tools.push(createWaitForPortTool(options));\n }\n\n if (tools.length !== selected.size) {\n throw toolPolicyError(\"Sandbox tool selection contains an unsupported tool name.\");\n }\n return Object.freeze(tools);\n}\n\nfunction createExecCommandTool(options: CreateDockerSandboxToolsOptions): AnyTool {\n return createTool({\n name: \"exec_command\",\n description: \"Run one executable inside the sandbox with structured arguments.\",\n inputSchema: execCommandInput,\n outputSchema: execResultOutput,\n execute: async ({ command, args, cwd, env, timeoutMs, input }, context) => {\n assertCommandAllowed(command, options.exec?.commands);\n const effectiveTimeoutMs = timeoutMs ?? options.exec?.defaultTimeoutMs;\n assertTimeoutAllowed(effectiveTimeoutMs, options.exec?.maxTimeoutMs);\n let execOptions: DockerSandboxExecOptions = {\n command,\n };\n if (args !== undefined) execOptions = { ...execOptions, args };\n if (cwd !== undefined) execOptions = { ...execOptions, cwd };\n if (env !== undefined) execOptions = { ...execOptions, env };\n if (effectiveTimeoutMs !== undefined) {\n execOptions = { ...execOptions, timeoutMs: effectiveTimeoutMs };\n }\n if (input !== undefined) execOptions = { ...execOptions, input };\n if (context.abortSignal !== undefined) {\n execOptions = { ...execOptions, abortSignal: context.abortSignal };\n }\n return serializeExecResult(await options.sandbox.exec(execOptions));\n },\n });\n}\n\nfunction createReadFileTool(options: CreateDockerSandboxToolsOptions): AnyTool {\n const limits = resolveReadFileLimits(options);\n return createTool({\n name: \"read_file\",\n description: \"Read a bounded page of a UTF-8 text file from the sandbox workspace.\",\n inputSchema: readFileInput,\n outputSchema: readFileOutput,\n execute: async ({ path, startLine, lineCount }, context) => {\n const effectiveLineCount = lineCount ?? limits.defaultLineCount;\n if (effectiveLineCount > limits.maxLineCount) {\n throw toolPolicyError(\n `File read line count exceeds policy (${effectiveLineCount} > ${limits.maxLineCount}).`,\n );\n }\n let readOptions: Parameters<typeof options.sandbox.readTextFilePage>[0] = {\n path,\n startLine: startLine ?? 1,\n lineCount: effectiveLineCount,\n maxBytes: limits.maxBytes,\n };\n if (context.abortSignal !== undefined) {\n readOptions = { ...readOptions, abortSignal: context.abortSignal };\n }\n return options.sandbox.readTextFilePage(readOptions);\n },\n });\n}\n\nfunction createWriteFileTool(options: CreateDockerSandboxToolsOptions): AnyTool {\n return createTool({\n name: \"write_file\",\n description: \"Write a complete UTF-8 text file inside the sandbox workspace.\",\n inputSchema: writeFileInput,\n outputSchema: writeFileOutput,\n execute: async ({ path, content }, context) => {\n const bytesWritten = new TextEncoder().encode(content).byteLength;\n const maxBytes = options.writeFile?.maxBytes;\n if (maxBytes !== undefined && bytesWritten > maxBytes) {\n throw toolPolicyError(`File content exceeds policy (${bytesWritten} > ${maxBytes}).`);\n }\n let writeOptions: Parameters<typeof options.sandbox.writeTextFile>[0] = {\n path,\n text: content,\n };\n if (context.abortSignal !== undefined) {\n writeOptions = { ...writeOptions, abortSignal: context.abortSignal };\n }\n await options.sandbox.writeTextFile(writeOptions);\n return { path, bytesWritten };\n },\n });\n}\n\nfunction createListFilesTool(sandbox: DockerSandboxRuntime): AnyTool {\n return createTool({\n name: \"list_files\",\n description: \"List direct children of a directory in the sandbox workspace.\",\n inputSchema: listFilesInput,\n outputSchema: listFilesOutput,\n execute: async ({ path }, context) => {\n let listOptions: Parameters<typeof sandbox.listFiles>[0] = {};\n if (path !== undefined) listOptions = { ...listOptions, path };\n if (context.abortSignal !== undefined) {\n listOptions = { ...listOptions, abortSignal: context.abortSignal };\n }\n return { path: path ?? \".\", entries: [...(await sandbox.listFiles(listOptions))] };\n },\n });\n}\n\nfunction createListPortsTool(sandbox: DockerSandboxRuntime): AnyTool {\n return createTool({\n name: \"list_ports\",\n description: \"List explicitly published localhost TCP ports for the sandbox.\",\n inputSchema: emptyInput,\n outputSchema: listPortsOutput,\n execute: async () => ({ ports: [...sandbox.publishedPorts] }),\n });\n}\n\nfunction createStartProcessTool(options: CreateDockerSandboxToolsOptions): AnyTool {\n return createTool({\n name: \"start_process\",\n description: \"Start a managed long-running process inside the sandbox.\",\n inputSchema: startProcessInput,\n outputSchema: processInfoOutput,\n execute: async ({ command, args, cwd, env }, context) => {\n assertCommandAllowed(command, options.exec?.commands);\n let startOptions: Parameters<typeof options.sandbox.startProcess>[0] = { command };\n if (args !== undefined) startOptions = { ...startOptions, args };\n if (cwd !== undefined) startOptions = { ...startOptions, cwd };\n if (env !== undefined) startOptions = { ...startOptions, env };\n if (context.abortSignal !== undefined) {\n startOptions = { ...startOptions, abortSignal: context.abortSignal };\n }\n return serializeProcessInfo(await options.sandbox.startProcess(startOptions));\n },\n });\n}\n\nfunction createListProcessesTool(sandbox: DockerSandboxRuntime): AnyTool {\n return createTool({\n name: \"list_processes\",\n description: \"List processes managed by this live sandbox handle.\",\n inputSchema: emptyInput,\n outputSchema: listProcessesOutput,\n execute: async (_, context) => ({\n processes: (\n await sandbox.listProcesses(\n context.abortSignal === undefined ? {} : { abortSignal: context.abortSignal },\n )\n ).map(serializeProcessInfo),\n }),\n });\n}\n\nfunction createReadProcessLogsTool(options: CreateDockerSandboxToolsOptions): AnyTool {\n const maxLogBytes = options.process?.maxLogBytes ?? 64 * 1024;\n return createTool({\n name: \"read_process_logs\",\n description: \"Read bounded UTF-8 output from a managed sandbox process.\",\n inputSchema: readProcessLogsInput,\n outputSchema: processLogsOutput,\n execute: async ({ processId, tailBytes }, context) => {\n const effectiveTailBytes = tailBytes ?? maxLogBytes;\n if (effectiveTailBytes > maxLogBytes) {\n throw toolPolicyError(\n `Process log request exceeds policy (${effectiveTailBytes} > ${maxLogBytes}).`,\n );\n }\n let readOptions: Parameters<typeof options.sandbox.readProcessLogs>[0] = {\n processId,\n tailBytes: effectiveTailBytes,\n };\n if (context.abortSignal !== undefined) {\n readOptions = { ...readOptions, abortSignal: context.abortSignal };\n }\n const logs = await options.sandbox.readProcessLogs(readOptions);\n return {\n processId,\n stdout: decodeUtf8(logs.stdout),\n stderr: decodeUtf8(logs.stderr),\n stdoutTruncated: logs.stdoutTruncated,\n stderrTruncated: logs.stderrTruncated,\n };\n },\n });\n}\n\nfunction createStopProcessTool(options: CreateDockerSandboxToolsOptions): AnyTool {\n return createTool({\n name: \"stop_process\",\n description: \"Stop a process managed by this live sandbox handle.\",\n inputSchema: processIdInput,\n outputSchema: processInfoOutput,\n execute: async ({ processId }, context) => {\n let stopOptions: Parameters<typeof options.sandbox.stopProcess>[0] = {\n processId,\n gracePeriodMs: options.process?.stopGracePeriodMs ?? 5_000,\n };\n if (context.abortSignal !== undefined) {\n stopOptions = { ...stopOptions, abortSignal: context.abortSignal };\n }\n return serializeProcessInfo(await options.sandbox.stopProcess(stopOptions));\n },\n });\n}\n\nfunction createWaitForPortTool(options: CreateDockerSandboxToolsOptions): AnyTool {\n return createTool({\n name: \"wait_for_port\",\n description: \"Wait until an explicitly published sandbox TCP port is listening.\",\n inputSchema: waitForPortInput,\n outputSchema: waitForPortOutput,\n execute: async ({ containerPort, timeoutMs }, context) => {\n const effectiveTimeoutMs = timeoutMs ?? options.process?.defaultWaitTimeoutMs ?? 30_000;\n const maxWaitTimeoutMs = options.process?.maxWaitTimeoutMs ?? maxToolTimeoutMs;\n if (effectiveTimeoutMs > maxWaitTimeoutMs) {\n throw toolPolicyError(\n `Port wait timeout exceeds policy (${effectiveTimeoutMs} > ${maxWaitTimeoutMs}).`,\n );\n }\n let waitOptions: Parameters<typeof options.sandbox.waitForPort>[0] = {\n containerPort,\n timeoutMs: effectiveTimeoutMs,\n };\n if (context.abortSignal !== undefined) {\n waitOptions = { ...waitOptions, abortSignal: context.abortSignal };\n }\n return { port: await options.sandbox.waitForPort(waitOptions) };\n },\n });\n}\n\nfunction serializeExecResult(result: DockerSandboxExecResult) {\n const output = {\n status: result.status,\n stdout: decodeUtf8(result.stdout),\n stderr: decodeUtf8(result.stderr),\n durationMs: result.durationMs,\n stdoutTruncated: result.stdoutTruncated,\n stderrTruncated: result.stderrTruncated,\n };\n return result.status === \"exited\"\n ? { ...output, status: \"exited\" as const, exitCode: result.exitCode }\n : { ...output, status: \"timed_out\" as const };\n}\n\nfunction serializeProcessInfo(\n process: DockerSandboxProcessInfo,\n): z.infer<typeof processInfoOutput> {\n let serialized: z.infer<typeof processInfoOutput> = {\n id: process.id,\n command: process.command,\n args: [...process.args],\n status: process.status,\n startedAt: process.startedAt,\n };\n if (process.cwd !== undefined) serialized = { ...serialized, cwd: process.cwd };\n if (process.exitCode !== undefined) serialized = { ...serialized, exitCode: process.exitCode };\n if (process.endedAt !== undefined) serialized = { ...serialized, endedAt: process.endedAt };\n return serialized;\n}\n\nfunction validateFactoryOptions(options: CreateDockerSandboxToolsOptions): void {\n if (!isRecord(options)) {\n throw new TypeError(\"options must be an object.\");\n }\n if (!isDockerSandboxRuntime(options.sandbox)) {\n throw new TypeError(\"sandbox must be a DockerSandboxRuntime.\");\n }\n if (!Array.isArray(options.tools) || options.tools.length === 0) {\n throw new TypeError(\"tools must be a non-empty array.\");\n }\n const known = new Set<string>(allToolNames);\n const seen = new Set<string>();\n for (const name of options.tools as readonly unknown[]) {\n if (typeof name !== \"string\" || !known.has(name)) {\n throw new TypeError(\"tools contains an unsupported sandbox tool name.\");\n }\n if (seen.has(name)) throw new TypeError(`tools contains a duplicate: ${name}`);\n seen.add(name);\n }\n for (const [name, policy] of [\n [\"exec\", options.exec],\n [\"readFile\", options.readFile],\n [\"writeFile\", options.writeFile],\n [\"process\", options.process],\n ] as const) {\n if (policy !== undefined && !isRecord(policy)) {\n throw new TypeError(`${name} must be an object.`);\n }\n }\n validateCommandPolicy(options.exec?.commands);\n assertOptionalPositiveInteger(options.exec?.defaultTimeoutMs, \"exec.defaultTimeoutMs\");\n assertOptionalPositiveInteger(options.exec?.maxTimeoutMs, \"exec.maxTimeoutMs\");\n if (\n (options.exec?.defaultTimeoutMs ?? 0) > maxToolTimeoutMs ||\n (options.exec?.maxTimeoutMs ?? 0) > maxToolTimeoutMs\n ) {\n throw toolPolicyError(`Sandbox tool command timeouts cannot exceed ${maxToolTimeoutMs}.`);\n }\n if (\n options.exec?.defaultTimeoutMs !== undefined &&\n options.exec.maxTimeoutMs !== undefined &&\n options.exec.defaultTimeoutMs > options.exec.maxTimeoutMs\n ) {\n throw toolPolicyError(\"exec.defaultTimeoutMs cannot exceed exec.maxTimeoutMs.\");\n }\n assertOptionalBoundedPositiveInteger(options.readFile?.maxBytes, \"readFile.maxBytes\");\n assertOptionalPositiveInteger(options.readFile?.defaultLineCount, \"readFile.defaultLineCount\");\n assertOptionalPositiveInteger(options.readFile?.maxLineCount, \"readFile.maxLineCount\");\n assertOptionalBoundedNonNegativeInteger(options.writeFile?.maxBytes, \"writeFile.maxBytes\");\n assertOptionalBoundedNonNegativeInteger(options.process?.maxLogBytes, \"process.maxLogBytes\");\n assertOptionalPositiveInteger(\n options.process?.defaultWaitTimeoutMs,\n \"process.defaultWaitTimeoutMs\",\n );\n assertOptionalPositiveInteger(options.process?.maxWaitTimeoutMs, \"process.maxWaitTimeoutMs\");\n assertOptionalNonNegativeInteger(options.process?.stopGracePeriodMs, \"process.stopGracePeriodMs\");\n const defaultWaitTimeoutMs = options.process?.defaultWaitTimeoutMs;\n const maxWaitTimeoutMs = options.process?.maxWaitTimeoutMs ?? maxToolTimeoutMs;\n if (maxWaitTimeoutMs > maxToolTimeoutMs) {\n throw toolPolicyError(`process.maxWaitTimeoutMs cannot exceed ${maxToolTimeoutMs}.`);\n }\n if (defaultWaitTimeoutMs !== undefined && defaultWaitTimeoutMs > maxWaitTimeoutMs) {\n throw toolPolicyError(\"process.defaultWaitTimeoutMs cannot exceed process.maxWaitTimeoutMs.\");\n }\n}\n\nfunction snapshotFactoryOptions(\n options: CreateDockerSandboxToolsOptions,\n): CreateDockerSandboxToolsOptions {\n const toolNames = Object.freeze([...options.tools]) as unknown as readonly [\n DockerSandboxToolName,\n ...DockerSandboxToolName[],\n ];\n const commands =\n options.exec?.commands === undefined\n ? undefined\n : Object.freeze({\n mode: options.exec.commands.mode,\n values: Object.freeze([...options.exec.commands.values]),\n });\n let snapshot: CreateDockerSandboxToolsOptions = {\n sandbox: options.sandbox,\n tools: toolNames,\n };\n if (options.exec !== undefined) {\n let exec = { ...options.exec };\n if (commands !== undefined) exec = { ...exec, commands };\n snapshot = { ...snapshot, exec: Object.freeze(exec) };\n }\n if (options.readFile !== undefined) {\n snapshot = { ...snapshot, readFile: Object.freeze({ ...options.readFile }) };\n }\n if (options.writeFile !== undefined) {\n snapshot = { ...snapshot, writeFile: Object.freeze({ ...options.writeFile }) };\n }\n if (options.process !== undefined) {\n snapshot = { ...snapshot, process: Object.freeze({ ...options.process }) };\n }\n return Object.freeze(snapshot);\n}\n\nfunction validateCommandPolicy(policy: DockerSandboxCommandPolicy | undefined): void {\n if (policy === undefined) return;\n if (!isRecord(policy)) throw toolPolicyError(\"exec.commands must be an object.\");\n if (policy.mode !== \"allow\" && policy.mode !== \"block\") {\n throw toolPolicyError(\"exec.commands must use mode allow or block.\");\n }\n if (!Array.isArray(policy.values))\n throw toolPolicyError(\"exec.commands.values must be an array.\");\n const seen = new Set<string>();\n for (const value of policy.values as readonly unknown[]) {\n if (typeof value !== \"string\" || value.length === 0) {\n throw toolPolicyError(\"exec.commands.values must contain non-empty strings.\");\n }\n if (seen.has(value))\n throw toolPolicyError(`exec.commands.values contains a duplicate: ${value}`);\n seen.add(value);\n }\n}\n\nfunction assertCommandAllowed(\n command: string,\n policy: DockerSandboxCommandPolicy | undefined,\n): void {\n if (policy === undefined) return;\n const included = policy.values.includes(command);\n if ((policy.mode === \"allow\" && !included) || (policy.mode === \"block\" && included)) {\n throw toolPolicyError(`Command is rejected by sandbox tool policy: ${command}`);\n }\n}\n\nfunction assertTimeoutAllowed(timeoutMs: number | undefined, maxTimeoutMs: number | undefined) {\n if (timeoutMs !== undefined && maxTimeoutMs !== undefined && timeoutMs > maxTimeoutMs) {\n throw toolPolicyError(`Command timeout exceeds policy (${timeoutMs} > ${maxTimeoutMs}).`);\n }\n}\n\nfunction resolveReadFileLimits(options: CreateDockerSandboxToolsOptions) {\n const defaultLineCount = options.readFile?.defaultLineCount ?? defaultReadFileLineCount;\n const maxLineCount = options.readFile?.maxLineCount ?? defaultReadFileMaxLineCount;\n const maxBytes = options.readFile?.maxBytes ?? defaultReadFileMaxBytes;\n if (defaultLineCount > maxLineCount) {\n throw toolPolicyError(\"readFile.defaultLineCount cannot exceed readFile.maxLineCount.\");\n }\n if (maxLineCount > maxToolReadFileLines) {\n throw toolPolicyError(`readFile.maxLineCount cannot exceed ${maxToolReadFileLines}.`);\n }\n return { defaultLineCount, maxLineCount, maxBytes };\n}\n\nfunction assertOptionalPositiveInteger(value: number | undefined, name: string): void {\n if (value !== undefined && (!Number.isSafeInteger(value) || value <= 0)) {\n throw toolPolicyError(`${name} must be a positive safe integer.`);\n }\n}\n\nfunction assertOptionalNonNegativeInteger(value: number | undefined, name: string): void {\n if (value !== undefined && (!Number.isSafeInteger(value) || value < 0)) {\n throw toolPolicyError(`${name} must be a non-negative safe integer.`);\n }\n}\n\nfunction assertOptionalBoundedNonNegativeInteger(value: number | undefined, name: string): void {\n assertOptionalNonNegativeInteger(value, name);\n if (value !== undefined && value > maxToolBytes) {\n throw toolPolicyError(`${name} cannot exceed ${maxToolBytes}.`);\n }\n}\n\nfunction assertOptionalBoundedPositiveInteger(value: number | undefined, name: string): void {\n assertOptionalPositiveInteger(value, name);\n if (value !== undefined && value > maxToolBytes) {\n throw toolPolicyError(`${name} cannot exceed ${maxToolBytes}.`);\n }\n}\n\nfunction isDockerSandboxRuntime(value: unknown): value is DockerSandboxRuntime {\n if (!isRecord(value)) return false;\n return (\n typeof value.id === \"string\" &&\n value.provider === \"docker\" &&\n typeof value.workdir === \"string\" &&\n Array.isArray(value.publishedPorts) &&\n [\n \"exec\",\n \"execStream\",\n \"readFile\",\n \"readTextFile\",\n \"readTextFilePage\",\n \"writeFile\",\n \"writeTextFile\",\n \"listFiles\",\n \"startProcess\",\n \"listProcesses\",\n \"readProcessLogs\",\n \"stopProcess\",\n \"waitForPort\",\n ].every((name) => typeof value[name] === \"function\")\n );\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction toolPolicyError(message: string): DockerSandboxError {\n return new DockerSandboxError(message, \"tool_policy\");\n}\n"],"mappings":"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","names":["randomUUID","path","randomUUID","path","path","isRecord"]}
|
|
1
|
+
{"version":3,"sources":["../src/docker-sandbox.ts","../src/docker-process.ts","../src/path.ts","../src/text-file.ts","../src/tools.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { lstat, mkdtemp, readFile, realpath, rm, writeFile } from \"node:fs/promises\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { assertDockerCli, decodeUtf8, runDockerCli } from \"./docker-cli\";\nimport { DockerProcessManager } from \"./docker-process\";\nimport { DockerSandboxError } from \"./errors\";\nimport { containerPath, normalizeSandboxPath, parentSandboxPath } from \"./path\";\nimport { createTextFilePage } from \"./text-file\";\nimport type {\n CreateDockerSandboxOptions,\n DockerSandbox,\n DockerSandboxClientOptions,\n DockerSandboxExecOptions,\n DockerSandboxExecResult,\n DockerSandboxExecStreamEvent,\n DockerSandboxFileEntry,\n DockerSandboxFileType,\n DockerSandboxInspectionOptions,\n DockerSandboxInspector,\n DockerSandboxListFilesOptions,\n DockerSandboxListProcessesOptions,\n DockerSandboxProcessInfo,\n DockerSandboxProcessLogs,\n DockerSandboxProcessStartOptions,\n DockerSandboxPublishedPort,\n DockerSandboxReadFileOptions,\n DockerSandboxReadProcessLogsOptions,\n DockerSandboxReadTextFilePageOptions,\n DockerSandboxRuntime,\n DockerSandboxRuntimeLimits,\n DockerSandboxState,\n DockerSandboxStopProcessOptions,\n DockerSandboxTextFilePage,\n DockerSandboxWaitForPortOptions,\n DockerSandboxWorkspace,\n DockerSandboxWriteFileOptions,\n DockerSandboxWriteTextFileOptions,\n PullDockerImageOptions,\n ResumeDockerSandboxOptions,\n} from \"./types\";\n\nconst schemaVersion = \"1\";\nconst labelPrefix = \"anvia.sandbox.\";\nconst defaultWorkdir = \"/workspace\";\nconst defaultCommandTimeoutMs = 30_000;\nconst defaultMaxOutputBytes = 1024 * 1024;\nconst defaultMaxFileBytes = 10 * 1024 * 1024;\nconst defaultMaxProcesses = 4;\nconst defaultTextFilePageLines = 500;\nconst defaultTextFilePageBytes = 64 * 1024;\nconst defaultPortWaitTimeoutMs = 30_000;\nconst defaultPortWaitIntervalMs = 100;\nconst idPattern = /^[a-z0-9](?:[a-z0-9_.-]{0,62})$/;\nconst envKeyPattern = /^[A-Za-z_][A-Za-z0-9_]*$/;\n\nconst labels = {\n schema: `${labelPrefix}schema`,\n id: `${labelPrefix}id`,\n workdir: `${labelPrefix}workdir`,\n workspaceType: `${labelPrefix}workspace.type`,\n workspaceVolume: `${labelPrefix}workspace.volume`,\n networkMode: `${labelPrefix}network.mode`,\n containerRuntime: `${labelPrefix}container-runtime`,\n commandTimeoutMs: `${labelPrefix}runtime.command-timeout-ms`,\n maxOutputBytes: `${labelPrefix}runtime.max-output-bytes`,\n maxFileBytes: `${labelPrefix}runtime.max-file-bytes`,\n maxProcesses: `${labelPrefix}runtime.max-processes`,\n} as const;\n\nconst portProbeScript = [\n 'port=\"$(printf \\'%04X\\' \"$1\")\"',\n \"for table in /proc/net/tcp /proc/net/tcp6; do\",\n ' [ -r \"$table\" ] || continue',\n \" while read -r _ local _ state _; do\",\n ' case \"$local\" in',\n ' \"00000000:$port\"|\"00000000000000000000000000000000:$port\")',\n ' [ \"$state\" = \"0A\" ] && exit 0',\n \" ;;\",\n \" esac\",\n ' done < \"$table\"',\n \"done\",\n \"exit 1\",\n].join(\"\\n\");\n\ntype ResolvedRuntimeLimits = Required<DockerSandboxRuntimeLimits>;\n\ntype SandboxConfiguration = {\n id: string;\n containerName: string;\n workdir: string;\n containerRuntime: string;\n workspace: DockerSandboxWorkspace;\n volumeName: string;\n ownsVolume: boolean;\n env: Record<string, string>;\n runtime: ResolvedRuntimeLimits;\n publishedPorts: DockerSandboxPublishedPort[];\n};\n\nexport class DockerSandboxClient {\n private readonly dockerPath: string;\n\n constructor(options: DockerSandboxClientOptions = {}) {\n if (!isRecord(options)) throw new TypeError(\"options must be an object.\");\n this.dockerPath = options.dockerPath ?? \"docker\";\n assertNonEmptyString(this.dockerPath, \"dockerPath\");\n }\n\n async pullImage(options: PullDockerImageOptions): Promise<void> {\n if (!isRecord(options)) throw new TypeError(\"options must be an object.\");\n assertNonEmptyString(options.image, \"image\");\n options.abortSignal?.throwIfAborted();\n await assertDockerCli([\"pull\", options.image], this.cliOptions(options.abortSignal));\n }\n\n async createSandbox(options: CreateDockerSandboxOptions): Promise<DockerSandbox> {\n validateCreateOptions(options);\n options = snapshotCreateOptions(options);\n options.abortSignal?.throwIfAborted();\n\n const id = options.id ?? randomUUID();\n assertSandboxId(id);\n const containerName = containerNameFor(id);\n const workdir = options.workdir ?? defaultWorkdir;\n const containerRuntime = options.containerRuntime ?? \"default\";\n const runtime = resolveRuntimeLimits(options.runtime);\n const workspace = copyWorkspace(options.workspace);\n const network = copyNetwork(options.network);\n const env = copyStringRecord(options.env, \"env\");\n const userLabels = copyStringRecord(options.labels, \"labels\");\n const volumeName =\n workspace.type === \"ephemeral\"\n ? `${containerName}-workspace-${randomUUID()}`\n : workspace.name;\n const ownsVolume = workspace.type === \"ephemeral\";\n\n await this.assertContainerDoesNotExist(containerName, options.abortSignal);\n await this.assertImageExists(options.image, options.abortSignal);\n if (workspace.type === \"docker-volume\") {\n await this.assertVolumeExists(workspace.name, options.abortSignal);\n }\n await this.assertRuntimeAvailable(containerRuntime, options.abortSignal);\n\n let containerCreated = false;\n let volumeCreated = false;\n try {\n if (workspace.type === \"ephemeral\") {\n await assertDockerCli(\n [\"volume\", \"create\", \"--label\", `${labels.id}=${id}`, volumeName],\n this.cliOptions(options.abortSignal),\n );\n volumeCreated = true;\n }\n await assertDockerCli(\n createRunArgs({\n id,\n containerName,\n image: options.image,\n workdir,\n containerRuntime,\n workspace,\n volumeName,\n env,\n user: options.user,\n userLabels,\n resources: options.resources,\n runtime,\n security: options.security,\n network,\n }),\n {\n ...this.cliOptions(options.abortSignal),\n timeoutMs: runtime.commandTimeoutMs,\n },\n );\n containerCreated = true;\n\n const publishedPorts = await inspectPublishedPorts({\n dockerPath: this.dockerPath,\n containerName,\n ports: network.mode === \"bridge\" ? [...(network.ports ?? [])] : [],\n abortSignal: options.abortSignal,\n });\n const sandbox = this.createHandle({\n id,\n containerName,\n workdir,\n containerRuntime,\n workspace,\n volumeName,\n ownsVolume,\n env,\n runtime,\n publishedPorts,\n });\n await applyInitialContent(sandbox.runtime, options);\n return sandbox;\n } catch (error) {\n const cleanupErrors: unknown[] = [];\n if (containerCreated) {\n try {\n await removeContainer(this.dockerPath, containerName);\n } catch (cleanupError) {\n cleanupErrors.push(cleanupError);\n }\n }\n if (ownsVolume && volumeCreated) {\n try {\n await removeVolume(this.dockerPath, volumeName);\n } catch (cleanupError) {\n cleanupErrors.push(cleanupError);\n }\n }\n if (cleanupErrors.length > 0) {\n throw new AggregateError([error, ...cleanupErrors], \"Sandbox creation and rollback failed\");\n }\n throw error;\n }\n }\n\n async resumeSandbox(options: ResumeDockerSandboxOptions): Promise<DockerSandbox> {\n if (!isRecord(options)) throw new TypeError(\"options must be an object.\");\n assertSandboxId(options.id);\n options.abortSignal?.throwIfAborted();\n const containerName = containerNameFor(options.id);\n const inspection = await inspectContainer(\n this.dockerPath,\n containerName,\n options.abortSignal,\n true,\n );\n const configuration = configurationFromInspection(options.id, containerName, inspection);\n\n if (inspection.State.Paused === true || inspection.State.Dead === true) {\n throw new DockerSandboxError(\n `Sandbox cannot be resumed from Docker state: ${inspection.State.Status ?? \"unknown\"}`,\n \"invalid_state\",\n );\n }\n if (inspection.State.Running === true) {\n await assertDockerCli([\"stop\", containerName], this.cliOptions(options.abortSignal));\n }\n await assertDockerCli([\"start\", containerName], this.cliOptions(options.abortSignal));\n configuration.publishedPorts = await inspectPublishedPorts({\n dockerPath: this.dockerPath,\n containerName,\n ports: configuredContainerPorts(inspection),\n abortSignal: options.abortSignal,\n });\n return this.createHandle(configuration);\n }\n\n private createHandle(configuration: SandboxConfiguration): DockerSandbox {\n return new DockerSandboxHandle({\n dockerPath: this.dockerPath,\n configuration,\n });\n }\n\n private async assertImageExists(image: string, abortSignal?: AbortSignal): Promise<void> {\n const result = await runDockerCli([\"image\", \"inspect\", image], this.cliOptions(abortSignal));\n if (result.exitCode === 0) return;\n const message = safeDecode(result.stderr);\n if (message.toLowerCase().includes(\"no such image\")) {\n throw new DockerSandboxError(\n `Docker image is not available locally: ${image}`,\n \"image_not_found\",\n );\n }\n throw new DockerSandboxError(\n \"Unable to inspect Docker image.\",\n \"docker_command_failed\",\n result,\n );\n }\n\n private async assertContainerDoesNotExist(\n containerName: string,\n abortSignal?: AbortSignal,\n ): Promise<void> {\n const result = await runDockerCli([\"container\", \"inspect\", containerName], {\n ...this.cliOptions(abortSignal),\n maxOutputBytes: defaultMaxOutputBytes,\n });\n if (result.exitCode === 0) {\n throw new DockerSandboxError(\n `A Docker container already exists for sandbox: ${containerName}`,\n \"invalid_state\",\n );\n }\n if (safeDecode(result.stderr).toLowerCase().includes(\"no such\")) return;\n throw new DockerSandboxError(\n \"Unable to check whether the Docker sandbox already exists.\",\n \"docker_command_failed\",\n result,\n );\n }\n\n private async assertVolumeExists(name: string, abortSignal?: AbortSignal): Promise<void> {\n const result = await runDockerCli([\"volume\", \"inspect\", name], this.cliOptions(abortSignal));\n if (result.exitCode === 0) return;\n const message = safeDecode(result.stderr);\n if (message.toLowerCase().includes(\"no such volume\")) {\n throw new DockerSandboxError(`Docker volume does not exist: ${name}`, \"volume_not_found\");\n }\n throw new DockerSandboxError(\n \"Unable to inspect Docker volume.\",\n \"docker_command_failed\",\n result,\n );\n }\n private async assertRuntimeAvailable(name: string, abortSignal?: AbortSignal): Promise<void> {\n if (name === \"default\") return;\n const result = await runDockerCli([\"info\", \"--format\", \"{{json .Runtimes}}\"], {\n ...this.cliOptions(abortSignal),\n maxOutputBytes: defaultMaxOutputBytes,\n });\n if (result.exitCode !== 0) {\n throw new DockerSandboxError(\n \"Unable to inspect Docker runtimes.\",\n \"docker_command_failed\",\n result,\n );\n }\n let runtimes: unknown;\n try {\n runtimes = JSON.parse(decodeUtf8(result.stdout));\n } catch (error) {\n throw new DockerSandboxError(\n \"Docker returned invalid runtime metadata.\",\n \"docker_command_failed\",\n undefined,\n { cause: error },\n );\n }\n if (!isRecord(runtimes) || !(name in runtimes)) {\n throw new DockerSandboxError(\n `Docker runtime is not registered in the daemon: ${JSON.stringify(name)}. ` +\n `Install the runtime (for gVisor: runsc install) and restart the Docker daemon.`,\n \"runtime_not_found\",\n );\n }\n }\n\n private cliOptions(abortSignal?: AbortSignal) {\n return { dockerPath: this.dockerPath, signal: abortSignal };\n }\n}\n\nclass DockerSandboxHandle implements DockerSandbox {\n readonly id: string;\n readonly runtime: DockerSandboxRuntime;\n\n private currentState: DockerSandboxState = \"running\";\n private readonly dockerPath: string;\n private readonly configuration: SandboxConfiguration;\n private readonly runtimeImpl: DockerSandboxRuntimeImpl;\n private stopPromise: Promise<void> | undefined;\n private destroyPromise: Promise<void> | undefined;\n\n constructor(options: { dockerPath: string; configuration: SandboxConfiguration }) {\n this.dockerPath = options.dockerPath;\n this.configuration = options.configuration;\n this.id = options.configuration.id;\n this.runtimeImpl = new DockerSandboxRuntimeImpl({\n configuration: options.configuration,\n dockerPath: options.dockerPath,\n state: () => this.currentState,\n });\n this.runtime = Object.freeze(this.runtimeImpl.publicRuntime());\n }\n\n get state(): DockerSandboxState {\n return this.currentState;\n }\n\n inspector(options: DockerSandboxInspectionOptions): DockerSandboxInspector {\n if (!isRecord(options)) throw new TypeError(\"options must be an object.\");\n if (options.files !== true && options.ports !== true && options.processes !== true) {\n throw new TypeError(\"Sandbox inspector must enable at least one capability.\");\n }\n let inspector: DockerSandboxInspector = {\n id: this.id,\n provider: \"docker\",\n workdir: this.configuration.workdir,\n containerRuntime: this.configuration.containerRuntime,\n };\n if (options.files === true) {\n inspector = {\n ...inspector,\n listFiles: this.runtime.listFiles.bind(this.runtime),\n readFile: this.runtime.readFile.bind(this.runtime),\n };\n }\n if (options.ports === true) {\n inspector = { ...inspector, publishedPorts: this.runtime.publishedPorts };\n }\n if (options.processes === true) {\n inspector = {\n ...inspector,\n listProcesses: this.runtime.listProcesses.bind(this.runtime),\n readProcessLogs: this.runtime.readProcessLogs.bind(this.runtime),\n };\n }\n return Object.freeze(inspector);\n }\n\n async stop(options: Readonly<{ abortSignal?: AbortSignal }> = {}): Promise<void> {\n if (!isRecord(options)) throw new TypeError(\"options must be an object.\");\n if (this.currentState === \"stopped\") return;\n if (this.currentState === \"destroyed\" || this.currentState === \"destroying\") {\n throw invalidState(this.id, this.currentState);\n }\n if (this.stopPromise !== undefined) return this.stopPromise;\n this.stopPromise = this.performStop(options.abortSignal);\n try {\n await this.stopPromise;\n } finally {\n this.stopPromise = undefined;\n }\n }\n\n private async performStop(abortSignal?: AbortSignal): Promise<void> {\n abortSignal?.throwIfAborted();\n this.currentState = \"stopping\";\n try {\n await this.runtimeImpl.closeActiveOperations(\"Sandbox is stopping.\");\n await this.runtimeImpl.disposeProcesses(abortSignal);\n await assertDockerCli([\"stop\", this.configuration.containerName], {\n dockerPath: this.dockerPath,\n signal: abortSignal,\n });\n this.currentState = \"stopped\";\n } catch (error) {\n this.currentState = \"error\";\n throw error;\n }\n }\n\n async destroy(): Promise<void> {\n if (this.currentState === \"destroyed\") return;\n if (this.destroyPromise !== undefined) return this.destroyPromise;\n this.destroyPromise = this.performDestroy();\n try {\n await this.destroyPromise;\n } finally {\n this.destroyPromise = undefined;\n }\n }\n\n private async performDestroy(): Promise<void> {\n if (this.stopPromise !== undefined) await this.stopPromise.catch(() => undefined);\n this.currentState = \"destroying\";\n const failures: unknown[] = [];\n try {\n await this.runtimeImpl.closeActiveOperations(\"Sandbox is being destroyed.\");\n } catch (error) {\n failures.push(error);\n }\n try {\n await this.runtimeImpl.disposeProcesses();\n } catch (error) {\n failures.push(error);\n }\n try {\n await removeContainer(this.dockerPath, this.configuration.containerName);\n } catch (error) {\n failures.push(error);\n }\n if (this.configuration.ownsVolume) {\n try {\n await removeVolume(this.dockerPath, this.configuration.volumeName);\n } catch (error) {\n failures.push(error);\n }\n }\n if (failures.length > 0) {\n this.currentState = \"error\";\n throw new AggregateError(failures, `Unable to destroy sandbox: ${this.id}`);\n }\n this.currentState = \"destroyed\";\n }\n\n async [Symbol.asyncDispose](): Promise<void> {\n await this.destroy();\n }\n}\n\nclass DockerSandboxRuntimeImpl {\n private readonly configuration: SandboxConfiguration;\n private readonly dockerPath: string;\n private readonly state: () => DockerSandboxState;\n private readonly processManager: DockerProcessManager;\n private readonly activeControllers = new Set<AbortController>();\n private readonly activeOperations = new Set<Promise<unknown>>();\n private processDisposed = false;\n\n constructor(options: {\n configuration: SandboxConfiguration;\n dockerPath: string;\n state: () => DockerSandboxState;\n }) {\n this.configuration = options.configuration;\n this.dockerPath = options.dockerPath;\n this.state = options.state;\n this.processManager = new DockerProcessManager({\n containerName: options.configuration.containerName,\n dockerPath: options.dockerPath,\n workdir: options.configuration.workdir,\n env: options.configuration.env,\n maxOutputBytes: options.configuration.runtime.maxOutputBytes,\n maxProcesses: options.configuration.runtime.maxProcesses,\n startupTimeoutMs: options.configuration.runtime.commandTimeoutMs,\n });\n }\n\n publicRuntime(): DockerSandboxRuntime {\n return {\n id: this.configuration.id,\n provider: \"docker\",\n workdir: this.configuration.workdir,\n publishedPorts: Object.freeze(\n this.configuration.publishedPorts.map((port) => Object.freeze({ ...port })),\n ),\n exec: (options) => this.exec(options),\n execStream: (options) => this.execStream(options),\n readFile: (options) => this.readFile(options),\n readTextFile: (options) => this.readTextFile(options),\n readTextFilePage: (options) => this.readTextFilePage(options),\n writeFile: (options) => this.writeFile(options),\n writeTextFile: (options) => this.writeTextFile(options),\n listFiles: (options) => this.listFiles(options),\n startProcess: (options) => this.startProcess(options),\n listProcesses: (options) => this.listProcesses(options),\n readProcessLogs: (options) => this.readProcessLogs(options),\n stopProcess: (options) => this.stopProcess(options),\n waitForPort: (options) => this.waitForPort(options),\n };\n }\n\n async exec(options: DockerSandboxExecOptions): Promise<DockerSandboxExecResult> {\n validateExecOptions(options);\n return this.runOperation(options.abortSignal, async (abortSignal) => {\n const result = await runDockerCli(this.execArgs(options), {\n dockerPath: this.dockerPath,\n timeoutMs: options.timeoutMs ?? this.configuration.runtime.commandTimeoutMs,\n maxOutputBytes: this.configuration.runtime.maxOutputBytes,\n input: options.input,\n signal: abortSignal,\n });\n return toExecResult(result);\n });\n }\n\n async *execStream(\n options: DockerSandboxExecOptions,\n ): AsyncIterable<DockerSandboxExecStreamEvent> {\n validateExecOptions(options);\n this.assertRunning();\n const streamAbort = new AbortController();\n const combined = combineSignals(options.abortSignal, streamAbort.signal);\n const queue: DockerSandboxExecStreamEvent[] = [];\n let queuedBytes = 0;\n let wake: (() => void) | undefined;\n let complete = false;\n let failure: unknown;\n const push = (event: DockerSandboxExecStreamEvent) => {\n if (event.type !== \"result\") {\n queuedBytes += event.data.byteLength;\n if (queuedBytes > this.configuration.runtime.maxOutputBytes) {\n streamAbort.abort(\n new DockerSandboxError(\"Sandbox stream consumer is too slow.\", \"docker_command_failed\"),\n );\n return;\n }\n }\n queue.push(event);\n wake?.();\n wake = undefined;\n };\n const run = this.runOperation(combined, async (abortSignal) => {\n const result = await runDockerCli(this.execArgs(options), {\n dockerPath: this.dockerPath,\n timeoutMs: options.timeoutMs ?? this.configuration.runtime.commandTimeoutMs,\n maxOutputBytes: this.configuration.runtime.maxOutputBytes,\n input: options.input,\n signal: abortSignal,\n onStdout: (data) => push({ type: \"stdout\", data: data.slice() }),\n onStderr: (data) => push({ type: \"stderr\", data: data.slice() }),\n });\n push({ type: \"result\", result: toExecResult(result) });\n });\n void run.then(\n () => {\n complete = true;\n wake?.();\n },\n (error) => {\n failure = error;\n complete = true;\n wake?.();\n },\n );\n\n try {\n while (!complete || queue.length > 0) {\n const event = queue.shift();\n if (event !== undefined) {\n if (event.type !== \"result\") queuedBytes -= event.data.byteLength;\n yield event;\n continue;\n }\n await new Promise<void>((resolve) => {\n wake = resolve;\n });\n }\n if (failure !== undefined) throw failure;\n } finally {\n if (!complete) streamAbort.abort(new DOMException(\"Stream closed\", \"AbortError\"));\n await run.catch(() => undefined);\n }\n }\n\n async readFile(options: DockerSandboxReadFileOptions): Promise<Uint8Array> {\n assertReadOptions(options);\n return this.runOperation(options.abortSignal, async (abortSignal) => {\n const normalized = normalizeSandboxPath(options.path);\n const tempDir = await mkdtemp(path.join(os.tmpdir(), \"anvia-sandbox-read-\"));\n const target = path.join(tempDir, path.basename(normalized));\n try {\n await assertDockerCli(\n [\n \"cp\",\n `${this.configuration.containerName}:${containerPath(this.configuration.workdir, normalized)}`,\n target,\n ],\n { dockerPath: this.dockerPath, signal: abortSignal },\n );\n await assertCopiedRegularFile(tempDir, target, normalized);\n const bytes = await readFile(target, { signal: abortSignal });\n this.assertFileSize(bytes.byteLength, normalized);\n return new Uint8Array(bytes.buffer, bytes.byteOffset, bytes.byteLength).slice();\n } finally {\n await rm(tempDir, { recursive: true, force: true });\n }\n });\n }\n\n async readTextFile(options: DockerSandboxReadFileOptions): Promise<string> {\n return decodeUtf8(await this.readFile(options));\n }\n\n async readTextFilePage(\n options: DockerSandboxReadTextFilePageOptions,\n ): Promise<DockerSandboxTextFilePage> {\n assertReadOptions(options);\n const startLine = options.startLine ?? 1;\n const lineCount = options.lineCount ?? defaultTextFilePageLines;\n const maxBytes = options.maxBytes ?? defaultTextFilePageBytes;\n assertPositiveSafeInteger(startLine, \"startLine\");\n assertPositiveSafeInteger(lineCount, \"lineCount\");\n assertPositiveSafeInteger(maxBytes, \"maxBytes\");\n let readOptions: DockerSandboxReadFileOptions = {\n path: options.path,\n };\n if (options.abortSignal !== undefined) {\n readOptions = { ...readOptions, abortSignal: options.abortSignal };\n }\n const text = await this.readTextFile(readOptions);\n return createTextFilePage(text, { startLine, lineCount, maxBytes });\n }\n\n async writeFile(options: DockerSandboxWriteFileOptions): Promise<void> {\n assertOptionsObject(options);\n if (!(options.data instanceof Uint8Array)) throw new TypeError(\"data must be a Uint8Array.\");\n const data = options.data.slice();\n await this.writeBytes(options.path, data, options.abortSignal);\n }\n\n async writeTextFile(options: DockerSandboxWriteTextFileOptions): Promise<void> {\n assertOptionsObject(options);\n if (typeof options.text !== \"string\") throw new TypeError(\"text must be a string.\");\n await this.writeBytes(\n options.path,\n new TextEncoder().encode(options.text),\n options.abortSignal,\n );\n }\n\n private async writeBytes(\n filePath: string,\n data: Uint8Array,\n abortSignal?: AbortSignal,\n ): Promise<void> {\n const normalized = normalizeSandboxPath(filePath);\n this.assertFileSize(data.byteLength, normalized);\n await this.runOperation(abortSignal, async (effectiveSignal) => {\n await this.mkdir(parentSandboxPath(normalized), effectiveSignal);\n const tempDir = await mkdtemp(path.join(os.tmpdir(), \"anvia-sandbox-write-\"));\n const source = path.join(tempDir, path.basename(normalized));\n try {\n await writeFile(source, data, { signal: effectiveSignal });\n await assertDockerCli(\n [\n \"cp\",\n source,\n `${this.configuration.containerName}:${containerPath(this.configuration.workdir, normalized)}`,\n ],\n { dockerPath: this.dockerPath, signal: effectiveSignal },\n );\n } finally {\n await rm(tempDir, { recursive: true, force: true });\n }\n });\n }\n\n async listFiles(\n options: DockerSandboxListFilesOptions = {},\n ): Promise<readonly DockerSandboxFileEntry[]> {\n assertOptionsObject(options);\n const requestedPath = options.path ?? \".\";\n const normalized = normalizeSandboxPath(requestedPath, { allowRoot: true });\n return this.runOperation(options.abortSignal, async (abortSignal) => {\n const result = await this.execCommand(\n {\n command: \"find\",\n args: [\n containerPath(this.configuration.workdir, normalized),\n \"-mindepth\",\n \"1\",\n \"-maxdepth\",\n \"1\",\n \"-printf\",\n \"%p\\t%y\\t%s\\n\",\n ],\n },\n abortSignal,\n );\n if (result.status !== \"exited\" || result.exitCode !== 0) {\n throw new DockerSandboxError(\n \"Unable to list sandbox files.\",\n \"docker_command_failed\",\n result,\n );\n }\n const output = decodeUtf8(result.stdout);\n return output\n .split(\"\\n\")\n .filter((line) => line.length > 0)\n .map((line) => parseFindEntry(line, this.configuration.workdir));\n });\n }\n\n async startProcess(options: DockerSandboxProcessStartOptions): Promise<DockerSandboxProcessInfo> {\n validateProcessStartOptions(options);\n return this.runOperation(options.abortSignal, async (abortSignal) =>\n this.processManager.start({ ...options, abortSignal }),\n );\n }\n\n async listProcesses(\n options: DockerSandboxListProcessesOptions = {},\n ): Promise<readonly DockerSandboxProcessInfo[]> {\n assertOptionsObject(options);\n return this.runOperation(options.abortSignal, async () => this.processManager.list());\n }\n\n async readProcessLogs(\n options: DockerSandboxReadProcessLogsOptions,\n ): Promise<DockerSandboxProcessLogs> {\n assertOptionsObject(options);\n assertNonEmptyString(options.processId, \"processId\");\n if (options.tailBytes !== undefined)\n assertNonNegativeSafeInteger(options.tailBytes, \"tailBytes\");\n return this.runOperation(options.abortSignal, async () =>\n this.processManager.logs(options.processId, options.tailBytes),\n );\n }\n\n async stopProcess(options: DockerSandboxStopProcessOptions): Promise<DockerSandboxProcessInfo> {\n assertOptionsObject(options);\n assertNonEmptyString(options.processId, \"processId\");\n if (options.gracePeriodMs !== undefined) {\n assertNonNegativeSafeInteger(options.gracePeriodMs, \"gracePeriodMs\");\n }\n return this.runOperation(options.abortSignal, async (abortSignal) =>\n this.processManager.stop(options.processId, options.gracePeriodMs, abortSignal),\n );\n }\n\n async waitForPort(options: DockerSandboxWaitForPortOptions): Promise<DockerSandboxPublishedPort> {\n assertOptionsObject(options);\n assertPort(options.containerPort);\n const publishedPort = this.configuration.publishedPorts.find(\n (candidate) => candidate.containerPort === options.containerPort,\n );\n if (publishedPort === undefined) {\n throw new DockerSandboxError(\n `Sandbox port is not published: ${options.containerPort}/tcp`,\n \"port\",\n );\n }\n const timeoutMs = options.timeoutMs ?? defaultPortWaitTimeoutMs;\n const intervalMs = options.intervalMs ?? defaultPortWaitIntervalMs;\n assertPositiveSafeInteger(timeoutMs, \"timeoutMs\");\n assertPositiveSafeInteger(intervalMs, \"intervalMs\");\n\n return this.runOperation(options.abortSignal, async (abortSignal) => {\n const deadline = Date.now() + timeoutMs;\n while (true) {\n const result = await this.execCommand(\n {\n command: \"sh\",\n args: [\"-c\", portProbeScript, \"anvia-port-probe\", `${options.containerPort}`],\n timeoutMs: Math.min(5_000, timeoutMs),\n },\n abortSignal,\n );\n if (result.status === \"exited\" && result.exitCode === 0) return { ...publishedPort };\n if (Date.now() >= deadline) {\n throw new DockerSandboxError(\n `Waiting for sandbox port timed out: ${options.containerPort}`,\n \"timeout\",\n );\n }\n await waitWithSignal(Math.min(intervalMs, deadline - Date.now()), abortSignal);\n }\n });\n }\n\n async closeActiveOperations(message: string): Promise<void> {\n const reason = new DockerSandboxError(message, \"invalid_state\");\n for (const controller of this.activeControllers) controller.abort(reason);\n await Promise.allSettled(this.activeOperations);\n }\n\n async disposeProcesses(abortSignal?: AbortSignal): Promise<void> {\n if (this.processDisposed) return;\n await this.processManager.dispose(abortSignal);\n this.processDisposed = true;\n }\n\n private async runOperation<T>(\n abortSignal: AbortSignal | undefined,\n operation: (abortSignal: AbortSignal) => Promise<T>,\n ): Promise<T> {\n this.assertRunning();\n abortSignal?.throwIfAborted();\n const controller = new AbortController();\n const effectiveSignal = combineSignals(abortSignal, controller.signal);\n const execution = operation(effectiveSignal);\n this.activeControllers.add(controller);\n this.activeOperations.add(execution);\n try {\n return await execution;\n } finally {\n this.activeControllers.delete(controller);\n this.activeOperations.delete(execution);\n }\n }\n\n private assertRunning(): void {\n const current = this.state();\n if (current !== \"running\") throw invalidState(this.configuration.id, current);\n }\n\n private execArgs(options: DockerSandboxExecOptions): string[] {\n const args = [\"exec\"];\n if (options.input !== undefined) args.push(\"-i\");\n args.push(\"-w\", containerPath(this.configuration.workdir, options.cwd ?? \".\"));\n for (const [key, value] of Object.entries(options.env ?? {}))\n args.push(\"-e\", `${key}=${value}`);\n args.push(this.configuration.containerName, options.command, ...(options.args ?? []));\n return args;\n }\n\n private async execCommand(\n options: Omit<DockerSandboxExecOptions, \"abortSignal\">,\n abortSignal: AbortSignal,\n ): Promise<DockerSandboxExecResult> {\n const result = await runDockerCli(this.execArgs(options), {\n dockerPath: this.dockerPath,\n timeoutMs: options.timeoutMs ?? this.configuration.runtime.commandTimeoutMs,\n maxOutputBytes: this.configuration.runtime.maxOutputBytes,\n input: options.input,\n signal: abortSignal,\n });\n return toExecResult(result);\n }\n\n private async mkdir(directory: string, abortSignal: AbortSignal): Promise<void> {\n if (directory === \".\") return;\n const result = await this.execCommand(\n { command: \"mkdir\", args: [\"-p\", containerPath(this.configuration.workdir, directory)] },\n abortSignal,\n );\n if (result.status !== \"exited\" || result.exitCode !== 0) {\n throw new DockerSandboxError(\n \"Unable to create sandbox directory.\",\n \"docker_command_failed\",\n result,\n );\n }\n }\n\n private assertFileSize(size: number, filePath: string): void {\n if (size > this.configuration.runtime.maxFileBytes) {\n throw new DockerSandboxError(\n `Sandbox file exceeds maxFileBytes (${size} > ${this.configuration.runtime.maxFileBytes}): ${filePath}`,\n \"file_too_large\",\n );\n }\n }\n}\n\nasync function applyInitialContent(\n runtime: DockerSandboxRuntime,\n options: CreateDockerSandboxOptions,\n): Promise<void> {\n for (const directory of options.directories ?? []) {\n const marker = path.posix.join(normalizeSandboxPath(directory), \".anvia-keep\");\n const abort = options.abortSignal === undefined ? {} : { abortSignal: options.abortSignal };\n await runtime.writeFile({ path: marker, data: new Uint8Array(), ...abort });\n const removed = await runtime.exec({ command: \"rm\", args: [marker], ...abort });\n if (removed.status !== \"exited\" || removed.exitCode !== 0) {\n throw new DockerSandboxError(\n `Unable to create initial sandbox directory: ${directory}`,\n \"docker_command_failed\",\n removed,\n );\n }\n }\n for (const [filePath, content] of Object.entries(options.files ?? {})) {\n if (typeof content === \"string\") {\n let writeOptions: DockerSandboxWriteTextFileOptions = {\n path: filePath,\n text: content,\n };\n if (options.abortSignal !== undefined) {\n writeOptions = { ...writeOptions, abortSignal: options.abortSignal };\n }\n await runtime.writeTextFile(writeOptions);\n } else {\n let writeOptions: DockerSandboxWriteFileOptions = {\n path: filePath,\n data: content,\n };\n if (options.abortSignal !== undefined) {\n writeOptions = { ...writeOptions, abortSignal: options.abortSignal };\n }\n await runtime.writeFile(writeOptions);\n }\n }\n}\n\nfunction createRunArgs(options: {\n id: string;\n containerName: string;\n image: string;\n workdir: string;\n containerRuntime: string;\n workspace: DockerSandboxWorkspace;\n volumeName: string;\n env: Record<string, string>;\n user: string | undefined;\n userLabels: Record<string, string>;\n resources: CreateDockerSandboxOptions[\"resources\"] | undefined;\n runtime: ResolvedRuntimeLimits;\n security: CreateDockerSandboxOptions[\"security\"] | undefined;\n network: CreateDockerSandboxOptions[\"network\"];\n}): string[] {\n const runtimeLabels: Record<string, string> = {\n [labels.schema]: schemaVersion,\n [labels.id]: options.id,\n [labels.workdir]: options.workdir,\n [labels.workspaceType]: options.workspace.type,\n [labels.workspaceVolume]: options.volumeName,\n [labels.networkMode]: options.network.mode,\n [labels.containerRuntime]: options.containerRuntime,\n [labels.commandTimeoutMs]: `${options.runtime.commandTimeoutMs}`,\n [labels.maxOutputBytes]: `${options.runtime.maxOutputBytes}`,\n [labels.maxFileBytes]: `${options.runtime.maxFileBytes}`,\n [labels.maxProcesses]: `${options.runtime.maxProcesses}`,\n };\n const args = [\n \"run\",\n \"-d\",\n \"--name\",\n options.containerName,\n \"--mount\",\n `type=volume,src=${options.volumeName},dst=${options.workdir}`,\n \"-w\",\n options.workdir,\n ];\n if (options.containerRuntime !== \"default\") {\n args.push(\"--runtime\", options.containerRuntime);\n }\n for (const [key, value] of Object.entries({ ...options.userLabels, ...runtimeLabels })) {\n args.push(\"--label\", `${key}=${value}`);\n }\n for (const [key, value] of Object.entries(options.env)) args.push(\"--env\", `${key}=${value}`);\n if (options.user !== undefined) args.push(\"--user\", options.user);\n if (options.network.mode === \"none\") {\n args.push(\"--network\", \"none\");\n } else {\n for (const port of options.network.ports ?? [])\n args.push(\"--publish\", `127.0.0.1::${port}/tcp`);\n }\n if (options.resources?.memoryMb !== undefined)\n args.push(\"--memory\", `${options.resources.memoryMb}m`);\n if (options.resources?.cpus !== undefined) args.push(\"--cpus\", `${options.resources.cpus}`);\n if (options.resources?.pidsLimit !== undefined) {\n args.push(\"--pids-limit\", `${options.resources.pidsLimit}`);\n }\n if (options.resources?.sharedMemoryMb !== undefined) {\n args.push(\"--shm-size\", `${options.resources.sharedMemoryMb}m`);\n }\n if (options.security?.readonlyRootfs === true) args.push(\"--read-only\");\n if (options.security?.noNewPrivileges ?? true)\n args.push(\"--security-opt\", \"no-new-privileges:true\");\n if (options.security?.seccompProfile !== undefined) {\n args.push(\"--security-opt\", `seccomp=${options.security.seccompProfile.path}`);\n }\n for (const capability of options.security?.dropCapabilities ?? [\"ALL\"]) {\n args.push(\"--cap-drop\", capability);\n }\n for (const capability of options.security?.addCapabilities ?? []) {\n args.push(\"--cap-add\", capability);\n }\n args.push(\n options.image,\n \"sh\",\n \"-c\",\n \"trap 'exit 0' TERM INT; while :; do sleep 3600 & wait $!; done\",\n );\n return args;\n}\n\nfunction validateCreateOptions(options: CreateDockerSandboxOptions): void {\n if (options === null || typeof options !== \"object\")\n throw new TypeError(\"options must be an object.\");\n assertNonEmptyString(options.image, \"image\");\n if (options.id !== undefined) assertSandboxId(options.id);\n const workdir = options.workdir ?? defaultWorkdir;\n if (!path.posix.isAbsolute(workdir) || workdir.includes(\"\\0\")) {\n throw new TypeError(\"workdir must be an absolute POSIX path.\");\n }\n if (!isRecord(options.workspace)) throw new TypeError(\"workspace must be an object.\");\n if (options.workspace.type === \"docker-volume\") assertDockerVolumeName(options.workspace.name);\n if (options.workspace.type !== \"ephemeral\" && options.workspace.type !== \"docker-volume\") {\n throw new TypeError(\"workspace must use type ephemeral or docker-volume.\");\n }\n if (options.workspace.type === \"ephemeral\" && \"name\" in options.workspace) {\n throw new TypeError(\"An ephemeral workspace cannot specify a Docker volume name.\");\n }\n if (!isRecord(options.network)) throw new TypeError(\"network must be an object.\");\n if (options.network.mode !== \"none\" && options.network.mode !== \"bridge\") {\n throw new TypeError(\"network must use mode none or bridge.\");\n }\n if (options.network.mode === \"none\" && \"ports\" in options.network) {\n throw new TypeError(\"Network mode none cannot publish ports.\");\n }\n if (options.network.mode === \"bridge\") {\n if (options.network.ports !== undefined && !Array.isArray(options.network.ports)) {\n throw new TypeError(\"network.ports must be an array.\");\n }\n validatePorts(options.network.ports ?? []);\n }\n validateRuntimeLimits(options.runtime);\n validateResources(options.resources);\n validateSecurity(options.security);\n copyStringRecord(options.env, \"env\");\n const userLabels = copyStringRecord(options.labels, \"labels\");\n for (const key of Object.keys(userLabels)) {\n if (key.startsWith(labelPrefix)) throw new TypeError(`Docker label is reserved: ${key}`);\n }\n if (options.user !== undefined) assertNonEmptyString(options.user, \"user\");\n if (options.containerRuntime !== undefined) {\n assertNonEmptyString(options.containerRuntime, \"containerRuntime\");\n }\n if (options.directories !== undefined && !Array.isArray(options.directories)) {\n throw new TypeError(\"directories must be an array.\");\n }\n for (const directory of options.directories ?? []) {\n if (typeof directory !== \"string\") throw new TypeError(\"directories must contain strings.\");\n normalizeSandboxPath(directory);\n }\n if (options.files !== undefined && !isRecord(options.files)) {\n throw new TypeError(\"files must be an object.\");\n }\n for (const [filePath, content] of Object.entries(options.files ?? {})) {\n normalizeSandboxPath(filePath);\n if (typeof content !== \"string\" && !(content instanceof Uint8Array)) {\n throw new TypeError(`Initial file must be a string or Uint8Array: ${filePath}`);\n }\n const byteLength =\n typeof content === \"string\"\n ? new TextEncoder().encode(content).byteLength\n : content.byteLength;\n const maxFileBytes = options.runtime?.maxFileBytes ?? defaultMaxFileBytes;\n if (byteLength > maxFileBytes) {\n throw new DockerSandboxError(\n `Initial file exceeds maxFileBytes (${byteLength} > ${maxFileBytes}): ${filePath}`,\n \"file_too_large\",\n );\n }\n }\n}\n\nfunction validateRuntimeLimits(runtime?: DockerSandboxRuntimeLimits): void {\n if (runtime !== undefined && !isRecord(runtime)) {\n throw new TypeError(\"runtime must be an object.\");\n }\n if (runtime?.commandTimeoutMs !== undefined)\n assertPositiveSafeInteger(runtime.commandTimeoutMs, \"commandTimeoutMs\");\n if (runtime?.maxOutputBytes !== undefined)\n assertNonNegativeSafeInteger(runtime.maxOutputBytes, \"maxOutputBytes\");\n if (runtime?.maxFileBytes !== undefined)\n assertNonNegativeSafeInteger(runtime.maxFileBytes, \"maxFileBytes\");\n if (runtime?.maxProcesses !== undefined)\n assertNonNegativeSafeInteger(runtime.maxProcesses, \"maxProcesses\");\n}\n\nfunction validateResources(resources: CreateDockerSandboxOptions[\"resources\"]): void {\n if (resources !== undefined && !isRecord(resources)) {\n throw new TypeError(\"resources must be an object.\");\n }\n if (resources?.memoryMb !== undefined) assertPositiveSafeInteger(resources.memoryMb, \"memoryMb\");\n if (resources?.pidsLimit !== undefined)\n assertPositiveSafeInteger(resources.pidsLimit, \"pidsLimit\");\n if (resources?.sharedMemoryMb !== undefined)\n assertPositiveSafeInteger(resources.sharedMemoryMb, \"sharedMemoryMb\");\n if (resources?.cpus !== undefined && (!Number.isFinite(resources.cpus) || resources.cpus <= 0)) {\n throw new RangeError(\"cpus must be a positive finite number.\");\n }\n}\n\nfunction validateSecurity(security: CreateDockerSandboxOptions[\"security\"]): void {\n if (security !== undefined && !isRecord(security)) {\n throw new TypeError(\"security must be an object.\");\n }\n if (security?.dropCapabilities !== undefined && !Array.isArray(security.dropCapabilities)) {\n throw new TypeError(\"dropCapabilities must be an array.\");\n }\n if (security?.addCapabilities !== undefined && !Array.isArray(security.addCapabilities)) {\n throw new TypeError(\"addCapabilities must be an array.\");\n }\n if (security?.readonlyRootfs !== undefined && typeof security.readonlyRootfs !== \"boolean\") {\n throw new TypeError(\"readonlyRootfs must be a boolean.\");\n }\n if (security?.noNewPrivileges !== undefined && typeof security.noNewPrivileges !== \"boolean\") {\n throw new TypeError(\"noNewPrivileges must be a boolean.\");\n }\n if (security?.seccompProfile !== undefined) {\n if (!isRecord(security.seccompProfile) || security.seccompProfile.type !== \"path\") {\n throw new TypeError('seccompProfile must be a { type: \"path\", path } object.');\n }\n assertNonEmptyString(security.seccompProfile.path, \"seccompProfile.path\");\n if (\n !path.isAbsolute(security.seccompProfile.path) ||\n security.seccompProfile.path.includes(\"\\0\")\n ) {\n throw new TypeError(\"seccompProfile.path must be an absolute host path.\");\n }\n }\n const seen = new Set<string>();\n for (const capability of security?.dropCapabilities ?? []) {\n assertNonEmptyString(capability, \"dropCapabilities value\");\n if (seen.has(capability))\n throw new TypeError(`dropCapabilities contains a duplicate: ${capability}`);\n seen.add(capability);\n }\n seen.clear();\n for (const capability of security?.addCapabilities ?? []) {\n assertNonEmptyString(capability, \"addCapabilities value\");\n if (seen.has(capability))\n throw new TypeError(`addCapabilities contains a duplicate: ${capability}`);\n seen.add(capability);\n }\n}\n\nfunction validateExecOptions(options: DockerSandboxExecOptions): void {\n assertOptionsObject(options);\n assertNonEmptyString(options.command, \"command\");\n if (\n options.args !== undefined &&\n (!Array.isArray(options.args) || !options.args.every((value) => typeof value === \"string\"))\n ) {\n throw new TypeError(\"args must contain only strings.\");\n }\n if (options.cwd !== undefined) normalizeSandboxPath(options.cwd, { allowRoot: true });\n copyStringRecord(options.env, \"env\");\n if (options.timeoutMs !== undefined) assertPositiveSafeInteger(options.timeoutMs, \"timeoutMs\");\n if (\n options.input !== undefined &&\n typeof options.input !== \"string\" &&\n !(options.input instanceof Uint8Array)\n ) {\n throw new TypeError(\"input must be a string or Uint8Array.\");\n }\n}\n\nfunction validateProcessStartOptions(options: DockerSandboxProcessStartOptions): void {\n assertOptionsObject(options);\n assertNonEmptyString(options.command, \"command\");\n if (\n options.args !== undefined &&\n (!Array.isArray(options.args) || !options.args.every((value) => typeof value === \"string\"))\n ) {\n throw new TypeError(\"args must contain only strings.\");\n }\n if (options.cwd !== undefined) normalizeSandboxPath(options.cwd, { allowRoot: true });\n copyStringRecord(options.env, \"env\");\n}\n\nfunction assertReadOptions(options: DockerSandboxReadFileOptions): void {\n assertOptionsObject(options);\n normalizeSandboxPath(options.path);\n}\n\nfunction assertOptionsObject(value: unknown): asserts value is Record<string, unknown> {\n if (!isRecord(value)) throw new TypeError(\"options must be an object.\");\n}\n\nfunction resolveRuntimeLimits(runtime?: DockerSandboxRuntimeLimits): ResolvedRuntimeLimits {\n return {\n commandTimeoutMs: runtime?.commandTimeoutMs ?? defaultCommandTimeoutMs,\n maxOutputBytes: runtime?.maxOutputBytes ?? defaultMaxOutputBytes,\n maxFileBytes: runtime?.maxFileBytes ?? defaultMaxFileBytes,\n maxProcesses: runtime?.maxProcesses ?? defaultMaxProcesses,\n };\n}\n\nfunction snapshotCreateOptions(options: CreateDockerSandboxOptions): CreateDockerSandboxOptions {\n const files: Record<string, string | Uint8Array> = {};\n for (const [filePath, content] of Object.entries(options.files ?? {})) {\n files[filePath] = typeof content === \"string\" ? content : content.slice();\n }\n const workspace = copyWorkspace(options.workspace);\n const network = copyNetwork(options.network);\n let snapshot: CreateDockerSandboxOptions = {\n image: options.image,\n workspace,\n network,\n };\n if (options.id !== undefined) snapshot = { ...snapshot, id: options.id };\n if (options.workdir !== undefined) snapshot = { ...snapshot, workdir: options.workdir };\n if (options.containerRuntime !== undefined) {\n snapshot = { ...snapshot, containerRuntime: options.containerRuntime };\n }\n if (options.files !== undefined) snapshot = { ...snapshot, files: Object.freeze(files) };\n if (options.directories !== undefined) {\n snapshot = { ...snapshot, directories: Object.freeze([...options.directories]) };\n }\n if (options.env !== undefined) {\n snapshot = { ...snapshot, env: Object.freeze({ ...options.env }) };\n }\n if (options.user !== undefined) snapshot = { ...snapshot, user: options.user };\n if (options.labels !== undefined) {\n snapshot = { ...snapshot, labels: Object.freeze({ ...options.labels }) };\n }\n if (options.resources !== undefined) {\n snapshot = { ...snapshot, resources: Object.freeze({ ...options.resources }) };\n }\n if (options.runtime !== undefined) {\n snapshot = { ...snapshot, runtime: Object.freeze({ ...options.runtime }) };\n }\n if (options.security !== undefined) {\n let security: NonNullable<CreateDockerSandboxOptions[\"security\"]> = {\n ...options.security,\n };\n if (options.security.seccompProfile !== undefined) {\n security = {\n ...security,\n seccompProfile: Object.freeze({ ...options.security.seccompProfile }),\n };\n }\n if (options.security.dropCapabilities !== undefined) {\n security = {\n ...security,\n dropCapabilities: Object.freeze([...options.security.dropCapabilities]),\n };\n }\n if (options.security.addCapabilities !== undefined) {\n security = {\n ...security,\n addCapabilities: Object.freeze([...options.security.addCapabilities]),\n };\n }\n snapshot = { ...snapshot, security: Object.freeze(security) };\n }\n if (options.abortSignal !== undefined) {\n snapshot = { ...snapshot, abortSignal: options.abortSignal };\n }\n return Object.freeze(snapshot);\n}\n\nfunction configurationFromInspection(\n id: string,\n containerName: string,\n inspection: DockerContainerInspection,\n): SandboxConfiguration {\n const containerLabels = inspection.Config.Labels ?? {};\n if (containerLabels[labels.schema] !== schemaVersion || containerLabels[labels.id] !== id) {\n throw new DockerSandboxError(\n `Container is not an Anvia sandbox: ${containerName}`,\n \"sandbox_not_found\",\n );\n }\n const workdir = requiredLabel(containerLabels, labels.workdir);\n const workspaceType = requiredLabel(containerLabels, labels.workspaceType);\n const volumeName = requiredLabel(containerLabels, labels.workspaceVolume);\n const networkMode = requiredLabel(containerLabels, labels.networkMode);\n const labeledRuntime = containerLabels[labels.containerRuntime];\n const hostRuntime = inspection.HostConfig?.Runtime;\n const containerRuntime =\n labeledRuntime !== undefined && labeledRuntime !== \"\"\n ? labeledRuntime\n : hostRuntime !== undefined && hostRuntime !== \"\"\n ? hostRuntime\n : \"default\";\n if (networkMode !== \"none\" && networkMode !== \"bridge\") invalidInspection(\"network mode\");\n const workspace: DockerSandboxWorkspace =\n workspaceType === \"ephemeral\"\n ? { type: \"ephemeral\" }\n : workspaceType === \"docker-volume\"\n ? { type: \"docker-volume\", name: volumeName }\n : invalidInspection(\"workspace type\");\n const runtime = {\n commandTimeoutMs: parseLabelInteger(containerLabels, labels.commandTimeoutMs, true),\n maxOutputBytes: parseLabelInteger(containerLabels, labels.maxOutputBytes, false),\n maxFileBytes: parseLabelInteger(containerLabels, labels.maxFileBytes, false),\n maxProcesses: parseLabelInteger(containerLabels, labels.maxProcesses, false),\n };\n return {\n id,\n containerName,\n containerRuntime,\n workdir,\n workspace,\n volumeName,\n ownsVolume: workspace.type === \"ephemeral\",\n env: {},\n runtime,\n publishedPorts: [],\n };\n}\n\ntype DockerContainerInspection = {\n Config: { Labels?: Record<string, string>; WorkingDir?: string };\n HostConfig?: {\n PortBindings?: Record<string, Array<{ HostIp?: string; HostPort?: string }> | null>;\n Runtime?: string;\n };\n State: { Running?: boolean; Paused?: boolean; Dead?: boolean; Status?: string };\n NetworkSettings?: {\n Ports?: Record<string, Array<{ HostIp?: string; HostPort?: string }> | null>;\n };\n};\n\nasync function inspectContainer(\n dockerPath: string,\n containerName: string,\n abortSignal: AbortSignal | undefined,\n notFoundAsSandboxError: boolean,\n): Promise<DockerContainerInspection> {\n const result = await runDockerCli([\"container\", \"inspect\", containerName], {\n dockerPath,\n signal: abortSignal,\n });\n if (result.exitCode !== 0) {\n const message = safeDecode(result.stderr);\n if (notFoundAsSandboxError && message.toLowerCase().includes(\"no such\")) {\n throw new DockerSandboxError(`Sandbox does not exist: ${containerName}`, \"sandbox_not_found\");\n }\n throw new DockerSandboxError(\n \"Unable to inspect Docker sandbox.\",\n \"docker_command_failed\",\n result,\n );\n }\n let value: unknown;\n try {\n value = JSON.parse(decodeUtf8(result.stdout));\n } catch (error) {\n throw new DockerSandboxError(\n \"Docker returned invalid container metadata.\",\n \"docker_command_failed\",\n undefined,\n { cause: error },\n );\n }\n if (!Array.isArray(value) || value.length !== 1 || !isInspection(value[0])) {\n throw new DockerSandboxError(\n \"Docker returned invalid container metadata.\",\n \"docker_command_failed\",\n );\n }\n return value[0];\n}\n\nfunction isInspection(value: unknown): value is DockerContainerInspection {\n return isRecord(value) && isRecord(value.Config) && isRecord(value.State);\n}\n\nasync function inspectPublishedPorts(options: {\n dockerPath: string;\n containerName: string;\n ports: readonly number[];\n abortSignal?: AbortSignal | undefined;\n}): Promise<DockerSandboxPublishedPort[]> {\n if (options.ports.length === 0) return [];\n const inspection = await inspectContainer(\n options.dockerPath,\n options.containerName,\n options.abortSignal,\n false,\n );\n const mappings = inspection.NetworkSettings?.Ports ?? {};\n return options.ports.map((containerPort) => {\n const entries = mappings[`${containerPort}/tcp`];\n const entry = entries?.find((candidate) => candidate.HostIp === \"127.0.0.1\");\n const hostPort = Number(entry?.HostPort);\n if (!isPort(hostPort)) {\n throw new DockerSandboxError(`Docker did not publish port: ${containerPort}`, \"port\");\n }\n return { containerPort, host: \"127.0.0.1\", hostPort, protocol: \"tcp\" };\n });\n}\n\nfunction configuredContainerPorts(inspection: DockerContainerInspection): number[] {\n return Object.keys(inspection.HostConfig?.PortBindings ?? {}).flatMap((key) => {\n const match = /^(\\d+)\\/tcp$/.exec(key);\n if (match?.[1] === undefined) return [];\n const value = Number(match[1]);\n return isPort(value) ? [value] : [];\n });\n}\n\nasync function assertCopiedRegularFile(\n temporaryDirectory: string,\n target: string,\n sandboxPath: string,\n): Promise<void> {\n const metadata = await lstat(target);\n if (metadata.isSymbolicLink() || !metadata.isFile()) {\n throw new DockerSandboxError(\n `Sandbox path is not a regular file: ${sandboxPath}`,\n \"invalid_path\",\n );\n }\n const resolvedTarget = await realpath(target);\n const relativeTarget = path.relative(temporaryDirectory, resolvedTarget);\n if (\n relativeTarget === \"\" ||\n relativeTarget === \"..\" ||\n relativeTarget.startsWith(`..${path.sep}`) ||\n path.isAbsolute(relativeTarget)\n ) {\n throw new DockerSandboxError(\n `Sandbox file escaped its temporary read boundary: ${sandboxPath}`,\n \"invalid_path\",\n );\n }\n}\n\nasync function removeContainer(dockerPath: string, containerName: string): Promise<void> {\n const result = await runDockerCli([\"rm\", \"-f\", containerName], { dockerPath });\n if (result.exitCode === 0 || safeDecode(result.stderr).toLowerCase().includes(\"no such\")) return;\n throw new DockerSandboxError(\"Unable to remove Docker sandbox.\", \"docker_command_failed\", result);\n}\n\nasync function removeVolume(dockerPath: string, volumeName: string): Promise<void> {\n const result = await runDockerCli([\"volume\", \"rm\", volumeName], { dockerPath });\n if (result.exitCode === 0 || safeDecode(result.stderr).toLowerCase().includes(\"no such\")) return;\n throw new DockerSandboxError(\n \"Unable to remove Docker sandbox volume.\",\n \"docker_command_failed\",\n result,\n );\n}\n\nfunction parseFindEntry(line: string, workdir: string): DockerSandboxFileEntry {\n const [absolutePath, rawType, rawSize] = line.split(\"\\t\");\n if (absolutePath === undefined || rawType === undefined || rawSize === undefined) {\n throw new DockerSandboxError(\"Docker returned invalid file metadata.\", \"docker_command_failed\");\n }\n const relativePath = path.posix.relative(workdir, absolutePath);\n const size = Number(rawSize);\n const type = mapFindType(rawType);\n let entry: DockerSandboxFileEntry = {\n path: normalizeSandboxPath(relativePath),\n type,\n };\n if (type === \"file\" && Number.isSafeInteger(size) && size >= 0) {\n entry = { ...entry, size };\n }\n return entry;\n}\n\nfunction mapFindType(value: string): DockerSandboxFileType {\n if (value === \"f\") return \"file\";\n if (value === \"d\") return \"directory\";\n if (value === \"l\") return \"symlink\";\n return \"other\";\n}\n\nfunction toExecResult(result: Awaited<ReturnType<typeof runDockerCli>>): DockerSandboxExecResult {\n const common = {\n stdout: result.stdout.slice(),\n stderr: result.stderr.slice(),\n durationMs: result.durationMs,\n stdoutTruncated: result.stdoutTruncated,\n stderrTruncated: result.stderrTruncated,\n };\n return result.timedOut\n ? { ...common, status: \"timed_out\" }\n : { ...common, status: \"exited\", exitCode: result.exitCode };\n}\n\nfunction copyWorkspace(workspace: DockerSandboxWorkspace): DockerSandboxWorkspace {\n return workspace.type === \"ephemeral\"\n ? Object.freeze({ type: \"ephemeral\" })\n : Object.freeze({ type: \"docker-volume\", name: workspace.name });\n}\n\nfunction copyNetwork(\n network: CreateDockerSandboxOptions[\"network\"],\n): CreateDockerSandboxOptions[\"network\"] {\n return network.mode === \"none\"\n ? Object.freeze({ mode: \"none\" })\n : Object.freeze({ mode: \"bridge\", ports: Object.freeze([...(network.ports ?? [])]) });\n}\n\nfunction copyStringRecord(\n value: Readonly<Record<string, string>> | undefined,\n name: string,\n): Record<string, string> {\n if (value === undefined) return {};\n if (!isRecord(value)) throw new TypeError(`${name} must be an object.`);\n const copy: Record<string, string> = {};\n for (const [key, item] of Object.entries(value)) {\n if (typeof item !== \"string\") throw new TypeError(`${name}.${key} must be a string.`);\n if (name === \"env\" && !envKeyPattern.test(key))\n throw new TypeError(`Invalid environment variable name: ${key}`);\n copy[key] = item;\n }\n return copy;\n}\n\nfunction requiredLabel(containerLabels: Record<string, string>, name: string): string {\n const value = containerLabels[name];\n if (value === undefined || value.length === 0) invalidInspection(name);\n return value;\n}\n\nfunction parseLabelInteger(\n containerLabels: Record<string, string>,\n name: string,\n positive: boolean,\n): number {\n const value = Number(requiredLabel(containerLabels, name));\n if (!Number.isSafeInteger(value) || (positive ? value <= 0 : value < 0)) invalidInspection(name);\n return value;\n}\n\nfunction invalidInspection(field: string): never {\n throw new DockerSandboxError(`Sandbox metadata is invalid: ${field}`, \"invalid_state\");\n}\n\nfunction validatePorts(ports: readonly number[]): void {\n if (!Array.isArray(ports)) throw new TypeError(\"ports must be an array.\");\n const seen = new Set<number>();\n for (const port of ports) {\n assertPort(port);\n if (seen.has(port)) throw new DockerSandboxError(`Sandbox port is duplicated: ${port}`, \"port\");\n seen.add(port);\n }\n}\n\nfunction assertPort(port: number): void {\n if (!isPort(port))\n throw new DockerSandboxError(\n `Sandbox port must be an integer from 1 to 65535: ${port}`,\n \"port\",\n );\n}\n\nfunction isPort(port: number): boolean {\n return Number.isInteger(port) && port >= 1 && port <= 65_535;\n}\n\nfunction assertSandboxId(id: string): void {\n if (typeof id !== \"string\" || !idPattern.test(id)) {\n throw new TypeError(\n \"Sandbox id must be 1-63 lowercase letters, numbers, dots, underscores, or hyphens.\",\n );\n }\n}\n\nfunction assertDockerVolumeName(name: string): void {\n assertNonEmptyString(name, \"workspace.name\");\n if (name.includes(\",\") || name.includes(\"\\0\"))\n throw new TypeError(\"workspace.name is not a valid Docker volume name.\");\n}\n\nfunction assertNonEmptyString(value: unknown, name: string): asserts value is string {\n if (typeof value !== \"string\" || value.length === 0)\n throw new TypeError(`${name} must be a non-empty string.`);\n}\n\nfunction assertPositiveSafeInteger(value: number, name: string): void {\n if (!Number.isSafeInteger(value) || value <= 0)\n throw new RangeError(`${name} must be a positive safe integer.`);\n}\n\nfunction assertNonNegativeSafeInteger(value: number, name: string): void {\n if (!Number.isSafeInteger(value) || value < 0)\n throw new RangeError(`${name} must be a non-negative safe integer.`);\n}\n\nfunction invalidState(id: string, state: DockerSandboxState): DockerSandboxError {\n return new DockerSandboxError(`Sandbox ${id} is not running (${state}).`, \"invalid_state\", {\n state,\n });\n}\n\nfunction containerNameFor(id: string): string {\n return `anvia-sandbox-${id}`;\n}\n\nfunction combineSignals(first: AbortSignal | undefined, second: AbortSignal): AbortSignal {\n return first === undefined ? second : AbortSignal.any([first, second]);\n}\n\nasync function waitWithSignal(timeoutMs: number, abortSignal: AbortSignal): Promise<void> {\n abortSignal.throwIfAborted();\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n abortSignal.removeEventListener(\"abort\", abort);\n resolve();\n }, timeoutMs);\n const abort = () => {\n clearTimeout(timeout);\n reject(abortSignal.reason ?? new DOMException(\"Aborted\", \"AbortError\"));\n };\n abortSignal.addEventListener(\"abort\", abort, { once: true });\n });\n}\n\nfunction safeDecode(bytes: Uint8Array): string {\n try {\n return decodeUtf8(bytes);\n } catch {\n return \"\";\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n","import { type ChildProcessWithoutNullStreams, spawn } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport { decodeUtf8, runDockerCli } from \"./docker-cli\";\nimport { DockerSandboxError } from \"./errors\";\nimport { containerPath } from \"./path\";\nimport type {\n DockerSandboxProcessInfo,\n DockerSandboxProcessLogs,\n DockerSandboxProcessStartOptions,\n} from \"./types\";\n\nconst processMarkerPrefix = \"ANVIA_PROCESS\";\n// Establish a killable process group and report it before starting the user command. The wrapper\n// waits for a host acknowledgement, so cancelling startup before the marker is accepted can only\n// leave an idle wrapper that exits when Docker closes stdin, never an untracked user process.\nconst processLauncher = [\n 'wrapper=\"$1\"',\n \"shift\",\n // GNU setsid forks when it is already a process-group leader. `-w` keeps that launcher alive\n // until the new session exits, so Docker does not detach from a still-running managed process.\n \"if command -v setsid >/dev/null 2>&1 && setsid -w true >/dev/null 2>&1; then\",\n ' exec setsid -w sh -c \"$wrapper\" \"$@\"',\n \"fi\",\n 'exec sh -c \"$wrapper\" \"$@\"',\n].join(\"\\n\");\n\nconst processWrapper = [\n 'marker=\"$1\"',\n \"shift\",\n \"group=$$\",\n `printf '\\\\036%s:%s:%s\\\\036' \"$marker\" \"$$\" \"$group\"`,\n \"IFS= read -r ready || exit 125\",\n '[ \"$ready\" = \"start\" ] || exit 125',\n '\"$@\" &',\n \"child=$!\",\n \"terminate() {\",\n ' wait \"$child\" 2>/dev/null || true',\n \" exit 143\",\n \"}\",\n \"trap terminate TERM INT\",\n 'wait \"$child\"',\n \"exit $?\",\n].join(\"\\n\");\n\ninterface DockerProcessManagerOptions {\n containerName: string;\n dockerPath: string;\n workdir: string;\n env: Record<string, string>;\n maxOutputBytes: number;\n maxProcesses: number;\n startupTimeoutMs: number;\n}\n\ntype MutableProcessInfo = {\n id: string;\n command: string;\n args: string[];\n cwd?: string;\n status: \"running\" | \"exited\" | \"stopped\";\n exitCode?: number;\n startedAt: string;\n endedAt?: string;\n};\n\ninterface ManagedProcessRecord {\n info: MutableProcessInfo;\n child: ChildProcessWithoutNullStreams;\n stdout: TailOutputCollector;\n stderr: TailOutputCollector;\n markerStart: Buffer;\n markerBuffer: Buffer;\n supervisorPid?: number;\n processGroupId?: number;\n spawnFailed: boolean;\n stopRequested: boolean;\n startResolved: boolean;\n resolveStarted: () => void;\n rejectStarted: (error: unknown) => void;\n started: Promise<void>;\n resolveClosed: () => void;\n closed: Promise<void>;\n}\n\nexport class DockerProcessManager {\n private readonly records = new Map<string, ManagedProcessRecord>();\n private disposed = false;\n\n constructor(private readonly options: DockerProcessManagerOptions) {\n if (!Number.isInteger(options.maxProcesses) || options.maxProcesses < 0) {\n throw processError(\"Sandbox maxProcesses must be a non-negative integer.\");\n }\n if (!Number.isInteger(options.maxOutputBytes) || options.maxOutputBytes < 0) {\n throw processError(\"Sandbox maxOutputBytes must be a non-negative integer.\");\n }\n if (!Number.isInteger(options.startupTimeoutMs) || options.startupTimeoutMs <= 0) {\n throw processError(\"Sandbox process startup timeout must be a positive integer.\");\n }\n }\n\n async start(options: DockerSandboxProcessStartOptions): Promise<DockerSandboxProcessInfo> {\n this.assertActive();\n assertStartOptions(options);\n options.abortSignal?.throwIfAborted();\n await this.pruneCompletedRecords(options.abortSignal);\n\n const trackedCount = this.records.size;\n if (trackedCount >= this.options.maxProcesses) {\n throw processError(\n `Sandbox process limit reached (${trackedCount} >= ${this.options.maxProcesses}).`,\n );\n }\n\n const id = randomUUID();\n const marker = `${processMarkerPrefix}:${id}`;\n const dockerArgs = this.createExecArgs(options, marker);\n const child = spawn(this.options.dockerPath, dockerArgs, {\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n\n let resolveStarted!: () => void;\n let rejectStarted!: (error: unknown) => void;\n const started = new Promise<void>((resolve, reject) => {\n resolveStarted = resolve;\n rejectStarted = reject;\n });\n let resolveClosed!: () => void;\n const closed = new Promise<void>((resolve) => {\n resolveClosed = resolve;\n });\n\n const info: MutableProcessInfo = {\n id,\n command: options.command,\n args: [...(options.args ?? [])],\n status: \"running\",\n startedAt: new Date().toISOString(),\n };\n if (options.cwd !== undefined) info.cwd = options.cwd;\n\n const record: ManagedProcessRecord = {\n info,\n child,\n stdout: new TailOutputCollector(this.options.maxOutputBytes),\n stderr: new TailOutputCollector(this.options.maxOutputBytes),\n markerStart: Buffer.from(`\\u001e${marker}:`),\n markerBuffer: Buffer.alloc(0),\n spawnFailed: false,\n stopRequested: false,\n startResolved: false,\n resolveStarted,\n rejectStarted,\n started,\n resolveClosed,\n closed,\n };\n this.records.set(id, record);\n this.observe(record);\n\n try {\n await this.waitForStart(record, options.abortSignal);\n record.startResolved = true;\n return copyProcessInfo(record.info);\n } catch (error) {\n if (await this.cleanupFailedStart(record)) this.records.delete(id);\n throw error;\n }\n }\n\n list(): DockerSandboxProcessInfo[] {\n this.assertActive();\n return [...this.records.values()].map((record) => copyProcessInfo(record.info));\n }\n\n logs(processId: string, tailBytes?: number): DockerSandboxProcessLogs {\n this.assertActive();\n const record = this.getRecord(processId);\n const stdout = record.stdout.snapshot(tailBytes);\n const stderr = record.stderr.snapshot(tailBytes);\n return {\n stdout: stdout.bytes,\n stderr: stderr.bytes,\n stdoutTruncated: stdout.truncated,\n stderrTruncated: stderr.truncated,\n };\n }\n\n async stop(\n processId: string,\n gracePeriodMs = 5_000,\n abortSignal?: AbortSignal,\n ): Promise<DockerSandboxProcessInfo> {\n this.assertActive();\n const record = this.getRecord(processId);\n if (!Number.isInteger(gracePeriodMs) || gracePeriodMs < 0) {\n throw processError(\"Process gracePeriodMs must be a non-negative integer.\");\n }\n\n try {\n if (!(await this.terminateRecord(record, gracePeriodMs, abortSignal))) {\n throw processError(`Sandbox process did not stop: ${processId}`);\n }\n } catch (error) {\n if (record.info.status === \"running\") record.stopRequested = false;\n throw error;\n }\n\n return copyProcessInfo(record.info);\n }\n\n async dispose(abortSignal?: AbortSignal): Promise<void> {\n if (this.disposed) return;\n abortSignal?.throwIfAborted();\n\n await Promise.all(\n [...this.records.values()].map(async (record) => {\n if (!(await this.terminateRecord(record, 1_000, abortSignal))) {\n throw processError(`Sandbox process did not stop: ${record.info.id}`);\n }\n }),\n );\n this.disposed = true;\n }\n\n private createExecArgs(options: DockerSandboxProcessStartOptions, marker: string): string[] {\n const args = [\"exec\", \"-i\", \"-w\", containerPath(this.options.workdir, options.cwd ?? \".\")];\n for (const [key, value] of Object.entries({ ...this.options.env, ...options.env })) {\n args.push(\"-e\", `${key}=${value}`);\n }\n args.push(\n this.options.containerName,\n \"sh\",\n \"-c\",\n processLauncher,\n \"anvia-process-launcher\",\n processWrapper,\n \"anvia-managed-process\",\n marker,\n options.command,\n ...(options.args ?? []),\n );\n return args;\n }\n\n private observe(record: ManagedProcessRecord): void {\n record.child.stdout.on(\"data\", (chunk: Buffer) => this.acceptStdout(record, chunk));\n record.child.stderr.on(\"data\", (chunk: Buffer) => record.stderr.accept(chunk));\n\n record.child.on(\"error\", (error) => {\n record.spawnFailed = true;\n const normalized =\n (error as NodeJS.ErrnoException).code === \"ENOENT\"\n ? new DockerSandboxError(\"Docker CLI was not found.\", \"docker_unavailable\", undefined, {\n cause: error,\n })\n : error;\n record.rejectStarted(normalized);\n });\n\n record.child.on(\"close\", (code) => {\n if (record.markerBuffer.length > 0) {\n record.stdout.accept(record.markerBuffer);\n record.markerBuffer = Buffer.alloc(0);\n }\n record.info.status = record.stopRequested ? \"stopped\" : \"exited\";\n record.info.exitCode = code ?? 1;\n record.info.endedAt = new Date().toISOString();\n record.rejectStarted(\n processError(`Sandbox process exited before startup completed: ${record.info.id}`),\n );\n record.resolveClosed();\n });\n }\n\n private acceptStdout(record: ManagedProcessRecord, chunk: Buffer): void {\n if (record.supervisorPid !== undefined) {\n record.stdout.accept(chunk);\n return;\n }\n\n record.markerBuffer = Buffer.concat([record.markerBuffer, chunk]);\n const start = record.markerBuffer.indexOf(record.markerStart);\n if (start < 0) {\n const retainedBytes = Math.max(0, record.markerStart.length - 1);\n if (record.markerBuffer.length > retainedBytes) {\n const split = record.markerBuffer.length - retainedBytes;\n record.stdout.accept(record.markerBuffer.subarray(0, split));\n record.markerBuffer = record.markerBuffer.subarray(split);\n }\n return;\n }\n\n const end = record.markerBuffer.indexOf(0x1e, start + record.markerStart.length);\n if (end < 0) {\n if (start > 0) {\n record.stdout.accept(record.markerBuffer.subarray(0, start));\n record.markerBuffer = record.markerBuffer.subarray(start);\n }\n return;\n }\n\n const rawPids = decodeUtf8(\n record.markerBuffer.subarray(start + record.markerStart.length, end),\n ).split(\":\");\n const supervisorPid = Number(rawPids[0]);\n const processGroupId = Number(rawPids[1]);\n if (!isProcessId(supervisorPid) || !isProcessId(processGroupId) || rawPids.length !== 2) {\n record.rejectStarted(processError(\"Sandbox process returned invalid process IDs.\"));\n return;\n }\n\n if (start > 0) record.stdout.accept(record.markerBuffer.subarray(0, start));\n if (end + 1 < record.markerBuffer.length) {\n record.stdout.accept(record.markerBuffer.subarray(end + 1));\n }\n record.markerBuffer = Buffer.alloc(0);\n record.supervisorPid = supervisorPid;\n record.processGroupId = processGroupId;\n // Keep stdin attached for the lifetime of `docker exec -i`. Closing it makes the Docker CLI\n // return successfully while the in-container process keeps running, which would orphan the\n // process from status, logs, and lifecycle management.\n record.child.stdin.write(\"start\\n\");\n record.resolveStarted();\n }\n\n private async waitForStart(\n record: ManagedProcessRecord,\n abortSignal: AbortSignal | undefined,\n ): Promise<void> {\n let timeout: ReturnType<typeof setTimeout> | undefined;\n let abort: (() => void) | undefined;\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeout = setTimeout(() => {\n reject(new DockerSandboxError(\"Starting sandbox process timed out.\", \"timeout\"));\n }, this.options.startupTimeoutMs);\n timeout.unref?.();\n });\n\n try {\n const abortPromise = new Promise<never>((_, reject) => {\n if (abortSignal === undefined) return;\n abort = () => reject(abortSignal.reason ?? new DOMException(\"Aborted\", \"AbortError\"));\n if (abortSignal.aborted) abort();\n else abortSignal.addEventListener(\"abort\", abort, { once: true });\n });\n await Promise.race([record.started, timeoutPromise, abortPromise]);\n } finally {\n if (timeout !== undefined) clearTimeout(timeout);\n if (abort !== undefined) abortSignal?.removeEventListener(\"abort\", abort);\n }\n }\n\n private async cleanupFailedStart(record: ManagedProcessRecord): Promise<boolean> {\n record.stopRequested = true;\n if (record.processGroupId === undefined && record.info.status === \"running\") {\n record.child.stdin.destroy();\n record.child.kill(\"SIGKILL\");\n await waitForPromise(record.closed, 1_000);\n }\n\n try {\n return await this.terminateRecord(record, 1_000);\n } catch {\n return false;\n }\n }\n\n private async terminateRecord(\n record: ManagedProcessRecord,\n gracePeriodMs: number,\n abortSignal?: AbortSignal,\n ): Promise<boolean> {\n abortSignal?.throwIfAborted();\n record.stopRequested = true;\n\n if (record.processGroupId === undefined) {\n if (record.info.status === \"running\") {\n await waitForPromise(record.closed, Math.min(gracePeriodMs, 250), abortSignal);\n }\n if (record.processGroupId === undefined) {\n return record.info.status !== \"running\";\n }\n }\n\n if (!(await this.isProcessGroupRunning(record, abortSignal))) {\n return this.finishAfterGroupExit(record, abortSignal);\n }\n\n await this.signal(record, \"TERM\", abortSignal);\n if (await this.waitForRecordExit(record, gracePeriodMs, abortSignal)) return true;\n\n await this.signal(record, \"KILL\", abortSignal);\n if (await this.waitForRecordExit(record, 1_000, abortSignal)) return true;\n\n return false;\n }\n\n private async waitForRecordExit(\n record: ManagedProcessRecord,\n timeoutMs: number,\n abortSignal?: AbortSignal,\n ): Promise<boolean> {\n const deadline = Date.now() + timeoutMs;\n while (true) {\n abortSignal?.throwIfAborted();\n if (!(await this.isProcessGroupRunning(record, abortSignal))) {\n return this.finishAfterGroupExit(record, abortSignal);\n }\n\n const remainingMs = deadline - Date.now();\n if (remainingMs <= 0) return false;\n const intervalMs = Math.min(50, remainingMs);\n if (record.info.status === \"running\") {\n await waitForPromise(record.closed, intervalMs, abortSignal);\n } else {\n await waitForDelay(intervalMs, abortSignal);\n }\n }\n }\n\n private async finishAfterGroupExit(\n record: ManagedProcessRecord,\n abortSignal?: AbortSignal,\n ): Promise<boolean> {\n if (record.info.status !== \"running\") return true;\n record.child.kill(\"SIGKILL\");\n return waitForPromise(record.closed, 1_000, abortSignal);\n }\n\n private async isProcessGroupRunning(\n record: ManagedProcessRecord,\n abortSignal?: AbortSignal,\n ): Promise<boolean> {\n if (record.processGroupId === undefined) return false;\n const result = await runDockerCli(\n [\n \"exec\",\n this.options.containerName,\n \"sh\",\n \"-c\",\n 'kill -0 \"-$1\" 2>/dev/null',\n \"anvia-process-group-check\",\n `${record.processGroupId}`,\n ],\n {\n dockerPath: this.options.dockerPath,\n timeoutMs: 5_000,\n maxOutputBytes: this.options.maxOutputBytes,\n signal: abortSignal,\n },\n );\n return result.exitCode === 0;\n }\n\n private async signal(\n record: ManagedProcessRecord,\n dockerSignal: \"TERM\" | \"KILL\",\n abortSignal?: AbortSignal,\n ): Promise<void> {\n if (record.processGroupId === undefined) return;\n const result = await runDockerCli(\n [\n \"exec\",\n this.options.containerName,\n \"sh\",\n \"-c\",\n 'kill \"-$2\" \"-$1\" 2>/dev/null || ! kill -0 \"-$1\" 2>/dev/null',\n \"anvia-process-signal\",\n `${record.processGroupId}`,\n dockerSignal,\n ],\n {\n dockerPath: this.options.dockerPath,\n timeoutMs: 5_000,\n maxOutputBytes: this.options.maxOutputBytes,\n signal: abortSignal,\n },\n );\n if (result.exitCode !== 0) {\n throw new DockerSandboxError(\n `Unable to stop sandbox process: ${record.info.id}`,\n \"docker_command_failed\",\n result,\n );\n }\n }\n\n private getRecord(processId: string): ManagedProcessRecord {\n const record = this.records.get(processId);\n if (record === undefined) {\n throw processError(`Unknown sandbox process: ${processId}`);\n }\n return record;\n }\n\n private async pruneCompletedRecords(abortSignal?: AbortSignal): Promise<void> {\n for (const [id, record] of this.records) {\n if (this.records.size < this.options.maxProcesses) return;\n const cleanupConfirmed =\n record.processGroupId === undefined\n ? record.spawnFailed\n : !(await this.isProcessGroupRunning(record, abortSignal));\n if (record.info.status !== \"running\" && cleanupConfirmed) {\n this.records.delete(id);\n }\n }\n }\n\n private assertActive(): void {\n if (this.disposed) {\n throw processError(\"Sandbox process manager has been disposed.\");\n }\n }\n}\n\nclass TailOutputCollector {\n private chunks: Buffer[] = [];\n private length = 0;\n private didTruncate = false;\n\n constructor(private readonly maxBytes: number) {}\n\n accept(chunk: Buffer): void {\n if (chunk.length === 0) return;\n if (this.maxBytes <= 0) {\n this.didTruncate = true;\n return;\n }\n\n if (chunk.length >= this.maxBytes) {\n this.chunks = [chunk.subarray(chunk.length - this.maxBytes)];\n this.length = this.maxBytes;\n this.didTruncate = true;\n return;\n }\n\n this.chunks.push(chunk);\n this.length += chunk.length;\n while (this.length > this.maxBytes) {\n const first = this.chunks[0];\n if (first === undefined) break;\n const overflow = this.length - this.maxBytes;\n if (first.length <= overflow) {\n this.chunks.shift();\n this.length -= first.length;\n } else {\n this.chunks[0] = first.subarray(overflow);\n this.length -= overflow;\n }\n this.didTruncate = true;\n }\n }\n\n snapshot(tailBytes?: number): { bytes: Uint8Array; truncated: boolean } {\n if (tailBytes !== undefined && (!Number.isInteger(tailBytes) || tailBytes < 0)) {\n throw processError(\"Process tailBytes must be a non-negative integer.\");\n }\n const bytes = Buffer.concat(this.chunks, this.length);\n const selected =\n tailBytes === 0\n ? Buffer.alloc(0)\n : tailBytes === undefined || bytes.length <= tailBytes\n ? bytes\n : bytes.subarray(bytes.length - tailBytes);\n return {\n bytes: new Uint8Array(selected.buffer, selected.byteOffset, selected.byteLength).slice(),\n truncated: this.didTruncate || selected.length < bytes.length,\n };\n }\n}\n\nfunction processError(message: string): DockerSandboxError {\n return new DockerSandboxError(message, \"process\");\n}\n\nfunction assertStartOptions(options: DockerSandboxProcessStartOptions): void {\n if (options.command.trim().length === 0) {\n throw processError(\"Sandbox process command cannot be empty.\");\n }\n}\n\nfunction isProcessId(value: number): boolean {\n return Number.isSafeInteger(value) && value > 0;\n}\n\nfunction copyProcessInfo(info: DockerSandboxProcessInfo): DockerSandboxProcessInfo {\n let copy: DockerSandboxProcessInfo = {\n id: info.id,\n command: info.command,\n args: [...info.args],\n status: info.status,\n startedAt: info.startedAt,\n };\n if (info.cwd !== undefined) copy = { ...copy, cwd: info.cwd };\n if (info.exitCode !== undefined) copy = { ...copy, exitCode: info.exitCode };\n if (info.endedAt !== undefined) copy = { ...copy, endedAt: info.endedAt };\n return copy;\n}\n\nasync function waitForPromise(\n promise: Promise<void>,\n timeoutMs: number,\n abortSignal?: AbortSignal,\n): Promise<boolean> {\n abortSignal?.throwIfAborted();\n let timeout: ReturnType<typeof setTimeout> | undefined;\n let abort: (() => void) | undefined;\n try {\n return await Promise.race([\n promise.then(() => true),\n new Promise<boolean>((resolve) => {\n timeout = setTimeout(() => resolve(false), timeoutMs);\n timeout.unref?.();\n }),\n new Promise<boolean>((_, reject) => {\n if (abortSignal === undefined) return;\n abort = () => reject(abortSignal.reason ?? new DOMException(\"Aborted\", \"AbortError\"));\n if (abortSignal.aborted) abort();\n else abortSignal.addEventListener(\"abort\", abort, { once: true });\n }),\n ]);\n } finally {\n if (timeout !== undefined) clearTimeout(timeout);\n if (abort !== undefined) abortSignal?.removeEventListener(\"abort\", abort);\n }\n}\n\nasync function waitForDelay(timeoutMs: number, abortSignal?: AbortSignal): Promise<void> {\n await waitForPromise(\n new Promise<void>((resolve) => {\n const timeout = setTimeout(resolve, timeoutMs);\n timeout.unref?.();\n }),\n timeoutMs,\n abortSignal,\n );\n}\n","import path from \"node:path\";\nimport { DockerSandboxError } from \"./errors\";\n\nexport function normalizeSandboxPath(input: string, options: { allowRoot?: boolean } = {}): string {\n if (input.length === 0) {\n throw new DockerSandboxError(\"Sandbox path cannot be empty.\", \"invalid_path\");\n }\n\n if (input.includes(\"\\0\")) {\n throw new DockerSandboxError(\"Sandbox path cannot contain null bytes.\", \"invalid_path\");\n }\n\n const normalized = path.posix.normalize(input.replaceAll(\"\\\\\", \"/\"));\n\n if (path.posix.isAbsolute(normalized)) {\n throw new DockerSandboxError(`Sandbox path must be relative: ${input}`, \"invalid_path\");\n }\n\n if (normalized === \"..\" || normalized.startsWith(\"../\")) {\n throw new DockerSandboxError(\n `Sandbox path cannot leave the workspace: ${input}`,\n \"invalid_path\",\n );\n }\n\n if (normalized === \".\" && options.allowRoot !== true) {\n throw new DockerSandboxError(\n \"Sandbox path must refer to a file or directory inside the workspace.\",\n \"invalid_path\",\n );\n }\n\n return normalized;\n}\n\nexport function containerPath(workdir: string, relativePath: string): string {\n const normalizedWorkdir = path.posix.normalize(workdir);\n const normalizedPath = normalizeSandboxPath(relativePath, { allowRoot: true });\n return normalizedPath === \".\"\n ? normalizedWorkdir\n : path.posix.join(normalizedWorkdir, normalizedPath);\n}\n\nexport function parentSandboxPath(relativePath: string): string {\n const normalized = normalizeSandboxPath(relativePath);\n const parent = path.posix.dirname(normalized);\n return parent === \".\" ? \".\" : parent;\n}\n","import type { DockerSandboxTextFilePage } from \"./types\";\n\ninterface CreateTextFilePageOptions {\n startLine: number;\n lineCount: number;\n maxBytes: number;\n contentStartLine?: number;\n}\n\nexport function createTextFilePage(\n text: string,\n options: CreateTextFilePageOptions,\n): DockerSandboxTextFilePage {\n const contentStartLine = options.contentStartLine ?? 1;\n const relativeStart = Math.max(0, options.startLine - contentStartLine);\n const lines = splitLines(text).slice(relativeStart, relativeStart + options.lineCount + 1);\n const hasMoreLines = lines.length > options.lineCount;\n const selectedLines = lines.slice(0, options.lineCount);\n const selectedContent = selectedLines.join(\"\");\n const selectedBytes = Buffer.from(selectedContent);\n\n if (selectedBytes.byteLength > options.maxBytes) {\n const content = decodeCompleteUtf8(selectedBytes.subarray(0, options.maxBytes));\n const lineBreaks = countLineBreaks(content);\n const endedAtLineBoundary = content.endsWith(\"\\n\");\n return {\n content,\n startLine: options.startLine,\n endLine:\n content.length === 0\n ? null\n : options.startLine + lineBreaks - (endedAtLineBoundary ? 1 : 0),\n nextStartLine: endedAtLineBoundary ? options.startLine + lineBreaks : null,\n truncated: true,\n truncatedBy: \"bytes\",\n };\n }\n\n return {\n content: selectedContent,\n startLine: options.startLine,\n endLine: selectedLines.length === 0 ? null : options.startLine + selectedLines.length - 1,\n nextStartLine: hasMoreLines ? options.startLine + selectedLines.length : null,\n truncated: hasMoreLines,\n truncatedBy: hasMoreLines ? \"lines\" : null,\n };\n}\n\nfunction splitLines(text: string): string[] {\n return text.match(/[^\\n]*\\n|[^\\n]+$/g) ?? [];\n}\n\nfunction countLineBreaks(text: string): number {\n let count = 0;\n for (const character of text) {\n if (character === \"\\n\") count += 1;\n }\n return count;\n}\n\nfunction decodeCompleteUtf8(bytes: Uint8Array): string {\n return new TextDecoder().decode(bytes, { stream: true });\n}\n","import { type AnyTool, createTool } from \"@anvia/core/tool\";\nimport { z } from \"zod\";\nimport { decodeUtf8 } from \"./docker-cli\";\nimport { DockerSandboxError } from \"./errors\";\nimport type {\n CreateDockerSandboxToolsOptions,\n DockerSandboxCommandPolicy,\n DockerSandboxExecOptions,\n DockerSandboxExecResult,\n DockerSandboxProcessInfo,\n DockerSandboxRuntime,\n DockerSandboxToolName,\n} from \"./types\";\n\nconst allToolNames = [\n \"exec_command\",\n \"read_file\",\n \"write_file\",\n \"list_files\",\n \"list_ports\",\n \"start_process\",\n \"list_processes\",\n \"read_process_logs\",\n \"stop_process\",\n \"wait_for_port\",\n] as const satisfies readonly DockerSandboxToolName[];\n\nconst execCommandInput = z.object({\n command: z.string().min(1),\n args: z.array(z.string()).optional(),\n cwd: z.string().optional(),\n env: z.record(z.string(), z.string()).optional(),\n timeoutMs: z.number().int().positive().max(300_000).optional(),\n input: z.string().optional(),\n});\n\nconst execResultOutput = z.discriminatedUnion(\"status\", [\n z.object({\n status: z.literal(\"exited\"),\n exitCode: z.number().int(),\n stdout: z.string(),\n stderr: z.string(),\n durationMs: z.number().nonnegative(),\n stdoutTruncated: z.boolean(),\n stderrTruncated: z.boolean(),\n }),\n z.object({\n status: z.literal(\"timed_out\"),\n stdout: z.string(),\n stderr: z.string(),\n durationMs: z.number().nonnegative(),\n stdoutTruncated: z.boolean(),\n stderrTruncated: z.boolean(),\n }),\n]);\n\nconst readFileInput = z.object({\n path: z.string().min(1),\n startLine: z.number().int().positive().optional(),\n lineCount: z.number().int().positive().max(10_000).optional(),\n});\n\nconst readFileOutput = z.object({\n content: z.string(),\n startLine: z.number().int().positive(),\n endLine: z.number().int().positive().nullable(),\n nextStartLine: z.number().int().positive().nullable(),\n truncated: z.boolean(),\n truncatedBy: z.enum([\"lines\", \"bytes\"]).nullable(),\n});\n\nconst writeFileInput = z.object({\n path: z.string().min(1),\n content: z.string(),\n});\n\nconst writeFileOutput = z.object({\n path: z.string(),\n bytesWritten: z.number().int().nonnegative(),\n});\n\nconst listFilesInput = z.object({ path: z.string().optional() });\nconst fileEntryOutput = z.object({\n path: z.string(),\n type: z.enum([\"file\", \"directory\", \"symlink\", \"other\"]),\n size: z.number().int().nonnegative().optional(),\n});\nconst listFilesOutput = z.object({\n path: z.string(),\n entries: z.array(fileEntryOutput),\n});\n\nconst emptyInput = z.object({});\nconst publishedPortOutput = z.object({\n containerPort: z.number().int(),\n host: z.literal(\"127.0.0.1\"),\n hostPort: z.number().int(),\n protocol: z.literal(\"tcp\"),\n});\nconst listPortsOutput = z.object({ ports: z.array(publishedPortOutput) });\n\nconst startProcessInput = z.object({\n command: z.string().min(1),\n args: z.array(z.string()).optional(),\n cwd: z.string().optional(),\n env: z.record(z.string(), z.string()).optional(),\n});\nconst processInfoOutput = z.object({\n id: z.string(),\n command: z.string(),\n args: z.array(z.string()),\n cwd: z.string().optional(),\n status: z.enum([\"running\", \"exited\", \"stopped\"]),\n exitCode: z.number().int().optional(),\n startedAt: z.string(),\n endedAt: z.string().optional(),\n});\nconst listProcessesOutput = z.object({ processes: z.array(processInfoOutput) });\n\nconst processIdInput = z.object({ processId: z.string().min(1) });\nconst readProcessLogsInput = processIdInput.extend({\n tailBytes: z\n .number()\n .int()\n .nonnegative()\n .max(1024 * 1024)\n .optional(),\n});\nconst processLogsOutput = z.object({\n processId: z.string(),\n stdout: z.string(),\n stderr: z.string(),\n stdoutTruncated: z.boolean(),\n stderrTruncated: z.boolean(),\n});\n\nconst waitForPortInput = z.object({\n containerPort: z.number().int().min(1).max(65_535),\n timeoutMs: z.number().int().positive().max(300_000).optional(),\n});\nconst waitForPortOutput = z.object({ port: publishedPortOutput });\n\nconst defaultReadFileLineCount = 500;\nconst defaultReadFileMaxLineCount = 2_000;\nconst defaultReadFileMaxBytes = 64 * 1024;\nconst maxToolReadFileLines = 10_000;\nconst maxToolBytes = 1024 * 1024;\nconst maxToolTimeoutMs = 300_000;\n\nexport function createDockerSandboxTools(\n options: CreateDockerSandboxToolsOptions,\n): readonly AnyTool[] {\n validateFactoryOptions(options);\n options = snapshotFactoryOptions(options);\n const selected = new Set(options.tools);\n const tools: AnyTool[] = [];\n\n for (const name of options.tools) {\n if (name === \"exec_command\") tools.push(createExecCommandTool(options));\n else if (name === \"read_file\") tools.push(createReadFileTool(options));\n else if (name === \"write_file\") tools.push(createWriteFileTool(options));\n else if (name === \"list_files\") tools.push(createListFilesTool(options.sandbox));\n else if (name === \"list_ports\") tools.push(createListPortsTool(options.sandbox));\n else if (name === \"start_process\") tools.push(createStartProcessTool(options));\n else if (name === \"list_processes\") tools.push(createListProcessesTool(options.sandbox));\n else if (name === \"read_process_logs\") tools.push(createReadProcessLogsTool(options));\n else if (name === \"stop_process\") tools.push(createStopProcessTool(options));\n else if (name === \"wait_for_port\") tools.push(createWaitForPortTool(options));\n }\n\n if (tools.length !== selected.size) {\n throw toolPolicyError(\"Sandbox tool selection contains an unsupported tool name.\");\n }\n return Object.freeze(tools);\n}\n\nfunction createExecCommandTool(options: CreateDockerSandboxToolsOptions): AnyTool {\n return createTool({\n name: \"exec_command\",\n description: \"Run one executable inside the sandbox with structured arguments.\",\n inputSchema: execCommandInput,\n outputSchema: execResultOutput,\n execute: async ({ command, args, cwd, env, timeoutMs, input }, context) => {\n assertCommandAllowed(command, options.exec?.commands);\n const effectiveTimeoutMs = timeoutMs ?? options.exec?.defaultTimeoutMs;\n assertTimeoutAllowed(effectiveTimeoutMs, options.exec?.maxTimeoutMs);\n let execOptions: DockerSandboxExecOptions = {\n command,\n };\n if (args !== undefined) execOptions = { ...execOptions, args };\n if (cwd !== undefined) execOptions = { ...execOptions, cwd };\n if (env !== undefined) execOptions = { ...execOptions, env };\n if (effectiveTimeoutMs !== undefined) {\n execOptions = { ...execOptions, timeoutMs: effectiveTimeoutMs };\n }\n if (input !== undefined) execOptions = { ...execOptions, input };\n if (context.abortSignal !== undefined) {\n execOptions = { ...execOptions, abortSignal: context.abortSignal };\n }\n return serializeExecResult(await options.sandbox.exec(execOptions));\n },\n });\n}\n\nfunction createReadFileTool(options: CreateDockerSandboxToolsOptions): AnyTool {\n const limits = resolveReadFileLimits(options);\n return createTool({\n name: \"read_file\",\n description: \"Read a bounded page of a UTF-8 text file from the sandbox workspace.\",\n inputSchema: readFileInput,\n outputSchema: readFileOutput,\n execute: async ({ path, startLine, lineCount }, context) => {\n const effectiveLineCount = lineCount ?? limits.defaultLineCount;\n if (effectiveLineCount > limits.maxLineCount) {\n throw toolPolicyError(\n `File read line count exceeds policy (${effectiveLineCount} > ${limits.maxLineCount}).`,\n );\n }\n let readOptions: Parameters<typeof options.sandbox.readTextFilePage>[0] = {\n path,\n startLine: startLine ?? 1,\n lineCount: effectiveLineCount,\n maxBytes: limits.maxBytes,\n };\n if (context.abortSignal !== undefined) {\n readOptions = { ...readOptions, abortSignal: context.abortSignal };\n }\n return options.sandbox.readTextFilePage(readOptions);\n },\n });\n}\n\nfunction createWriteFileTool(options: CreateDockerSandboxToolsOptions): AnyTool {\n return createTool({\n name: \"write_file\",\n description: \"Write a complete UTF-8 text file inside the sandbox workspace.\",\n inputSchema: writeFileInput,\n outputSchema: writeFileOutput,\n execute: async ({ path, content }, context) => {\n const bytesWritten = new TextEncoder().encode(content).byteLength;\n const maxBytes = options.writeFile?.maxBytes;\n if (maxBytes !== undefined && bytesWritten > maxBytes) {\n throw toolPolicyError(`File content exceeds policy (${bytesWritten} > ${maxBytes}).`);\n }\n let writeOptions: Parameters<typeof options.sandbox.writeTextFile>[0] = {\n path,\n text: content,\n };\n if (context.abortSignal !== undefined) {\n writeOptions = { ...writeOptions, abortSignal: context.abortSignal };\n }\n await options.sandbox.writeTextFile(writeOptions);\n return { path, bytesWritten };\n },\n });\n}\n\nfunction createListFilesTool(sandbox: DockerSandboxRuntime): AnyTool {\n return createTool({\n name: \"list_files\",\n description: \"List direct children of a directory in the sandbox workspace.\",\n inputSchema: listFilesInput,\n outputSchema: listFilesOutput,\n execute: async ({ path }, context) => {\n let listOptions: Parameters<typeof sandbox.listFiles>[0] = {};\n if (path !== undefined) listOptions = { ...listOptions, path };\n if (context.abortSignal !== undefined) {\n listOptions = { ...listOptions, abortSignal: context.abortSignal };\n }\n return { path: path ?? \".\", entries: [...(await sandbox.listFiles(listOptions))] };\n },\n });\n}\n\nfunction createListPortsTool(sandbox: DockerSandboxRuntime): AnyTool {\n return createTool({\n name: \"list_ports\",\n description: \"List explicitly published localhost TCP ports for the sandbox.\",\n inputSchema: emptyInput,\n outputSchema: listPortsOutput,\n execute: async () => ({ ports: [...sandbox.publishedPorts] }),\n });\n}\n\nfunction createStartProcessTool(options: CreateDockerSandboxToolsOptions): AnyTool {\n return createTool({\n name: \"start_process\",\n description: \"Start a managed long-running process inside the sandbox.\",\n inputSchema: startProcessInput,\n outputSchema: processInfoOutput,\n execute: async ({ command, args, cwd, env }, context) => {\n assertCommandAllowed(command, options.exec?.commands);\n let startOptions: Parameters<typeof options.sandbox.startProcess>[0] = { command };\n if (args !== undefined) startOptions = { ...startOptions, args };\n if (cwd !== undefined) startOptions = { ...startOptions, cwd };\n if (env !== undefined) startOptions = { ...startOptions, env };\n if (context.abortSignal !== undefined) {\n startOptions = { ...startOptions, abortSignal: context.abortSignal };\n }\n return serializeProcessInfo(await options.sandbox.startProcess(startOptions));\n },\n });\n}\n\nfunction createListProcessesTool(sandbox: DockerSandboxRuntime): AnyTool {\n return createTool({\n name: \"list_processes\",\n description: \"List processes managed by this live sandbox handle.\",\n inputSchema: emptyInput,\n outputSchema: listProcessesOutput,\n execute: async (_, context) => ({\n processes: (\n await sandbox.listProcesses(\n context.abortSignal === undefined ? {} : { abortSignal: context.abortSignal },\n )\n ).map(serializeProcessInfo),\n }),\n });\n}\n\nfunction createReadProcessLogsTool(options: CreateDockerSandboxToolsOptions): AnyTool {\n const maxLogBytes = options.process?.maxLogBytes ?? 64 * 1024;\n return createTool({\n name: \"read_process_logs\",\n description: \"Read bounded UTF-8 output from a managed sandbox process.\",\n inputSchema: readProcessLogsInput,\n outputSchema: processLogsOutput,\n execute: async ({ processId, tailBytes }, context) => {\n const effectiveTailBytes = tailBytes ?? maxLogBytes;\n if (effectiveTailBytes > maxLogBytes) {\n throw toolPolicyError(\n `Process log request exceeds policy (${effectiveTailBytes} > ${maxLogBytes}).`,\n );\n }\n let readOptions: Parameters<typeof options.sandbox.readProcessLogs>[0] = {\n processId,\n tailBytes: effectiveTailBytes,\n };\n if (context.abortSignal !== undefined) {\n readOptions = { ...readOptions, abortSignal: context.abortSignal };\n }\n const logs = await options.sandbox.readProcessLogs(readOptions);\n return {\n processId,\n stdout: decodeUtf8(logs.stdout),\n stderr: decodeUtf8(logs.stderr),\n stdoutTruncated: logs.stdoutTruncated,\n stderrTruncated: logs.stderrTruncated,\n };\n },\n });\n}\n\nfunction createStopProcessTool(options: CreateDockerSandboxToolsOptions): AnyTool {\n return createTool({\n name: \"stop_process\",\n description: \"Stop a process managed by this live sandbox handle.\",\n inputSchema: processIdInput,\n outputSchema: processInfoOutput,\n execute: async ({ processId }, context) => {\n let stopOptions: Parameters<typeof options.sandbox.stopProcess>[0] = {\n processId,\n gracePeriodMs: options.process?.stopGracePeriodMs ?? 5_000,\n };\n if (context.abortSignal !== undefined) {\n stopOptions = { ...stopOptions, abortSignal: context.abortSignal };\n }\n return serializeProcessInfo(await options.sandbox.stopProcess(stopOptions));\n },\n });\n}\n\nfunction createWaitForPortTool(options: CreateDockerSandboxToolsOptions): AnyTool {\n return createTool({\n name: \"wait_for_port\",\n description: \"Wait until an explicitly published sandbox TCP port is listening.\",\n inputSchema: waitForPortInput,\n outputSchema: waitForPortOutput,\n execute: async ({ containerPort, timeoutMs }, context) => {\n const effectiveTimeoutMs = timeoutMs ?? options.process?.defaultWaitTimeoutMs ?? 30_000;\n const maxWaitTimeoutMs = options.process?.maxWaitTimeoutMs ?? maxToolTimeoutMs;\n if (effectiveTimeoutMs > maxWaitTimeoutMs) {\n throw toolPolicyError(\n `Port wait timeout exceeds policy (${effectiveTimeoutMs} > ${maxWaitTimeoutMs}).`,\n );\n }\n let waitOptions: Parameters<typeof options.sandbox.waitForPort>[0] = {\n containerPort,\n timeoutMs: effectiveTimeoutMs,\n };\n if (context.abortSignal !== undefined) {\n waitOptions = { ...waitOptions, abortSignal: context.abortSignal };\n }\n return { port: await options.sandbox.waitForPort(waitOptions) };\n },\n });\n}\n\nfunction serializeExecResult(result: DockerSandboxExecResult) {\n const output = {\n status: result.status,\n stdout: decodeUtf8(result.stdout),\n stderr: decodeUtf8(result.stderr),\n durationMs: result.durationMs,\n stdoutTruncated: result.stdoutTruncated,\n stderrTruncated: result.stderrTruncated,\n };\n return result.status === \"exited\"\n ? { ...output, status: \"exited\" as const, exitCode: result.exitCode }\n : { ...output, status: \"timed_out\" as const };\n}\n\nfunction serializeProcessInfo(\n process: DockerSandboxProcessInfo,\n): z.infer<typeof processInfoOutput> {\n let serialized: z.infer<typeof processInfoOutput> = {\n id: process.id,\n command: process.command,\n args: [...process.args],\n status: process.status,\n startedAt: process.startedAt,\n };\n if (process.cwd !== undefined) serialized = { ...serialized, cwd: process.cwd };\n if (process.exitCode !== undefined) serialized = { ...serialized, exitCode: process.exitCode };\n if (process.endedAt !== undefined) serialized = { ...serialized, endedAt: process.endedAt };\n return serialized;\n}\n\nfunction validateFactoryOptions(options: CreateDockerSandboxToolsOptions): void {\n if (!isRecord(options)) {\n throw new TypeError(\"options must be an object.\");\n }\n if (!isDockerSandboxRuntime(options.sandbox)) {\n throw new TypeError(\"sandbox must be a DockerSandboxRuntime.\");\n }\n if (!Array.isArray(options.tools) || options.tools.length === 0) {\n throw new TypeError(\"tools must be a non-empty array.\");\n }\n const known = new Set<string>(allToolNames);\n const seen = new Set<string>();\n for (const name of options.tools as readonly unknown[]) {\n if (typeof name !== \"string\" || !known.has(name)) {\n throw new TypeError(\"tools contains an unsupported sandbox tool name.\");\n }\n if (seen.has(name)) throw new TypeError(`tools contains a duplicate: ${name}`);\n seen.add(name);\n }\n for (const [name, policy] of [\n [\"exec\", options.exec],\n [\"readFile\", options.readFile],\n [\"writeFile\", options.writeFile],\n [\"process\", options.process],\n ] as const) {\n if (policy !== undefined && !isRecord(policy)) {\n throw new TypeError(`${name} must be an object.`);\n }\n }\n validateCommandPolicy(options.exec?.commands);\n assertOptionalPositiveInteger(options.exec?.defaultTimeoutMs, \"exec.defaultTimeoutMs\");\n assertOptionalPositiveInteger(options.exec?.maxTimeoutMs, \"exec.maxTimeoutMs\");\n if (\n (options.exec?.defaultTimeoutMs ?? 0) > maxToolTimeoutMs ||\n (options.exec?.maxTimeoutMs ?? 0) > maxToolTimeoutMs\n ) {\n throw toolPolicyError(`Sandbox tool command timeouts cannot exceed ${maxToolTimeoutMs}.`);\n }\n if (\n options.exec?.defaultTimeoutMs !== undefined &&\n options.exec.maxTimeoutMs !== undefined &&\n options.exec.defaultTimeoutMs > options.exec.maxTimeoutMs\n ) {\n throw toolPolicyError(\"exec.defaultTimeoutMs cannot exceed exec.maxTimeoutMs.\");\n }\n assertOptionalBoundedPositiveInteger(options.readFile?.maxBytes, \"readFile.maxBytes\");\n assertOptionalPositiveInteger(options.readFile?.defaultLineCount, \"readFile.defaultLineCount\");\n assertOptionalPositiveInteger(options.readFile?.maxLineCount, \"readFile.maxLineCount\");\n assertOptionalBoundedNonNegativeInteger(options.writeFile?.maxBytes, \"writeFile.maxBytes\");\n assertOptionalBoundedNonNegativeInteger(options.process?.maxLogBytes, \"process.maxLogBytes\");\n assertOptionalPositiveInteger(\n options.process?.defaultWaitTimeoutMs,\n \"process.defaultWaitTimeoutMs\",\n );\n assertOptionalPositiveInteger(options.process?.maxWaitTimeoutMs, \"process.maxWaitTimeoutMs\");\n assertOptionalNonNegativeInteger(options.process?.stopGracePeriodMs, \"process.stopGracePeriodMs\");\n const defaultWaitTimeoutMs = options.process?.defaultWaitTimeoutMs;\n const maxWaitTimeoutMs = options.process?.maxWaitTimeoutMs ?? maxToolTimeoutMs;\n if (maxWaitTimeoutMs > maxToolTimeoutMs) {\n throw toolPolicyError(`process.maxWaitTimeoutMs cannot exceed ${maxToolTimeoutMs}.`);\n }\n if (defaultWaitTimeoutMs !== undefined && defaultWaitTimeoutMs > maxWaitTimeoutMs) {\n throw toolPolicyError(\"process.defaultWaitTimeoutMs cannot exceed process.maxWaitTimeoutMs.\");\n }\n}\n\nfunction snapshotFactoryOptions(\n options: CreateDockerSandboxToolsOptions,\n): CreateDockerSandboxToolsOptions {\n const toolNames = Object.freeze([...options.tools]) as unknown as readonly [\n DockerSandboxToolName,\n ...DockerSandboxToolName[],\n ];\n const commands =\n options.exec?.commands === undefined\n ? undefined\n : Object.freeze({\n mode: options.exec.commands.mode,\n values: Object.freeze([...options.exec.commands.values]),\n });\n let snapshot: CreateDockerSandboxToolsOptions = {\n sandbox: options.sandbox,\n tools: toolNames,\n };\n if (options.exec !== undefined) {\n let exec = { ...options.exec };\n if (commands !== undefined) exec = { ...exec, commands };\n snapshot = { ...snapshot, exec: Object.freeze(exec) };\n }\n if (options.readFile !== undefined) {\n snapshot = { ...snapshot, readFile: Object.freeze({ ...options.readFile }) };\n }\n if (options.writeFile !== undefined) {\n snapshot = { ...snapshot, writeFile: Object.freeze({ ...options.writeFile }) };\n }\n if (options.process !== undefined) {\n snapshot = { ...snapshot, process: Object.freeze({ ...options.process }) };\n }\n return Object.freeze(snapshot);\n}\n\nfunction validateCommandPolicy(policy: DockerSandboxCommandPolicy | undefined): void {\n if (policy === undefined) return;\n if (!isRecord(policy)) throw toolPolicyError(\"exec.commands must be an object.\");\n if (policy.mode !== \"allow\" && policy.mode !== \"block\") {\n throw toolPolicyError(\"exec.commands must use mode allow or block.\");\n }\n if (!Array.isArray(policy.values))\n throw toolPolicyError(\"exec.commands.values must be an array.\");\n const seen = new Set<string>();\n for (const value of policy.values as readonly unknown[]) {\n if (typeof value !== \"string\" || value.length === 0) {\n throw toolPolicyError(\"exec.commands.values must contain non-empty strings.\");\n }\n if (seen.has(value))\n throw toolPolicyError(`exec.commands.values contains a duplicate: ${value}`);\n seen.add(value);\n }\n}\n\nfunction assertCommandAllowed(\n command: string,\n policy: DockerSandboxCommandPolicy | undefined,\n): void {\n if (policy === undefined) return;\n const included = policy.values.includes(command);\n if ((policy.mode === \"allow\" && !included) || (policy.mode === \"block\" && included)) {\n throw toolPolicyError(`Command is rejected by sandbox tool policy: ${command}`);\n }\n}\n\nfunction assertTimeoutAllowed(timeoutMs: number | undefined, maxTimeoutMs: number | undefined) {\n if (timeoutMs !== undefined && maxTimeoutMs !== undefined && timeoutMs > maxTimeoutMs) {\n throw toolPolicyError(`Command timeout exceeds policy (${timeoutMs} > ${maxTimeoutMs}).`);\n }\n}\n\nfunction resolveReadFileLimits(options: CreateDockerSandboxToolsOptions) {\n const defaultLineCount = options.readFile?.defaultLineCount ?? defaultReadFileLineCount;\n const maxLineCount = options.readFile?.maxLineCount ?? defaultReadFileMaxLineCount;\n const maxBytes = options.readFile?.maxBytes ?? defaultReadFileMaxBytes;\n if (defaultLineCount > maxLineCount) {\n throw toolPolicyError(\"readFile.defaultLineCount cannot exceed readFile.maxLineCount.\");\n }\n if (maxLineCount > maxToolReadFileLines) {\n throw toolPolicyError(`readFile.maxLineCount cannot exceed ${maxToolReadFileLines}.`);\n }\n return { defaultLineCount, maxLineCount, maxBytes };\n}\n\nfunction assertOptionalPositiveInteger(value: number | undefined, name: string): void {\n if (value !== undefined && (!Number.isSafeInteger(value) || value <= 0)) {\n throw toolPolicyError(`${name} must be a positive safe integer.`);\n }\n}\n\nfunction assertOptionalNonNegativeInteger(value: number | undefined, name: string): void {\n if (value !== undefined && (!Number.isSafeInteger(value) || value < 0)) {\n throw toolPolicyError(`${name} must be a non-negative safe integer.`);\n }\n}\n\nfunction assertOptionalBoundedNonNegativeInteger(value: number | undefined, name: string): void {\n assertOptionalNonNegativeInteger(value, name);\n if (value !== undefined && value > maxToolBytes) {\n throw toolPolicyError(`${name} cannot exceed ${maxToolBytes}.`);\n }\n}\n\nfunction assertOptionalBoundedPositiveInteger(value: number | undefined, name: string): void {\n assertOptionalPositiveInteger(value, name);\n if (value !== undefined && value > maxToolBytes) {\n throw toolPolicyError(`${name} cannot exceed ${maxToolBytes}.`);\n }\n}\n\nfunction isDockerSandboxRuntime(value: unknown): value is DockerSandboxRuntime {\n if (!isRecord(value)) return false;\n return (\n typeof value.id === \"string\" &&\n value.provider === \"docker\" &&\n typeof value.workdir === \"string\" &&\n Array.isArray(value.publishedPorts) &&\n [\n \"exec\",\n \"execStream\",\n \"readFile\",\n \"readTextFile\",\n \"readTextFilePage\",\n \"writeFile\",\n \"writeTextFile\",\n \"listFiles\",\n \"startProcess\",\n \"listProcesses\",\n \"readProcessLogs\",\n \"stopProcess\",\n \"waitForPort\",\n ].every((name) => typeof value[name] === \"function\")\n );\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction toolPolicyError(message: string): DockerSandboxError {\n return new DockerSandboxError(message, \"tool_policy\");\n}\n"],"mappings":"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","names":["randomUUID","path","randomUUID","path","path","isRecord"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anvia/sandbox",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"description": "Sandboxed workspace tools for Anvia agents.",
|
|
5
5
|
"author": "anvia",
|
|
6
6
|
"license": "MIT",
|
|
@@ -36,10 +36,10 @@
|
|
|
36
36
|
"tsup": "^8.5.0",
|
|
37
37
|
"typescript": "^5.9.3",
|
|
38
38
|
"vitest": "^4.0.8",
|
|
39
|
-
"@anvia/core": "1.1.
|
|
39
|
+
"@anvia/core": "1.1.2"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
|
-
"@anvia/core": "1.1.
|
|
42
|
+
"@anvia/core": "1.1.2"
|
|
43
43
|
},
|
|
44
44
|
"engines": {
|
|
45
45
|
"node": ">=20.12.0"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/docker-cli.ts"],"sourcesContent":["export type DockerSandboxErrorCode =\n | \"docker_unavailable\"\n | \"docker_command_failed\"\n | \"image_not_found\"\n | \"volume_not_found\"\n | \"sandbox_not_found\"\n | \"invalid_state\"\n | \"invalid_path\"\n | \"timeout\"\n | \"file_too_large\"\n | \"tool_policy\"\n | \"port\"\n | \"process\";\n\nexport class DockerSandboxError extends Error {\n constructor(\n message: string,\n readonly code: DockerSandboxErrorCode,\n readonly details?: unknown,\n options?: ErrorOptions,\n ) {\n super(message, options);\n this.name = \"DockerSandboxError\";\n }\n}\n\nexport function dockerSandboxError(\n message: string,\n code: DockerSandboxErrorCode,\n cause?: unknown,\n details?: unknown,\n): DockerSandboxError {\n return new DockerSandboxError(\n message,\n code,\n details,\n cause === undefined ? undefined : { cause },\n );\n}\n","import { spawn } from \"node:child_process\";\nimport { DockerSandboxError } from \"./errors\";\n\nexport interface DockerCliResult {\n stdout: Uint8Array;\n stderr: Uint8Array;\n exitCode: number;\n durationMs: number;\n timedOut: boolean;\n stdoutTruncated: boolean;\n stderrTruncated: boolean;\n}\n\nexport interface DockerCliOptions {\n dockerPath: string;\n timeoutMs?: number | undefined;\n maxOutputBytes?: number | undefined;\n input?: string | Uint8Array | undefined;\n signal?: AbortSignal | undefined;\n onStdout?: (chunk: Uint8Array) => void;\n onStderr?: (chunk: Uint8Array) => void;\n}\n\nconst defaultMaxOutputBytes = 1024 * 1024;\n\nexport async function runDockerCli(\n args: string[],\n options: DockerCliOptions,\n): Promise<DockerCliResult> {\n const startedAt = Date.now();\n const maxOutputBytes = options.maxOutputBytes ?? defaultMaxOutputBytes;\n const stdout = createOutputCollector(maxOutputBytes, options.onStdout);\n const stderr = createOutputCollector(maxOutputBytes, options.onStderr);\n\n return new Promise((resolve, reject) => {\n const child = spawn(options.dockerPath, args, {\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n\n let timedOut = false;\n let settled = false;\n\n const timeout =\n options.timeoutMs === undefined\n ? undefined\n : setTimeout(() => {\n timedOut = true;\n child.kill(\"SIGKILL\");\n }, options.timeoutMs);\n\n const abort = () => {\n child.kill(\"SIGKILL\");\n };\n\n if (options.signal?.aborted === true) {\n abort();\n } else {\n options.signal?.addEventListener(\"abort\", abort, { once: true });\n }\n\n child.stdout.on(\"data\", (chunk: Buffer) => stdout.accept(chunk));\n child.stderr.on(\"data\", (chunk: Buffer) => stderr.accept(chunk));\n\n child.on(\"error\", (error) => {\n if (settled) {\n return;\n }\n settled = true;\n clearTimeout(timeout);\n options.signal?.removeEventListener(\"abort\", abort);\n\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n reject(\n new DockerSandboxError(\"Docker CLI was not found.\", \"docker_unavailable\", undefined, {\n cause: error,\n }),\n );\n return;\n }\n\n reject(error);\n });\n\n child.on(\"close\", (code) => {\n if (settled) {\n return;\n }\n settled = true;\n clearTimeout(timeout);\n options.signal?.removeEventListener(\"abort\", abort);\n\n if (options.signal?.aborted === true) {\n reject(options.signal.reason ?? new DOMException(\"Aborted\", \"AbortError\"));\n return;\n }\n\n resolve({\n stdout: stdout.bytes(),\n stderr: stderr.bytes(),\n exitCode: code ?? 1,\n durationMs: Date.now() - startedAt,\n timedOut,\n stdoutTruncated: stdout.truncated,\n stderrTruncated: stderr.truncated,\n });\n });\n\n if (options.input !== undefined) {\n child.stdin.end(options.input);\n } else {\n child.stdin.end();\n }\n });\n}\n\nexport async function assertDockerCli(args: string[], options: DockerCliOptions): Promise<void> {\n const result = await runDockerCli(args, options);\n\n if (result.exitCode !== 0) {\n throw new DockerSandboxError(\n `Docker command failed: docker ${args.join(\" \")}`,\n \"docker_command_failed\",\n result,\n );\n }\n}\n\nfunction createOutputCollector(maxBytes: number, onChunk?: (chunk: Uint8Array) => void) {\n const chunks: Buffer[] = [];\n let length = 0;\n let truncated = false;\n\n return {\n get truncated() {\n return truncated;\n },\n accept(chunk: Buffer) {\n onChunk?.(chunk);\n\n if (length >= maxBytes) {\n truncated = true;\n return;\n }\n\n const remaining = maxBytes - length;\n const next = chunk.length > remaining ? chunk.subarray(0, remaining) : chunk;\n chunks.push(next);\n length += next.length;\n\n if (next.length < chunk.length) {\n truncated = true;\n }\n },\n bytes() {\n const bytes = Buffer.concat(chunks, length);\n return new Uint8Array(bytes.buffer, bytes.byteOffset, bytes.byteLength).slice();\n },\n };\n}\n\nexport function decodeUtf8(bytes: Uint8Array): string {\n return new TextDecoder(\"utf-8\", { fatal: true }).decode(bytes);\n}\n"],"mappings":"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","names":[]}
|