@cloudflare/sandbox 0.2.4 → 0.3.1
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.
- package/CHANGELOG.md +75 -0
- package/Dockerfile +9 -11
- package/README.md +69 -7
- package/container_src/control-process.ts +784 -0
- package/container_src/handler/exec.ts +99 -254
- package/container_src/handler/file.ts +179 -837
- package/container_src/handler/git.ts +28 -80
- package/container_src/handler/process.ts +443 -515
- package/container_src/handler/session.ts +92 -0
- package/container_src/index.ts +68 -130
- package/container_src/isolation.ts +1038 -0
- package/container_src/shell-escape.ts +42 -0
- package/container_src/types.ts +27 -13
- package/dist/{chunk-HHUDRGPY.js → chunk-BEQUGUY4.js} +2 -2
- package/dist/{chunk-CKIGERRS.js → chunk-LFLJGISB.js} +240 -264
- package/dist/chunk-LFLJGISB.js.map +1 -0
- package/dist/{chunk-3CQ6THKA.js → chunk-SMUEY5JR.js} +85 -103
- package/dist/chunk-SMUEY5JR.js.map +1 -0
- package/dist/{client-Ce40ujDF.d.ts → client-Dny_ro_v.d.ts} +41 -25
- package/dist/client.d.ts +1 -1
- package/dist/client.js +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +8 -9
- package/dist/interpreter.d.ts +1 -1
- package/dist/jupyter-client.d.ts +1 -1
- package/dist/jupyter-client.js +2 -2
- package/dist/request-handler.d.ts +1 -1
- package/dist/request-handler.js +3 -5
- package/dist/sandbox.d.ts +1 -1
- package/dist/sandbox.js +3 -5
- package/dist/types.d.ts +10 -21
- package/dist/types.js +35 -9
- package/dist/types.js.map +1 -1
- package/package.json +2 -2
- package/src/client.ts +120 -135
- package/src/index.ts +8 -0
- package/src/sandbox.ts +290 -331
- package/src/types.ts +15 -24
- package/dist/chunk-3CQ6THKA.js.map +0 -1
- package/dist/chunk-6EWSYSO7.js +0 -46
- package/dist/chunk-6EWSYSO7.js.map +0 -1
- package/dist/chunk-CKIGERRS.js.map +0 -1
- /package/dist/{chunk-HHUDRGPY.js.map → chunk-BEQUGUY4.js.map} +0 -0
package/src/client.ts
CHANGED
|
@@ -28,14 +28,14 @@ interface GitCheckoutRequest {
|
|
|
28
28
|
repoUrl: string;
|
|
29
29
|
branch?: string;
|
|
30
30
|
targetDir?: string;
|
|
31
|
-
sessionId
|
|
31
|
+
sessionId: string;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
|
|
35
35
|
interface MkdirRequest {
|
|
36
36
|
path: string;
|
|
37
37
|
recursive?: boolean;
|
|
38
|
-
sessionId
|
|
38
|
+
sessionId: string;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
|
|
@@ -43,34 +43,34 @@ interface WriteFileRequest {
|
|
|
43
43
|
path: string;
|
|
44
44
|
content: string;
|
|
45
45
|
encoding?: string;
|
|
46
|
-
sessionId
|
|
46
|
+
sessionId: string;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
|
|
50
50
|
interface ReadFileRequest {
|
|
51
51
|
path: string;
|
|
52
52
|
encoding?: string;
|
|
53
|
-
sessionId
|
|
53
|
+
sessionId: string;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
|
|
57
57
|
interface DeleteFileRequest {
|
|
58
58
|
path: string;
|
|
59
|
-
sessionId
|
|
59
|
+
sessionId: string;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
|
|
63
63
|
interface RenameFileRequest {
|
|
64
64
|
oldPath: string;
|
|
65
65
|
newPath: string;
|
|
66
|
-
sessionId
|
|
66
|
+
sessionId: string;
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
|
|
70
70
|
interface MoveFileRequest {
|
|
71
71
|
sourcePath: string;
|
|
72
72
|
destinationPath: string;
|
|
73
|
-
sessionId
|
|
73
|
+
sessionId: string;
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
|
|
@@ -80,7 +80,7 @@ interface ListFilesRequest {
|
|
|
80
80
|
recursive?: boolean;
|
|
81
81
|
includeHidden?: boolean;
|
|
82
82
|
};
|
|
83
|
-
sessionId
|
|
83
|
+
sessionId: string;
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
|
|
@@ -143,7 +143,6 @@ interface HttpClientOptions {
|
|
|
143
143
|
export class HttpClient {
|
|
144
144
|
private baseUrl: string;
|
|
145
145
|
private options: HttpClientOptions;
|
|
146
|
-
private sessionId: string | null = null;
|
|
147
146
|
|
|
148
147
|
constructor(options: HttpClientOptions = {}) {
|
|
149
148
|
this.options = {
|
|
@@ -193,25 +192,52 @@ export class HttpClient {
|
|
|
193
192
|
}
|
|
194
193
|
}
|
|
195
194
|
|
|
196
|
-
async
|
|
195
|
+
async createSession(options: {
|
|
196
|
+
id: string;
|
|
197
|
+
env?: Record<string, string>;
|
|
198
|
+
cwd?: string;
|
|
199
|
+
isolation?: boolean;
|
|
200
|
+
}): Promise<{ success: boolean; id: string; message: string }> {
|
|
201
|
+
try {
|
|
202
|
+
const response = await this.doFetch(`/api/session/create`, {
|
|
203
|
+
method: "POST",
|
|
204
|
+
headers: {
|
|
205
|
+
"Content-Type": "application/json",
|
|
206
|
+
},
|
|
207
|
+
body: JSON.stringify(options),
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
if (!response.ok) {
|
|
211
|
+
const errorData = (await response.json().catch(() => ({}))) as {
|
|
212
|
+
error?: string;
|
|
213
|
+
};
|
|
214
|
+
throw new Error(
|
|
215
|
+
errorData.error || `Failed to create session: ${response.status}`
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const data = await response.json() as { success: boolean; id: string; message: string };
|
|
220
|
+
console.log(`[HTTP Client] Session created: ${options.id}`);
|
|
221
|
+
return data;
|
|
222
|
+
} catch (error) {
|
|
223
|
+
console.error("[HTTP Client] Error creating session:", error);
|
|
224
|
+
throw error;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
async exec(
|
|
229
|
+
sessionId: string,
|
|
197
230
|
command: string,
|
|
198
|
-
options
|
|
231
|
+
options?: Pick<BaseExecOptions, "cwd" | "env">
|
|
199
232
|
): Promise<ExecuteResponse> {
|
|
200
233
|
try {
|
|
201
|
-
|
|
202
|
-
const executeRequest = {
|
|
203
|
-
command,
|
|
204
|
-
sessionId: targetSessionId,
|
|
205
|
-
cwd: options.cwd,
|
|
206
|
-
env: options.env,
|
|
207
|
-
} satisfies ExecuteRequest;
|
|
208
|
-
|
|
234
|
+
// Always use session-specific endpoint
|
|
209
235
|
const response = await this.doFetch(`/api/execute`, {
|
|
210
|
-
|
|
236
|
+
method: "POST",
|
|
211
237
|
headers: {
|
|
212
238
|
"Content-Type": "application/json",
|
|
213
239
|
},
|
|
214
|
-
|
|
240
|
+
body: JSON.stringify({ id: sessionId, command }),
|
|
215
241
|
});
|
|
216
242
|
|
|
217
243
|
if (!response.ok) {
|
|
@@ -219,27 +245,34 @@ export class HttpClient {
|
|
|
219
245
|
error?: string;
|
|
220
246
|
};
|
|
221
247
|
throw new Error(
|
|
222
|
-
errorData.error || `
|
|
248
|
+
errorData.error || `Failed to execute in session: ${response.status}`
|
|
223
249
|
);
|
|
224
250
|
}
|
|
225
251
|
|
|
226
|
-
const data
|
|
252
|
+
const data = await response.json() as { stdout: string; stderr: string; exitCode: number; success: boolean };
|
|
227
253
|
console.log(
|
|
228
|
-
`[HTTP Client] Command executed
|
|
254
|
+
`[HTTP Client] Command executed in session ${sessionId}: ${command}`
|
|
229
255
|
);
|
|
256
|
+
|
|
257
|
+
// Convert to ExecuteResponse format for consistency
|
|
258
|
+
const executeResponse: ExecuteResponse = {
|
|
259
|
+
...data,
|
|
260
|
+
command,
|
|
261
|
+
timestamp: new Date().toISOString()
|
|
262
|
+
};
|
|
230
263
|
|
|
231
264
|
// Call the callback if provided
|
|
232
265
|
this.options.onCommandComplete?.(
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
266
|
+
executeResponse.success,
|
|
267
|
+
executeResponse.exitCode,
|
|
268
|
+
executeResponse.stdout,
|
|
269
|
+
executeResponse.stderr,
|
|
270
|
+
executeResponse.command
|
|
238
271
|
);
|
|
239
272
|
|
|
240
|
-
return
|
|
273
|
+
return executeResponse;
|
|
241
274
|
} catch (error) {
|
|
242
|
-
console.error("[HTTP Client] Error executing
|
|
275
|
+
console.error("[HTTP Client] Error executing in session:", error);
|
|
243
276
|
this.options.onError?.(
|
|
244
277
|
error instanceof Error ? error.message : "Unknown error",
|
|
245
278
|
command
|
|
@@ -248,23 +281,21 @@ export class HttpClient {
|
|
|
248
281
|
}
|
|
249
282
|
}
|
|
250
283
|
|
|
251
|
-
async
|
|
252
|
-
|
|
253
|
-
|
|
284
|
+
async execStream(
|
|
285
|
+
sessionId: string,
|
|
286
|
+
command: string
|
|
254
287
|
): Promise<ReadableStream<Uint8Array>> {
|
|
255
288
|
try {
|
|
256
|
-
|
|
257
|
-
|
|
289
|
+
// Always use session-specific streaming endpoint
|
|
258
290
|
const response = await this.doFetch(`/api/execute/stream`, {
|
|
259
|
-
|
|
260
|
-
command,
|
|
261
|
-
sessionId: targetSessionId,
|
|
262
|
-
}),
|
|
291
|
+
method: "POST",
|
|
263
292
|
headers: {
|
|
264
293
|
"Content-Type": "application/json",
|
|
265
|
-
Accept: "text/event-stream",
|
|
266
294
|
},
|
|
267
|
-
|
|
295
|
+
body: JSON.stringify({
|
|
296
|
+
id: sessionId,
|
|
297
|
+
command
|
|
298
|
+
}),
|
|
268
299
|
});
|
|
269
300
|
|
|
270
301
|
if (!response.ok) {
|
|
@@ -272,38 +303,37 @@ export class HttpClient {
|
|
|
272
303
|
error?: string;
|
|
273
304
|
};
|
|
274
305
|
throw new Error(
|
|
275
|
-
errorData.error || `
|
|
306
|
+
errorData.error || `Failed to stream execute in session: ${response.status}`
|
|
276
307
|
);
|
|
277
308
|
}
|
|
278
309
|
|
|
279
310
|
if (!response.body) {
|
|
280
|
-
throw new Error("No response body for streaming
|
|
311
|
+
throw new Error("No response body for streaming execution");
|
|
281
312
|
}
|
|
282
313
|
|
|
283
|
-
console.log(
|
|
284
|
-
|
|
314
|
+
console.log(
|
|
315
|
+
`[HTTP Client] Started streaming command in session ${sessionId}: ${command}`
|
|
316
|
+
);
|
|
285
317
|
return response.body;
|
|
286
318
|
} catch (error) {
|
|
287
|
-
console.error("[HTTP Client] Error in
|
|
319
|
+
console.error("[HTTP Client] Error streaming execute in session:", error);
|
|
288
320
|
throw error;
|
|
289
321
|
}
|
|
290
322
|
}
|
|
291
323
|
|
|
292
324
|
async gitCheckout(
|
|
293
325
|
repoUrl: string,
|
|
326
|
+
sessionId: string,
|
|
294
327
|
branch: string = "main",
|
|
295
|
-
targetDir?: string
|
|
296
|
-
sessionId?: string
|
|
328
|
+
targetDir?: string
|
|
297
329
|
): Promise<GitCheckoutResponse> {
|
|
298
330
|
try {
|
|
299
|
-
const targetSessionId = sessionId || this.sessionId;
|
|
300
|
-
|
|
301
331
|
const response = await this.doFetch(`/api/git/checkout`, {
|
|
302
332
|
body: JSON.stringify({
|
|
303
333
|
branch,
|
|
304
334
|
repoUrl,
|
|
305
|
-
sessionId: targetSessionId,
|
|
306
335
|
targetDir,
|
|
336
|
+
sessionId,
|
|
307
337
|
} as GitCheckoutRequest),
|
|
308
338
|
headers: {
|
|
309
339
|
"Content-Type": "application/json",
|
|
@@ -335,16 +365,14 @@ export class HttpClient {
|
|
|
335
365
|
async mkdir(
|
|
336
366
|
path: string,
|
|
337
367
|
recursive: boolean = false,
|
|
338
|
-
sessionId
|
|
368
|
+
sessionId: string
|
|
339
369
|
): Promise<MkdirResponse> {
|
|
340
370
|
try {
|
|
341
|
-
const targetSessionId = sessionId || this.sessionId;
|
|
342
|
-
|
|
343
371
|
const response = await this.doFetch(`/api/mkdir`, {
|
|
344
372
|
body: JSON.stringify({
|
|
345
373
|
path,
|
|
346
374
|
recursive,
|
|
347
|
-
sessionId
|
|
375
|
+
sessionId,
|
|
348
376
|
} as MkdirRequest),
|
|
349
377
|
headers: {
|
|
350
378
|
"Content-Type": "application/json",
|
|
@@ -363,7 +391,7 @@ export class HttpClient {
|
|
|
363
391
|
|
|
364
392
|
const data: MkdirResponse = await response.json();
|
|
365
393
|
console.log(
|
|
366
|
-
`[HTTP Client] Directory created: ${path}, Success: ${data.success}, Recursive: ${data.recursive}`
|
|
394
|
+
`[HTTP Client] Directory created: ${path}, Success: ${data.success}, Recursive: ${data.recursive}${sessionId ? ` in session: ${sessionId}` : ''}`
|
|
367
395
|
);
|
|
368
396
|
|
|
369
397
|
return data;
|
|
@@ -377,17 +405,15 @@ export class HttpClient {
|
|
|
377
405
|
path: string,
|
|
378
406
|
content: string,
|
|
379
407
|
encoding: string = "utf-8",
|
|
380
|
-
sessionId
|
|
408
|
+
sessionId: string
|
|
381
409
|
): Promise<WriteFileResponse> {
|
|
382
410
|
try {
|
|
383
|
-
const targetSessionId = sessionId || this.sessionId;
|
|
384
|
-
|
|
385
411
|
const response = await this.doFetch(`/api/write`, {
|
|
386
412
|
body: JSON.stringify({
|
|
387
413
|
content,
|
|
388
414
|
encoding,
|
|
389
415
|
path,
|
|
390
|
-
sessionId
|
|
416
|
+
sessionId,
|
|
391
417
|
} as WriteFileRequest),
|
|
392
418
|
headers: {
|
|
393
419
|
"Content-Type": "application/json",
|
|
@@ -406,7 +432,7 @@ export class HttpClient {
|
|
|
406
432
|
|
|
407
433
|
const data: WriteFileResponse = await response.json();
|
|
408
434
|
console.log(
|
|
409
|
-
`[HTTP Client] File written: ${path}, Success: ${data.success}`
|
|
435
|
+
`[HTTP Client] File written: ${path}, Success: ${data.success}${sessionId ? ` in session: ${sessionId}` : ''}`
|
|
410
436
|
);
|
|
411
437
|
|
|
412
438
|
return data;
|
|
@@ -419,16 +445,14 @@ export class HttpClient {
|
|
|
419
445
|
async readFile(
|
|
420
446
|
path: string,
|
|
421
447
|
encoding: string = "utf-8",
|
|
422
|
-
sessionId
|
|
448
|
+
sessionId: string
|
|
423
449
|
): Promise<ReadFileResponse> {
|
|
424
450
|
try {
|
|
425
|
-
const targetSessionId = sessionId || this.sessionId;
|
|
426
|
-
|
|
427
451
|
const response = await this.doFetch(`/api/read`, {
|
|
428
452
|
body: JSON.stringify({
|
|
429
453
|
encoding,
|
|
430
454
|
path,
|
|
431
|
-
sessionId
|
|
455
|
+
sessionId,
|
|
432
456
|
} as ReadFileRequest),
|
|
433
457
|
headers: {
|
|
434
458
|
"Content-Type": "application/json",
|
|
@@ -447,7 +471,7 @@ export class HttpClient {
|
|
|
447
471
|
|
|
448
472
|
const data: ReadFileResponse = await response.json();
|
|
449
473
|
console.log(
|
|
450
|
-
`[HTTP Client] File read: ${path}, Success: ${data.success}, Content length: ${data.content.length}`
|
|
474
|
+
`[HTTP Client] File read: ${path}, Success: ${data.success}, Content length: ${data.content.length}${sessionId ? ` in session: ${sessionId}` : ''}`
|
|
451
475
|
);
|
|
452
476
|
|
|
453
477
|
return data;
|
|
@@ -459,15 +483,13 @@ export class HttpClient {
|
|
|
459
483
|
|
|
460
484
|
async deleteFile(
|
|
461
485
|
path: string,
|
|
462
|
-
sessionId
|
|
486
|
+
sessionId: string
|
|
463
487
|
): Promise<DeleteFileResponse> {
|
|
464
488
|
try {
|
|
465
|
-
const targetSessionId = sessionId || this.sessionId;
|
|
466
|
-
|
|
467
489
|
const response = await this.doFetch(`/api/delete`, {
|
|
468
490
|
body: JSON.stringify({
|
|
469
491
|
path,
|
|
470
|
-
sessionId
|
|
492
|
+
sessionId,
|
|
471
493
|
} as DeleteFileRequest),
|
|
472
494
|
headers: {
|
|
473
495
|
"Content-Type": "application/json",
|
|
@@ -486,7 +508,7 @@ export class HttpClient {
|
|
|
486
508
|
|
|
487
509
|
const data: DeleteFileResponse = await response.json();
|
|
488
510
|
console.log(
|
|
489
|
-
`[HTTP Client] File deleted: ${path}, Success: ${data.success}`
|
|
511
|
+
`[HTTP Client] File deleted: ${path}, Success: ${data.success}${sessionId ? ` in session: ${sessionId}` : ''}`
|
|
490
512
|
);
|
|
491
513
|
|
|
492
514
|
return data;
|
|
@@ -499,16 +521,14 @@ export class HttpClient {
|
|
|
499
521
|
async renameFile(
|
|
500
522
|
oldPath: string,
|
|
501
523
|
newPath: string,
|
|
502
|
-
sessionId
|
|
524
|
+
sessionId: string
|
|
503
525
|
): Promise<RenameFileResponse> {
|
|
504
526
|
try {
|
|
505
|
-
const targetSessionId = sessionId || this.sessionId;
|
|
506
|
-
|
|
507
527
|
const response = await this.doFetch(`/api/rename`, {
|
|
508
528
|
body: JSON.stringify({
|
|
509
529
|
newPath,
|
|
510
530
|
oldPath,
|
|
511
|
-
sessionId
|
|
531
|
+
sessionId,
|
|
512
532
|
} as RenameFileRequest),
|
|
513
533
|
headers: {
|
|
514
534
|
"Content-Type": "application/json",
|
|
@@ -527,7 +547,7 @@ export class HttpClient {
|
|
|
527
547
|
|
|
528
548
|
const data: RenameFileResponse = await response.json();
|
|
529
549
|
console.log(
|
|
530
|
-
`[HTTP Client] File renamed: ${oldPath} -> ${newPath}, Success: ${data.success}`
|
|
550
|
+
`[HTTP Client] File renamed: ${oldPath} -> ${newPath}, Success: ${data.success}${sessionId ? ` in session: ${sessionId}` : ''}`
|
|
531
551
|
);
|
|
532
552
|
|
|
533
553
|
return data;
|
|
@@ -540,16 +560,14 @@ export class HttpClient {
|
|
|
540
560
|
async moveFile(
|
|
541
561
|
sourcePath: string,
|
|
542
562
|
destinationPath: string,
|
|
543
|
-
sessionId
|
|
563
|
+
sessionId: string
|
|
544
564
|
): Promise<MoveFileResponse> {
|
|
545
565
|
try {
|
|
546
|
-
const targetSessionId = sessionId || this.sessionId;
|
|
547
|
-
|
|
548
566
|
const response = await this.doFetch(`/api/move`, {
|
|
549
567
|
body: JSON.stringify({
|
|
550
568
|
destinationPath,
|
|
551
|
-
sessionId: targetSessionId,
|
|
552
569
|
sourcePath,
|
|
570
|
+
sessionId,
|
|
553
571
|
} as MoveFileRequest),
|
|
554
572
|
headers: {
|
|
555
573
|
"Content-Type": "application/json",
|
|
@@ -568,7 +586,7 @@ export class HttpClient {
|
|
|
568
586
|
|
|
569
587
|
const data: MoveFileResponse = await response.json();
|
|
570
588
|
console.log(
|
|
571
|
-
`[HTTP Client] File moved: ${sourcePath} -> ${destinationPath}, Success: ${data.success}`
|
|
589
|
+
`[HTTP Client] File moved: ${sourcePath} -> ${destinationPath}, Success: ${data.success}${sessionId ? ` in session: ${sessionId}` : ''}`
|
|
572
590
|
);
|
|
573
591
|
|
|
574
592
|
return data;
|
|
@@ -580,20 +598,18 @@ export class HttpClient {
|
|
|
580
598
|
|
|
581
599
|
async listFiles(
|
|
582
600
|
path: string,
|
|
601
|
+
sessionId: string,
|
|
583
602
|
options?: {
|
|
584
603
|
recursive?: boolean;
|
|
585
604
|
includeHidden?: boolean;
|
|
586
|
-
}
|
|
587
|
-
sessionId?: string
|
|
605
|
+
}
|
|
588
606
|
): Promise<ListFilesResponse> {
|
|
589
607
|
try {
|
|
590
|
-
const targetSessionId = sessionId || this.sessionId;
|
|
591
|
-
|
|
592
608
|
const response = await this.doFetch(`/api/list-files`, {
|
|
593
609
|
body: JSON.stringify({
|
|
594
610
|
path,
|
|
595
611
|
options,
|
|
596
|
-
sessionId
|
|
612
|
+
sessionId,
|
|
597
613
|
} as ListFilesRequest),
|
|
598
614
|
headers: {
|
|
599
615
|
"Content-Type": "application/json",
|
|
@@ -612,7 +628,7 @@ export class HttpClient {
|
|
|
612
628
|
|
|
613
629
|
const data: ListFilesResponse = await response.json();
|
|
614
630
|
console.log(
|
|
615
|
-
`[HTTP Client] Listed ${data.files.length} files in: ${path}, Success: ${data.success}`
|
|
631
|
+
`[HTTP Client] Listed ${data.files.length} files in: ${path}, Success: ${data.success}${sessionId ? ` in session: ${sessionId}` : ''}`
|
|
616
632
|
);
|
|
617
633
|
|
|
618
634
|
return data;
|
|
@@ -742,48 +758,13 @@ export class HttpClient {
|
|
|
742
758
|
}
|
|
743
759
|
}
|
|
744
760
|
|
|
745
|
-
async getCommands(): Promise<string[]> {
|
|
746
|
-
try {
|
|
747
|
-
const response = await fetch(`${this.baseUrl}/api/commands`, {
|
|
748
|
-
headers: {
|
|
749
|
-
"Content-Type": "application/json",
|
|
750
|
-
},
|
|
751
|
-
method: "GET",
|
|
752
|
-
});
|
|
753
|
-
|
|
754
|
-
if (!response.ok) {
|
|
755
|
-
throw new Error(`HTTP error! status: ${response.status}`);
|
|
756
|
-
}
|
|
757
|
-
|
|
758
|
-
const data: CommandsResponse = await response.json();
|
|
759
|
-
console.log(
|
|
760
|
-
`[HTTP Client] Available commands: ${data.availableCommands.length}`
|
|
761
|
-
);
|
|
762
|
-
return data.availableCommands;
|
|
763
|
-
} catch (error) {
|
|
764
|
-
console.error("[HTTP Client] Error getting commands:", error);
|
|
765
|
-
throw error;
|
|
766
|
-
}
|
|
767
|
-
}
|
|
768
|
-
|
|
769
|
-
getSessionId(): string | null {
|
|
770
|
-
return this.sessionId;
|
|
771
|
-
}
|
|
772
|
-
|
|
773
|
-
setSessionId(sessionId: string): void {
|
|
774
|
-
this.sessionId = sessionId;
|
|
775
|
-
}
|
|
776
|
-
|
|
777
|
-
clearSession(): void {
|
|
778
|
-
this.sessionId = null;
|
|
779
|
-
}
|
|
780
761
|
|
|
781
762
|
// Process management methods
|
|
782
763
|
async startProcess(
|
|
783
764
|
command: string,
|
|
765
|
+
sessionId: string,
|
|
784
766
|
options?: {
|
|
785
767
|
processId?: string;
|
|
786
|
-
sessionId?: string;
|
|
787
768
|
timeout?: number;
|
|
788
769
|
env?: Record<string, string>;
|
|
789
770
|
cwd?: string;
|
|
@@ -792,15 +773,11 @@ export class HttpClient {
|
|
|
792
773
|
}
|
|
793
774
|
): Promise<StartProcessResponse> {
|
|
794
775
|
try {
|
|
795
|
-
const targetSessionId = options?.sessionId || this.sessionId;
|
|
796
|
-
|
|
797
776
|
const response = await this.doFetch("/api/process/start", {
|
|
798
777
|
body: JSON.stringify({
|
|
799
778
|
command,
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
sessionId: targetSessionId,
|
|
803
|
-
},
|
|
779
|
+
sessionId,
|
|
780
|
+
options,
|
|
804
781
|
} as StartProcessRequest),
|
|
805
782
|
headers: {
|
|
806
783
|
"Content-Type": "application/json",
|
|
@@ -829,9 +806,12 @@ export class HttpClient {
|
|
|
829
806
|
}
|
|
830
807
|
}
|
|
831
808
|
|
|
832
|
-
async listProcesses(): Promise<ListProcessesResponse> {
|
|
809
|
+
async listProcesses(sessionId?: string): Promise<ListProcessesResponse> {
|
|
833
810
|
try {
|
|
834
|
-
const
|
|
811
|
+
const url = sessionId
|
|
812
|
+
? `/api/process/list?session=${encodeURIComponent(sessionId)}`
|
|
813
|
+
: "/api/process/list";
|
|
814
|
+
const response = await this.doFetch(url, {
|
|
835
815
|
headers: {
|
|
836
816
|
"Content-Type": "application/json",
|
|
837
817
|
},
|
|
@@ -922,13 +902,16 @@ export class HttpClient {
|
|
|
922
902
|
}
|
|
923
903
|
}
|
|
924
904
|
|
|
925
|
-
async killAllProcesses(): Promise<{
|
|
905
|
+
async killAllProcesses(sessionId?: string): Promise<{
|
|
926
906
|
success: boolean;
|
|
927
907
|
killedCount: number;
|
|
928
908
|
message: string;
|
|
929
909
|
}> {
|
|
930
910
|
try {
|
|
931
|
-
const
|
|
911
|
+
const url = sessionId
|
|
912
|
+
? `/api/process/kill-all?session=${encodeURIComponent(sessionId)}`
|
|
913
|
+
: "/api/process/kill-all";
|
|
914
|
+
const response = await this.doFetch(url, {
|
|
932
915
|
headers: {
|
|
933
916
|
"Content-Type": "application/json",
|
|
934
917
|
},
|
|
@@ -987,7 +970,8 @@ export class HttpClient {
|
|
|
987
970
|
}
|
|
988
971
|
|
|
989
972
|
async streamProcessLogs(
|
|
990
|
-
processId: string
|
|
973
|
+
processId: string,
|
|
974
|
+
options?: { signal?: AbortSignal }
|
|
991
975
|
): Promise<ReadableStream<Uint8Array>> {
|
|
992
976
|
try {
|
|
993
977
|
const response = await this.doFetch(`/api/process/${processId}/stream`, {
|
|
@@ -996,6 +980,7 @@ export class HttpClient {
|
|
|
996
980
|
"Cache-Control": "no-cache",
|
|
997
981
|
},
|
|
998
982
|
method: "GET",
|
|
983
|
+
signal: options?.signal,
|
|
999
984
|
});
|
|
1000
985
|
|
|
1001
986
|
if (!response.ok) {
|
package/src/index.ts
CHANGED
|
@@ -44,13 +44,21 @@ export {
|
|
|
44
44
|
export type {
|
|
45
45
|
DeleteFileResponse,
|
|
46
46
|
ExecEvent,
|
|
47
|
+
ExecOptions,
|
|
48
|
+
ExecResult,
|
|
47
49
|
ExecuteResponse,
|
|
50
|
+
ExecutionSession,
|
|
48
51
|
GitCheckoutResponse,
|
|
52
|
+
ISandbox,
|
|
49
53
|
ListFilesResponse,
|
|
50
54
|
LogEvent,
|
|
51
55
|
MkdirResponse,
|
|
52
56
|
MoveFileResponse,
|
|
57
|
+
Process,
|
|
58
|
+
ProcessOptions,
|
|
59
|
+
ProcessStatus,
|
|
53
60
|
ReadFileResponse,
|
|
54
61
|
RenameFileResponse,
|
|
62
|
+
StreamOptions,
|
|
55
63
|
WriteFileResponse
|
|
56
64
|
} from "./types";
|