@cloudflare/sandbox 0.5.1 → 0.5.3

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