@cloudflare/sandbox 0.0.0-c87db11 → 0.0.0-cdb8197

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 (35) hide show
  1. package/CHANGELOG.md +117 -0
  2. package/Dockerfile +32 -29
  3. package/README.md +127 -12
  4. package/container_src/bun.lock +31 -77
  5. package/container_src/control-process.ts +784 -0
  6. package/container_src/handler/exec.ts +99 -254
  7. package/container_src/handler/file.ts +253 -640
  8. package/container_src/handler/git.ts +28 -80
  9. package/container_src/handler/process.ts +443 -515
  10. package/container_src/handler/session.ts +92 -0
  11. package/container_src/index.ts +108 -163
  12. package/container_src/interpreter-service.ts +276 -0
  13. package/container_src/isolation.ts +1213 -0
  14. package/container_src/mime-processor.ts +1 -1
  15. package/container_src/package.json +4 -4
  16. package/container_src/runtime/executors/javascript/node_executor.ts +123 -0
  17. package/container_src/runtime/executors/python/ipython_executor.py +338 -0
  18. package/container_src/runtime/executors/typescript/ts_executor.ts +138 -0
  19. package/container_src/runtime/process-pool.ts +464 -0
  20. package/container_src/shell-escape.ts +42 -0
  21. package/container_src/startup.sh +6 -79
  22. package/container_src/types.ts +35 -12
  23. package/package.json +2 -2
  24. package/src/client.ts +214 -187
  25. package/src/errors.ts +15 -14
  26. package/src/file-stream.ts +162 -0
  27. package/src/index.ts +43 -16
  28. package/src/{jupyter-client.ts → interpreter-client.ts} +6 -3
  29. package/src/interpreter-types.ts +102 -95
  30. package/src/interpreter.ts +8 -8
  31. package/src/sandbox.ts +314 -336
  32. package/src/types.ts +194 -24
  33. package/container_src/jupyter-server.ts +0 -579
  34. package/container_src/jupyter-service.ts +0 -458
  35. package/container_src/jupyter_config.py +0 -48
package/src/types.ts CHANGED
@@ -1,11 +1,6 @@
1
1
  // Core Types
2
2
 
