sandbox-agent 0.3.0 → 0.3.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.
@@ -1,8 +1,5 @@
1
1
  // src/spawn.ts
2
- import {
3
- assertExecutable,
4
- formatNonExecutableBinaryMessage
5
- } from "@sandbox-agent/cli-shared";
2
+ import { assertExecutable, formatNonExecutableBinaryMessage } from "@sandbox-agent/cli-shared";
6
3
  var PLATFORM_PACKAGES = {
7
4
  "darwin-arm64": "@sandbox-agent/cli-darwin-arm64",
8
5
  "darwin-x64": "@sandbox-agent/cli-darwin-x64",
@@ -18,9 +15,7 @@ async function spawnSandboxAgent(options, fetcher) {
18
15
  if (!isNodeRuntime()) {
19
16
  throw new Error("Autospawn requires a Node.js runtime.");
20
17
  }
21
- const {
22
- spawn
23
- } = await import("child_process");
18
+ const { spawn } = await import("child_process");
24
19
  const crypto = await import("crypto");
25
20
  const fs = await import("fs");
26
21
  const path = await import("path");
@@ -44,17 +39,11 @@ async function spawnSandboxAgent(options, fetcher) {
44
39
  bunInstallBlocks: [
45
40
  {
46
41
  label: "Project install",
47
- commands: [
48
- `bun pm trust ${TRUST_PACKAGES}`,
49
- "bun add sandbox-agent"
50
- ]
42
+ commands: [`bun pm trust ${TRUST_PACKAGES}`, "bun add sandbox-agent"]
51
43
  },
52
44
  {
53
45
  label: "Global install",
54
- commands: [
55
- `bun pm -g trust ${TRUST_PACKAGES}`,
56
- "bun add -g sandbox-agent"
57
- ]
46
+ commands: [`bun pm -g trust ${TRUST_PACKAGES}`, "bun add -g sandbox-agent"]
58
47
  }
59
48
  ]
60
49
  })
@@ -195,4 +184,4 @@ export {
195
184
  isNodeRuntime,
196
185
  spawnSandboxAgent
197
186
  };
198
- //# sourceMappingURL=spawn-BQVVCZX7.js.map
187
+ //# sourceMappingURL=spawn-ROM6CN74.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/spawn.ts"],"sourcesContent":["import type { ChildProcess } from \"node:child_process\";\nimport type { AddressInfo } from \"node:net\";\nimport { assertExecutable, formatNonExecutableBinaryMessage } from \"@sandbox-agent/cli-shared\";\n\nexport type SandboxAgentSpawnLogMode = \"inherit\" | \"pipe\" | \"silent\";\n\nexport type SandboxAgentSpawnOptions = {\n enabled?: boolean;\n host?: string;\n port?: number;\n token?: string;\n binaryPath?: string;\n timeoutMs?: number;\n log?: SandboxAgentSpawnLogMode;\n env?: Record<string, string>;\n};\n\nexport type SandboxAgentSpawnHandle = {\n baseUrl: string;\n token: string;\n child: ChildProcess;\n dispose: () => Promise<void>;\n};\n\nconst PLATFORM_PACKAGES: Record<string, string> = {\n \"darwin-arm64\": \"@sandbox-agent/cli-darwin-arm64\",\n \"darwin-x64\": \"@sandbox-agent/cli-darwin-x64\",\n \"linux-x64\": \"@sandbox-agent/cli-linux-x64\",\n \"linux-arm64\": \"@sandbox-agent/cli-linux-arm64\",\n \"win32-x64\": \"@sandbox-agent/cli-win32-x64\",\n};\n\nconst TRUST_PACKAGES =\n \"@sandbox-agent/cli-linux-x64 @sandbox-agent/cli-linux-arm64 @sandbox-agent/cli-darwin-arm64 @sandbox-agent/cli-darwin-x64 @sandbox-agent/cli-win32-x64\";\n\nexport function isNodeRuntime(): boolean {\n return typeof process !== \"undefined\" && !!process.versions?.node;\n}\n\nexport async function spawnSandboxAgent(options: SandboxAgentSpawnOptions, fetcher?: typeof fetch): Promise<SandboxAgentSpawnHandle> {\n if (!isNodeRuntime()) {\n throw new Error(\"Autospawn requires a Node.js runtime.\");\n }\n\n const { spawn } = await import(\"node:child_process\");\n const crypto = await import(\"node:crypto\");\n const fs = await import(\"node:fs\");\n const path = await import(\"node:path\");\n const net = await import(\"node:net\");\n const { createRequire } = await import(\"node:module\");\n\n const bindHost = options.host ?? \"127.0.0.1\";\n const port = options.port ?? (await getFreePort(net, bindHost));\n const connectHost = bindHost === \"0.0.0.0\" || bindHost === \"::\" ? \"127.0.0.1\" : bindHost;\n const token = options.token ?? crypto.randomBytes(24).toString(\"hex\");\n const timeoutMs = options.timeoutMs ?? 15_000;\n const logMode: SandboxAgentSpawnLogMode = options.log ?? \"inherit\";\n\n const binaryPath =\n options.binaryPath ??\n resolveBinaryFromEnv(fs, path) ??\n resolveBinaryFromCliPackage(createRequire(import.meta.url), path, fs) ??\n resolveBinaryFromPath(fs, path);\n\n if (!binaryPath) {\n throw new Error(\"sandbox-agent binary not found. Install @sandbox-agent/cli or set SANDBOX_AGENT_BIN.\");\n }\n\n if (!assertExecutable(binaryPath, fs)) {\n throw new Error(\n formatNonExecutableBinaryMessage({\n binPath: binaryPath,\n trustPackages: TRUST_PACKAGES,\n bunInstallBlocks: [\n {\n label: \"Project install\",\n commands: [`bun pm trust ${TRUST_PACKAGES}`, \"bun add sandbox-agent\"],\n },\n {\n label: \"Global install\",\n commands: [`bun pm -g trust ${TRUST_PACKAGES}`, \"bun add -g sandbox-agent\"],\n },\n ],\n }),\n );\n }\n\n const stdio = logMode === \"inherit\" ? \"inherit\" : logMode === \"silent\" ? \"ignore\" : \"pipe\";\n const args = [\"server\", \"--host\", bindHost, \"--port\", String(port), \"--token\", token];\n const child = spawn(binaryPath, args, {\n stdio,\n env: {\n ...process.env,\n ...(options.env ?? {}),\n },\n });\n const cleanup = registerProcessCleanup(child);\n\n const baseUrl = `http://${connectHost}:${port}`;\n const ready = waitForHealth(baseUrl, fetcher ?? globalThis.fetch, timeoutMs, child, token);\n\n await ready;\n\n const dispose = async () => {\n if (child.exitCode !== null) {\n cleanup.dispose();\n return;\n }\n child.kill(\"SIGTERM\");\n const exited = await waitForExit(child, 5_000);\n if (!exited) {\n child.kill(\"SIGKILL\");\n }\n cleanup.dispose();\n };\n\n return { baseUrl, token, child, dispose };\n}\n\nfunction resolveBinaryFromEnv(fs: typeof import(\"node:fs\"), path: typeof import(\"node:path\")): string | null {\n const value = process.env.SANDBOX_AGENT_BIN;\n if (!value) {\n return null;\n }\n const resolved = path.resolve(value);\n if (fs.existsSync(resolved)) {\n return resolved;\n }\n return null;\n}\n\nfunction resolveBinaryFromCliPackage(\n require: ReturnType<typeof import(\"node:module\").createRequire>,\n path: typeof import(\"node:path\"),\n fs: typeof import(\"node:fs\"),\n): string | null {\n const key = `${process.platform}-${process.arch}`;\n const pkg = PLATFORM_PACKAGES[key];\n if (!pkg) {\n return null;\n }\n try {\n const pkgPath = require.resolve(`${pkg}/package.json`);\n const bin = process.platform === \"win32\" ? \"sandbox-agent.exe\" : \"sandbox-agent\";\n const resolved = path.join(path.dirname(pkgPath), \"bin\", bin);\n return fs.existsSync(resolved) ? resolved : null;\n } catch {\n return null;\n }\n}\n\nfunction resolveBinaryFromPath(fs: typeof import(\"node:fs\"), path: typeof import(\"node:path\")): string | null {\n const pathEnv = process.env.PATH ?? \"\";\n const separator = process.platform === \"win32\" ? \";\" : \":\";\n const candidates = pathEnv.split(separator).filter(Boolean);\n const bin = process.platform === \"win32\" ? \"sandbox-agent.exe\" : \"sandbox-agent\";\n for (const dir of candidates) {\n const resolved = path.join(dir, bin);\n if (fs.existsSync(resolved)) {\n return resolved;\n }\n }\n return null;\n}\n\nasync function getFreePort(net: typeof import(\"node:net\"), host: string): Promise<number> {\n return new Promise((resolve, reject) => {\n const server = net.createServer();\n server.unref();\n server.on(\"error\", reject);\n server.listen(0, host, () => {\n const address = server.address() as AddressInfo;\n server.close(() => resolve(address.port));\n });\n });\n}\n\nasync function waitForHealth(baseUrl: string, fetcher: typeof fetch | undefined, timeoutMs: number, child: ChildProcess, token: string): Promise<void> {\n if (!fetcher) {\n throw new Error(\"Fetch API is not available; provide a fetch implementation.\");\n }\n const start = Date.now();\n let lastError: string | undefined;\n\n while (Date.now() - start < timeoutMs) {\n if (child.exitCode !== null) {\n throw new Error(\"sandbox-agent exited before becoming healthy.\");\n }\n try {\n const response = await fetcher(`${baseUrl}/v1/health`, {\n headers: { Authorization: `Bearer ${token}` },\n });\n if (response.ok) {\n return;\n }\n lastError = `status ${response.status}`;\n } catch (err) {\n lastError = err instanceof Error ? err.message : String(err);\n }\n await new Promise((resolve) => setTimeout(resolve, 200));\n }\n\n throw new Error(`Timed out waiting for sandbox-agent health (${lastError ?? \"unknown error\"}).`);\n}\n\nasync function waitForExit(child: ChildProcess, timeoutMs: number): Promise<boolean> {\n if (child.exitCode !== null) {\n return true;\n }\n return new Promise((resolve) => {\n const timer = setTimeout(() => resolve(false), timeoutMs);\n child.once(\"exit\", () => {\n clearTimeout(timer);\n resolve(true);\n });\n });\n}\n\nfunction registerProcessCleanup(child: ChildProcess): { dispose: () => void } {\n const handler = () => {\n if (child.exitCode === null) {\n child.kill(\"SIGTERM\");\n }\n };\n\n process.once(\"exit\", handler);\n process.once(\"SIGINT\", handler);\n process.once(\"SIGTERM\", handler);\n\n return {\n dispose: () => {\n process.off(\"exit\", handler);\n process.off(\"SIGINT\", handler);\n process.off(\"SIGTERM\", handler);\n },\n };\n}\n"],"mappings":"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","names":["require"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sandbox-agent",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "Universal API for automatic coding agents in sandboxes. Supports Claude Code, Codex, OpenCode, and Amp.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -17,8 +17,8 @@
17
17
  }
