@cloudflare/sandbox 0.2.3 → 0.3.0

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.
Files changed (44) hide show
  1. package/CHANGELOG.md +69 -0
  2. package/Dockerfile +9 -11
  3. package/README.md +69 -7
  4. package/container_src/control-process.ts +784 -0
  5. package/container_src/handler/exec.ts +99 -254
  6. package/container_src/handler/file.ts +204 -642
  7. package/container_src/handler/git.ts +28 -80
  8. package/container_src/handler/process.ts +443 -515
  9. package/container_src/handler/session.ts +92 -0
  10. package/container_src/index.ts +74 -129
  11. package/container_src/isolation.ts +1039 -0
  12. package/container_src/jupyter-service.ts +8 -5
  13. package/container_src/shell-escape.ts +42 -0
  14. package/container_src/types.ts +35 -12
  15. package/dist/{chunk-VTKZL632.js → chunk-BEQUGUY4.js} +2 -2
  16. package/dist/{chunk-4KELYYKS.js → chunk-GTGWAEED.js} +239 -265
  17. package/dist/chunk-GTGWAEED.js.map +1 -0
  18. package/dist/{chunk-CUHYLCMT.js → chunk-SMUEY5JR.js} +111 -99
  19. package/dist/chunk-SMUEY5JR.js.map +1 -0
  20. package/dist/{client-bzEV222a.d.ts → client-Dny_ro_v.d.ts} +48 -84
  21. package/dist/client.d.ts +1 -1
  22. package/dist/client.js +1 -1
  23. package/dist/index.d.ts +2 -2
  24. package/dist/index.js +8 -9
  25. package/dist/interpreter.d.ts +2 -2
  26. package/dist/jupyter-client.d.ts +2 -2
  27. package/dist/jupyter-client.js +2 -2
  28. package/dist/request-handler.d.ts +3 -3
  29. package/dist/request-handler.js +3 -5
  30. package/dist/sandbox.d.ts +2 -2
  31. package/dist/sandbox.js +3 -5
  32. package/dist/types.d.ts +127 -21
  33. package/dist/types.js +35 -9
  34. package/dist/types.js.map +1 -1
  35. package/package.json +1 -1
  36. package/src/client.ts +175 -187
  37. package/src/index.ts +23 -13
  38. package/src/sandbox.ts +297 -332
  39. package/src/types.ts +125 -24
  40. package/dist/chunk-4KELYYKS.js.map +0 -1
  41. package/dist/chunk-CUHYLCMT.js.map +0 -1
  42. package/dist/chunk-S5FFBU4Y.js +0 -46
  43. package/dist/chunk-S5FFBU4Y.js.map +0 -1
  44. /package/dist/{chunk-VTKZL632.js.map → chunk-BEQUGUY4.js.map} +0 -0
@@ -1,6 +1,6 @@
1
+ import { ISandbox, ExecOptions, ExecResult, ProcessOptions, Process, StreamOptions, GitCheckoutResponse, MkdirResponse, WriteFileResponse, DeleteFileResponse, RenameFileResponse, MoveFileResponse, ReadFileResponse, ListFilesResponse, ExecutionSession, BaseExecOptions, ExecuteResponse, StartProcessResponse, ListProcessesResponse, GetProcessResponse, GetProcessLogsResponse } from './types.js';
1
2
  import { Container } from '@cloudflare/containers';
2
3
  import { CreateContextOptions, CodeContext, OutputMessage, Result, ExecutionError, RunCodeOptions, ExecutionResult } from './interpreter-types.js';
3
- import { ISandbox, ExecOptions, ExecResult, ProcessOptions, Process, StreamOptions, BaseExecOptions, StartProcessResponse, ListProcessesResponse, GetProcessResponse, GetProcessLogsResponse } from './types.js';
4
4
 
