@cloudflare/sandbox 0.2.3 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/CHANGELOG.md +69 -0
  2. package/Dockerfile +9 -11
  3. package/README.md +69 -7
  4. package/container_src/control-process.ts +784 -0
  5. package/container_src/handler/exec.ts +99 -254
  6. package/container_src/handler/file.ts +204 -642
  7. package/container_src/handler/git.ts +28 -80
  8. package/container_src/handler/process.ts +443 -515
  9. package/container_src/handler/session.ts +92 -0
  10. package/container_src/index.ts +74 -129
  11. package/container_src/isolation.ts +1039 -0
  12. package/container_src/jupyter-service.ts +8 -5
  13. package/container_src/shell-escape.ts +42 -0
  14. package/container_src/types.ts +35 -12
  15. package/dist/{chunk-VTKZL632.js → chunk-BEQUGUY4.js} +2 -2
  16. package/dist/{chunk-4KELYYKS.js → chunk-GTGWAEED.js} +239 -265
  17. package/dist/chunk-GTGWAEED.js.map +1 -0
  18. package/dist/{chunk-CUHYLCMT.js → chunk-SMUEY5JR.js} +111 -99
  19. package/dist/chunk-SMUEY5JR.js.map +1 -0
  20. package/dist/{client-bzEV222a.d.ts → client-Dny_ro_v.d.ts} +48 -84
  21. package/dist/client.d.ts +1 -1
  22. package/dist/client.js +1 -1
  23. package/dist/index.d.ts +2 -2
  24. package/dist/index.js +8 -9
  25. package/dist/interpreter.d.ts +2 -2
  26. package/dist/jupyter-client.d.ts +2 -2
  27. package/dist/jupyter-client.js +2 -2
  28. package/dist/request-handler.d.ts +3 -3
  29. package/dist/request-handler.js +3 -5
  30. package/dist/sandbox.d.ts +2 -2
  31. package/dist/sandbox.js +3 -5
  32. package/dist/types.d.ts +127 -21
  33. package/dist/types.js +35 -9
  34. package/dist/types.js.map +1 -1
  35. package/package.json +1 -1
  36. package/src/client.ts +175 -187
  37. package/src/index.ts +23 -13
  38. package/src/sandbox.ts +297 -332
  39. package/src/types.ts +125 -24
  40. package/dist/chunk-4KELYYKS.js.map +0 -1
  41. package/dist/chunk-CUHYLCMT.js.map +0 -1
  42. package/dist/chunk-S5FFBU4Y.js +0 -46
  43. package/dist/chunk-S5FFBU4Y.js.map +0 -1
  44. /package/dist/{chunk-VTKZL632.js.map → chunk-BEQUGUY4.js.map} +0 -0
@@ -141,13 +141,16 @@ export class JupyterService {
141
141
  "[JupyterService] Pre-warming context pools for better performance"
142
142
  );
143
143
 
144
- // Warm one at a time with delay between them
144
+ // Only pre-warm Python contexts to avoid Bun WebSocket validation errors
145
+ // JavaScript contexts will be created on-demand
145
146
  await this.jupyterServer.enablePoolWarming("python", 1);
146
147
 
