sandbox-agent 0.0.1 → 0.1.0-test.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,239 @@
1
+ // src/client.ts
2
+ var API_PREFIX = "/v1";
3
+ var SandboxAgentError = class extends Error {
4
+ status;
5
+ problem;
6
+ response;
7
+ constructor(status, problem, response) {
8
+ super(problem?.title ?? `Request failed with status ${status}`);
9
+ this.name = "SandboxAgentError";
10
+ this.status = status;
11
+ this.problem = problem;
12
+ this.response = response;
13
+ }
14
+ };
15
+ var SandboxAgent = class _SandboxAgent {
16
+ baseUrl;
17
+ token;
18
+ fetcher;
19
+ defaultHeaders;
20
+ spawnHandle;
21
+ constructor(options) {
22
+ this.baseUrl = options.baseUrl.replace(/\/$/, "");
23
+ this.token = options.token;
24
+ this.fetcher = options.fetch ?? globalThis.fetch;
25
+ this.defaultHeaders = options.headers;
26
+ if (!this.fetcher) {
27
+ throw new Error("Fetch API is not available; provide a fetch implementation.");
28
+ }
29
+ }
30
+ static async connect(options) {
31
+ return new _SandboxAgent(options);
32
+ }
33
+ static async start(options = {}) {
34
+ const spawnOptions = normalizeSpawnOptions(options.spawn, true);
35
+ if (!spawnOptions.enabled) {
36
+ throw new Error("SandboxAgent.start requires spawn to be enabled.");
37
+ }
38
+ const { spawnSandboxAgent } = await import("./spawn-BT4YX7BC.js");
39
+ const handle = await spawnSandboxAgent(spawnOptions, options.fetch ?? globalThis.fetch);
40
+ const client = new _SandboxAgent({
41
+ baseUrl: handle.baseUrl,
42
+ token: handle.token,
43
+ fetch: options.fetch,
44
+ headers: options.headers
45
+ });
46
+ client.spawnHandle = handle;
47
+ return client;
48
+ }
49
+ async listAgents() {
50
+ return this.requestJson("GET", `${API_PREFIX}/agents`);
51
+ }
52
+ async getHealth() {
53
+ return this.requestJson("GET", `${API_PREFIX}/health`);
54
+ }
55
+ async installAgent(agent, request = {}) {
56
+ await this.requestJson("POST", `${API_PREFIX}/agents/${encodeURIComponent(agent)}/install`, {
57
+ body: request
58
+ });
59
+ }
60
+ async getAgentModes(agent) {
61
+ return this.requestJson("GET", `${API_PREFIX}/agents/${encodeURIComponent(agent)}/modes`);
62
+ }
63
+ async createSession(sessionId, request) {
64
+ return this.requestJson("POST", `${API_PREFIX}/sessions/${encodeURIComponent(sessionId)}`, {
65
+ body: request
66
+ });
67
+ }
68
+ async listSessions() {
69
+ return this.requestJson("GET", `${API_PREFIX}/sessions`);
70
+ }
71
+ async postMessage(sessionId, request) {
72
+ await this.requestJson("POST", `${API_PREFIX}/sessions/${encodeURIComponent(sessionId)}/messages`, {
73
+ body: request
74
+ });
75
+ }
76
+ async getEvents(sessionId, query) {
77
+ return this.requestJson("GET", `${API_PREFIX}/sessions/${encodeURIComponent(sessionId)}/events`, {
78
+ query
79
+ });
80
+ }
81
+ async getEventsSse(sessionId, query, signal) {
82
+ return this.requestRaw("GET", `${API_PREFIX}/sessions/${encodeURIComponent(sessionId)}/events/sse`, {
83
+ query,
84
+ accept: "text/event-stream",
85
+ signal
86
+ });
87
+ }
88
+ async postMessageStream(sessionId, request, query, signal) {
89
+ return this.requestRaw("POST", `${API_PREFIX}/sessions/${encodeURIComponent(sessionId)}/messages/stream`, {
90
+ query,
91
+ body: request,
92
+ accept: "text/event-stream",
93
+ signal
94
+ });
95
+ }
96
+ async *streamEvents(sessionId, query, signal) {
97
+ const response = await this.getEventsSse(sessionId, query, signal);
98
+ yield* this.parseSseStream(response);
99
+ }
100
+ async *streamTurn(sessionId, request, query, signal) {
101
+ const response = await this.postMessageStream(sessionId, request, query, signal);
102
+ yield* this.parseSseStream(response);
103
+ }
104
+ async replyQuestion(sessionId, questionId, request) {
105
+ await this.requestJson(
106
+ "POST",
107
+ `${API_PREFIX}/sessions/${encodeURIComponent(sessionId)}/questions/${encodeURIComponent(questionId)}/reply`,
108
+ { body: request }
109
+ );
110
+ }
111
+ async rejectQuestion(sessionId, questionId) {
112
+ await this.requestJson(
113
+ "POST",
114
+ `${API_PREFIX}/sessions/${encodeURIComponent(sessionId)}/questions/${encodeURIComponent(questionId)}/reject`
115
+ );
116
+ }
117
+ async replyPermission(sessionId, permissionId, request) {
118
+ await this.requestJson(
119
+ "POST",
120
+ `${API_PREFIX}/sessions/${encodeURIComponent(sessionId)}/permissions/${encodeURIComponent(permissionId)}/reply`,
121
+ { body: request }
122
+ );
123
+ }
124
+ async terminateSession(sessionId) {
125
+ await this.requestJson("POST", `${API_PREFIX}/sessions/${encodeURIComponent(sessionId)}/terminate`);
126
+ }
127
+ async dispose() {
128
+ if (this.spawnHandle) {
129
+ await this.spawnHandle.dispose();
130
+ this.spawnHandle = void 0;
131
+ }
132
+ }
133
+ async requestJson(method, path, options = {}) {
134
+ const response = await this.requestRaw(method, path, {
135
+ query: options.query,
136
+ body: options.body,
137
+ headers: options.headers,
138
+ accept: options.accept ?? "application/json"
139
+ });
140
+ if (response.status === 204) {
141
+ return void 0;
142
+ }
143
+ const text = await response.text();
144
+ if (!text) {
145
+ return void 0;
146
+ }
147
+ return JSON.parse(text);
148
+ }
149
+ async requestRaw(method, path, options = {}) {
150
+ const url = this.buildUrl(path, options.query);
151
+ const headers = new Headers(this.defaultHeaders ?? void 0);
152
+ if (this.token) {
153
+ headers.set("Authorization", `Bearer ${this.token}`);
154
+ }
155
+ if (options.accept) {
156
+ headers.set("Accept", options.accept);
157
+ }
158
+ const init = { method, headers, signal: options.signal };
159
+ if (options.body !== void 0) {
160
+ headers.set("Content-Type", "application/json");
161
+ init.body = JSON.stringify(options.body);
162
+ }
163
+ if (options.headers) {
164
+ const extra = new Headers(options.headers);
165
+ extra.forEach((value, key) => headers.set(key, value));
166
+ }
167
+ const response = await this.fetcher(url, init);
168
+ if (!response.ok) {
169
+ const problem = await this.readProblem(response);
170
+ throw new SandboxAgentError(response.status, problem, response);
171
+ }
172
+ return response;
173
+ }
174
+ buildUrl(path, query) {
175
+ const url = new URL(`${this.baseUrl}${path}`);
176
+ if (query) {
177
+ Object.entries(query).forEach(([key, value]) => {
178
+ if (value === void 0 || value === null) {
179
+ return;
180
+ }
181
+ url.searchParams.set(key, String(value));
182
+ });
183
+ }
184
+ return url.toString();
185
+ }
186
+ async readProblem(response) {
187
+ try {
188
+ const text = await response.clone().text();
189
+ if (!text) {
190
+ return void 0;
191
+ }
192
+ return JSON.parse(text);
193
+ } catch {
194
+ return void 0;
195
+ }
196
+ }
197
+ async *parseSseStream(response) {
198
+ if (!response.body) {
199
+ throw new Error("SSE stream is not readable in this environment.");
200
+ }
201
+ const reader = response.body.getReader();
202
+ const decoder = new TextDecoder();
203
+ let buffer = "";
204
+ while (true) {
205
+ const { done, value } = await reader.read();
206
+ if (done) {
207
+ break;
208
+ }
209
+ buffer += decoder.decode(value, { stream: true }).replace(/\r\n/g, "\n");
210
+ let index = buffer.indexOf("\n\n");
211
+ while (index !== -1) {
212
+ const chunk = buffer.slice(0, index);
213
+ buffer = buffer.slice(index + 2);
214
+ const dataLines = chunk.split("\n").filter((line) => line.startsWith("data:"));
215
+ if (dataLines.length > 0) {
216
+ const payload = dataLines.map((line) => line.slice(5).trim()).join("\n");
217
+ if (payload) {
218
+ yield JSON.parse(payload);
219
+ }
220
+ }
221
+ index = buffer.indexOf("\n\n");
222
+ }
223
+ }
224
+ }
225
+ };
226
+ var normalizeSpawnOptions = (spawn, defaultEnabled) => {
227
+ if (typeof spawn === "boolean") {
228
+ return { enabled: spawn };
229
+ }
230
+ if (spawn) {
231
+ return { enabled: spawn.enabled ?? defaultEnabled, ...spawn };
232
+ }
233
+ return { enabled: defaultEnabled };
234
+ };
235
+ export {
236
+ SandboxAgent,
237
+ SandboxAgentError
238
+ };
239
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/client.ts"],"sourcesContent":["import type { SandboxAgentSpawnHandle, SandboxAgentSpawnOptions } from \"./spawn.ts\";\nimport type {\n AgentInstallRequest,\n AgentListResponse,\n AgentModesResponse,\n CreateSessionRequest,\n CreateSessionResponse,\n EventsQuery,\n EventsResponse,\n HealthResponse,\n MessageRequest,\n PermissionReplyRequest,\n ProblemDetails,\n QuestionReplyRequest,\n SessionListResponse,\n TurnStreamQuery,\n UniversalEvent,\n} from \"./types.ts\";\n\nconst API_PREFIX = \"/v1\";\n\nexport interface SandboxAgentConnectOptions {\n baseUrl: string;\n token?: string;\n fetch?: typeof fetch;\n headers?: HeadersInit;\n}\n\nexport interface SandboxAgentStartOptions {\n spawn?: SandboxAgentSpawnOptions | boolean;\n fetch?: typeof fetch;\n headers?: HeadersInit;\n}\n\nexport class SandboxAgentError extends Error {\n readonly status: number;\n readonly problem?: ProblemDetails;\n readonly response: Response;\n\n constructor(status: number, problem: ProblemDetails | undefined, response: Response) {\n super(problem?.title ?? `Request failed with status ${status}`);\n this.name = \"SandboxAgentError\";\n this.status = status;\n this.problem = problem;\n this.response = response;\n }\n}\n\ntype QueryValue = string | number | boolean | null | undefined;\n\ntype RequestOptions = {\n query?: Record<string, QueryValue>;\n body?: unknown;\n headers?: HeadersInit;\n accept?: string;\n signal?: AbortSignal;\n};\n\nexport class SandboxAgent {\n private readonly baseUrl: string;\n private readonly token?: string;\n private readonly fetcher: typeof fetch;\n private readonly defaultHeaders?: HeadersInit;\n private spawnHandle?: SandboxAgentSpawnHandle;\n\n private constructor(options: SandboxAgentConnectOptions) {\n this.baseUrl = options.baseUrl.replace(/\\/$/, \"\");\n this.token = options.token;\n this.fetcher = options.fetch ?? globalThis.fetch;\n this.defaultHeaders = options.headers;\n\n if (!this.fetcher) {\n throw new Error(\"Fetch API is not available; provide a fetch implementation.\");\n }\n }\n\n static async connect(options: SandboxAgentConnectOptions): Promise<SandboxAgent> {\n return new SandboxAgent(options);\n }\n\n static async start(options: SandboxAgentStartOptions = {}): Promise<SandboxAgent> {\n const spawnOptions = normalizeSpawnOptions(options.spawn, true);\n if (!spawnOptions.enabled) {\n throw new Error(\"SandboxAgent.start requires spawn to be enabled.\");\n }\n const { spawnSandboxAgent } = await import(\"./spawn.js\");\n const handle = await spawnSandboxAgent(spawnOptions, options.fetch ?? globalThis.fetch);\n const client = new SandboxAgent({\n baseUrl: handle.baseUrl,\n token: handle.token,\n fetch: options.fetch,\n headers: options.headers,\n });\n client.spawnHandle = handle;\n return client;\n }\n\n async listAgents(): Promise<AgentListResponse> {\n return this.requestJson(\"GET\", `${API_PREFIX}/agents`);\n }\n\n async getHealth(): Promise<HealthResponse> {\n return this.requestJson(\"GET\", `${API_PREFIX}/health`);\n }\n\n async installAgent(agent: string, request: AgentInstallRequest = {}): Promise<void> {\n await this.requestJson(\"POST\", `${API_PREFIX}/agents/${encodeURIComponent(agent)}/install`, {\n body: request,\n });\n }\n\n async getAgentModes(agent: string): Promise<AgentModesResponse> {\n return this.requestJson(\"GET\", `${API_PREFIX}/agents/${encodeURIComponent(agent)}/modes`);\n }\n\n async createSession(sessionId: string, request: CreateSessionRequest): Promise<CreateSessionResponse> {\n return this.requestJson(\"POST\", `${API_PREFIX}/sessions/${encodeURIComponent(sessionId)}`, {\n body: request,\n });\n }\n\n async listSessions(): Promise<SessionListResponse> {\n return this.requestJson(\"GET\", `${API_PREFIX}/sessions`);\n }\n\n async postMessage(sessionId: string, request: MessageRequest): Promise<void> {\n await this.requestJson(\"POST\", `${API_PREFIX}/sessions/${encodeURIComponent(sessionId)}/messages`, {\n body: request,\n });\n }\n\n async getEvents(sessionId: string, query?: EventsQuery): Promise<EventsResponse> {\n return this.requestJson(\"GET\", `${API_PREFIX}/sessions/${encodeURIComponent(sessionId)}/events`, {\n query,\n });\n }\n\n async getEventsSse(sessionId: string, query?: EventsQuery, signal?: AbortSignal): Promise<Response> {\n return this.requestRaw(\"GET\", `${API_PREFIX}/sessions/${encodeURIComponent(sessionId)}/events/sse`, {\n query,\n accept: \"text/event-stream\",\n signal,\n });\n }\n\n async postMessageStream(\n sessionId: string,\n request: MessageRequest,\n query?: TurnStreamQuery,\n signal?: AbortSignal,\n ): Promise<Response> {\n return this.requestRaw(\"POST\", `${API_PREFIX}/sessions/${encodeURIComponent(sessionId)}/messages/stream`, {\n query,\n body: request,\n accept: \"text/event-stream\",\n signal,\n });\n }\n\n async *streamEvents(\n sessionId: string,\n query?: EventsQuery,\n signal?: AbortSignal,\n ): AsyncGenerator<UniversalEvent, void, void> {\n const response = await this.getEventsSse(sessionId, query, signal);\n yield* this.parseSseStream(response);\n }\n\n async *streamTurn(\n sessionId: string,\n request: MessageRequest,\n query?: TurnStreamQuery,\n signal?: AbortSignal,\n ): AsyncGenerator<UniversalEvent, void, void> {\n const response = await this.postMessageStream(sessionId, request, query, signal);\n yield* this.parseSseStream(response);\n }\n\n async replyQuestion(\n sessionId: string,\n questionId: string,\n request: QuestionReplyRequest,\n ): Promise<void> {\n await this.requestJson(\n \"POST\",\n `${API_PREFIX}/sessions/${encodeURIComponent(sessionId)}/questions/${encodeURIComponent(questionId)}/reply`,\n { body: request },\n );\n }\n\n async rejectQuestion(sessionId: string, questionId: string): Promise<void> {\n await this.requestJson(\n \"POST\",\n `${API_PREFIX}/sessions/${encodeURIComponent(sessionId)}/questions/${encodeURIComponent(questionId)}/reject`,\n );\n }\n\n async replyPermission(\n sessionId: string,\n permissionId: string,\n request: PermissionReplyRequest,\n ): Promise<void> {\n await this.requestJson(\n \"POST\",\n `${API_PREFIX}/sessions/${encodeURIComponent(sessionId)}/permissions/${encodeURIComponent(permissionId)}/reply`,\n { body: request },\n );\n }\n\n async terminateSession(sessionId: string): Promise<void> {\n await this.requestJson(\"POST\", `${API_PREFIX}/sessions/${encodeURIComponent(sessionId)}/terminate`);\n }\n\n async dispose(): Promise<void> {\n if (this.spawnHandle) {\n await this.spawnHandle.dispose();\n this.spawnHandle = undefined;\n }\n }\n\n private async requestJson<T>(method: string, path: string, options: RequestOptions = {}): Promise<T> {\n const response = await this.requestRaw(method, path, {\n query: options.query,\n body: options.body,\n headers: options.headers,\n accept: options.accept ?? \"application/json\",\n });\n\n if (response.status === 204) {\n return undefined as T;\n }\n\n const text = await response.text();\n if (!text) {\n return undefined as T;\n }\n\n return JSON.parse(text) as T;\n }\n\n private async requestRaw(method: string, path: string, options: RequestOptions = {}): Promise<Response> {\n const url = this.buildUrl(path, options.query);\n const headers = new Headers(this.defaultHeaders ?? undefined);\n\n if (this.token) {\n headers.set(\"Authorization\", `Bearer ${this.token}`);\n }\n\n if (options.accept) {\n headers.set(\"Accept\", options.accept);\n }\n\n const init: RequestInit = { method, headers, signal: options.signal };\n if (options.body !== undefined) {\n headers.set(\"Content-Type\", \"application/json\");\n init.body = JSON.stringify(options.body);\n }\n\n if (options.headers) {\n const extra = new Headers(options.headers);\n extra.forEach((value, key) => headers.set(key, value));\n }\n\n const response = await this.fetcher(url, init);\n if (!response.ok) {\n const problem = await this.readProblem(response);\n throw new SandboxAgentError(response.status, problem, response);\n }\n\n return response;\n }\n\n private buildUrl(path: string, query?: Record<string, QueryValue>): string {\n const url = new URL(`${this.baseUrl}${path}`);\n if (query) {\n Object.entries(query).forEach(([key, value]) => {\n if (value === undefined || value === null) {\n return;\n }\n url.searchParams.set(key, String(value));\n });\n }\n return url.toString();\n }\n\n private async readProblem(response: Response): Promise<ProblemDetails | undefined> {\n try {\n const text = await response.clone().text();\n if (!text) {\n return undefined;\n }\n return JSON.parse(text) as ProblemDetails;\n } catch {\n return undefined;\n }\n }\n\n private async *parseSseStream(response: Response): AsyncGenerator<UniversalEvent, void, void> {\n if (!response.body) {\n throw new Error(\"SSE stream is not readable in this environment.\");\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n // Normalize CRLF to LF for consistent parsing\n buffer += decoder.decode(value, { stream: true }).replace(/\\r\\n/g, \"\\n\");\n let index = buffer.indexOf(\"\\n\\n\");\n while (index !== -1) {\n const chunk = buffer.slice(0, index);\n buffer = buffer.slice(index + 2);\n const dataLines = chunk\n .split(\"\\n\")\n .filter((line) => line.startsWith(\"data:\"));\n if (dataLines.length > 0) {\n const payload = dataLines\n .map((line) => line.slice(5).trim())\n .join(\"\\n\");\n if (payload) {\n yield JSON.parse(payload) as UniversalEvent;\n }\n }\n index = buffer.indexOf(\"\\n\\n\");\n }\n }\n }\n}\n\nconst normalizeSpawnOptions = (\n spawn: SandboxAgentSpawnOptions | boolean | undefined,\n defaultEnabled: boolean,\n): SandboxAgentSpawnOptions => {\n if (typeof spawn === \"boolean\") {\n return { enabled: spawn };\n }\n if (spawn) {\n return { enabled: spawn.enabled ?? defaultEnabled, ...spawn };\n }\n return { enabled: defaultEnabled };\n};\n"],"mappings":"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","names":[]}
@@ -0,0 +1,168 @@
1
+ // src/spawn.ts
2
+ var PLATFORM_PACKAGES = {
3
+ "darwin-arm64": "@sandbox-agent/cli-darwin-arm64",
4
+ "darwin-x64": "@sandbox-agent/cli-darwin-x64",
5
+ "linux-x64": "@sandbox-agent/cli-linux-x64",
6
+ "win32-x64": "@sandbox-agent/cli-win32-x64"
7
+ };
8
+ function isNodeRuntime() {
9
+ return typeof process !== "undefined" && !!process.versions?.node;
10
+ }
11
+ async function spawnSandboxAgent(options, fetcher) {
12
+ if (!isNodeRuntime()) {
13
+ throw new Error("Autospawn requires a Node.js runtime.");
14
+ }
15
+ const {
16
+ spawn
17
+ } = await import("child_process");
18
+ const crypto = await import("crypto");
19
+ const fs = await import("fs");
20
+ const path = await import("path");
21
+ const net = await import("net");
22
+ const { createRequire } = await import("module");
23
+ const bindHost = options.host ?? "127.0.0.1";
24
+ const port = options.port ?? await getFreePort(net, bindHost);
25
+ const connectHost = bindHost === "0.0.0.0" || bindHost === "::" ? "127.0.0.1" : bindHost;
26
+ const token = options.token ?? crypto.randomBytes(24).toString("hex");
27
+ const timeoutMs = options.timeoutMs ?? 15e3;
28
+ const logMode = options.log ?? "inherit";
29
+ const binaryPath = options.binaryPath ?? resolveBinaryFromEnv(fs, path) ?? resolveBinaryFromCliPackage(createRequire(import.meta.url), path, fs) ?? resolveBinaryFromPath(fs, path);
30
+ if (!binaryPath) {
31
+ throw new Error("sandbox-agent binary not found. Install @sandbox-agent/cli or set SANDBOX_AGENT_BIN.");
32
+ }
33
+ const stdio = logMode === "inherit" ? "inherit" : logMode === "silent" ? "ignore" : "pipe";
34
+ const args = ["server", "--host", bindHost, "--port", String(port), "--token", token];
35
+ const child = spawn(binaryPath, args, {
36
+ stdio,
37
+ env: {
38
+ ...process.env,
39
+ ...options.env ?? {}
40
+ }
41
+ });
42
+ const cleanup = registerProcessCleanup(child);
43
+ const baseUrl = `http://${connectHost}:${port}`;
44
+ const ready = waitForHealth(baseUrl, fetcher ?? globalThis.fetch, timeoutMs, child, token);
45
+ await ready;
46
+ const dispose = async () => {
47
+ if (child.exitCode !== null) {
48
+ cleanup.dispose();
49
+ return;
50
+ }
51
+ child.kill("SIGTERM");
52
+ const exited = await waitForExit(child, 5e3);
53
+ if (!exited) {
54
+ child.kill("SIGKILL");
55
+ }
56
+ cleanup.dispose();
57
+ };
58
+ return { baseUrl, token, child, dispose };
59
+ }
60
+ function resolveBinaryFromEnv(fs, path) {
61
+ const value = process.env.SANDBOX_AGENT_BIN;
62
+ if (!value) {
63
+ return null;
64
+ }
65
+ const resolved = path.resolve(value);
66
+ if (fs.existsSync(resolved)) {
67
+ return resolved;
68
+ }
69
+ return null;
70
+ }
71
+ function resolveBinaryFromCliPackage(require2, path, fs) {
72
+ const key = `${process.platform}-${process.arch}`;
73
+ const pkg = PLATFORM_PACKAGES[key];
74
+ if (!pkg) {
75
+ return null;
76
+ }
77
+ try {
78
+ const pkgPath = require2.resolve(`${pkg}/package.json`);
79
+ const bin = process.platform === "win32" ? "sandbox-agent.exe" : "sandbox-agent";
80
+ const resolved = path.join(path.dirname(pkgPath), "bin", bin);
81
+ return fs.existsSync(resolved) ? resolved : null;
82
+ } catch {
83
+ return null;
84
+ }
85
+ }
86
+ function resolveBinaryFromPath(fs, path) {
87
+ const pathEnv = process.env.PATH ?? "";
88
+ const separator = process.platform === "win32" ? ";" : ":";
89
+ const candidates = pathEnv.split(separator).filter(Boolean);
90
+ const bin = process.platform === "win32" ? "sandbox-agent.exe" : "sandbox-agent";
91
+ for (const dir of candidates) {
92
+ const resolved = path.join(dir, bin);
93
+ if (fs.existsSync(resolved)) {
94
+ return resolved;
95
+ }
96
+ }
97
+ return null;
98
+ }
99
+ async function getFreePort(net, host) {
100
+ return new Promise((resolve, reject) => {
101
+ const server = net.createServer();
102
+ server.unref();
103
+ server.on("error", reject);
104
+ server.listen(0, host, () => {
105
+ const address = server.address();
106
+ server.close(() => resolve(address.port));
107
+ });
108
+ });
109
+ }
110
+ async function waitForHealth(baseUrl, fetcher, timeoutMs, child, token) {
111
+ if (!fetcher) {
112
+ throw new Error("Fetch API is not available; provide a fetch implementation.");
113
+ }
114
+ const start = Date.now();
115
+ let lastError;
116
+ while (Date.now() - start < timeoutMs) {
117
+ if (child.exitCode !== null) {
118
+ throw new Error("sandbox-agent exited before becoming healthy.");
119
+ }
120
+ try {
121
+ const response = await fetcher(`${baseUrl}/v1/health`, {
122
+ headers: { Authorization: `Bearer ${token}` }
123
+ });
124
+ if (response.ok) {
125
+ return;
126
+ }
127
+ lastError = `status ${response.status}`;
128
+ } catch (err) {
129
+ lastError = err instanceof Error ? err.message : String(err);
130
+ }
131
+ await new Promise((resolve) => setTimeout(resolve, 200));
132
+ }
133
+ throw new Error(`Timed out waiting for sandbox-agent health (${lastError ?? "unknown error"}).`);
134
+ }
135
+ async function waitForExit(child, timeoutMs) {
136
+ if (child.exitCode !== null) {
137
+ return true;
138
+ }
139
+ return new Promise((resolve) => {
140
+ const timer = setTimeout(() => resolve(false), timeoutMs);
141
+ child.once("exit", () => {
142
+ clearTimeout(timer);
143
+ resolve(true);
144
+ });
145
+ });
146
+ }
147
+ function registerProcessCleanup(child) {
148
+ const handler = () => {
149
+ if (child.exitCode === null) {
150
+ child.kill("SIGTERM");
151
+ }
152
+ };
153
+ process.once("exit", handler);
154
+ process.once("SIGINT", handler);
155
+ process.once("SIGTERM", handler);
156
+ return {
157
+ dispose: () => {
158
+ process.off("exit", handler);
159
+ process.off("SIGINT", handler);
160
+ process.off("SIGTERM", handler);
161
+ }
162
+ };
163
+ }
164
+ export {
165
+ isNodeRuntime,
166
+ spawnSandboxAgent
167
+ };
168
+ //# sourceMappingURL=spawn-BT4YX7BC.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\";\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 \"win32-x64\": \"@sandbox-agent/cli-win32-x64\",\n};\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 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"]}
package/package.json CHANGED
@@ -1,11 +1,41 @@
1
1
  {
2
2
  "name": "sandbox-agent",
3
- "version": "0.0.1",
4
- "description": "Universal API for automatic coding agents in sandboxes. Supports Claude Code, Codex, OpenCode, and Amp.",
3
+ "version": "0.1.0-test.5",
4
+ "description": "Universal API for automatic coding agents in sandboxes. Supprots Claude Code, Codex, OpenCode, and Amp.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "https://github.com/rivet-dev/sandbox-agent"
9
9
  },