5
5
  interface ExecutionCallbacks {
6
6
  onStdout?: (output: OutputMessage) => void | Promise<void>;
@@ -35,6 +35,7 @@ declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox
35
35
  client: JupyterClient;
36
36
  private sandboxName;
37
37
  private codeInterpreter;
38
+ private defaultSession;
38
39
  constructor(ctx: DurableObjectState, env: Env);
39
40
  setSandboxName(name: string): Promise<void>;
40
41
  setEnvVars(envVars: Record<string, string>): Promise<void>;
@@ -43,13 +44,12 @@ declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox
43
44
  onError(error: unknown): void;
44
45
  fetch(request: Request): Promise<Response>;
45
46
  private determinePort;
47
+ private ensureDefaultSession;
46
48
  exec(command: string, options?: ExecOptions): Promise<ExecResult>;
47
- private executeWithStreaming;
48
- private mapExecuteResponseToExecResult;
49
49
  startProcess(command: string, options?: ProcessOptions): Promise<Process>;
50
50
  listProcesses(): Promise<Process[]>;
51
51
  getProcess(id: string): Promise<Process | null>;
52
- killProcess(id: string, _signal?: string): Promise<void>;
52
+ killProcess(id: string, signal?: string): Promise<void>;
53
53
  killAllProcesses(): Promise<number>;
54
54
  cleanupCompletedProcesses(): Promise<number>;
55
55
  getProcessLogs(id: string): Promise<{
@@ -76,6 +76,10 @@ declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox
76
76
  readFile(path: string, options?: {
77
77
  encoding?: string;
78
78
  }): Promise<ReadFileResponse>;
79
+ listFiles(path: string, options?: {
80
+ recursive?: boolean;
81
+ includeHidden?: boolean;
82
+ }): Promise<ListFilesResponse>;
79
83
  exposePort(port: number, options: {
80
84
  name?: string;
81
85
  hostname: string;
@@ -112,68 +116,18 @@ declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox
112
116
  * Delete a code context
113
117
  */
114
118
  deleteCodeContext(contextId: string): Promise<void>;
119
+ /**
120
+ * Create a new execution session with isolation
121
+ * Returns a session object with exec() method
122
+ */
123
+ createSession(options: {
124
+ id?: string;
125
+ env?: Record<string, string>;
126
+ cwd?: string;
127
+ isolation?: boolean;
128
+ }): Promise<ExecutionSession>;
115
129
  }
116
130
 
117
- interface ExecuteResponse {
118
- success: boolean;
119
- stdout: string;
120
- stderr: string;
121
- exitCode: number;
122
- command: string;
123
- timestamp: string;
124
- }
125
- interface GitCheckoutResponse {
126
- success: boolean;
127
- stdout: string;
128
- stderr: string;
129
- exitCode: number;
130
- repoUrl: string;
131
- branch: string;
132
- targetDir: string;
133
- timestamp: string;
134
- }
135
- interface MkdirResponse {
136
- success: boolean;
137
- stdout: string;
138
- stderr: string;
139
- exitCode: number;
140
- path: string;
141
- recursive: boolean;
142
- timestamp: string;
143
- }
144
- interface WriteFileResponse {
145
- success: boolean;
146
- exitCode: number;
147
- path: string;
148
- timestamp: string;
149
- }
150
- interface ReadFileResponse {
151
- success: boolean;
152
- exitCode: number;
153
- path: string;
154
- content: string;
155
- timestamp: string;
156
- }
157
- interface DeleteFileResponse {
158
- success: boolean;
159
- exitCode: number;
160
- path: string;
161
- timestamp: string;
162
- }
163
- interface RenameFileResponse {
164
- success: boolean;
165
- exitCode: number;
166
- oldPath: string;
167
- newPath: string;
168
- timestamp: string;
169
- }
170
- interface MoveFileResponse {
171
- success: boolean;
172
- exitCode: number;
173
- sourcePath: string;
174
- destinationPath: string;
175
- timestamp: string;
176
- }
177
131
  interface PreviewInfo {
178
132
  url: string;
179
133
  port: number;
@@ -212,48 +166,58 @@ interface HttpClientOptions {
212
166
  declare class HttpClient {
213
167
  private baseUrl;
214
168
  private options;
215
- private sessionId;
216
169
  constructor(options?: HttpClientOptions);
217
170
  protected doFetch(path: string, options?: RequestInit): Promise<Response>;
218
- execute(command: string, options: Pick<BaseExecOptions, "sessionId" | "cwd" | "env">): Promise<ExecuteResponse>;
219
- executeCommandStream(command: string, sessionId?: string): Promise<ReadableStream<Uint8Array>>;
220
- gitCheckout(repoUrl: string, branch?: string, targetDir?: string, sessionId?: string): Promise<GitCheckoutResponse>;
221
- mkdir(path: string, recursive?: boolean, sessionId?: string): Promise<MkdirResponse>;
222
- writeFile(path: string, content: string, encoding?: string, sessionId?: string): Promise<WriteFileResponse>;
223
- readFile(path: string, encoding?: string, sessionId?: string): Promise<ReadFileResponse>;
224
- deleteFile(path: string, sessionId?: string): Promise<DeleteFileResponse>;
225
- renameFile(oldPath: string, newPath: string, sessionId?: string): Promise<RenameFileResponse>;
226
- moveFile(sourcePath: string, destinationPath: string, sessionId?: string): Promise<MoveFileResponse>;
171
+ createSession(options: {
172
+ id: string;
173
+ env?: Record<string, string>;
174
+ cwd?: string;
175
+ isolation?: boolean;
176
+ }): Promise<{
177
+ success: boolean;
178
+ id: string;
179
+ message: string;
180
+ }>;
181
+ exec(sessionId: string, command: string, options?: Pick<BaseExecOptions, "cwd" | "env">): Promise<ExecuteResponse>;
182
+ execStream(sessionId: string, command: string): Promise<ReadableStream<Uint8Array>>;
183
+ gitCheckout(repoUrl: string, sessionId: string, branch?: string, targetDir?: string): Promise<GitCheckoutResponse>;
184
+ mkdir(path: string, recursive: boolean | undefined, sessionId: string): Promise<MkdirResponse>;
185
+ writeFile(path: string, content: string, encoding: string | undefined, sessionId: string): Promise<WriteFileResponse>;
186
+ readFile(path: string, encoding: string | undefined, sessionId: string): Promise<ReadFileResponse>;
187
+ deleteFile(path: string, sessionId: string): Promise<DeleteFileResponse>;
188
+ renameFile(oldPath: string, newPath: string, sessionId: string): Promise<RenameFileResponse>;
189
+ moveFile(sourcePath: string, destinationPath: string, sessionId: string): Promise<MoveFileResponse>;
190
+ listFiles(path: string, sessionId: string, options?: {
191
+ recursive?: boolean;
192
+ includeHidden?: boolean;
193
+ }): Promise<ListFilesResponse>;
227
194
  exposePort(port: number, name?: string): Promise<ExposePortResponse>;
228
195
  unexposePort(port: number): Promise<UnexposePortResponse>;
229
196
  getExposedPorts(): Promise<GetExposedPortsResponse>;
230
197
  ping(): Promise<string>;
231
- getCommands(): Promise<string[]>;
232
- getSessionId(): string | null;
233
- setSessionId(sessionId: string): void;
234
- clearSession(): void;
235
- startProcess(command: string, options?: {
198
+ startProcess(command: string, sessionId: string, options?: {
236
199
  processId?: string;
237
- sessionId?: string;
238
200
  timeout?: number;
239
201
  env?: Record<string, string>;
240
202
  cwd?: string;
241
203
  encoding?: string;
242
204
  autoCleanup?: boolean;
243
205
  }): Promise<StartProcessResponse>;
244
- listProcesses(): Promise<ListProcessesResponse>;
206
+ listProcesses(sessionId?: string): Promise<ListProcessesResponse>;
245
207
  getProcess(processId: string): Promise<GetProcessResponse>;
246
208
  killProcess(processId: string): Promise<{
247
209
  success: boolean;
248
210
  message: string;
249
211
  }>;
250
- killAllProcesses(): Promise<{
212
+ killAllProcesses(sessionId?: string): Promise<{
251
213
  success: boolean;
252
214
  killedCount: number;
253
215
  message: string;
254
216
  }>;
255
217
  getProcessLogs(processId: string): Promise<GetProcessLogsResponse>;
256
- streamProcessLogs(processId: string): Promise<ReadableStream<Uint8Array>>;
218
+ streamProcessLogs(processId: string, options?: {
219
+ signal?: AbortSignal;
220
+ }): Promise<ReadableStream<Uint8Array>>;
257
221
  }
258
222
 
259
- export { type DeleteFileResponse as D, type ExecuteResponse as E, type GitCheckoutResponse as G, HttpClient as H, JupyterClient as J, type MkdirResponse as M, type ReadFileResponse as R, Sandbox as S, type WriteFileResponse as W, type MoveFileResponse as a, type RenameFileResponse as b, type ExecutionCallbacks as c, getSandbox as g };
223
+ export { type ExecutionCallbacks as E, HttpClient as H, JupyterClient as J, Sandbox as S, getSandbox as g };
package/dist/client.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { D as DeleteFileResponse, E as ExecuteResponse, G as GitCheckoutResponse, H as HttpClient, M as MkdirResponse, a as MoveFileResponse, R as ReadFileResponse, b as RenameFileResponse, W as WriteFileResponse } from './client-bzEV222a.js';
1
+ export { H as HttpClient } from './client-Dny_ro_v.js';
2
2
  import './types.js';
3
3
  import '@cloudflare/containers';
4
4
  import './interpreter-types.js';
package/dist/client.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  HttpClient
3
- } from "./chunk-CUHYLCMT.js";
3
+ } from "./chunk-SMUEY5JR.js";
4
4
  export {
5
5
  HttpClient
6
6
  };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- export { D as DeleteFileResponse, E as ExecuteResponse, G as GitCheckoutResponse, M as MkdirResponse, a as MoveFileResponse, R as ReadFileResponse, b as RenameFileResponse, S as Sandbox, W as WriteFileResponse, g as getSandbox } from './client-bzEV222a.js';
2
1
  export { CodeExecutionError, ContainerNotReadyError, ContextNotFoundError, JupyterNotReadyError, SandboxError, SandboxErrorResponse, SandboxNetworkError, ServiceUnavailableError, isJupyterNotReadyError, isRetryableError, isSandboxError, parseErrorResponse } from './errors.js';
3
2
  export { ChartData, CodeContext, CreateContextOptions, Execution, ExecutionError, OutputMessage, Result, ResultImpl, RunCodeOptions } from './interpreter-types.js';
4
3
  export { RouteInfo, SandboxEnv, proxyToSandbox } from './request-handler.js';
4
+ export { S as Sandbox, g as getSandbox } from './client-Dny_ro_v.js';
5
5
  export { asyncIterableToSSEStream, parseSSEStream, responseToAsyncIterable } from './sse-parser.js';
6
- export { ExecEvent, LogEvent } from './types.js';
6
+ export { DeleteFileResponse, ExecEvent, ExecOptions, ExecResult, ExecuteResponse, ExecutionSession, GitCheckoutResponse, ISandbox, ListFilesResponse, LogEvent, MkdirResponse, MoveFileResponse, Process, ProcessOptions, ProcessStatus, ReadFileResponse, RenameFileResponse, StreamOptions, WriteFileResponse } from './types.js';
7
7
  import '@cloudflare/containers';
package/dist/index.js CHANGED
@@ -1,21 +1,20 @@
1
- import {
2
- Sandbox,
3
- getSandbox,
4
- proxyToSandbox
5
- } from "./chunk-4KELYYKS.js";
6
- import "./chunk-6UAWTJ5S.js";
7
1
  import {
8
2
  asyncIterableToSSEStream,
9
3
  parseSSEStream,
10
4
  responseToAsyncIterable
11
5
  } from "./chunk-NNGBXDMY.js";
12
- import "./chunk-S5FFBU4Y.js";
6
+ import {
7
+ Sandbox,
8
+ getSandbox,
9
+ proxyToSandbox
10
+ } from "./chunk-GTGWAEED.js";
11
+ import "./chunk-6UAWTJ5S.js";
13
12
  import "./chunk-FKBV7CZS.js";
14
13
  import {
15
14
  ResultImpl
16
15
  } from "./chunk-EGC5IYXA.js";
17
- import "./chunk-VTKZL632.js";
18
- import "./chunk-CUHYLCMT.js";
16
+ import "./chunk-BEQUGUY4.js";
17
+ import "./chunk-SMUEY5JR.js";
19
18
  import {
20
19
  CodeExecutionError,
21
20
  ContainerNotReadyError,
@@ -1,7 +1,7 @@
1
1
  import { CreateContextOptions, CodeContext, RunCodeOptions, Execution } from './interpreter-types.js';
2
- import { S as Sandbox } from './client-bzEV222a.js';
3
- import '@cloudflare/containers';
2
+ import { S as Sandbox } from './client-Dny_ro_v.js';
4
3
  import './types.js';
4
+ import '@cloudflare/containers';
5
5
 
6
6
  declare class CodeInterpreter {
7
7
  private jupyterClient;
@@ -1,4 +1,4 @@
1
- export { c as ExecutionCallbacks, J as JupyterClient } from './client-bzEV222a.js';
1
+ export { E as ExecutionCallbacks, J as JupyterClient } from './client-Dny_ro_v.js';
2
2
  import './interpreter-types.js';
3
- import '@cloudflare/containers';
4
3
  import './types.js';
4
+ import '@cloudflare/containers';
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  JupyterClient
3
- } from "./chunk-VTKZL632.js";
4
- import "./chunk-CUHYLCMT.js";
3
+ } from "./chunk-BEQUGUY4.js";
4
+ import "./chunk-SMUEY5JR.js";
5
5
  import "./chunk-LALY4SFU.js";
6
6
  export {
7
7
  JupyterClient
@@ -1,7 +1,7 @@
1
- import { S as Sandbox } from './client-bzEV222a.js';
2
- import '@cloudflare/containers';
3
- import './interpreter-types.js';
1
+ import { S as Sandbox } from './client-Dny_ro_v.js';
4
2
  import './types.js';
3
+ import './interpreter-types.js';
4
+ import '@cloudflare/containers';
5
5
 
6
6
  interface SandboxEnv {
7
7
  Sandbox: DurableObjectNamespace<Sandbox>;
@@ -1,14 +1,12 @@
1
1
  import {
2
2
  isLocalhostPattern,
3
3
  proxyToSandbox
4
- } from "./chunk-4KELYYKS.js";
4
+ } from "./chunk-GTGWAEED.js";
5
5
  import "./chunk-6UAWTJ5S.js";
6
- import "./chunk-NNGBXDMY.js";
7
- import "./chunk-S5FFBU4Y.js";
8
6
  import "./chunk-FKBV7CZS.js";
9
7
  import "./chunk-EGC5IYXA.js";
10
- import "./chunk-VTKZL632.js";
11
- import "./chunk-CUHYLCMT.js";
8
+ import "./chunk-BEQUGUY4.js";
9
+ import "./chunk-SMUEY5JR.js";
12
10
  import "./chunk-LALY4SFU.js";
13
11
  export {
14
12
  isLocalhostPattern,
package/dist/sandbox.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { S as Sandbox, g as getSandbox } from './client-bzEV222a.js';
1
+ import './types.js';
2
2
  import '@cloudflare/containers';
3
3
  import './interpreter-types.js';
4
- import './types.js';
4
+ export { S as Sandbox, g as getSandbox } from './client-Dny_ro_v.js';
package/dist/sandbox.js CHANGED
@@ -1,14 +1,12 @@
1
1
  import {
2
2
  Sandbox,
3
3
  getSandbox
4
- } from "./chunk-4KELYYKS.js";
4
+ } from "./chunk-GTGWAEED.js";
5
5
  import "./chunk-6UAWTJ5S.js";
6
- import "./chunk-NNGBXDMY.js";
7
- import "./chunk-S5FFBU4Y.js";
8
6
  import "./chunk-FKBV7CZS.js";
9
7
  import "./chunk-EGC5IYXA.js";
10
- import "./chunk-VTKZL632.js";
11
- import "./chunk-CUHYLCMT.js";
8
+ import "./chunk-BEQUGUY4.js";
9
+ import "./chunk-SMUEY5JR.js";
12
10
  import "./chunk-LALY4SFU.js";
13
11
  export {
14
12
  Sandbox,
package/dist/types.d.ts CHANGED
@@ -1,10 +1,6 @@
1
1
  import { CreateContextOptions, CodeContext, RunCodeOptions, ExecutionResult } from './interpreter-types.js';
2
2
 
3
3
  interface BaseExecOptions {
4
- /**
5
- * Session ID for grouping related commands
6
- */
7
- sessionId?: string;
8
4
  /**
9
5
  * Maximum execution time in milliseconds
10
6
  */
@@ -73,10 +69,6 @@ interface ExecResult {
73
69
  * ISO timestamp when command started
74
70
  */
75
71
  timestamp: string;
76
- /**
77
- * Session ID if provided
78
- */
79
- sessionId?: string;
80
72
  }
81
73
  interface ProcessOptions extends BaseExecOptions {
82
74
  /**
@@ -135,10 +127,6 @@ interface Process {
135
127
  * Process exit code (if completed)
136
128
  */
137
129
  readonly exitCode?: number;
138
- /**
139
- * Session ID if provided
140
- */
141
- readonly sessionId?: string;
142
130
  /**
143
131
  * Kill the process
144
132
  */
@@ -163,14 +151,12 @@ interface ExecEvent {
163
151
  exitCode?: number;
164
152
  result?: ExecResult;
165
153
  error?: string;
166
- sessionId?: string;
167
154
  }
168
155
  interface LogEvent {
169
156
  type: 'stdout' | 'stderr' | 'exit' | 'error';
170
157
  timestamp: string;
171
158
  data: string;
172
159
  processId: string;
173
- sessionId?: string;
174
160
  exitCode?: number;
175
161
  }
176
162
  interface StreamOptions extends BaseExecOptions {
@@ -204,8 +190,6 @@ interface ProcessRecord {
204
190
  startTime: Date;
205
191
  endTime?: Date;
206
192
  exitCode?: number;
207
- sessionId?: string;
208
- childProcess?: any;
209
193
  stdout: string;
210
194
  stderr: string;
211
195
  outputListeners: Set<(stream: 'stdout' | 'stderr', data: string) => void>;
@@ -215,7 +199,6 @@ interface StartProcessRequest {
215
199
  command: string;
216
200
  options?: {
217
201
  processId?: string;
218
- sessionId?: string;
219
202
  timeout?: number;
220
203
  env?: Record<string, string>;
221
204
  cwd?: string;
@@ -230,7 +213,9 @@ interface StartProcessResponse {
230
213
  command: string;
231
214
  status: ProcessStatus;
232
215
  startTime: string;
233
- sessionId?: string;
216
+ endTime?: string | null;
217
+ exitCode?: number | null;
218
+ sessionId: string;
234
219
  };
235
220
  }
236
221
  interface ListProcessesResponse {
@@ -242,7 +227,6 @@ interface ListProcessesResponse {
242
227
  startTime: string;
243
228
  endTime?: string;
244
229
  exitCode?: number;
245
- sessionId?: string;
246
230
  }>;
247
231
  }
248
232
  interface GetProcessResponse {
@@ -254,7 +238,6 @@ interface GetProcessResponse {
254
238
  startTime: string;
255
239
  endTime?: string;
256
240
  exitCode?: number;
257
- sessionId?: string;
258
241
  } | null;
259
242
  }
260
243
  interface GetProcessLogsResponse {
@@ -279,14 +262,137 @@ interface ISandbox {
279
262
  stdout: string;
280
263
  stderr: string;
281
264
  }>;
265
+ gitCheckout(repoUrl: string, options: {
266
+ branch?: string;
267
+ targetDir?: string;
268
+ }): Promise<GitCheckoutResponse>;
269
+ mkdir(path: string, options?: {
270
+ recursive?: boolean;
271
+ }): Promise<MkdirResponse>;
272
+ writeFile(path: string, content: string, options?: {
273
+ encoding?: string;
274
+ }): Promise<WriteFileResponse>;
275
+ deleteFile(path: string): Promise<DeleteFileResponse>;
276
+ renameFile(oldPath: string, newPath: string): Promise<RenameFileResponse>;
277
+ moveFile(sourcePath: string, destinationPath: string): Promise<MoveFileResponse>;
278
+ readFile(path: string, options?: {
279
+ encoding?: string;
280
+ }): Promise<ReadFileResponse>;
281
+ listFiles(path: string, options?: {
282
+ recursive?: boolean;
283
+ includeHidden?: boolean;
284
+ }): Promise<ListFilesResponse>;
285
+ exposePort(port: number, options: {
286
+ name?: string;
287
+ hostname: string;
288
+ }): Promise<{
289
+ url: string;
290
+ port: number;
291
+ name?: string;
292
+ }>;
293
+ unexposePort(port: number): Promise<void>;
294
+ getExposedPorts(hostname: string): Promise<Array<{
295
+ url: string;
296
+ port: number;
297
+ name?: string;
298
+ exposedAt: string;
299
+ }>>;
300
+ setEnvVars(envVars: Record<string, string>): Promise<void>;
301
+ setSandboxName(name: string): Promise<void>;
282
302
  createCodeContext(options?: CreateContextOptions): Promise<CodeContext>;
283
303
  runCode(code: string, options?: RunCodeOptions): Promise<ExecutionResult>;
284
304
  runCodeStream(code: string, options?: RunCodeOptions): Promise<ReadableStream>;
285
305
  listCodeContexts(): Promise<CodeContext[]>;
286
306
  deleteCodeContext(contextId: string): Promise<void>;
287
307
  }
308
+ interface ExecutionSession extends Omit<ISandbox, 'createSession' | 'setSandboxName'> {
309
+ /**
310
+ * Session ID
311
+ */
312
+ id: string;
313
+ }
314
+ interface ExecuteResponse {
315
+ success: boolean;
316
+ stdout: string;
317
+ stderr: string;
318
+ exitCode: number;
319
+ command: string;
320
+ timestamp: string;
321
+ }
322
+ interface GitCheckoutResponse {
323
+ success: boolean;
324
+ stdout: string;
325
+ stderr: string;
326
+ exitCode: number;
327
+ repoUrl: string;
328
+ branch: string;
329
+ targetDir: string;
330
+ timestamp: string;
331
+ }
332
+ interface MkdirResponse {
333
+ success: boolean;
334
+ stdout: string;
335
+ stderr: string;
336
+ exitCode: number;
337
+ path: string;
338
+ recursive: boolean;
339
+ timestamp: string;
340
+ }
341
+ interface WriteFileResponse {
342
+ success: boolean;
343
+ exitCode: number;
344
+ path: string;
345
+ timestamp: string;
346
+ }
347
+ interface ReadFileResponse {
348
+ success: boolean;
349
+ exitCode: number;
350
+ path: string;
351
+ content: string;
352
+ timestamp: string;
353
+ }
354
+ interface DeleteFileResponse {
355
+ success: boolean;
356
+ exitCode: number;
357
+ path: string;
358
+ timestamp: string;
359
+ }
360
+ interface RenameFileResponse {
361
+ success: boolean;
362
+ exitCode: number;
363
+ oldPath: string;
364
+ newPath: string;
365
+ timestamp: string;
366
+ }
367
+ interface MoveFileResponse {
368
+ success: boolean;
369
+ exitCode: number;
370
+ sourcePath: string;
371
+ destinationPath: string;
372
+ timestamp: string;
373
+ }
374
+ interface ListFilesResponse {
375
+ success: boolean;
376
+ exitCode: number;
377
+ path: string;
378
+ files: Array<{
379
+ name: string;
380
+ absolutePath: string;
381
+ relativePath: string;
382
+ type: 'file' | 'directory' | 'symlink' | 'other';
383
+ size: number;
384
+ modifiedAt: string;
385
+ mode: string;
386
+ permissions: {
387
+ readable: boolean;
388
+ writable: boolean;
389
+ executable: boolean;
390
+ };
391
+ }>;
392
+ timestamp: string;
393
+ }
288
394
  declare function isExecResult(value: any): value is ExecResult;
289
395
  declare function isProcess(value: any): value is Process;
290
396
  declare function isProcessStatus(value: string): value is ProcessStatus;
291
397
 
292
- export { type BaseExecOptions, type ExecEvent, type ExecOptions, type ExecResult, ExecutionTimeoutError, type GetProcessLogsResponse, type GetProcessResponse, type ISandbox, type ListProcessesResponse, type LogEvent, type Process, ProcessAlreadyExistsError, ProcessNotFoundError, type ProcessOptions, type ProcessRecord, type ProcessStatus, SandboxError, type StartProcessRequest, type StartProcessResponse, type StreamOptions, isExecResult, isProcess, isProcessStatus };
398
+ export { type BaseExecOptions, type DeleteFileResponse, type ExecEvent, type ExecOptions, type ExecResult, type ExecuteResponse, type ExecutionSession, ExecutionTimeoutError, type GetProcessLogsResponse, type GetProcessResponse, type GitCheckoutResponse, type ISandbox, type ListFilesResponse, type ListProcessesResponse, type LogEvent, type MkdirResponse, type MoveFileResponse, type Process, ProcessAlreadyExistsError, ProcessNotFoundError, type ProcessOptions, type ProcessRecord, type ProcessStatus, type ReadFileResponse, type RenameFileResponse, SandboxError, type StartProcessRequest, type StartProcessResponse, type StreamOptions, type WriteFileResponse, isExecResult, isProcess, isProcessStatus };
package/dist/types.js CHANGED
@@ -1,12 +1,38 @@
1
- import {
2
- ExecutionTimeoutError,
3
- ProcessAlreadyExistsError,
4
- ProcessNotFoundError,
5
- SandboxError,
6
- isExecResult,
7
- isProcess,
8
- isProcessStatus
9
- } from "./chunk-S5FFBU4Y.js";
1
+ // src/types.ts
2
+ var SandboxError = class extends Error {
3
+ constructor(message, code) {
4
+ super(message);
5
+ this.code = code;
6
+ this.name = "SandboxError";
7
+ }
8
+ };
9
+ var ProcessNotFoundError = class extends SandboxError {
10
+ constructor(processId) {
11
+ super(`Process not found: ${processId}`, "PROCESS_NOT_FOUND");
12
+ this.name = "ProcessNotFoundError";
13
+ }
14
+ };
15
+ var ProcessAlreadyExistsError = class extends SandboxError {
16
+ constructor(processId) {
17
+ super(`Process already exists: ${processId}`, "PROCESS_EXISTS");
18
+ this.name = "ProcessAlreadyExistsError";
19
+ }
20
+ };
21
+ var ExecutionTimeoutError = class extends SandboxError {
22
+ constructor(timeout) {
23
+ super(`Execution timed out after ${timeout}ms`, "EXECUTION_TIMEOUT");
24
+ this.name = "ExecutionTimeoutError";
25
+ }
26
+ };
27
+ function isExecResult(value) {
28
+ return value && typeof value.success === "boolean" && typeof value.exitCode === "number" && typeof value.stdout === "string" && typeof value.stderr === "string";
29
+ }
30
+ function isProcess(value) {
31
+ return value && typeof value.id === "string" && typeof value.command === "string" && typeof value.status === "string";
32
+ }
33
+ function isProcessStatus(value) {
34
+ return ["starting", "running", "completed", "failed", "killed", "error"].includes(value);
35
+ }
10
36
  export {
11
37
  ExecutionTimeoutError,
12
38
  ProcessAlreadyExistsError,
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
1
+ {"version":3,"sources":["../src/types.ts"],"sourcesContent":["// Core Types\n\nexport interface BaseExecOptions {\n /**\n * Maximum execution time in milliseconds\n */\n timeout?: number;\n\n /**\n * Environment variables for the command\n */\n env?: Record<string, string>;\n\n /**\n * Working directory for command execution\n */\n cwd?: string;\n\n /**\n * Text encoding for output (default: 'utf8')\n */\n encoding?: string;\n}\n\nexport interface ExecOptions extends BaseExecOptions {\n /**\n * Enable real-time output streaming via callbacks\n */\n stream?: boolean;\n\n /**\n * Callback for real-time output data\n */\n onOutput?: (stream: 'stdout' | 'stderr', data: string) => void;\n\n /**\n * Callback when command completes (only when stream: true)\n */\n onComplete?: (result: ExecResult) => void;\n\n /**\n * Callback for execution errors\n */\n onError?: (error: Error) => void;\n\n /**\n * AbortSignal for cancelling execution\n */\n signal?: AbortSignal;\n}\n\nexport interface ExecResult {\n /**\n * Whether the command succeeded (exitCode === 0)\n */\n success: boolean;\n\n /**\n * Process exit code\n */\n exitCode: number;\n\n /**\n * Standard output content\n */\n stdout: string;\n\n /**\n * Standard error content\n */\n stderr: string;\n\n /**\n * Command that was executed\n */\n command: string;\n\n\n /**\n * Execution duration in milliseconds\n */\n duration: number;\n\n /**\n * ISO timestamp when command started\n */\n timestamp: string;\n}\n\n// Background Process Types\n\nexport interface ProcessOptions extends BaseExecOptions {\n /**\n * Custom process ID for later reference\n * If not provided, a UUID will be generated\n */\n processId?: string;\n\n /**\n * Automatically cleanup process record after exit (default: true)\n */\n autoCleanup?: boolean;\n\n /**\n * Callback when process exits\n */\n onExit?: (code: number | null) => void;\n\n /**\n * Callback for real-time output (background processes)\n */\n onOutput?: (stream: 'stdout' | 'stderr', data: string) => void;\n\n /**\n * Callback when process starts successfully\n */\n onStart?: (process: Process) => void;\n\n /**\n * Callback for process errors\n */\n onError?: (error: Error) => void;\n}\n\nexport type ProcessStatus =\n | 'starting' // Process is being initialized\n | 'running' // Process is actively running\n | 'completed' // Process exited successfully (code 0)\n | 'failed' // Process exited with non-zero code\n | 'killed' // Process was terminated by signal\n | 'error'; // Process failed to start or encountered error\n\nexport interface Process {\n /**\n * Unique process identifier\n */\n readonly id: string;\n\n /**\n * System process ID (if available and running)\n */\n readonly pid?: number;\n\n /**\n * Command that was executed\n */\n readonly command: string;\n\n\n /**\n * Current process status\n */\n readonly status: ProcessStatus;\n\n /**\n * When the process was started\n */\n readonly startTime: Date;\n\n /**\n * When the process ended (if completed)\n */\n readonly endTime?: Date;\n\n /**\n * Process exit code (if completed)\n */\n readonly exitCode?: number;\n\n /**\n * Kill the process\n */\n kill(signal?: string): Promise<void>;\n\n /**\n * Get current process status (refreshed)\n */\n getStatus(): Promise<ProcessStatus>;\n\n /**\n * Get accumulated logs\n */\n getLogs(): Promise<{ stdout: string; stderr: string }>;\n}\n\n// Streaming Types\n\nexport interface ExecEvent {\n type: 'start' | 'stdout' | 'stderr' | 'complete' | 'error';\n timestamp: string;\n data?: string;\n command?: string;\n exitCode?: number;\n result?: ExecResult;\n error?: string; // Changed to string for serialization\n}\n\nexport interface LogEvent {\n type: 'stdout' | 'stderr' | 'exit' | 'error';\n timestamp: string;\n data: string;\n processId: string;\n exitCode?: number; // For 'exit' events\n}\n\nexport interface StreamOptions extends BaseExecOptions {\n /**\n * Buffer size for streaming output\n */\n bufferSize?: number;\n\n /**\n * AbortSignal for cancelling stream\n */\n signal?: AbortSignal;\n}\n\n// Error Types\n\nexport class SandboxError extends Error {\n constructor(message: string, public code?: string) {\n super(message);\n this.name = 'SandboxError';\n }\n}\n\nexport class ProcessNotFoundError extends SandboxError {\n constructor(processId: string) {\n super(`Process not found: ${processId}`, 'PROCESS_NOT_FOUND');\n this.name = 'ProcessNotFoundError';\n }\n}\n\nexport class ProcessAlreadyExistsError extends SandboxError {\n constructor(processId: string) {\n super(`Process already exists: ${processId}`, 'PROCESS_EXISTS');\n this.name = 'ProcessAlreadyExistsError';\n }\n}\n\nexport class ExecutionTimeoutError extends SandboxError {\n constructor(timeout: number) {\n super(`Execution timed out after ${timeout}ms`, 'EXECUTION_TIMEOUT');\n this.name = 'ExecutionTimeoutError';\n }\n}\n\n// Internal Container Types\n\nexport interface ProcessRecord {\n id: string;\n pid?: number;\n command: string;\n status: ProcessStatus;\n startTime: Date;\n endTime?: Date;\n exitCode?: number;\n\n // Internal fields\n stdout: string; // Accumulated output (ephemeral)\n stderr: string; // Accumulated output (ephemeral)\n\n // Streaming\n outputListeners: Set<(stream: 'stdout' | 'stderr', data: string) => void>;\n statusListeners: Set<(status: ProcessStatus) => void>;\n}\n\n// Container Request/Response Types\n\nexport interface StartProcessRequest {\n command: string;\n options?: {\n processId?: string;\n timeout?: number;\n env?: Record<string, string>;\n cwd?: string;\n encoding?: string;\n autoCleanup?: boolean;\n };\n}\n\nexport interface StartProcessResponse {\n process: {\n id: string;\n pid?: number;\n command: string;\n status: ProcessStatus;\n startTime: string;\n endTime?: string | null;\n exitCode?: number | null;\n sessionId: string;\n };\n}\n\nexport interface ListProcessesResponse {\n processes: Array<{\n id: string;\n pid?: number;\n command: string;\n status: ProcessStatus;\n startTime: string;\n endTime?: string;\n exitCode?: number;\n }>;\n}\n\nexport interface GetProcessResponse {\n process: {\n id: string;\n pid?: number;\n command: string;\n status: ProcessStatus;\n startTime: string;\n endTime?: string;\n exitCode?: number;\n } | null;\n}\n\nexport interface GetProcessLogsResponse {\n stdout: string;\n stderr: string;\n processId: string;\n}\n\n// Import code interpreter types\nimport type {\n CodeContext,\n CreateContextOptions,\n ExecutionResult, \n RunCodeOptions\n} from './interpreter-types';\n\n// Main Sandbox Interface\n\nexport interface ISandbox {\n // Enhanced execution API\n exec(command: string, options?: ExecOptions): Promise<ExecResult>;\n\n // Background process management\n startProcess(command: string, options?: ProcessOptions): Promise<Process>;\n listProcesses(): Promise<Process[]>;\n getProcess(id: string): Promise<Process | null>;\n killProcess(id: string, signal?: string): Promise<void>;\n killAllProcesses(): Promise<number>;\n\n // Advanced streaming - returns ReadableStream that can be converted to AsyncIterable\n execStream(command: string, options?: StreamOptions): Promise<ReadableStream<Uint8Array>>;\n streamProcessLogs(processId: string, options?: { signal?: AbortSignal }): Promise<ReadableStream<Uint8Array>>;\n\n // Utility methods\n cleanupCompletedProcesses(): Promise<number>;\n getProcessLogs(id: string): Promise<{ stdout: string; stderr: string }>;\n\n // File operations\n gitCheckout(repoUrl: string, options: { branch?: string; targetDir?: string }): Promise<GitCheckoutResponse>;\n mkdir(path: string, options?: { recursive?: boolean }): Promise<MkdirResponse>;\n writeFile(path: string, content: string, options?: { encoding?: string }): Promise<WriteFileResponse>;\n deleteFile(path: string): Promise<DeleteFileResponse>;\n renameFile(oldPath: string, newPath: string): Promise<RenameFileResponse>;\n moveFile(sourcePath: string, destinationPath: string): Promise<MoveFileResponse>;\n readFile(path: string, options?: { encoding?: string }): Promise<ReadFileResponse>;\n listFiles(path: string, options?: { recursive?: boolean; includeHidden?: boolean }): Promise<ListFilesResponse>;\n\n // Port management\n exposePort(port: number, options: { name?: string; hostname: string }): Promise<{ url: string; port: number; name?: string }>;\n unexposePort(port: number): Promise<void>;\n getExposedPorts(hostname: string): Promise<Array<{ url: string; port: number; name?: string; exposedAt: string }>>;\n\n // Environment management\n setEnvVars(envVars: Record<string, string>): Promise<void>;\n setSandboxName(name: string): Promise<void>;\n\n // Code Interpreter API\n createCodeContext(options?: CreateContextOptions): Promise<CodeContext>;\n runCode(code: string, options?: RunCodeOptions): Promise<ExecutionResult>;\n runCodeStream(code: string, options?: RunCodeOptions): Promise<ReadableStream>;\n listCodeContexts(): Promise<CodeContext[]>;\n deleteCodeContext(contextId: string): Promise<void>;\n}\n\n// Execution session returned by createSession()\n// Sessions are full-featured sandbox objects with scoped execution context\n// Inherits all ISandbox methods except createSession (sessions can't create sub-sessions),\n// and setSandboxName (sessions inherit sandbox name).\nexport interface ExecutionSession extends Omit<ISandbox, 'createSession' | 'setSandboxName'> {\n /**\n * Session ID\n */\n id: string;\n}\n\n// API Response Types\n\nexport interface ExecuteResponse {\n success: boolean;\n stdout: string;\n stderr: string;\n exitCode: number;\n command: string;\n timestamp: string;\n}\n\nexport interface GitCheckoutResponse {\n success: boolean;\n stdout: string;\n stderr: string;\n exitCode: number;\n repoUrl: string;\n branch: string;\n targetDir: string;\n timestamp: string;\n}\n\nexport interface MkdirResponse {\n success: boolean;\n stdout: string;\n stderr: string;\n exitCode: number;\n path: string;\n recursive: boolean;\n timestamp: string;\n}\n\nexport interface WriteFileResponse {\n success: boolean;\n exitCode: number;\n path: string;\n timestamp: string;\n}\n\nexport interface ReadFileResponse {\n success: boolean;\n exitCode: number;\n path: string;\n content: string;\n timestamp: string;\n}\n\nexport interface DeleteFileResponse {\n success: boolean;\n exitCode: number;\n path: string;\n timestamp: string;\n}\n\nexport interface RenameFileResponse {\n success: boolean;\n exitCode: number;\n oldPath: string;\n newPath: string;\n timestamp: string;\n}\n\nexport interface MoveFileResponse {\n success: boolean;\n exitCode: number;\n sourcePath: string;\n destinationPath: string;\n timestamp: string;\n}\n\nexport interface ListFilesResponse {\n success: boolean;\n exitCode: number;\n path: string;\n files: Array<{\n name: string;\n absolutePath: string;\n relativePath: string;\n type: 'file' | 'directory' | 'symlink' | 'other';\n size: number;\n modifiedAt: string;\n mode: string;\n permissions: {\n readable: boolean;\n writable: boolean;\n executable: boolean;\n };\n }>;\n timestamp: string;\n}\n\n// Type Guards\n\nexport function isExecResult(value: any): value is ExecResult {\n return value &&\n typeof value.success === 'boolean' &&\n typeof value.exitCode === 'number' &&\n typeof value.stdout === 'string' &&\n typeof value.stderr === 'string';\n}\n\nexport function isProcess(value: any): value is Process {\n return value &&\n typeof value.id === 'string' &&\n typeof value.command === 'string' &&\n typeof value.status === 'string';\n}\n\nexport function isProcessStatus(value: string): value is ProcessStatus {\n return ['starting', 'running', 'completed', 'failed', 'killed', 'error'].includes(value);\n}"],"mappings":";AA2NO,IAAM,eAAN,cAA2B,MAAM;AAAA,EACtC,YAAY,SAAwB,MAAe;AACjD,UAAM,OAAO;AADqB;AAElC,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,uBAAN,cAAmC,aAAa;AAAA,EACrD,YAAY,WAAmB;AAC7B,UAAM,sBAAsB,SAAS,IAAI,mBAAmB;AAC5D,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,4BAAN,cAAwC,aAAa;AAAA,EAC1D,YAAY,WAAmB;AAC7B,UAAM,2BAA2B,SAAS,IAAI,gBAAgB;AAC9D,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,wBAAN,cAAoC,aAAa;AAAA,EACtD,YAAY,SAAiB;AAC3B,UAAM,6BAA6B,OAAO,MAAM,mBAAmB;AACnE,SAAK,OAAO;AAAA,EACd;AACF;AA+OO,SAAS,aAAa,OAAiC;AAC5D,SAAO,SACL,OAAO,MAAM,YAAY,aACzB,OAAO,MAAM,aAAa,YAC1B,OAAO,MAAM,WAAW,YACxB,OAAO,MAAM,WAAW;AAC5B;AAEO,SAAS,UAAU,OAA8B;AACtD,SAAO,SACL,OAAO,MAAM,OAAO,YACpB,OAAO,MAAM,YAAY,YACzB,OAAO,MAAM,WAAW;AAC5B;AAEO,SAAS,gBAAgB,OAAuC;AACrE,SAAO,CAAC,YAAY,WAAW,aAAa,UAAU,UAAU,OAAO,EAAE,SAAS,KAAK;AACzF;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudflare/sandbox",
3
- "version": "0.2.3",
3
+ "version": "0.3.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/cloudflare/sandbox-sdk"