@ai-hero/sandcastle 0.4.0 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +185 -126
- package/dist/AgentProvider.d.ts +22 -2
- package/dist/AgentProvider.d.ts.map +1 -1
- package/dist/AgentProvider.js +18 -2
- package/dist/AgentProvider.js.map +1 -1
- package/dist/InitService.d.ts.map +1 -1
- package/dist/InitService.js +55 -6
- package/dist/InitService.js.map +1 -1
- package/dist/MountConfig.d.ts +15 -0
- package/dist/MountConfig.d.ts.map +1 -0
- package/dist/MountConfig.js +7 -0
- package/dist/MountConfig.js.map +1 -0
- package/dist/Orchestrator.d.ts +0 -1
- package/dist/Orchestrator.d.ts.map +1 -1
- package/dist/Orchestrator.js +29 -19
- package/dist/Orchestrator.js.map +1 -1
- package/dist/SandboxFactory.d.ts +16 -10
- package/dist/SandboxFactory.d.ts.map +1 -1
- package/dist/SandboxFactory.js +20 -22
- package/dist/SandboxFactory.js.map +1 -1
- package/dist/SandboxLifecycle.d.ts +1 -1
- package/dist/SandboxLifecycle.d.ts.map +1 -1
- package/dist/SandboxLifecycle.js +2 -2
- package/dist/SandboxLifecycle.js.map +1 -1
- package/dist/SandboxProvider.d.ts +31 -21
- package/dist/SandboxProvider.d.ts.map +1 -1
- package/dist/SandboxProvider.js +2 -2
- package/dist/SandboxProvider.js.map +1 -1
- package/dist/TextDeltaBuffer.d.ts +24 -0
- package/dist/TextDeltaBuffer.d.ts.map +1 -0
- package/dist/TextDeltaBuffer.js +68 -0
- package/dist/TextDeltaBuffer.js.map +1 -0
- package/dist/WorktreeManager.d.ts +2 -0
- package/dist/WorktreeManager.d.ts.map +1 -1
- package/dist/WorktreeManager.js +3 -0
- package/dist/WorktreeManager.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +11 -7
- package/dist/cli.js.map +1 -1
- package/dist/createSandbox.d.ts +6 -5
- package/dist/createSandbox.d.ts.map +1 -1
- package/dist/createSandbox.js +18 -8
- package/dist/createSandbox.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mergeProviderEnv.d.ts +13 -0
- package/dist/mergeProviderEnv.d.ts.map +1 -0
- package/dist/mergeProviderEnv.js +23 -0
- package/dist/mergeProviderEnv.js.map +1 -0
- package/dist/run.d.ts +7 -2
- package/dist/run.d.ts.map +1 -1
- package/dist/run.js +20 -6
- package/dist/run.js.map +1 -1
- package/dist/sandboxes/daytona.d.ts +48 -0
- package/dist/sandboxes/daytona.d.ts.map +1 -0
- package/dist/sandboxes/daytona.js +125 -0
- package/dist/sandboxes/daytona.js.map +1 -0
- package/dist/sandboxes/docker.d.ts +11 -3
- package/dist/sandboxes/docker.d.ts.map +1 -1
- package/dist/sandboxes/docker.js +69 -43
- package/dist/sandboxes/docker.js.map +1 -1
- package/dist/sandboxes/podman.d.ts +46 -0
- package/dist/sandboxes/podman.d.ts.map +1 -0
- package/dist/sandboxes/podman.js +195 -0
- package/dist/sandboxes/podman.js.map +1 -0
- package/dist/sandboxes/test-isolated.d.ts +3 -7
- package/dist/sandboxes/test-isolated.d.ts.map +1 -1
- package/dist/sandboxes/test-isolated.js +57 -47
- package/dist/sandboxes/test-isolated.js.map +1 -1
- package/dist/sandboxes/vercel.d.ts +92 -0
- package/dist/sandboxes/vercel.d.ts.map +1 -0
- package/dist/sandboxes/vercel.js +165 -0
- package/dist/sandboxes/vercel.js.map +1 -0
- package/dist/syncOut.d.ts +1 -1
- package/dist/syncOut.js +3 -3
- package/dist/syncOut.js.map +1 -1
- package/dist/templates/parallel-planner/main.mts +6 -3
- package/dist/templates/parallel-planner-with-review/.env.example +5 -0
- package/dist/templates/parallel-planner-with-review/CODING_STANDARDS.md +27 -0
- package/dist/templates/parallel-planner-with-review/implement-prompt.md +62 -0
- package/dist/templates/parallel-planner-with-review/main.mts +251 -0
- package/dist/templates/parallel-planner-with-review/merge-prompt.md +22 -0
- package/dist/templates/parallel-planner-with-review/plan-prompt.md +33 -0
- package/dist/templates/parallel-planner-with-review/review-prompt.md +55 -0
- package/dist/templates/parallel-planner-with-review/template.json +4 -0
- package/dist/templates/sequential-reviewer/CODING_STANDARDS.md +27 -0
- package/dist/templates/sequential-reviewer/implement-prompt.md +34 -45
- package/dist/templates/sequential-reviewer/main.mts +4 -2
- package/dist/templates/sequential-reviewer/review-prompt.md +1 -1
- package/dist/templates/simple-loop/main.mts +6 -0
- package/dist/testSandbox.d.ts.map +1 -1
- package/dist/testSandbox.js +58 -53
- package/dist/testSandbox.js.map +1 -1
- package/package.json +25 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"docker.js","sourceRoot":"","sources":["../../src/sandboxes/docker.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AACnE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EACL,cAAc,EACd,eAAe,EACf,gBAAgB,GACjB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,8BAA8B,
|
|
1
|
+
{"version":3,"file":"docker.js","sourceRoot":"","sources":["../../src/sandboxes/docker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Podman sandbox provider — creates Podman containers with bind-mounts.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* import { podman } from "sandcastle/sandboxes/podman";
|
|
6
|
+
* await run({ agent: claudeCode("claude-opus-4-6"), sandbox: podman() });
|
|
7
|
+
*/
|
|
8
|
+
import { type SandboxProvider } from "../SandboxProvider.js";
|
|
9
|
+
import type { MountConfig } from "../MountConfig.js";
|
|
10
|
+
export interface PodmanOptions {
|
|
11
|
+
/** Podman image name (default: derived from repo directory name). */
|
|
12
|
+
readonly imageName?: string;
|
|
13
|
+
/**
|
|
14
|
+
* SELinux volume label suffix applied to bind mounts.
|
|
15
|
+
*
|
|
16
|
+
* - `"z"` — shared label (default). No-op on non-SELinux systems.
|
|
17
|
+
* - `"Z"` — private label; only this container can access the mount.
|
|
18
|
+
* - `false` — disable labeling entirely.
|
|
19
|
+
*/
|
|
20
|
+
readonly selinuxLabel?: "z" | "Z" | false;
|
|
21
|
+
/**
|
|
22
|
+
* Additional host directories to bind-mount into the sandbox.
|
|
23
|
+
*
|
|
24
|
+
* Each entry specifies a `hostPath` (tilde-expanded) and `sandboxPath`.
|
|
25
|
+
* If `hostPath` does not exist, sandbox creation fails with a clear error.
|
|
26
|
+
*/
|
|
27
|
+
readonly mounts?: readonly MountConfig[];
|
|
28
|
+
/** Environment variables injected by this provider. Merged at launch time with env resolver and agent provider env. */
|
|
29
|
+
readonly env?: Record<string, string>;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Create a Podman sandbox provider.
|
|
33
|
+
*
|
|
34
|
+
* The returned provider creates Podman containers with bind-mounts
|
|
35
|
+
* for the worktree and git directories. Calls the `podman` binary
|
|
36
|
+
* on PATH directly — no Podman Machine detection or special
|
|
37
|
+
* macOS/Windows handling.
|
|
38
|
+
*/
|
|
39
|
+
export declare const podman: (options?: PodmanOptions | undefined) => SandboxProvider;
|
|
40
|
+
/**
|
|
41
|
+
* Derive the default Podman image name from the repo directory.
|
|
42
|
+
* Returns `sandcastle:<dir-name>` where dir-name is the last path segment,
|
|
43
|
+
* lowercased and sanitized for image tag rules.
|
|
44
|
+
*/
|
|
45
|
+
export declare const defaultImageName: (repoDir: string) => string;
|
|
46
|
+
//# sourceMappingURL=podman.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"podman.d.ts","sourceRoot":"","sources":["../../src/sandboxes/podman.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,EAEL,KAAK,eAAe,EAIrB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,MAAM,WAAW,aAAa;IAC5B,qEAAqE;IACrE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;;OAMG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,GAAG,GAAG,GAAG,GAAG,KAAK,CAAC;IAC1C;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,WAAW,EAAE,CAAC;IACzC,uHAAuH;IACvH,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACvC;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,MAAM,0DA4KlB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,6BAI5B,CAAC"}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Podman sandbox provider — creates Podman containers with bind-mounts.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* import { podman } from "sandcastle/sandboxes/podman";
|
|
6
|
+
* await run({ agent: claudeCode("claude-opus-4-6"), sandbox: podman() });
|
|
7
|
+
*/
|
|
8
|
+
import { execFile, execFileSync, spawn } from "node:child_process";
|
|
9
|
+
import { randomUUID } from "node:crypto";
|
|
10
|
+
import { createInterface } from "node:readline";
|
|
11
|
+
import { createBindMountSandboxProvider, } from "../SandboxProvider.js";
|
|
12
|
+
import { existsSync } from "node:fs";
|
|
13
|
+
import { homedir } from "node:os";
|
|
14
|
+
/**
|
|
15
|
+
* Create a Podman sandbox provider.
|
|
16
|
+
*
|
|
17
|
+
* The returned provider creates Podman containers with bind-mounts
|
|
18
|
+
* for the worktree and git directories. Calls the `podman` binary
|
|
19
|
+
* on PATH directly — no Podman Machine detection or special
|
|
20
|
+
* macOS/Windows handling.
|
|
21
|
+
*/
|
|
22
|
+
export const podman = (options) => {
|
|
23
|
+
const configuredImageName = options?.imageName;
|
|
24
|
+
const selinuxLabel = options?.selinuxLabel ?? "z";
|
|
25
|
+
const userMounts = options?.mounts ? resolveUserMounts(options.mounts) : [];
|
|
26
|
+
return createBindMountSandboxProvider({
|
|
27
|
+
name: "podman",
|
|
28
|
+
env: options?.env,
|
|
29
|
+
create: async (createOptions) => {
|
|
30
|
+
const containerName = `sandcastle-${randomUUID()}`;
|
|
31
|
+
const workspacePath = createOptions.mounts.find((m) => m.hostPath === createOptions.worktreePath)?.sandboxPath ?? "/home/agent/workspace";
|
|
32
|
+
// Build volume mount strings with optional SELinux label (internal + user mounts)
|
|
33
|
+
const labelSuffix = selinuxLabel ? `:${selinuxLabel}` : "";
|
|
34
|
+
const allMounts = [...createOptions.mounts, ...userMounts];
|
|
35
|
+
const volumeMounts = allMounts.map((m) => {
|
|
36
|
+
const base = `${m.hostPath}:${m.sandboxPath}`;
|
|
37
|
+
if (m.readonly)
|
|
38
|
+
return `${base}:ro${labelSuffix}`;
|
|
39
|
+
return `${base}${labelSuffix}`;
|
|
40
|
+
});
|
|
41
|
+
// Resolve image name
|
|
42
|
+
const imageName = configuredImageName ?? defaultImageName(createOptions.hostRepoPath);
|
|
43
|
+
const hostUid = process.getuid?.() ?? 1000;
|
|
44
|
+
const hostGid = process.getgid?.() ?? 1000;
|
|
45
|
+
const env = { ...createOptions.env, HOME: "/home/agent" };
|
|
46
|
+
const envArgs = Object.entries(env).flatMap(([key, value]) => [
|
|
47
|
+
"-e",
|
|
48
|
+
`${key}=${value}`,
|
|
49
|
+
]);
|
|
50
|
+
const volumeArgs = volumeMounts.flatMap((v) => ["-v", v]);
|
|
51
|
+
// Start container via podman run
|
|
52
|
+
await new Promise((resolve, reject) => {
|
|
53
|
+
execFile("podman", [
|
|
54
|
+
"run",
|
|
55
|
+
"-d",
|
|
56
|
+
"--name",
|
|
57
|
+
containerName,
|
|
58
|
+
"--user",
|
|
59
|
+
`${hostUid}:${hostGid}`,
|
|
60
|
+
"-w",
|
|
61
|
+
workspacePath,
|
|
62
|
+
...envArgs,
|
|
63
|
+
...volumeArgs,
|
|
64
|
+
imageName,
|
|
65
|
+
"sleep",
|
|
66
|
+
"infinity",
|
|
67
|
+
], (error) => {
|
|
68
|
+
if (error) {
|
|
69
|
+
reject(new Error(`podman run failed: ${error.message}`));
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
resolve();
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
// Set up signal handlers for cleanup
|
|
77
|
+
const onExit = () => {
|
|
78
|
+
try {
|
|
79
|
+
execFileSync("podman", ["rm", "-f", containerName], {
|
|
80
|
+
stdio: "ignore",
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
/* best-effort */
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
const onSignal = () => {
|
|
88
|
+
onExit();
|
|
89
|
+
process.exit(1);
|
|
90
|
+
};
|
|
91
|
+
process.on("exit", onExit);
|
|
92
|
+
process.on("SIGINT", onSignal);
|
|
93
|
+
process.on("SIGTERM", onSignal);
|
|
94
|
+
const handle = {
|
|
95
|
+
workspacePath,
|
|
96
|
+
exec: (command, opts) => {
|
|
97
|
+
const args = ["exec"];
|
|
98
|
+
if (opts?.cwd)
|
|
99
|
+
args.push("-w", opts.cwd);
|
|
100
|
+
args.push(containerName, "sh", "-c", command);
|
|
101
|
+
if (opts?.onLine) {
|
|
102
|
+
const onLine = opts.onLine;
|
|
103
|
+
return new Promise((resolve, reject) => {
|
|
104
|
+
const proc = spawn("podman", args, {
|
|
105
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
106
|
+
});
|
|
107
|
+
const stdoutChunks = [];
|
|
108
|
+
const stderrChunks = [];
|
|
109
|
+
const rl = createInterface({ input: proc.stdout });
|
|
110
|
+
rl.on("line", (line) => {
|
|
111
|
+
stdoutChunks.push(line);
|
|
112
|
+
onLine(line);
|
|
113
|
+
});
|
|
114
|
+
proc.stderr.on("data", (chunk) => {
|
|
115
|
+
stderrChunks.push(chunk.toString());
|
|
116
|
+
});
|
|
117
|
+
proc.on("error", (error) => {
|
|
118
|
+
reject(new Error(`podman exec failed: ${error.message}`));
|
|
119
|
+
});
|
|
120
|
+
proc.on("close", (code) => {
|
|
121
|
+
resolve({
|
|
122
|
+
stdout: stdoutChunks.join("\n"),
|
|
123
|
+
stderr: stderrChunks.join(""),
|
|
124
|
+
exitCode: code ?? 0,
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
return new Promise((resolve, reject) => {
|
|
130
|
+
execFile("podman", args, { maxBuffer: 10 * 1024 * 1024 }, (error, stdout, stderr) => {
|
|
131
|
+
if (error && error.code === undefined) {
|
|
132
|
+
reject(new Error(`podman exec failed: ${error.message}`));
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
resolve({
|
|
136
|
+
stdout: stdout.toString(),
|
|
137
|
+
stderr: stderr.toString(),
|
|
138
|
+
exitCode: typeof error?.code === "number" ? error.code : 0,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
},
|
|
144
|
+
close: async () => {
|
|
145
|
+
process.removeListener("exit", onExit);
|
|
146
|
+
process.removeListener("SIGINT", onSignal);
|
|
147
|
+
process.removeListener("SIGTERM", onSignal);
|
|
148
|
+
await new Promise((resolve, reject) => {
|
|
149
|
+
execFile("podman", ["rm", "-f", containerName], (error) => {
|
|
150
|
+
if (error) {
|
|
151
|
+
reject(new Error(`podman rm failed: ${error.message}`));
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
resolve();
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
return handle;
|
|
161
|
+
},
|
|
162
|
+
});
|
|
163
|
+
};
|
|
164
|
+
/**
|
|
165
|
+
* Derive the default Podman image name from the repo directory.
|
|
166
|
+
* Returns `sandcastle:<dir-name>` where dir-name is the last path segment,
|
|
167
|
+
* lowercased and sanitized for image tag rules.
|
|
168
|
+
*/
|
|
169
|
+
export const defaultImageName = (repoDir) => {
|
|
170
|
+
const dirName = repoDir.replace(/\/+$/, "").split("/").pop() || "local";
|
|
171
|
+
const sanitized = dirName.toLowerCase().replace(/[^a-z0-9_.-]/g, "-");
|
|
172
|
+
return `sandcastle:${sanitized}`;
|
|
173
|
+
};
|
|
174
|
+
const expandTilde = (p) => {
|
|
175
|
+
if (p === "~")
|
|
176
|
+
return homedir();
|
|
177
|
+
if (p.startsWith("~/"))
|
|
178
|
+
return homedir() + p.slice(1);
|
|
179
|
+
return p;
|
|
180
|
+
};
|
|
181
|
+
const resolveUserMounts = (mounts) => mounts.map((m) => {
|
|
182
|
+
const resolvedHostPath = expandTilde(m.hostPath);
|
|
183
|
+
if (!existsSync(resolvedHostPath)) {
|
|
184
|
+
throw new Error(`Mount hostPath does not exist: ${m.hostPath}` +
|
|
185
|
+
(m.hostPath !== resolvedHostPath
|
|
186
|
+
? ` (resolved to ${resolvedHostPath})`
|
|
187
|
+
: ""));
|
|
188
|
+
}
|
|
189
|
+
return {
|
|
190
|
+
hostPath: resolvedHostPath,
|
|
191
|
+
sandboxPath: m.sandboxPath,
|
|
192
|
+
...(m.readonly ? { readonly: true } : {}),
|
|
193
|
+
};
|
|
194
|
+
});
|
|
195
|
+
//# sourceMappingURL=podman.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"podman.js","sourceRoot":"","sources":["../../src/sandboxes/podman.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,17 +5,13 @@
|
|
|
5
5
|
* Intended for testing the isolated provider abstraction without
|
|
6
6
|
* requiring a real remote environment.
|
|
7
7
|
*/
|
|
8
|
-
import { type
|
|
9
|
-
export interface TestIsolatedOptions {
|
|
10
|
-
/** Branch strategy for this provider. Defaults to { type: "merge-to-head" }. */
|
|
11
|
-
readonly branchStrategy?: IsolatedBranchStrategy;
|
|
12
|
-
}
|
|
8
|
+
import { type IsolatedSandboxProvider } from "../SandboxProvider.js";
|
|
13
9
|
/**
|
|
14
10
|
* Create a filesystem-based test isolated sandbox provider.
|
|
15
11
|
*
|
|
16
12
|
* The "sandbox" is a temp directory. `exec` runs shell commands in it,
|
|
17
|
-
* `copyIn`/`
|
|
13
|
+
* `copyIn`/`copyFileOut` copy files between host and the temp dir,
|
|
18
14
|
* and `close` removes the temp dir.
|
|
19
15
|
*/
|
|
20
|
-
export declare const testIsolated: (
|
|
16
|
+
export declare const testIsolated: () => IsolatedSandboxProvider;
|
|
21
17
|
//# sourceMappingURL=test-isolated.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-isolated.d.ts","sourceRoot":"","sources":["../../src/sandboxes/test-isolated.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAOH,OAAO,
|
|
1
|
+
{"version":3,"file":"test-isolated.d.ts","sourceRoot":"","sources":["../../src/sandboxes/test-isolated.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAOH,OAAO,EAIL,KAAK,uBAAuB,EAC7B,MAAM,uBAAuB,CAAC;AAE/B;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,+BAmGrB,CAAC"}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* requiring a real remote environment.
|
|
7
7
|
*/
|
|
8
8
|
import { execFile, spawn } from "node:child_process";
|
|
9
|
-
import { copyFile, mkdir, mkdtemp, rm } from "node:fs/promises";
|
|
9
|
+
import { copyFile, cp, mkdir, mkdtemp, rm, stat } from "node:fs/promises";
|
|
10
10
|
import { tmpdir } from "node:os";
|
|
11
11
|
import { dirname, join } from "node:path";
|
|
12
12
|
import { createInterface } from "node:readline";
|
|
@@ -15,66 +15,76 @@ import { createIsolatedSandboxProvider, } from "../SandboxProvider.js";
|
|
|
15
15
|
* Create a filesystem-based test isolated sandbox provider.
|
|
16
16
|
*
|
|
17
17
|
* The "sandbox" is a temp directory. `exec` runs shell commands in it,
|
|
18
|
-
* `copyIn`/`
|
|
18
|
+
* `copyIn`/`copyFileOut` copy files between host and the temp dir,
|
|
19
19
|
* and `close` removes the temp dir.
|
|
20
20
|
*/
|
|
21
|
-
export const testIsolated = (
|
|
21
|
+
export const testIsolated = () => createIsolatedSandboxProvider({
|
|
22
22
|
name: "test-isolated",
|
|
23
|
-
branchStrategy: options?.branchStrategy,
|
|
24
23
|
create: async () => {
|
|
25
24
|
const sandboxRoot = await mkdtemp(join(tmpdir(), "sandcastle-test-"));
|
|
26
25
|
const workspacePath = join(sandboxRoot, "workspace");
|
|
27
26
|
await mkdir(workspacePath, { recursive: true });
|
|
28
27
|
return {
|
|
29
28
|
workspacePath,
|
|
30
|
-
exec: (command, options) =>
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
29
|
+
exec: (command, options) => {
|
|
30
|
+
if (options?.onLine) {
|
|
31
|
+
const onLine = options.onLine;
|
|
32
|
+
return new Promise((resolve, reject) => {
|
|
33
|
+
const proc = spawn("sh", ["-c", command], {
|
|
34
|
+
cwd: options?.cwd ?? workspacePath,
|
|
35
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
36
|
+
});
|
|
37
|
+
const stdoutChunks = [];
|
|
38
|
+
const stderrChunks = [];
|
|
39
|
+
const rl = createInterface({ input: proc.stdout });
|
|
40
|
+
rl.on("line", (line) => {
|
|
41
|
+
stdoutChunks.push(line);
|
|
42
|
+
onLine(line);
|
|
43
|
+
});
|
|
44
|
+
proc.stderr.on("data", (chunk) => {
|
|
45
|
+
stderrChunks.push(chunk.toString());
|
|
46
|
+
});
|
|
47
|
+
proc.on("error", (error) => {
|
|
48
|
+
reject(new Error(`exec failed: ${error.message}`));
|
|
49
|
+
});
|
|
50
|
+
proc.on("close", (code) => {
|
|
51
|
+
resolve({
|
|
52
|
+
stdout: stdoutChunks.join("\n"),
|
|
53
|
+
stderr: stderrChunks.join(""),
|
|
54
|
+
exitCode: code ?? 0,
|
|
55
|
+
});
|
|
43
56
|
});
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
});
|
|
62
|
-
proc.on("error", (error) => {
|
|
63
|
-
reject(new Error(`exec streaming failed: ${error.message}`));
|
|
64
|
-
});
|
|
65
|
-
proc.on("close", (code) => {
|
|
66
|
-
resolve({
|
|
67
|
-
stdout: stdoutChunks.join("\n"),
|
|
68
|
-
stderr: stderrChunks.join(""),
|
|
69
|
-
exitCode: code ?? 0,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
return new Promise((resolve, reject) => {
|
|
60
|
+
execFile("sh", ["-c", command], {
|
|
61
|
+
cwd: options?.cwd ?? workspacePath,
|
|
62
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
63
|
+
}, (error, stdout, stderr) => {
|
|
64
|
+
if (error && error.code === undefined) {
|
|
65
|
+
reject(new Error(`exec failed: ${error.message}`));
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
resolve({
|
|
69
|
+
stdout: stdout.toString(),
|
|
70
|
+
stderr: stderr.toString(),
|
|
71
|
+
exitCode: typeof error?.code === "number" ? error.code : 0,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
70
74
|
});
|
|
71
75
|
});
|
|
72
|
-
}
|
|
76
|
+
},
|
|
73
77
|
copyIn: async (hostPath, sandboxPath) => {
|
|
74
|
-
|
|
75
|
-
|
|
78
|
+
const info = await stat(hostPath);
|
|
79
|
+
if (info.isDirectory()) {
|
|
80
|
+
await cp(hostPath, sandboxPath, { recursive: true });
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
await mkdir(dirname(sandboxPath), { recursive: true });
|
|
84
|
+
await copyFile(hostPath, sandboxPath);
|
|
85
|
+
}
|
|
76
86
|
},
|
|
77
|
-
|
|
87
|
+
copyFileOut: async (sandboxPath, hostPath) => {
|
|
78
88
|
await mkdir(dirname(hostPath), { recursive: true });
|
|
79
89
|
await copyFile(sandboxPath, hostPath);
|
|
80
90
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-isolated.js","sourceRoot":"","sources":["../../src/sandboxes/test-isolated.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"test-isolated.js","sourceRoot":"","sources":["../../src/sandboxes/test-isolated.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EACL,6BAA6B,GAI9B,MAAM,uBAAuB,CAAC;AAE/B;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,GAA4B,EAAE,CACxD,6BAA6B,CAAC;IAC5B,IAAI,EAAE,eAAe;IACrB,MAAM,EAAE,KAAK,IAAoC,EAAE;QACjD,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,kBAAkB,CAAC,CAAC,CAAC;QACtE,MAAM,aAAa,GAAG,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;QACrD,MAAM,KAAK,CAAC,aAAa,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAEhD,OAAO;YACL,aAAa;YAEb,IAAI,EAAE,CACJ,OAAe,EACf,OAA2D,EACtC,EAAE;gBACvB,IAAI,OAAO,EAAE,MAAM,EAAE,CAAC;oBACpB,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;oBAC9B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;wBACrC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE;4BACxC,GAAG,EAAE,OAAO,EAAE,GAAG,IAAI,aAAa;4BAClC,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;yBAClC,CAAC,CAAC;wBAEH,MAAM,YAAY,GAAa,EAAE,CAAC;wBAClC,MAAM,YAAY,GAAa,EAAE,CAAC;wBAElC,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,MAAO,EAAE,CAAC,CAAC;wBACpD,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;4BACrB,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;4BACxB,MAAM,CAAC,IAAI,CAAC,CAAC;wBACf,CAAC,CAAC,CAAC;wBAEH,IAAI,CAAC,MAAO,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;4BACxC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;wBACtC,CAAC,CAAC,CAAC;wBAEH,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;4BACzB,MAAM,CAAC,IAAI,KAAK,CAAC,gBAAgB,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;wBACrD,CAAC,CAAC,CAAC;wBAEH,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;4BACxB,OAAO,CAAC;gCACN,MAAM,EAAE,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;gCAC/B,MAAM,EAAE,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;gCAC7B,QAAQ,EAAE,IAAI,IAAI,CAAC;6BACpB,CAAC,CAAC;wBACL,CAAC,CAAC,CAAC;oBACL,CAAC,CAAC,CAAC;gBACL,CAAC;gBAED,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;oBACrC,QAAQ,CACN,IAAI,EACJ,CAAC,IAAI,EAAE,OAAO,CAAC,EACf;wBACE,GAAG,EAAE,OAAO,EAAE,GAAG,IAAI,aAAa;wBAClC,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI;qBAC5B,EACD,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;wBACxB,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;4BACtC,MAAM,CAAC,IAAI,KAAK,CAAC,gBAAgB,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;wBACrD,CAAC;6BAAM,CAAC;4BACN,OAAO,CAAC;gCACN,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE;gCACzB,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE;gCACzB,QAAQ,EAAE,OAAO,KAAK,EAAE,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;6BAC3D,CAAC,CAAC;wBACL,CAAC;oBACH,CAAC,CACF,CAAC;gBACJ,CAAC,CAAC,CAAC;YACL,CAAC;YAED,MAAM,EAAE,KAAK,EACX,QAAgB,EAChB,WAAmB,EACJ,EAAE;gBACjB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC;gBAClC,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;oBACvB,MAAM,EAAE,CAAC,QAAQ,EAAE,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;gBACvD,CAAC;qBAAM,CAAC;oBACN,MAAM,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;oBACvD,MAAM,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;gBACxC,CAAC;YACH,CAAC;YAED,WAAW,EAAE,KAAK,EAChB,WAAmB,EACnB,QAAgB,EACD,EAAE;gBACjB,MAAM,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;gBACpD,MAAM,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;YACxC,CAAC;YAED,KAAK,EAAE,KAAK,IAAmB,EAAE;gBAC/B,MAAM,EAAE,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YAC1D,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vercel isolated sandbox provider — wraps `@vercel/sandbox` into a SandboxProvider.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* import { vercel } from "sandcastle/sandboxes/vercel";
|
|
6
|
+
* await run({ agent: claudeCode("claude-opus-4-6"), sandbox: vercel() });
|
|
7
|
+
*/
|
|
8
|
+
import { type IsolatedSandboxProvider } from "../SandboxProvider.js";
|
|
9
|
+
/**
|
|
10
|
+
* Options for creating a Vercel sandbox provider.
|
|
11
|
+
*
|
|
12
|
+
* All `@vercel/sandbox` `Sandbox.create()` options are accepted as pass-through,
|
|
13
|
+
* plus Sandcastle-specific options for auth and branch strategy.
|
|
14
|
+
*/
|
|
15
|
+
export interface VercelOptions {
|
|
16
|
+
/**
|
|
17
|
+
* Vercel access token.
|
|
18
|
+
*
|
|
19
|
+
* Falls back to the SDK's default auth behavior, which reads
|
|
20
|
+
* `VERCEL_OIDC_TOKEN` (recommended for Vercel-hosted environments) or
|
|
21
|
+
* `VERCEL_TOKEN` from the environment.
|
|
22
|
+
*/
|
|
23
|
+
readonly token?: string;
|
|
24
|
+
/**
|
|
25
|
+
* The source of the sandbox (git repo, tarball, or snapshot).
|
|
26
|
+
* Omit to start an empty sandbox.
|
|
27
|
+
*/
|
|
28
|
+
readonly source?: {
|
|
29
|
+
type: "git";
|
|
30
|
+
url: string;
|
|
31
|
+
depth?: number;
|
|
32
|
+
revision?: string;
|
|
33
|
+
username?: string;
|
|
34
|
+
password?: string;
|
|
35
|
+
} | {
|
|
36
|
+
type: "tarball";
|
|
37
|
+
url: string;
|
|
38
|
+
} | {
|
|
39
|
+
type: "snapshot";
|
|
40
|
+
snapshotId: string;
|
|
41
|
+
};
|
|
42
|
+
/** Array of port numbers to expose from the sandbox (up to 4). */
|
|
43
|
+
readonly ports?: number[];
|
|
44
|
+
/** Timeout in milliseconds before the sandbox auto-terminates. */
|
|
45
|
+
readonly timeout?: number;
|
|
46
|
+
/**
|
|
47
|
+
* Resources to allocate to the sandbox.
|
|
48
|
+
* Each vCPU gets 2048 MB of memory.
|
|
49
|
+
*/
|
|
50
|
+
readonly resources?: {
|
|
51
|
+
vcpus: number;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* The runtime of the sandbox (e.g. `"node24"`, `"node22"`, `"python3.13"`).
|
|
55
|
+
* Defaults to `"node24"`.
|
|
56
|
+
*/
|
|
57
|
+
readonly runtime?: string;
|
|
58
|
+
/**
|
|
59
|
+
* Network policy for the sandbox.
|
|
60
|
+
* Defaults to full internet access if not specified.
|
|
61
|
+
*/
|
|
62
|
+
readonly networkPolicy?: Record<string, unknown>;
|
|
63
|
+
/**
|
|
64
|
+
* Vercel project ID to associate sandbox operations with.
|
|
65
|
+
*/
|
|
66
|
+
readonly projectId?: string;
|
|
67
|
+
/**
|
|
68
|
+
* Vercel team ID to associate sandbox operations with.
|
|
69
|
+
*/
|
|
70
|
+
readonly teamId?: string;
|
|
71
|
+
/**
|
|
72
|
+
* Timeout in milliseconds (alias for `timeout`, kept for discoverability).
|
|
73
|
+
*/
|
|
74
|
+
readonly timeoutMs?: number;
|
|
75
|
+
/**
|
|
76
|
+
* Sandbox template shorthand (e.g. `"node-22"`).
|
|
77
|
+
* Maps to the `runtime` option.
|
|
78
|
+
*/
|
|
79
|
+
readonly template?: string;
|
|
80
|
+
/** Environment variables injected by this provider. Merged at launch time with env resolver and agent provider env. */
|
|
81
|
+
readonly env?: Record<string, string>;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Create a Vercel isolated sandbox provider.
|
|
85
|
+
*
|
|
86
|
+
* The returned provider creates Vercel Firecracker microVM sandboxes via
|
|
87
|
+
* the `@vercel/sandbox` SDK. Each sandbox is ephemeral — one sandbox per run.
|
|
88
|
+
*
|
|
89
|
+
* Requires `@vercel/sandbox` to be installed as a peer dependency.
|
|
90
|
+
*/
|
|
91
|
+
export declare const vercel: (options?: VercelOptions | undefined) => IsolatedSandboxProvider;
|
|
92
|
+
//# sourceMappingURL=vercel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vercel.d.ts","sourceRoot":"","sources":["../../src/sandboxes/vercel.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAOH,OAAO,EAIL,KAAK,uBAAuB,EAC7B,MAAM,uBAAuB,CAAC;AAK/B;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B;;;;;;OAMG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAIxB;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EACZ;QACE,IAAI,EAAE,KAAK,CAAC;QACZ,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,GACD;QACE,IAAI,EAAE,SAAS,CAAC;QAChB,GAAG,EAAE,MAAM,CAAC;KACb,GACD;QACE,IAAI,EAAE,UAAU,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IAEN,kEAAkE;IAClE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IAE1B,kEAAkE;IAClE,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAE1B;;;OAGG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE;QACnB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IAEF;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAE1B;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEjD;;OAEG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAE5B;;OAEG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAEzB;;OAEG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAE5B;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAE3B,uHAAuH;IACvH,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACvC;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,MAAM,kEAqKf,CAAC"}
|