@anvia/sandbox 0.5.0 → 1.0.0-rc.1

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/dist/index.d.ts CHANGED
@@ -26,11 +26,25 @@ interface SandboxSession {
26
26
  execStream(options: SandboxExecOptions): AsyncIterable<SandboxExecStreamEvent>;
27
27
  readFile(path: string): Promise<Uint8Array>;
28
28
  readTextFile(path: string): Promise<string>;
29
+ readTextFilePage?(path: string, options?: SandboxTextFileReadOptions): Promise<SandboxTextFileReadResult>;
29
30
  writeFile(path: string, data: string | Uint8Array): Promise<void>;
30
31
  writeTextFile(path: string, content: string): Promise<void>;
31
32
  listFiles(path?: string): Promise<SandboxFileEntry[]>;
32
33
  destroy(): Promise<void>;
33
34
  }
35
+ interface SandboxTextFileReadOptions {
36
+ startLine?: number;
37
+ lineCount?: number;
38
+ maxBytes?: number;
39
+ }
40
+ interface SandboxTextFileReadResult {
41
+ content: string;
42
+ startLine: number;
43
+ endLine: number | null;
44
+ nextStartLine: number | null;
45
+ truncated: boolean;
46
+ truncatedBy: "lines" | "bytes" | null;
47
+ }
34
48
  interface SandboxPortSession extends SandboxSession {
35
49
  readonly publishedPorts: readonly SandboxPublishedPort[];
36
50
  waitForPort(containerPort: number, options?: SandboxWaitForPortOptions): Promise<SandboxPublishedPort>;
@@ -42,6 +56,7 @@ interface SandboxProcessSession extends SandboxSession {
42
56
  stopProcess(processId: string, options?: SandboxProcessStopOptions): Promise<SandboxProcessInfo>;
43
57
  }
44
58
  interface DockerSandboxSession extends SandboxPortSession, SandboxProcessSession {
59
+ readTextFilePage(path: string, options?: SandboxTextFileReadOptions): Promise<SandboxTextFileReadResult>;
45
60
  }
46
61
  interface SandboxCreateSessionOptions {
47
62
  id?: string;
@@ -195,7 +210,7 @@ interface SandboxToolsOptions {
195
210
  include?: SandboxToolName[];
196
211
  execTimeoutMs?: number;
197
212
  exec?: SandboxExecToolPolicy;
198
- readFile?: SandboxFileToolPolicy;
213
+ readFile?: SandboxReadFileToolPolicy;
199
214
  writeFile?: SandboxFileToolPolicy;
200
215
  process?: SandboxProcessToolPolicy;
201
216
  }
@@ -209,6 +224,10 @@ interface SandboxExecToolPolicy {
209
224
  interface SandboxFileToolPolicy {
210
225
  maxBytes?: number;
211
226
  }
227
+ interface SandboxReadFileToolPolicy extends SandboxFileToolPolicy {
228
+ defaultLineCount?: number;
229
+ maxLineCount?: number;
230
+ }
212
231
  interface SandboxProcessToolPolicy {
213
232
  maxLogBytes?: number;
214
233
  defaultWaitTimeoutMs?: number;
@@ -285,4 +304,4 @@ declare class SandboxProcessError extends SandboxError {
285
304
 
286
305
  declare function createSandboxTools(session: SandboxSession, options?: SandboxToolsOptions): AnyTool[];
287
306
 
288
- export { DockerSandbox, type DockerSandboxCreateSessionOptions, type DockerSandboxNetworkOptions, type DockerSandboxOptions, type DockerSandboxSecurityOptions, type DockerSandboxSession, type Sandbox, type SandboxCreateSessionOptions, SandboxDockerCommandError, SandboxDockerUnavailableError, SandboxError, type SandboxExecEndEvent, type SandboxExecEvent, type SandboxExecOptions, type SandboxExecResult, type SandboxExecStreamEvent, type SandboxExecToolPolicy, type SandboxFileEntry, SandboxFileSizeError, type SandboxFileToolPolicy, type SandboxFileType, type SandboxFileWriteEvent, type SandboxHooks, type SandboxLifecycleOptions, type SandboxLimits, type SandboxManifest, type SandboxNetworkMode, SandboxPathError, SandboxPortError, type SandboxPortSession, SandboxProcessError, type SandboxProcessInfo, type SandboxProcessLogs, type SandboxProcessLogsOptions, type SandboxProcessSession, type SandboxProcessStartOptions, type SandboxProcessStatus, type SandboxProcessStopOptions, type SandboxProcessToolPolicy, type SandboxPublishedPort, type SandboxSession, SandboxSessionDestroyedError, type SandboxSessionEvent, SandboxTimeoutError, type SandboxToolName, SandboxToolPolicyError, type SandboxToolsFactory, type SandboxToolsOptions, type SandboxWaitForPortOptions, type SandboxWorkspaceOptions, createSandboxTools, isSandboxPortSession, isSandboxProcessSession };
307
+ export { DockerSandbox, type DockerSandboxCreateSessionOptions, type DockerSandboxNetworkOptions, type DockerSandboxOptions, type DockerSandboxSecurityOptions, type DockerSandboxSession, type Sandbox, type SandboxCreateSessionOptions, SandboxDockerCommandError, SandboxDockerUnavailableError, SandboxError, type SandboxExecEndEvent, type SandboxExecEvent, type SandboxExecOptions, type SandboxExecResult, type SandboxExecStreamEvent, type SandboxExecToolPolicy, type SandboxFileEntry, SandboxFileSizeError, type SandboxFileToolPolicy, type SandboxFileType, type SandboxFileWriteEvent, type SandboxHooks, type SandboxLifecycleOptions, type SandboxLimits, type SandboxManifest, type SandboxNetworkMode, SandboxPathError, SandboxPortError, type SandboxPortSession, SandboxProcessError, type SandboxProcessInfo, type SandboxProcessLogs, type SandboxProcessLogsOptions, type SandboxProcessSession, type SandboxProcessStartOptions, type SandboxProcessStatus, type SandboxProcessStopOptions, type SandboxProcessToolPolicy, type SandboxPublishedPort, type SandboxReadFileToolPolicy, type SandboxSession, SandboxSessionDestroyedError, type SandboxSessionEvent, type SandboxTextFileReadOptions, type SandboxTextFileReadResult, SandboxTimeoutError, type SandboxToolName, SandboxToolPolicyError, type SandboxToolsFactory, type SandboxToolsOptions, type SandboxWaitForPortOptions, type SandboxWorkspaceOptions, createSandboxTools, isSandboxPortSession, isSandboxProcessSession };
package/dist/index.js CHANGED
@@ -540,12 +540,59 @@ async function waitForDelay(timeoutMs) {
540
540
  });
541
541
  }
542
542
 
543
+ // src/text-file.ts
544
+ function createTextFilePage(text, options) {
545
+ const contentStartLine = options.contentStartLine ?? 1;
546
+ const relativeStart = Math.max(0, options.startLine - contentStartLine);
547
+ const lines = splitLines(text).slice(relativeStart, relativeStart + options.lineCount + 1);
548
+ const hasMoreLines = lines.length > options.lineCount;
549
+ const selectedLines = lines.slice(0, options.lineCount);
550
+ const selectedContent = selectedLines.join("");
551
+ const selectedBytes = Buffer.from(selectedContent);
552
+ if (selectedBytes.byteLength > options.maxBytes) {
553
+ const content = decodeCompleteUtf8(selectedBytes.subarray(0, options.maxBytes));
554
+ const lineBreaks = countLineBreaks(content);
555
+ const endedAtLineBoundary = content.endsWith("\n");
556
+ return {
557
+ content,
558
+ startLine: options.startLine,
559
+ endLine: content.length === 0 ? null : options.startLine + lineBreaks - (endedAtLineBoundary ? 1 : 0),
560
+ nextStartLine: endedAtLineBoundary ? options.startLine + lineBreaks : null,
561
+ truncated: true,
562
+ truncatedBy: "bytes"
563
+ };
564
+ }
565
+ return {
566
+ content: selectedContent,
567
+ startLine: options.startLine,
568
+ endLine: selectedLines.length === 0 ? null : options.startLine + selectedLines.length - 1,
569
+ nextStartLine: hasMoreLines ? options.startLine + selectedLines.length : null,
570
+ truncated: hasMoreLines,
571
+ truncatedBy: hasMoreLines ? "lines" : null
572
+ };
573
+ }
574
+ function splitLines(text) {
575
+ return text.match(/[^\n]*\n|[^\n]+$/g) ?? [];
576
+ }
577
+ function countLineBreaks(text) {
578
+ let count = 0;
579
+ for (const character of text) {
580
+ if (character === "\n") count += 1;
581
+ }
582
+ return count;
583
+ }
584
+ function decodeCompleteUtf8(bytes) {
585
+ return new TextDecoder().decode(bytes, { stream: true });
586
+ }
587
+
543
588
  // src/docker-sandbox.ts
544
589
  var defaultImage = "node:22-bookworm";
545
590
  var defaultWorkdir = "/workspace";
546
591
  var defaultTimeoutMs = 3e4;
547
592
  var defaultMaxOutputBytes = 1024 * 1024;
548
593
  var defaultMaxProcesses = 4;
594
+ var defaultTextFilePageLines = 500;
595
+ var defaultTextFilePageBytes = 64 * 1024;
549
596
  var portProbeScript = [
550
597
  `port="$(printf '%04X' "$1")"`,
551
598
  "for table in /proc/net/tcp /proc/net/tcp6; do",
@@ -560,6 +607,15 @@ var portProbeScript = [
560
607
  "done",
561
608
  "exit 1"
562
609
  ].join("\n");
610
+ var textFilePageScript = [
611
+ 'start="$1"',
612
+ 'count="$2"',
613
+ 'max_bytes="$3"',
614
+ 'file="$4"',
615
+ 'end="$((start + count))"',
616
+ '[ -f "$file" ] || { echo "Not a readable file: $file" >&2; exit 66; }',
617
+ 'sed -n "$start,$end p;$end q" "$file" | head -c "$max_bytes"'
618
+ ].join("\n");
563
619
  var DockerSandbox = class _DockerSandbox {
564
620
  provider = "docker";
565
621
  image;
@@ -1010,6 +1066,48 @@ var DockerSandboxSessionImpl = class {
1010
1066
  const bytes = await this.readFile(filePath);
1011
1067
  return new TextDecoder().decode(bytes);
1012
1068
  }
1069
+ async readTextFilePage(filePath, options = {}) {
1070
+ return this.runOperation(async () => {
1071
+ const startLine = options.startLine ?? 1;
1072
+ const lineCount = options.lineCount ?? defaultTextFilePageLines;
1073
+ const maxBytes = options.maxBytes ?? defaultTextFilePageBytes;
1074
+ assertTextFileReadOptions(startLine, lineCount, maxBytes);
1075
+ const normalized = normalizeSandboxPath(filePath);
1076
+ const captureBytes = maxBytes + 4;
1077
+ const result = await runDockerCli(
1078
+ [
1079
+ "exec",
1080
+ "-w",
1081
+ this.workdir,
1082
+ this.containerName,
1083
+ "sh",
1084
+ "-c",
1085
+ textFilePageScript,
1086
+ "anvia-read-file-page",
1087
+ String(startLine),
1088
+ String(lineCount),
1089
+ String(captureBytes),
1090
+ containerPath(this.workdir, normalized)
1091
+ ],
1092
+ {
1093
+ ...this.cliOptions(),
1094
+ maxOutputBytes: captureBytes
1095
+ }
1096
+ );
1097
+ if (result.exitCode !== 0) {
1098
+ throw new SandboxDockerCommandError(
1099
+ `Unable to read sandbox text file: ${filePath}`,
1100
+ result
1101
+ );
1102
+ }
1103
+ return createTextFilePage(result.stdout, {
1104
+ startLine,
1105
+ lineCount,
1106
+ maxBytes,
1107
+ contentStartLine: startLine
1108
+ });
1109
+ });
1110
+ }
1013
1111
  async writeFile(filePath, data) {
1014
1112
  await this.runOperation(async () => {
1015
1113
  const size = byteLength(data);
@@ -1279,6 +1377,17 @@ function assertWaitOptions(timeoutMs, intervalMs) {
1279
1377
  throw new SandboxPortError("Port wait intervalMs must be a positive integer.");
1280
1378
  }
1281
1379
  }
1380
+ function assertTextFileReadOptions(startLine, lineCount, maxBytes) {
1381
+ if (!Number.isInteger(startLine) || startLine <= 0) {
1382
+ throw new RangeError("Text file startLine must be a positive integer.");
1383
+ }
1384
+ if (!Number.isInteger(lineCount) || lineCount <= 0) {
1385
+ throw new RangeError("Text file lineCount must be a positive integer.");
1386
+ }
1387
+ if (!Number.isInteger(maxBytes) || maxBytes <= 0) {
1388
+ throw new RangeError("Text file maxBytes must be a positive integer.");
1389
+ }
1390
+ }
1282
1391
  async function waitWithSignal(timeoutMs, signal) {
1283
1392
  if (signal?.aborted === true) throw abortReason(signal);
1284
1393
  await new Promise((resolve, reject) => {
@@ -1309,7 +1418,9 @@ var execCommandInput = z.object({
1309
1418
  input: z.string().optional().describe("Optional stdin text to pass to the command.")
1310
1419
  });
1311
1420
  var readFileInput = z.object({
1312
- path: z.string().min(1).describe("Relative file path inside the sandbox.")
1421
+ path: z.string().min(1).describe("Relative file path inside the sandbox."),
1422
+ startLine: z.number().int().positive().optional().describe("One-based first line to read. Defaults to 1."),
1423
+ lineCount: z.number().int().positive().max(1e4).optional().describe("Maximum lines to return. Defaults to 500.")
1313
1424
  });
1314
1425
  var writeFileInput = z.object({
1315
1426
  path: z.string().min(1).describe("Relative file path inside the sandbox."),
@@ -1337,6 +1448,19 @@ var waitForPortInput = z.object({
1337
1448
  });
1338
1449
  var textOutput = z.string();
1339
1450
  var maxToolLogBytes = 1024 * 1024;
1451
+ var defaultReadFileLineCount = 500;
1452
+ var defaultReadFileMaxLineCount = 2e3;
1453
+ var defaultReadFileMaxBytes = 64 * 1024;
1454
+ var maxToolReadFileBytes = 1024 * 1024;
1455
+ var maxToolReadFileLines = 1e4;
1456
+ var readFileOutput = z.object({
1457
+ content: z.string(),
1458
+ startLine: z.number().int().positive(),
1459
+ endLine: z.number().int().positive().nullable(),
1460
+ nextStartLine: z.number().int().positive().nullable(),
1461
+ truncated: z.boolean(),
1462
+ truncatedBy: z.enum(["lines", "bytes"]).nullable()
1463
+ });
1340
1464
  var sandboxToolMetadataKey = /* @__PURE__ */ Symbol.for("anvia.sandbox.tool.metadata");
1341
1465
  function createSandboxTools(session, options = {}) {
1342
1466
  const include = new Set(
@@ -1391,8 +1515,8 @@ function createExecCommandTool(session, options) {
1391
1515
  return createTool({
1392
1516
  name: "exec_command",
1393
1517
  description: "Run a command inside the sandbox workspace. Use structured args instead of shell quoting.",
1394
- input: execCommandInput,
1395
- output: textOutput,
1518
+ inputSchema: execCommandInput,
1519
+ outputSchema: textOutput,
1396
1520
  execute: async ({ command, args, cwd, env, timeoutMs, input }) => {
1397
1521
  assertCommandAllowed(command, options);
1398
1522
  const execOptions = {
@@ -1423,13 +1547,30 @@ function createExecCommandTool(session, options) {
1423
1547
  function createReadFileTool(session, options) {
1424
1548
  return createTool({
1425
1549
  name: "read_file",
1426
- description: "Read a text file from the sandbox workspace.",
1427
- input: readFileInput,
1428
- output: textOutput,
1429
- execute: async ({ path: path3 }) => {
1430
- const content = await session.readTextFile(path3);
1431
- assertReadAllowed(content, options);
1432
- return content;
1550
+ description: "Read a bounded page of a text file from the sandbox workspace. Continue with nextStartLine when provided.",
1551
+ inputSchema: readFileInput,
1552
+ outputSchema: readFileOutput,
1553
+ execute: async ({ path: path3, startLine, lineCount }) => {
1554
+ const limits = resolveReadFileLimits(options);
1555
+ const effectiveStartLine = startLine ?? 1;
1556
+ const effectiveLineCount = lineCount ?? limits.defaultLineCount;
1557
+ if (effectiveLineCount > limits.maxLineCount) {
1558
+ throw new SandboxToolPolicyError(
1559
+ `File read line count exceeds sandbox tool policy (${effectiveLineCount} > ${limits.maxLineCount}).`
1560
+ );
1561
+ }
1562
+ if (session.readTextFilePage !== void 0) {
1563
+ return session.readTextFilePage(path3, {
1564
+ startLine: effectiveStartLine,
1565
+ lineCount: effectiveLineCount,
1566
+ maxBytes: limits.maxBytes
1567
+ });
1568
+ }
1569
+ return createTextFilePage(await session.readTextFile(path3), {
1570
+ startLine: effectiveStartLine,
1571
+ lineCount: effectiveLineCount,
1572
+ maxBytes: limits.maxBytes
1573
+ });
1433
1574
  }
1434
1575
  });
1435
1576
  }
@@ -1437,8 +1578,8 @@ function createWriteFileTool(session, options) {
1437
1578
  return createTool({
1438
1579
  name: "write_file",
1439
1580
  description: "Write a text file inside the sandbox workspace. Creates parent directories.",
1440
- input: writeFileInput,
1441
- output: textOutput,
1581
+ inputSchema: writeFileInput,
1582
+ outputSchema: textOutput,
1442
1583
  execute: async ({ path: path3, content }) => {
1443
1584
  assertContentAllowed(content, options);
1444
1585
  await session.writeTextFile(path3, content);
@@ -1450,8 +1591,8 @@ function createListFilesTool(session) {
1450
1591
  return createTool({
1451
1592
  name: "list_files",
1452
1593
  description: "List files and directories inside the sandbox workspace.",
1453
- input: listFilesInput,
1454
- output: textOutput,
1594
+ inputSchema: listFilesInput,
1595
+ outputSchema: textOutput,
1455
1596
  execute: async ({ path: path3 }) => {
1456
1597
  const entries = await session.listFiles(path3);
1457
1598
  if (entries.length === 0) {
@@ -1468,8 +1609,8 @@ function createListPortsTool(session) {
1468
1609
  return createTool({
1469
1610
  name: "list_ports",
1470
1611
  description: "List pre-authorized sandbox preview ports. Servers must bind to 0.0.0.0 on a listed container port.",
1471
- input: emptyInput,
1472
- output: textOutput,
1612
+ inputSchema: emptyInput,
1613
+ outputSchema: textOutput,
1473
1614
  execute: async () => {
1474
1615
  if (session.publishedPorts.length === 0) {
1475
1616
  return "No sandbox ports are published.";
@@ -1482,8 +1623,8 @@ function createStartProcessTool(session, options) {
1482
1623
  return createTool({
1483
1624
  name: "start_process",
1484
1625
  description: "Start a managed long-running process inside the sandbox. Use list_ports first and bind web servers to 0.0.0.0.",
1485
- input: startProcessInput,
1486
- output: textOutput,
1626
+ inputSchema: startProcessInput,
1627
+ outputSchema: textOutput,
1487
1628
  execute: async ({ command, args, cwd, env }) => {
1488
1629
  assertCommandAllowed(command, options);
1489
1630
  const processOptions = { command };
@@ -1498,8 +1639,8 @@ function createListProcessesTool(session) {
1498
1639
  return createTool({
1499
1640
  name: "list_processes",
1500
1641
  description: "List managed sandbox processes and their current status.",
1501
- input: emptyInput,
1502
- output: textOutput,
1642
+ inputSchema: emptyInput,
1643
+ outputSchema: textOutput,
1503
1644
  execute: async () => {
1504
1645
  const processes = await session.listProcesses();
1505
1646
  if (processes.length === 0) return "No managed processes.";
@@ -1511,8 +1652,8 @@ function createReadProcessLogsTool(session, options) {
1511
1652
  return createTool({
1512
1653
  name: "read_process_logs",
1513
1654
  description: "Read recent stdout and stderr from a managed sandbox process.",
1514
- input: readProcessLogsInput,
1515
- output: textOutput,
1655
+ inputSchema: readProcessLogsInput,
1656
+ outputSchema: textOutput,
1516
1657
  execute: async ({ processId, tailBytes }) => {
1517
1658
  const configuredMaxLogBytes = options.process?.maxLogBytes ?? 64 * 1024;
1518
1659
  if (!Number.isInteger(configuredMaxLogBytes) || configuredMaxLogBytes < 0) {
@@ -1542,8 +1683,8 @@ function createStopProcessTool(session, options) {
1542
1683
  return createTool({
1543
1684
  name: "stop_process",
1544
1685
  description: "Stop a managed sandbox process.",
1545
- input: processIdInput,
1546
- output: textOutput,
1686
+ inputSchema: processIdInput,
1687
+ outputSchema: textOutput,
1547
1688
  execute: async ({ processId }) => formatProcessInfo(
1548
1689
  await session.stopProcess(processId, {
1549
1690
  gracePeriodMs: options.process?.stopGracePeriodMs ?? 5e3
@@ -1555,8 +1696,8 @@ function createWaitForPortTool(session, options) {
1555
1696
  return createTool({
1556
1697
  name: "wait_for_port",
1557
1698
  description: "Wait until a pre-authorized sandbox TCP port is accepting connections.",
1558
- input: waitForPortInput,
1559
- output: textOutput,
1699
+ inputSchema: waitForPortInput,
1700
+ outputSchema: textOutput,
1560
1701
  execute: async ({ containerPort, timeoutMs }) => {
1561
1702
  const effectiveTimeoutMs = timeoutMs ?? options.process?.defaultWaitTimeoutMs ?? 3e4;
1562
1703
  const maxWaitTimeoutMs = options.process?.maxWaitTimeoutMs ?? 3e5;
@@ -1660,11 +1801,29 @@ function assertContentAllowed(content, options) {
1660
1801
  throw new SandboxToolPolicyError("File content exceeds sandbox tool policy.");
1661
1802
  }
1662
1803
  }
1663
- function assertReadAllowed(content, options) {
1664
- const maxBytes = options.readFile?.maxBytes;
1665
- if (maxBytes !== void 0 && Buffer.byteLength(content) > maxBytes) {
1666
- throw new SandboxToolPolicyError("File content exceeds sandbox tool policy.");
1804
+ function resolveReadFileLimits(options) {
1805
+ const defaultLineCount = options.readFile?.defaultLineCount ?? defaultReadFileLineCount;
1806
+ const maxLineCount = options.readFile?.maxLineCount ?? defaultReadFileMaxLineCount;
1807
+ const maxBytes = options.readFile?.maxBytes ?? defaultReadFileMaxBytes;
1808
+ if (!Number.isInteger(defaultLineCount) || defaultLineCount <= 0) {
1809
+ throw new SandboxToolPolicyError("File defaultLineCount must be a positive integer.");
1810
+ }
1811
+ if (!Number.isInteger(maxLineCount) || maxLineCount <= 0 || maxLineCount > maxToolReadFileLines) {
1812
+ throw new SandboxToolPolicyError(
1813
+ `File maxLineCount must be a positive integer no greater than ${maxToolReadFileLines}.`
1814
+ );
1815
+ }
1816
+ if (defaultLineCount > maxLineCount) {
1817
+ throw new SandboxToolPolicyError(
1818
+ `File defaultLineCount exceeds maxLineCount (${defaultLineCount} > ${maxLineCount}).`
1819
+ );
1820
+ }
1821
+ if (!Number.isInteger(maxBytes) || maxBytes <= 0 || maxBytes > maxToolReadFileBytes) {
1822
+ throw new SandboxToolPolicyError(
1823
+ `File maxBytes must be a positive integer no greater than ${maxToolReadFileBytes}.`
1824
+ );
1667
1825
  }
1826
+ return { defaultLineCount, maxLineCount, maxBytes };
1668
1827
  }
1669
1828
  export {
1670
1829
  DockerSandbox,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/capabilities.ts","../src/docker-sandbox.ts","../src/docker-process.ts","../src/path.ts","../src/tools.ts"],"sourcesContent":["import type { SandboxPortSession, SandboxProcessSession, SandboxSession } from \"./types\";\n\nexport function isSandboxPortSession(session: SandboxSession): session is SandboxPortSession {\n const candidate = session as Partial<SandboxPortSession>;\n return Array.isArray(candidate.publishedPorts) && typeof candidate.waitForPort === \"function\";\n}\n\nexport function isSandboxProcessSession(session: SandboxSession): session is SandboxProcessSession {\n const candidate = session as Partial<SandboxProcessSession>;\n return (\n typeof candidate.startProcess === \"function\" &&\n typeof candidate.listProcesses === \"function\" &&\n typeof candidate.readProcessLogs === \"function\" &&\n typeof candidate.stopProcess === \"function\"\n );\n}\n","import { randomUUID } from \"node:crypto\";\nimport { mkdtemp, rm, writeFile } from \"node:fs/promises\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { assertDockerCli, type DockerCliOptions, runDockerCli } from \"./docker-cli\";\nimport { DockerProcessManager } from \"./docker-process\";\nimport {\n SandboxDockerCommandError,\n SandboxFileSizeError,\n SandboxPortError,\n SandboxSessionDestroyedError,\n SandboxTimeoutError,\n} from \"./errors\";\nimport { containerPath, normalizeSandboxPath, parentSandboxPath } from \"./path\";\nimport type {\n DockerSandboxCreateSessionOptions,\n DockerSandboxOptions,\n DockerSandboxSession,\n Sandbox,\n SandboxExecEndEvent,\n SandboxExecEvent,\n SandboxExecOptions,\n SandboxExecResult,\n SandboxExecStreamEvent,\n SandboxFileEntry,\n SandboxFileType,\n SandboxHooks,\n SandboxLifecycleOptions,\n SandboxLimits,\n SandboxManifest,\n SandboxProcessInfo,\n SandboxProcessLogs,\n SandboxProcessLogsOptions,\n SandboxProcessStartOptions,\n SandboxProcessStopOptions,\n SandboxPublishedPort,\n SandboxSessionEvent,\n SandboxWaitForPortOptions,\n SandboxWorkspaceOptions,\n} from \"./types\";\n\nconst defaultImage = \"node:22-bookworm\";\nconst defaultWorkdir = \"/workspace\";\nconst defaultTimeoutMs = 30_000;\nconst defaultMaxOutputBytes = 1024 * 1024;\nconst defaultMaxProcesses = 4;\n// Docker Desktop may accept a host-side TCP connection before a container service is ready. Probe\n// Linux socket state in the container so readiness requires an all-interface listening socket.\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\nexport class DockerSandbox implements Sandbox {\n readonly provider = \"docker\";\n\n private readonly image: string;\n private readonly pull: \"missing\" | \"always\" | \"never\";\n private readonly workdir: string;\n private readonly workspace: SandboxWorkspaceOptions;\n private readonly lifecycle: Required<Pick<SandboxLifecycleOptions, \"autoDestroy\">> &\n Omit<SandboxLifecycleOptions, \"autoDestroy\">;\n private readonly network: NonNullable<DockerSandboxOptions[\"network\"]>;\n private readonly dockerPath: string;\n private readonly labels: Record<string, string>;\n private readonly limits: SandboxLimits;\n private readonly security: Required<NonNullable<DockerSandboxOptions[\"security\"]>>;\n private readonly hooks: SandboxHooks;\n private readonly user: string | undefined;\n\n constructor(options: DockerSandboxOptions = {}) {\n this.image = options.image ?? defaultImage;\n this.pull = options.pull ?? \"missing\";\n this.workdir = options.workdir ?? defaultWorkdir;\n this.workspace = options.workspace ?? { mode: \"ephemeral\" };\n const lifecycle: Required<Pick<SandboxLifecycleOptions, \"autoDestroy\">> &\n Omit<SandboxLifecycleOptions, \"autoDestroy\"> = {\n autoDestroy: options.lifecycle?.autoDestroy ?? true,\n };\n if (options.lifecycle?.ttlMs !== undefined) lifecycle.ttlMs = options.lifecycle.ttlMs;\n if (options.lifecycle?.idleTimeoutMs !== undefined) {\n lifecycle.idleTimeoutMs = options.lifecycle.idleTimeoutMs;\n }\n this.lifecycle = lifecycle;\n this.network = options.network ?? false;\n this.dockerPath = options.dockerPath ?? \"docker\";\n this.labels = options.labels ?? {};\n this.limits = options.limits ?? {};\n this.security = {\n readonlyRootfs: options.security?.readonlyRootfs ?? false,\n noNewPrivileges: options.security?.noNewPrivileges ?? true,\n dropCapabilities: options.security?.dropCapabilities ?? [\"ALL\"],\n };\n this.hooks = options.hooks ?? {};\n this.user = options.user;\n }\n\n static node(options: DockerSandboxOptions = {}): DockerSandbox {\n return new DockerSandbox({ ...options, image: options.image ?? \"node:22-bookworm\" });\n }\n\n static python(options: DockerSandboxOptions = {}): DockerSandbox {\n return new DockerSandbox({ ...options, image: options.image ?? \"python:3.13-bookworm\" });\n }\n\n static deno(options: DockerSandboxOptions = {}): DockerSandbox {\n return new DockerSandbox({ ...options, image: options.image ?? \"denoland/deno:debian\" });\n }\n\n async createSession(\n options: DockerSandboxCreateSessionOptions = {},\n ): Promise<DockerSandboxSession> {\n const ports = validatePublishedPorts(options.ports ?? []);\n this.assertPortNetworkCompatible(ports);\n await this.ensureImage();\n\n const id = sanitizeResourceId(options.id ?? randomUUID());\n const workspace = options.workspace ?? this.workspace;\n const workspaceId = getWorkspaceId(workspace, id);\n const containerName = `anvia-sandbox-${id}`;\n const volumeName = `anvia-sandbox-${workspaceId}-workspace`;\n const removeVolumeOnDestroy = shouldDestroyWorkspace(workspace);\n\n await assertDockerCli([\"volume\", \"create\", volumeName], this.cliOptions());\n\n try {\n await assertDockerCli(\n this.createRunArgs(containerName, volumeName, workspace, options.metadata, ports),\n {\n ...this.cliOptions(),\n timeoutMs: this.limits.timeoutMs ?? defaultTimeoutMs,\n },\n );\n\n const publishedPorts = await this.inspectPublishedPorts(containerName, ports);\n\n const session = new DockerSandboxSessionImpl({\n id,\n containerName,\n volumeName,\n workdir: this.workdir,\n dockerPath: this.dockerPath,\n limits: this.limits,\n lifecycle: this.lifecycle,\n removeVolumeOnDestroy,\n env: options.manifest?.env ?? {},\n hooks: this.hooks,\n publishedPorts,\n });\n\n await session.applyManifest(options.manifest);\n await this.hooks.onSessionCreate?.(session.event());\n return session;\n } catch (error) {\n await this.cleanup(containerName, removeVolumeOnDestroy ? volumeName : undefined);\n throw error;\n }\n }\n\n private async ensureImage(): Promise<void> {\n if (this.pull === \"always\") {\n await assertDockerCli([\"pull\", this.image], this.cliOptions());\n return;\n }\n\n if (this.pull === \"missing\") {\n const inspect = await runDockerCli([\"image\", \"inspect\", this.image], this.cliOptions());\n if (inspect.exitCode !== 0) {\n await assertDockerCli([\"pull\", this.image], this.cliOptions());\n }\n }\n }\n\n private createRunArgs(\n containerName: string,\n volumeName: string,\n workspace: SandboxWorkspaceOptions,\n metadata: Record<string, string> | undefined,\n ports: readonly number[],\n ): string[] {\n const args = [\n \"run\",\n \"-d\",\n \"--name\",\n containerName,\n \"-v\",\n `${volumeName}:${this.workdir}`,\n \"-w\",\n this.workdir,\n \"--label\",\n \"anvia.sandbox=true\",\n \"--label\",\n `anvia.sandbox.workspace.mode=${workspace.mode ?? \"ephemeral\"}`,\n \"--label\",\n `anvia.sandbox.workspace.volume=${volumeName}`,\n ];\n\n for (const [key, value] of Object.entries(this.labels)) {\n args.push(\"--label\", `${key}=${value}`);\n }\n\n if (metadata !== undefined) {\n for (const [key, value] of Object.entries(metadata)) {\n args.push(\"--label\", `anvia.sandbox.metadata.${key}=${value}`);\n }\n }\n\n this.appendNetworkArgs(args);\n for (const port of ports) {\n args.push(\"--publish\", `127.0.0.1::${port}/tcp`);\n }\n this.appendLimitArgs(args);\n this.appendSecurityArgs(args);\n\n if (this.user !== undefined) {\n args.push(\"-u\", this.user);\n }\n\n args.push(\n this.image,\n \"sh\",\n \"-c\",\n \"trap 'exit 0' TERM INT; while :; do sleep 3600 & wait $!; done\",\n );\n return args;\n }\n\n private appendNetworkArgs(args: string[]): void {\n const mode = typeof this.network === \"object\" ? this.network.mode : this.network;\n\n if (mode === false || mode === \"none\") {\n args.push(\"--network\", \"none\");\n return;\n }\n\n if (mode !== true) {\n args.push(\"--network\", mode);\n }\n }\n\n private assertPortNetworkCompatible(ports: readonly number[]): void {\n if (ports.length === 0) return;\n const mode = typeof this.network === \"object\" ? this.network.mode : this.network;\n if (\n mode === false ||\n mode === \"none\" ||\n mode === \"host\" ||\n (typeof mode === \"string\" && mode.startsWith(\"container:\"))\n ) {\n throw new SandboxPortError(\n \"Published sandbox ports require network: true or a bridge-capable Docker network.\",\n );\n }\n }\n\n private async inspectPublishedPorts(\n containerName: string,\n ports: readonly number[],\n ): Promise<SandboxPublishedPort[]> {\n if (ports.length === 0) return [];\n\n const raw = await assertDockerCli(\n [\"container\", \"inspect\", \"--format\", \"{{json .NetworkSettings.Ports}}\", containerName],\n this.cliOptions(),\n );\n let mappings: unknown;\n try {\n mappings = JSON.parse(raw);\n } catch (error) {\n throw new SandboxPortError(\"Docker returned invalid published port metadata.\", error);\n }\n if (!isRecord(mappings)) {\n throw new SandboxPortError(\"Docker returned invalid published port metadata.\");\n }\n\n return ports.map((containerPort) => {\n const entries = mappings[`${containerPort}/tcp`];\n if (!Array.isArray(entries)) {\n throw new SandboxPortError(`Docker did not publish sandbox port ${containerPort}/tcp.`);\n }\n const entry = entries.find(\n (candidate) =>\n isRecord(candidate) &&\n candidate.HostIp === \"127.0.0.1\" &&\n typeof candidate.HostPort === \"string\",\n );\n if (!isRecord(entry) || typeof entry.HostPort !== \"string\") {\n throw new SandboxPortError(\n `Docker did not bind sandbox port ${containerPort}/tcp to 127.0.0.1.`,\n );\n }\n const hostPort = Number(entry.HostPort);\n if (!isValidPort(hostPort)) {\n throw new SandboxPortError(\n `Docker returned an invalid host port for ${containerPort}/tcp.`,\n );\n }\n return { containerPort, host: \"127.0.0.1\", hostPort, protocol: \"tcp\" };\n });\n }\n\n private appendLimitArgs(args: string[]): void {\n if (this.limits.memoryMb !== undefined) {\n args.push(\"--memory\", `${this.limits.memoryMb}m`);\n }\n\n if (this.limits.cpus !== undefined) {\n args.push(\"--cpus\", String(this.limits.cpus));\n }\n\n if (this.limits.pidsLimit !== undefined) {\n args.push(\"--pids-limit\", String(this.limits.pidsLimit));\n }\n }\n\n private appendSecurityArgs(args: string[]): void {\n if (this.security.readonlyRootfs) {\n args.push(\"--read-only\");\n }\n\n if (this.security.noNewPrivileges) {\n args.push(\"--security-opt\", \"no-new-privileges\");\n }\n\n for (const capability of this.security.dropCapabilities) {\n args.push(\"--cap-drop\", capability);\n }\n }\n\n private cliOptions() {\n return {\n dockerPath: this.dockerPath,\n maxOutputBytes: this.limits.maxOutputBytes ?? defaultMaxOutputBytes,\n };\n }\n\n private async cleanup(containerName: string, volumeName: string | undefined): Promise<void> {\n await runDockerCli([\"rm\", \"-f\", containerName], this.cliOptions()).catch(() => undefined);\n\n if (volumeName !== undefined) {\n await runDockerCli([\"volume\", \"rm\", \"-f\", volumeName], this.cliOptions()).catch(\n () => undefined,\n );\n }\n }\n}\n\nclass DockerSandboxSessionImpl implements DockerSandboxSession {\n readonly provider = \"docker\";\n readonly id: string;\n readonly workdir: string;\n readonly publishedPorts: readonly SandboxPublishedPort[];\n\n private readonly containerName: string;\n private readonly volumeName: string;\n private readonly dockerPath: string;\n private readonly limits: SandboxLimits;\n private readonly lifecycle: Required<Pick<SandboxLifecycleOptions, \"autoDestroy\">> &\n Omit<SandboxLifecycleOptions, \"autoDestroy\">;\n private readonly removeVolumeOnDestroy: boolean;\n private readonly env: Record<string, string>;\n private readonly hooks: SandboxHooks;\n private readonly processManager: DockerProcessManager;\n private ttlTimer: ReturnType<typeof setTimeout> | undefined;\n private idleTimer: ReturnType<typeof setTimeout> | undefined;\n private activeOperations = 0;\n private destroyed = false;\n\n constructor(options: {\n id: string;\n containerName: string;\n volumeName: string;\n workdir: string;\n dockerPath: string;\n limits: SandboxLimits;\n lifecycle: Required<Pick<SandboxLifecycleOptions, \"autoDestroy\">> &\n Omit<SandboxLifecycleOptions, \"autoDestroy\">;\n removeVolumeOnDestroy: boolean;\n env: Record<string, string>;\n hooks: SandboxHooks;\n publishedPorts: SandboxPublishedPort[];\n }) {\n this.id = options.id;\n this.containerName = options.containerName;\n this.volumeName = options.volumeName;\n this.workdir = options.workdir;\n this.dockerPath = options.dockerPath;\n this.limits = options.limits;\n this.lifecycle = options.lifecycle;\n this.removeVolumeOnDestroy = options.removeVolumeOnDestroy;\n this.env = options.env;\n this.hooks = options.hooks;\n this.publishedPorts = options.publishedPorts;\n this.processManager = new DockerProcessManager({\n containerName: this.containerName,\n dockerPath: this.dockerPath,\n workdir: this.workdir,\n env: this.env,\n maxOutputBytes: this.limits.maxOutputBytes ?? defaultMaxOutputBytes,\n maxProcesses: this.limits.maxProcesses ?? defaultMaxProcesses,\n startupTimeoutMs: this.limits.timeoutMs ?? defaultTimeoutMs,\n onStart: async (process) => {\n const event: SandboxExecEvent = {\n ...this.event(),\n command: process.command,\n args: process.args,\n };\n if (process.cwd !== undefined) event.cwd = process.cwd;\n await this.hooks.onExecStart?.(event);\n },\n onExit: async (process, logs, durationMs) => {\n const event: SandboxExecEndEvent = {\n ...this.event(),\n command: process.command,\n args: process.args,\n result: {\n stdout: logs.stdout,\n stderr: logs.stderr,\n exitCode: process.exitCode ?? 1,\n durationMs,\n timedOut: false,\n aborted: process.status === \"stopped\",\n stdoutTruncated: logs.stdoutTruncated,\n stderrTruncated: logs.stderrTruncated,\n },\n };\n if (process.cwd !== undefined) event.cwd = process.cwd;\n await this.hooks.onExecEnd?.(event);\n },\n });\n this.startLifecycleTimers();\n }\n\n async applyManifest(manifest: SandboxManifest | undefined): Promise<void> {\n await this.runOperation(async () => {\n for (const directory of manifest?.directories ?? []) {\n await this.mkdir(directory);\n }\n\n for (const [filePath, content] of Object.entries(manifest?.files ?? {})) {\n await this.writeFile(filePath, content);\n }\n });\n }\n\n async exec(options: SandboxExecOptions): Promise<SandboxExecResult> {\n return this.runOperation(async () => {\n const startEvent: SandboxExecEvent = {\n ...this.event(),\n command: options.command,\n args: options.args ?? [],\n };\n if (options.cwd !== undefined) startEvent.cwd = options.cwd;\n await this.hooks.onExecStart?.(startEvent);\n\n const normalizedResult = await this.execCommand(options);\n\n const endEvent: SandboxExecEndEvent = {\n ...this.event(),\n command: options.command,\n args: options.args ?? [],\n result: normalizedResult,\n };\n if (options.cwd !== undefined) endEvent.cwd = options.cwd;\n await this.hooks.onExecEnd?.(endEvent);\n\n return normalizedResult;\n });\n }\n\n async *execStream(options: SandboxExecOptions): AsyncIterable<SandboxExecStreamEvent> {\n const events: SandboxExecStreamEvent[] = [];\n let notify: (() => void) | undefined;\n let done = false;\n let error: unknown;\n\n const push = (event: SandboxExecStreamEvent) => {\n events.push(event);\n notify?.();\n notify = undefined;\n };\n\n const wait = () =>\n new Promise<void>((resolve) => {\n notify = resolve;\n });\n\n const run = this.exec({\n ...options,\n onStdout: (chunk) => {\n options.onStdout?.(chunk);\n push({ type: \"stdout\", chunk, text: Buffer.from(chunk).toString(\"utf8\") });\n },\n onStderr: (chunk) => {\n options.onStderr?.(chunk);\n push({ type: \"stderr\", chunk, text: Buffer.from(chunk).toString(\"utf8\") });\n },\n })\n .then((result) => {\n push({ type: \"exit\", result });\n })\n .catch((caught) => {\n error = caught;\n })\n .finally(() => {\n done = true;\n notify?.();\n notify = undefined;\n });\n\n try {\n while (!done || events.length > 0) {\n const event = events.shift();\n if (event !== undefined) {\n yield event;\n continue;\n }\n\n await wait();\n }\n\n if (error !== undefined) {\n throw error;\n }\n } finally {\n await run;\n }\n }\n\n async startProcess(options: SandboxProcessStartOptions): Promise<SandboxProcessInfo> {\n return this.runOperation(async () => this.processManager.start(options));\n }\n\n async listProcesses(): Promise<SandboxProcessInfo[]> {\n return this.runOperation(async () => this.processManager.list());\n }\n\n async readProcessLogs(\n processId: string,\n options?: SandboxProcessLogsOptions,\n ): Promise<SandboxProcessLogs> {\n return this.runOperation(async () => this.processManager.logs(processId, options));\n }\n\n async stopProcess(\n processId: string,\n options?: SandboxProcessStopOptions,\n ): Promise<SandboxProcessInfo> {\n return this.runOperation(async () => this.processManager.stop(processId, options));\n }\n\n async waitForPort(\n containerPort: number,\n options: SandboxWaitForPortOptions = {},\n ): Promise<SandboxPublishedPort> {\n return this.runOperation(async () => {\n const publishedPort = this.publishedPorts.find(\n (candidate) => candidate.containerPort === containerPort,\n );\n if (publishedPort === undefined) {\n throw new SandboxPortError(`Sandbox port is not published: ${containerPort}/tcp`);\n }\n\n const timeoutMs = options.timeoutMs ?? this.limits.timeoutMs ?? defaultTimeoutMs;\n const intervalMs = options.intervalMs ?? 250;\n assertWaitOptions(timeoutMs, intervalMs);\n const deadline = Date.now() + timeoutMs;\n\n while (true) {\n this.assertActive();\n if (options.signal?.aborted === true) throw abortReason(options.signal);\n const remainingMs = deadline - Date.now();\n if (remainingMs <= 0) {\n throw new SandboxTimeoutError(`Waiting for sandbox port ${containerPort}/tcp timed out.`);\n }\n const probeTimeoutMs = Math.min(1_000, remainingMs);\n if (await this.isPortListening(containerPort, probeTimeoutMs)) {\n return publishedPort;\n }\n const remainingAfterProbeMs = deadline - Date.now();\n if (remainingAfterProbeMs <= 0) {\n throw new SandboxTimeoutError(`Waiting for sandbox port ${containerPort}/tcp timed out.`);\n }\n await waitWithSignal(Math.min(intervalMs, remainingAfterProbeMs), options.signal);\n }\n });\n }\n\n async readFile(filePath: string): Promise<Uint8Array> {\n return this.runOperation(async () => {\n const normalized = normalizeSandboxPath(filePath);\n const tempDir = await mkdtemp(path.join(os.tmpdir(), \"anvia-sandbox-read-\"));\n const target = path.join(tempDir, path.basename(normalized));\n\n try {\n await assertDockerCli(\n [\"cp\", `${this.containerName}:${containerPath(this.workdir, normalized)}`, target],\n this.cliOptions(),\n );\n const { readFile } = await import(\"node:fs/promises\");\n const bytes = await readFile(target);\n this.assertFileSize(bytes.byteLength, filePath);\n return bytes;\n } finally {\n await rm(tempDir, { recursive: true, force: true });\n }\n });\n }\n\n async readTextFile(filePath: string): Promise<string> {\n const bytes = await this.readFile(filePath);\n return new TextDecoder().decode(bytes);\n }\n\n async writeFile(filePath: string, data: string | Uint8Array): Promise<void> {\n await this.runOperation(async () => {\n const size = byteLength(data);\n this.assertFileSize(size, filePath);\n const normalized = normalizeSandboxPath(filePath);\n await this.mkdir(parentSandboxPath(normalized));\n\n const tempDir = await mkdtemp(path.join(os.tmpdir(), \"anvia-sandbox-write-\"));\n const source = path.join(tempDir, path.basename(normalized));\n\n try {\n await writeFile(source, data);\n await assertDockerCli(\n [\"cp\", source, `${this.containerName}:${containerPath(this.workdir, normalized)}`],\n this.cliOptions(),\n );\n await this.hooks.onFileWrite?.({ ...this.event(), path: normalized, size });\n } finally {\n await rm(tempDir, { recursive: true, force: true });\n }\n });\n }\n\n async writeTextFile(filePath: string, content: string): Promise<void> {\n await this.writeFile(filePath, content);\n }\n\n async listFiles(filePath = \".\"): Promise<SandboxFileEntry[]> {\n return this.runOperation(async () => {\n const normalized = normalizeSandboxPath(filePath, { allowRoot: true });\n const target = containerPath(this.workdir, normalized);\n const result = await this.execCommand({\n command: \"find\",\n args: [target, \"-mindepth\", \"1\", \"-maxdepth\", \"1\", \"-printf\", \"%p\\t%y\\t%s\\n\"],\n });\n\n if (result.timedOut) {\n throw new SandboxTimeoutError(`Listing files timed out for ${filePath}.`);\n }\n\n if (result.exitCode !== 0) {\n throw new SandboxDockerCommandError(`Unable to list sandbox path: ${filePath}`, result);\n }\n\n return result.stdout\n .split(\"\\n\")\n .filter((line) => line.trim().length > 0)\n .map((line) => this.parseFindEntry(line));\n });\n }\n\n async destroy(): Promise<void> {\n if (this.destroyed) {\n return;\n }\n\n this.destroyed = true;\n this.clearLifecycleTimers();\n await this.processManager.dispose();\n await runDockerCli([\"rm\", \"-f\", this.containerName], this.cliOptions()).catch(() => undefined);\n\n if (this.removeVolumeOnDestroy) {\n await runDockerCli([\"volume\", \"rm\", \"-f\", this.volumeName], this.cliOptions()).catch(\n () => undefined,\n );\n }\n\n await this.hooks.onDestroy?.(this.event());\n }\n\n private async mkdir(directoryPath: string): Promise<void> {\n const normalized = normalizeSandboxPath(directoryPath, { allowRoot: true });\n const result = await this.execCommand({\n command: \"mkdir\",\n args: [\"-p\", containerPath(this.workdir, normalized)],\n });\n\n if (result.exitCode !== 0) {\n throw new SandboxDockerCommandError(\n `Unable to create sandbox directory: ${directoryPath}`,\n result,\n );\n }\n }\n\n private parseFindEntry(line: string): SandboxFileEntry {\n const [rawPath, rawType, rawSize] = line.split(\"\\t\");\n const absolutePath = rawPath ?? \"\";\n const relativePath = absolutePath.startsWith(`${this.workdir}/`)\n ? absolutePath.slice(this.workdir.length + 1)\n : absolutePath;\n const size = rawSize === undefined ? undefined : Number(rawSize);\n const entry: SandboxFileEntry = {\n path: relativePath,\n type: mapFindType(rawType),\n };\n\n if (size !== undefined && Number.isFinite(size)) {\n entry.size = size;\n }\n\n return entry;\n }\n\n private cliOptions() {\n return {\n dockerPath: this.dockerPath,\n maxOutputBytes: this.limits.maxOutputBytes ?? defaultMaxOutputBytes,\n };\n }\n\n private async isPortListening(containerPort: number, timeoutMs: number): Promise<boolean> {\n const result = await runDockerCli(\n [\n \"exec\",\n this.containerName,\n \"sh\",\n \"-c\",\n portProbeScript,\n \"anvia-port-probe\",\n String(containerPort),\n ],\n {\n ...this.cliOptions(),\n timeoutMs: Math.max(1, timeoutMs),\n },\n );\n return result.exitCode === 0;\n }\n\n private async execCommand(options: SandboxExecOptions): Promise<SandboxExecResult> {\n if (options.command.trim().length === 0) {\n throw new SandboxDockerCommandError(\"Sandbox command cannot be empty.\", {\n stdout: \"\",\n stderr: \"\",\n exitCode: 1,\n });\n }\n\n const args = [\"exec\"];\n\n if (options.input !== undefined) {\n args.push(\"-i\");\n }\n\n const cwd = containerPath(this.workdir, options.cwd ?? \".\");\n args.push(\"-w\", cwd);\n\n for (const [key, value] of Object.entries({ ...this.env, ...options.env })) {\n args.push(\"-e\", `${key}=${value}`);\n }\n\n args.push(this.containerName, options.command, ...(options.args ?? []));\n\n const cliOptions: DockerCliOptions = {\n dockerPath: this.dockerPath,\n timeoutMs: options.timeoutMs ?? this.limits.timeoutMs ?? defaultTimeoutMs,\n maxOutputBytes: this.limits.maxOutputBytes ?? defaultMaxOutputBytes,\n };\n if (options.input !== undefined) cliOptions.input = options.input;\n if (options.signal !== undefined) cliOptions.signal = options.signal;\n if (options.onStdout !== undefined) cliOptions.onStdout = options.onStdout;\n if (options.onStderr !== undefined) cliOptions.onStderr = options.onStderr;\n\n const result = await runDockerCli(args, cliOptions);\n\n if (result.timedOut) {\n return {\n ...result,\n exitCode: result.exitCode === 0 ? 124 : result.exitCode,\n };\n }\n\n return result;\n }\n\n private assertActive(): void {\n if (this.destroyed) {\n throw new SandboxSessionDestroyedError(`Sandbox session ${this.id} has been destroyed.`);\n }\n }\n\n event(): SandboxSessionEvent {\n return {\n sessionId: this.id,\n provider: this.provider,\n workdir: this.workdir,\n };\n }\n\n private async runOperation<T>(operation: () => Promise<T>): Promise<T> {\n this.assertActive();\n this.activeOperations += 1;\n this.clearIdleTimer();\n\n try {\n return await operation();\n } finally {\n this.activeOperations -= 1;\n this.scheduleIdleTimer();\n }\n }\n\n private assertFileSize(size: number, filePath: string): void {\n if (this.limits.maxFileBytes !== undefined && size > this.limits.maxFileBytes) {\n throw new SandboxFileSizeError(\n `Sandbox file exceeds maxFileBytes (${size} > ${this.limits.maxFileBytes}): ${filePath}`,\n );\n }\n }\n\n private startLifecycleTimers(): void {\n if (!this.lifecycle.autoDestroy) {\n return;\n }\n\n if (this.lifecycle.ttlMs !== undefined) {\n this.ttlTimer = setTimeout(() => {\n void this.destroy().catch(() => undefined);\n }, this.lifecycle.ttlMs);\n this.ttlTimer.unref?.();\n }\n\n this.scheduleIdleTimer();\n }\n\n private scheduleIdleTimer(): void {\n if (!this.lifecycle.autoDestroy || this.lifecycle.idleTimeoutMs === undefined) {\n return;\n }\n\n if (this.destroyed || this.activeOperations > 0) {\n return;\n }\n\n this.clearIdleTimer();\n this.idleTimer = setTimeout(() => {\n void this.destroy().catch(() => undefined);\n }, this.lifecycle.idleTimeoutMs);\n this.idleTimer.unref?.();\n }\n\n private clearLifecycleTimers(): void {\n if (this.ttlTimer !== undefined) {\n clearTimeout(this.ttlTimer);\n this.ttlTimer = undefined;\n }\n this.clearIdleTimer();\n }\n\n private clearIdleTimer(): void {\n if (this.idleTimer !== undefined) {\n clearTimeout(this.idleTimer);\n this.idleTimer = undefined;\n }\n }\n}\n\nfunction getWorkspaceId(workspace: SandboxWorkspaceOptions, sessionId: string): string {\n if (workspace.mode === \"persistent\") {\n return sanitizeResourceId(workspace.id);\n }\n\n return sessionId;\n}\n\nfunction shouldDestroyWorkspace(workspace: SandboxWorkspaceOptions): boolean {\n if (workspace.mode === \"persistent\") {\n return workspace.destroyOnSessionDestroy ?? false;\n }\n\n return true;\n}\n\nfunction sanitizeResourceId(id: string): string {\n const sanitized = id\n .toLowerCase()\n .replaceAll(/[^a-z0-9_.-]/g, \"-\")\n .replaceAll(/^-+|-+$/g, \"\");\n return sanitized.length > 0 ? sanitized : randomUUID();\n}\n\nfunction byteLength(data: string | Uint8Array): number {\n return typeof data === \"string\" ? Buffer.byteLength(data) : data.byteLength;\n}\n\nfunction mapFindType(type: string | undefined): SandboxFileType {\n if (type === \"f\") {\n return \"file\";\n }\n if (type === \"d\") {\n return \"directory\";\n }\n if (type === \"l\") {\n return \"symlink\";\n }\n return \"other\";\n}\n\nfunction validatePublishedPorts(ports: readonly number[]): number[] {\n const unique = new Set<number>();\n for (const port of ports) {\n if (!isValidPort(port)) {\n throw new SandboxPortError(`Sandbox port must be an integer from 1 to 65535: ${port}`);\n }\n if (unique.has(port)) {\n throw new SandboxPortError(`Sandbox port is duplicated: ${port}`);\n }\n unique.add(port);\n }\n return [...unique];\n}\n\nfunction isValidPort(port: number): boolean {\n return Number.isInteger(port) && port >= 1 && port <= 65_535;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction assertWaitOptions(timeoutMs: number, intervalMs: number): void {\n if (!Number.isInteger(timeoutMs) || timeoutMs <= 0) {\n throw new SandboxPortError(\"Port wait timeoutMs must be a positive integer.\");\n }\n if (!Number.isInteger(intervalMs) || intervalMs <= 0) {\n throw new SandboxPortError(\"Port wait intervalMs must be a positive integer.\");\n }\n}\n\nasync function waitWithSignal(timeoutMs: number, signal: AbortSignal | undefined): Promise<void> {\n if (signal?.aborted === true) throw abortReason(signal);\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n signal?.removeEventListener(\"abort\", abort);\n resolve();\n }, timeoutMs);\n const abort = () => {\n clearTimeout(timeout);\n reject(abortReason(signal));\n };\n signal?.addEventListener(\"abort\", abort, { once: true });\n });\n}\n\nfunction abortReason(signal: AbortSignal | undefined): unknown {\n return signal?.reason ?? new SandboxPortError(\"Waiting for sandbox port was aborted.\");\n}\n","import { type ChildProcessWithoutNullStreams, spawn } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport { runDockerCli } from \"./docker-cli\";\nimport {\n SandboxDockerCommandError,\n SandboxDockerUnavailableError,\n SandboxProcessError,\n SandboxTimeoutError,\n} from \"./errors\";\nimport { containerPath } from \"./path\";\nimport type {\n SandboxProcessInfo,\n SandboxProcessLogs,\n SandboxProcessLogsOptions,\n SandboxProcessStartOptions,\n SandboxProcessStopOptions,\n} from \"./types\";\n\nconst processMarkerPrefix = \"ANVIA_PROCESS\";\n// Report the supervisor, direct-child, and process-group PIDs through a private stdout marker. Use\n// a dedicated session when setsid is available; Docker exec otherwise gives the supervisor its own\n// process group. User-provided command arguments remain positional rather than shell-interpolated.\nconst processWrapper = [\n 'marker=\"$1\"',\n \"shift\",\n \"if command -v setsid >/dev/null 2>&1; then\",\n ' setsid \"$@\" &',\n \" child=$!\",\n \" group=$child\",\n \"else\",\n ' \"$@\" &',\n \" child=$!\",\n \" group=$$\",\n \"fi\",\n `printf '\\\\036%s:%s:%s:%s\\\\036' \"$marker\" \"$$\" \"$child\" \"$group\"`,\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 onStart?: (process: SandboxProcessInfo) => void | Promise<void>;\n onExit?: (\n process: SandboxProcessInfo,\n logs: SandboxProcessLogs,\n durationMs: number,\n ) => void | Promise<void>;\n}\n\ninterface ManagedProcessRecord {\n info: SandboxProcessInfo;\n startedAtMs: number;\n child: ChildProcessWithoutNullStreams;\n stdout: TailOutputCollector;\n stderr: TailOutputCollector;\n markerStart: Buffer;\n markerBuffer: Buffer;\n supervisorPid?: number;\n childPid?: number;\n processGroupId?: number;\n spawnFailed: boolean;\n stopRequested: boolean;\n startResolved: boolean;\n exitNotified: 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 new SandboxProcessError(\"Sandbox maxProcesses must be a non-negative integer.\");\n }\n if (!Number.isInteger(options.maxOutputBytes) || options.maxOutputBytes < 0) {\n throw new SandboxProcessError(\"Sandbox maxOutputBytes must be a non-negative integer.\");\n }\n if (!Number.isInteger(options.startupTimeoutMs) || options.startupTimeoutMs <= 0) {\n throw new SandboxProcessError(\"Sandbox process startup timeout must be a positive integer.\");\n }\n }\n\n async start(options: SandboxProcessStartOptions): Promise<SandboxProcessInfo> {\n this.assertActive();\n assertStartOptions(options);\n await this.pruneCompletedRecords();\n\n const trackedCount = this.records.size;\n if (trackedCount >= this.options.maxProcesses) {\n throw new SandboxProcessError(\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 child.stdin.end();\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: SandboxProcessInfo = {\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 startedAtMs: Date.now(),\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 exitNotified: 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);\n await this.options.onStart?.(copyProcessInfo(record.info));\n record.startResolved = true;\n if (record.info.status !== \"running\") this.notifyExit(record);\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(): SandboxProcessInfo[] {\n this.assertActive();\n return [...this.records.values()].map((record) => copyProcessInfo(record.info));\n }\n\n logs(processId: string, options: SandboxProcessLogsOptions = {}): SandboxProcessLogs {\n this.assertActive();\n const record = this.getRecord(processId);\n const stdout = record.stdout.snapshot(options.tailBytes);\n const stderr = record.stderr.snapshot(options.tailBytes);\n return {\n stdout: stdout.text,\n stderr: stderr.text,\n stdoutTruncated: stdout.truncated,\n stderrTruncated: stderr.truncated,\n };\n }\n\n async stop(\n processId: string,\n options: SandboxProcessStopOptions = {},\n ): Promise<SandboxProcessInfo> {\n this.assertActive();\n const record = this.getRecord(processId);\n const gracePeriodMs = options.gracePeriodMs ?? 5_000;\n if (!Number.isInteger(gracePeriodMs) || gracePeriodMs < 0) {\n throw new SandboxProcessError(\"Process gracePeriodMs must be a non-negative integer.\");\n }\n\n try {\n if (!(await this.terminateRecord(record, gracePeriodMs))) {\n throw new SandboxProcessError(`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(): Promise<void> {\n if (this.disposed) return;\n this.disposed = true;\n\n await Promise.all(\n [...this.records.values()].map(async (record) => {\n await this.terminateRecord(record, 1_000).catch(() => false);\n }),\n );\n }\n\n private createExecArgs(options: SandboxProcessStartOptions, marker: string): string[] {\n const args = [\"exec\", \"-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 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 SandboxDockerUnavailableError(\"Docker CLI was not found.\", error)\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 new SandboxProcessError(\n `Sandbox process exited before startup completed: ${record.info.id}`,\n ),\n );\n record.resolveClosed();\n\n if (record.startResolved) this.notifyExit(record);\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 = record.markerBuffer\n .subarray(start + record.markerStart.length, end)\n .toString(\"utf8\")\n .split(\":\");\n const supervisorPid = Number(rawPids[0]);\n const childPid = Number(rawPids[1]);\n const processGroupId = Number(rawPids[2]);\n if (!isProcessId(supervisorPid) || !isProcessId(childPid) || !isProcessId(processGroupId)) {\n record.rejectStarted(\n new SandboxProcessError(\"Sandbox process returned invalid process IDs.\"),\n );\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.childPid = childPid;\n record.processGroupId = processGroupId;\n record.resolveStarted();\n }\n\n private async waitForStart(record: ManagedProcessRecord) {\n let timeout: ReturnType<typeof setTimeout> | undefined;\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeout = setTimeout(() => {\n reject(new SandboxTimeoutError(\"Starting sandbox process timed out.\"));\n }, this.options.startupTimeoutMs);\n timeout.unref?.();\n });\n\n try {\n await Promise.race([record.started, timeoutPromise]);\n } finally {\n if (timeout !== undefined) clearTimeout(timeout);\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 await waitForPromise(record.closed, 250);\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 ): Promise<boolean> {\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));\n }\n if (record.processGroupId === undefined) {\n return record.spawnFailed && record.info.status !== \"running\";\n }\n }\n\n if (!(await this.isProcessGroupRunning(record))) {\n return this.finishAfterGroupExit(record);\n }\n\n await this.signal(record, \"TERM\");\n if (await this.waitForRecordExit(record, gracePeriodMs)) return true;\n\n await this.signal(record, \"KILL\");\n if (await this.waitForRecordExit(record, 1_000)) return true;\n\n return false;\n }\n\n private async waitForRecordExit(\n record: ManagedProcessRecord,\n timeoutMs: number,\n ): Promise<boolean> {\n const deadline = Date.now() + timeoutMs;\n while (true) {\n if (!(await this.isProcessGroupRunning(record))) {\n return this.finishAfterGroupExit(record);\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);\n } else {\n await waitForDelay(intervalMs);\n }\n }\n }\n\n private async finishAfterGroupExit(record: ManagedProcessRecord): Promise<boolean> {\n if (record.info.status !== \"running\") return true;\n record.child.kill(\"SIGKILL\");\n return waitForPromise(record.closed, 1_000);\n }\n\n private async isProcessGroupRunning(record: ManagedProcessRecord): 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 String(record.processGroupId),\n ],\n {\n dockerPath: this.options.dockerPath,\n timeoutMs: 5_000,\n maxOutputBytes: this.options.maxOutputBytes,\n },\n );\n return result.exitCode === 0;\n }\n\n private async signal(record: ManagedProcessRecord, signal: \"TERM\" | \"KILL\"): 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 String(record.processGroupId),\n signal,\n ],\n {\n dockerPath: this.options.dockerPath,\n timeoutMs: 5_000,\n maxOutputBytes: this.options.maxOutputBytes,\n },\n );\n if (result.exitCode !== 0) {\n throw new SandboxDockerCommandError(\n `Unable to stop sandbox process: ${record.info.id}`,\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 new SandboxProcessError(`Unknown sandbox process: ${processId}`);\n }\n return record;\n }\n\n private async pruneCompletedRecords(): 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));\n if (record.info.status !== \"running\" && cleanupConfirmed) {\n this.records.delete(id);\n }\n }\n }\n\n private logsUnsafe(record: ManagedProcessRecord): SandboxProcessLogs {\n const stdout = record.stdout.snapshot();\n const stderr = record.stderr.snapshot();\n return {\n stdout: stdout.text,\n stderr: stderr.text,\n stdoutTruncated: stdout.truncated,\n stderrTruncated: stderr.truncated,\n };\n }\n\n private notifyExit(record: ManagedProcessRecord): void {\n if (record.exitNotified) return;\n record.exitNotified = true;\n const durationMs = Date.now() - record.startedAtMs;\n const notify = async () =>\n this.options.onExit?.(copyProcessInfo(record.info), this.logsUnsafe(record), durationMs);\n void notify().catch(() => undefined);\n }\n\n private assertActive(): void {\n if (this.disposed) {\n throw new SandboxProcessError(\"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): { text: string; truncated: boolean } {\n if (tailBytes !== undefined && (!Number.isInteger(tailBytes) || tailBytes < 0)) {\n throw new SandboxProcessError(\"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 text: selected.toString(\"utf8\"),\n truncated: this.didTruncate || selected.length < bytes.length,\n };\n }\n}\n\nfunction assertStartOptions(options: SandboxProcessStartOptions): void {\n if (options.command.trim().length === 0) {\n throw new SandboxProcessError(\"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: SandboxProcessInfo): SandboxProcessInfo {\n const copy: SandboxProcessInfo = {\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.cwd = info.cwd;\n if (info.exitCode !== undefined) copy.exitCode = info.exitCode;\n if (info.endedAt !== undefined) copy.endedAt = info.endedAt;\n return copy;\n}\n\nasync function waitForPromise(promise: Promise<void>, timeoutMs: number): Promise<boolean> {\n let timeout: ReturnType<typeof setTimeout> | 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 ]);\n } finally {\n if (timeout !== undefined) clearTimeout(timeout);\n }\n}\n\nasync function waitForDelay(timeoutMs: number): Promise<void> {\n await new Promise<void>((resolve) => {\n const timeout = setTimeout(resolve, timeoutMs);\n timeout.unref?.();\n });\n}\n","import path from \"node:path\";\nimport { SandboxPathError } from \"./errors\";\n\nexport function normalizeSandboxPath(input: string, options: { allowRoot?: boolean } = {}): string {\n if (input.length === 0) {\n throw new SandboxPathError(\"Sandbox path cannot be empty.\");\n }\n\n if (input.includes(\"\\0\")) {\n throw new SandboxPathError(\"Sandbox path cannot contain null bytes.\");\n }\n\n const normalized = path.posix.normalize(input.replaceAll(\"\\\\\", \"/\"));\n\n if (path.posix.isAbsolute(normalized)) {\n throw new SandboxPathError(`Sandbox path must be relative: ${input}`);\n }\n\n if (normalized === \"..\" || normalized.startsWith(\"../\")) {\n throw new SandboxPathError(`Sandbox path cannot leave the workspace: ${input}`);\n }\n\n if (normalized === \".\" && options.allowRoot !== true) {\n throw new SandboxPathError(\n \"Sandbox path must refer to a file or directory inside the workspace.\",\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 AnyTool, createTool } from \"@anvia/core/tool\";\nimport { z } from \"zod\";\nimport { isSandboxPortSession, isSandboxProcessSession } from \"./capabilities\";\nimport { SandboxToolPolicyError } from \"./errors\";\nimport type {\n SandboxExecOptions,\n SandboxExecResult,\n SandboxPortSession,\n SandboxProcessInfo,\n SandboxProcessSession,\n SandboxProcessStartOptions,\n SandboxSession,\n SandboxToolName,\n SandboxToolsOptions,\n} from \"./types\";\n\nconst execCommandInput = z.object({\n command: z.string().min(1).describe(\"Executable to run inside the sandbox workspace.\"),\n args: z.array(z.string()).optional().describe(\"Command arguments.\"),\n cwd: z.string().optional().describe(\"Relative working directory inside the sandbox.\"),\n env: z\n .record(z.string(), z.string())\n .optional()\n .describe(\"Environment variables for this command.\"),\n timeoutMs: z\n .number()\n .int()\n .positive()\n .max(300_000)\n .optional()\n .describe(\"Optional command timeout in milliseconds.\"),\n input: z.string().optional().describe(\"Optional stdin text to pass to the command.\"),\n});\n\nconst readFileInput = z.object({\n path: z.string().min(1).describe(\"Relative file path inside the sandbox.\"),\n});\n\nconst writeFileInput = z.object({\n path: z.string().min(1).describe(\"Relative file path inside the sandbox.\"),\n content: z.string().describe(\"Complete text content to write.\"),\n});\n\nconst listFilesInput = z.object({\n path: z\n .string()\n .optional()\n .describe(\"Relative directory path inside the sandbox. Defaults to root.\"),\n});\n\nconst emptyInput = z.object({});\n\nconst startProcessInput = z.object({\n command: z.string().min(1).describe(\"Executable to run as a managed sandbox process.\"),\n args: z.array(z.string()).optional().describe(\"Command arguments.\"),\n cwd: z.string().optional().describe(\"Relative working directory inside the sandbox.\"),\n env: z\n .record(z.string(), z.string())\n .optional()\n .describe(\"Environment variables for this process.\"),\n});\n\nconst processIdInput = z.object({\n processId: z.string().min(1).describe(\"Managed process identifier.\"),\n});\n\nconst readProcessLogsInput = processIdInput.extend({\n tailBytes: z\n .number()\n .int()\n .nonnegative()\n .max(1024 * 1024)\n .optional()\n .describe(\"Maximum trailing bytes to return from each output stream.\"),\n});\n\nconst waitForPortInput = z.object({\n containerPort: z\n .number()\n .int()\n .min(1)\n .max(65_535)\n .describe(\"Pre-authorized TCP port inside the sandbox container.\"),\n timeoutMs: z\n .number()\n .int()\n .positive()\n .max(300_000)\n .optional()\n .describe(\"Maximum time to wait for the port to accept connections.\"),\n});\n\nconst textOutput = z.string();\nconst maxToolLogBytes = 1024 * 1024;\nconst sandboxToolMetadataKey = Symbol.for(\"anvia.sandbox.tool.metadata\");\n\nexport function createSandboxTools(\n session: SandboxSession,\n options: SandboxToolsOptions = {},\n): AnyTool[] {\n const include = new Set<SandboxToolName>(\n options.allow ?? options.include ?? [\"exec_command\", \"read_file\", \"write_file\", \"list_files\"],\n );\n const tools: AnyTool[] = [];\n\n if (include.has(\"exec_command\")) {\n tools.push(createExecCommandTool(session, options));\n }\n\n if (include.has(\"read_file\")) {\n tools.push(createReadFileTool(session, options));\n }\n\n if (include.has(\"write_file\")) {\n tools.push(createWriteFileTool(session, options));\n }\n\n if (include.has(\"list_files\")) {\n tools.push(createListFilesTool(session));\n }\n\n const portToolsRequested = include.has(\"list_ports\") || include.has(\"wait_for_port\");\n const portSession = portToolsRequested ? requirePortSession(session) : undefined;\n if (include.has(\"list_ports\") && portSession !== undefined) {\n tools.push(createListPortsTool(portSession));\n }\n\n const processToolsRequested =\n include.has(\"start_process\") ||\n include.has(\"list_processes\") ||\n include.has(\"read_process_logs\") ||\n include.has(\"stop_process\");\n if (include.has(\"wait_for_port\") || processToolsRequested) assertProcessToolPolicy(options);\n const processSession = processToolsRequested ? requireProcessSession(session) : undefined;\n if (include.has(\"start_process\") && processSession !== undefined) {\n tools.push(createStartProcessTool(processSession, options));\n }\n\n if (include.has(\"list_processes\") && processSession !== undefined) {\n tools.push(createListProcessesTool(processSession));\n }\n\n if (include.has(\"read_process_logs\") && processSession !== undefined) {\n tools.push(createReadProcessLogsTool(processSession, options));\n }\n\n if (include.has(\"stop_process\") && processSession !== undefined) {\n tools.push(createStopProcessTool(processSession, options));\n }\n\n if (include.has(\"wait_for_port\") && portSession !== undefined) {\n tools.push(createWaitForPortTool(portSession, options));\n }\n\n for (const tool of tools) {\n Object.defineProperty(tool, sandboxToolMetadataKey, {\n value: { session },\n enumerable: false,\n });\n }\n\n return tools;\n}\n\nfunction createExecCommandTool(session: SandboxSession, options: SandboxToolsOptions): AnyTool {\n const policy = options.exec ?? {};\n\n return createTool({\n name: \"exec_command\",\n description:\n \"Run a command inside the sandbox workspace. Use structured args instead of shell quoting.\",\n input: execCommandInput,\n output: textOutput,\n execute: async ({ command, args, cwd, env, timeoutMs, input }) => {\n assertCommandAllowed(command, options);\n\n const execOptions: SandboxExecOptions = {\n command,\n };\n\n if (args !== undefined) {\n execOptions.args = args;\n }\n if (cwd !== undefined) {\n execOptions.cwd = cwd;\n }\n if (env !== undefined) {\n execOptions.env = env;\n }\n const effectiveTimeoutMs = timeoutMs ?? policy.defaultTimeoutMs ?? options.execTimeoutMs;\n if (effectiveTimeoutMs !== undefined) {\n assertTimeoutAllowed(effectiveTimeoutMs, options);\n execOptions.timeoutMs = effectiveTimeoutMs;\n }\n if (input !== undefined) {\n execOptions.input = input;\n }\n\n const result = await session.exec(execOptions);\n\n return formatExecResult(result);\n },\n });\n}\n\nfunction createReadFileTool(session: SandboxSession, options: SandboxToolsOptions): AnyTool {\n return createTool({\n name: \"read_file\",\n description: \"Read a text file from the sandbox workspace.\",\n input: readFileInput,\n output: textOutput,\n execute: async ({ path }) => {\n const content = await session.readTextFile(path);\n assertReadAllowed(content, options);\n return content;\n },\n });\n}\n\nfunction createWriteFileTool(session: SandboxSession, options: SandboxToolsOptions): AnyTool {\n return createTool({\n name: \"write_file\",\n description: \"Write a text file inside the sandbox workspace. Creates parent directories.\",\n input: writeFileInput,\n output: textOutput,\n execute: async ({ path, content }) => {\n assertContentAllowed(content, options);\n await session.writeTextFile(path, content);\n return `Wrote ${path}`;\n },\n });\n}\n\nfunction createListFilesTool(session: SandboxSession): AnyTool {\n return createTool({\n name: \"list_files\",\n description: \"List files and directories inside the sandbox workspace.\",\n input: listFilesInput,\n output: textOutput,\n execute: async ({ path }) => {\n const entries = await session.listFiles(path);\n\n if (entries.length === 0) {\n return \"No files found.\";\n }\n\n return entries\n .map((entry) => {\n const size = entry.size === undefined ? \"\" : ` ${entry.size}b`;\n return `${entry.type}${size}\\t${entry.path}`;\n })\n .join(\"\\n\");\n },\n });\n}\n\nfunction createListPortsTool(session: SandboxPortSession): AnyTool {\n return createTool({\n name: \"list_ports\",\n description:\n \"List pre-authorized sandbox preview ports. Servers must bind to 0.0.0.0 on a listed container port.\",\n input: emptyInput,\n output: textOutput,\n execute: async () => {\n if (session.publishedPorts.length === 0) {\n return \"No sandbox ports are published.\";\n }\n return session.publishedPorts\n .map((port) => `${port.containerPort}/${port.protocol}\\t${port.host}:${port.hostPort}`)\n .join(\"\\n\");\n },\n });\n}\n\nfunction createStartProcessTool(\n session: SandboxProcessSession,\n options: SandboxToolsOptions,\n): AnyTool {\n return createTool({\n name: \"start_process\",\n description:\n \"Start a managed long-running process inside the sandbox. Use list_ports first and bind web servers to 0.0.0.0.\",\n input: startProcessInput,\n output: textOutput,\n execute: async ({ command, args, cwd, env }) => {\n assertCommandAllowed(command, options);\n const processOptions: SandboxProcessStartOptions = { command };\n if (args !== undefined) processOptions.args = args;\n if (cwd !== undefined) processOptions.cwd = cwd;\n if (env !== undefined) processOptions.env = env;\n return formatProcessInfo(await session.startProcess(processOptions));\n },\n });\n}\n\nfunction createListProcessesTool(session: SandboxProcessSession): AnyTool {\n return createTool({\n name: \"list_processes\",\n description: \"List managed sandbox processes and their current status.\",\n input: emptyInput,\n output: textOutput,\n execute: async () => {\n const processes = await session.listProcesses();\n if (processes.length === 0) return \"No managed processes.\";\n return processes.map(formatProcessInfo).join(\"\\n\\n\");\n },\n });\n}\n\nfunction createReadProcessLogsTool(\n session: SandboxProcessSession,\n options: SandboxToolsOptions,\n): AnyTool {\n return createTool({\n name: \"read_process_logs\",\n description: \"Read recent stdout and stderr from a managed sandbox process.\",\n input: readProcessLogsInput,\n output: textOutput,\n execute: async ({ processId, tailBytes }) => {\n const configuredMaxLogBytes = options.process?.maxLogBytes ?? 64 * 1024;\n if (!Number.isInteger(configuredMaxLogBytes) || configuredMaxLogBytes < 0) {\n throw new SandboxToolPolicyError(\"Process maxLogBytes must be a non-negative integer.\");\n }\n const maxLogBytes = Math.min(configuredMaxLogBytes, maxToolLogBytes);\n const effectiveTailBytes = tailBytes ?? maxLogBytes;\n if (effectiveTailBytes > maxLogBytes) {\n throw new SandboxToolPolicyError(\n `Process log request exceeds sandbox tool policy (${effectiveTailBytes} > ${maxLogBytes}).`,\n );\n }\n const logs = await session.readProcessLogs(processId, {\n tailBytes: effectiveTailBytes,\n });\n const parts: string[] = [];\n if (logs.stdout.length > 0) parts.push(`stdout:\\n${logs.stdout.trimEnd()}`);\n if (logs.stderr.length > 0) parts.push(`stderr:\\n${logs.stderr.trimEnd()}`);\n if (logs.stdoutTruncated || logs.stderrTruncated) parts.push(\"output_truncated: true\");\n return parts.length > 0 ? parts.join(\"\\n\\n\") : \"No process output.\";\n },\n });\n}\n\nfunction createStopProcessTool(\n session: SandboxProcessSession,\n options: SandboxToolsOptions,\n): AnyTool {\n return createTool({\n name: \"stop_process\",\n description: \"Stop a managed sandbox process.\",\n input: processIdInput,\n output: textOutput,\n execute: async ({ processId }) =>\n formatProcessInfo(\n await session.stopProcess(processId, {\n gracePeriodMs: options.process?.stopGracePeriodMs ?? 5_000,\n }),\n ),\n });\n}\n\nfunction createWaitForPortTool(session: SandboxPortSession, options: SandboxToolsOptions): AnyTool {\n return createTool({\n name: \"wait_for_port\",\n description: \"Wait until a pre-authorized sandbox TCP port is accepting connections.\",\n input: waitForPortInput,\n output: textOutput,\n execute: async ({ containerPort, timeoutMs }) => {\n const effectiveTimeoutMs = timeoutMs ?? options.process?.defaultWaitTimeoutMs ?? 30_000;\n const maxWaitTimeoutMs = options.process?.maxWaitTimeoutMs ?? 300_000;\n if (effectiveTimeoutMs > maxWaitTimeoutMs) {\n throw new SandboxToolPolicyError(\n `Port wait timeout exceeds sandbox tool policy (${effectiveTimeoutMs} > ${maxWaitTimeoutMs}).`,\n );\n }\n const port = await session.waitForPort(containerPort, {\n timeoutMs: effectiveTimeoutMs,\n });\n return `ready: ${port.containerPort}/${port.protocol} -> ${port.host}:${port.hostPort}`;\n },\n });\n}\n\nfunction formatExecResult(result: SandboxExecResult): string {\n const parts = [`exit_code: ${result.exitCode}`];\n\n if (result.timedOut) {\n parts.push(\"timed_out: true\");\n }\n\n if (result.aborted) {\n parts.push(\"aborted: true\");\n }\n\n if (result.stdout.length > 0) {\n parts.push(`stdout:\\n${result.stdout.trimEnd()}`);\n }\n\n if (result.stderr.length > 0) {\n parts.push(`stderr:\\n${result.stderr.trimEnd()}`);\n }\n\n if (result.stdoutTruncated || result.stderrTruncated) {\n parts.push(\"output_truncated: true\");\n }\n\n return parts.join(\"\\n\\n\");\n}\n\nfunction formatProcessInfo(process: SandboxProcessInfo): string {\n const parts = [\n `process_id: ${process.id}`,\n `status: ${process.status}`,\n `command: ${[process.command, ...process.args].join(\" \")}`,\n ];\n if (process.exitCode !== undefined) parts.push(`exit_code: ${process.exitCode}`);\n return parts.join(\"\\n\");\n}\n\nfunction requirePortSession(session: SandboxSession): SandboxPortSession {\n if (!isSandboxPortSession(session)) {\n throw new SandboxToolPolicyError(\"The sandbox session does not support published port tools.\");\n }\n return session;\n}\n\nfunction requireProcessSession(session: SandboxSession): SandboxProcessSession {\n if (!isSandboxProcessSession(session)) {\n throw new SandboxToolPolicyError(\"The sandbox session does not support managed process tools.\");\n }\n return session;\n}\n\nfunction assertProcessToolPolicy(options: SandboxToolsOptions): void {\n const policy = options.process;\n if (policy === undefined) return;\n if (\n policy.maxLogBytes !== undefined &&\n (!Number.isInteger(policy.maxLogBytes) ||\n policy.maxLogBytes < 0 ||\n policy.maxLogBytes > maxToolLogBytes)\n ) {\n throw new SandboxToolPolicyError(\n `Process maxLogBytes must be an integer from 0 to ${maxToolLogBytes}.`,\n );\n }\n const maxWaitTimeoutMs = policy.maxWaitTimeoutMs ?? 300_000;\n if (!Number.isInteger(maxWaitTimeoutMs) || maxWaitTimeoutMs <= 0 || maxWaitTimeoutMs > 300_000) {\n throw new SandboxToolPolicyError(\n \"Process maxWaitTimeoutMs must be an integer from 1 to 300000.\",\n );\n }\n if (\n policy.defaultWaitTimeoutMs !== undefined &&\n (!Number.isInteger(policy.defaultWaitTimeoutMs) ||\n policy.defaultWaitTimeoutMs <= 0 ||\n policy.defaultWaitTimeoutMs > maxWaitTimeoutMs)\n ) {\n throw new SandboxToolPolicyError(\n \"Process defaultWaitTimeoutMs must be positive and no greater than maxWaitTimeoutMs.\",\n );\n }\n if (\n policy.stopGracePeriodMs !== undefined &&\n (!Number.isInteger(policy.stopGracePeriodMs) || policy.stopGracePeriodMs < 0)\n ) {\n throw new SandboxToolPolicyError(\"Process stopGracePeriodMs must be a non-negative integer.\");\n }\n}\n\nfunction assertCommandAllowed(command: string, options: SandboxToolsOptions): void {\n const policy = options.exec;\n\n if (policy?.blockedCommands?.includes(command)) {\n throw new SandboxToolPolicyError(`Command is blocked by sandbox tool policy: ${command}`);\n }\n\n if (policy?.allowedCommands !== undefined && !policy.allowedCommands.includes(command)) {\n throw new SandboxToolPolicyError(`Command is not allowed by sandbox tool policy: ${command}`);\n }\n}\n\nfunction assertTimeoutAllowed(timeoutMs: number, options: SandboxToolsOptions): void {\n const maxTimeoutMs = options.exec?.maxTimeoutMs;\n\n if (maxTimeoutMs !== undefined && timeoutMs > maxTimeoutMs) {\n throw new SandboxToolPolicyError(\n `Command timeout exceeds sandbox tool policy (${timeoutMs} > ${maxTimeoutMs}).`,\n );\n }\n}\n\nfunction assertContentAllowed(content: string, options: SandboxToolsOptions): void {\n const maxBytes = options.writeFile?.maxBytes;\n\n if (maxBytes !== undefined && Buffer.byteLength(content) > maxBytes) {\n throw new SandboxToolPolicyError(\"File content exceeds sandbox tool policy.\");\n }\n}\n\nfunction assertReadAllowed(content: string, options: SandboxToolsOptions): void {\n const maxBytes = options.readFile?.maxBytes;\n\n if (maxBytes !== undefined && Buffer.byteLength(content) > maxBytes) {\n throw new SandboxToolPolicyError(\"File content exceeds sandbox tool policy.\");\n }\n}\n"],"mappings":"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","names":["randomUUID","path","randomUUID","path","path"]}
1
+ {"version":3,"sources":["../src/capabilities.ts","../src/docker-sandbox.ts","../src/docker-process.ts","../src/path.ts","../src/text-file.ts","../src/tools.ts"],"sourcesContent":["import type { SandboxPortSession, SandboxProcessSession, SandboxSession } from \"./types\";\n\nexport function isSandboxPortSession(session: SandboxSession): session is SandboxPortSession {\n const candidate = session as Partial<SandboxPortSession>;\n return Array.isArray(candidate.publishedPorts) && typeof candidate.waitForPort === \"function\";\n}\n\nexport function isSandboxProcessSession(session: SandboxSession): session is SandboxProcessSession {\n const candidate = session as Partial<SandboxProcessSession>;\n return (\n typeof candidate.startProcess === \"function\" &&\n typeof candidate.listProcesses === \"function\" &&\n typeof candidate.readProcessLogs === \"function\" &&\n typeof candidate.stopProcess === \"function\"\n );\n}\n","import { randomUUID } from \"node:crypto\";\nimport { mkdtemp, rm, writeFile } from \"node:fs/promises\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { assertDockerCli, type DockerCliOptions, runDockerCli } from \"./docker-cli\";\nimport { DockerProcessManager } from \"./docker-process\";\nimport {\n SandboxDockerCommandError,\n SandboxFileSizeError,\n SandboxPortError,\n SandboxSessionDestroyedError,\n SandboxTimeoutError,\n} from \"./errors\";\nimport { containerPath, normalizeSandboxPath, parentSandboxPath } from \"./path\";\nimport { createTextFilePage } from \"./text-file\";\nimport type {\n DockerSandboxCreateSessionOptions,\n DockerSandboxOptions,\n DockerSandboxSession,\n Sandbox,\n SandboxExecEndEvent,\n SandboxExecEvent,\n SandboxExecOptions,\n SandboxExecResult,\n SandboxExecStreamEvent,\n SandboxFileEntry,\n SandboxFileType,\n SandboxHooks,\n SandboxLifecycleOptions,\n SandboxLimits,\n SandboxManifest,\n SandboxProcessInfo,\n SandboxProcessLogs,\n SandboxProcessLogsOptions,\n SandboxProcessStartOptions,\n SandboxProcessStopOptions,\n SandboxPublishedPort,\n SandboxSessionEvent,\n SandboxTextFileReadOptions,\n SandboxTextFileReadResult,\n SandboxWaitForPortOptions,\n SandboxWorkspaceOptions,\n} from \"./types\";\n\nconst defaultImage = \"node:22-bookworm\";\nconst defaultWorkdir = \"/workspace\";\nconst defaultTimeoutMs = 30_000;\nconst defaultMaxOutputBytes = 1024 * 1024;\nconst defaultMaxProcesses = 4;\nconst defaultTextFilePageLines = 500;\nconst defaultTextFilePageBytes = 64 * 1024;\n// Docker Desktop may accept a host-side TCP connection before a container service is ready. Probe\n// Linux socket state in the container so readiness requires an all-interface listening socket.\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\");\nconst textFilePageScript = [\n 'start=\"$1\"',\n 'count=\"$2\"',\n 'max_bytes=\"$3\"',\n 'file=\"$4\"',\n 'end=\"$((start + count))\"',\n '[ -f \"$file\" ] || { echo \"Not a readable file: $file\" >&2; exit 66; }',\n 'sed -n \"$start,$end p;$end q\" \"$file\" | head -c \"$max_bytes\"',\n].join(\"\\n\");\n\nexport class DockerSandbox implements Sandbox {\n readonly provider = \"docker\";\n\n private readonly image: string;\n private readonly pull: \"missing\" | \"always\" | \"never\";\n private readonly workdir: string;\n private readonly workspace: SandboxWorkspaceOptions;\n private readonly lifecycle: Required<Pick<SandboxLifecycleOptions, \"autoDestroy\">> &\n Omit<SandboxLifecycleOptions, \"autoDestroy\">;\n private readonly network: NonNullable<DockerSandboxOptions[\"network\"]>;\n private readonly dockerPath: string;\n private readonly labels: Record<string, string>;\n private readonly limits: SandboxLimits;\n private readonly security: Required<NonNullable<DockerSandboxOptions[\"security\"]>>;\n private readonly hooks: SandboxHooks;\n private readonly user: string | undefined;\n\n constructor(options: DockerSandboxOptions = {}) {\n this.image = options.image ?? defaultImage;\n this.pull = options.pull ?? \"missing\";\n this.workdir = options.workdir ?? defaultWorkdir;\n this.workspace = options.workspace ?? { mode: \"ephemeral\" };\n const lifecycle: Required<Pick<SandboxLifecycleOptions, \"autoDestroy\">> &\n Omit<SandboxLifecycleOptions, \"autoDestroy\"> = {\n autoDestroy: options.lifecycle?.autoDestroy ?? true,\n };\n if (options.lifecycle?.ttlMs !== undefined) lifecycle.ttlMs = options.lifecycle.ttlMs;\n if (options.lifecycle?.idleTimeoutMs !== undefined) {\n lifecycle.idleTimeoutMs = options.lifecycle.idleTimeoutMs;\n }\n this.lifecycle = lifecycle;\n this.network = options.network ?? false;\n this.dockerPath = options.dockerPath ?? \"docker\";\n this.labels = options.labels ?? {};\n this.limits = options.limits ?? {};\n this.security = {\n readonlyRootfs: options.security?.readonlyRootfs ?? false,\n noNewPrivileges: options.security?.noNewPrivileges ?? true,\n dropCapabilities: options.security?.dropCapabilities ?? [\"ALL\"],\n };\n this.hooks = options.hooks ?? {};\n this.user = options.user;\n }\n\n static node(options: DockerSandboxOptions = {}): DockerSandbox {\n return new DockerSandbox({ ...options, image: options.image ?? \"node:22-bookworm\" });\n }\n\n static python(options: DockerSandboxOptions = {}): DockerSandbox {\n return new DockerSandbox({ ...options, image: options.image ?? \"python:3.13-bookworm\" });\n }\n\n static deno(options: DockerSandboxOptions = {}): DockerSandbox {\n return new DockerSandbox({ ...options, image: options.image ?? \"denoland/deno:debian\" });\n }\n\n async createSession(\n options: DockerSandboxCreateSessionOptions = {},\n ): Promise<DockerSandboxSession> {\n const ports = validatePublishedPorts(options.ports ?? []);\n this.assertPortNetworkCompatible(ports);\n await this.ensureImage();\n\n const id = sanitizeResourceId(options.id ?? randomUUID());\n const workspace = options.workspace ?? this.workspace;\n const workspaceId = getWorkspaceId(workspace, id);\n const containerName = `anvia-sandbox-${id}`;\n const volumeName = `anvia-sandbox-${workspaceId}-workspace`;\n const removeVolumeOnDestroy = shouldDestroyWorkspace(workspace);\n\n await assertDockerCli([\"volume\", \"create\", volumeName], this.cliOptions());\n\n try {\n await assertDockerCli(\n this.createRunArgs(containerName, volumeName, workspace, options.metadata, ports),\n {\n ...this.cliOptions(),\n timeoutMs: this.limits.timeoutMs ?? defaultTimeoutMs,\n },\n );\n\n const publishedPorts = await this.inspectPublishedPorts(containerName, ports);\n\n const session = new DockerSandboxSessionImpl({\n id,\n containerName,\n volumeName,\n workdir: this.workdir,\n dockerPath: this.dockerPath,\n limits: this.limits,\n lifecycle: this.lifecycle,\n removeVolumeOnDestroy,\n env: options.manifest?.env ?? {},\n hooks: this.hooks,\n publishedPorts,\n });\n\n await session.applyManifest(options.manifest);\n await this.hooks.onSessionCreate?.(session.event());\n return session;\n } catch (error) {\n await this.cleanup(containerName, removeVolumeOnDestroy ? volumeName : undefined);\n throw error;\n }\n }\n\n private async ensureImage(): Promise<void> {\n if (this.pull === \"always\") {\n await assertDockerCli([\"pull\", this.image], this.cliOptions());\n return;\n }\n\n if (this.pull === \"missing\") {\n const inspect = await runDockerCli([\"image\", \"inspect\", this.image], this.cliOptions());\n if (inspect.exitCode !== 0) {\n await assertDockerCli([\"pull\", this.image], this.cliOptions());\n }\n }\n }\n\n private createRunArgs(\n containerName: string,\n volumeName: string,\n workspace: SandboxWorkspaceOptions,\n metadata: Record<string, string> | undefined,\n ports: readonly number[],\n ): string[] {\n const args = [\n \"run\",\n \"-d\",\n \"--name\",\n containerName,\n \"-v\",\n `${volumeName}:${this.workdir}`,\n \"-w\",\n this.workdir,\n \"--label\",\n \"anvia.sandbox=true\",\n \"--label\",\n `anvia.sandbox.workspace.mode=${workspace.mode ?? \"ephemeral\"}`,\n \"--label\",\n `anvia.sandbox.workspace.volume=${volumeName}`,\n ];\n\n for (const [key, value] of Object.entries(this.labels)) {\n args.push(\"--label\", `${key}=${value}`);\n }\n\n if (metadata !== undefined) {\n for (const [key, value] of Object.entries(metadata)) {\n args.push(\"--label\", `anvia.sandbox.metadata.${key}=${value}`);\n }\n }\n\n this.appendNetworkArgs(args);\n for (const port of ports) {\n args.push(\"--publish\", `127.0.0.1::${port}/tcp`);\n }\n this.appendLimitArgs(args);\n this.appendSecurityArgs(args);\n\n if (this.user !== undefined) {\n args.push(\"-u\", this.user);\n }\n\n args.push(\n this.image,\n \"sh\",\n \"-c\",\n \"trap 'exit 0' TERM INT; while :; do sleep 3600 & wait $!; done\",\n );\n return args;\n }\n\n private appendNetworkArgs(args: string[]): void {\n const mode = typeof this.network === \"object\" ? this.network.mode : this.network;\n\n if (mode === false || mode === \"none\") {\n args.push(\"--network\", \"none\");\n return;\n }\n\n if (mode !== true) {\n args.push(\"--network\", mode);\n }\n }\n\n private assertPortNetworkCompatible(ports: readonly number[]): void {\n if (ports.length === 0) return;\n const mode = typeof this.network === \"object\" ? this.network.mode : this.network;\n if (\n mode === false ||\n mode === \"none\" ||\n mode === \"host\" ||\n (typeof mode === \"string\" && mode.startsWith(\"container:\"))\n ) {\n throw new SandboxPortError(\n \"Published sandbox ports require network: true or a bridge-capable Docker network.\",\n );\n }\n }\n\n private async inspectPublishedPorts(\n containerName: string,\n ports: readonly number[],\n ): Promise<SandboxPublishedPort[]> {\n if (ports.length === 0) return [];\n\n const raw = await assertDockerCli(\n [\"container\", \"inspect\", \"--format\", \"{{json .NetworkSettings.Ports}}\", containerName],\n this.cliOptions(),\n );\n let mappings: unknown;\n try {\n mappings = JSON.parse(raw);\n } catch (error) {\n throw new SandboxPortError(\"Docker returned invalid published port metadata.\", error);\n }\n if (!isRecord(mappings)) {\n throw new SandboxPortError(\"Docker returned invalid published port metadata.\");\n }\n\n return ports.map((containerPort) => {\n const entries = mappings[`${containerPort}/tcp`];\n if (!Array.isArray(entries)) {\n throw new SandboxPortError(`Docker did not publish sandbox port ${containerPort}/tcp.`);\n }\n const entry = entries.find(\n (candidate) =>\n isRecord(candidate) &&\n candidate.HostIp === \"127.0.0.1\" &&\n typeof candidate.HostPort === \"string\",\n );\n if (!isRecord(entry) || typeof entry.HostPort !== \"string\") {\n throw new SandboxPortError(\n `Docker did not bind sandbox port ${containerPort}/tcp to 127.0.0.1.`,\n );\n }\n const hostPort = Number(entry.HostPort);\n if (!isValidPort(hostPort)) {\n throw new SandboxPortError(\n `Docker returned an invalid host port for ${containerPort}/tcp.`,\n );\n }\n return { containerPort, host: \"127.0.0.1\", hostPort, protocol: \"tcp\" };\n });\n }\n\n private appendLimitArgs(args: string[]): void {\n if (this.limits.memoryMb !== undefined) {\n args.push(\"--memory\", `${this.limits.memoryMb}m`);\n }\n\n if (this.limits.cpus !== undefined) {\n args.push(\"--cpus\", String(this.limits.cpus));\n }\n\n if (this.limits.pidsLimit !== undefined) {\n args.push(\"--pids-limit\", String(this.limits.pidsLimit));\n }\n }\n\n private appendSecurityArgs(args: string[]): void {\n if (this.security.readonlyRootfs) {\n args.push(\"--read-only\");\n }\n\n if (this.security.noNewPrivileges) {\n args.push(\"--security-opt\", \"no-new-privileges\");\n }\n\n for (const capability of this.security.dropCapabilities) {\n args.push(\"--cap-drop\", capability);\n }\n }\n\n private cliOptions() {\n return {\n dockerPath: this.dockerPath,\n maxOutputBytes: this.limits.maxOutputBytes ?? defaultMaxOutputBytes,\n };\n }\n\n private async cleanup(containerName: string, volumeName: string | undefined): Promise<void> {\n await runDockerCli([\"rm\", \"-f\", containerName], this.cliOptions()).catch(() => undefined);\n\n if (volumeName !== undefined) {\n await runDockerCli([\"volume\", \"rm\", \"-f\", volumeName], this.cliOptions()).catch(\n () => undefined,\n );\n }\n }\n}\n\nclass DockerSandboxSessionImpl implements DockerSandboxSession {\n readonly provider = \"docker\";\n readonly id: string;\n readonly workdir: string;\n readonly publishedPorts: readonly SandboxPublishedPort[];\n\n private readonly containerName: string;\n private readonly volumeName: string;\n private readonly dockerPath: string;\n private readonly limits: SandboxLimits;\n private readonly lifecycle: Required<Pick<SandboxLifecycleOptions, \"autoDestroy\">> &\n Omit<SandboxLifecycleOptions, \"autoDestroy\">;\n private readonly removeVolumeOnDestroy: boolean;\n private readonly env: Record<string, string>;\n private readonly hooks: SandboxHooks;\n private readonly processManager: DockerProcessManager;\n private ttlTimer: ReturnType<typeof setTimeout> | undefined;\n private idleTimer: ReturnType<typeof setTimeout> | undefined;\n private activeOperations = 0;\n private destroyed = false;\n\n constructor(options: {\n id: string;\n containerName: string;\n volumeName: string;\n workdir: string;\n dockerPath: string;\n limits: SandboxLimits;\n lifecycle: Required<Pick<SandboxLifecycleOptions, \"autoDestroy\">> &\n Omit<SandboxLifecycleOptions, \"autoDestroy\">;\n removeVolumeOnDestroy: boolean;\n env: Record<string, string>;\n hooks: SandboxHooks;\n publishedPorts: SandboxPublishedPort[];\n }) {\n this.id = options.id;\n this.containerName = options.containerName;\n this.volumeName = options.volumeName;\n this.workdir = options.workdir;\n this.dockerPath = options.dockerPath;\n this.limits = options.limits;\n this.lifecycle = options.lifecycle;\n this.removeVolumeOnDestroy = options.removeVolumeOnDestroy;\n this.env = options.env;\n this.hooks = options.hooks;\n this.publishedPorts = options.publishedPorts;\n this.processManager = new DockerProcessManager({\n containerName: this.containerName,\n dockerPath: this.dockerPath,\n workdir: this.workdir,\n env: this.env,\n maxOutputBytes: this.limits.maxOutputBytes ?? defaultMaxOutputBytes,\n maxProcesses: this.limits.maxProcesses ?? defaultMaxProcesses,\n startupTimeoutMs: this.limits.timeoutMs ?? defaultTimeoutMs,\n onStart: async (process) => {\n const event: SandboxExecEvent = {\n ...this.event(),\n command: process.command,\n args: process.args,\n };\n if (process.cwd !== undefined) event.cwd = process.cwd;\n await this.hooks.onExecStart?.(event);\n },\n onExit: async (process, logs, durationMs) => {\n const event: SandboxExecEndEvent = {\n ...this.event(),\n command: process.command,\n args: process.args,\n result: {\n stdout: logs.stdout,\n stderr: logs.stderr,\n exitCode: process.exitCode ?? 1,\n durationMs,\n timedOut: false,\n aborted: process.status === \"stopped\",\n stdoutTruncated: logs.stdoutTruncated,\n stderrTruncated: logs.stderrTruncated,\n },\n };\n if (process.cwd !== undefined) event.cwd = process.cwd;\n await this.hooks.onExecEnd?.(event);\n },\n });\n this.startLifecycleTimers();\n }\n\n async applyManifest(manifest: SandboxManifest | undefined): Promise<void> {\n await this.runOperation(async () => {\n for (const directory of manifest?.directories ?? []) {\n await this.mkdir(directory);\n }\n\n for (const [filePath, content] of Object.entries(manifest?.files ?? {})) {\n await this.writeFile(filePath, content);\n }\n });\n }\n\n async exec(options: SandboxExecOptions): Promise<SandboxExecResult> {\n return this.runOperation(async () => {\n const startEvent: SandboxExecEvent = {\n ...this.event(),\n command: options.command,\n args: options.args ?? [],\n };\n if (options.cwd !== undefined) startEvent.cwd = options.cwd;\n await this.hooks.onExecStart?.(startEvent);\n\n const normalizedResult = await this.execCommand(options);\n\n const endEvent: SandboxExecEndEvent = {\n ...this.event(),\n command: options.command,\n args: options.args ?? [],\n result: normalizedResult,\n };\n if (options.cwd !== undefined) endEvent.cwd = options.cwd;\n await this.hooks.onExecEnd?.(endEvent);\n\n return normalizedResult;\n });\n }\n\n async *execStream(options: SandboxExecOptions): AsyncIterable<SandboxExecStreamEvent> {\n const events: SandboxExecStreamEvent[] = [];\n let notify: (() => void) | undefined;\n let done = false;\n let error: unknown;\n\n const push = (event: SandboxExecStreamEvent) => {\n events.push(event);\n notify?.();\n notify = undefined;\n };\n\n const wait = () =>\n new Promise<void>((resolve) => {\n notify = resolve;\n });\n\n const run = this.exec({\n ...options,\n onStdout: (chunk) => {\n options.onStdout?.(chunk);\n push({ type: \"stdout\", chunk, text: Buffer.from(chunk).toString(\"utf8\") });\n },\n onStderr: (chunk) => {\n options.onStderr?.(chunk);\n push({ type: \"stderr\", chunk, text: Buffer.from(chunk).toString(\"utf8\") });\n },\n })\n .then((result) => {\n push({ type: \"exit\", result });\n })\n .catch((caught) => {\n error = caught;\n })\n .finally(() => {\n done = true;\n notify?.();\n notify = undefined;\n });\n\n try {\n while (!done || events.length > 0) {\n const event = events.shift();\n if (event !== undefined) {\n yield event;\n continue;\n }\n\n await wait();\n }\n\n if (error !== undefined) {\n throw error;\n }\n } finally {\n await run;\n }\n }\n\n async startProcess(options: SandboxProcessStartOptions): Promise<SandboxProcessInfo> {\n return this.runOperation(async () => this.processManager.start(options));\n }\n\n async listProcesses(): Promise<SandboxProcessInfo[]> {\n return this.runOperation(async () => this.processManager.list());\n }\n\n async readProcessLogs(\n processId: string,\n options?: SandboxProcessLogsOptions,\n ): Promise<SandboxProcessLogs> {\n return this.runOperation(async () => this.processManager.logs(processId, options));\n }\n\n async stopProcess(\n processId: string,\n options?: SandboxProcessStopOptions,\n ): Promise<SandboxProcessInfo> {\n return this.runOperation(async () => this.processManager.stop(processId, options));\n }\n\n async waitForPort(\n containerPort: number,\n options: SandboxWaitForPortOptions = {},\n ): Promise<SandboxPublishedPort> {\n return this.runOperation(async () => {\n const publishedPort = this.publishedPorts.find(\n (candidate) => candidate.containerPort === containerPort,\n );\n if (publishedPort === undefined) {\n throw new SandboxPortError(`Sandbox port is not published: ${containerPort}/tcp`);\n }\n\n const timeoutMs = options.timeoutMs ?? this.limits.timeoutMs ?? defaultTimeoutMs;\n const intervalMs = options.intervalMs ?? 250;\n assertWaitOptions(timeoutMs, intervalMs);\n const deadline = Date.now() + timeoutMs;\n\n while (true) {\n this.assertActive();\n if (options.signal?.aborted === true) throw abortReason(options.signal);\n const remainingMs = deadline - Date.now();\n if (remainingMs <= 0) {\n throw new SandboxTimeoutError(`Waiting for sandbox port ${containerPort}/tcp timed out.`);\n }\n const probeTimeoutMs = Math.min(1_000, remainingMs);\n if (await this.isPortListening(containerPort, probeTimeoutMs)) {\n return publishedPort;\n }\n const remainingAfterProbeMs = deadline - Date.now();\n if (remainingAfterProbeMs <= 0) {\n throw new SandboxTimeoutError(`Waiting for sandbox port ${containerPort}/tcp timed out.`);\n }\n await waitWithSignal(Math.min(intervalMs, remainingAfterProbeMs), options.signal);\n }\n });\n }\n\n async readFile(filePath: string): Promise<Uint8Array> {\n return this.runOperation(async () => {\n const normalized = normalizeSandboxPath(filePath);\n const tempDir = await mkdtemp(path.join(os.tmpdir(), \"anvia-sandbox-read-\"));\n const target = path.join(tempDir, path.basename(normalized));\n\n try {\n await assertDockerCli(\n [\"cp\", `${this.containerName}:${containerPath(this.workdir, normalized)}`, target],\n this.cliOptions(),\n );\n const { readFile } = await import(\"node:fs/promises\");\n const bytes = await readFile(target);\n this.assertFileSize(bytes.byteLength, filePath);\n return bytes;\n } finally {\n await rm(tempDir, { recursive: true, force: true });\n }\n });\n }\n\n async readTextFile(filePath: string): Promise<string> {\n const bytes = await this.readFile(filePath);\n return new TextDecoder().decode(bytes);\n }\n\n async readTextFilePage(\n filePath: string,\n options: SandboxTextFileReadOptions = {},\n ): Promise<SandboxTextFileReadResult> {\n return this.runOperation(async () => {\n const startLine = options.startLine ?? 1;\n const lineCount = options.lineCount ?? defaultTextFilePageLines;\n const maxBytes = options.maxBytes ?? defaultTextFilePageBytes;\n assertTextFileReadOptions(startLine, lineCount, maxBytes);\n\n const normalized = normalizeSandboxPath(filePath);\n const captureBytes = maxBytes + 4;\n const result = await runDockerCli(\n [\n \"exec\",\n \"-w\",\n this.workdir,\n this.containerName,\n \"sh\",\n \"-c\",\n textFilePageScript,\n \"anvia-read-file-page\",\n String(startLine),\n String(lineCount),\n String(captureBytes),\n containerPath(this.workdir, normalized),\n ],\n {\n ...this.cliOptions(),\n maxOutputBytes: captureBytes,\n },\n );\n\n if (result.exitCode !== 0) {\n throw new SandboxDockerCommandError(\n `Unable to read sandbox text file: ${filePath}`,\n result,\n );\n }\n\n return createTextFilePage(result.stdout, {\n startLine,\n lineCount,\n maxBytes,\n contentStartLine: startLine,\n });\n });\n }\n\n async writeFile(filePath: string, data: string | Uint8Array): Promise<void> {\n await this.runOperation(async () => {\n const size = byteLength(data);\n this.assertFileSize(size, filePath);\n const normalized = normalizeSandboxPath(filePath);\n await this.mkdir(parentSandboxPath(normalized));\n\n const tempDir = await mkdtemp(path.join(os.tmpdir(), \"anvia-sandbox-write-\"));\n const source = path.join(tempDir, path.basename(normalized));\n\n try {\n await writeFile(source, data);\n await assertDockerCli(\n [\"cp\", source, `${this.containerName}:${containerPath(this.workdir, normalized)}`],\n this.cliOptions(),\n );\n await this.hooks.onFileWrite?.({ ...this.event(), path: normalized, size });\n } finally {\n await rm(tempDir, { recursive: true, force: true });\n }\n });\n }\n\n async writeTextFile(filePath: string, content: string): Promise<void> {\n await this.writeFile(filePath, content);\n }\n\n async listFiles(filePath = \".\"): Promise<SandboxFileEntry[]> {\n return this.runOperation(async () => {\n const normalized = normalizeSandboxPath(filePath, { allowRoot: true });\n const target = containerPath(this.workdir, normalized);\n const result = await this.execCommand({\n command: \"find\",\n args: [target, \"-mindepth\", \"1\", \"-maxdepth\", \"1\", \"-printf\", \"%p\\t%y\\t%s\\n\"],\n });\n\n if (result.timedOut) {\n throw new SandboxTimeoutError(`Listing files timed out for ${filePath}.`);\n }\n\n if (result.exitCode !== 0) {\n throw new SandboxDockerCommandError(`Unable to list sandbox path: ${filePath}`, result);\n }\n\n return result.stdout\n .split(\"\\n\")\n .filter((line) => line.trim().length > 0)\n .map((line) => this.parseFindEntry(line));\n });\n }\n\n async destroy(): Promise<void> {\n if (this.destroyed) {\n return;\n }\n\n this.destroyed = true;\n this.clearLifecycleTimers();\n await this.processManager.dispose();\n await runDockerCli([\"rm\", \"-f\", this.containerName], this.cliOptions()).catch(() => undefined);\n\n if (this.removeVolumeOnDestroy) {\n await runDockerCli([\"volume\", \"rm\", \"-f\", this.volumeName], this.cliOptions()).catch(\n () => undefined,\n );\n }\n\n await this.hooks.onDestroy?.(this.event());\n }\n\n private async mkdir(directoryPath: string): Promise<void> {\n const normalized = normalizeSandboxPath(directoryPath, { allowRoot: true });\n const result = await this.execCommand({\n command: \"mkdir\",\n args: [\"-p\", containerPath(this.workdir, normalized)],\n });\n\n if (result.exitCode !== 0) {\n throw new SandboxDockerCommandError(\n `Unable to create sandbox directory: ${directoryPath}`,\n result,\n );\n }\n }\n\n private parseFindEntry(line: string): SandboxFileEntry {\n const [rawPath, rawType, rawSize] = line.split(\"\\t\");\n const absolutePath = rawPath ?? \"\";\n const relativePath = absolutePath.startsWith(`${this.workdir}/`)\n ? absolutePath.slice(this.workdir.length + 1)\n : absolutePath;\n const size = rawSize === undefined ? undefined : Number(rawSize);\n const entry: SandboxFileEntry = {\n path: relativePath,\n type: mapFindType(rawType),\n };\n\n if (size !== undefined && Number.isFinite(size)) {\n entry.size = size;\n }\n\n return entry;\n }\n\n private cliOptions() {\n return {\n dockerPath: this.dockerPath,\n maxOutputBytes: this.limits.maxOutputBytes ?? defaultMaxOutputBytes,\n };\n }\n\n private async isPortListening(containerPort: number, timeoutMs: number): Promise<boolean> {\n const result = await runDockerCli(\n [\n \"exec\",\n this.containerName,\n \"sh\",\n \"-c\",\n portProbeScript,\n \"anvia-port-probe\",\n String(containerPort),\n ],\n {\n ...this.cliOptions(),\n timeoutMs: Math.max(1, timeoutMs),\n },\n );\n return result.exitCode === 0;\n }\n\n private async execCommand(options: SandboxExecOptions): Promise<SandboxExecResult> {\n if (options.command.trim().length === 0) {\n throw new SandboxDockerCommandError(\"Sandbox command cannot be empty.\", {\n stdout: \"\",\n stderr: \"\",\n exitCode: 1,\n });\n }\n\n const args = [\"exec\"];\n\n if (options.input !== undefined) {\n args.push(\"-i\");\n }\n\n const cwd = containerPath(this.workdir, options.cwd ?? \".\");\n args.push(\"-w\", cwd);\n\n for (const [key, value] of Object.entries({ ...this.env, ...options.env })) {\n args.push(\"-e\", `${key}=${value}`);\n }\n\n args.push(this.containerName, options.command, ...(options.args ?? []));\n\n const cliOptions: DockerCliOptions = {\n dockerPath: this.dockerPath,\n timeoutMs: options.timeoutMs ?? this.limits.timeoutMs ?? defaultTimeoutMs,\n maxOutputBytes: this.limits.maxOutputBytes ?? defaultMaxOutputBytes,\n };\n if (options.input !== undefined) cliOptions.input = options.input;\n if (options.signal !== undefined) cliOptions.signal = options.signal;\n if (options.onStdout !== undefined) cliOptions.onStdout = options.onStdout;\n if (options.onStderr !== undefined) cliOptions.onStderr = options.onStderr;\n\n const result = await runDockerCli(args, cliOptions);\n\n if (result.timedOut) {\n return {\n ...result,\n exitCode: result.exitCode === 0 ? 124 : result.exitCode,\n };\n }\n\n return result;\n }\n\n private assertActive(): void {\n if (this.destroyed) {\n throw new SandboxSessionDestroyedError(`Sandbox session ${this.id} has been destroyed.`);\n }\n }\n\n event(): SandboxSessionEvent {\n return {\n sessionId: this.id,\n provider: this.provider,\n workdir: this.workdir,\n };\n }\n\n private async runOperation<T>(operation: () => Promise<T>): Promise<T> {\n this.assertActive();\n this.activeOperations += 1;\n this.clearIdleTimer();\n\n try {\n return await operation();\n } finally {\n this.activeOperations -= 1;\n this.scheduleIdleTimer();\n }\n }\n\n private assertFileSize(size: number, filePath: string): void {\n if (this.limits.maxFileBytes !== undefined && size > this.limits.maxFileBytes) {\n throw new SandboxFileSizeError(\n `Sandbox file exceeds maxFileBytes (${size} > ${this.limits.maxFileBytes}): ${filePath}`,\n );\n }\n }\n\n private startLifecycleTimers(): void {\n if (!this.lifecycle.autoDestroy) {\n return;\n }\n\n if (this.lifecycle.ttlMs !== undefined) {\n this.ttlTimer = setTimeout(() => {\n void this.destroy().catch(() => undefined);\n }, this.lifecycle.ttlMs);\n this.ttlTimer.unref?.();\n }\n\n this.scheduleIdleTimer();\n }\n\n private scheduleIdleTimer(): void {\n if (!this.lifecycle.autoDestroy || this.lifecycle.idleTimeoutMs === undefined) {\n return;\n }\n\n if (this.destroyed || this.activeOperations > 0) {\n return;\n }\n\n this.clearIdleTimer();\n this.idleTimer = setTimeout(() => {\n void this.destroy().catch(() => undefined);\n }, this.lifecycle.idleTimeoutMs);\n this.idleTimer.unref?.();\n }\n\n private clearLifecycleTimers(): void {\n if (this.ttlTimer !== undefined) {\n clearTimeout(this.ttlTimer);\n this.ttlTimer = undefined;\n }\n this.clearIdleTimer();\n }\n\n private clearIdleTimer(): void {\n if (this.idleTimer !== undefined) {\n clearTimeout(this.idleTimer);\n this.idleTimer = undefined;\n }\n }\n}\n\nfunction getWorkspaceId(workspace: SandboxWorkspaceOptions, sessionId: string): string {\n if (workspace.mode === \"persistent\") {\n return sanitizeResourceId(workspace.id);\n }\n\n return sessionId;\n}\n\nfunction shouldDestroyWorkspace(workspace: SandboxWorkspaceOptions): boolean {\n if (workspace.mode === \"persistent\") {\n return workspace.destroyOnSessionDestroy ?? false;\n }\n\n return true;\n}\n\nfunction sanitizeResourceId(id: string): string {\n const sanitized = id\n .toLowerCase()\n .replaceAll(/[^a-z0-9_.-]/g, \"-\")\n .replaceAll(/^-+|-+$/g, \"\");\n return sanitized.length > 0 ? sanitized : randomUUID();\n}\n\nfunction byteLength(data: string | Uint8Array): number {\n return typeof data === \"string\" ? Buffer.byteLength(data) : data.byteLength;\n}\n\nfunction mapFindType(type: string | undefined): SandboxFileType {\n if (type === \"f\") {\n return \"file\";\n }\n if (type === \"d\") {\n return \"directory\";\n }\n if (type === \"l\") {\n return \"symlink\";\n }\n return \"other\";\n}\n\nfunction validatePublishedPorts(ports: readonly number[]): number[] {\n const unique = new Set<number>();\n for (const port of ports) {\n if (!isValidPort(port)) {\n throw new SandboxPortError(`Sandbox port must be an integer from 1 to 65535: ${port}`);\n }\n if (unique.has(port)) {\n throw new SandboxPortError(`Sandbox port is duplicated: ${port}`);\n }\n unique.add(port);\n }\n return [...unique];\n}\n\nfunction isValidPort(port: number): boolean {\n return Number.isInteger(port) && port >= 1 && port <= 65_535;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction assertWaitOptions(timeoutMs: number, intervalMs: number): void {\n if (!Number.isInteger(timeoutMs) || timeoutMs <= 0) {\n throw new SandboxPortError(\"Port wait timeoutMs must be a positive integer.\");\n }\n if (!Number.isInteger(intervalMs) || intervalMs <= 0) {\n throw new SandboxPortError(\"Port wait intervalMs must be a positive integer.\");\n }\n}\n\nfunction assertTextFileReadOptions(startLine: number, lineCount: number, maxBytes: number): void {\n if (!Number.isInteger(startLine) || startLine <= 0) {\n throw new RangeError(\"Text file startLine must be a positive integer.\");\n }\n if (!Number.isInteger(lineCount) || lineCount <= 0) {\n throw new RangeError(\"Text file lineCount must be a positive integer.\");\n }\n if (!Number.isInteger(maxBytes) || maxBytes <= 0) {\n throw new RangeError(\"Text file maxBytes must be a positive integer.\");\n }\n}\n\nasync function waitWithSignal(timeoutMs: number, signal: AbortSignal | undefined): Promise<void> {\n if (signal?.aborted === true) throw abortReason(signal);\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n signal?.removeEventListener(\"abort\", abort);\n resolve();\n }, timeoutMs);\n const abort = () => {\n clearTimeout(timeout);\n reject(abortReason(signal));\n };\n signal?.addEventListener(\"abort\", abort, { once: true });\n });\n}\n\nfunction abortReason(signal: AbortSignal | undefined): unknown {\n return signal?.reason ?? new SandboxPortError(\"Waiting for sandbox port was aborted.\");\n}\n","import { type ChildProcessWithoutNullStreams, spawn } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport { runDockerCli } from \"./docker-cli\";\nimport {\n SandboxDockerCommandError,\n SandboxDockerUnavailableError,\n SandboxProcessError,\n SandboxTimeoutError,\n} from \"./errors\";\nimport { containerPath } from \"./path\";\nimport type {\n SandboxProcessInfo,\n SandboxProcessLogs,\n SandboxProcessLogsOptions,\n SandboxProcessStartOptions,\n SandboxProcessStopOptions,\n} from \"./types\";\n\nconst processMarkerPrefix = \"ANVIA_PROCESS\";\n// Report the supervisor, direct-child, and process-group PIDs through a private stdout marker. Use\n// a dedicated session when setsid is available; Docker exec otherwise gives the supervisor its own\n// process group. User-provided command arguments remain positional rather than shell-interpolated.\nconst processWrapper = [\n 'marker=\"$1\"',\n \"shift\",\n \"if command -v setsid >/dev/null 2>&1; then\",\n ' setsid \"$@\" &',\n \" child=$!\",\n \" group=$child\",\n \"else\",\n ' \"$@\" &',\n \" child=$!\",\n \" group=$$\",\n \"fi\",\n `printf '\\\\036%s:%s:%s:%s\\\\036' \"$marker\" \"$$\" \"$child\" \"$group\"`,\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 onStart?: (process: SandboxProcessInfo) => void | Promise<void>;\n onExit?: (\n process: SandboxProcessInfo,\n logs: SandboxProcessLogs,\n durationMs: number,\n ) => void | Promise<void>;\n}\n\ninterface ManagedProcessRecord {\n info: SandboxProcessInfo;\n startedAtMs: number;\n child: ChildProcessWithoutNullStreams;\n stdout: TailOutputCollector;\n stderr: TailOutputCollector;\n markerStart: Buffer;\n markerBuffer: Buffer;\n supervisorPid?: number;\n childPid?: number;\n processGroupId?: number;\n spawnFailed: boolean;\n stopRequested: boolean;\n startResolved: boolean;\n exitNotified: 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 new SandboxProcessError(\"Sandbox maxProcesses must be a non-negative integer.\");\n }\n if (!Number.isInteger(options.maxOutputBytes) || options.maxOutputBytes < 0) {\n throw new SandboxProcessError(\"Sandbox maxOutputBytes must be a non-negative integer.\");\n }\n if (!Number.isInteger(options.startupTimeoutMs) || options.startupTimeoutMs <= 0) {\n throw new SandboxProcessError(\"Sandbox process startup timeout must be a positive integer.\");\n }\n }\n\n async start(options: SandboxProcessStartOptions): Promise<SandboxProcessInfo> {\n this.assertActive();\n assertStartOptions(options);\n await this.pruneCompletedRecords();\n\n const trackedCount = this.records.size;\n if (trackedCount >= this.options.maxProcesses) {\n throw new SandboxProcessError(\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 child.stdin.end();\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: SandboxProcessInfo = {\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 startedAtMs: Date.now(),\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 exitNotified: 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);\n await this.options.onStart?.(copyProcessInfo(record.info));\n record.startResolved = true;\n if (record.info.status !== \"running\") this.notifyExit(record);\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(): SandboxProcessInfo[] {\n this.assertActive();\n return [...this.records.values()].map((record) => copyProcessInfo(record.info));\n }\n\n logs(processId: string, options: SandboxProcessLogsOptions = {}): SandboxProcessLogs {\n this.assertActive();\n const record = this.getRecord(processId);\n const stdout = record.stdout.snapshot(options.tailBytes);\n const stderr = record.stderr.snapshot(options.tailBytes);\n return {\n stdout: stdout.text,\n stderr: stderr.text,\n stdoutTruncated: stdout.truncated,\n stderrTruncated: stderr.truncated,\n };\n }\n\n async stop(\n processId: string,\n options: SandboxProcessStopOptions = {},\n ): Promise<SandboxProcessInfo> {\n this.assertActive();\n const record = this.getRecord(processId);\n const gracePeriodMs = options.gracePeriodMs ?? 5_000;\n if (!Number.isInteger(gracePeriodMs) || gracePeriodMs < 0) {\n throw new SandboxProcessError(\"Process gracePeriodMs must be a non-negative integer.\");\n }\n\n try {\n if (!(await this.terminateRecord(record, gracePeriodMs))) {\n throw new SandboxProcessError(`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(): Promise<void> {\n if (this.disposed) return;\n this.disposed = true;\n\n await Promise.all(\n [...this.records.values()].map(async (record) => {\n await this.terminateRecord(record, 1_000).catch(() => false);\n }),\n );\n }\n\n private createExecArgs(options: SandboxProcessStartOptions, marker: string): string[] {\n const args = [\"exec\", \"-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 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 SandboxDockerUnavailableError(\"Docker CLI was not found.\", error)\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 new SandboxProcessError(\n `Sandbox process exited before startup completed: ${record.info.id}`,\n ),\n );\n record.resolveClosed();\n\n if (record.startResolved) this.notifyExit(record);\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 = record.markerBuffer\n .subarray(start + record.markerStart.length, end)\n .toString(\"utf8\")\n .split(\":\");\n const supervisorPid = Number(rawPids[0]);\n const childPid = Number(rawPids[1]);\n const processGroupId = Number(rawPids[2]);\n if (!isProcessId(supervisorPid) || !isProcessId(childPid) || !isProcessId(processGroupId)) {\n record.rejectStarted(\n new SandboxProcessError(\"Sandbox process returned invalid process IDs.\"),\n );\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.childPid = childPid;\n record.processGroupId = processGroupId;\n record.resolveStarted();\n }\n\n private async waitForStart(record: ManagedProcessRecord) {\n let timeout: ReturnType<typeof setTimeout> | undefined;\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeout = setTimeout(() => {\n reject(new SandboxTimeoutError(\"Starting sandbox process timed out.\"));\n }, this.options.startupTimeoutMs);\n timeout.unref?.();\n });\n\n try {\n await Promise.race([record.started, timeoutPromise]);\n } finally {\n if (timeout !== undefined) clearTimeout(timeout);\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 await waitForPromise(record.closed, 250);\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 ): Promise<boolean> {\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));\n }\n if (record.processGroupId === undefined) {\n return record.spawnFailed && record.info.status !== \"running\";\n }\n }\n\n if (!(await this.isProcessGroupRunning(record))) {\n return this.finishAfterGroupExit(record);\n }\n\n await this.signal(record, \"TERM\");\n if (await this.waitForRecordExit(record, gracePeriodMs)) return true;\n\n await this.signal(record, \"KILL\");\n if (await this.waitForRecordExit(record, 1_000)) return true;\n\n return false;\n }\n\n private async waitForRecordExit(\n record: ManagedProcessRecord,\n timeoutMs: number,\n ): Promise<boolean> {\n const deadline = Date.now() + timeoutMs;\n while (true) {\n if (!(await this.isProcessGroupRunning(record))) {\n return this.finishAfterGroupExit(record);\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);\n } else {\n await waitForDelay(intervalMs);\n }\n }\n }\n\n private async finishAfterGroupExit(record: ManagedProcessRecord): Promise<boolean> {\n if (record.info.status !== \"running\") return true;\n record.child.kill(\"SIGKILL\");\n return waitForPromise(record.closed, 1_000);\n }\n\n private async isProcessGroupRunning(record: ManagedProcessRecord): 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 String(record.processGroupId),\n ],\n {\n dockerPath: this.options.dockerPath,\n timeoutMs: 5_000,\n maxOutputBytes: this.options.maxOutputBytes,\n },\n );\n return result.exitCode === 0;\n }\n\n private async signal(record: ManagedProcessRecord, signal: \"TERM\" | \"KILL\"): 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 String(record.processGroupId),\n signal,\n ],\n {\n dockerPath: this.options.dockerPath,\n timeoutMs: 5_000,\n maxOutputBytes: this.options.maxOutputBytes,\n },\n );\n if (result.exitCode !== 0) {\n throw new SandboxDockerCommandError(\n `Unable to stop sandbox process: ${record.info.id}`,\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 new SandboxProcessError(`Unknown sandbox process: ${processId}`);\n }\n return record;\n }\n\n private async pruneCompletedRecords(): 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));\n if (record.info.status !== \"running\" && cleanupConfirmed) {\n this.records.delete(id);\n }\n }\n }\n\n private logsUnsafe(record: ManagedProcessRecord): SandboxProcessLogs {\n const stdout = record.stdout.snapshot();\n const stderr = record.stderr.snapshot();\n return {\n stdout: stdout.text,\n stderr: stderr.text,\n stdoutTruncated: stdout.truncated,\n stderrTruncated: stderr.truncated,\n };\n }\n\n private notifyExit(record: ManagedProcessRecord): void {\n if (record.exitNotified) return;\n record.exitNotified = true;\n const durationMs = Date.now() - record.startedAtMs;\n const notify = async () =>\n this.options.onExit?.(copyProcessInfo(record.info), this.logsUnsafe(record), durationMs);\n void notify().catch(() => undefined);\n }\n\n private assertActive(): void {\n if (this.disposed) {\n throw new SandboxProcessError(\"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): { text: string; truncated: boolean } {\n if (tailBytes !== undefined && (!Number.isInteger(tailBytes) || tailBytes < 0)) {\n throw new SandboxProcessError(\"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 text: selected.toString(\"utf8\"),\n truncated: this.didTruncate || selected.length < bytes.length,\n };\n }\n}\n\nfunction assertStartOptions(options: SandboxProcessStartOptions): void {\n if (options.command.trim().length === 0) {\n throw new SandboxProcessError(\"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: SandboxProcessInfo): SandboxProcessInfo {\n const copy: SandboxProcessInfo = {\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.cwd = info.cwd;\n if (info.exitCode !== undefined) copy.exitCode = info.exitCode;\n if (info.endedAt !== undefined) copy.endedAt = info.endedAt;\n return copy;\n}\n\nasync function waitForPromise(promise: Promise<void>, timeoutMs: number): Promise<boolean> {\n let timeout: ReturnType<typeof setTimeout> | 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 ]);\n } finally {\n if (timeout !== undefined) clearTimeout(timeout);\n }\n}\n\nasync function waitForDelay(timeoutMs: number): Promise<void> {\n await new Promise<void>((resolve) => {\n const timeout = setTimeout(resolve, timeoutMs);\n timeout.unref?.();\n });\n}\n","import path from \"node:path\";\nimport { SandboxPathError } from \"./errors\";\n\nexport function normalizeSandboxPath(input: string, options: { allowRoot?: boolean } = {}): string {\n if (input.length === 0) {\n throw new SandboxPathError(\"Sandbox path cannot be empty.\");\n }\n\n if (input.includes(\"\\0\")) {\n throw new SandboxPathError(\"Sandbox path cannot contain null bytes.\");\n }\n\n const normalized = path.posix.normalize(input.replaceAll(\"\\\\\", \"/\"));\n\n if (path.posix.isAbsolute(normalized)) {\n throw new SandboxPathError(`Sandbox path must be relative: ${input}`);\n }\n\n if (normalized === \"..\" || normalized.startsWith(\"../\")) {\n throw new SandboxPathError(`Sandbox path cannot leave the workspace: ${input}`);\n }\n\n if (normalized === \".\" && options.allowRoot !== true) {\n throw new SandboxPathError(\n \"Sandbox path must refer to a file or directory inside the workspace.\",\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 { SandboxTextFileReadResult } 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): SandboxTextFileReadResult {\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 { isSandboxPortSession, isSandboxProcessSession } from \"./capabilities\";\nimport { SandboxToolPolicyError } from \"./errors\";\nimport { createTextFilePage } from \"./text-file\";\nimport type {\n SandboxExecOptions,\n SandboxExecResult,\n SandboxPortSession,\n SandboxProcessInfo,\n SandboxProcessSession,\n SandboxProcessStartOptions,\n SandboxSession,\n SandboxToolName,\n SandboxToolsOptions,\n} from \"./types\";\n\nconst execCommandInput = z.object({\n command: z.string().min(1).describe(\"Executable to run inside the sandbox workspace.\"),\n args: z.array(z.string()).optional().describe(\"Command arguments.\"),\n cwd: z.string().optional().describe(\"Relative working directory inside the sandbox.\"),\n env: z\n .record(z.string(), z.string())\n .optional()\n .describe(\"Environment variables for this command.\"),\n timeoutMs: z\n .number()\n .int()\n .positive()\n .max(300_000)\n .optional()\n .describe(\"Optional command timeout in milliseconds.\"),\n input: z.string().optional().describe(\"Optional stdin text to pass to the command.\"),\n});\n\nconst readFileInput = z.object({\n path: z.string().min(1).describe(\"Relative file path inside the sandbox.\"),\n startLine: z\n .number()\n .int()\n .positive()\n .optional()\n .describe(\"One-based first line to read. Defaults to 1.\"),\n lineCount: z\n .number()\n .int()\n .positive()\n .max(10_000)\n .optional()\n .describe(\"Maximum lines to return. Defaults to 500.\"),\n});\n\nconst writeFileInput = z.object({\n path: z.string().min(1).describe(\"Relative file path inside the sandbox.\"),\n content: z.string().describe(\"Complete text content to write.\"),\n});\n\nconst listFilesInput = z.object({\n path: z\n .string()\n .optional()\n .describe(\"Relative directory path inside the sandbox. Defaults to root.\"),\n});\n\nconst emptyInput = z.object({});\n\nconst startProcessInput = z.object({\n command: z.string().min(1).describe(\"Executable to run as a managed sandbox process.\"),\n args: z.array(z.string()).optional().describe(\"Command arguments.\"),\n cwd: z.string().optional().describe(\"Relative working directory inside the sandbox.\"),\n env: z\n .record(z.string(), z.string())\n .optional()\n .describe(\"Environment variables for this process.\"),\n});\n\nconst processIdInput = z.object({\n processId: z.string().min(1).describe(\"Managed process identifier.\"),\n});\n\nconst readProcessLogsInput = processIdInput.extend({\n tailBytes: z\n .number()\n .int()\n .nonnegative()\n .max(1024 * 1024)\n .optional()\n .describe(\"Maximum trailing bytes to return from each output stream.\"),\n});\n\nconst waitForPortInput = z.object({\n containerPort: z\n .number()\n .int()\n .min(1)\n .max(65_535)\n .describe(\"Pre-authorized TCP port inside the sandbox container.\"),\n timeoutMs: z\n .number()\n .int()\n .positive()\n .max(300_000)\n .optional()\n .describe(\"Maximum time to wait for the port to accept connections.\"),\n});\n\nconst textOutput = z.string();\nconst maxToolLogBytes = 1024 * 1024;\nconst defaultReadFileLineCount = 500;\nconst defaultReadFileMaxLineCount = 2_000;\nconst defaultReadFileMaxBytes = 64 * 1024;\nconst maxToolReadFileBytes = 1024 * 1024;\nconst maxToolReadFileLines = 10_000;\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});\nconst sandboxToolMetadataKey = Symbol.for(\"anvia.sandbox.tool.metadata\");\n\nexport function createSandboxTools(\n session: SandboxSession,\n options: SandboxToolsOptions = {},\n): AnyTool[] {\n const include = new Set<SandboxToolName>(\n options.allow ?? options.include ?? [\"exec_command\", \"read_file\", \"write_file\", \"list_files\"],\n );\n const tools: AnyTool[] = [];\n\n if (include.has(\"exec_command\")) {\n tools.push(createExecCommandTool(session, options));\n }\n\n if (include.has(\"read_file\")) {\n tools.push(createReadFileTool(session, options));\n }\n\n if (include.has(\"write_file\")) {\n tools.push(createWriteFileTool(session, options));\n }\n\n if (include.has(\"list_files\")) {\n tools.push(createListFilesTool(session));\n }\n\n const portToolsRequested = include.has(\"list_ports\") || include.has(\"wait_for_port\");\n const portSession = portToolsRequested ? requirePortSession(session) : undefined;\n if (include.has(\"list_ports\") && portSession !== undefined) {\n tools.push(createListPortsTool(portSession));\n }\n\n const processToolsRequested =\n include.has(\"start_process\") ||\n include.has(\"list_processes\") ||\n include.has(\"read_process_logs\") ||\n include.has(\"stop_process\");\n if (include.has(\"wait_for_port\") || processToolsRequested) assertProcessToolPolicy(options);\n const processSession = processToolsRequested ? requireProcessSession(session) : undefined;\n if (include.has(\"start_process\") && processSession !== undefined) {\n tools.push(createStartProcessTool(processSession, options));\n }\n\n if (include.has(\"list_processes\") && processSession !== undefined) {\n tools.push(createListProcessesTool(processSession));\n }\n\n if (include.has(\"read_process_logs\") && processSession !== undefined) {\n tools.push(createReadProcessLogsTool(processSession, options));\n }\n\n if (include.has(\"stop_process\") && processSession !== undefined) {\n tools.push(createStopProcessTool(processSession, options));\n }\n\n if (include.has(\"wait_for_port\") && portSession !== undefined) {\n tools.push(createWaitForPortTool(portSession, options));\n }\n\n for (const tool of tools) {\n Object.defineProperty(tool, sandboxToolMetadataKey, {\n value: { session },\n enumerable: false,\n });\n }\n\n return tools;\n}\n\nfunction createExecCommandTool(session: SandboxSession, options: SandboxToolsOptions): AnyTool {\n const policy = options.exec ?? {};\n\n return createTool({\n name: \"exec_command\",\n description:\n \"Run a command inside the sandbox workspace. Use structured args instead of shell quoting.\",\n inputSchema: execCommandInput,\n outputSchema: textOutput,\n execute: async ({ command, args, cwd, env, timeoutMs, input }) => {\n assertCommandAllowed(command, options);\n\n const execOptions: SandboxExecOptions = {\n command,\n };\n\n if (args !== undefined) {\n execOptions.args = args;\n }\n if (cwd !== undefined) {\n execOptions.cwd = cwd;\n }\n if (env !== undefined) {\n execOptions.env = env;\n }\n const effectiveTimeoutMs = timeoutMs ?? policy.defaultTimeoutMs ?? options.execTimeoutMs;\n if (effectiveTimeoutMs !== undefined) {\n assertTimeoutAllowed(effectiveTimeoutMs, options);\n execOptions.timeoutMs = effectiveTimeoutMs;\n }\n if (input !== undefined) {\n execOptions.input = input;\n }\n\n const result = await session.exec(execOptions);\n\n return formatExecResult(result);\n },\n });\n}\n\nfunction createReadFileTool(session: SandboxSession, options: SandboxToolsOptions): AnyTool {\n return createTool({\n name: \"read_file\",\n description:\n \"Read a bounded page of a text file from the sandbox workspace. Continue with nextStartLine when provided.\",\n inputSchema: readFileInput,\n outputSchema: readFileOutput,\n execute: async ({ path, startLine, lineCount }) => {\n const limits = resolveReadFileLimits(options);\n const effectiveStartLine = startLine ?? 1;\n const effectiveLineCount = lineCount ?? limits.defaultLineCount;\n\n if (effectiveLineCount > limits.maxLineCount) {\n throw new SandboxToolPolicyError(\n `File read line count exceeds sandbox tool policy (${effectiveLineCount} > ${limits.maxLineCount}).`,\n );\n }\n\n if (session.readTextFilePage !== undefined) {\n return session.readTextFilePage(path, {\n startLine: effectiveStartLine,\n lineCount: effectiveLineCount,\n maxBytes: limits.maxBytes,\n });\n }\n\n return createTextFilePage(await session.readTextFile(path), {\n startLine: effectiveStartLine,\n lineCount: effectiveLineCount,\n maxBytes: limits.maxBytes,\n });\n },\n });\n}\n\nfunction createWriteFileTool(session: SandboxSession, options: SandboxToolsOptions): AnyTool {\n return createTool({\n name: \"write_file\",\n description: \"Write a text file inside the sandbox workspace. Creates parent directories.\",\n inputSchema: writeFileInput,\n outputSchema: textOutput,\n execute: async ({ path, content }) => {\n assertContentAllowed(content, options);\n await session.writeTextFile(path, content);\n return `Wrote ${path}`;\n },\n });\n}\n\nfunction createListFilesTool(session: SandboxSession): AnyTool {\n return createTool({\n name: \"list_files\",\n description: \"List files and directories inside the sandbox workspace.\",\n inputSchema: listFilesInput,\n outputSchema: textOutput,\n execute: async ({ path }) => {\n const entries = await session.listFiles(path);\n\n if (entries.length === 0) {\n return \"No files found.\";\n }\n\n return entries\n .map((entry) => {\n const size = entry.size === undefined ? \"\" : ` ${entry.size}b`;\n return `${entry.type}${size}\\t${entry.path}`;\n })\n .join(\"\\n\");\n },\n });\n}\n\nfunction createListPortsTool(session: SandboxPortSession): AnyTool {\n return createTool({\n name: \"list_ports\",\n description:\n \"List pre-authorized sandbox preview ports. Servers must bind to 0.0.0.0 on a listed container port.\",\n inputSchema: emptyInput,\n outputSchema: textOutput,\n execute: async () => {\n if (session.publishedPorts.length === 0) {\n return \"No sandbox ports are published.\";\n }\n return session.publishedPorts\n .map((port) => `${port.containerPort}/${port.protocol}\\t${port.host}:${port.hostPort}`)\n .join(\"\\n\");\n },\n });\n}\n\nfunction createStartProcessTool(\n session: SandboxProcessSession,\n options: SandboxToolsOptions,\n): AnyTool {\n return createTool({\n name: \"start_process\",\n description:\n \"Start a managed long-running process inside the sandbox. Use list_ports first and bind web servers to 0.0.0.0.\",\n inputSchema: startProcessInput,\n outputSchema: textOutput,\n execute: async ({ command, args, cwd, env }) => {\n assertCommandAllowed(command, options);\n const processOptions: SandboxProcessStartOptions = { command };\n if (args !== undefined) processOptions.args = args;\n if (cwd !== undefined) processOptions.cwd = cwd;\n if (env !== undefined) processOptions.env = env;\n return formatProcessInfo(await session.startProcess(processOptions));\n },\n });\n}\n\nfunction createListProcessesTool(session: SandboxProcessSession): AnyTool {\n return createTool({\n name: \"list_processes\",\n description: \"List managed sandbox processes and their current status.\",\n inputSchema: emptyInput,\n outputSchema: textOutput,\n execute: async () => {\n const processes = await session.listProcesses();\n if (processes.length === 0) return \"No managed processes.\";\n return processes.map(formatProcessInfo).join(\"\\n\\n\");\n },\n });\n}\n\nfunction createReadProcessLogsTool(\n session: SandboxProcessSession,\n options: SandboxToolsOptions,\n): AnyTool {\n return createTool({\n name: \"read_process_logs\",\n description: \"Read recent stdout and stderr from a managed sandbox process.\",\n inputSchema: readProcessLogsInput,\n outputSchema: textOutput,\n execute: async ({ processId, tailBytes }) => {\n const configuredMaxLogBytes = options.process?.maxLogBytes ?? 64 * 1024;\n if (!Number.isInteger(configuredMaxLogBytes) || configuredMaxLogBytes < 0) {\n throw new SandboxToolPolicyError(\"Process maxLogBytes must be a non-negative integer.\");\n }\n const maxLogBytes = Math.min(configuredMaxLogBytes, maxToolLogBytes);\n const effectiveTailBytes = tailBytes ?? maxLogBytes;\n if (effectiveTailBytes > maxLogBytes) {\n throw new SandboxToolPolicyError(\n `Process log request exceeds sandbox tool policy (${effectiveTailBytes} > ${maxLogBytes}).`,\n );\n }\n const logs = await session.readProcessLogs(processId, {\n tailBytes: effectiveTailBytes,\n });\n const parts: string[] = [];\n if (logs.stdout.length > 0) parts.push(`stdout:\\n${logs.stdout.trimEnd()}`);\n if (logs.stderr.length > 0) parts.push(`stderr:\\n${logs.stderr.trimEnd()}`);\n if (logs.stdoutTruncated || logs.stderrTruncated) parts.push(\"output_truncated: true\");\n return parts.length > 0 ? parts.join(\"\\n\\n\") : \"No process output.\";\n },\n });\n}\n\nfunction createStopProcessTool(\n session: SandboxProcessSession,\n options: SandboxToolsOptions,\n): AnyTool {\n return createTool({\n name: \"stop_process\",\n description: \"Stop a managed sandbox process.\",\n inputSchema: processIdInput,\n outputSchema: textOutput,\n execute: async ({ processId }) =>\n formatProcessInfo(\n await session.stopProcess(processId, {\n gracePeriodMs: options.process?.stopGracePeriodMs ?? 5_000,\n }),\n ),\n });\n}\n\nfunction createWaitForPortTool(session: SandboxPortSession, options: SandboxToolsOptions): AnyTool {\n return createTool({\n name: \"wait_for_port\",\n description: \"Wait until a pre-authorized sandbox TCP port is accepting connections.\",\n inputSchema: waitForPortInput,\n outputSchema: textOutput,\n execute: async ({ containerPort, timeoutMs }) => {\n const effectiveTimeoutMs = timeoutMs ?? options.process?.defaultWaitTimeoutMs ?? 30_000;\n const maxWaitTimeoutMs = options.process?.maxWaitTimeoutMs ?? 300_000;\n if (effectiveTimeoutMs > maxWaitTimeoutMs) {\n throw new SandboxToolPolicyError(\n `Port wait timeout exceeds sandbox tool policy (${effectiveTimeoutMs} > ${maxWaitTimeoutMs}).`,\n );\n }\n const port = await session.waitForPort(containerPort, {\n timeoutMs: effectiveTimeoutMs,\n });\n return `ready: ${port.containerPort}/${port.protocol} -> ${port.host}:${port.hostPort}`;\n },\n });\n}\n\nfunction formatExecResult(result: SandboxExecResult): string {\n const parts = [`exit_code: ${result.exitCode}`];\n\n if (result.timedOut) {\n parts.push(\"timed_out: true\");\n }\n\n if (result.aborted) {\n parts.push(\"aborted: true\");\n }\n\n if (result.stdout.length > 0) {\n parts.push(`stdout:\\n${result.stdout.trimEnd()}`);\n }\n\n if (result.stderr.length > 0) {\n parts.push(`stderr:\\n${result.stderr.trimEnd()}`);\n }\n\n if (result.stdoutTruncated || result.stderrTruncated) {\n parts.push(\"output_truncated: true\");\n }\n\n return parts.join(\"\\n\\n\");\n}\n\nfunction formatProcessInfo(process: SandboxProcessInfo): string {\n const parts = [\n `process_id: ${process.id}`,\n `status: ${process.status}`,\n `command: ${[process.command, ...process.args].join(\" \")}`,\n ];\n if (process.exitCode !== undefined) parts.push(`exit_code: ${process.exitCode}`);\n return parts.join(\"\\n\");\n}\n\nfunction requirePortSession(session: SandboxSession): SandboxPortSession {\n if (!isSandboxPortSession(session)) {\n throw new SandboxToolPolicyError(\"The sandbox session does not support published port tools.\");\n }\n return session;\n}\n\nfunction requireProcessSession(session: SandboxSession): SandboxProcessSession {\n if (!isSandboxProcessSession(session)) {\n throw new SandboxToolPolicyError(\"The sandbox session does not support managed process tools.\");\n }\n return session;\n}\n\nfunction assertProcessToolPolicy(options: SandboxToolsOptions): void {\n const policy = options.process;\n if (policy === undefined) return;\n if (\n policy.maxLogBytes !== undefined &&\n (!Number.isInteger(policy.maxLogBytes) ||\n policy.maxLogBytes < 0 ||\n policy.maxLogBytes > maxToolLogBytes)\n ) {\n throw new SandboxToolPolicyError(\n `Process maxLogBytes must be an integer from 0 to ${maxToolLogBytes}.`,\n );\n }\n const maxWaitTimeoutMs = policy.maxWaitTimeoutMs ?? 300_000;\n if (!Number.isInteger(maxWaitTimeoutMs) || maxWaitTimeoutMs <= 0 || maxWaitTimeoutMs > 300_000) {\n throw new SandboxToolPolicyError(\n \"Process maxWaitTimeoutMs must be an integer from 1 to 300000.\",\n );\n }\n if (\n policy.defaultWaitTimeoutMs !== undefined &&\n (!Number.isInteger(policy.defaultWaitTimeoutMs) ||\n policy.defaultWaitTimeoutMs <= 0 ||\n policy.defaultWaitTimeoutMs > maxWaitTimeoutMs)\n ) {\n throw new SandboxToolPolicyError(\n \"Process defaultWaitTimeoutMs must be positive and no greater than maxWaitTimeoutMs.\",\n );\n }\n if (\n policy.stopGracePeriodMs !== undefined &&\n (!Number.isInteger(policy.stopGracePeriodMs) || policy.stopGracePeriodMs < 0)\n ) {\n throw new SandboxToolPolicyError(\"Process stopGracePeriodMs must be a non-negative integer.\");\n }\n}\n\nfunction assertCommandAllowed(command: string, options: SandboxToolsOptions): void {\n const policy = options.exec;\n\n if (policy?.blockedCommands?.includes(command)) {\n throw new SandboxToolPolicyError(`Command is blocked by sandbox tool policy: ${command}`);\n }\n\n if (policy?.allowedCommands !== undefined && !policy.allowedCommands.includes(command)) {\n throw new SandboxToolPolicyError(`Command is not allowed by sandbox tool policy: ${command}`);\n }\n}\n\nfunction assertTimeoutAllowed(timeoutMs: number, options: SandboxToolsOptions): void {\n const maxTimeoutMs = options.exec?.maxTimeoutMs;\n\n if (maxTimeoutMs !== undefined && timeoutMs > maxTimeoutMs) {\n throw new SandboxToolPolicyError(\n `Command timeout exceeds sandbox tool policy (${timeoutMs} > ${maxTimeoutMs}).`,\n );\n }\n}\n\nfunction assertContentAllowed(content: string, options: SandboxToolsOptions): void {\n const maxBytes = options.writeFile?.maxBytes;\n\n if (maxBytes !== undefined && Buffer.byteLength(content) > maxBytes) {\n throw new SandboxToolPolicyError(\"File content exceeds sandbox tool policy.\");\n }\n}\n\nfunction resolveReadFileLimits(options: SandboxToolsOptions): {\n defaultLineCount: number;\n maxLineCount: number;\n maxBytes: number;\n} {\n const defaultLineCount = options.readFile?.defaultLineCount ?? defaultReadFileLineCount;\n const maxLineCount = options.readFile?.maxLineCount ?? defaultReadFileMaxLineCount;\n const maxBytes = options.readFile?.maxBytes ?? defaultReadFileMaxBytes;\n\n if (!Number.isInteger(defaultLineCount) || defaultLineCount <= 0) {\n throw new SandboxToolPolicyError(\"File defaultLineCount must be a positive integer.\");\n }\n if (!Number.isInteger(maxLineCount) || maxLineCount <= 0 || maxLineCount > maxToolReadFileLines) {\n throw new SandboxToolPolicyError(\n `File maxLineCount must be a positive integer no greater than ${maxToolReadFileLines}.`,\n );\n }\n if (defaultLineCount > maxLineCount) {\n throw new SandboxToolPolicyError(\n `File defaultLineCount exceeds maxLineCount (${defaultLineCount} > ${maxLineCount}).`,\n );\n }\n if (!Number.isInteger(maxBytes) || maxBytes <= 0 || maxBytes > maxToolReadFileBytes) {\n throw new SandboxToolPolicyError(\n `File maxBytes must be a positive integer no greater than ${maxToolReadFileBytes}.`,\n );\n }\n\n return { defaultLineCount, maxLineCount, maxBytes };\n}\n"],"mappings":"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","names":["randomUUID","path","randomUUID","path","path"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anvia/sandbox",
3
- "version": "0.5.0",
3
+ "version": "1.0.0-rc.1",
4
4
  "description": "Sandboxed workspace tools for Anvia agents.",
5
5
  "author": "anvia",
6
6
  "maintainer": "Indra Zulfi",
@@ -37,10 +37,10 @@
37
37
  "tsup": "^8.5.0",
38
38
  "typescript": "^5.9.3",
39
39
  "vitest": "^4.0.8",
40
- "@anvia/core": "0.13.5"
40
+ "@anvia/core": "1.0.0-rc.1"
41
41
  },
42
42
  "peerDependencies": {
43
- "@anvia/core": ">=0.7.1 <1.0.0"
43
+ "@anvia/core": "1.0.0-rc.1"
44
44
  },
45
45
  "engines": {
46
46
  "node": ">=20.12.0"