@cloudflare/sandbox 0.3.7 → 0.4.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 (120) hide show
  1. package/.turbo/turbo-build.log +44 -0
  2. package/CHANGELOG.md +8 -10
  3. package/Dockerfile +82 -18
  4. package/README.md +89 -824
  5. package/dist/chunk-53JFOF7F.js +2352 -0
  6. package/dist/chunk-53JFOF7F.js.map +1 -0
  7. package/dist/chunk-BFVUNTP4.js +104 -0
  8. package/dist/chunk-BFVUNTP4.js.map +1 -0
  9. package/dist/{chunk-NNGBXDMY.js → chunk-EKSWCBCA.js} +3 -6
  10. package/dist/chunk-EKSWCBCA.js.map +1 -0
  11. package/dist/chunk-JXZMAU2C.js +559 -0
  12. package/dist/chunk-JXZMAU2C.js.map +1 -0
  13. package/dist/{chunk-6UAWTJ5S.js → chunk-Z532A7QC.js} +13 -20
  14. package/dist/{chunk-6UAWTJ5S.js.map → chunk-Z532A7QC.js.map} +1 -1
  15. package/dist/file-stream.d.ts +16 -38
  16. package/dist/file-stream.js +1 -2
  17. package/dist/index.d.ts +6 -5
  18. package/dist/index.js +45 -38
  19. package/dist/interpreter.d.ts +3 -3
  20. package/dist/interpreter.js +2 -2
  21. package/dist/request-handler.d.ts +4 -3
  22. package/dist/request-handler.js +4 -7
  23. package/dist/sandbox-D9K2ypln.d.ts +583 -0
  24. package/dist/sandbox.d.ts +3 -3
  25. package/dist/sandbox.js +4 -7
  26. package/dist/security.d.ts +4 -3
  27. package/dist/security.js +3 -3
  28. package/dist/sse-parser.js +1 -1
  29. package/package.json +12 -4
  30. package/src/clients/base-client.ts +280 -0
  31. package/src/clients/command-client.ts +115 -0
  32. package/src/clients/file-client.ts +269 -0
  33. package/src/clients/git-client.ts +92 -0
  34. package/src/clients/index.ts +63 -0
  35. package/src/{interpreter-client.ts → clients/interpreter-client.ts} +148 -171
  36. package/src/clients/port-client.ts +105 -0
  37. package/src/clients/process-client.ts +177 -0
  38. package/src/clients/sandbox-client.ts +41 -0
  39. package/src/clients/types.ts +84 -0
  40. package/src/clients/utility-client.ts +94 -0
  41. package/src/errors/adapter.ts +180 -0
  42. package/src/errors/classes.ts +469 -0
  43. package/src/errors/index.ts +105 -0
  44. package/src/file-stream.ts +119 -117
  45. package/src/index.ts +81 -69
  46. package/src/interpreter.ts +17 -8
  47. package/src/request-handler.ts +69 -43
  48. package/src/sandbox.ts +694 -533
  49. package/src/security.ts +14 -23
  50. package/src/sse-parser.ts +4 -8
  51. package/startup.sh +3 -0
  52. package/tests/base-client.test.ts +328 -0
  53. package/tests/command-client.test.ts +407 -0
  54. package/tests/file-client.test.ts +643 -0
  55. package/tests/file-stream.test.ts +306 -0
  56. package/tests/git-client.test.ts +328 -0
  57. package/tests/port-client.test.ts +301 -0
  58. package/tests/process-client.test.ts +658 -0
  59. package/tests/sandbox.test.ts +465 -0
  60. package/tests/sse-parser.test.ts +290 -0
  61. package/tests/utility-client.test.ts +266 -0
  62. package/tests/wrangler.jsonc +35 -0
  63. package/tsconfig.json +9 -1
  64. package/vitest.config.ts +31 -0
  65. package/container_src/bun.lock +0 -76
  66. package/container_src/circuit-breaker.ts +0 -121
  67. package/container_src/control-process.ts +0 -784
  68. package/container_src/handler/exec.ts +0 -185
  69. package/container_src/handler/file.ts +0 -457
  70. package/container_src/handler/git.ts +0 -130
  71. package/container_src/handler/ports.ts +0 -314
  72. package/container_src/handler/process.ts +0 -568
  73. package/container_src/handler/session.ts +0 -92
  74. package/container_src/index.ts +0 -601
  75. package/container_src/interpreter-service.ts +0 -276
  76. package/container_src/isolation.ts +0 -1213
  77. package/container_src/mime-processor.ts +0 -255
  78. package/container_src/package.json +0 -18
  79. package/container_src/runtime/executors/javascript/node_executor.ts +0 -123
  80. package/container_src/runtime/executors/python/ipython_executor.py +0 -338
  81. package/container_src/runtime/executors/typescript/ts_executor.ts +0 -138
  82. package/container_src/runtime/process-pool.ts +0 -464
  83. package/container_src/shell-escape.ts +0 -42
  84. package/container_src/startup.sh +0 -11
  85. package/container_src/types.ts +0 -131
  86. package/dist/chunk-32UDXUPC.js +0 -671
  87. package/dist/chunk-32UDXUPC.js.map +0 -1
  88. package/dist/chunk-5DILEXGY.js +0 -85
  89. package/dist/chunk-5DILEXGY.js.map +0 -1
  90. package/dist/chunk-D3U63BZP.js +0 -240
  91. package/dist/chunk-D3U63BZP.js.map +0 -1
  92. package/dist/chunk-FXYPFGOZ.js +0 -129
  93. package/dist/chunk-FXYPFGOZ.js.map +0 -1
  94. package/dist/chunk-JTKON2SH.js +0 -113
  95. package/dist/chunk-JTKON2SH.js.map +0 -1
  96. package/dist/chunk-NNGBXDMY.js.map +0 -1
  97. package/dist/chunk-SQLJNZ3K.js +0 -674
  98. package/dist/chunk-SQLJNZ3K.js.map +0 -1
  99. package/dist/chunk-W7TVRPBG.js +0 -108
  100. package/dist/chunk-W7TVRPBG.js.map +0 -1
  101. package/dist/client-B3RUab0s.d.ts +0 -225
  102. package/dist/client.d.ts +0 -4
  103. package/dist/client.js +0 -7
  104. package/dist/client.js.map +0 -1
  105. package/dist/errors.d.ts +0 -95
  106. package/dist/errors.js +0 -27
  107. package/dist/errors.js.map +0 -1
  108. package/dist/interpreter-client.d.ts +0 -4
  109. package/dist/interpreter-client.js +0 -9
  110. package/dist/interpreter-client.js.map +0 -1
  111. package/dist/interpreter-types.d.ts +0 -259
  112. package/dist/interpreter-types.js +0 -9
  113. package/dist/interpreter-types.js.map +0 -1
  114. package/dist/types.d.ts +0 -453
  115. package/dist/types.js +0 -45
  116. package/dist/types.js.map +0 -1
  117. package/src/client.ts +0 -1048
  118. package/src/errors.ts +0 -219
  119. package/src/interpreter-types.ts +0 -390
  120. package/src/types.ts +0 -571