147
- // Small delay between different language kernels
148
- await new Promise((resolve) => setTimeout(resolve, 1000));
149
-
150
- await this.jupyterServer.enablePoolWarming("javascript", 1);
148
+ // Commenting out JavaScript pre-warming due to kernel message validation errors
149
+ // The errors appear to be related to Bun's handling of WebSocket messages
150
+ // JavaScript contexts still work fine when created on-demand
151
+ //
152
+ // await new Promise((resolve) => setTimeout(resolve, 1000));
153
+ // await this.jupyterServer.enablePoolWarming("javascript", 1);
151
154
  } catch (error) {
152
155
  console.error("[JupyterService] Error pre-warming context pools:", error);
153
156
  console.error(
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Secure shell command utilities to prevent injection attacks
3
+ */
4
+
5
+ /**
6
+ * Escapes a string for safe use in shell commands.
7
+ * This follows POSIX shell escaping rules to prevent command injection.
8
+ *
9
+ * @param str - The string to escape
10
+ * @returns The escaped string safe for shell use
11
+ */
12
+ export function escapeShellArg(str: string): string {
13
+ // If string is empty, return empty quotes
14
+ if (str === '') {
15
+ return "''";
16
+ }
17
+
18
+ // Check if string contains any characters that need escaping
19
+ // Safe characters: alphanumeric, dash, underscore, dot, slash
20
+ if (/^[a-zA-Z0-9._\-/]+$/.test(str)) {
21
+ return str;
22
+ }
23
+
24
+ // For strings with special characters, use single quotes and escape single quotes
25
+ // Single quotes preserve all characters literally except the single quote itself
26
+ // To include a single quote, we end the quoted string, add an escaped quote, and start a new quoted string
27
+ return `'${str.replace(/'/g, "'\\''")}'`;
28
+ }
29
+
30
+ /**
31
+ * Escapes a file path for safe use in shell commands.
32
+ *
33
+ * @param path - The file path to escape
34
+ * @returns The escaped path safe for shell use
35
+ */
36
+ export function escapeShellPath(path: string): string {
37
+ // Normalize path to prevent issues with multiple slashes
38
+ const normalizedPath = path.replace(/\/+/g, '/');
39
+
40
+ // Apply standard shell escaping
41
+ return escapeShellArg(normalizedPath);
42
+ }
@@ -17,19 +17,20 @@ export interface ProcessRecord {
17
17
  startTime: Date;
18
18
  endTime?: Date;
19
19
  exitCode?: number;
20
- sessionId?: string;
21
- childProcess?: ChildProcess;
20
+ stdoutFile?: string; // Path to temp file containing stdout
21
+ stderrFile?: string; // Path to temp file containing stderr
22
22
  stdout: string;
23
23
  stderr: string;
24
24
  outputListeners: Set<(stream: 'stdout' | 'stderr', data: string) => void>;
25
25
  statusListeners: Set<(status: ProcessStatus) => void>;
26
+ monitoringInterval?: NodeJS.Timeout; // For polling temp files when streaming
26
27
  }
27
28
 
28
29
  export interface StartProcessRequest {
29
30
  command: string;
31
+ sessionId: string;
30
32
  options?: {
31
33
  processId?: string;
32
- sessionId?: string;
33
34
  timeout?: number;
34
35
  env?: Record<string, string>;
35
36
  cwd?: string;
@@ -39,7 +40,6 @@ export interface StartProcessRequest {
39
40
  }
40
41
 
41
42
  export interface ExecuteOptions {
42
- sessionId?: string | null;
43
43
  background?: boolean;
44
44
  cwd?: string | URL;
45
45
  env?: Record<string, string>;
@@ -47,49 +47,59 @@ export interface ExecuteOptions {
47
47
 
48
48
  export interface ExecuteRequest extends ExecuteOptions {
49
49
  command: string;
50
+ sessionId: string;
50
51
  }
51
52
 
52
53
  export interface GitCheckoutRequest {
53
54
  repoUrl: string;
54
55
  branch?: string;
55
56
  targetDir?: string;
56
- sessionId?: string;
57
+ sessionId: string;
57
58
  }
58
59
 
59
60
  export interface MkdirRequest {
60
61
  path: string;
61
62
  recursive?: boolean;
62
- sessionId?: string;
63
+ sessionId: string;
63
64
  }
64
65
 
65
66
  export interface WriteFileRequest {
66
67
  path: string;
67
68
  content: string;
68
69
  encoding?: string;
69
- sessionId?: string;
70
+ sessionId: string;
70
71
  }
71
72
 
72
73
  export interface ReadFileRequest {
73
74
  path: string;
74
75
  encoding?: string;
75
- sessionId?: string;
76
+ sessionId: string;
76
77
  }
77
78
 
78
79
  export interface DeleteFileRequest {
79
80
  path: string;
80
- sessionId?: string;
81
+ sessionId: string;
81
82
  }
82
83
 
83
84
  export interface RenameFileRequest {
84
85
  oldPath: string;
85
86
  newPath: string;
86
- sessionId?: string;
87
+ sessionId: string;
87
88
  }
88
89
 
89
90
  export interface MoveFileRequest {
90
91
  sourcePath: string;
91
92
  destinationPath: string;
92
- sessionId?: string;
93
+ sessionId: string;
94
+ }
95
+
96
+ export interface ListFilesRequest {
97
+ path: string;
98
+ options?: {
99
+ recursive?: boolean;
100
+ includeHidden?: boolean;
101
+ };
102
+ sessionId: string;
93
103
  }
94
104
 
95
105
  export interface ExposePortRequest {
@@ -102,7 +112,20 @@ export interface UnexposePortRequest {
102
112
  }
103
113
 
104
114
  export interface SessionData {
105
- sessionId: string;
115
+ id: string;
106
116
  activeProcess: ChildProcess | null;
107
117
  createdAt: Date;
108
118
  }
119
+
120
+ // Session management API types
121
+ export interface CreateSessionRequest {
122
+ id: string;
123
+ env?: Record<string, string>;
124
+ cwd?: string;
125
+ isolation?: boolean;
126
+ }
127
+
128
+ export interface SessionExecRequest {
129
+ id: string;
130
+ command: string;
131
+ }
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  HttpClient
3
- } from "./chunk-CUHYLCMT.js";
3
+ } from "./chunk-SMUEY5JR.js";
4
4
  import {
5
5
  isRetryableError,
6
6
  parseErrorResponse
@@ -234,4 +234,4 @@ var JupyterClient = class extends HttpClient {
234
234
  export {
235
235
  JupyterClient
236
236
  };
237
- //# sourceMappingURL=chunk-VTKZL632.js.map
237
+ //# sourceMappingURL=chunk-BEQUGUY4.js.map