@cloudflare/sandbox 0.4.18 → 0.5.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.
Files changed (40) hide show
  1. package/.turbo/turbo-build.log +17 -9
  2. package/CHANGELOG.md +64 -0
  3. package/Dockerfile +5 -1
  4. package/LICENSE +176 -0
  5. package/README.md +1 -1
  6. package/dist/dist-gVyG2H2h.js +612 -0
  7. package/dist/dist-gVyG2H2h.js.map +1 -0
  8. package/dist/index.d.ts +94 -1834
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +489 -678
  11. package/dist/index.js.map +1 -1
  12. package/dist/openai/index.d.ts +67 -0
  13. package/dist/openai/index.d.ts.map +1 -0
  14. package/dist/openai/index.js +362 -0
  15. package/dist/openai/index.js.map +1 -0
  16. package/dist/sandbox-B3vJ541e.d.ts +1729 -0
  17. package/dist/sandbox-B3vJ541e.d.ts.map +1 -0
  18. package/package.json +16 -2
  19. package/src/clients/base-client.ts +107 -46
  20. package/src/index.ts +19 -2
  21. package/src/openai/index.ts +465 -0
  22. package/src/request-handler.ts +2 -1
  23. package/src/sandbox.ts +684 -62
  24. package/src/storage-mount/credential-detection.ts +41 -0
  25. package/src/storage-mount/errors.ts +51 -0
  26. package/src/storage-mount/index.ts +17 -0
  27. package/src/storage-mount/provider-detection.ts +93 -0
  28. package/src/storage-mount/types.ts +17 -0
  29. package/src/version.ts +1 -1
  30. package/tests/base-client.test.ts +218 -0
  31. package/tests/get-sandbox.test.ts +24 -1
  32. package/tests/git-client.test.ts +7 -39
  33. package/tests/openai-shell-editor.test.ts +434 -0
  34. package/tests/port-client.test.ts +25 -35
  35. package/tests/process-client.test.ts +73 -107
  36. package/tests/sandbox.test.ts +128 -1
  37. package/tests/storage-mount/credential-detection.test.ts +119 -0
  38. package/tests/storage-mount/provider-detection.test.ts +77 -0
  39. package/tsconfig.json +2 -2
  40. package/tsdown.config.ts +3 -2