@@ -0,0 +1,583 @@
1
+ import * as _repo_shared from '@repo/shared';
2
+ import { Logger, MkdirResult, WriteFileResult, ReadFileResult, DeleteFileResult, RenameFileResult, MoveFileResult, ListFilesOptions, ListFilesResult, GitCheckoutResult, CreateContextOptions, CodeContext, OutputMessage, Result, ExecutionError, PortExposeResult, PortCloseResult, PortListResult, ProcessStartResult, ProcessListResult, ProcessInfoResult, ProcessKillResult, ProcessCleanupResult, ProcessLogsResult, ISandbox, ExecOptions, ExecResult, ProcessOptions, Process, StreamOptions, SessionOptions, ExecutionSession, RunCodeOptions, ExecutionResult } from '@repo/shared';
3
+ import { DurableObject } from 'cloudflare:workers';
4
+ import { Container } from '@cloudflare/containers';
5
+
6
+ /**
7
+ * Minimal interface for container fetch functionality
8
+ */
9
+ interface ContainerStub {
10
+ containerFetch(url: string, options: RequestInit, port?: number): Promise<Response>;
11
+ }
12
+ /**
13
+ * Shared HTTP client configuration options
14
+ */
15
+ interface HttpClientOptions {
16
+ logger?: Logger;
17
+ baseUrl?: string;
18
+ port?: number;
19
+ stub?: ContainerStub;
20
+ onCommandComplete?: (success: boolean, exitCode: number, stdout: string, stderr: string, command: string) => void;
21
+ onError?: (error: string, command?: string) => void;
22
+ }
23
+ /**
24
+ * Base response interface for all API responses
25
+ */
26
+ interface BaseApiResponse {
27
+ success: boolean;
28
+ timestamp: string;
29
+ }
30
+ /**
31
+ * Legacy error response interface - deprecated, use ApiErrorResponse
32
+ */
33
+ interface ErrorResponse {
34
+ error: string;
35
+ details?: string;
36
+ code?: string;
37
+ }
38
+ /**
39
+ * HTTP request configuration
40
+ */
41
+ interface RequestConfig extends RequestInit {
42
+ endpoint: string;
43
+ data?: Record<string, any>;
44
+ }
45
+ /**
46
+ * Typed response handler
47
+ */
48
+ type ResponseHandler<T> = (response: Response) => Promise<T>;
49
+ /**
50
+ * Common session-aware request interface
51
+ */
52
+ interface SessionRequest {
53
+ sessionId?: string;
54
+ }
55
+
56
+ /**
57
+ * Abstract base class providing common HTTP functionality for all domain clients
58
+ */
59
+ declare abstract class BaseHttpClient {
60
+ protected baseUrl: string;
61
+ protected options: HttpClientOptions;
62
+ protected logger: Logger;
63
+ constructor(options?: HttpClientOptions);
64
+ /**
65
+ * Core HTTP request method with automatic retry for container provisioning delays
66
+ */
67
+ protected doFetch(path: string, options?: RequestInit): Promise<Response>;
68
+ /**
69
+ * Make a POST request with JSON body
70
+ */
71
+ protected post<T>(endpoint: string, data: Record<string, any>, responseHandler?: ResponseHandler<T>): Promise<T>;
72
+ /**
73
+ * Make a GET request
74
+ */
75
+ protected get<T>(endpoint: string, responseHandler?: ResponseHandler<T>): Promise<T>;
76
+ /**
77
+ * Make a DELETE request
78
+ */
79
+ protected delete<T>(endpoint: string, responseHandler?: ResponseHandler<T>): Promise<T>;
80
+ /**
81
+ * Handle HTTP response with error checking and parsing
82
+ */
83
+ protected handleResponse<T>(response: Response, customHandler?: ResponseHandler<T>): Promise<T>;
84
+ /**
85
+ * Handle error responses with consistent error throwing
86
+ */
87
+ protected handleErrorResponse(response: Response): Promise<never>;
88
+ /**
89
+ * Create a streaming response handler for Server-Sent Events
90
+ */
91
+ protected handleStreamResponse(response: Response): Promise<ReadableStream<Uint8Array>>;
92
+ /**
93
+ * Utility method to log successful operations
94
+ */
95
+ protected logSuccess(operation: string, details?: string): void;
96
+ /**
97
+ * Utility method to log errors intelligently
98
+ * Only logs unexpected errors (5xx), not expected errors (4xx)
99
+ *
100
+ * - 4xx errors (validation, not found, conflicts): Don't log (expected client errors)
101
+ * - 5xx errors (server failures, internal errors): DO log (unexpected server errors)
102
+ */
103
+ protected logError(operation: string, error: unknown): void;
104
+ /**
105
+ * Check if 503 response is from container provisioning (retryable)
106
+ * vs user application (not retryable)
107
+ */
108
+ private isContainerProvisioningError;
109
+ private executeFetch;
110
+ }
111
+
112
+ /**
113
+ * Request interface for command execution
114
+ */
115
+ interface ExecuteRequest extends SessionRequest {
116
+ command: string;
117
+ timeoutMs?: number;
118
+ }
119
+ /**
120
+ * Response interface for command execution
121
+ */
122
+ interface ExecuteResponse extends BaseApiResponse {
123
+ stdout: string;
124
+ stderr: string;
125
+ exitCode: number;
126
+ command: string;
127
+ }
128
+ /**
129
+ * Client for command execution operations
130
+ */
131
+ declare class CommandClient extends BaseHttpClient {
132
+ /**
133
+ * Execute a command and return the complete result
134
+ * @param command - The command to execute
135
+ * @param sessionId - The session ID for this command execution
136
+ * @param timeoutMs - Optional timeout in milliseconds (unlimited by default)
137
+ */
138
+ execute(command: string, sessionId: string, timeoutMs?: number): Promise<ExecuteResponse>;
139
+ /**
140
+ * Execute a command and return a stream of events
141
+ * @param command - The command to execute
142
+ * @param sessionId - The session ID for this command execution
143
+ */
144
+ executeStream(command: string, sessionId: string): Promise<ReadableStream<Uint8Array>>;
145
+ }
146
+
147
+ /**
148
+ * Request interface for creating directories
149
+ */
150
+ interface MkdirRequest extends SessionRequest {
151
+ path: string;
152
+ recursive?: boolean;
153
+ }
154
+ /**
155
+ * Request interface for writing files
156
+ */
157
+ interface WriteFileRequest extends SessionRequest {
158
+ path: string;
159
+ content: string;
160
+ encoding?: string;
161
+ }
162
+ /**
163
+ * Request interface for reading files
164
+ */
165
+ interface ReadFileRequest extends SessionRequest {
166
+ path: string;
167
+ encoding?: string;
168
+ }
169
+ /**
170
+ * Request interface for file operations (delete, rename, move)
171
+ */
172
+ interface FileOperationRequest extends SessionRequest {
173
+ path: string;
174
+ newPath?: string;
175
+ }
176
+ /**
177
+ * Client for file system operations
178
+ */
179
+ declare class FileClient extends BaseHttpClient {
180
+ /**
181
+ * Create a directory
182
+ * @param path - Directory path to create
183
+ * @param sessionId - The session ID for this operation
184
+ * @param options - Optional settings (recursive)
185
+ */
186
+ mkdir(path: string, sessionId: string, options?: {
187
+ recursive?: boolean;
188
+ }): Promise<MkdirResult>;
189
+ /**
190
+ * Write content to a file
191
+ * @param path - File path to write to
192
+ * @param content - Content to write
193
+ * @param sessionId - The session ID for this operation
194
+ * @param options - Optional settings (encoding)
195
+ */
196
+ writeFile(path: string, content: string, sessionId: string, options?: {
197
+ encoding?: string;
198
+ }): Promise<WriteFileResult>;
199
+ /**
200
+ * Read content from a file
201
+ * @param path - File path to read from
202
+ * @param sessionId - The session ID for this operation
203
+ * @param options - Optional settings (encoding)
204
+ */
205
+ readFile(path: string, sessionId: string, options?: {
206
+ encoding?: string;
207
+ }): Promise<ReadFileResult>;
208
+ /**
209
+ * Stream a file using Server-Sent Events
210
+ * Returns a ReadableStream of SSE events containing metadata, chunks, and completion
211
+ * @param path - File path to stream
212
+ * @param sessionId - The session ID for this operation
213
+ */
214
+ readFileStream(path: string, sessionId: string): Promise<ReadableStream<Uint8Array>>;
215
+ /**
216
+ * Delete a file
217
+ * @param path - File path to delete
218
+ * @param sessionId - The session ID for this operation
219
+ */
220
+ deleteFile(path: string, sessionId: string): Promise<DeleteFileResult>;
221
+ /**
222
+ * Rename a file
223
+ * @param path - Current file path
224
+ * @param newPath - New file path
225
+ * @param sessionId - The session ID for this operation
226
+ */
227
+ renameFile(path: string, newPath: string, sessionId: string): Promise<RenameFileResult>;
228
+ /**
229
+ * Move a file
230
+ * @param path - Current file path
231
+ * @param newPath - Destination file path
232
+ * @param sessionId - The session ID for this operation
233
+ */
234
+ moveFile(path: string, newPath: string, sessionId: string): Promise<MoveFileResult>;
235
+ /**
236
+ * List files in a directory
237
+ * @param path - Directory path to list
238
+ * @param sessionId - The session ID for this operation
239
+ * @param options - Optional settings (recursive, includeHidden)
240
+ */
241
+ listFiles(path: string, sessionId: string, options?: ListFilesOptions): Promise<ListFilesResult>;
242
+ }
243
+
244
+ /**
245
+ * Request interface for Git checkout operations
246
+ */
247
+ interface GitCheckoutRequest extends SessionRequest {
248
+ repoUrl: string;
249
+ branch?: string;
250
+ targetDir?: string;
251
+ }
252
+ /**
253
+ * Client for Git repository operations
254
+ */
255
+ declare class GitClient extends BaseHttpClient {
256
+ /**
257
+ * Clone a Git repository
258
+ * @param repoUrl - URL of the Git repository to clone
259
+ * @param sessionId - The session ID for this operation
260
+ * @param options - Optional settings (branch, targetDir)
261
+ */
262
+ checkout(repoUrl: string, sessionId: string, options?: {
263
+ branch?: string;
264
+ targetDir?: string;
265
+ }): Promise<GitCheckoutResult>;
266
+ /**
267
+ * Extract repository name from URL for default directory name
268
+ */
269
+ private extractRepoName;
270
+ }
271
+
272
+ interface ExecutionCallbacks {
273
+ onStdout?: (output: OutputMessage) => void | Promise<void>;
274
+ onStderr?: (output: OutputMessage) => void | Promise<void>;
275
+ onResult?: (result: Result) => void | Promise<void>;
276
+ onError?: (error: ExecutionError) => void | Promise<void>;
277
+ }
278
+ declare class InterpreterClient extends BaseHttpClient {
279
+ private readonly maxRetries;
280
+ private readonly retryDelayMs;
281
+ createCodeContext(options?: CreateContextOptions): Promise<CodeContext>;
282
+ runCodeStream(contextId: string | undefined, code: string, language: string | undefined, callbacks: ExecutionCallbacks, timeoutMs?: number): Promise<void>;
283
+ listCodeContexts(): Promise<CodeContext[]>;
284
+ deleteCodeContext(contextId: string): Promise<void>;
285
+ /**
286
+ * Execute an operation with automatic retry for transient errors
287
+ */
288
+ private executeWithRetry;
289
+ private isRetryableError;
290
+ private parseErrorResponse;
291
+ private readLines;
292
+ private parseExecutionResult;
293
+ }
294
+
295
+ /**
296
+ * Request interface for exposing ports
297
+ */
298
+ interface ExposePortRequest {
299
+ port: number;
300
+ name?: string;
301
+ }
302
+ /**
303
+ * Request interface for unexposing ports
304
+ */
305
+ interface UnexposePortRequest {
306
+ port: number;
307
+ }
308
+ /**
309
+ * Client for port management and preview URL operations
310
+ */
311
+ declare class PortClient extends BaseHttpClient {
312
+ /**
313
+ * Expose a port and get a preview URL
314
+ * @param port - Port number to expose
315
+ * @param sessionId - The session ID for this operation
316
+ * @param name - Optional name for the port
317
+ */
318
+ exposePort(port: number, sessionId: string, name?: string): Promise<PortExposeResult>;
319
+ /**
320
+ * Unexpose a port and remove its preview URL
321
+ * @param port - Port number to unexpose
322
+ * @param sessionId - The session ID for this operation
323
+ */
324
+ unexposePort(port: number, sessionId: string): Promise<PortCloseResult>;
325
+ /**
326
+ * Get all currently exposed ports
327
+ * @param sessionId - The session ID for this operation
328
+ */
329
+ getExposedPorts(sessionId: string): Promise<PortListResult>;
330
+ }
331
+
332
+ /**
333
+ * Client for background process management
334
+ */
335
+ declare class ProcessClient extends BaseHttpClient {
336
+ /**
337
+ * Start a background process
338
+ * @param command - Command to execute as a background process
339
+ * @param sessionId - The session ID for this operation
340
+ * @param options - Optional settings (processId)
341
+ */
342
+ startProcess(command: string, sessionId: string, options?: {
343
+ processId?: string;
344
+ }): Promise<ProcessStartResult>;
345
+ /**
346
+ * List all processes (sandbox-scoped, not session-scoped)
347
+ */
348
+ listProcesses(): Promise<ProcessListResult>;
349
+ /**
350
+ * Get information about a specific process (sandbox-scoped, not session-scoped)
351
+ * @param processId - ID of the process to retrieve
352
+ */
353
+ getProcess(processId: string): Promise<ProcessInfoResult>;
354
+ /**
355
+ * Kill a specific process (sandbox-scoped, not session-scoped)
356
+ * @param processId - ID of the process to kill
357
+ */
358
+ killProcess(processId: string): Promise<ProcessKillResult>;
359
+ /**
360
+ * Kill all running processes (sandbox-scoped, not session-scoped)
361
+ */
362
+ killAllProcesses(): Promise<ProcessCleanupResult>;
363
+ /**
364
+ * Get logs from a specific process (sandbox-scoped, not session-scoped)
365
+ * @param processId - ID of the process to get logs from
366
+ */
367
+ getProcessLogs(processId: string): Promise<ProcessLogsResult>;
368
+ /**
369
+ * Stream logs from a specific process (sandbox-scoped, not session-scoped)
370
+ * @param processId - ID of the process to stream logs from
371
+ */
372
+ streamProcessLogs(processId: string): Promise<ReadableStream<Uint8Array>>;
373
+ }
374
+
375
+ /**
376
+ * Response interface for ping operations
377
+ */
378
+ interface PingResponse extends BaseApiResponse {
379
+ message: string;
380
+ uptime?: number;
381
+ }
382
+ /**
383
+ * Response interface for getting available commands
384
+ */
385
+ interface CommandsResponse extends BaseApiResponse {
386
+ availableCommands: string[];
387
+ count: number;
388
+ }
389
+ /**
390
+ * Request interface for creating sessions
391
+ */
392
+ interface CreateSessionRequest {
393
+ id: string;
394
+ env?: Record<string, string>;
395
+ cwd?: string;
396
+ }
397
+ /**
398
+ * Response interface for creating sessions
399
+ */
400
+ interface CreateSessionResponse extends BaseApiResponse {
401
+ id: string;
402
+ message: string;
403
+ }
404
+ /**
405
+ * Client for health checks and utility operations
406
+ */
407
+ declare class UtilityClient extends BaseHttpClient {
408
+ /**
409
+ * Ping the sandbox to check if it's responsive
410
+ */
411
+ ping(): Promise<string>;
412
+ /**
413
+ * Get list of available commands in the sandbox environment
414
+ */
415
+ getCommands(): Promise<string[]>;
416
+ /**
417
+ * Create a new execution session
418
+ * @param options - Session configuration (id, env, cwd)
419
+ */
420
+ createSession(options: CreateSessionRequest): Promise<CreateSessionResponse>;
421
+ }
422
+
423
+ /**
424
+ * Main sandbox client that composes all domain-specific clients
425
+ * Provides organized access to all sandbox functionality
426
+ */
427
+ declare class SandboxClient {
428
+ readonly commands: CommandClient;
429
+ readonly files: FileClient;
430
+ readonly processes: ProcessClient;
431
+ readonly ports: PortClient;
432
+ readonly git: GitClient;
433
+ readonly interpreter: InterpreterClient;
434
+ readonly utils: UtilityClient;
435
+ constructor(options: HttpClientOptions);
436
+ }
437
+
438
+ declare function getSandbox(ns: DurableObjectNamespace<Sandbox>, id: string, options?: {
439
+ baseUrl: string;
440
+ }): DurableObjectStub<Sandbox<unknown>>;
441
+ declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox {
442
+ defaultPort: number;
443
+ sleepAfter: string;
444
+ client: SandboxClient;
445
+ private codeInterpreter;
446
+ private sandboxName;
447
+ private baseUrl;
448
+ private portTokens;
449
+ private defaultSession;
450
+ envVars: Record<string, string>;
451
+ private logger;
452
+ constructor(ctx: DurableObject['ctx'], env: Env);
453
+ setSandboxName(name: string): Promise<void>;
454
+ setBaseUrl(baseUrl: string): Promise<void>;
455
+ setEnvVars(envVars: Record<string, string>): Promise<void>;
456
+ /**
457
+ * Cleanup and destroy the sandbox container
458
+ */
459
+ destroy(): Promise<void>;
460
+ onStart(): void;
461
+ onStop(): void;
462
+ onError(error: unknown): void;
463
+ fetch(request: Request): Promise<Response>;
464
+ private determinePort;
465
+ /**
466
+ * Ensure default session exists - lazy initialization
467
+ * This is called automatically by all public methods that need a session
468
+ */
469
+ private ensureDefaultSession;
470
+ exec(command: string, options?: ExecOptions): Promise<ExecResult>;
471
+ /**
472
+ * Internal session-aware exec implementation
473
+ * Used by both public exec() and session wrappers
474
+ */
475
+ private execWithSession;
476
+ private executeWithStreaming;
477
+ private mapExecuteResponseToExecResult;
478
+ /**
479
+ * Create a Process domain object from HTTP client DTO
480
+ * Centralizes process object creation with bound methods
481
+ * This eliminates duplication across startProcess, listProcesses, getProcess, and session wrappers
482
+ */
483
+ private createProcessFromDTO;
484
+ startProcess(command: string, options?: ProcessOptions, sessionId?: string): Promise<Process>;
485
+ listProcesses(sessionId?: string): Promise<Process[]>;
486
+ getProcess(id: string, sessionId?: string): Promise<Process | null>;
487
+ killProcess(id: string, signal?: string, sessionId?: string): Promise<void>;
488
+ killAllProcesses(sessionId?: string): Promise<number>;
489
+ cleanupCompletedProcesses(sessionId?: string): Promise<number>;
490
+ getProcessLogs(id: string, sessionId?: string): Promise<{
491
+ stdout: string;
492
+ stderr: string;
493
+ processId: string;
494
+ }>;
495
+ execStream(command: string, options?: StreamOptions): Promise<ReadableStream<Uint8Array>>;
496
+ /**
497
+ * Internal session-aware execStream implementation
498
+ */
499
+ private execStreamWithSession;
500
+ streamProcessLogs(processId: string, options?: {
501
+ signal?: AbortSignal;
502
+ }): Promise<ReadableStream<Uint8Array>>;
503
+ gitCheckout(repoUrl: string, options: {
504
+ branch?: string;
505
+ targetDir?: string;
506
+ sessionId?: string;
507
+ }): Promise<_repo_shared.GitCheckoutResult>;
508
+ mkdir(path: string, options?: {
509
+ recursive?: boolean;
510
+ sessionId?: string;
511
+ }): Promise<_repo_shared.MkdirResult>;
512
+ writeFile(path: string, content: string, options?: {
513
+ encoding?: string;
514
+ sessionId?: string;
515
+ }): Promise<_repo_shared.WriteFileResult>;
516
+ deleteFile(path: string, sessionId?: string): Promise<_repo_shared.DeleteFileResult>;
517
+ renameFile(oldPath: string, newPath: string, sessionId?: string): Promise<_repo_shared.RenameFileResult>;
518
+ moveFile(sourcePath: string, destinationPath: string, sessionId?: string): Promise<_repo_shared.MoveFileResult>;
519
+ readFile(path: string, options?: {
520
+ encoding?: string;
521
+ sessionId?: string;
522
+ }): Promise<_repo_shared.ReadFileResult>;
523
+ /**
524
+ * Stream a file from the sandbox using Server-Sent Events
525
+ * Returns a ReadableStream that can be consumed with streamFile() or collectFile() utilities
526
+ * @param path - Path to the file to stream
527
+ * @param options - Optional session ID
528
+ */
529
+ readFileStream(path: string, options?: {
530
+ sessionId?: string;
531
+ }): Promise<ReadableStream<Uint8Array>>;
532
+ listFiles(path: string, options?: {
533
+ recursive?: boolean;
534
+ includeHidden?: boolean;
535
+ }): Promise<_repo_shared.ListFilesResult>;
536
+ exposePort(port: number, options: {
537
+ name?: string;
538
+ hostname: string;
539
+ }): Promise<{
540
+ url: string;
541
+ port: number;
542
+ name: string | undefined;
543
+ }>;
544
+ unexposePort(port: number): Promise<void>;
545
+ getExposedPorts(hostname: string): Promise<{
546
+ url: string;
547
+ port: number;
548
+ status: "active" | "inactive";
549
+ }[]>;
550
+ isPortExposed(port: number): Promise<boolean>;
551
+ validatePortToken(port: number, token: string): Promise<boolean>;
552
+ private generatePortToken;
553
+ private persistPortTokens;
554
+ private constructPreviewUrl;
555
+ /**
556
+ * Create isolated execution session for advanced use cases
557
+ * Returns ExecutionSession with full sandbox API bound to specific session
558
+ */
559
+ createSession(options?: SessionOptions): Promise<ExecutionSession>;
560
+ /**
561
+ * Get an existing session by ID
562
+ * Returns ExecutionSession wrapper bound to the specified session
563
+ *
564
+ * This is useful for retrieving sessions across different requests/contexts
565
+ * without storing the ExecutionSession object (which has RPC lifecycle limitations)
566
+ *
567
+ * @param sessionId - The ID of an existing session
568
+ * @returns ExecutionSession wrapper bound to the session
569
+ */
570
+ getSession(sessionId: string): Promise<ExecutionSession>;
571
+ /**
572
+ * Internal helper to create ExecutionSession wrapper for a given sessionId
573
+ * Used by both createSession and getSession
574
+ */
575
+ private getSessionWrapper;
576
+ createCodeContext(options?: CreateContextOptions): Promise<CodeContext>;
577
+ runCode(code: string, options?: RunCodeOptions): Promise<ExecutionResult>;
578
+ runCodeStream(code: string, options?: RunCodeOptions): Promise<ReadableStream>;
579
+ listCodeContexts(): Promise<CodeContext[]>;
580
+ deleteCodeContext(contextId: string): Promise<void>;
581
+ }
582
+
583
+ export { type BaseApiResponse as B, CommandClient as C, type ErrorResponse as E, FileClient as F, GitClient as G, type HttpClientOptions as H, InterpreterClient as I, type MkdirRequest as M, PortClient as P, type ReadFileRequest as R, SandboxClient as S, UtilityClient as U, type WriteFileRequest as W, ProcessClient as a, Sandbox as b, type CommandsResponse as c, type ContainerStub as d, type ExecuteRequest as e, type ExecuteResponse as f, getSandbox as g, type ExposePortRequest as h, type FileOperationRequest as i, type GitCheckoutRequest as j, type PingResponse as k, type RequestConfig as l, type ResponseHandler as m, type SessionRequest as n, type UnexposePortRequest as o, type ExecutionCallbacks as p };
package/dist/sandbox.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import './types.js';
1
+ import '@repo/shared';
2
+ import 'cloudflare:workers';
2
3
  import '@cloudflare/containers';