10
- "main": "index.js"
11
- }
10
+ "type": "module",
11
+ "main": "./dist/index.js",
12
+ "types": "./dist/index.d.ts",
13
+ "exports": {
14
+ ".": {
15
+ "types": "./dist/index.d.ts",
16
+ "import": "./dist/index.js"
17
+ }
18
+ },
19
+ "files": [
20
+ "dist"
21
+ ],
22
+ "devDependencies": {
23
+ "@types/node": "^22.0.0",
24
+ "openapi-typescript": "^6.7.0",
25
+ "tsup": "^8.0.0",
26
+ "typescript": "^5.7.0",
27
+ "vitest": "^3.0.0"
28
+ },
29
+ "optionalDependencies": {
30
+ "@sandbox-agent/cli": "0.1.0"
31
+ },
32
+ "scripts": {
33
+ "generate:openapi": "cargo check -p sandbox-agent-openapi-gen && cargo run -p sandbox-agent-openapi-gen -- --out ../../docs/openapi.json",
34
+ "generate:types": "openapi-typescript ../../docs/openapi.json -o src/generated/openapi.ts",
35
+ "generate": "pnpm run generate:openapi && pnpm run generate:types",
36
+ "build": "if [ -z \"$SKIP_OPENAPI_GEN\" ]; then pnpm run generate:openapi; fi && pnpm run generate:types && tsup",
37
+ "typecheck": "tsc --noEmit",
38
+ "test": "vitest run",
39
+ "test:watch": "vitest"
40
+ }
41
+ }
package/index.js DELETED
@@ -1 +0,0 @@
1
- module.exports = {};