@cloudflare/sandbox 0.0.0-dcf36ef → 0.0.0-e489cbb

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 (96) hide show
  1. package/CHANGELOG.md +8 -10
  2. package/Dockerfile +82 -18
  3. package/README.md +89 -824
  4. package/dist/chunk-53JFOF7F.js +2352 -0
  5. package/dist/chunk-53JFOF7F.js.map +1 -0
  6. package/dist/chunk-BFVUNTP4.js +104 -0
  7. package/dist/chunk-BFVUNTP4.js.map +1 -0
  8. package/dist/chunk-EKSWCBCA.js +86 -0
  9. package/dist/chunk-EKSWCBCA.js.map +1 -0
  10. package/dist/chunk-JXZMAU2C.js +559 -0
  11. package/dist/chunk-JXZMAU2C.js.map +1 -0
  12. package/dist/chunk-Z532A7QC.js +78 -0
  13. package/dist/chunk-Z532A7QC.js.map +1 -0
  14. package/dist/file-stream.d.ts +43 -0
  15. package/dist/file-stream.js +9 -0
  16. package/dist/file-stream.js.map +1 -0
  17. package/dist/index.d.ts +9 -0
  18. package/dist/index.js +66 -0
  19. package/dist/index.js.map +1 -0
  20. package/dist/interpreter.d.ts +33 -0
  21. package/dist/interpreter.js +8 -0
  22. package/dist/interpreter.js.map +1 -0
  23. package/dist/request-handler.d.ts +18 -0
  24. package/dist/request-handler.js +12 -0
  25. package/dist/request-handler.js.map +1 -0
  26. package/dist/sandbox-D9K2ypln.d.ts +583 -0
  27. package/dist/sandbox.d.ts +4 -0
  28. package/dist/sandbox.js +12 -0
  29. package/dist/sandbox.js.map +1 -0
  30. package/dist/security.d.ts +31 -0
  31. package/dist/security.js +13 -0
  32. package/dist/security.js.map +1 -0
  33. package/dist/sse-parser.d.ts +28 -0
  34. package/dist/sse-parser.js +11 -0
  35. package/dist/sse-parser.js.map +1 -0
  36. package/package.json +12 -4
  37. package/src/clients/base-client.ts +280 -0
  38. package/src/clients/command-client.ts +115 -0
  39. package/src/clients/file-client.ts +269 -0
  40. package/src/clients/git-client.ts +92 -0
  41. package/src/clients/index.ts +63 -0
  42. package/src/{interpreter-client.ts → clients/interpreter-client.ts} +148 -171
  43. package/src/clients/port-client.ts +105 -0
  44. package/src/clients/process-client.ts +177 -0
  45. package/src/clients/sandbox-client.ts +41 -0
  46. package/src/clients/types.ts +84 -0
  47. package/src/clients/utility-client.ts +94 -0
  48. package/src/errors/adapter.ts +180 -0
  49. package/src/errors/classes.ts +469 -0
  50. package/src/errors/index.ts +105 -0
  51. package/src/file-stream.ts +119 -117
  52. package/src/index.ts +81 -69
  53. package/src/interpreter.ts +17 -8
  54. package/src/request-handler.ts +69 -43
  55. package/src/sandbox.ts +694 -533
  56. package/src/security.ts +14 -23
  57. package/src/sse-parser.ts +4 -8
  58. package/startup.sh +3 -0
  59. package/tests/base-client.test.ts +328 -0
  60. package/tests/command-client.test.ts +407 -0
  61. package/tests/file-client.test.ts +643 -0
  62. package/tests/file-stream.test.ts +306 -0
  63. package/tests/git-client.test.ts +328 -0
  64. package/tests/port-client.test.ts +301 -0
  65. package/tests/process-client.test.ts +658 -0
  66. package/tests/sandbox.test.ts +465 -0
  67. package/tests/sse-parser.test.ts +290 -0
  68. package/tests/utility-client.test.ts +266 -0
  69. package/tests/wrangler.jsonc +35 -0
  70. package/tsconfig.json +9 -1
  71. package/vitest.config.ts +31 -0
  72. package/container_src/bun.lock +0 -76
  73. package/container_src/circuit-breaker.ts +0 -121
  74. package/container_src/control-process.ts +0 -784
  75. package/container_src/handler/exec.ts +0 -185
  76. package/container_src/handler/file.ts +0 -457
  77. package/container_src/handler/git.ts +0 -130
  78. package/container_src/handler/ports.ts +0 -314
  79. package/container_src/handler/process.ts +0 -568
  80. package/container_src/handler/session.ts +0 -92
  81. package/container_src/index.ts +0 -601
  82. package/container_src/interpreter-service.ts +0 -276
  83. package/container_src/isolation.ts +0 -1213
  84. package/container_src/mime-processor.ts +0 -255
  85. package/container_src/package.json +0 -18
  86. package/container_src/runtime/executors/javascript/node_executor.ts +0 -123
  87. package/container_src/runtime/executors/python/ipython_executor.py +0 -338
  88. package/container_src/runtime/executors/typescript/ts_executor.ts +0 -138
  89. package/container_src/runtime/process-pool.ts +0 -464
  90. package/container_src/shell-escape.ts +0 -42
  91. package/container_src/startup.sh +0 -11
  92. package/container_src/types.ts +0 -131
  93. package/src/client.ts +0 -1048
  94. package/src/errors.ts +0 -219
  95. package/src/interpreter-types.ts +0 -390
  96. package/src/types.ts +0 -571