3
- export { S as Sandbox, g as getSandbox } from './client-B3RUab0s.js';
4
- import './interpreter-types.js';
4
+ export { b as Sandbox, g as getSandbox } from './sandbox-D9K2ypln.js';
package/dist/sandbox.js CHANGED
@@ -1,13 +1,10 @@
1
1
  import {
2
2
  Sandbox,
3
3
  getSandbox
4
- } from "./chunk-SQLJNZ3K.js";
5
- import "./chunk-6UAWTJ5S.js";
6
- import "./chunk-D3U63BZP.js";
7
- import "./chunk-32UDXUPC.js";
8
- import "./chunk-FXYPFGOZ.js";
9
- import "./chunk-JTKON2SH.js";
10
- import "./chunk-W7TVRPBG.js";
4
+ } from "./chunk-53JFOF7F.js";
5
+ import "./chunk-JXZMAU2C.js";
6
+ import "./chunk-Z532A7QC.js";
7
+ import "./chunk-EKSWCBCA.js";
11
8
  export {
12
9
  Sandbox,
13
10
  getSandbox
@@ -23,8 +23,9 @@ declare function validatePort(port: number): boolean;
23
23
  */
24
24
  declare function sanitizeSandboxId(id: string): string;
25
25
  /**
26
- * Logs security events for monitoring
26
+ * Validates language for code interpreter
27
+ * Only allows supported languages
27
28
  */
28
- declare function logSecurityEvent(event: string, details: Record<string, any>, severity?: 'low' | 'medium' | 'high' | 'critical'): void;
29
+ declare function validateLanguage(language: string | undefined): void;
29
30
 
30
- export { SecurityError, logSecurityEvent, sanitizeSandboxId, validatePort };
31
+ export { SecurityError, sanitizeSandboxId, validateLanguage, validatePort };
package/dist/security.js CHANGED
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  SecurityError,
3
- logSecurityEvent,
4
3
  sanitizeSandboxId,
4
+ validateLanguage,
5
5
  validatePort
6
- } from "./chunk-6UAWTJ5S.js";
6
+ } from "./chunk-Z532A7QC.js";
7
7
  export {
8
8
  SecurityError,
9
- logSecurityEvent,
10
9
  sanitizeSandboxId,
10
+ validateLanguage,
11
11
  validatePort
12
12
  };