18
18
  },
19
19
  "dependencies": {
20
- "acp-http-client": "0.3.0",
21
- "@sandbox-agent/cli-shared": "0.3.0"
20
+ "@sandbox-agent/cli-shared": "0.3.2",
21
+ "acp-http-client": "0.3.2"
22
22
  },
23
23
  "files": [
24
24
  "dist"
@@ -33,7 +33,7 @@
33
33
  "ws": "^8.19.0"
34
34
  },
35
35
  "optionalDependencies": {
36
- "@sandbox-agent/cli": "0.3.0"
36
+ "@sandbox-agent/cli": "0.3.2"
37
37
  },
38
38
  "scripts": {
39
39
  "generate:openapi": "SANDBOX_AGENT_SKIP_INSPECTOR=1 cargo run -p sandbox-agent-openapi-gen -- --out ../../docs/openapi.json",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/spawn.ts"],"sourcesContent":["import type { ChildProcess } from \"node:child_process\";\nimport type { AddressInfo } from \"node:net\";\nimport {\n assertExecutable,\n formatNonExecutableBinaryMessage,\n} from \"@sandbox-agent/cli-shared\";\n\nexport type SandboxAgentSpawnLogMode = \"inherit\" | \"pipe\" | \"silent\";\n\nexport type SandboxAgentSpawnOptions = {\n enabled?: boolean;\n host?: string;\n port?: number;\n token?: string;\n binaryPath?: string;\n timeoutMs?: number;\n log?: SandboxAgentSpawnLogMode;\n env?: Record<string, string>;\n};\n\nexport type SandboxAgentSpawnHandle = {\n baseUrl: string;\n token: string;\n child: ChildProcess;\n dispose: () => Promise<void>;\n};\n\nconst PLATFORM_PACKAGES: Record<string, string> = {\n \"darwin-arm64\": \"@sandbox-agent/cli-darwin-arm64\",\n \"darwin-x64\": \"@sandbox-agent/cli-darwin-x64\",\n \"linux-x64\": \"@sandbox-agent/cli-linux-x64\",\n \"linux-arm64\": \"@sandbox-agent/cli-linux-arm64\",\n \"win32-x64\": \"@sandbox-agent/cli-win32-x64\",\n};\n\nconst TRUST_PACKAGES =\n \"@sandbox-agent/cli-linux-x64 @sandbox-agent/cli-linux-arm64 @sandbox-agent/cli-darwin-arm64 @sandbox-agent/cli-darwin-x64 @sandbox-agent/cli-win32-x64\";\n\nexport function isNodeRuntime(): boolean {\n return typeof process !== \"undefined\" && !!process.versions?.node;\n}\n\nexport async function spawnSandboxAgent(\n options: SandboxAgentSpawnOptions,\n fetcher?: typeof fetch,\n): Promise<SandboxAgentSpawnHandle> {\n if (!isNodeRuntime()) {\n throw new Error(\"Autospawn requires a Node.js runtime.\");\n }\n\n const {\n spawn,\n } = await import(\"node:child_process\");\n const crypto = await import(\"node:crypto\");\n const fs = await import(\"node:fs\");\n const path = await import(\"node:path\");\n const net = await import(\"node:net\");\n const { createRequire } = await import(\"node:module\");\n\n const bindHost = options.host ?? \"127.0.0.1\";\n const port = options.port ?? (await getFreePort(net, bindHost));\n const connectHost = bindHost === \"0.0.0.0\" || bindHost === \"::\" ? \"127.0.0.1\" : bindHost;\n const token = options.token ?? crypto.randomBytes(24).toString(\"hex\");\n const timeoutMs = options.timeoutMs ?? 15_000;\n const logMode: SandboxAgentSpawnLogMode = options.log ?? \"inherit\";\n\n const binaryPath =\n options.binaryPath ??\n resolveBinaryFromEnv(fs, path) ??\n resolveBinaryFromCliPackage(createRequire(import.meta.url), path, fs) ??\n resolveBinaryFromPath(fs, path);\n\n if (!binaryPath) {\n throw new Error(\"sandbox-agent binary not found. Install @sandbox-agent/cli or set SANDBOX_AGENT_BIN.\");\n }\n\n if (!assertExecutable(binaryPath, fs)) {\n throw new Error(\n formatNonExecutableBinaryMessage({\n binPath: binaryPath,\n trustPackages: TRUST_PACKAGES,\n bunInstallBlocks: [\n {\n label: \"Project install\",\n commands: [\n `bun pm trust ${TRUST_PACKAGES}`,\n \"bun add sandbox-agent\",\n ],\n },\n {\n label: \"Global install\",\n commands: [\n `bun pm -g trust ${TRUST_PACKAGES}`,\n \"bun add -g sandbox-agent\",\n ],\n },\n ],\n }),\n );\n }\n\n const stdio = logMode === \"inherit\" ? \"inherit\" : logMode === \"silent\" ? \"ignore\" : \"pipe\";\n const args = [\"server\", \"--host\", bindHost, \"--port\", String(port), \"--token\", token];\n const child = spawn(binaryPath, args, {\n stdio,\n env: {\n ...process.env,\n ...(options.env ?? {}),\n },\n });\n const cleanup = registerProcessCleanup(child);\n\n const baseUrl = `http://${connectHost}:${port}`;\n const ready = waitForHealth(baseUrl, fetcher ?? globalThis.fetch, timeoutMs, child, token);\n\n await ready;\n\n const dispose = async () => {\n if (child.exitCode !== null) {\n cleanup.dispose();\n return;\n }\n child.kill(\"SIGTERM\");\n const exited = await waitForExit(child, 5_000);\n if (!exited) {\n child.kill(\"SIGKILL\");\n }\n cleanup.dispose();\n };\n\n return { baseUrl, token, child, dispose };\n}\n\nfunction resolveBinaryFromEnv(fs: typeof import(\"node:fs\"), path: typeof import(\"node:path\")): string | null {\n const value = process.env.SANDBOX_AGENT_BIN;\n if (!value) {\n return null;\n }\n const resolved = path.resolve(value);\n if (fs.existsSync(resolved)) {\n return resolved;\n }\n return null;\n}\n\nfunction resolveBinaryFromCliPackage(\n require: ReturnType<typeof import(\"node:module\").createRequire>,\n path: typeof import(\"node:path\"),\n fs: typeof import(\"node:fs\"),\n): string | null {\n const key = `${process.platform}-${process.arch}`;\n const pkg = PLATFORM_PACKAGES[key];\n if (!pkg) {\n return null;\n }\n try {\n const pkgPath = require.resolve(`${pkg}/package.json`);\n const bin = process.platform === \"win32\" ? \"sandbox-agent.exe\" : \"sandbox-agent\";\n const resolved = path.join(path.dirname(pkgPath), \"bin\", bin);\n return fs.existsSync(resolved) ? resolved : null;\n } catch {\n return null;\n }\n}\n\nfunction resolveBinaryFromPath(fs: typeof import(\"node:fs\"), path: typeof import(\"node:path\")): string | null {\n const pathEnv = process.env.PATH ?? \"\";\n const separator = process.platform === \"win32\" ? \";\" : \":\";\n const candidates = pathEnv.split(separator).filter(Boolean);\n const bin = process.platform === \"win32\" ? \"sandbox-agent.exe\" : \"sandbox-agent\";\n for (const dir of candidates) {\n const resolved = path.join(dir, bin);\n if (fs.existsSync(resolved)) {\n return resolved;\n }\n }\n return null;\n}\n\nasync function getFreePort(net: typeof import(\"node:net\"), host: string): Promise<number> {\n return new Promise((resolve, reject) => {\n const server = net.createServer();\n server.unref();\n server.on(\"error\", reject);\n server.listen(0, host, () => {\n const address = server.address() as AddressInfo;\n server.close(() => resolve(address.port));\n });\n });\n}\n\nasync function waitForHealth(\n baseUrl: string,\n fetcher: typeof fetch | undefined,\n timeoutMs: number,\n child: ChildProcess,\n token: string,\n): Promise<void> {\n if (!fetcher) {\n throw new Error(\"Fetch API is not available; provide a fetch implementation.\");\n }\n const start = Date.now();\n let lastError: string | undefined;\n\n while (Date.now() - start < timeoutMs) {\n if (child.exitCode !== null) {\n throw new Error(\"sandbox-agent exited before becoming healthy.\");\n }\n try {\n const response = await fetcher(`${baseUrl}/v1/health`, {\n headers: { Authorization: `Bearer ${token}` },\n });\n if (response.ok) {\n return;\n }\n lastError = `status ${response.status}`;\n } catch (err) {\n lastError = err instanceof Error ? err.message : String(err);\n }\n await new Promise((resolve) => setTimeout(resolve, 200));\n }\n\n throw new Error(`Timed out waiting for sandbox-agent health (${lastError ?? \"unknown error\"}).`);\n}\n\nasync function waitForExit(child: ChildProcess, timeoutMs: number): Promise<boolean> {\n if (child.exitCode !== null) {\n return true;\n }\n return new Promise((resolve) => {\n const timer = setTimeout(() => resolve(false), timeoutMs);\n child.once(\"exit\", () => {\n clearTimeout(timer);\n resolve(true);\n });\n });\n}\n\nfunction registerProcessCleanup(child: ChildProcess): { dispose: () => void } {\n const handler = () => {\n if (child.exitCode === null) {\n child.kill(\"SIGTERM\");\n }\n };\n\n process.once(\"exit\", handler);\n process.once(\"SIGINT\", handler);\n process.once(\"SIGTERM\", handler);\n\n return {\n dispose: () => {\n process.off(\"exit\", handler);\n process.off(\"SIGINT\", handler);\n process.off(\"SIGTERM\", handler);\n },\n };\n}\n"],"mappings":"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","names":["require"]}