@@ -1,185 +0,0 @@
1
- import type { SessionManager } from "../isolation";
2
- import type { SessionExecRequest } from "../types";
3
-
4
- export async function handleExecuteRequest(
5
- req: Request,
6
- corsHeaders: Record<string, string>,
7
- sessionManager: SessionManager
8
- ) {
9
- try {
10
- const body = (await req.json()) as SessionExecRequest;
11
- const { id, command } = body;
12
-
13
- console.log(
14
- `[Container] Session exec request for '${id}': ${command}`
15
- );
16
-
17
- if (!id || !command) {
18
- return new Response(
19
- JSON.stringify({
20
- error: "Session ID and command are required",
21
- }),
22
- {
23
- status: 400,
24
- headers: {
25
- "Content-Type": "application/json",
26
- ...corsHeaders,
27
- },
28
- }
29
- );
30
- }
31
-
32
- const session = sessionManager.getSession(id);
33
- if (!session) {
34
- console.error(`[Container] Session '${id}' not found!`);
35
- const availableSessions = sessionManager.listSessions();
36
- console.log(
37
- `[Container] Available sessions: ${
38
- availableSessions.join(", ") || "none"
39
- }`
40
- );
41
-
42
- return new Response(
43
- JSON.stringify({
44
- error: `Session '${id}' not found`,
45
- availableSessions,
46
- }),
47
- {
48
- status: 404,
49
- headers: {
50
- "Content-Type": "application/json",
51
- ...corsHeaders,
52
- },
53
- }
54
- );
55
- }
56
-
57
- const result = await session.exec(command);
58
-
59
- return new Response(JSON.stringify(result), {
60
- headers: { "Content-Type": "application/json", ...corsHeaders },
61
- });
62
- } catch (error) {
63
- console.error("[Container] Session exec failed:", error);
64
- return new Response(
65
- JSON.stringify({
66
- error: "Command execution failed",
67
- message:
68
- error instanceof Error ? error.message : String(error),
69
- }),
70
- {
71
- status: 500,
72
- headers: {
73
- "Content-Type": "application/json",
74
- ...corsHeaders,
75
- },
76
- }
77
- );
78
- }
79
- }
80
-
81
- export async function handleStreamingExecuteRequest(
82
- req: Request,
83
- sessionManager: SessionManager,
84
- corsHeaders: Record<string, string>
85
- ) {
86
- try {
87
- const body = (await req.json()) as SessionExecRequest;
88
- const { id, command } = body;
89
-
90
- console.log(
91
- `[Container] Session streaming exec request for '${id}': ${command}`
92
- );
93
-
94
- if (!id || !command) {
95
- return new Response(
96
- JSON.stringify({
97
- error: "Session ID and command are required",
98
- }),
99
- {
100
- status: 400,
101
- headers: {
102
- "Content-Type": "application/json",
103
- ...corsHeaders,
104
- },
105
- }
106
- );
107
- }
108
-
109
- const session = sessionManager.getSession(id);
110
- if (!session) {
111
- console.error(`[Container] Session '${id}' not found!`);
112
- const availableSessions = sessionManager.listSessions();
113
-
114
- return new Response(
115
- JSON.stringify({
116
- error: `Session '${id}' not found`,
117
- availableSessions,
118
- }),
119
- {
120
- status: 404,
121
- headers: {
122
- "Content-Type": "application/json",
123
- ...corsHeaders,
124
- },
125
- }
126
- );
127
- }
128
-
129
- // Create a streaming response using the actual streaming method
130
- const stream = new ReadableStream({
131
- async start(controller) {
132
- try {
133
- // Use the streaming generator method
134
- for await (const event of session.execStream(command)) {
135
- // Forward each event as SSE
136
- controller.enqueue(
137
- new TextEncoder().encode(
138
- `data: ${JSON.stringify(event)}\n\n`
139
- )
140
- );
141
- }
142
- controller.close();
143
- } catch (error) {
144
- controller.enqueue(
145
- new TextEncoder().encode(
146
- `data: ${JSON.stringify({
147
- type: "error",
148
- message:
149
- error instanceof Error
150
- ? error.message
151
- : String(error),
152
- })}\n\n`
153
- )
154
- );
155
- controller.close();
156
- }
157
- },
158
- });
159
-
160
- return new Response(stream, {
161
- headers: {
162
- "Content-Type": "text/event-stream",
163
- "Cache-Control": "no-cache",
164
- Connection: "keep-alive",
165
- ...corsHeaders,
166
- },
167
- });
168
- } catch (error) {
169
- console.error("[Container] Session stream exec failed:", error);
170
- return new Response(
171
- JSON.stringify({
172
- error: "Stream execution failed",
173
- message:
174
- error instanceof Error ? error.message : String(error),
175
- }),
176
- {
177
- status: 500,
178
- headers: {
179
- "Content-Type": "application/json",
180
- ...corsHeaders,
181
- },
182
- }
183
- );
184
- }
185
- }
@@ -1,457 +0,0 @@
1
- import type { SessionManager } from "../isolation";
2
- import type {
3
- DeleteFileRequest,
4
- ListFilesRequest,
5
- MkdirRequest,
6
- MoveFileRequest,
7
- ReadFileRequest,
8
- RenameFileRequest,
9
- WriteFileRequest
10
- } from "../types";
11
-
12
- // Common path validation patterns
13
- const DANGEROUS_PATH_PATTERNS = [
14
- /^\/$/, // Root directory
15
- /^\/etc/, // System directories
16
- /^\/var/, // System directories
17
- /^\/usr/, // System directories
18
- /^\/bin/, // System directories
19
- /^\/sbin/, // System directories
20
- /^\/boot/, // System directories
21
- /^\/dev/, // System directories
22
- /^\/proc/, // System directories
23
- /^\/sys/, // System directories
24
- /^\/tmp\/\.\./, // Path traversal attempts
25
- /\.\./, // Path traversal attempts
26
- ];
27
-
28
- // Path validation utility
29
- function validatePath(...paths: string[]): string | null {
30
- for (const path of paths) {
31
- if (!path || typeof path !== "string") {
32
- return "Path is required and must be a string";
33
- }
34
-
35
- if (DANGEROUS_PATH_PATTERNS.some((pattern) => pattern.test(path))) {
36
- return "Dangerous path not allowed";
37
- }
38
- }
39
- return null;
40
- }
41
-
42
- // Common error response utility
43
- function createPathErrorResponse(
44
- error: string,
45
- corsHeaders: Record<string, string>
46
- ): Response {
47
- return new Response(
48
- JSON.stringify({ error }),
49
- {
50
- headers: {
51
- "Content-Type": "application/json",
52
- ...corsHeaders,
53
- },
54
- status: 400,
55
- }
56
- );
57
- }
58
-
59
- // Common server error response utility
60
- function createServerErrorResponse(
61
- operation: string,
62
- error: unknown,
63
- corsHeaders: Record<string, string>
64
- ): Response {
65
- console.error(`[Server] Error in ${operation}:`, error);
66
- return new Response(
67
- JSON.stringify({
68
- error: `Failed to ${operation.replace('handle', '').replace('Request', '').toLowerCase().replace('file', ' file')}`,
69
- message: error instanceof Error ? error.message : "Unknown error",
70
- }),
71
- {
72
- headers: {
73
- "Content-Type": "application/json",
74
- ...corsHeaders,
75
- },
76
- status: 500,
77
- }
78
- );
79
- }
80
-
81
- export async function handleMkdirRequest(
82
- req: Request,
83
- corsHeaders: Record<string, string>,
84
- sessionManager: SessionManager
85
- ): Promise<Response> {
86
- try {
87
- const body = (await req.json()) as MkdirRequest;
88
- const { path, recursive = false, sessionId } = body;
89
-
90
- // Validate path
91
- const pathError = validatePath(path);
92
- if (pathError) {
93
- return createPathErrorResponse(pathError, corsHeaders);
94
- }
95
-
96
- console.log(`[Server] Creating directory: ${path} (recursive: ${recursive})${sessionId ? ` in session: ${sessionId}` : ''}`);
97
-
98
- // Use specific session if provided, otherwise default session
99
- const result = sessionId
100
- ? await sessionManager.getSession(sessionId)?.mkdirOperation(path, recursive)
101
- : await sessionManager.mkdir(path, recursive);
102
-
103
- if (!result) {
104
- return createServerErrorResponse("handleMkdirRequest", new Error(`Session '${sessionId}' not found`), corsHeaders);
105
- }
106
-
107
- return new Response(
108
- JSON.stringify({
109
- exitCode: result.exitCode,
110
- path,
111
- recursive,
112
- stderr: "",
113
- stdout: "",
114
- success: result.success,
115
- timestamp: new Date().toISOString(),
116
- }),
117
- {
118
- headers: {
119
- "Content-Type": "application/json",
120
- ...corsHeaders,
121
- },
122
- }
123
- );
124
- } catch (error) {
125
- return createServerErrorResponse("handleMkdirRequest", error, corsHeaders);
126
- }
127
- }
128
-
129
- export async function handleWriteFileRequest(
130
- req: Request,
131
- corsHeaders: Record<string, string>,
132
- sessionManager: SessionManager
133
- ): Promise<Response> {
134
- try {
135
- const body = (await req.json()) as WriteFileRequest;
136
- const { path, content, encoding = "utf-8", sessionId } = body;
137
-
138
- // Validate path
139
- const pathError = validatePath(path);
140
- if (pathError) {
141
- return createPathErrorResponse(pathError, corsHeaders);
142
- }
143
-
144
- console.log(`[Server] Writing file: ${path} (content length: ${content.length})${sessionId ? ` in session: ${sessionId}` : ''}`);
145
-
146
- // Use specific session if provided, otherwise default session
147
- const result = sessionId
148
- ? await sessionManager.getSession(sessionId)?.writeFileOperation(path, content, encoding)
149
- : await sessionManager.writeFile(path, content, encoding);
150
-
151
- if (!result) {
152
- return createServerErrorResponse("handleWriteFileRequest", new Error(`Session '${sessionId}' not found`), corsHeaders);
153
- }
154
-
155
- return new Response(
156
- JSON.stringify({
157
- exitCode: result.exitCode,
158
- path,
159
- success: result.success,
160
- timestamp: new Date().toISOString(),
161
- }),
162
- {
163
- headers: {
164
- "Content-Type": "application/json",
165
- ...corsHeaders,
166
- },
167
- }
168
- );
169
- } catch (error) {
170
- return createServerErrorResponse("handleWriteFileRequest", error, corsHeaders);
171
- }
172
- }
173
-
174
- export async function handleReadFileRequest(
175
- req: Request,
176
- corsHeaders: Record<string, string>,
177
- sessionManager: SessionManager
178
- ): Promise<Response> {
179
- try {
180
- const body = (await req.json()) as ReadFileRequest;
181
- const { path, encoding = "utf-8", sessionId } = body;
182
-
183
- // Validate path
184
- const pathError = validatePath(path);
185
- if (pathError) {
186
- return createPathErrorResponse(pathError, corsHeaders);
187
- }
188
-
189
- console.log(`[Server] Reading file: ${path}${sessionId ? ` in session: ${sessionId}` : ''}`);
190
-
191
- // Use specific session if provided, otherwise default session
192
- const result = sessionId
193
- ? await sessionManager.getSession(sessionId)?.readFileOperation(path, encoding)
194
- : await sessionManager.readFile(path, encoding);
195
-
196
- if (!result) {
197
- return createServerErrorResponse("handleReadFileRequest", new Error(`Session '${sessionId}' not found`), corsHeaders);
198
- }
199
-
200
- return new Response(
201
- JSON.stringify({
202
- content: result.content,
203
- exitCode: result.exitCode,
204
- path,
205
- success: result.success,
206
- timestamp: new Date().toISOString(),
207
- // New metadata fields for binary file support
208
- encoding: result.encoding,
209
- isBinary: result.isBinary,
210
- mimeType: result.mimeType,
211
- size: result.size,
212
- }),
213
- {
214
- headers: {
215
- "Content-Type": "application/json",
216
- ...corsHeaders,
217
- },
218
- }
219
- );
220
- } catch (error) {
221
- return createServerErrorResponse("handleReadFileRequest", error, corsHeaders);
222
- }
223
- }
224
-
225
- export async function handleDeleteFileRequest(
226
- req: Request,
227
- corsHeaders: Record<string, string>,
228
- sessionManager: SessionManager
229
- ): Promise<Response> {
230
- try {
231
- const body = (await req.json()) as DeleteFileRequest;
232
- const { path, sessionId } = body;
233
-
234
- // Validate path
235
- const pathError = validatePath(path);
236
- if (pathError) {
237
- return createPathErrorResponse(pathError, corsHeaders);
238
- }
239
-
240
- console.log(`[Server] Deleting file: ${path}${sessionId ? ` in session: ${sessionId}` : ''}`);
241
-
242
- // Use specific session if provided, otherwise default session
243
- const result = sessionId
244
- ? await sessionManager.getSession(sessionId)?.deleteFileOperation(path)
245
- : await sessionManager.deleteFile(path);
246
-
247
- if (!result) {
248
- return createServerErrorResponse("handleDeleteFileRequest", new Error(`Session '${sessionId}' not found`), corsHeaders);
249
- }
250
-
251
- return new Response(
252
- JSON.stringify({
253
- exitCode: result.exitCode,
254
- path,
255
- success: result.success,
256
- timestamp: new Date().toISOString(),
257
- }),
258
- {
259
- headers: {
260
- "Content-Type": "application/json",
261
- ...corsHeaders,
262
- },
263
- }
264
- );
265
- } catch (error) {
266
- return createServerErrorResponse("handleDeleteFileRequest", error, corsHeaders);
267
- }
268
- }
269
-
270
- export async function handleRenameFileRequest(
271
- req: Request,
272
- corsHeaders: Record<string, string>,
273
- sessionManager: SessionManager
274
- ): Promise<Response> {
275
- try {
276
- const body = (await req.json()) as RenameFileRequest;
277
- const { oldPath, newPath, sessionId } = body;
278
-
279
- // Validate paths
280
- const pathError = validatePath(oldPath, newPath);
281
- if (pathError) {
282
- return createPathErrorResponse(pathError, corsHeaders);
283
- }
284
-
285
- console.log(`[Server] Renaming file: ${oldPath} -> ${newPath}${sessionId ? ` in session: ${sessionId}` : ''}`);
286
-
287
- // Use specific session if provided, otherwise default session
288
- const result = sessionId
289
- ? await sessionManager.getSession(sessionId)?.renameFileOperation(oldPath, newPath)
290
- : await sessionManager.renameFile(oldPath, newPath);
291
-
292
- if (!result) {
293
- return createServerErrorResponse("handleRenameFileRequest", new Error(`Session '${sessionId}' not found`), corsHeaders);
294
- }
295
-
296
- return new Response(
297
- JSON.stringify({
298
- exitCode: result.exitCode,
299
- newPath,
300
- oldPath,
301
- success: result.success,
302
- timestamp: new Date().toISOString(),
303
- }),
304
- {
305
- headers: {
306
- "Content-Type": "application/json",
307
- ...corsHeaders,
308
- },
309
- }
310
- );
311
- } catch (error) {
312
- return createServerErrorResponse("handleRenameFileRequest", error, corsHeaders);
313
- }
314
- }
315
-
316
- export async function handleMoveFileRequest(
317
- req: Request,
318
- corsHeaders: Record<string, string>,
319
- sessionManager: SessionManager
320
- ): Promise<Response> {
321
- try {
322
- const body = (await req.json()) as MoveFileRequest;
323
- const { sourcePath, destinationPath, sessionId } = body;
324
-
325
- // Validate paths
326
- const pathError = validatePath(sourcePath, destinationPath);
327
- if (pathError) {
328
- return createPathErrorResponse(pathError, corsHeaders);
329
- }
330
-
331
- console.log(`[Server] Moving file: ${sourcePath} -> ${destinationPath}${sessionId ? ` in session: ${sessionId}` : ''}`);
332
-
333
- // Use specific session if provided, otherwise default session
334
- const result = sessionId
335
- ? await sessionManager.getSession(sessionId)?.moveFileOperation(sourcePath, destinationPath)
336
- : await sessionManager.moveFile(sourcePath, destinationPath);
337
-
338
- if (!result) {
339
- return createServerErrorResponse("handleMoveFileRequest", new Error(`Session '${sessionId}' not found`), corsHeaders);
340
- }
341
-
342
- return new Response(
343
- JSON.stringify({
344
- destinationPath,
345
- exitCode: result.exitCode,
346
- sourcePath,
347
- success: result.success,
348
- timestamp: new Date().toISOString(),
349
- }),
350
- {
351
- headers: {
352
- "Content-Type": "application/json",
353
- ...corsHeaders,
354
- },
355
- }
356
- );
357
- } catch (error) {
358
- return createServerErrorResponse("handleMoveFileRequest", error, corsHeaders);
359
- }
360
- }
361
-
362
- export async function handleListFilesRequest(
363
- req: Request,
364
- corsHeaders: Record<string, string>,
365
- sessionManager: SessionManager
366
- ): Promise<Response> {
367
- try {
368
- const body = (await req.json()) as ListFilesRequest;
369
- const { path, options, sessionId } = body;
370
-
371
- // Validate path (note: listFiles allows root directory listing)
372
- const pathError = validatePath(path);
373
- if (pathError && pathError !== "Dangerous path not allowed") {
374
- return createPathErrorResponse(pathError, corsHeaders);
375
- }
376
-
377
- // For listFiles, we allow root directory but still check other dangerous patterns
378
- if (path !== "/" && DANGEROUS_PATH_PATTERNS.slice(1).some((pattern) => pattern.test(path))) {
379
- return createPathErrorResponse("Dangerous path not allowed", corsHeaders);
380
- }
381
-
382
- console.log(`[Server] Listing files in: ${path}${sessionId ? ` in session: ${sessionId}` : ''}`);
383
-
384
- // Use specific session if provided, otherwise default session
385
- const result = sessionId
386
- ? await sessionManager.getSession(sessionId)?.listFilesOperation(path, options)
387
- : await sessionManager.listFiles(path, options);
388
-
389
- if (!result) {
390
- return createServerErrorResponse("handleListFilesRequest", new Error(`Session '${sessionId}' not found`), corsHeaders);
391
- }
392
-
393
- return new Response(
394
- JSON.stringify({
395
- exitCode: result.exitCode,
396
- files: result.files,
397
- path,
398
- success: result.success,
399
- timestamp: new Date().toISOString(),
400
- }),
401
- {
402
- headers: {
403
- "Content-Type": "application/json",
404
- ...corsHeaders,
405
- },
406
- }
407
- );
408
- } catch (error) {
409
- return createServerErrorResponse("handleListFilesRequest", error, corsHeaders);
410
- }
411
- }
412
-
413
- export async function handleReadFileStreamRequest(
414
- req: Request,
415
- corsHeaders: Record<string, string>,
416
- sessionManager: SessionManager
417
- ): Promise<Response> {
418
- try {
419
- const body = (await req.json()) as ReadFileRequest;
420
- const { path, sessionId } = body;
421
-
422
- // Validate path
423
- const pathError = validatePath(path);
424
- if (pathError) {
425
- return createPathErrorResponse(pathError, corsHeaders);
426
- }
427
-
428
- console.log(`[Server] Streaming file: ${path}${sessionId ? ` in session: ${sessionId}` : ''}`);
429
-
430
- // Get the appropriate session
431
- const session = sessionId
432
- ? sessionManager.getSession(sessionId)
433
- : await sessionManager.getOrCreateDefaultSession();
434
-
435
- if (!session) {
436
- return createServerErrorResponse(
437
- "handleReadFileStreamRequest",
438
- new Error(`Session '${sessionId}' not found`),
439
- corsHeaders
440
- );
441
- }
442
-
443
- // Create SSE stream
444
- const stream = await session.readFileStreamOperation(path);
445
-
446
- return new Response(stream, {
447
- headers: {
448
- "Content-Type": "text/event-stream",
449
- "Cache-Control": "no-cache",
450
- "Connection": "keep-alive",
451
- ...corsHeaders,
452
- },
453
- });
454
- } catch (error) {
455
- return createServerErrorResponse("handleReadFileStreamRequest", error, corsHeaders);
456
- }
457
- }