13
13
  //# sourceMappingURL=security.js.map
@@ -2,7 +2,7 @@ import {
2
2
  asyncIterableToSSEStream,
3
3
  parseSSEStream,
4
4
  responseToAsyncIterable
5
- } from "./chunk-NNGBXDMY.js";
5
+ } from "./chunk-EKSWCBCA.js";
6
6
  export {
7
7
  asyncIterableToSSEStream,
8
8
  parseSSEStream,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudflare/sandbox",
3
- "version": "0.3.7",
3
+ "version": "0.4.2",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/cloudflare/sandbox-sdk"
@@ -9,6 +9,9 @@
9
9
  "dependencies": {
10
10
  "@cloudflare/containers": "^0.0.28"
11
11
  },
12
+ "devDependencies": {
13
+ "@repo/shared": "^0.0.0"
14
+ },
12
15
  "tags": [
13
16
  "sandbox",
14
17
  "codegen",
@@ -18,9 +21,14 @@
18
21
  ],
19
22
  "scripts": {
20
23
  "build": "rm -rf dist && tsup src/*.ts --outDir dist --dts --sourcemap --format esm",
21
- "docker:local": "docker build . -t cloudflare/sandbox-test:$npm_package_version",
22
- "docker:publish": "docker buildx build --platform linux/amd64,linux/arm64 -t cloudflare/sandbox:$npm_package_version --push .",
23
- "docker:publish:beta": "docker buildx build --platform linux/amd64,linux/arm64 -t cloudflare/sandbox:$npm_package_version-beta --push ."
24
+ "check": "biome check && npm run typecheck",
25
+ "fix": "biome check --fix && npm run typecheck",
26
+ "typecheck": "tsc --noEmit",
27
+ "docker:local": "cd ../.. && docker build -f packages/sandbox/Dockerfile -t cloudflare/sandbox-test:$npm_package_version .",
28
+ "docker:publish": "cd ../.. && docker buildx build --platform linux/amd64,linux/arm64 -f packages/sandbox/Dockerfile -t cloudflare/sandbox:$npm_package_version --push .",
29
+ "docker:publish:beta": "cd ../.. && docker buildx build --platform linux/amd64,linux/arm64 -f packages/sandbox/Dockerfile -t cloudflare/sandbox:$npm_package_version-beta --push .",
30
+ "test": "vitest run --config vitest.config.ts",
31
+ "test:e2e": "cd ../.. && vitest run --config vitest.e2e.config.ts \"$@\""
24
32
  },
25
33
  "exports": {
26
34
  ".": {