3
3
  export interface BaseExecOptions {
4
- /**
5
- * Session ID for grouping related commands
6
- */
7
- sessionId?: string;
8
-
9
4
  /**
10
5
  * Maximum execution time in milliseconds
11
6
  */
@@ -90,11 +85,6 @@ export interface ExecResult {
90
85
  * ISO timestamp when command started
91
86
  */
92
87
  timestamp: string;
93
-
94
- /**
95
- * Session ID if provided
96
- */
97
- sessionId?: string;
98
88
  }
99
89
 
100
90
  // Background Process Types
@@ -177,11 +167,6 @@ export interface Process {
177
167
  */
178
168
  readonly exitCode?: number;
179
169
 
180
- /**
181
- * Session ID if provided
182
- */
183
- readonly sessionId?: string;
184
-
185
170
  /**
186
171
  * Kill the process
187
172
  */
@@ -208,7 +193,6 @@ export interface ExecEvent {
208
193
  exitCode?: number;
209
194
  result?: ExecResult;
210
195
  error?: string; // Changed to string for serialization
211
- sessionId?: string;
212
196
  }
213
197
 
214
198
  export interface LogEvent {
@@ -216,7 +200,6 @@ export interface LogEvent {
216
200
  timestamp: string;
217
201
  data: string;
218
202
  processId: string;
219
- sessionId?: string;
220
203
  exitCode?: number; // For 'exit' events
221
204
  }
222
205
 
@@ -232,6 +215,54 @@ export interface StreamOptions extends BaseExecOptions {
232
215
  signal?: AbortSignal;
233
216
  }
234
217
 
218
+ // File Streaming Types
219
+
220
+ /**
221
+ * SSE events for file streaming
222
+ */
223
+ export type FileStreamEvent =
224
+ | {
225
+ type: 'metadata';
226
+ mimeType: string;
227
+ size: number;
228
+ isBinary: boolean;
229
+ encoding: 'utf-8' | 'base64';
230
+ }
231
+ | {
232
+ type: 'chunk';
233
+ data: string; // base64 for binary, UTF-8 for text
234
+ }
235
+ | {
236
+ type: 'complete';
237
+ bytesRead: number;
238
+ }
239
+ | {
240
+ type: 'error';
241
+ error: string;
242
+ };
243
+
244
+ /**
245
+ * File metadata from streaming
246
+ */
247
+ export interface FileMetadata {
248
+ mimeType: string;
249
+ size: number;
250
+ isBinary: boolean;
251
+ encoding: 'utf-8' | 'base64';
252
+ }
253
+
254
+ /**
255
+ * File stream chunk - either string (text) or Uint8Array (binary, auto-decoded)
256
+ */
257
+ export type FileChunk = string | Uint8Array;
258
+
259
+ /**
260
+ * AsyncIterable of file chunks with metadata
261
+ */
262
+ export interface FileStream extends AsyncIterable<FileChunk> {
263
+ metadata?: FileMetadata;
264
+ }
265
+
235
266
  // Error Types
236
267
 
237
268
  export class SandboxError extends Error {
@@ -272,10 +303,8 @@ export interface ProcessRecord {
272
303
  startTime: Date;
273
304
  endTime?: Date;
274
305
  exitCode?: number;
275
- sessionId?: string;
276
306
 
277
307
  // Internal fields
278
- childProcess?: any; // Node.js ChildProcess
279
308
  stdout: string; // Accumulated output (ephemeral)
280
309
  stderr: string; // Accumulated output (ephemeral)
281
310
 
@@ -290,7 +319,6 @@ export interface StartProcessRequest {
290
319
  command: string;
291
320
  options?: {
292
321
  processId?: string;
293
- sessionId?: string;
294
322
  timeout?: number;
295
323
  env?: Record<string, string>;
296
324
  cwd?: string;
@@ -304,9 +332,11 @@ export interface StartProcessResponse {
304
332
  id: string;
305
333
  pid?: number;
306
334
  command: string;
307
- status: ProcessStatus;
335
+ status: ProcessStatus;
308
336
  startTime: string;
309
- sessionId?: string;
337
+ endTime?: string | null;
338
+ exitCode?: number | null;
339
+ sessionId: string;
310
340
  };
311
341
  }
312
342
 
@@ -319,7 +349,6 @@ export interface ListProcessesResponse {
319
349
  startTime: string;
320
350
  endTime?: string;
321
351
  exitCode?: number;
322
- sessionId?: string;
323
352
  }>;
324
353
  }
325
354
 
@@ -332,7 +361,6 @@ export interface GetProcessResponse {
332
361
  startTime: string;
333
362
  endTime?: string;
334
363
  exitCode?: number;
335
- sessionId?: string;
336
364
  } | null;
337
365
  }
338
366
 
@@ -371,6 +399,26 @@ export interface ISandbox {
371
399
  cleanupCompletedProcesses(): Promise<number>;
372
400
  getProcessLogs(id: string): Promise<{ stdout: string; stderr: string }>;
373
401
 
402
+ // File operations
403
+ gitCheckout(repoUrl: string, options: { branch?: string; targetDir?: string }): Promise<GitCheckoutResponse>;
404
+ mkdir(path: string, options?: { recursive?: boolean }): Promise<MkdirResponse>;
405
+ writeFile(path: string, content: string, options?: { encoding?: string }): Promise<WriteFileResponse>;
406
+ deleteFile(path: string): Promise<DeleteFileResponse>;
407
+ renameFile(oldPath: string, newPath: string): Promise<RenameFileResponse>;
408
+ moveFile(sourcePath: string, destinationPath: string): Promise<MoveFileResponse>;
409
+ readFile(path: string, options?: { encoding?: string }): Promise<ReadFileResponse>;
410
+ readFileStream(path: string): Promise<ReadableStream<Uint8Array>>;
411
+ listFiles(path: string, options?: { recursive?: boolean; includeHidden?: boolean }): Promise<ListFilesResponse>;
412
+
413
+ // Port management
414
+ exposePort(port: number, options: { name?: string; hostname: string }): Promise<{ url: string; port: number; name?: string }>;
415
+ unexposePort(port: number): Promise<void>;
416
+ getExposedPorts(hostname: string): Promise<Array<{ url: string; port: number; name?: string; exposedAt: string }>>;
417
+
418
+ // Environment management
419
+ setEnvVars(envVars: Record<string, string>): Promise<void>;
420
+ setSandboxName(name: string): Promise<void>;
421
+
374
422
  // Code Interpreter API
375
423
  createCodeContext(options?: CreateContextOptions): Promise<CodeContext>;
376
424
  runCode(code: string, options?: RunCodeOptions): Promise<ExecutionResult>;
@@ -379,6 +427,128 @@ export interface ISandbox {
379
427
  deleteCodeContext(contextId: string): Promise<void>;
380
428
  }
381
429
 
430
+ // Execution session returned by createSession()
431
+ // Sessions are full-featured sandbox objects with scoped execution context
432
+ // Inherits all ISandbox methods except createSession (sessions can't create sub-sessions),
433
+ // and setSandboxName (sessions inherit sandbox name).
434
+ export interface ExecutionSession extends Omit<ISandbox, 'createSession' | 'setSandboxName'> {
435
+ /**
436
+ * Session ID
437
+ */
438
+ id: string;
439
+ }
440
+
441
+ // API Response Types
442
+
443
+ export interface ExecuteResponse {
444
+ success: boolean;
445
+ stdout: string;
446
+ stderr: string;
447
+ exitCode: number;
448
+ command: string;
449
+ timestamp: string;
450
+ }
451
+
452
+ export interface GitCheckoutResponse {
453
+ success: boolean;
454
+ stdout: string;
455
+ stderr: string;
456
+ exitCode: number;
457
+ repoUrl: string;
458
+ branch: string;
459
+ targetDir: string;
460
+ timestamp: string;
461
+ }
462
+
463
+ export interface MkdirResponse {
464
+ success: boolean;
465
+ stdout: string;
466
+ stderr: string;
467
+ exitCode: number;
468
+ path: string;
469
+ recursive: boolean;
470
+ timestamp: string;
471
+ }
472
+
473
+ export interface WriteFileResponse {
474
+ success: boolean;
475
+ exitCode: number;
476
+ path: string;
477
+ timestamp: string;
478
+ }
479
+
480
+ export interface ReadFileResponse {
481
+ success: boolean;
482
+ exitCode: number;
483
+ path: string;
484
+ content: string;
485
+ timestamp: string;
486
+
487
+ /**
488
+ * Encoding used for content (utf-8 for text, base64 for binary)
489
+ */
490
+ encoding?: 'utf-8' | 'base64';
491
+
492
+ /**
493
+ * Whether the file is detected as binary
494
+ */
495
+ isBinary?: boolean;
496
+
497
+ /**
498
+ * MIME type of the file (e.g., 'image/png', 'text/plain')
499
+ */
500
+ mimeType?: string;
501
+
502
+ /**
503
+ * File size in bytes
504
+ */
505
+ size?: number;
506
+ }
507
+
508
+ export interface DeleteFileResponse {
509
+ success: boolean;
510
+ exitCode: number;
511
+ path: string;
512
+ timestamp: string;
513
+ }
514
+
515
+ export interface RenameFileResponse {
516
+ success: boolean;
517
+ exitCode: number;
518
+ oldPath: string;
519
+ newPath: string;
520
+ timestamp: string;
521
+ }
522
+
523
+ export interface MoveFileResponse {
524
+ success: boolean;
525
+ exitCode: number;
526
+ sourcePath: string;
527
+ destinationPath: string;
528
+ timestamp: string;
529
+ }
530
+
531
+ export interface ListFilesResponse {
532
+ success: boolean;
533
+ exitCode: number;
534
+ path: string;
535
+ files: Array<{
536
+ name: string;
537
+ absolutePath: string;
538
+ relativePath: string;
539
+ type: 'file' | 'directory' | 'symlink' | 'other';
540
+ size: number;
541
+ modifiedAt: string;
542
+ mode: string;
543
+ permissions: {
544
+ readable: boolean;
545
+ writable: boolean;
546
+ executable: boolean;
547
+ };
548
+ }>;
549
+ timestamp: string;
550
+ }
551
+
382
552
  // Type Guards
383
553
 
384
554
  export function isExecResult(value: any): value is ExecResult {