@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 +21 -2
- package/dist/index.js +189 -30
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
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?:
|
|
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
|
-
|
|
1395
|
-
|
|
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
|
-
|
|
1428
|
-
|
|
1429
|
-
execute: async ({ path: path3 }) => {
|
|
1430
|
-
const
|
|
1431
|
-
|
|
1432
|
-
|
|
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
|
-
|
|
1441
|
-
|
|
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
|
-
|
|
1454
|
-
|
|
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
|
-
|
|
1472
|
-
|
|
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
|
-
|
|
1486
|
-
|
|
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
|
-
|
|
1502
|
-
|
|
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
|
-
|
|
1515
|
-
|
|
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
|
-
|
|
1546
|
-
|
|
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
|
-
|
|
1559
|
-
|
|
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
|
|
1664
|
-
const
|
|
1665
|
-
|
|
1666
|
-
|
|
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.
|
|
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.
|
|
40
|
+
"@anvia/core": "1.0.0-rc.1"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
|
-
"@anvia/core": "
|
|
43
|
+
"@anvia/core": "1.0.0-rc.1"
|
|
44
44
|
},
|
|
45
45
|
"engines": {
|
|
46
46
|
"node": ">=20.12.0"
|