@snappedly-tools/shipyard 0.6.0 → 0.7.0-staging.36082887921
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 +64 -165
- package/dist/MountConfig-BHnKnA4h.d.ts +145 -0
- package/dist/{chunk-WAXEMZUV.js → chunk-44I2BL6E.js} +225 -33
- package/dist/chunk-44I2BL6E.js.map +1 -0
- package/dist/{chunk-56TDSWFU.js → chunk-JI3HDDMS.js} +3 -3
- package/dist/{chunk-56TDSWFU.js.map → chunk-JI3HDDMS.js.map} +1 -1
- package/dist/{chunk-FDYOTN55.js → chunk-L6PX5QTU.js} +253 -878
- package/dist/chunk-L6PX5QTU.js.map +1 -0
- package/dist/index.d.ts +117 -97
- package/dist/index.js +322 -344
- package/dist/index.js.map +1 -1
- package/dist/main.js +235 -139
- package/dist/main.js.map +1 -1
- package/dist/sandboxes/docker.d.ts +1 -3
- package/dist/sandboxes/docker.js +2 -4
- package/dist/templates/parallel-planner/main.mts +67 -9
- package/dist/templates/parallel-planner/planner-branch.mts +151 -0
- package/dist/templates/parallel-planner-with-review/main.mts +70 -12
- package/dist/templates/parallel-planner-with-review/planner-branch.mts +151 -0
- package/dist/templates/sequential-reviewer/main.mts +52 -3
- package/dist/templates/simple-loop/main.mts +51 -2
- package/package.json +1 -17
- package/dist/MountConfig-bZoCs4Dd.d.ts +0 -26
- package/dist/SandboxProvider-XJQqEdSf.d.ts +0 -261
- package/dist/chunk-ACD46ZM4.js +0 -136
- package/dist/chunk-ACD46ZM4.js.map +0 -1
- package/dist/chunk-FDYOTN55.js.map +0 -1
- package/dist/chunk-KMGNFXKN.js +0 -38
- package/dist/chunk-KMGNFXKN.js.map +0 -1
- package/dist/chunk-SOJTAJTF.js +0 -78
- package/dist/chunk-SOJTAJTF.js.map +0 -1
- package/dist/chunk-WAXEMZUV.js.map +0 -1
- package/dist/sandboxes/no-sandbox.d.ts +0 -37
- package/dist/sandboxes/no-sandbox.js +0 -4
- package/dist/sandboxes/no-sandbox.js.map +0 -1
- package/dist/sandboxes/vercel.d.ts +0 -104
- package/dist/sandboxes/vercel.js +0 -166
- package/dist/sandboxes/vercel.js.map +0 -1
- package/dist/templates/blank/main.mts +0 -13
- package/dist/templates/blank/prompt.md +0 -12
- package/dist/templates/blank/template.json +0 -4
package/dist/chunk-KMGNFXKN.js
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
// src/SandboxProvider.ts
|
|
2
|
-
var createBindMountSandboxProvider = (config) => ({
|
|
3
|
-
tag: "bind-mount",
|
|
4
|
-
name: config.name,
|
|
5
|
-
env: config.env ?? {},
|
|
6
|
-
sandboxHomedir: config.sandboxHomedir,
|
|
7
|
-
create: config.create
|
|
8
|
-
});
|
|
9
|
-
var createIsolatedSandboxProvider = (config) => ({
|
|
10
|
-
tag: "isolated",
|
|
11
|
-
name: config.name,
|
|
12
|
-
env: config.env ?? {},
|
|
13
|
-
create: config.create
|
|
14
|
-
});
|
|
15
|
-
var toSessionTransferHandle = (handle) => {
|
|
16
|
-
if (handle === void 0 || !("copyFileOut" in handle)) return void 0;
|
|
17
|
-
if ("copyFileIn" in handle) return handle;
|
|
18
|
-
return {
|
|
19
|
-
worktreePath: handle.worktreePath,
|
|
20
|
-
exec: (command, options) => handle.exec(command, options),
|
|
21
|
-
interactiveExec: handle.interactiveExec?.bind(handle),
|
|
22
|
-
copyFileIn: (source, destination) => handle.copyIn(source, destination),
|
|
23
|
-
copyFileOut: (source, destination) => handle.copyFileOut(source, destination),
|
|
24
|
-
close: () => handle.close()
|
|
25
|
-
};
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
// src/shellQuote.ts
|
|
29
|
-
var shellQuote = (value) => {
|
|
30
|
-
if (value.includes("\0")) {
|
|
31
|
-
throw new Error("Cannot quote a string containing a NUL byte");
|
|
32
|
-
}
|
|
33
|
-
return `'${value.replaceAll("'", "'\\''")}'`;
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
export { createBindMountSandboxProvider, createIsolatedSandboxProvider, shellQuote, toSessionTransferHandle };
|
|
37
|
-
//# sourceMappingURL=chunk-KMGNFXKN.js.map
|
|
38
|
-
//# sourceMappingURL=chunk-KMGNFXKN.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/SandboxProvider.ts","../src/shellQuote.ts"],"names":[],"mappings":";AAsUO,IAAM,8BAAA,GAAiC,CAC5C,MAAA,MAC8B;AAAA,EAC9B,GAAA,EAAK,YAAA;AAAA,EACL,MAAM,MAAA,CAAO,IAAA;AAAA,EACb,GAAA,EAAK,MAAA,CAAO,GAAA,IAAO,EAAC;AAAA,EACpB,gBAAgB,MAAA,CAAO,cAAA;AAAA,EACvB,QAAQ,MAAA,CAAO;AACjB,CAAA;AAMO,IAAM,6BAAA,GAAgC,CAC3C,MAAA,MAC6B;AAAA,EAC7B,GAAA,EAAK,UAAA;AAAA,EACL,MAAM,MAAA,CAAO,IAAA;AAAA,EACb,GAAA,EAAK,MAAA,CAAO,GAAA,IAAO,EAAC;AAAA,EACpB,QAAQ,MAAA,CAAO;AACjB,CAAA;AAGO,IAAM,uBAAA,GAA0B,CACrC,MAAA,KAKuC;AACvC,EAAA,IAAI,MAAA,KAAW,MAAA,IAAa,EAAE,aAAA,IAAiB,SAAS,OAAO,MAAA;AAC/D,EAAA,IAAI,YAAA,IAAgB,QAAQ,OAAO,MAAA;AACnC,EAAA,OAAO;AAAA,IACL,cAAc,MAAA,CAAO,YAAA;AAAA,IACrB,MAAM,CAAC,OAAA,EAAS,YAAY,MAAA,CAAO,IAAA,CAAK,SAAS,OAAO,CAAA;AAAA,IACxD,eAAA,EAAiB,MAAA,CAAO,eAAA,EAAiB,IAAA,CAAK,MAAM,CAAA;AAAA,IACpD,YAAY,CAAC,MAAA,EAAQ,gBAAgB,MAAA,CAAO,MAAA,CAAO,QAAQ,WAAW,CAAA;AAAA,IACtE,aAAa,CAAC,MAAA,EAAQ,gBACpB,MAAA,CAAO,WAAA,CAAY,QAAQ,WAAW,CAAA;AAAA,IACxC,KAAA,EAAO,MAAM,MAAA,CAAO,KAAA;AAAM,GAC5B;AACF;;;AC/WO,IAAM,UAAA,GAAa,CAAC,KAAA,KAA0B;AACnD,EAAA,IAAI,KAAA,CAAM,QAAA,CAAS,IAAI,CAAA,EAAG;AACxB,IAAA,MAAM,IAAI,MAAM,6CAA6C,CAAA;AAAA,EAC/D;AACA,EAAA,OAAO,CAAA,CAAA,EAAI,KAAA,CAAM,UAAA,CAAW,GAAA,EAAK,OAAO,CAAC,CAAA,CAAA,CAAA;AAC3C","file":"chunk-KMGNFXKN.js","sourcesContent":["/**\n * Sandbox provider types — the pluggable interface for sandbox runtimes.\n *\n * Provider authors implement a small Promise-based interface. Shipyard\n * handles worktree creation, git mount resolution, and commit extraction.\n */\n\n/** Result of executing a command inside a sandbox. */\nexport interface ExecResult {\n readonly stdout: string;\n readonly stderr: string;\n readonly exitCode: number;\n}\n\n/** Options for interactiveExec — the streams the provider should wire to the spawned process. */\nexport interface InteractiveExecOptions {\n readonly stdin: NodeJS.ReadableStream;\n readonly stdout: NodeJS.WritableStream;\n readonly stderr: NodeJS.WritableStream;\n readonly cwd?: string;\n /** Terminate the interactive process when the caller cancels the session. */\n readonly signal?: AbortSignal;\n}\n\n/** Handle to a running bind-mount sandbox. */\nexport interface BindMountSandboxHandle {\n /** Absolute path to the worktree inside the sandbox. */\n readonly worktreePath: string;\n /**\n * Execute a command in the sandbox.\n *\n * Implementations MUST support line-by-line streaming via `onLine`. This is\n * how Shipyard delivers live feedback to the user and enforces idle timeouts —\n * without a streaming implementation, neither will work. A buffered/batch\n * implementation that only calls `onLine` after the process exits does NOT\n * satisfy this contract.\n *\n * When `stdin` is set, the implementation pipes the string to the child\n * process's stdin and closes it. This avoids the Linux 128 KB per-arg limit.\n */\n exec(\n command: string,\n options?: {\n onLine?: (line: string) => void;\n cwd?: string;\n sudo?: boolean;\n stdin?: string;\n /** Abort the command when the caller's operation is cancelled. */\n signal?: AbortSignal;\n /** Reject/terminate the command after this many combined output bytes. */\n maxOutputBytes?: number;\n },\n ): Promise<ExecResult>;\n /**\n * Launch an interactive process inside the sandbox.\n * Optional — providers that support interactive sessions implement this.\n * The provider detects TTY mode from the streams (e.g. stdin.isTTY) and\n * allocates a pseudo-terminal accordingly.\n * Implementations MUST terminate the underlying process when `signal` aborts.\n */\n interactiveExec?(\n args: string[],\n options: InteractiveExecOptions,\n ): Promise<{ exitCode: number }>;\n /** Copy a single file from the host into the sandbox. */\n copyFileIn(hostPath: string, sandboxPath: string): Promise<void>;\n /** Copy a single file from the sandbox to the host. */\n copyFileOut(sandboxPath: string, hostPath: string): Promise<void>;\n /** Tear down the sandbox. */\n close(): Promise<void>;\n}\n\n/** Options passed to a bind-mount provider's `create` function. */\nexport interface BindMountCreateOptions {\n /** Host-side path to the worktree directory. */\n readonly worktreePath: string;\n /** Host-side path to the original repo root. */\n readonly hostRepoPath: string;\n /** Volume mounts to apply (host:sandbox pairs). */\n readonly mounts: Array<{\n hostPath: string;\n sandboxPath: string;\n readonly?: boolean;\n }>;\n /** Environment variables to inject into the sandbox. */\n readonly env: Record<string, string>;\n}\n\n/** Configuration for createBindMountSandboxProvider. */\nexport interface BindMountSandboxProviderConfig {\n /** Human-readable name for this provider (e.g. \"docker\"). */\n readonly name: string;\n /** Environment variables injected by this provider. Merged at launch time. */\n readonly env?: Record<string, string>;\n /**\n * Absolute path to the home directory inside the sandbox (e.g. `\"/home/agent\"`).\n * Used to expand `~` in user-provided `sandboxPath` mount configs.\n * Set to `undefined` for providers that do not have a fixed home directory.\n */\n readonly sandboxHomedir?: string;\n /** Create a sandbox handle from the given options. */\n readonly create: (\n options: BindMountCreateOptions,\n ) => Promise<BindMountSandboxHandle>;\n}\n\n/** Handle to a running isolated sandbox (extends bind-mount with file transfer). */\nexport interface IsolatedSandboxHandle {\n /** Absolute path to the worktree inside the sandbox. */\n readonly worktreePath: string;\n /**\n * Execute a command in the sandbox.\n *\n * Implementations MUST support line-by-line streaming via `onLine`. This is\n * how Shipyard delivers live feedback to the user and enforces idle timeouts —\n * without a streaming implementation, neither will work. A buffered/batch\n * implementation that only calls `onLine` after the process exits does NOT\n * satisfy this contract.\n *\n * When `stdin` is set, the implementation pipes the string to the child\n * process's stdin and closes it. This avoids the Linux 128 KB per-arg limit.\n */\n exec(\n command: string,\n options?: {\n onLine?: (line: string) => void;\n cwd?: string;\n sudo?: boolean;\n stdin?: string;\n /** Abort the command when the caller's operation is cancelled. */\n signal?: AbortSignal;\n /** Reject/terminate the command after this many combined output bytes. */\n maxOutputBytes?: number;\n },\n ): Promise<ExecResult>;\n /**\n * Launch an interactive process inside the sandbox.\n * Optional — providers that support interactive sessions implement this.\n * The provider detects TTY mode from the streams (e.g. stdin.isTTY) and\n * allocates a pseudo-terminal accordingly.\n * Implementations MUST terminate the underlying process when `signal` aborts.\n */\n interactiveExec?(\n args: string[],\n options: InteractiveExecOptions,\n ): Promise<{ exitCode: number }>;\n /** Copy a file or directory from the host into the sandbox. */\n copyIn(hostPath: string, sandboxPath: string): Promise<void>;\n /** Copy a single file from the sandbox to the host. */\n copyFileOut(sandboxPath: string, hostPath: string): Promise<void>;\n /** Tear down the sandbox. */\n close(): Promise<void>;\n}\n\n/** Options passed to an isolated provider's `create` function. */\nexport interface IsolatedCreateOptions {\n /** Original host repository path, used only for image naming; never mounted. */\n readonly hostRepoPath?: string;\n /** Environment variables to inject into the sandbox. */\n readonly env: Record<string, string>;\n}\n\n/** Configuration for createIsolatedSandboxProvider. */\nexport interface IsolatedSandboxProviderConfig {\n /** Human-readable name for this provider (e.g. \"vercel\"). */\n readonly name: string;\n /** Environment variables injected by this provider. Merged at launch time. */\n readonly env?: Record<string, string>;\n /** Create an isolated sandbox handle from the given options. */\n readonly create: (\n options: IsolatedCreateOptions,\n ) => Promise<IsolatedSandboxHandle>;\n}\n\n/** A bind-mount sandbox provider. */\nexport interface BindMountSandboxProvider {\n /** @internal Discriminator for internal dispatch. */\n readonly tag: \"bind-mount\";\n /** Human-readable provider name. */\n readonly name: string;\n /** Environment variables injected by this provider. */\n readonly env: Record<string, string>;\n /**\n * Absolute path to the home directory inside the sandbox (e.g. `\"/home/agent\"`).\n * `undefined` when the provider does not declare a sandbox home directory.\n */\n readonly sandboxHomedir: string | undefined;\n /** @internal Create a sandbox handle. */\n readonly create: (\n options: BindMountCreateOptions,\n ) => Promise<BindMountSandboxHandle>;\n}\n\n/** An isolated sandbox provider. */\nexport interface IsolatedSandboxProvider {\n /** @internal Discriminator for internal dispatch. */\n readonly tag: \"isolated\";\n /** Human-readable provider name. */\n readonly name: string;\n /** Environment variables injected by this provider. */\n readonly env: Record<string, string>;\n /** @internal Create an isolated sandbox handle. */\n readonly create: (\n options: IsolatedCreateOptions,\n ) => Promise<IsolatedSandboxHandle>;\n}\n\n/** Handle to a no-sandbox session — runs commands directly on the host. */\nexport interface NoSandboxHandle {\n /** Absolute path to the worktree on the host. */\n readonly worktreePath: string;\n /**\n * Execute a command on the host.\n *\n * Implementations MUST support line-by-line streaming via `onLine`. This is\n * how Shipyard delivers live feedback to the user and enforces idle timeouts —\n * without a streaming implementation, neither will work.\n *\n * When `stdin` is set, the implementation pipes the string to the child\n * process's stdin and closes it. This avoids the Linux 128 KB per-arg limit.\n */\n exec(\n command: string,\n options?: {\n onLine?: (line: string) => void;\n cwd?: string;\n sudo?: boolean;\n stdin?: string;\n /** Abort the command when the caller's operation is cancelled. */\n signal?: AbortSignal;\n /** Reject/terminate the command after this many combined output bytes. */\n maxOutputBytes?: number;\n },\n ): Promise<ExecResult>;\n /**\n * Launch an interactive process on the host with inherited stdio.\n */\n interactiveExec(\n args: string[],\n options: InteractiveExecOptions,\n ): Promise<{ exitCode: number }>;\n /** No-op — no container to tear down. */\n close(): Promise<void>;\n}\n\n/** A no-sandbox provider — runs the agent directly on the host with no container isolation. */\nexport interface NoSandboxProvider {\n /** @internal Discriminator for internal dispatch. */\n readonly tag: \"none\";\n /** Human-readable provider name. */\n readonly name: string;\n /** Environment variables injected by this provider. */\n readonly env: Record<string, string>;\n /** @internal Create a no-sandbox handle. */\n readonly create: (options: {\n readonly worktreePath: string;\n readonly env: Record<string, string>;\n }) => Promise<NoSandboxHandle>;\n}\n\n// ---------- Branch strategy types ----------\n\n/** Head strategy: agent writes directly to host working directory. Bind-mount only. */\nexport interface HeadBranchStrategy {\n readonly type: \"head\";\n}\n\n/** Merge-to-head strategy: temp branch, merge back to HEAD, delete temp branch. */\nexport interface MergeToHeadBranchStrategy {\n readonly type: \"merge-to-head\";\n}\n\n/** Branch strategy: commits land on an explicit named branch. */\nexport interface NamedBranchStrategy {\n readonly type: \"branch\";\n readonly branch: string;\n /**\n * Git ref to use as the starting point when creating a new branch.\n * Only used when the branch doesn't already exist — ignored otherwise.\n * Callers are responsible for ensuring the ref is current (e.g. `git fetch`).\n * Defaults to `HEAD` when omitted.\n */\n readonly baseBranch?: string;\n}\n\n/** Branch strategy for bind-mount providers (all three variants). */\nexport type BindMountBranchStrategy =\n | HeadBranchStrategy\n | MergeToHeadBranchStrategy\n | NamedBranchStrategy;\n\n/** Branch strategy for isolated providers (no head — can't write to host). */\nexport type IsolatedBranchStrategy =\n | MergeToHeadBranchStrategy\n | NamedBranchStrategy;\n\n/** Branch strategy for no-sandbox providers (all three — same as bind-mount). */\nexport type NoSandboxBranchStrategy =\n | HeadBranchStrategy\n | MergeToHeadBranchStrategy\n | NamedBranchStrategy;\n\n/** Union of all branch strategy variants. */\nexport type BranchStrategy =\n | BindMountBranchStrategy\n | IsolatedBranchStrategy\n | NoSandboxBranchStrategy;\n\n/**\n * A sandbox provider — the pluggable unit that `run()`, `interactive()`, and\n * `createSandbox()` accept. Tagged for internal dispatch: \"bind-mount\",\n * \"isolated\", or \"none\". When `NoSandboxProvider` is used, the agent runs\n * directly on the host with no container isolation — opt in at your own risk.\n */\nexport type SandboxProvider =\n | BindMountSandboxProvider\n | IsolatedSandboxProvider\n | NoSandboxProvider;\n\n/** @deprecated Use `SandboxProvider` — it now includes `NoSandboxProvider`. */\nexport type AnySandboxProvider = SandboxProvider;\n\n/**\n * Create a bind-mount sandbox provider from a config object.\n * The returned provider can be passed to `run()` or `createSandbox()`.\n */\nexport const createBindMountSandboxProvider = (\n config: BindMountSandboxProviderConfig,\n): BindMountSandboxProvider => ({\n tag: \"bind-mount\",\n name: config.name,\n env: config.env ?? {},\n sandboxHomedir: config.sandboxHomedir,\n create: config.create,\n});\n\n/**\n * Create an isolated sandbox provider from a config object.\n * The returned provider can be passed to `run()` or `createSandbox()`.\n */\nexport const createIsolatedSandboxProvider = (\n config: IsolatedSandboxProviderConfig,\n): IsolatedSandboxProvider => ({\n tag: \"isolated\",\n name: config.name,\n env: config.env ?? {},\n create: config.create,\n});\n\n/** @internal Adapt isolated file transfer to the existing agent-session boundary. */\nexport const toSessionTransferHandle = (\n handle:\n | BindMountSandboxHandle\n | IsolatedSandboxHandle\n | NoSandboxHandle\n | undefined,\n): BindMountSandboxHandle | undefined => {\n if (handle === undefined || !(\"copyFileOut\" in handle)) return undefined;\n if (\"copyFileIn\" in handle) return handle;\n return {\n worktreePath: handle.worktreePath,\n exec: (command, options) => handle.exec(command, options),\n interactiveExec: handle.interactiveExec?.bind(handle),\n copyFileIn: (source, destination) => handle.copyIn(source, destination),\n copyFileOut: (source, destination) =>\n handle.copyFileOut(source, destination),\n close: () => handle.close(),\n };\n};\n","/** Quote a value for use as one POSIX-shell argument. */\nexport const shellQuote = (value: string): string => {\n if (value.includes(\"\\0\")) {\n throw new Error(\"Cannot quote a string containing a NUL byte\");\n }\n return `'${value.replaceAll(\"'\", \"'\\\\''\")}'`;\n};\n"]}
|
package/dist/chunk-SOJTAJTF.js
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { MAX_TAIL_CHARS, collectProcessOutput } from './chunk-ACD46ZM4.js';
|
|
2
|
-
import { spawn } from 'child_process';
|
|
3
|
-
|
|
4
|
-
var noSandbox = (options) => ({
|
|
5
|
-
tag: "none",
|
|
6
|
-
name: "no-sandbox",
|
|
7
|
-
env: options?.env ?? {},
|
|
8
|
-
create: async (createOptions) => {
|
|
9
|
-
const worktreePath = createOptions.worktreePath;
|
|
10
|
-
const processEnv = { ...process.env, ...createOptions.env };
|
|
11
|
-
const maxOutputTailChars = options?.maxOutputTailChars ?? MAX_TAIL_CHARS;
|
|
12
|
-
const handle = {
|
|
13
|
-
worktreePath,
|
|
14
|
-
exec: (command, opts) => {
|
|
15
|
-
const cwd = opts?.cwd ?? worktreePath;
|
|
16
|
-
const isWindows = process.platform === "win32";
|
|
17
|
-
const shellCmd = isWindows ? "cmd.exe" : "sh";
|
|
18
|
-
const shellArgs = isWindows ? ["/d", "/s", "/c", command] : ["-c", command];
|
|
19
|
-
return new Promise((resolve, reject) => {
|
|
20
|
-
const proc = spawn(shellCmd, shellArgs, {
|
|
21
|
-
cwd,
|
|
22
|
-
env: processEnv,
|
|
23
|
-
signal: opts?.signal,
|
|
24
|
-
stdio: [
|
|
25
|
-
opts?.stdin !== void 0 ? "pipe" : "ignore",
|
|
26
|
-
"pipe",
|
|
27
|
-
"pipe"
|
|
28
|
-
],
|
|
29
|
-
windowsVerbatimArguments: isWindows
|
|
30
|
-
});
|
|
31
|
-
if (opts?.stdin !== void 0) {
|
|
32
|
-
proc.stdin.write(opts.stdin);
|
|
33
|
-
proc.stdin.end();
|
|
34
|
-
}
|
|
35
|
-
proc.on("error", (error) => {
|
|
36
|
-
reject(new Error(`exec failed: ${error.message}`));
|
|
37
|
-
});
|
|
38
|
-
collectProcessOutput(
|
|
39
|
-
{
|
|
40
|
-
stdout: proc.stdout,
|
|
41
|
-
stderr: proc.stderr,
|
|
42
|
-
kill: () => proc.kill("SIGKILL"),
|
|
43
|
-
onClose: (listener) => proc.on("close", listener)
|
|
44
|
-
},
|
|
45
|
-
{ ...opts, maxOutputTailChars },
|
|
46
|
-
resolve,
|
|
47
|
-
reject
|
|
48
|
-
);
|
|
49
|
-
});
|
|
50
|
-
},
|
|
51
|
-
interactiveExec: (args, opts) => {
|
|
52
|
-
return new Promise((resolve, reject) => {
|
|
53
|
-
const [cmd, ...rest] = args;
|
|
54
|
-
const proc = spawn(cmd, rest, {
|
|
55
|
-
cwd: opts.cwd ?? worktreePath,
|
|
56
|
-
env: processEnv,
|
|
57
|
-
stdio: [opts.stdin, opts.stdout, opts.stderr],
|
|
58
|
-
shell: process.platform === "win32",
|
|
59
|
-
signal: opts.signal
|
|
60
|
-
});
|
|
61
|
-
proc.on("error", (error) => {
|
|
62
|
-
reject(new Error(`exec failed: ${error.message}`));
|
|
63
|
-
});
|
|
64
|
-
proc.on("close", (code) => {
|
|
65
|
-
resolve({ exitCode: code ?? 0 });
|
|
66
|
-
});
|
|
67
|
-
});
|
|
68
|
-
},
|
|
69
|
-
close: async () => {
|
|
70
|
-
}
|
|
71
|
-
};
|
|
72
|
-
return handle;
|
|
73
|
-
}
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
export { noSandbox };
|
|
77
|
-
//# sourceMappingURL=chunk-SOJTAJTF.js.map
|
|
78
|
-
//# sourceMappingURL=chunk-SOJTAJTF.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/sandboxes/no-sandbox.ts"],"names":[],"mappings":"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","file":"chunk-SOJTAJTF.js","sourcesContent":["/**\n * No-sandbox provider — runs the agent directly on the host with no container isolation.\n *\n * Usage:\n * import { noSandbox } from \"@snappedly-tools/shipyard/sandboxes/no-sandbox\";\n * await run({ agent: codex(CODEX_MODELS.routine), sandbox: noSandbox(), prompt: \"...\" });\n *\n * Accepted by `run()`, `interactive()`, and `createSandbox()`. It skips\n * container isolation entirely and does not pass\n * `--dangerously-skip-permissions` to the agent.\n */\n\nimport { spawn, type StdioOptions } from \"node:child_process\";\nimport type {\n NoSandboxProvider,\n NoSandboxHandle,\n ExecResult,\n InteractiveExecOptions,\n} from \"../SandboxProvider.js\";\nimport { MAX_TAIL_CHARS } from \"../boundedTail.js\";\nimport { collectProcessOutput } from \"../processOutput.js\";\n\nexport interface NoSandboxOptions {\n /** Environment variables injected by this provider. Merged at launch time. */\n readonly env?: Record<string, string>;\n /**\n * Maximum number of characters of streamed `exec` output retained per stream\n * (stdout and stderr) when an `onLine` callback is supplied (default: 64KiB).\n *\n * Output is delivered live to `onLine` regardless; this only bounds the tail\n * returned in `ExecResult`, preventing a long-running agent's output from\n * overflowing V8's max string length and crashing the run.\n */\n readonly maxOutputTailChars?: number;\n}\n\n/**\n * Create a no-sandbox provider.\n *\n * The returned provider runs the agent directly on the host. All three\n * branch strategies are supported (head, merge-to-head, branch),\n * defaulting to head.\n */\nexport const noSandbox = (options?: NoSandboxOptions): NoSandboxProvider => ({\n tag: \"none\",\n name: \"no-sandbox\",\n env: options?.env ?? {},\n create: async (createOptions): Promise<NoSandboxHandle> => {\n const worktreePath = createOptions.worktreePath;\n const processEnv = { ...process.env, ...createOptions.env };\n const maxOutputTailChars = options?.maxOutputTailChars ?? MAX_TAIL_CHARS;\n\n const handle: NoSandboxHandle = {\n worktreePath,\n\n exec: (\n command: string,\n opts?: {\n onLine?: (line: string) => void;\n cwd?: string;\n sudo?: boolean;\n stdin?: string;\n signal?: AbortSignal;\n maxOutputBytes?: number;\n },\n ): Promise<ExecResult> => {\n // sudo is a no-op for no-sandbox — the user is already on the host\n const cwd = opts?.cwd ?? worktreePath;\n const isWindows = process.platform === \"win32\";\n // PowerShell and cmd.exe don't ship `sh`, so on Windows route the\n // command string through cmd.exe instead. `/d` skips AutoRun, `/s`\n // preserves the quoted command verbatim, `/c` runs it and exits.\n // `windowsVerbatimArguments` keeps Node from re-quoting our args.\n const shellCmd = isWindows ? \"cmd.exe\" : \"sh\";\n const shellArgs = isWindows\n ? [\"/d\", \"/s\", \"/c\", command]\n : [\"-c\", command];\n\n return new Promise((resolve, reject) => {\n const proc = spawn(shellCmd, shellArgs, {\n cwd,\n env: processEnv,\n signal: opts?.signal,\n stdio: [\n opts?.stdin !== undefined ? \"pipe\" : \"ignore\",\n \"pipe\",\n \"pipe\",\n ],\n windowsVerbatimArguments: isWindows,\n });\n\n if (opts?.stdin !== undefined) {\n proc.stdin!.write(opts.stdin);\n proc.stdin!.end();\n }\n\n proc.on(\"error\", (error) => {\n reject(new Error(`exec failed: ${error.message}`));\n });\n\n collectProcessOutput(\n {\n stdout: proc.stdout!,\n stderr: proc.stderr!,\n kill: () => proc.kill(\"SIGKILL\"),\n onClose: (listener) => proc.on(\"close\", listener),\n },\n { ...opts, maxOutputTailChars },\n resolve,\n reject,\n );\n });\n },\n\n interactiveExec: (\n args: string[],\n opts: InteractiveExecOptions,\n ): Promise<{ exitCode: number }> => {\n return new Promise((resolve, reject) => {\n const [cmd, ...rest] = args;\n // Agent CLIs on Windows are typically installed as `.cmd`/`.ps1`\n // npm wrappers; bare `spawn(\"claude\", …)` only resolves `.exe`\n // without `shell: true`, so let cmd.exe handle PATHEXT lookup.\n const proc = spawn(cmd!, rest, {\n cwd: opts.cwd ?? worktreePath,\n env: processEnv,\n stdio: [opts.stdin, opts.stdout, opts.stderr] as StdioOptions,\n shell: process.platform === \"win32\",\n signal: opts.signal,\n });\n\n proc.on(\"error\", (error: Error) => {\n reject(new Error(`exec failed: ${error.message}`));\n });\n\n proc.on(\"close\", (code: number | null) => {\n resolve({ exitCode: code ?? 0 });\n });\n });\n },\n\n close: async (): Promise<void> => {\n // No-op — no container to tear down\n },\n };\n\n return handle;\n },\n});\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/sandboxes/copyIntoContainer.ts","../src/DockerLifecycle.ts","../src/RepositoryRunnerLifecycle.ts","../src/sandboxes/docker.ts"],"names":["execFile","promisify","resolve","Effect"],"mappings":"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","file":"chunk-WAXEMZUV.js","sourcesContent":["import { execFile } from \"node:child_process\";\nimport { posix } from \"node:path\";\nimport { promisify } from \"node:util\";\n\nconst exec = promisify(execFile);\n\n/** Container cp creates root-owned files; session files may have mode 0600. */\nexport const copyIntoContainer = async (\n engine: \"docker\",\n container: string,\n owner: string,\n hostPath: string,\n sandboxPath: string,\n): Promise<void> => {\n try {\n await exec(engine, [\n \"exec\",\n container,\n \"mkdir\",\n \"-p\",\n \"--\",\n posix.dirname(sandboxPath),\n ]);\n await exec(engine, [\"cp\", hostPath, `${container}:${sandboxPath}`]);\n await exec(engine, [\n \"exec\",\n \"--user\",\n \"0:0\",\n container,\n \"chown\",\n \"-hR\",\n \"--\",\n owner,\n sandboxPath,\n ]);\n } catch (error) {\n throw new Error(\n `${engine} cp (in) failed: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n};\n","import { Effect } from \"effect\";\nimport { execFile } from \"node:child_process\";\nimport { resolve } from \"node:path\";\nimport { DockerError } from \"./errors.js\";\nimport { formatVolumeMount, type SelinuxLabel } from \"./mountUtils.js\";\n\nconst dockerExec = (args: string[]): Effect.Effect<string, DockerError> =>\n Effect.async((resume) => {\n execFile(\n \"docker\",\n args,\n { maxBuffer: 10 * 1024 * 1024 },\n (error, stdout, stderr) => {\n if (error) {\n resume(\n Effect.fail(\n new DockerError({\n message: `docker ${args[0]} failed: ${stderr?.toString() || error.message}`,\n }),\n ),\n );\n } else {\n resume(Effect.succeed(stdout.toString()));\n }\n },\n );\n });\n\n/**\n * Build the shipyard Docker image.\n *\n * When `dockerfile` is provided, uses `docker build -f <dockerfile> <cwd>`\n * so COPY instructions resolve relative to the current working directory.\n * Otherwise, uses `docker build <dockerfileDir>` (the default .shipyard/ directory).\n */\nexport const buildImage = (\n imageName: string,\n dockerfileDir: string,\n options?: {\n readonly dockerfile?: string;\n readonly buildArgs?: Record<string, string>;\n },\n): Effect.Effect<void, DockerError> =>\n Effect.gen(function* () {\n const buildArgFlags = Object.entries(options?.buildArgs ?? {}).flatMap(\n ([k, v]) => [\"--build-arg\", `${k}=${v}`],\n );\n if (options?.dockerfile) {\n yield* dockerExec([\n \"build\",\n \"-t\",\n imageName,\n ...buildArgFlags,\n \"-f\",\n resolve(options.dockerfile),\n process.cwd(),\n ]);\n } else {\n yield* dockerExec([\n \"build\",\n \"-t\",\n imageName,\n ...buildArgFlags,\n resolve(dockerfileDir),\n ]);\n }\n });\n\nexport interface VolumeMount {\n readonly hostPath: string;\n readonly sandboxPath: string;\n readonly readonly?: boolean;\n}\n\nexport interface StartContainerOptions {\n readonly volumeMounts?: readonly VolumeMount[];\n readonly workdir?: string;\n /** Run the container as this uid:gid instead of the Dockerfile's USER. */\n readonly user?: string;\n /** Docker network(s) to attach the container to. Passed as `--network` flags. */\n readonly network?: string | readonly string[];\n /** Supplementary groups to add the container user to. Passed as `--group-add` flags. */\n readonly groups?: readonly (string | number)[];\n /** Host devices to expose to the container. Passed as `--device` flags. */\n readonly devices?: readonly string[];\n /** Limit CPU resources via `--cpus` (e.g. `1.5`). Fractional values allowed. */\n readonly cpus?: number;\n /** Docker labels used to scope repository-runner crash recovery. */\n readonly labels?: Readonly<Record<string, string>>;\n /**\n * SELinux volume label suffix applied to bind mounts (default `\"z\"`).\n *\n * - `\"z\"` — shared label. No-op on non-SELinux systems.\n * - `\"Z\"` — private label; only this container can access the mount.\n * - `false` — disable labeling entirely.\n */\n readonly selinuxLabel?: SelinuxLabel;\n}\n\n/**\n * Start a new container with environment variables injected.\n */\nexport const startContainer = (\n containerName: string,\n imageName: string,\n env: Record<string, string>,\n options?: StartContainerOptions,\n): Effect.Effect<void, DockerError> =>\n Effect.gen(function* () {\n // Check if container already exists\n const existing = yield* dockerExec([\n \"ps\",\n \"-a\",\n \"--filter\",\n `name=^${containerName}$`,\n \"--format\",\n \"{{.Names}}\",\n ]);\n\n if (existing.trim() === containerName) {\n yield* Effect.fail(\n new DockerError({\n message: `Container '${containerName}' already exists. Run cleanup first.`,\n }),\n );\n }\n\n const envFlags = Object.entries(env).flatMap(([k, v]) => [\n \"-e\",\n `${k}=${v}`,\n ]);\n\n const selinuxLabel = options?.selinuxLabel ?? \"z\";\n const volumeFlags = (options?.volumeMounts ?? []).flatMap((mount) => [\n \"-v\",\n formatVolumeMount(mount, selinuxLabel),\n ]);\n\n const workdirFlags = options?.workdir ? [\"-w\", options.workdir] : [];\n const userFlags = options?.user ? [\"--user\", options.user] : [];\n const networks = options?.network\n ? Array.isArray(options.network)\n ? options.network\n : [options.network]\n : [];\n const networkFlags = networks.flatMap((n) => [\"--network\", n]);\n const groupAddFlags = (options?.groups ?? []).flatMap((g) => [\n \"--group-add\",\n String(g),\n ]);\n const deviceFlags = (options?.devices ?? []).flatMap((d) => [\n \"--device\",\n d,\n ]);\n const cpusFlags =\n options?.cpus !== undefined ? [\"--cpus\", String(options.cpus)] : [];\n const labelFlags = Object.entries(options?.labels ?? {}).flatMap(\n ([key, value]) => [\"--label\", `${key}=${value}`],\n );\n\n yield* dockerExec([\n \"run\",\n \"-d\",\n \"--init\",\n \"--name\",\n containerName,\n ...labelFlags,\n ...envFlags,\n ...volumeFlags,\n ...workdirFlags,\n ...userFlags,\n ...networkFlags,\n ...groupAddFlags,\n ...deviceFlags,\n ...cpusFlags,\n imageName,\n ]);\n });\n\n/**\n * Stop and remove a container without removing the image.\n */\nexport const removeContainer = (\n containerName: string,\n): Effect.Effect<void, DockerError> =>\n Effect.gen(function* () {\n // Stop container (ignore errors if already stopped)\n yield* Effect.ignore(dockerExec([\"stop\", containerName]));\n // Remove container (ignore errors if not found)\n yield* Effect.ignore(dockerExec([\"rm\", containerName]));\n });\n\n/**\n * Remove a Docker image.\n */\nexport const removeImage = (\n imageName: string,\n): Effect.Effect<void, DockerError> =>\n Effect.gen(function* () {\n yield* dockerExec([\"rmi\", imageName]);\n });\n","import { execFile } from \"node:child_process\";\nimport { constants } from \"node:fs\";\nimport { access, lstat, mkdir, readFile, realpath, rm } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { promisify } from \"node:util\";\nimport {\n ACTIVATION_LABEL,\n CONFIG_DIR,\n RUNNER_DIR,\n RUNNER_SANDBOX_MASK_DIR,\n} from \"./runtimeNames.js\";\nimport {\n assertProtectedDirectoryIdentities,\n repositoryRunnerEnvironment,\n type ProtectedDirectoryIdentity,\n} from \"./runnerSecurity.js\";\n\nconst execFileAsync = promisify(execFile);\n\nexport const RUNNER_INSTALL_METADATA = \".shipyard-install.json\";\nexport const RUNNER_CONTROLLER_LOCK = \".shipyard-controller.lock\";\nexport const RUNNER_WORK_DIR = \"_work\";\nexport const REPOSITORY_RUNNER_OWNER_LABEL =\n \"com.snappedly.shipyard.repository-runner-owner\";\nexport const REPOSITORY_RUNNER_OWNER_ENV = \"SHIPYARD_RUNNER_OWNER\";\nconst REGISTRATION_FILES = [\n \".credentials\",\n \".credentials_rsaparams\",\n \".runner\",\n] as const;\n\ninterface CommandResult {\n readonly stdout: string;\n readonly stderr: string;\n}\n\ninterface CommandOptions {\n readonly cwd: string;\n readonly env: NodeJS.ProcessEnv;\n}\n\nexport interface RunnerInstallMetadata {\n readonly schemaVersion: 1;\n readonly repository: string;\n readonly repositoryUrl: string;\n readonly name: string;\n readonly label: string;\n readonly version: string;\n}\n\ninterface RunnerControllerLock {\n readonly schemaVersion: 1;\n readonly pid: number;\n readonly repository: string;\n readonly processStartedAt: string;\n}\n\nexport class RunnerLifecycleError extends Error {\n readonly name = \"RunnerLifecycleError\";\n}\n\n/** Internal seams for validating an existing runner installation. */\nexport interface RunnerInstallValidationAdapters {\n readonly environment: () => NodeJS.ProcessEnv;\n readonly exists: (path: string) => Promise<boolean>;\n readonly readText: (path: string) => Promise<string>;\n readonly makeDirectory: (path: string) => Promise<void>;\n readonly inspectDirectory?: (\n path: string,\n ) => Promise<ProtectedDirectoryIdentity>;\n readonly run: (\n command: string,\n args: readonly string[],\n options: CommandOptions,\n ) => Promise<CommandResult>;\n}\n\n/** Internal seams for runner registration, filesystem cleanup, and process control. */\nexport interface RunnerLifecycleAdapters extends RunnerInstallValidationAdapters {\n readonly remove: (path: string) => Promise<void>;\n readonly isProcessRunning: (pid: number) => boolean;\n readonly signalProcess: (pid: number, signal: NodeJS.Signals) => void;\n readonly pause: (milliseconds: number) => Promise<void>;\n readonly processIdentity: (pid: number) => Promise<string | undefined>;\n}\n\nconst defaultAdapters: RunnerLifecycleAdapters = {\n environment: () => process.env,\n exists: async (path) => {\n try {\n await access(path, constants.F_OK);\n return true;\n } catch {\n return false;\n }\n },\n readText: (path) => readFile(path, \"utf8\"),\n makeDirectory: async (path) => {\n await mkdir(path, { recursive: true, mode: 0o700 });\n },\n inspectDirectory: async (path) => {\n const [stat, resolved] = await Promise.all([lstat(path), realpath(path)]);\n return {\n realPath: resolved,\n directory: stat.isDirectory(),\n symbolicLink: stat.isSymbolicLink(),\n };\n },\n remove: (path) => rm(path, { recursive: true, force: true }),\n run: async (command, args, options) => {\n const result = await execFileAsync(command, [...args], {\n cwd: options.cwd,\n env: options.env,\n maxBuffer: 10 * 1024 * 1024,\n });\n return { stdout: result.stdout, stderr: result.stderr };\n },\n processIdentity: async (pid) => {\n try {\n const result = await execFileAsync(\"ps\", [\n \"-p\",\n String(pid),\n \"-o\",\n \"lstart=\",\n ]);\n const identity = result.stdout.trim().replace(/\\s+/g, \" \");\n return identity.length > 0 ? identity : undefined;\n } catch {\n return undefined;\n }\n },\n isProcessRunning: (pid) => {\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n },\n signalProcess: (pid, signal) => process.kill(pid, signal),\n pause: (milliseconds) =>\n new Promise((resolve) => setTimeout(resolve, milliseconds)),\n};\n\nconst lockOwnsProcess = async (\n lock: RunnerControllerLock | undefined,\n adapters: Pick<\n RunnerLifecycleAdapters,\n \"isProcessRunning\" | \"processIdentity\"\n >,\n): Promise<boolean> =>\n lock !== undefined &&\n Number.isInteger(lock.pid) &&\n typeof lock.processStartedAt === \"string\" &&\n lock.processStartedAt.length > 0 &&\n adapters.isProcessRunning(lock.pid) &&\n (await adapters.processIdentity(lock.pid)) === lock.processStartedAt;\n\nconst lifecycleFailure = (\n purpose: string,\n error: unknown,\n): RunnerLifecycleError =>\n error instanceof RunnerLifecycleError\n ? error\n : new RunnerLifecycleError(\n `${purpose} failed: ${error instanceof Error ? error.message : String(error)}`,\n );\n\nconst runCommand = async (\n adapters: Pick<RunnerInstallValidationAdapters, \"run\">,\n purpose: string,\n command: string,\n args: readonly string[],\n options: CommandOptions,\n): Promise<CommandResult> => {\n try {\n return await adapters.run(command, args, options);\n } catch (error) {\n throw lifecycleFailure(purpose, error);\n }\n};\n\nconst readJson = async <T>(\n path: string,\n adapters: Pick<RunnerInstallValidationAdapters, \"exists\" | \"readText\">,\n): Promise<T | undefined> => {\n if (!(await adapters.exists(path))) return undefined;\n try {\n return JSON.parse(await adapters.readText(path)) as T;\n } catch (error) {\n throw lifecycleFailure(`Reading repository runner state at ${path}`, error);\n }\n};\n\nconst requireInstallMetadata = async (\n runnerDir: string,\n adapters: Pick<RunnerInstallValidationAdapters, \"exists\" | \"readText\">,\n): Promise<RunnerInstallMetadata> => {\n const metadata = await readJson<RunnerInstallMetadata>(\n join(runnerDir, RUNNER_INSTALL_METADATA),\n adapters,\n );\n if (\n metadata?.schemaVersion !== 1 ||\n typeof metadata.repository !== \"string\" ||\n typeof metadata.repositoryUrl !== \"string\" ||\n typeof metadata.name !== \"string\" ||\n metadata.label !== ACTIVATION_LABEL ||\n typeof metadata.version !== \"string\"\n ) {\n throw new RunnerLifecycleError(\n `The existing directory at ${runnerDir} is not a valid Shipyard repository runner installation. Refusing to replace it.`,\n );\n }\n return metadata;\n};\n\ninterface RemoteRunner {\n readonly name: string;\n readonly status: string;\n readonly labels: ReadonlySet<string>;\n}\n\nconst parseRemoteRunners = (stdout: string): readonly RemoteRunner[] =>\n stdout\n .split(/\\r?\\n/)\n .filter((line) => line.length > 0)\n .map((line) => {\n const [name = \"\", status = \"\", labels = \"\"] = line.split(\"\\t\");\n return {\n name,\n status,\n labels: new Set(labels.split(\",\").filter(Boolean)),\n };\n });\n\nconst listRemoteRunners = async (\n repository: string,\n repoDir: string,\n environment: NodeJS.ProcessEnv,\n adapters: RunnerInstallValidationAdapters,\n): Promise<readonly RemoteRunner[]> => {\n const response = await runCommand(\n adapters,\n \"Checking registered GitHub repository runners\",\n \"gh\",\n [\n \"api\",\n \"--paginate\",\n `repos/${repository}/actions/runners`,\n \"--jq\",\n '.runners[] | [.name, .status, ([.labels[].name] | join(\",\"))] | @tsv',\n ],\n { cwd: repoDir, env: environment },\n );\n return parseRemoteRunners(response.stdout);\n};\n\nexport const validateExistingRepositoryRunner = async (\n options: {\n readonly repoDir: string;\n readonly runnerDir: string;\n readonly maskDir: string;\n readonly repository: string;\n readonly runnerName: string;\n },\n adapters: RunnerInstallValidationAdapters = defaultAdapters,\n): Promise<RunnerInstallMetadata> => {\n if (!(await adapters.exists(options.maskDir))) {\n await adapters.makeDirectory(options.maskDir);\n }\n await assertProtectedDirectoryIdentities(\n options.runnerDir,\n options.maskDir,\n adapters.inspectDirectory,\n ).catch((error) => {\n throw lifecycleFailure(\"Validating protected runner directories\", error);\n });\n const metadata = await requireInstallMetadata(options.runnerDir, adapters);\n if (metadata.repository !== options.repository) {\n throw new RunnerLifecycleError(\n `The existing repository runner belongs to ${metadata.repository}, not ${options.repository}. Refusing to replace it.`,\n );\n }\n if (metadata.name !== options.runnerName) {\n throw new RunnerLifecycleError(\n `The existing installation belongs to runner ${metadata.name}, not ${options.runnerName}. A Mac rename does not rename a registered runner; remove and reinstall it explicitly.`,\n );\n }\n for (const required of [\".credentials\", \"run.sh\"] as const) {\n if (!(await adapters.exists(join(options.runnerDir, required)))) {\n throw new RunnerLifecycleError(\n `The existing repository runner is missing ${required}. Refusing to replace its registration; remove it explicitly first.`,\n );\n }\n }\n\n const remoteRunners = await listRemoteRunners(\n options.repository,\n options.repoDir,\n adapters.environment(),\n adapters,\n );\n const labelled = remoteRunners.filter(({ labels }) =>\n labels.has(ACTIVATION_LABEL),\n );\n if (labelled.length > 1) {\n throw new RunnerLifecycleError(\n `Multiple repository runners carry the ${ACTIVATION_LABEL} label (${labelled.map(({ name }) => name).join(\", \")}). Remove duplicates before continuing.`,\n );\n }\n const matching = remoteRunners.find(({ name }) => name === metadata.name);\n if (!matching) {\n throw new RunnerLifecycleError(\n `Runner ${metadata.name} is installed locally but is no longer registered with GitHub. Run \\`shipyard runner start\\` to repair it, or remove it explicitly.`,\n );\n }\n if (!matching.labels.has(ACTIVATION_LABEL)) {\n throw new RunnerLifecycleError(\n `Registered runner ${metadata.name} does not carry the ${ACTIVATION_LABEL} label. Refusing to replace a customized registration.`,\n );\n }\n\n return metadata;\n};\n\nconst removeRegistrationFiles = async (\n runnerDir: string,\n adapters: RunnerLifecycleAdapters,\n): Promise<void> => {\n for (const name of REGISTRATION_FILES) {\n const path = join(runnerDir, name);\n if (await adapters.exists(path)) await adapters.remove(path);\n }\n};\n\nconst readOneTimeToken = (stdout: string, purpose: string): string => {\n try {\n const parsed = JSON.parse(stdout) as { token?: unknown };\n if (typeof parsed.token !== \"string\" || parsed.token.length === 0) {\n throw new Error(\"response did not contain a token\");\n }\n return parsed.token;\n } catch (error) {\n throw lifecycleFailure(purpose, error);\n }\n};\n\nconst requestRegistrationToken = async (\n repository: string,\n repoDir: string,\n environment: NodeJS.ProcessEnv,\n adapters: RunnerLifecycleAdapters,\n): Promise<string> => {\n await runCommand(\n adapters,\n \"Checking current administrative GitHub authorization\",\n \"gh\",\n [\"auth\", \"status\", \"--hostname\", \"github.com\"],\n { cwd: repoDir, env: environment },\n );\n const response = await runCommand(\n adapters,\n \"Requesting a one-time repository runner registration token\",\n \"gh\",\n [\n \"api\",\n \"--method\",\n \"POST\",\n `repos/${repository}/actions/runners/registration-token`,\n ],\n { cwd: repoDir, env: environment },\n );\n return readOneTimeToken(response.stdout, \"Reading the registration token\");\n};\n\nexport const recoverRepositoryRunner = async (\n options: {\n readonly repoDir: string;\n readonly runnerDir: string;\n readonly maskDir: string;\n readonly metadata: RunnerInstallMetadata;\n readonly runnerEnvironment: NodeJS.ProcessEnv;\n readonly dockerEnvironment?: NodeJS.ProcessEnv;\n },\n adapters: RunnerLifecycleAdapters = defaultAdapters,\n): Promise<{ readonly reRegistered: boolean }> => {\n const lockPath = join(options.runnerDir, RUNNER_CONTROLLER_LOCK);\n const lock = await readJson<RunnerControllerLock>(lockPath, adapters);\n if (await lockOwnsProcess(lock, adapters)) {\n throw new RunnerLifecycleError(\n `The repository runner is already running with process ${lock!.pid}.`,\n );\n }\n if (lock) await adapters.remove(lockPath);\n\n const workDir = join(options.runnerDir, RUNNER_WORK_DIR);\n if (await adapters.exists(workDir)) await adapters.remove(workDir);\n if (await adapters.exists(options.maskDir))\n await adapters.remove(options.maskDir);\n await adapters.makeDirectory(options.maskDir);\n await assertProtectedDirectoryIdentities(\n options.runnerDir,\n options.maskDir,\n adapters.inspectDirectory,\n ).catch((error) => {\n throw lifecycleFailure(\"Validating protected runner directories\", error);\n });\n\n await removeOwnedRepositoryRunnerContainers(\n {\n repoDir: options.repoDir,\n repository: options.metadata.repository,\n environment: options.dockerEnvironment ?? options.runnerEnvironment,\n },\n adapters,\n );\n\n const adminEnvironment = adapters.environment();\n const remoteRunners = await listRemoteRunners(\n options.metadata.repository,\n options.repoDir,\n adminEnvironment,\n adapters,\n );\n const labelled = remoteRunners.filter(({ labels }) =>\n labels.has(ACTIVATION_LABEL),\n );\n if (labelled.length > 1) {\n throw new RunnerLifecycleError(\n `Multiple repository runners carry the ${ACTIVATION_LABEL} label (${labelled.map(({ name }) => name).join(\", \")}). Remove duplicates before continuing.`,\n );\n }\n const matching = remoteRunners.find(\n ({ name }) => name === options.metadata.name,\n );\n if (matching) {\n if (!matching.labels.has(ACTIVATION_LABEL)) {\n throw new RunnerLifecycleError(\n `Registered runner ${matching.name} does not carry the ${ACTIVATION_LABEL} label. Refusing to replace a customized registration.`,\n );\n }\n if (!(await adapters.exists(join(options.runnerDir, \".credentials\")))) {\n throw new RunnerLifecycleError(\n `Registered runner ${matching.name} is missing local credentials. Remove and reinstall it explicitly.`,\n );\n }\n return { reRegistered: false };\n }\n\n const collision = labelled[0];\n if (collision) {\n throw new RunnerLifecycleError(\n `Repository runner ${collision.name} already carries the ${ACTIVATION_LABEL} label. Refusing to create a conflicting registration.`,\n );\n }\n\n const registrationToken = await requestRegistrationToken(\n options.metadata.repository,\n options.repoDir,\n adminEnvironment,\n adapters,\n );\n await removeRegistrationFiles(options.runnerDir, adapters);\n try {\n await adapters.run(\n \"./config.sh\",\n [\n \"--url\",\n options.metadata.repositoryUrl,\n \"--token\",\n registrationToken,\n \"--name\",\n options.metadata.name,\n \"--labels\",\n ACTIVATION_LABEL,\n \"--work\",\n RUNNER_WORK_DIR,\n \"--unattended\",\n ],\n { cwd: options.runnerDir, env: options.runnerEnvironment },\n );\n } catch {\n await removeRegistrationFiles(options.runnerDir, adapters);\n throw new RunnerLifecycleError(\n `Re-registering ${options.metadata.name} failed. Partial local registration files were removed; check GitHub Settings > Actions > Runners for an orphan registration, then retry \\`shipyard runner start\\`. The one-time token was not stored.`,\n );\n }\n return { reRegistered: true };\n};\n\nexport const removeOwnedRepositoryRunnerContainers = async (\n options: {\n readonly repoDir: string;\n readonly repository: string;\n readonly environment: NodeJS.ProcessEnv;\n },\n adapters: Pick<RunnerLifecycleAdapters, \"run\"> = defaultAdapters,\n): Promise<void> => {\n const ownedContainers = await runCommand(\n adapters,\n \"Finding stale repository-runner containers\",\n \"docker\",\n [\n \"ps\",\n \"-aq\",\n \"--filter\",\n `label=${REPOSITORY_RUNNER_OWNER_LABEL}=${options.repository}`,\n ],\n { cwd: options.repoDir, env: options.environment },\n );\n const containerIds = ownedContainers.stdout.split(/\\s+/).filter(Boolean);\n if (containerIds.length === 0) return;\n await runCommand(\n adapters,\n \"Removing stale repository-runner containers\",\n \"docker\",\n [\"rm\", \"-f\", ...containerIds],\n { cwd: options.repoDir, env: options.environment },\n );\n};\n\nconst waitForProcessToStop = async (\n pid: number,\n adapters: RunnerLifecycleAdapters,\n): Promise<void> => {\n adapters.signalProcess(pid, \"SIGTERM\");\n for (let attempt = 0; attempt < 50; attempt += 1) {\n if (!adapters.isProcessRunning(pid)) return;\n await adapters.pause(100);\n }\n throw new RunnerLifecycleError(\n `Repository runner process ${pid} did not stop within 5 seconds. Local runner files were preserved.`,\n );\n};\n\nconst unregisterRepositoryRunner = async (\n metadata: RunnerInstallMetadata,\n repoDir: string,\n runnerDir: string,\n environment: NodeJS.ProcessEnv,\n adapters: RunnerLifecycleAdapters,\n): Promise<void> => {\n await runCommand(\n adapters,\n \"Checking current administrative GitHub authorization\",\n \"gh\",\n [\"auth\", \"status\", \"--hostname\", \"github.com\"],\n { cwd: repoDir, env: environment },\n );\n const response = await runCommand(\n adapters,\n \"Requesting a one-time repository runner removal token\",\n \"gh\",\n [\n \"api\",\n \"--method\",\n \"POST\",\n `repos/${metadata.repository}/actions/runners/remove-token`,\n ],\n { cwd: repoDir, env: environment },\n );\n const token = readOneTimeToken(response.stdout, \"Reading the removal token\");\n try {\n await adapters.run(\n \"./config.sh\",\n [\"remove\", \"--token\", token, \"--unattended\"],\n { cwd: runnerDir, env: repositoryRunnerEnvironment(environment) },\n );\n } catch {\n throw new RunnerLifecycleError(\n `Unregistering ${metadata.name} from GitHub failed. Local runner files were preserved; retry after restoring repository administration access.`,\n );\n }\n};\n\nexport interface RepositoryRunnerRemoveResult {\n readonly removed: true;\n readonly forced: boolean;\n readonly manualCleanup?: string;\n}\n\nexport const removeRepositoryRunner = async (\n options: { readonly repoDir: string; readonly force?: boolean },\n adapters: RunnerLifecycleAdapters = defaultAdapters,\n): Promise<RepositoryRunnerRemoveResult> => {\n const configDir = join(options.repoDir, CONFIG_DIR);\n const runnerDir = join(configDir, RUNNER_DIR);\n const maskDir = join(configDir, RUNNER_SANDBOX_MASK_DIR);\n if (!(await adapters.exists(runnerDir))) {\n throw new RunnerLifecycleError(\n `No repository runner is installed at ${runnerDir}.`,\n );\n }\n let metadata: RunnerInstallMetadata;\n try {\n metadata = await requireInstallMetadata(runnerDir, adapters);\n } catch (error) {\n if (!options.force) throw error;\n await adapters.remove(runnerDir);\n if (await adapters.exists(maskDir)) await adapters.remove(maskDir);\n return {\n removed: true,\n forced: true,\n manualCleanup:\n \"Check GitHub Settings > Actions > Runners and manually remove any orphan repository runner registration.\",\n };\n }\n const lock = await readJson<RunnerControllerLock>(\n join(runnerDir, RUNNER_CONTROLLER_LOCK),\n adapters,\n );\n if (await lockOwnsProcess(lock, adapters)) {\n await waitForProcessToStop(lock!.pid, adapters);\n }\n\n try {\n await unregisterRepositoryRunner(\n metadata,\n options.repoDir,\n runnerDir,\n adapters.environment(),\n adapters,\n );\n } catch (error) {\n if (!options.force) {\n const failure = lifecycleFailure(\"Removing the repository runner\", error);\n throw new RunnerLifecycleError(\n `${failure.message} Local runner files were preserved.`,\n );\n }\n await adapters.remove(runnerDir);\n if (await adapters.exists(maskDir)) await adapters.remove(maskDir);\n return {\n removed: true,\n forced: true,\n manualCleanup: `Remove runner ${metadata.name} from ${metadata.repository} in GitHub Settings > Actions > Runners.`,\n };\n }\n\n if (await adapters.exists(maskDir)) await adapters.remove(maskDir);\n await adapters.remove(runnerDir);\n return { removed: true, forced: false };\n};\n","import { copyIntoContainer } from \"./copyIntoContainer.js\";\n/**\n * Docker sandbox provider — wraps DockerLifecycle into a SandboxProvider.\n *\n * Usage:\n * import { docker } from \"@snappedly-tools/shipyard/sandboxes/docker\";\n * await run({ agent: codex(CODEX_MODELS.routine), sandbox: docker() });\n */\n\nimport {\n execFile,\n execFileSync,\n spawn,\n type StdioOptions,\n} from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport { Effect } from \"effect\";\nimport { startContainer, removeContainer } from \"../DockerLifecycle.js\";\nimport {\n createIsolatedSandboxProvider,\n type IsolatedSandboxProvider,\n type IsolatedCreateOptions,\n type IsolatedSandboxHandle,\n type ExecResult,\n type InteractiveExecOptions,\n} from \"../SandboxProvider.js\";\nimport type { MountConfig } from \"../MountConfig.js\";\nimport type { SelinuxLabel } from \"../mountUtils.js\";\nimport {\n defaultImageName,\n resolveUserMounts,\n assertIsolatedWorkspaceMounts,\n processFileMountParents,\n} from \"../mountUtils.js\";\nimport { MAX_TAIL_CHARS } from \"../boundedTail.js\";\nimport { collectProcessOutput } from \"../processOutput.js\";\nimport { registerShutdown } from \"../shutdownRegistry.js\";\nimport {\n REPOSITORY_RUNNER_OWNER_ENV,\n REPOSITORY_RUNNER_OWNER_LABEL,\n} from \"../RepositoryRunnerLifecycle.js\";\n\nexport interface DockerOptions {\n /** Docker image name (default: derived from repo directory name). */\n readonly imageName?: string;\n /**\n * The UID of the `agent` user inside the container image (default: host UID via `process.getuid()`, or 1000).\n *\n * Must match the UID baked into the image at build time. Used as the `--user` flag value\n * and checked against the image's configured UID in the pre-flight diagnostic.\n */\n readonly containerUid?: number;\n /**\n * The GID of the `agent` user inside the container image (default: host GID via `process.getgid()`, or 1000).\n *\n * Must match the GID baked into the image at build time. Used as the `--user` flag value.\n */\n readonly containerGid?: number;\n /**\n * SELinux volume label suffix applied to bind mounts.\n *\n * - `\"z\"` — shared label (default). No-op on non-SELinux systems.\n * - `\"Z\"` — private label; only this container can access the mount.\n * - `false` — disable labeling entirely.\n */\n readonly selinuxLabel?: SelinuxLabel;\n /**\n * Additional host directories to bind-mount into the sandbox.\n *\n * Each entry specifies a `hostPath` (tilde-expanded) and `sandboxPath`.\n * If `hostPath` does not exist, sandbox creation fails with a clear error.\n */\n readonly mounts?: readonly MountConfig[];\n /** Environment variables injected by this provider. Merged at launch time with env resolver and agent provider env. */\n readonly env?: Record<string, string>;\n /**\n * Docker network(s) to attach the container to.\n *\n * - `\"my-network\"` → `--network my-network`\n * - `[\"net1\", \"net2\"]` → `--network net1 --network net2`\n *\n * When omitted, Docker's default bridge network is used.\n */\n readonly network?: string | readonly string[];\n /**\n * Supplementary groups to add the container user to, via `--group-add`.\n *\n * Accepts group names or numeric GIDs:\n *\n * - `[\"docker\"]` → `--group-add docker`\n * - `[999]` → `--group-add 999`\n * - `[\"docker\", 999]` → `--group-add docker --group-add 999`\n *\n * Useful for granting access to a bind-mounted Docker socket (Docker-outside-of-Docker).\n * When omitted, no `--group-add` flags are added.\n */\n readonly groups?: readonly (string | number)[];\n /**\n * Host devices to expose to the container, via `--device`.\n *\n * Each entry is a full device spec in `host[:container[:permissions]]` form:\n *\n * - `[\"/dev/kvm\"]` → `--device /dev/kvm`\n * - `[\"/dev/sda:/dev/xvda:rwm\"]` → `--device /dev/sda:/dev/xvda:rwm`\n * - `[\"/dev/kvm\", \"/dev/fuse\"]` → `--device /dev/kvm --device /dev/fuse`\n *\n * When omitted, no `--device` flags are added.\n */\n readonly devices?: readonly string[];\n /**\n * Maximum number of characters of streamed `exec` output retained per stream\n * (stdout and stderr) when an `onLine` callback is supplied (default: 64KiB).\n *\n * Output is delivered live to `onLine` regardless; this only bounds the tail\n * returned in `ExecResult`, preventing a long-running agent's output from\n * overflowing V8's max string length and crashing the run.\n */\n readonly maxOutputTailChars?: number;\n /**\n * Limit the CPU resources available to the container, via `--cpus`.\n *\n * Maps directly to `docker run --cpus`. Accepts fractional values:\n *\n * - `2` → `--cpus 2` (at most 2 CPUs)\n * - `1.5` → `--cpus 1.5` (at most 1.5 CPUs)\n *\n * When omitted, no `--cpus` flag is added and the container is unconstrained.\n */\n readonly cpus?: number;\n}\n\n/**\n * Create a Docker sandbox provider.\n *\n * The returned provider creates Docker containers with isolated repository and Git storage.\n * Changes are transferred through git bundle and validated sync-out.\n */\nexport const docker = (options?: DockerOptions): IsolatedSandboxProvider => {\n const configuredImageName = options?.imageName;\n const selinuxLabel = options?.selinuxLabel ?? \"z\";\n const maxOutputTailChars = options?.maxOutputTailChars ?? MAX_TAIL_CHARS;\n const sandboxHomedir = \"/home/agent\";\n const userMounts = options?.mounts\n ? resolveUserMounts(options.mounts, sandboxHomedir)\n : [];\n assertIsolatedWorkspaceMounts(userMounts);\n // Validate file mounts and collect parent dirs to create at container start.\n // Throws at construction time if any file mount parent is outside sandboxHomedir.\n const parentDirsToCreate = processFileMountParents(\n userMounts,\n sandboxHomedir,\n );\n\n return createIsolatedSandboxProvider({\n name: \"docker\",\n env: options?.env,\n create: async (\n createOptions: IsolatedCreateOptions,\n ): Promise<IsolatedSandboxHandle> => {\n const containerName = `shipyard-${randomUUID()}`;\n\n const worktreePath = \"/home/agent/workspace\";\n\n // Repository and Git storage are container-owned. Only explicitly\n // configured mounts cross the host boundary.\n const allMounts = userMounts;\n const volumeMounts = allMounts.map((m) => ({\n hostPath: m.hostPath,\n sandboxPath: m.sandboxPath,\n readonly: m.readonly,\n }));\n\n // Resolve image name\n const imageName =\n configuredImageName ??\n defaultImageName(createOptions.hostRepoPath ?? process.cwd());\n\n const containerUid = options?.containerUid ?? process.getuid?.() ?? 1000;\n const containerGid = options?.containerGid ?? process.getgid?.() ?? 1000;\n\n // Pre-flight: verify image exists and UID matches\n await checkImageUid(imageName, containerUid);\n\n // Start container\n await Effect.runPromise(\n startContainer(\n containerName,\n imageName,\n {\n ...createOptions.env,\n HOME: \"/home/agent\",\n },\n {\n volumeMounts,\n workdir: worktreePath,\n user: `${containerUid}:${containerGid}`,\n network: options?.network,\n groups: options?.groups,\n devices: options?.devices,\n cpus: options?.cpus,\n selinuxLabel,\n labels: process.env[REPOSITORY_RUNNER_OWNER_ENV]\n ? {\n [REPOSITORY_RUNNER_OWNER_LABEL]:\n process.env[REPOSITORY_RUNNER_OWNER_ENV],\n }\n : undefined,\n },\n ),\n );\n\n // Create parent directories for file mounts and chown to the container user\n for (const dir of parentDirsToCreate) {\n await new Promise<void>((resolve, reject) => {\n execFile(\n \"docker\",\n [\n \"exec\",\n \"--user\",\n \"0:0\",\n containerName,\n \"sh\",\n \"-c\",\n `mkdir -p \"$1\" && chown \"$2\" \"$1\"`,\n \"sh\",\n dir,\n `${containerUid}:${containerGid}`,\n ],\n (error) => {\n if (error) {\n reject(\n new Error(\n `Failed to create parent directory '${dir}' in container: ${error.message}`,\n ),\n );\n } else {\n resolve();\n }\n },\n );\n });\n }\n\n // Register synchronous container cleanup via the shared shutdown registry\n // so concurrent sandboxes share a single exit/SIGINT/SIGTERM listener\n // instead of tripping Node's MaxListenersExceededWarning.\n const removeContainerSync = () => {\n try {\n execFileSync(\"docker\", [\"rm\", \"-f\", containerName], {\n stdio: \"ignore\",\n });\n } catch {\n /* best-effort */\n }\n };\n const unregisterShutdown = registerShutdown(removeContainerSync);\n\n const handle: IsolatedSandboxHandle = {\n worktreePath,\n\n exec: (\n command: string,\n opts?: {\n onLine?: (line: string) => void;\n cwd?: string;\n sudo?: boolean;\n stdin?: string;\n signal?: AbortSignal;\n maxOutputBytes?: number;\n },\n ): Promise<ExecResult> => {\n const effectiveCommand = opts?.sudo ? `sudo ${command}` : command;\n const args = [\"exec\"];\n if (opts?.stdin !== undefined) args.push(\"-i\");\n if (opts?.cwd) args.push(\"-w\", opts.cwd);\n args.push(containerName, \"sh\", \"-c\", effectiveCommand);\n\n return new Promise((resolve, reject) => {\n const proc = spawn(\"docker\", args, {\n signal: opts?.signal,\n stdio: [\n opts?.stdin !== undefined ? \"pipe\" : \"ignore\",\n \"pipe\",\n \"pipe\",\n ],\n });\n\n if (opts?.stdin !== undefined) {\n proc.stdin!.write(opts.stdin);\n proc.stdin!.end();\n }\n\n proc.on(\"error\", (error) => {\n reject(new Error(`docker exec failed: ${error.message}`));\n });\n\n collectProcessOutput(\n {\n stdout: proc.stdout!,\n stderr: proc.stderr!,\n kill: () => proc.kill(\"SIGKILL\"),\n onClose: (listener) => proc.on(\"close\", listener),\n },\n { ...opts, maxOutputTailChars },\n resolve,\n reject,\n );\n });\n },\n\n interactiveExec: (\n args: string[],\n opts: InteractiveExecOptions,\n ): Promise<{ exitCode: number }> => {\n return new Promise((resolve, reject) => {\n opts.signal?.throwIfAborted();\n const executionId = randomUUID();\n const pidFile = `/tmp/shipyard-interactive-${executionId}.pid`;\n const cancelFile = `/tmp/shipyard-interactive-${executionId}.cancel`;\n const dockerArgs = [\"exec\"];\n // Allocate a pseudo-terminal when stdin looks like a TTY\n if (\n \"isTTY\" in opts.stdin &&\n (opts.stdin as { isTTY?: boolean }).isTTY\n ) {\n dockerArgs.push(\"-it\");\n } else {\n dockerArgs.push(\"-i\");\n }\n if (opts.cwd) dockerArgs.push(\"-w\", opts.cwd);\n dockerArgs.push(\n containerName,\n \"sh\",\n \"-c\",\n 'pid_file=$1; cancel_file=$2; shift 2; command -v setsid >/dev/null 2>&1 && command -v ps >/dev/null 2>&1 && command -v awk >/dev/null 2>&1 || { printf \"%s\\\\n\" \"setsid, ps, and awk are required for cancellable interactive execution\" >&2; exit 127; }; if [ -e \"$cancel_file\" ]; then rm -f \"$pid_file\" \"$cancel_file\"; exit 130; fi; setsid \"$@\" & child=$!; printf \"%s\\\\n\" \"$child\" > \"$pid_file\"; wait \"$child\"; status=$?; rm -f \"$pid_file\" \"$cancel_file\"; exit \"$status\"',\n \"shipyard-interactive\",\n pidFile,\n cancelFile,\n ...args,\n );\n\n const proc = spawn(\"docker\", dockerArgs, {\n stdio: [opts.stdin, opts.stdout, opts.stderr] as StdioOptions,\n });\n\n let settled = false;\n let cancelling = false;\n const finish = (\n result:\n | { readonly exitCode: number }\n | { readonly error: unknown },\n ): void => {\n if (settled) return;\n settled = true;\n opts.signal?.removeEventListener(\"abort\", onAbort);\n if (\"error\" in result) reject(result.error);\n else resolve(result);\n };\n\n const onAbort = (): void => {\n if (cancelling || settled) return;\n cancelling = true;\n const cancellationScript =\n 'touch \"$1\"; attempts=0; while [ ! -s \"$2\" ] && [ \"$attempts\" -lt 50 ]; do sleep 0.1; attempts=$((attempts + 1)); done; if [ -s \"$2\" ]; then pid=$(cat \"$2\"); group_running() { ps -eo pgid=,stat= | awk -v pg=\"$pid\" \\'$1 == pg && $2 !~ /^Z/ { found=1 } END { exit found ? 0 : 1 }\\'; }; kill -TERM \"-$pid\" 2>/dev/null || true; attempts=0; while group_running && [ \"$attempts\" -lt 20 ]; do sleep 0.1; attempts=$((attempts + 1)); done; kill -KILL \"-$pid\" 2>/dev/null || true; attempts=0; while group_running && [ \"$attempts\" -lt 20 ]; do sleep 0.1; attempts=$((attempts + 1)); done; if group_running; then exit 1; fi; rm -f \"$1\" \"$2\"; fi';\n execFile(\n \"docker\",\n [\n \"exec\",\n containerName,\n \"sh\",\n \"-c\",\n cancellationScript,\n \"shipyard-cancel\",\n cancelFile,\n pidFile,\n ],\n { timeout: 7_000 },\n (error) => {\n proc.kill(\"SIGKILL\");\n if (error) {\n finish({\n error: new Error(\n `Failed to terminate interactive process in Docker sandbox: ${error.message}`,\n ),\n });\n return;\n }\n finish({\n error:\n opts.signal?.reason ??\n new Error(\"Interactive execution aborted\"),\n });\n },\n );\n };\n\n opts.signal?.addEventListener(\"abort\", onAbort, { once: true });\n if (opts.signal?.aborted) onAbort();\n\n proc.on(\"error\", (error: Error) => {\n if (!cancelling) {\n finish({\n error: new Error(`docker exec failed: ${error.message}`),\n });\n }\n });\n\n proc.on(\"close\", (code: number | null) => {\n if (cancelling) return;\n execFile(\n \"docker\",\n [\"exec\", containerName, \"rm\", \"-f\", pidFile, cancelFile],\n () => {},\n );\n finish({ exitCode: code ?? 0 });\n });\n });\n },\n\n copyIn: (hostPath, sandboxPath) =>\n copyIntoContainer(\n \"docker\",\n containerName,\n `${containerUid}:${containerGid}`,\n hostPath,\n sandboxPath,\n ),\n\n copyFileOut: (sandboxPath: string, hostPath: string): Promise<void> =>\n new Promise((resolve, reject) => {\n execFile(\n \"docker\",\n [\"cp\", `${containerName}:${sandboxPath}`, hostPath],\n (error) => {\n if (error) {\n reject(new Error(`docker cp (out) failed: ${error.message}`));\n } else {\n resolve();\n }\n },\n );\n }),\n\n close: async (): Promise<void> => {\n unregisterShutdown();\n await Effect.runPromise(removeContainer(containerName));\n },\n };\n\n return handle;\n },\n });\n};\n\n// Re-export for backwards compatibility\nexport { defaultImageName };\n\nconst checkImageUid = (imageName: string, expectedUid: number): Promise<void> =>\n new Promise<void>((resolve, reject) => {\n execFile(\n \"docker\",\n [\"image\", \"inspect\", imageName, \"--format\", \"{{.Config.User}}\"],\n (error, stdout) => {\n if (error) {\n reject(\n new Error(\n `Image '${imageName}' not found locally. Build it first with 'shipyard docker build-image'.`,\n ),\n );\n return;\n }\n const imageUser = (stdout ?? \"\").toString().trim();\n if (!imageUser) {\n // No USER directive in image — skip check\n resolve();\n return;\n }\n const uidPart = imageUser.split(\":\")[0]!;\n const imageUid = parseInt(uidPart, 10);\n if (isNaN(imageUid)) {\n // Non-numeric user (e.g. \"agent\") — can't compare, skip check\n resolve();\n return;\n }\n if (imageUid !== expectedUid) {\n reject(\n new Error(\n `UID mismatch: image '${imageName}' was built with UID ${imageUid}, ` +\n `but the expected UID is ${expectedUid}. ` +\n `Rebuild the image with 'shipyard docker build-image', ` +\n `or pass containerUid: ${imageUid} to docker() to match the image.`,\n ),\n );\n } else {\n resolve();\n }\n },\n );\n });\n"]}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { N as NoSandboxProvider } from '../SandboxProvider-XJQqEdSf.js';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* No-sandbox provider — runs the agent directly on the host with no container isolation.
|
|
5
|
-
*
|
|
6
|
-
* Usage:
|
|
7
|
-
* import { noSandbox } from "@snappedly-tools/shipyard/sandboxes/no-sandbox";
|
|
8
|
-
* await run({ agent: codex(CODEX_MODELS.routine), sandbox: noSandbox(), prompt: "..." });
|
|
9
|
-
*
|
|
10
|
-
* Accepted by `run()`, `interactive()`, and `createSandbox()`. It skips
|
|
11
|
-
* container isolation entirely and does not pass
|
|
12
|
-
* `--dangerously-skip-permissions` to the agent.
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
interface NoSandboxOptions {
|
|
16
|
-
/** Environment variables injected by this provider. Merged at launch time. */
|
|
17
|
-
readonly env?: Record<string, string>;
|
|
18
|
-
/**
|
|
19
|
-
* Maximum number of characters of streamed `exec` output retained per stream
|
|
20
|
-
* (stdout and stderr) when an `onLine` callback is supplied (default: 64KiB).
|
|
21
|
-
*
|
|
22
|
-
* Output is delivered live to `onLine` regardless; this only bounds the tail
|
|
23
|
-
* returned in `ExecResult`, preventing a long-running agent's output from
|
|
24
|
-
* overflowing V8's max string length and crashing the run.
|
|
25
|
-
*/
|
|
26
|
-
readonly maxOutputTailChars?: number;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Create a no-sandbox provider.
|
|
30
|
-
*
|
|
31
|
-
* The returned provider runs the agent directly on the host. All three
|
|
32
|
-
* branch strategies are supported (head, merge-to-head, branch),
|
|
33
|
-
* defaulting to head.
|
|
34
|
-
*/
|
|
35
|
-
declare const noSandbox: (options?: NoSandboxOptions) => NoSandboxProvider;
|
|
36
|
-
|
|
37
|
-
export { type NoSandboxOptions, noSandbox };
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"no-sandbox.js"}
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
import { I as IsolatedSandboxProvider } from '../SandboxProvider-XJQqEdSf.js';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Vercel isolated sandbox provider — wraps `@vercel/sandbox` into a SandboxProvider.
|
|
5
|
-
*
|
|
6
|
-
* Usage:
|
|
7
|
-
* import { vercel } from "@snappedly-tools/shipyard/sandboxes/vercel";
|
|
8
|
-
* await run({ agent: codex(CODEX_MODELS.routine), sandbox: vercel() });
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Options for creating a Vercel sandbox provider.
|
|
13
|
-
*
|
|
14
|
-
* All `@vercel/sandbox` `Sandbox.create()` options are accepted as pass-through,
|
|
15
|
-
* plus Shipyard-specific options for auth and branch strategy.
|
|
16
|
-
*/
|
|
17
|
-
interface VercelOptions {
|
|
18
|
-
/**
|
|
19
|
-
* Vercel access token.
|
|
20
|
-
*
|
|
21
|
-
* Falls back to the SDK's default auth behavior, which reads
|
|
22
|
-
* `VERCEL_OIDC_TOKEN` (recommended for Vercel-hosted environments) or
|
|
23
|
-
* `VERCEL_TOKEN` from the environment.
|
|
24
|
-
*/
|
|
25
|
-
readonly token?: string;
|
|
26
|
-
/**
|
|
27
|
-
* The source of the sandbox (git repo, tarball, or snapshot).
|
|
28
|
-
* Omit to start an empty sandbox.
|
|
29
|
-
*/
|
|
30
|
-
readonly source?: {
|
|
31
|
-
type: "git";
|
|
32
|
-
url: string;
|
|
33
|
-
depth?: number;
|
|
34
|
-
revision?: string;
|
|
35
|
-
username?: string;
|
|
36
|
-
password?: string;
|
|
37
|
-
} | {
|
|
38
|
-
type: "tarball";
|
|
39
|
-
url: string;
|
|
40
|
-
} | {
|
|
41
|
-
type: "snapshot";
|
|
42
|
-
snapshotId: string;
|
|
43
|
-
};
|
|
44
|
-
/** Array of port numbers to expose from the sandbox (up to 4). */
|
|
45
|
-
readonly ports?: number[];
|
|
46
|
-
/** Timeout in milliseconds before the sandbox auto-terminates. */
|
|
47
|
-
readonly timeout?: number;
|
|
48
|
-
/**
|
|
49
|
-
* Resources to allocate to the sandbox.
|
|
50
|
-
* Each vCPU gets 2048 MB of memory.
|
|
51
|
-
*/
|
|
52
|
-
readonly resources?: {
|
|
53
|
-
vcpus: number;
|
|
54
|
-
};
|
|
55
|
-
/**
|
|
56
|
-
* The runtime of the sandbox (e.g. `"node24"`, `"node22"`, `"python3.13"`).
|
|
57
|
-
* Defaults to `"node24"`.
|
|
58
|
-
*/
|
|
59
|
-
readonly runtime?: string;
|
|
60
|
-
/**
|
|
61
|
-
* Network policy for the sandbox.
|
|
62
|
-
* Defaults to full internet access if not specified.
|
|
63
|
-
*/
|
|
64
|
-
readonly networkPolicy?: Record<string, unknown>;
|
|
65
|
-
/**
|
|
66
|
-
* Vercel project ID to associate sandbox operations with.
|
|
67
|
-
*/
|
|
68
|
-
readonly projectId?: string;
|
|
69
|
-
/**
|
|
70
|
-
* Vercel team ID to associate sandbox operations with.
|
|
71
|
-
*/
|
|
72
|
-
readonly teamId?: string;
|
|
73
|
-
/**
|
|
74
|
-
* Timeout in milliseconds (alias for `timeout`, kept for discoverability).
|
|
75
|
-
*/
|
|
76
|
-
readonly timeoutMs?: number;
|
|
77
|
-
/**
|
|
78
|
-
* Sandbox template shorthand (e.g. `"node-22"`).
|
|
79
|
-
* Maps to the `runtime` option.
|
|
80
|
-
*/
|
|
81
|
-
readonly template?: string;
|
|
82
|
-
/** Environment variables injected by this provider. Merged at launch time with env resolver and agent provider env. */
|
|
83
|
-
readonly env?: Record<string, string>;
|
|
84
|
-
/**
|
|
85
|
-
* Maximum number of characters of streamed `exec` output retained per stream
|
|
86
|
-
* (stdout and stderr) when an `onLine` callback is supplied (default: 64KiB).
|
|
87
|
-
*
|
|
88
|
-
* Output is delivered live to `onLine` regardless; this only bounds the tail
|
|
89
|
-
* returned in `ExecResult`, preventing a long-running agent's output from
|
|
90
|
-
* overflowing V8's max string length and crashing the run.
|
|
91
|
-
*/
|
|
92
|
-
readonly maxOutputTailChars?: number;
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* Create a Vercel isolated sandbox provider.
|
|
96
|
-
*
|
|
97
|
-
* The returned provider creates Vercel Firecracker microVM sandboxes via
|
|
98
|
-
* the `@vercel/sandbox` SDK. Each sandbox is ephemeral — one sandbox per run.
|
|
99
|
-
*
|
|
100
|
-
* Requires `@vercel/sandbox` to be installed as a peer dependency.
|
|
101
|
-
*/
|
|
102
|
-
declare const vercel: (options?: VercelOptions) => IsolatedSandboxProvider;
|
|
103
|
-
|
|
104
|
-
export { type VercelOptions, vercel };
|