@@ -0,0 +1,1729 @@
1
+ import { Container } from "@cloudflare/containers";
2
+
3
+ //#region ../shared/dist/logger/types.d.ts
4
+
5
+ type LogComponent = 'container' | 'sandbox-do' | 'executor';
6
+ /**
7
+ * Context metadata included in every log entry
8
+ */
9
+ interface LogContext {
10
+ /**
11
+ * Unique trace ID for request correlation across distributed components
12
+ * Format: "tr_" + 16 hex chars (e.g., "tr_7f3a9b2c4e5d6f1a")
13
+ */
14
+ traceId: string;
15
+ /**
16
+ * Component that generated the log
17
+ */
18
+ component: LogComponent;
19
+ /**
20
+ * Sandbox identifier (which sandbox instance)
21
+ */
22
+ sandboxId?: string;
23
+ /**
24
+ * Session identifier (which session within sandbox)
25
+ */
26
+ sessionId?: string;
27
+ /**
28
+ * Process identifier (which background process)
29
+ */
30
+ processId?: string;
31
+ /**
32
+ * Command identifier (which command execution)
33
+ */
34
+ commandId?: string;
35
+ /**
36
+ * Operation name (e.g., 'exec', 'startProcess', 'writeFile')
37
+ */
38
+ operation?: string;
39
+ /**
40
+ * Duration in milliseconds
41
+ */
42
+ duration?: number;
43
+ /**
44
+ * Extensible for additional metadata
45
+ */
46
+ [key: string]: unknown;
47
+ }
48
+ /**
49
+ * Logger interface for structured logging
50
+ *
51
+ * All methods accept optional context that gets merged with the logger's base context.
52
+ */
53
+ interface Logger {
54
+ /**
55
+ * Log debug-level message (most verbose, typically disabled in production)
56
+ *
57
+ * @param message Human-readable message
58
+ * @param context Optional additional context
59
+ */
60
+ debug(message: string, context?: Partial<LogContext>): void;
61
+ /**
62
+ * Log info-level message (normal operational events)
63
+ *
64
+ * @param message Human-readable message
65
+ * @param context Optional additional context
66
+ */
67
+ info(message: string, context?: Partial<LogContext>): void;
68
+ /**
69
+ * Log warning-level message (recoverable issues, degraded state)
70
+ *
71
+ * @param message Human-readable message
72
+ * @param context Optional additional context
73
+ */
74
+ warn(message: string, context?: Partial<LogContext>): void;
75
+ /**
76
+ * Log error-level message (failures, exceptions)
77
+ *
78
+ * @param message Human-readable message
79
+ * @param error Optional Error object to include
80
+ * @param context Optional additional context
81
+ */
82
+ error(message: string, error?: Error, context?: Partial<LogContext>): void;
83
+ /**
84
+ * Create a child logger with additional context
85
+ *
86
+ * The child logger inherits all context from the parent and adds new context.
87
+ * This is useful for adding operation-specific context without passing through parameters.
88
+ *
89
+ * @param context Additional context to merge
90
+ * @returns New logger instance with merged context
91
+ *
92
+ * @example
93
+ * const logger = createLogger({ component: 'sandbox-do', traceId: 'tr_abc123' });
94
+ * const execLogger = logger.child({ operation: 'exec', commandId: 'cmd-456' });
95
+ * execLogger.info('Command started'); // Includes all context: component, traceId, operation, commandId
96
+ */
97
+ child(context: Partial<LogContext>): Logger;
98
+ }
99
+ //#endregion
100
+ //#region ../shared/dist/interpreter-types.d.ts
101
+ interface CreateContextOptions {
102
+ /**
103
+ * Programming language for the context
104
+ * @default 'python'
105
+ */
106
+ language?: 'python' | 'javascript' | 'typescript';
107
+ /**
108
+ * Working directory for the context
109
+ * @default '/workspace'
110
+ */
111
+ cwd?: string;
112
+ /**
113
+ * Environment variables for the context
114
+ */
115
+ envVars?: Record<string, string>;
116
+ /**
117
+ * Request timeout in milliseconds
118
+ * @default 30000
119
+ */
120
+ timeout?: number;
121
+ }
122
+ interface CodeContext {
123
+ /**
124
+ * Unique identifier for the context
125
+ */
126
+ readonly id: string;
127
+ /**
128
+ * Programming language of the context
129
+ */
130
+ readonly language: string;
131
+ /**
132
+ * Current working directory
133
+ */
134
+ readonly cwd: string;
135
+ /**
136
+ * When the context was created
137
+ */
138
+ readonly createdAt: Date;
139
+ /**
140
+ * When the context was last used
141
+ */
142
+ readonly lastUsed: Date;
143
+ }
144
+ interface RunCodeOptions {
145
+ /**
146
+ * Context to run the code in. If not provided, uses default context for the language
147
+ */
148
+ context?: CodeContext;
149
+ /**
150
+ * Language to use if context is not provided
151
+ * @default 'python'
152
+ */
153
+ language?: 'python' | 'javascript' | 'typescript';
154
+ /**
155
+ * Environment variables for this execution
156
+ */
157
+ envVars?: Record<string, string>;
158
+ /**
159
+ * Execution timeout in milliseconds
160
+ * @default 60000
161
+ */
162
+ timeout?: number;
163
+ /**
164
+ * AbortSignal for cancelling execution
165
+ */
166
+ signal?: AbortSignal;
167
+ /**
168
+ * Callback for stdout output
169
+ */
170
+ onStdout?: (output: OutputMessage) => void | Promise<void>;
171
+ /**
172
+ * Callback for stderr output
173
+ */
174
+ onStderr?: (output: OutputMessage) => void | Promise<void>;
175
+ /**
176
+ * Callback for execution results (charts, tables, etc)
177
+ */
178
+ onResult?: (result: Result) => void | Promise<void>;
179
+ /**
180
+ * Callback for execution errors
181
+ */
182
+ onError?: (error: ExecutionError) => void | Promise<void>;
183
+ }
184
+ interface OutputMessage {
185
+ /**
186
+ * The output text
187
+ */
188
+ text: string;
189
+ /**
190
+ * Timestamp of the output
191
+ */
192
+ timestamp: number;
193
+ }
194
+ interface Result {
195
+ /**
196
+ * Plain text representation
197
+ */
198
+ text?: string;
199
+ /**
200
+ * HTML representation (tables, formatted output)
201
+ */
202
+ html?: string;
203
+ /**
204
+ * PNG image data (base64 encoded)
205
+ */
206
+ png?: string;
207
+ /**
208
+ * JPEG image data (base64 encoded)
209
+ */
210
+ jpeg?: string;
211
+ /**
212
+ * SVG image data
213
+ */
214
+ svg?: string;
215
+ /**
216
+ * LaTeX representation
217
+ */
218
+ latex?: string;
219
+ /**
220
+ * Markdown representation
221
+ */
222
+ markdown?: string;
223
+ /**
224
+ * JavaScript code to execute
225
+ */
226
+ javascript?: string;
227
+ /**
228
+ * JSON data
229
+ */
230
+ json?: any;
231
+ /**
232
+ * Chart data if the result is a visualization
233
+ */
234
+ chart?: ChartData;
235
+ /**
236
+ * Raw data object
237
+ */
238
+ data?: any;
239
+ /**
240
+ * Available output formats
241
+ */
242
+ formats(): string[];
243
+ }
244
+ interface ChartData {
245
+ /**
246
+ * Type of chart
247
+ */
248
+ type: 'line' | 'bar' | 'scatter' | 'pie' | 'histogram' | 'heatmap' | 'unknown';
249
+ /**
250
+ * Chart title
251
+ */
252
+ title?: string;
253
+ /**
254
+ * Chart data (format depends on library)
255
+ */
256
+ data: any;
257
+ /**
258
+ * Chart layout/configuration
259
+ */
260
+ layout?: any;
261
+ /**
262
+ * Additional configuration
263
+ */
264
+ config?: any;
265
+ /**
266
+ * Library that generated the chart
267
+ */
268
+ library?: 'matplotlib' | 'plotly' | 'altair' | 'seaborn' | 'unknown';
269
+ /**
270
+ * Base64 encoded image if available
271
+ */
272
+ image?: string;
273
+ }
274
+ interface ExecutionError {
275
+ /**
276
+ * Error name/type (e.g., 'NameError', 'SyntaxError')
277
+ */
278
+ name: string;
279
+ /**
280
+ * Error message
281
+ */
282
+ message: string;
283
+ /**
284
+ * Stack trace
285
+ */
286
+ traceback: string[];
287
+ /**
288
+ * Line number where error occurred
289
+ */
290
+ lineNumber?: number;
291
+ }
292
+ interface ExecutionResult {
293
+ code: string;
294
+ logs: {
295
+ stdout: string[];
296
+ stderr: string[];
297
+ };
298
+ error?: ExecutionError;
299
+ executionCount?: number;
300
+ results: Array<{
301
+ text?: string;
302
+ html?: string;
303
+ png?: string;
304
+ jpeg?: string;
305
+ svg?: string;
306
+ latex?: string;
307
+ markdown?: string;
308
+ javascript?: string;
309
+ json?: any;
310
+ chart?: ChartData;
311
+ data?: any;
312
+ }>;
313
+ }
314
+ declare class Execution {
315
+ readonly code: string;
316
+ readonly context: CodeContext;
317
+ /**
318
+ * All results from the execution
319
+ */
320
+ results: Result[];
321
+ /**
322
+ * Accumulated stdout and stderr
323
+ */
324
+ logs: {
325
+ stdout: string[];
326
+ stderr: string[];
327
+ };
328
+ /**
329
+ * Execution error if any
330
+ */
331
+ error?: ExecutionError;
332
+ /**
333
+ * Execution count (for interpreter)
334
+ */
335
+ executionCount?: number;
336
+ constructor(code: string, context: CodeContext);
337
+ /**
338
+ * Convert to a plain object for serialization
339
+ */
340
+ toJSON(): ExecutionResult;
341
+ }
342
+ //#endregion
343
+ //#region ../shared/dist/types.d.ts
344
+ interface BaseExecOptions {
345
+ /**
346
+ * Maximum execution time in milliseconds
347
+ */
348
+ timeout?: number;
349
+ /**
350
+ * Environment variables for the command
351
+ */
352
+ env?: Record<string, string>;
353
+ /**
354
+ * Working directory for command execution
355
+ */
356
+ cwd?: string;
357
+ /**
358
+ * Text encoding for output (default: 'utf8')
359
+ */
360
+ encoding?: string;
361
+ }
362
+ interface ExecOptions extends BaseExecOptions {
363
+ /**
364
+ * Enable real-time output streaming via callbacks
365
+ */
366
+ stream?: boolean;
367
+ /**
368
+ * Callback for real-time output data
369
+ */
370
+ onOutput?: (stream: 'stdout' | 'stderr', data: string) => void;
371
+ /**
372
+ * Callback when command completes (only when stream: true)
373
+ */
374
+ onComplete?: (result: ExecResult) => void;
375
+ /**
376
+ * Callback for execution errors
377
+ */
378
+ onError?: (error: Error) => void;
379
+ /**
380
+ * AbortSignal for cancelling execution
381
+ */
382
+ signal?: AbortSignal;
383
+ }
384
+ interface ExecResult {
385
+ /**
386
+ * Whether the command succeeded (exitCode === 0)
387
+ */
388
+ success: boolean;
389
+ /**
390
+ * Process exit code
391
+ */
392
+ exitCode: number;
393
+ /**
394
+ * Standard output content
395
+ */
396
+ stdout: string;
397
+ /**
398
+ * Standard error content
399
+ */
400
+ stderr: string;
401
+ /**
402
+ * Command that was executed
403
+ */
404
+ command: string;
405
+ /**
406
+ * Execution duration in milliseconds
407
+ */
408
+ duration: number;
409
+ /**
410
+ * ISO timestamp when command started
411
+ */
412
+ timestamp: string;
413
+ /**
414
+ * Session ID if provided
415
+ */
416
+ sessionId?: string;
417
+ }
418
+ interface ProcessOptions extends BaseExecOptions {
419
+ /**
420
+ * Custom process ID for later reference
421
+ * If not provided, a UUID will be generated
422
+ */
423
+ processId?: string;
424
+ /**
425
+ * Automatically cleanup process record after exit (default: true)
426
+ */
427
+ autoCleanup?: boolean;
428
+ /**
429
+ * Callback when process exits
430
+ */
431
+ onExit?: (code: number | null) => void;
432
+ /**
433
+ * Callback for real-time output (background processes)
434
+ */
435
+ onOutput?: (stream: 'stdout' | 'stderr', data: string) => void;
436
+ /**
437
+ * Callback when process starts successfully
438
+ */
439
+ onStart?: (process: Process) => void;
440
+ /**
441
+ * Callback for process errors
442
+ */
443
+ onError?: (error: Error) => void;
444
+ }
445
+ type ProcessStatus = 'starting' | 'running' | 'completed' | 'failed' | 'killed' | 'error';
446
+ interface Process {
447
+ /**
448
+ * Unique process identifier
449
+ */
450
+ readonly id: string;
451
+ /**
452
+ * System process ID (if available and running)
453
+ */
454
+ readonly pid?: number;
455
+ /**
456
+ * Command that was executed
457
+ */
458
+ readonly command: string;
459
+ /**
460
+ * Current process status
461
+ */
462
+ readonly status: ProcessStatus;
463
+ /**
464
+ * When the process was started
465
+ */
466
+ readonly startTime: Date;
467
+ /**
468
+ * When the process ended (if completed)
469
+ */
470
+ readonly endTime?: Date;
471
+ /**
472
+ * Process exit code (if completed)
473
+ */
474
+ readonly exitCode?: number;
475
+ /**
476
+ * Session ID if provided
477
+ */
478
+ readonly sessionId?: string;
479
+ /**
480
+ * Kill the process
481
+ */
482
+ kill(signal?: string): Promise<void>;
483
+ /**
484
+ * Get current process status (refreshed)
485
+ */
486
+ getStatus(): Promise<ProcessStatus>;
487
+ /**
488
+ * Get accumulated logs
489
+ */
490
+ getLogs(): Promise<{
491
+ stdout: string;
492
+ stderr: string;
493
+ }>;
494
+ }
495
+ interface ExecEvent {
496
+ type: 'start' | 'stdout' | 'stderr' | 'complete' | 'error';
497
+ timestamp: string;
498
+ data?: string;
499
+ command?: string;
500
+ exitCode?: number;
501
+ result?: ExecResult;
502
+ error?: string;
503
+ sessionId?: string;
504
+ }
505
+ interface LogEvent {
506
+ type: 'stdout' | 'stderr' | 'exit' | 'error';
507
+ timestamp: string;
508
+ data: string;
509
+ processId: string;
510
+ sessionId?: string;
511
+ exitCode?: number;
512
+ }
513
+ interface StreamOptions extends BaseExecOptions {
514
+ /**
515
+ * Buffer size for streaming output
516
+ */
517
+ bufferSize?: number;
518
+ /**
519
+ * AbortSignal for cancelling stream
520
+ */
521
+ signal?: AbortSignal;
522
+ }
523
+ interface SessionOptions {
524
+ /**
525
+ * Optional session ID (auto-generated if not provided)
526
+ */
527
+ id?: string;
528
+ /**
529
+ * Session name for identification
530
+ */
531
+ name?: string;
532
+ /**
533
+ * Environment variables for this session
534
+ */
535
+ env?: Record<string, string>;
536
+ /**
537
+ * Working directory
538
+ */
539
+ cwd?: string;
540
+ /**
541
+ * Enable PID namespace isolation (requires CAP_SYS_ADMIN)
542
+ */
543
+ isolation?: boolean;
544
+ }
545
+ interface SandboxOptions {
546
+ /**
547
+ * Duration after which the sandbox instance will sleep if no requests are received
548
+ * Can be:
549
+ * - A string like "30s", "3m", "5m", "1h" (seconds, minutes, or hours)
550
+ * - A number representing seconds (e.g., 180 for 3 minutes)
551
+ * Default: "10m" (10 minutes)
552
+ *
553
+ * Note: Ignored when keepAlive is true
554
+ */
555
+ sleepAfter?: string | number;
556
+ /**
557
+ * Base URL for the sandbox API
558
+ */
559
+ baseUrl?: string;
560
+ /**
561
+ * Keep the container alive indefinitely by preventing automatic shutdown
562
+ * When true, the container will never auto-timeout and must be explicitly destroyed
563
+ * - Any scenario where activity can't be automatically detected
564
+ *
565
+ * Important: You MUST call sandbox.destroy() when done to avoid resource leaks
566
+ *
567
+ * Default: false
568
+ */
569
+ keepAlive?: boolean;
570
+ /**
571
+ * Normalize sandbox ID to lowercase for preview URL compatibility
572
+ *
573
+ * Required for preview URLs because hostnames are case-insensitive (RFC 3986), which
574
+ * would route requests to a different Durable Object instance with IDs containing uppercase letters.
575
+ *
576
+ * **Important:** Different normalizeId values create different Durable Object instances:
577
+ * - `getSandbox(ns, "MyProject")` → DO key: "MyProject"
578
+ * - `getSandbox(ns, "MyProject", {normalizeId: true})` → DO key: "myproject"
579
+ *
580
+ * **Future change:** In a future version, this will default to `true` (automatically lowercase all IDs).
581
+ * IDs with uppercase letters will trigger a warning. To prepare, use lowercase IDs or explicitly
582
+ * pass `normalizeId: true`.
583
+ *
584
+ * @example
585
+ * getSandbox(ns, "my-project") // Works with preview URLs (lowercase)
586
+ * getSandbox(ns, "MyProject", {normalizeId: true}) // Normalized to "myproject"
587
+ *
588
+ * @default false
589
+ */
590
+ normalizeId?: boolean;
591
+ /**
592
+ * Container startup timeout configuration
593
+ *
594
+ * Tune timeouts based on your container's characteristics. SDK defaults (30s instance, 90s ports)
595
+ * work for most use cases. Adjust for heavy containers or fail-fast applications.
596
+ *
597
+ * Can also be configured via environment variables:
598
+ * - SANDBOX_INSTANCE_TIMEOUT_MS
599
+ * - SANDBOX_PORT_TIMEOUT_MS
600
+ * - SANDBOX_POLL_INTERVAL_MS
601
+ *
602
+ * Precedence: options > env vars > SDK defaults
603
+ *
604
+ * @example
605
+ * // Heavy containers (ML models, large apps)
606
+ * getSandbox(ns, id, {
607
+ * containerTimeouts: { portReadyTimeoutMS: 180_000 }
608
+ * })
609
+ *
610
+ * @example
611
+ * // Fail-fast for latency-sensitive apps
612
+ * getSandbox(ns, id, {
613
+ * containerTimeouts: {
614
+ * instanceGetTimeoutMS: 15_000,
615
+ * portReadyTimeoutMS: 30_000
616
+ * }
617
+ * })
618
+ */
619
+ containerTimeouts?: {
620
+ /**
621
+ * Time to wait for container instance provisioning
622
+ * @default 30000 (30s) - or SANDBOX_INSTANCE_TIMEOUT_MS env var
623
+ */
624
+ instanceGetTimeoutMS?: number;
625
+ /**
626
+ * Time to wait for application startup and ports to be ready
627
+ * @default 90000 (90s) - or SANDBOX_PORT_TIMEOUT_MS env var
628
+ */
629
+ portReadyTimeoutMS?: number;
630
+ /**
631
+ * How often to poll for container readiness
632
+ * @default 1000 (1s) - or SANDBOX_POLL_INTERVAL_MS env var
633
+ */
634
+ waitIntervalMS?: number;
635
+ };
636
+ }
637
+ /**
638
+ * Execution session - isolated execution context within a sandbox
639
+ * Returned by sandbox.createSession()
640
+ * Provides the same API as ISandbox but bound to a specific session
641
+ */
642
+ interface MkdirResult {
643
+ success: boolean;
644
+ path: string;
645
+ recursive: boolean;
646
+ timestamp: string;
647
+ exitCode?: number;
648
+ }
649
+ interface WriteFileResult {
650
+ success: boolean;
651
+ path: string;
652
+ timestamp: string;
653
+ exitCode?: number;
654
+ }
655
+ interface ReadFileResult {
656
+ success: boolean;
657
+ path: string;
658
+ content: string;
659
+ timestamp: string;
660
+ exitCode?: number;
661
+ /**
662
+ * Encoding used for content (utf-8 for text, base64 for binary)
663
+ */
664
+ encoding?: 'utf-8' | 'base64';
665
+ /**
666
+ * Whether the file is detected as binary
667
+ */
668
+ isBinary?: boolean;
669
+ /**
670
+ * MIME type of the file (e.g., 'image/png', 'text/plain')
671
+ */
672
+ mimeType?: string;
673
+ /**
674
+ * File size in bytes
675
+ */
676
+ size?: number;
677
+ }
678
+ interface DeleteFileResult {
679
+ success: boolean;
680
+ path: string;
681
+ timestamp: string;
682
+ exitCode?: number;
683
+ }
684
+ interface RenameFileResult {
685
+ success: boolean;
686
+ path: string;
687
+ newPath: string;
688
+ timestamp: string;
689
+ exitCode?: number;
690
+ }
691
+ interface MoveFileResult {
692
+ success: boolean;
693
+ path: string;
694
+ newPath: string;
695
+ timestamp: string;
696
+ exitCode?: number;
697
+ }
698
+ interface FileExistsResult {
699
+ success: boolean;
700
+ path: string;
701
+ exists: boolean;
702
+ timestamp: string;
703
+ }
704
+ interface FileInfo {
705
+ name: string;
706
+ absolutePath: string;
707
+ relativePath: string;
708
+ type: 'file' | 'directory' | 'symlink' | 'other';
709
+ size: number;
710
+ modifiedAt: string;
711
+ mode: string;
712
+ permissions: {
713
+ readable: boolean;
714
+ writable: boolean;
715
+ executable: boolean;
716
+ };
717
+ }
718
+ interface ListFilesOptions {
719
+ recursive?: boolean;
720
+ includeHidden?: boolean;
721
+ }
722
+ interface ListFilesResult {
723
+ success: boolean;
724
+ path: string;
725
+ files: FileInfo[];
726
+ count: number;
727
+ timestamp: string;
728
+ exitCode?: number;
729
+ }
730
+ interface GitCheckoutResult {
731
+ success: boolean;
732
+ repoUrl: string;
733
+ branch: string;
734
+ targetDir: string;
735
+ timestamp: string;
736
+ exitCode?: number;
737
+ }
738
+ /**
739
+ * SSE events for file streaming
740
+ */
741
+ type FileStreamEvent = {
742
+ type: 'metadata';
743
+ mimeType: string;
744
+ size: number;
745
+ isBinary: boolean;
746
+ encoding: 'utf-8' | 'base64';
747
+ } | {
748
+ type: 'chunk';
749
+ data: string;
750
+ } | {
751
+ type: 'complete';
752
+ bytesRead: number;
753
+ } | {
754
+ type: 'error';
755
+ error: string;
756
+ };
757
+ /**
758
+ * File metadata from streaming
759
+ */
760
+ interface FileMetadata {
761
+ mimeType: string;
762
+ size: number;
763
+ isBinary: boolean;
764
+ encoding: 'utf-8' | 'base64';
765
+ }
766
+ /**
767
+ * File stream chunk - either string (text) or Uint8Array (binary, auto-decoded)
768
+ */
769
+ type FileChunk = string | Uint8Array;
770
+ interface ProcessStartResult {
771
+ success: boolean;
772
+ processId: string;
773
+ pid?: number;
774
+ command: string;
775
+ timestamp: string;
776
+ }
777
+ interface ProcessListResult {
778
+ success: boolean;
779
+ processes: Array<{
780
+ id: string;
781
+ pid?: number;
782
+ command: string;
783
+ status: ProcessStatus;
784
+ startTime: string;
785
+ endTime?: string;
786
+ exitCode?: number;
787
+ }>;
788
+ timestamp: string;
789
+ }
790
+ interface ProcessInfoResult {
791
+ success: boolean;
792
+ process: {
793
+ id: string;
794
+ pid?: number;
795
+ command: string;
796
+ status: ProcessStatus;
797
+ startTime: string;
798
+ endTime?: string;
799
+ exitCode?: number;
800
+ };
801
+ timestamp: string;
802
+ }
803
+ interface ProcessKillResult {
804
+ success: boolean;
805
+ processId: string;
806
+ signal?: string;
807
+ timestamp: string;
808
+ }
809
+ interface ProcessLogsResult {
810
+ success: boolean;
811
+ processId: string;
812
+ stdout: string;
813
+ stderr: string;
814
+ timestamp: string;
815
+ }
816
+ interface ProcessCleanupResult {
817
+ success: boolean;
818
+ cleanedCount: number;
819
+ timestamp: string;
820
+ }
821
+ interface SessionDeleteResult {
822
+ success: boolean;
823
+ sessionId: string;
824
+ timestamp: string;
825
+ }
826
+ interface PortExposeResult {
827
+ success: boolean;
828
+ port: number;
829
+ url: string;
830
+ timestamp: string;
831
+ }
832
+ interface PortListResult {
833
+ success: boolean;
834
+ ports: Array<{
835
+ port: number;
836
+ url: string;
837
+ status: 'active' | 'inactive';
838
+ }>;
839
+ timestamp: string;
840
+ }
841
+ interface PortCloseResult {
842
+ success: boolean;
843
+ port: number;
844
+ timestamp: string;
845
+ }
846
+ interface ExecutionSession {
847
+ /** Unique session identifier */
848
+ readonly id: string;
849
+ exec(command: string, options?: ExecOptions): Promise<ExecResult>;
850
+ execStream(command: string, options?: StreamOptions): Promise<ReadableStream<Uint8Array>>;
851
+ startProcess(command: string, options?: ProcessOptions): Promise<Process>;
852
+ listProcesses(): Promise<Process[]>;
853
+ getProcess(id: string): Promise<Process | null>;
854
+ killProcess(id: string, signal?: string): Promise<void>;
855
+ killAllProcesses(): Promise<number>;
856
+ cleanupCompletedProcesses(): Promise<number>;
857
+ getProcessLogs(id: string): Promise<{
858
+ stdout: string;
859
+ stderr: string;
860
+ processId: string;
861
+ }>;
862
+ streamProcessLogs(processId: string, options?: {
863
+ signal?: AbortSignal;
864
+ }): Promise<ReadableStream<Uint8Array>>;
865
+ writeFile(path: string, content: string, options?: {
866
+ encoding?: string;
867
+ }): Promise<WriteFileResult>;
868
+ readFile(path: string, options?: {
869
+ encoding?: string;
870
+ }): Promise<ReadFileResult>;
871
+ readFileStream(path: string): Promise<ReadableStream<Uint8Array>>;
872
+ mkdir(path: string, options?: {
873
+ recursive?: boolean;
874
+ }): Promise<MkdirResult>;
875
+ deleteFile(path: string): Promise<DeleteFileResult>;
876
+ renameFile(oldPath: string, newPath: string): Promise<RenameFileResult>;
877
+ moveFile(sourcePath: string, destinationPath: string): Promise<MoveFileResult>;
878
+ listFiles(path: string, options?: ListFilesOptions): Promise<ListFilesResult>;
879
+ exists(path: string): Promise<FileExistsResult>;
880
+ gitCheckout(repoUrl: string, options?: {
881
+ branch?: string;
882
+ targetDir?: string;
883
+ }): Promise<GitCheckoutResult>;
884
+ setEnvVars(envVars: Record<string, string>): Promise<void>;
885
+ createCodeContext(options?: CreateContextOptions): Promise<CodeContext>;
886
+ runCode(code: string, options?: RunCodeOptions): Promise<ExecutionResult>;
887
+ runCodeStream(code: string, options?: RunCodeOptions): Promise<ReadableStream<Uint8Array>>;
888
+ listCodeContexts(): Promise<CodeContext[]>;
889
+ deleteCodeContext(contextId: string): Promise<void>;
890
+ mountBucket(bucket: string, mountPath: string, options: MountBucketOptions): Promise<void>;
891
+ unmountBucket(mountPath: string): Promise<void>;
892
+ }
893
+ /**
894
+ * Supported S3-compatible storage providers
895
+ */
896
+ type BucketProvider = 'r2' | 's3' | 'gcs';
897
+ /**
898
+ * Credentials for S3-compatible storage
899
+ */
900
+ interface BucketCredentials {
901
+ accessKeyId: string;
902
+ secretAccessKey: string;
903
+ }
904
+ /**
905
+ * Options for mounting an S3-compatible bucket
906
+ */
907
+ interface MountBucketOptions {
908
+ /**
909
+ * S3-compatible endpoint URL
910
+ *
911
+ * Examples:
912
+ * - R2: 'https://abc123.r2.cloudflarestorage.com'
913
+ * - AWS S3: 'https://s3.us-west-2.amazonaws.com'
914
+ * - GCS: 'https://storage.googleapis.com'
915
+ *
916
+ * Required field
917
+ */
918
+ endpoint: string;
919
+ /**
920
+ * Optional provider hint for automatic s3fs flag configuration
921
+ * If not specified, will attempt to detect from endpoint URL.
922
+ *
923
+ * Examples:
924
+ * - 'r2' - Cloudflare R2 (adds nomixupload)
925
+ * - 's3' - Amazon S3 (standard configuration)
926
+ * - 'gcs' - Google Cloud Storage (no special flags needed)
927
+ */
928
+ provider?: BucketProvider;
929
+ /**
930
+ * Explicit credentials (overrides env var auto-detection)
931
+ */
932
+ credentials?: BucketCredentials;
933
+ /**
934
+ * Mount filesystem as read-only
935
+ * Default: false
936
+ */
937
+ readOnly?: boolean;
938
+ /**
939
+ * Advanced: Override or extend s3fs options
940
+ *
941
+ * These will be merged with provider-specific defaults.
942
+ * To override defaults completely, specify all options here.
943
+ *
944
+ * Common options:
945
+ * - 'use_path_request_style' - Use path-style URLs (bucket/path vs bucket.host/path)
946
+ * - 'nomixupload' - Disable mixed multipart uploads (needed for some providers)
947
+ * - 'nomultipart' - Disable all multipart operations
948
+ * - 'sigv2' - Use signature version 2 instead of v4
949
+ * - 'no_check_certificate' - Skip SSL certificate validation (dev/testing only)
950
+ */
951
+ s3fsOptions?: string[];
952
+ }
953
+ interface ISandbox {
954
+ exec(command: string, options?: ExecOptions): Promise<ExecResult>;
955
+ startProcess(command: string, options?: ProcessOptions): Promise<Process>;
956
+ listProcesses(): Promise<Process[]>;
957
+ getProcess(id: string): Promise<Process | null>;
958
+ killProcess(id: string, signal?: string): Promise<void>;
959
+ killAllProcesses(): Promise<number>;
960
+ execStream(command: string, options?: StreamOptions): Promise<ReadableStream<Uint8Array>>;
961
+ streamProcessLogs(processId: string, options?: {
962
+ signal?: AbortSignal;
963
+ }): Promise<ReadableStream<Uint8Array>>;
964
+ cleanupCompletedProcesses(): Promise<number>;
965
+ getProcessLogs(id: string): Promise<{
966
+ stdout: string;
967
+ stderr: string;
968
+ processId: string;
969
+ }>;
970
+ writeFile(path: string, content: string, options?: {
971
+ encoding?: string;
972
+ }): Promise<WriteFileResult>;
973
+ readFile(path: string, options?: {
974
+ encoding?: string;
975
+ }): Promise<ReadFileResult>;
976
+ readFileStream(path: string): Promise<ReadableStream<Uint8Array>>;
977
+ mkdir(path: string, options?: {
978
+ recursive?: boolean;
979
+ }): Promise<MkdirResult>;
980
+ deleteFile(path: string): Promise<DeleteFileResult>;
981
+ renameFile(oldPath: string, newPath: string): Promise<RenameFileResult>;
982
+ moveFile(sourcePath: string, destinationPath: string): Promise<MoveFileResult>;
983
+ listFiles(path: string, options?: ListFilesOptions): Promise<ListFilesResult>;
984
+ exists(path: string, sessionId?: string): Promise<FileExistsResult>;
985
+ gitCheckout(repoUrl: string, options?: {
986
+ branch?: string;
987
+ targetDir?: string;
988
+ }): Promise<GitCheckoutResult>;
989
+ mountBucket(bucket: string, mountPath: string, options: MountBucketOptions): Promise<void>;
990
+ unmountBucket(mountPath: string): Promise<void>;
991
+ createSession(options?: SessionOptions): Promise<ExecutionSession>;
992
+ deleteSession(sessionId: string): Promise<SessionDeleteResult>;
993
+ createCodeContext(options?: CreateContextOptions): Promise<CodeContext>;
994
+ runCode(code: string, options?: RunCodeOptions): Promise<ExecutionResult>;
995
+ runCodeStream(code: string, options?: RunCodeOptions): Promise<ReadableStream>;
996
+ listCodeContexts(): Promise<CodeContext[]>;
997
+ deleteCodeContext(contextId: string): Promise<void>;
998
+ wsConnect(request: Request, port: number): Promise<Response>;
999
+ }
1000
+ declare function isExecResult(value: any): value is ExecResult;
1001
+ declare function isProcess(value: any): value is Process;
1002
+ declare function isProcessStatus(value: string): value is ProcessStatus;
1003
+ //#endregion
1004
+ //#region src/clients/types.d.ts
1005
+ /**
1006
+ * Minimal interface for container fetch functionality
1007
+ */
1008
+ interface ContainerStub {
1009
+ containerFetch(url: string, options: RequestInit, port?: number): Promise<Response>;
1010
+ }
1011
+ /**
1012
+ * Shared HTTP client configuration options
1013
+ */
1014
+ interface HttpClientOptions {
1015
+ logger?: Logger;
1016
+ baseUrl?: string;
1017
+ port?: number;
1018
+ stub?: ContainerStub;
1019
+ onCommandComplete?: (success: boolean, exitCode: number, stdout: string, stderr: string, command: string) => void;
1020
+ onError?: (error: string, command?: string) => void;
1021
+ }
1022
+ /**
1023
+ * Base response interface for all API responses
1024
+ */
1025
+ interface BaseApiResponse {
1026
+ success: boolean;
1027
+ timestamp: string;
1028
+ }
1029
+ /**
1030
+ * Legacy error response interface - deprecated, use ApiErrorResponse
1031
+ */
1032
+ interface ErrorResponse {
1033
+ error: string;
1034
+ details?: string;
1035
+ code?: string;
1036
+ }
1037
+ /**
1038
+ * HTTP request configuration
1039
+ */
1040
+ interface RequestConfig extends RequestInit {
1041
+ endpoint: string;
1042
+ data?: Record<string, any>;
1043
+ }
1044
+ /**
1045
+ * Typed response handler
1046
+ */
1047
+ type ResponseHandler<T> = (response: Response) => Promise<T>;
1048
+ /**
1049
+ * Common session-aware request interface
1050
+ */
1051
+ interface SessionRequest {
1052
+ sessionId?: string;
1053
+ }
1054
+ //#endregion
1055
+ //#region src/clients/base-client.d.ts
1056
+ /**
1057
+ * Abstract base class providing common HTTP functionality for all domain clients
1058
+ */
1059
+ declare abstract class BaseHttpClient {
1060
+ protected baseUrl: string;
1061
+ protected options: HttpClientOptions;
1062
+ protected logger: Logger;
1063
+ constructor(options?: HttpClientOptions);
1064
+ /**
1065
+ * Core HTTP request method with automatic retry for container startup delays
1066
+ * Retries both 503 (provisioning) and 500 (startup failure) errors when they're container-related
1067
+ */
1068
+ protected doFetch(path: string, options?: RequestInit): Promise<Response>;
1069
+ /**
1070
+ * Make a POST request with JSON body
1071
+ */
1072
+ protected post<T>(endpoint: string, data: unknown, responseHandler?: ResponseHandler<T>): Promise<T>;
1073
+ /**
1074
+ * Make a GET request
1075
+ */
1076
+ protected get<T>(endpoint: string, responseHandler?: ResponseHandler<T>): Promise<T>;
1077
+ /**
1078
+ * Make a DELETE request
1079
+ */
1080
+ protected delete<T>(endpoint: string, responseHandler?: ResponseHandler<T>): Promise<T>;
1081
+ /**
1082
+ * Handle HTTP response with error checking and parsing
1083
+ */
1084
+ protected handleResponse<T>(response: Response, customHandler?: ResponseHandler<T>): Promise<T>;
1085
+ /**
1086
+ * Handle error responses with consistent error throwing
1087
+ */
1088
+ protected handleErrorResponse(response: Response): Promise<never>;
1089
+ /**
1090
+ * Create a streaming response handler for Server-Sent Events
1091
+ */
1092
+ protected handleStreamResponse(response: Response): Promise<ReadableStream<Uint8Array>>;
1093
+ /**
1094
+ * Utility method to log successful operations
1095
+ */
1096
+ protected logSuccess(operation: string, details?: string): void;
1097
+ /**
1098
+ * Utility method to log errors intelligently
1099
+ * Only logs unexpected errors (5xx), not expected errors (4xx)
1100
+ *
1101
+ * - 4xx errors (validation, not found, conflicts): Don't log (expected client errors)
1102
+ * - 5xx errors (server failures, internal errors): DO log (unexpected server errors)
1103
+ */
1104
+ protected logError(operation: string, error: unknown): void;
1105
+ /**
1106
+ * Check if response indicates a retryable container error
1107
+ * Uses fail-safe strategy: only retry known transient errors
1108
+ *
1109
+ * TODO: This relies on string matching error messages, which is brittle.
1110
+ * Ideally, the container API should return structured errors with a
1111
+ * `retryable: boolean` field to avoid coupling to error message format.
1112
+ *
1113
+ * @param response - HTTP response to check
1114
+ * @returns true if error is retryable container error, false otherwise
1115
+ */
1116
+ private isRetryableContainerError;
1117
+ private executeFetch;
1118
+ }
1119
+ //#endregion
1120
+ //#region src/clients/command-client.d.ts
1121
+ /**
1122
+ * Request interface for command execution
1123
+ */
1124
+ interface ExecuteRequest extends SessionRequest {
1125
+ command: string;
1126
+ timeoutMs?: number;
1127
+ }
1128
+ /**
1129
+ * Response interface for command execution
1130
+ */
1131
+ interface ExecuteResponse extends BaseApiResponse {
1132
+ stdout: string;
1133
+ stderr: string;
1134
+ exitCode: number;
1135
+ command: string;
1136
+ }
1137
+ /**
1138
+ * Client for command execution operations
1139
+ */
1140
+ declare class CommandClient extends BaseHttpClient {
1141
+ /**
1142
+ * Execute a command and return the complete result
1143
+ * @param command - The command to execute
1144
+ * @param sessionId - The session ID for this command execution
1145
+ * @param timeoutMs - Optional timeout in milliseconds (unlimited by default)
1146
+ */
1147
+ execute(command: string, sessionId: string, timeoutMs?: number): Promise<ExecuteResponse>;
1148
+ /**
1149
+ * Execute a command and return a stream of events
1150
+ * @param command - The command to execute
1151
+ * @param sessionId - The session ID for this command execution
1152
+ */
1153
+ executeStream(command: string, sessionId: string): Promise<ReadableStream<Uint8Array>>;
1154
+ }
1155
+ //#endregion
1156
+ //#region src/clients/file-client.d.ts
1157
+ /**
1158
+ * Request interface for creating directories
1159
+ */
1160
+ interface MkdirRequest extends SessionRequest {
1161
+ path: string;
1162
+ recursive?: boolean;
1163
+ }
1164
+ /**
1165
+ * Request interface for writing files
1166
+ */
1167
+ interface WriteFileRequest extends SessionRequest {
1168
+ path: string;
1169
+ content: string;
1170
+ encoding?: string;
1171
+ }
1172
+ /**
1173
+ * Request interface for reading files
1174
+ */
1175
+ interface ReadFileRequest extends SessionRequest {
1176
+ path: string;
1177
+ encoding?: string;
1178
+ }
1179
+ /**
1180
+ * Request interface for file operations (delete, rename, move)
1181
+ */
1182
+ interface FileOperationRequest extends SessionRequest {
1183
+ path: string;
1184
+ newPath?: string;
1185
+ }
1186
+ /**
1187
+ * Client for file system operations
1188
+ */
1189
+ declare class FileClient extends BaseHttpClient {
1190
+ /**
1191
+ * Create a directory
1192
+ * @param path - Directory path to create
1193
+ * @param sessionId - The session ID for this operation
1194
+ * @param options - Optional settings (recursive)
1195
+ */
1196
+ mkdir(path: string, sessionId: string, options?: {
1197
+ recursive?: boolean;
1198
+ }): Promise<MkdirResult>;
1199
+ /**
1200
+ * Write content to a file
1201
+ * @param path - File path to write to
1202
+ * @param content - Content to write
1203
+ * @param sessionId - The session ID for this operation
1204
+ * @param options - Optional settings (encoding)
1205
+ */
1206
+ writeFile(path: string, content: string, sessionId: string, options?: {
1207
+ encoding?: string;
1208
+ }): Promise<WriteFileResult>;
1209
+ /**
1210
+ * Read content from a file
1211
+ * @param path - File path to read from
1212
+ * @param sessionId - The session ID for this operation
1213
+ * @param options - Optional settings (encoding)
1214
+ */
1215
+ readFile(path: string, sessionId: string, options?: {
1216
+ encoding?: string;
1217
+ }): Promise<ReadFileResult>;
1218
+ /**
1219
+ * Stream a file using Server-Sent Events
1220
+ * Returns a ReadableStream of SSE events containing metadata, chunks, and completion
1221
+ * @param path - File path to stream
1222
+ * @param sessionId - The session ID for this operation
1223
+ */
1224
+ readFileStream(path: string, sessionId: string): Promise<ReadableStream<Uint8Array>>;
1225
+ /**
1226
+ * Delete a file
1227
+ * @param path - File path to delete
1228
+ * @param sessionId - The session ID for this operation
1229
+ */
1230
+ deleteFile(path: string, sessionId: string): Promise<DeleteFileResult>;
1231
+ /**
1232
+ * Rename a file
1233
+ * @param path - Current file path
1234
+ * @param newPath - New file path
1235
+ * @param sessionId - The session ID for this operation
1236
+ */
1237
+ renameFile(path: string, newPath: string, sessionId: string): Promise<RenameFileResult>;
1238
+ /**
1239
+ * Move a file
1240
+ * @param path - Current file path
1241
+ * @param newPath - Destination file path
1242
+ * @param sessionId - The session ID for this operation
1243
+ */
1244
+ moveFile(path: string, newPath: string, sessionId: string): Promise<MoveFileResult>;
1245
+ /**
1246
+ * List files in a directory
1247
+ * @param path - Directory path to list
1248
+ * @param sessionId - The session ID for this operation
1249
+ * @param options - Optional settings (recursive, includeHidden)
1250
+ */
1251
+ listFiles(path: string, sessionId: string, options?: ListFilesOptions): Promise<ListFilesResult>;
1252
+ /**
1253
+ * Check if a file or directory exists
1254
+ * @param path - Path to check
1255
+ * @param sessionId - The session ID for this operation
1256
+ */
1257
+ exists(path: string, sessionId: string): Promise<FileExistsResult>;
1258
+ }
1259
+ //#endregion
1260
+ //#region src/clients/git-client.d.ts
1261
+ /**
1262
+ * Request interface for Git checkout operations
1263
+ */
1264
+ interface GitCheckoutRequest extends SessionRequest {
1265
+ repoUrl: string;
1266
+ branch?: string;
1267
+ targetDir?: string;
1268
+ }
1269
+ /**
1270
+ * Client for Git repository operations
1271
+ */
1272
+ declare class GitClient extends BaseHttpClient {
1273
+ constructor(options?: HttpClientOptions);
1274
+ /**
1275
+ * Clone a Git repository
1276
+ * @param repoUrl - URL of the Git repository to clone
1277
+ * @param sessionId - The session ID for this operation
1278
+ * @param options - Optional settings (branch, targetDir)
1279
+ */
1280
+ checkout(repoUrl: string, sessionId: string, options?: {
1281
+ branch?: string;
1282
+ targetDir?: string;
1283
+ }): Promise<GitCheckoutResult>;
1284
+ /**
1285
+ * Extract repository name from URL for default directory name
1286
+ */
1287
+ private extractRepoName;
1288
+ }
1289
+ //#endregion
1290
+ //#region src/clients/interpreter-client.d.ts
1291
+ interface ExecutionCallbacks {
1292
+ onStdout?: (output: OutputMessage) => void | Promise<void>;
1293
+ onStderr?: (output: OutputMessage) => void | Promise<void>;
1294
+ onResult?: (result: Result) => void | Promise<void>;
1295
+ onError?: (error: ExecutionError) => void | Promise<void>;
1296
+ }
1297
+ declare class InterpreterClient extends BaseHttpClient {
1298
+ private readonly maxRetries;
1299
+ private readonly retryDelayMs;
1300
+ createCodeContext(options?: CreateContextOptions): Promise<CodeContext>;
1301
+ runCodeStream(contextId: string | undefined, code: string, language: string | undefined, callbacks: ExecutionCallbacks, timeoutMs?: number): Promise<void>;
1302
+ listCodeContexts(): Promise<CodeContext[]>;
1303
+ deleteCodeContext(contextId: string): Promise<void>;
1304
+ /**
1305
+ * Execute an operation with automatic retry for transient errors
1306
+ */
1307
+ private executeWithRetry;
1308
+ private isRetryableError;
1309
+ private parseErrorResponse;
1310
+ private readLines;
1311
+ private parseExecutionResult;
1312
+ }
1313
+ //#endregion
1314
+ //#region src/clients/port-client.d.ts
1315
+ /**
1316
+ * Request interface for exposing ports
1317
+ */
1318
+ interface ExposePortRequest {
1319
+ port: number;
1320
+ name?: string;
1321
+ }
1322
+ /**
1323
+ * Request interface for unexposing ports
1324
+ */
1325
+ interface UnexposePortRequest {
1326
+ port: number;
1327
+ }
1328
+ /**
1329
+ * Client for port management and preview URL operations
1330
+ */
1331
+ declare class PortClient extends BaseHttpClient {
1332
+ /**
1333
+ * Expose a port and get a preview URL
1334
+ * @param port - Port number to expose
1335
+ * @param sessionId - The session ID for this operation
1336
+ * @param name - Optional name for the port
1337
+ */
1338
+ exposePort(port: number, sessionId: string, name?: string): Promise<PortExposeResult>;
1339
+ /**
1340
+ * Unexpose a port and remove its preview URL
1341
+ * @param port - Port number to unexpose
1342
+ * @param sessionId - The session ID for this operation
1343
+ */
1344
+ unexposePort(port: number, sessionId: string): Promise<PortCloseResult>;
1345
+ /**
1346
+ * Get all currently exposed ports
1347
+ * @param sessionId - The session ID for this operation
1348
+ */
1349
+ getExposedPorts(sessionId: string): Promise<PortListResult>;
1350
+ }
1351
+ //#endregion
1352
+ //#region src/clients/process-client.d.ts
1353
+ /**
1354
+ * Client for background process management
1355
+ */
1356
+ declare class ProcessClient extends BaseHttpClient {
1357
+ /**
1358
+ * Start a background process
1359
+ * @param command - Command to execute as a background process
1360
+ * @param sessionId - The session ID for this operation
1361
+ * @param options - Optional settings (processId)
1362
+ */
1363
+ startProcess(command: string, sessionId: string, options?: {
1364
+ processId?: string;
1365
+ }): Promise<ProcessStartResult>;
1366
+ /**
1367
+ * List all processes (sandbox-scoped, not session-scoped)
1368
+ */
1369
+ listProcesses(): Promise<ProcessListResult>;
1370
+ /**
1371
+ * Get information about a specific process (sandbox-scoped, not session-scoped)
1372
+ * @param processId - ID of the process to retrieve
1373
+ */
1374
+ getProcess(processId: string): Promise<ProcessInfoResult>;
1375
+ /**
1376
+ * Kill a specific process (sandbox-scoped, not session-scoped)
1377
+ * @param processId - ID of the process to kill
1378
+ */
1379
+ killProcess(processId: string): Promise<ProcessKillResult>;
1380
+ /**
1381
+ * Kill all running processes (sandbox-scoped, not session-scoped)
1382
+ */
1383
+ killAllProcesses(): Promise<ProcessCleanupResult>;
1384
+ /**
1385
+ * Get logs from a specific process (sandbox-scoped, not session-scoped)
1386
+ * @param processId - ID of the process to get logs from
1387
+ */
1388
+ getProcessLogs(processId: string): Promise<ProcessLogsResult>;
1389
+ /**
1390
+ * Stream logs from a specific process (sandbox-scoped, not session-scoped)
1391
+ * @param processId - ID of the process to stream logs from
1392
+ */
1393
+ streamProcessLogs(processId: string): Promise<ReadableStream<Uint8Array>>;
1394
+ }
1395
+ //#endregion
1396
+ //#region src/clients/utility-client.d.ts
1397
+ /**
1398
+ * Response interface for ping operations
1399
+ */
1400
+ interface PingResponse extends BaseApiResponse {
1401
+ message: string;
1402
+ uptime?: number;
1403
+ }
1404
+ /**
1405
+ * Response interface for getting available commands
1406
+ */
1407
+ interface CommandsResponse extends BaseApiResponse {
1408
+ availableCommands: string[];
1409
+ count: number;
1410
+ }
1411
+ /**
1412
+ * Request interface for creating sessions
1413
+ */
1414
+ interface CreateSessionRequest {
1415
+ id: string;
1416
+ env?: Record<string, string>;
1417
+ cwd?: string;
1418
+ }
1419
+ /**
1420
+ * Response interface for creating sessions
1421
+ */
1422
+ interface CreateSessionResponse extends BaseApiResponse {
1423
+ id: string;
1424
+ message: string;
1425
+ }
1426
+ /**
1427
+ * Request interface for deleting sessions
1428
+ */
1429
+ interface DeleteSessionRequest {
1430
+ sessionId: string;
1431
+ }
1432
+ /**
1433
+ * Response interface for deleting sessions
1434
+ */
1435
+ interface DeleteSessionResponse extends BaseApiResponse {
1436
+ sessionId: string;
1437
+ }
1438
+ /**
1439
+ * Client for health checks and utility operations
1440
+ */
1441
+ declare class UtilityClient extends BaseHttpClient {
1442
+ /**
1443
+ * Ping the sandbox to check if it's responsive
1444
+ */
1445
+ ping(): Promise<string>;
1446
+ /**
1447
+ * Get list of available commands in the sandbox environment
1448
+ */
1449
+ getCommands(): Promise<string[]>;
1450
+ /**
1451
+ * Create a new execution session
1452
+ * @param options - Session configuration (id, env, cwd)
1453
+ */
1454
+ createSession(options: CreateSessionRequest): Promise<CreateSessionResponse>;
1455
+ /**
1456
+ * Delete an execution session
1457
+ * @param sessionId - Session ID to delete
1458
+ */
1459
+ deleteSession(sessionId: string): Promise<DeleteSessionResponse>;
1460
+ /**
1461
+ * Get the container version
1462
+ * Returns the version embedded in the Docker image during build
1463
+ */
1464
+ getVersion(): Promise<string>;
1465
+ }
1466
+ //#endregion
1467
+ //#region src/clients/sandbox-client.d.ts
1468
+ /**
1469
+ * Main sandbox client that composes all domain-specific clients
1470
+ * Provides organized access to all sandbox functionality
1471
+ */
1472
+ declare class SandboxClient {
1473
+ readonly commands: CommandClient;
1474
+ readonly files: FileClient;
1475
+ readonly processes: ProcessClient;
1476
+ readonly ports: PortClient;
1477
+ readonly git: GitClient;
1478
+ readonly interpreter: InterpreterClient;
1479
+ readonly utils: UtilityClient;
1480
+ constructor(options: HttpClientOptions);
1481
+ }
1482
+ //#endregion
1483
+ //#region src/sandbox.d.ts
1484
+ declare function getSandbox(ns: DurableObjectNamespace<Sandbox>, id: string, options?: SandboxOptions): Sandbox;
1485
+ declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox {
1486
+ defaultPort: number;
1487
+ sleepAfter: string | number;
1488
+ client: SandboxClient;
1489
+ private codeInterpreter;
1490
+ private sandboxName;
1491
+ private normalizeId;
1492
+ private baseUrl;
1493
+ private portTokens;
1494
+ private defaultSession;
1495
+ envVars: Record<string, string>;
1496
+ private logger;
1497
+ private keepAliveEnabled;
1498
+ private activeMounts;
1499
+ /**
1500
+ * Default container startup timeouts (conservative for production)
1501
+ * Based on Cloudflare docs: "Containers take several minutes to provision"
1502
+ */
1503
+ private readonly DEFAULT_CONTAINER_TIMEOUTS;
1504
+ /**
1505
+ * Active container timeout configuration
1506
+ * Can be set via options, env vars, or defaults
1507
+ */
1508
+ private containerTimeouts;
1509
+ constructor(ctx: DurableObjectState<{}>, env: Env);
1510
+ setSandboxName(name: string, normalizeId?: boolean): Promise<void>;
1511
+ setBaseUrl(baseUrl: string): Promise<void>;
1512
+ setSleepAfter(sleepAfter: string | number): Promise<void>;
1513
+ setKeepAlive(keepAlive: boolean): Promise<void>;
1514
+ setEnvVars(envVars: Record<string, string>): Promise<void>;
1515
+ /**
1516
+ * RPC method to configure container startup timeouts
1517
+ */
1518
+ setContainerTimeouts(timeouts: NonNullable<SandboxOptions['containerTimeouts']>): Promise<void>;
1519
+ /**
1520
+ * Validate a timeout value is within acceptable range
1521
+ * Throws error if invalid - used for user-provided values
1522
+ */
1523
+ private validateTimeout;
1524
+ /**
1525
+ * Get default timeouts with env var fallbacks and validation
1526
+ * Precedence: SDK defaults < Env vars < User config
1527
+ */
1528
+ private getDefaultTimeouts;
1529
+ mountBucket(bucket: string, mountPath: string, options: MountBucketOptions): Promise<void>;
1530
+ /**
1531
+ * Manually unmount a bucket filesystem
1532
+ *
1533
+ * @param mountPath - Absolute path where the bucket is mounted
1534
+ * @throws InvalidMountConfigError if mount path doesn't exist or isn't mounted
1535
+ */
1536
+ unmountBucket(mountPath: string): Promise<void>;
1537
+ /**
1538
+ * Validate mount options
1539
+ */
1540
+ private validateMountOptions;
1541
+ /**
1542
+ * Generate unique password file path for s3fs credentials
1543
+ */
1544
+ private generatePasswordFilePath;
1545
+ /**
1546
+ * Create password file with s3fs credentials
1547
+ * Format: bucket:accessKeyId:secretAccessKey
1548
+ */
1549
+ private createPasswordFile;
1550
+ /**
1551
+ * Delete password file
1552
+ */
1553
+ private deletePasswordFile;
1554
+ /**
1555
+ * Execute S3FS mount command
1556
+ */
1557
+ private executeS3FSMount;
1558
+ /**
1559
+ * Cleanup and destroy the sandbox container
1560
+ */
1561
+ destroy(): Promise<void>;
1562
+ onStart(): void;
1563
+ /**
1564
+ * Check if the container version matches the SDK version
1565
+ * Logs a warning if there's a mismatch
1566
+ */
1567
+ private checkVersionCompatibility;
1568
+ onStop(): Promise<void>;
1569
+ onError(error: unknown): void;
1570
+ /**
1571
+ * Override Container.containerFetch to use production-friendly timeouts
1572
+ * Automatically starts container with longer timeouts if not running
1573
+ */
1574
+ containerFetch(requestOrUrl: Request | string | URL, portOrInit?: number | RequestInit, portParam?: number): Promise<Response>;
1575
+ /**
1576
+ * Helper: Check if error is "no container instance available"
1577
+ */
1578
+ private isNoInstanceError;
1579
+ /**
1580
+ * Helper: Parse containerFetch arguments (supports multiple signatures)
1581
+ */
1582
+ private parseContainerFetchArgs;
1583
+ /**
1584
+ * Override onActivityExpired to prevent automatic shutdown when keepAlive is enabled
1585
+ * When keepAlive is disabled, calls parent implementation which stops the container
1586
+ */
1587
+ onActivityExpired(): Promise<void>;
1588
+ fetch(request: Request): Promise<Response>;
1589
+ wsConnect(request: Request, port: number): Promise<Response>;
1590
+ private determinePort;
1591
+ /**
1592
+ * Ensure default session exists - lazy initialization
1593
+ * This is called automatically by all public methods that need a session
1594
+ *
1595
+ * The session is persisted to Durable Object storage to survive hot reloads
1596
+ * during development. If a session already exists in the container after reload,
1597
+ * we reuse it instead of trying to create a new one.
1598
+ */
1599
+ private ensureDefaultSession;
1600
+ exec(command: string, options?: ExecOptions): Promise<ExecResult>;
1601
+ /**
1602
+ * Internal session-aware exec implementation
1603
+ * Used by both public exec() and session wrappers
1604
+ */
1605
+ private execWithSession;
1606
+ private executeWithStreaming;
1607
+ private mapExecuteResponseToExecResult;
1608
+ /**
1609
+ * Create a Process domain object from HTTP client DTO
1610
+ * Centralizes process object creation with bound methods
1611
+ * This eliminates duplication across startProcess, listProcesses, getProcess, and session wrappers
1612
+ */
1613
+ private createProcessFromDTO;
1614
+ startProcess(command: string, options?: ProcessOptions, sessionId?: string): Promise<Process>;
1615
+ listProcesses(sessionId?: string): Promise<Process[]>;
1616
+ getProcess(id: string, sessionId?: string): Promise<Process | null>;
1617
+ killProcess(id: string, signal?: string, sessionId?: string): Promise<void>;
1618
+ killAllProcesses(sessionId?: string): Promise<number>;
1619
+ cleanupCompletedProcesses(sessionId?: string): Promise<number>;
1620
+ getProcessLogs(id: string, sessionId?: string): Promise<{
1621
+ stdout: string;
1622
+ stderr: string;
1623
+ processId: string;
1624
+ }>;
1625
+ execStream(command: string, options?: StreamOptions): Promise<ReadableStream<Uint8Array>>;
1626
+ /**
1627
+ * Internal session-aware execStream implementation
1628
+ */
1629
+ private execStreamWithSession;
1630
+ /**
1631
+ * Stream logs from a background process as a ReadableStream.
1632
+ */
1633
+ streamProcessLogs(processId: string, options?: {
1634
+ signal?: AbortSignal;
1635
+ }): Promise<ReadableStream<Uint8Array>>;
1636
+ gitCheckout(repoUrl: string, options: {
1637
+ branch?: string;
1638
+ targetDir?: string;
1639
+ sessionId?: string;
1640
+ }): Promise<GitCheckoutResult>;
1641
+ mkdir(path: string, options?: {
1642
+ recursive?: boolean;
1643
+ sessionId?: string;
1644
+ }): Promise<MkdirResult>;
1645
+ writeFile(path: string, content: string, options?: {
1646
+ encoding?: string;
1647
+ sessionId?: string;
1648
+ }): Promise<WriteFileResult>;
1649
+ deleteFile(path: string, sessionId?: string): Promise<DeleteFileResult>;
1650
+ renameFile(oldPath: string, newPath: string, sessionId?: string): Promise<RenameFileResult>;
1651
+ moveFile(sourcePath: string, destinationPath: string, sessionId?: string): Promise<MoveFileResult>;
1652
+ readFile(path: string, options?: {
1653
+ encoding?: string;
1654
+ sessionId?: string;
1655
+ }): Promise<ReadFileResult>;
1656
+ /**
1657
+ * Stream a file from the sandbox using Server-Sent Events
1658
+ * Returns a ReadableStream that can be consumed with streamFile() or collectFile() utilities
1659
+ * @param path - Path to the file to stream
1660
+ * @param options - Optional session ID
1661
+ */
1662
+ readFileStream(path: string, options?: {
1663
+ sessionId?: string;
1664
+ }): Promise<ReadableStream<Uint8Array>>;
1665
+ listFiles(path: string, options?: {
1666
+ recursive?: boolean;
1667
+ includeHidden?: boolean;
1668
+ }): Promise<ListFilesResult>;
1669
+ exists(path: string, sessionId?: string): Promise<FileExistsResult>;
1670
+ exposePort(port: number, options: {
1671
+ name?: string;
1672
+ hostname: string;
1673
+ }): Promise<{
1674
+ url: string;
1675
+ port: number;
1676
+ name: string | undefined;
1677
+ }>;
1678
+ unexposePort(port: number): Promise<void>;
1679
+ getExposedPorts(hostname: string): Promise<{
1680
+ url: string;
1681
+ port: number;
1682
+ status: "active" | "inactive";
1683
+ }[]>;
1684
+ isPortExposed(port: number): Promise<boolean>;
1685
+ validatePortToken(port: number, token: string): Promise<boolean>;
1686
+ private generatePortToken;
1687
+ private persistPortTokens;
1688
+ private constructPreviewUrl;
1689
+ /**
1690
+ * Create isolated execution session for advanced use cases
1691
+ * Returns ExecutionSession with full sandbox API bound to specific session
1692
+ */
1693
+ createSession(options?: SessionOptions): Promise<ExecutionSession>;
1694
+ /**
1695
+ * Get an existing session by ID
1696
+ * Returns ExecutionSession wrapper bound to the specified session
1697
+ *
1698
+ * This is useful for retrieving sessions across different requests/contexts
1699
+ * without storing the ExecutionSession object (which has RPC lifecycle limitations)
1700
+ *
1701
+ * @param sessionId - The ID of an existing session
1702
+ * @returns ExecutionSession wrapper bound to the session
1703
+ */
1704
+ getSession(sessionId: string): Promise<ExecutionSession>;
1705
+ /**
1706
+ * Delete an execution session
1707
+ * Cleans up session resources and removes it from the container
1708
+ * Note: Cannot delete the default session. To reset the default session,
1709
+ * use sandbox.destroy() to terminate the entire sandbox.
1710
+ *
1711
+ * @param sessionId - The ID of the session to delete
1712
+ * @returns Result with success status, sessionId, and timestamp
1713
+ * @throws Error if attempting to delete the default session
1714
+ */
1715
+ deleteSession(sessionId: string): Promise<SessionDeleteResult>;
1716
+ /**
1717
+ * Internal helper to create ExecutionSession wrapper for a given sessionId
1718
+ * Used by both createSession and getSession
1719
+ */
1720
+ private getSessionWrapper;
1721
+ createCodeContext(options?: CreateContextOptions): Promise<CodeContext>;
1722
+ runCode(code: string, options?: RunCodeOptions): Promise<ExecutionResult>;
1723
+ runCodeStream(code: string, options?: RunCodeOptions): Promise<ReadableStream>;
1724
+ listCodeContexts(): Promise<CodeContext[]>;
1725
+ deleteCodeContext(contextId: string): Promise<void>;
1726
+ }
1727
+ //#endregion
1728
+ export { ProcessCleanupResult as $, HttpClientOptions as A, ExecutionSession as B, WriteFileRequest as C, BaseApiResponse as D, ExecuteResponse as E, BucketCredentials as F, ISandbox as G, FileMetadata as H, BucketProvider as I, MountBucketOptions as J, ListFilesOptions as K, ExecEvent as L, ResponseHandler as M, SessionRequest as N, ContainerStub as O, BaseExecOptions as P, Process as Q, ExecOptions as R, ReadFileRequest as S, ExecuteRequest as T, FileStreamEvent as U, FileChunk as V, GitCheckoutResult as W, PortExposeResult as X, PortCloseResult as Y, PortListResult as Z, GitCheckoutRequest as _, RunCodeOptions as _t, CreateSessionRequest as a, ProcessStartResult as at, FileOperationRequest as b, DeleteSessionResponse as c, SessionOptions as ct, ProcessClient as d, isProcess as dt, ProcessInfoResult as et, ExposePortRequest as f, isProcessStatus as ft, InterpreterClient as g, ExecutionResult as gt, ExecutionCallbacks as h, Execution as ht, CommandsResponse as i, ProcessOptions as it, RequestConfig as j, ErrorResponse as k, PingResponse as l, StreamOptions as lt, UnexposePortRequest as m, CreateContextOptions as mt, getSandbox as n, ProcessListResult as nt, CreateSessionResponse as o, ProcessStatus as ot, PortClient as p, CodeContext as pt, LogEvent as q, SandboxClient as r, ProcessLogsResult as rt, DeleteSessionRequest as s, SandboxOptions as st, Sandbox as t, ProcessKillResult as tt, UtilityClient as u, isExecResult as ut, GitClient as v, CommandClient as w, MkdirRequest as x, FileClient as y, ExecResult as z };
1729
+ //# sourceMappingURL=sandbox-B3vJ541e.d.ts.map