computesdk 1.1.1 → 1.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.
package/dist/index.mjs CHANGED
@@ -1,35 +1,18 @@
1
- // src/sandbox.ts
2
- var SandboxManager = class {
3
- /**
4
- * Create a sandbox from a provider
5
- */
6
- async create(provider, options) {
7
- return await provider.sandbox.create(options);
8
- }
9
- /**
10
- * Get an existing sandbox by ID from a provider
11
- */
12
- async getById(provider, sandboxId) {
13
- return await provider.sandbox.getById(sandboxId);
14
- }
15
- /**
16
- * List all active sandboxes from a provider
17
- */
18
- async list(provider) {
19
- return await provider.sandbox.list();
20
- }
21
- /**
22
- * Destroy a sandbox via a provider
23
- */
24
- async destroy(provider, sandboxId) {
25
- return await provider.sandbox.destroy(sandboxId);
1
+ // src/types/sandbox.ts
2
+ var CommandExitError = class extends Error {
3
+ constructor(result) {
4
+ super(`Command exited with code ${result.exitCode}`);
5
+ this.result = result;
6
+ this.name = "CommandExitError";
26
7
  }
27
8
  };
9
+ function isCommandExitError(error) {
10
+ return typeof error === "object" && error !== null && "name" in error && error.name === "CommandExitError" && "result" in error;
11
+ }
28
12
 
29
13
  // src/compute.ts
30
14
  var ComputeManager = class {
31
15
  constructor() {
32
- this.sandboxManager = new SandboxManager();
33
16
  this.config = null;
34
17
  this.sandbox = {
35
18
  /**
@@ -45,16 +28,16 @@ var ComputeManager = class {
45
28
  * provider: e2b({ apiKey: 'your-key' })
46
29
  * })
47
30
  *
48
- * // With default provider (both forms work)
49
- * compute.setConfig({ provider: e2b({ apiKey: 'your-key' }) })
50
- * const sandbox1 = await compute.sandbox.create({})
51
- * const sandbox2 = await compute.sandbox.create()
31
+ * // With default provider (both forms work)
32
+ * compute.setConfig({ defaultProvider: e2b({ apiKey: 'your-key' }) })
33
+ * const sandbox1 = await compute.sandbox.create({})
34
+ * const sandbox2 = await compute.sandbox.create()
52
35
  * ```
53
36
  */
54
37
  create: async (params) => {
55
38
  const provider = params && "provider" in params && params.provider ? params.provider : this.getDefaultProvider();
56
39
  const options = params?.options;
57
- return await this.sandboxManager.create(provider, options);
40
+ return await provider.sandbox.create(options);
58
41
  },
59
42
  /**
60
43
  * Get an existing sandbox by ID from a provider (or default provider if configured)
@@ -62,12 +45,12 @@ var ComputeManager = class {
62
45
  getById: async (providerOrSandboxId, sandboxId) => {
63
46
  if (typeof providerOrSandboxId === "string") {
64
47
  const provider = this.getDefaultProvider();
65
- return await this.sandboxManager.getById(provider, providerOrSandboxId);
48
+ return await provider.sandbox.getById(providerOrSandboxId);
66
49
  } else {
67
50
  if (!sandboxId) {
68
51
  throw new Error("sandboxId is required when provider is specified");
69
52
  }
70
- return await this.sandboxManager.getById(providerOrSandboxId, sandboxId);
53
+ return await providerOrSandboxId.sandbox.getById(sandboxId);
71
54
  }
72
55
  },
73
56
  /**
@@ -75,7 +58,7 @@ var ComputeManager = class {
75
58
  */
76
59
  list: async (provider) => {
77
60
  const actualProvider = provider || this.getDefaultProvider();
78
- return await this.sandboxManager.list(actualProvider);
61
+ return await actualProvider.sandbox.list();
79
62
  },
80
63
  /**
81
64
  * Destroy a sandbox via a provider (or default provider if configured)
@@ -83,12 +66,12 @@ var ComputeManager = class {
83
66
  destroy: async (providerOrSandboxId, sandboxId) => {
84
67
  if (typeof providerOrSandboxId === "string") {
85
68
  const provider = this.getDefaultProvider();
86
- return await this.sandboxManager.destroy(provider, providerOrSandboxId);
69
+ return await provider.sandbox.destroy(providerOrSandboxId);
87
70
  } else {
88
71
  if (!sandboxId) {
89
72
  throw new Error("sandboxId is required when provider is specified");
90
73
  }
91
- return await this.sandboxManager.destroy(providerOrSandboxId, sandboxId);
74
+ return await providerOrSandboxId.sandbox.destroy(sandboxId);
92
75
  }
93
76
  }
94
77
  };
@@ -97,7 +80,17 @@ var ComputeManager = class {
97
80
  * Set default configuration
98
81
  */
99
82
  setConfig(config) {
100
- this.config = config;
83
+ if (!config.defaultProvider && !config.provider) {
84
+ throw new Error("Either defaultProvider or provider must be specified in setConfig");
85
+ }
86
+ if (config.defaultProvider && config.provider) {
87
+ console.warn("Both defaultProvider and provider specified in setConfig. Using defaultProvider. The provider key is deprecated, please use defaultProvider instead.");
88
+ }
89
+ const actualProvider = config.defaultProvider || config.provider;
90
+ this.config = {
91
+ provider: actualProvider,
92
+ defaultProvider: actualProvider
93
+ };
101
94
  }
102
95
  /**
103
96
  * Get current configuration
@@ -117,7 +110,7 @@ var ComputeManager = class {
117
110
  getDefaultProvider() {
118
111
  if (!this.config?.provider) {
119
112
  throw new Error(
120
- "No default provider configured. Either call compute.setConfig({ provider }) or pass provider explicitly."
113
+ "No default provider configured. Either call compute.setConfig({ defaultProvider }) or pass provider explicitly."
121
114
  );
122
115
  }
123
116
  return this.config.provider;
@@ -126,567 +119,281 @@ var ComputeManager = class {
126
119
  // blob = new BlobManager();
127
120
  // database = new DatabaseManager();
128
121
  // git = new GitManager();
129
- /**
130
- * Get the sandbox manager (useful for testing)
131
- */
132
- getSandboxManager() {
133
- return this.sandboxManager;
134
- }
135
122
  };
136
123
  var compute = new ComputeManager();
137
124
 
138
125
  // src/request-handler.ts
139
- async function handleComputeRequest(params) {
140
- const { request, provider } = params;
126
+ async function executeAction(body, provider) {
141
127
  try {
142
- const getSandbox = async (sandboxId) => {
143
- if (sandboxId) {
144
- const existingSandbox = await compute.sandbox.getById(provider, sandboxId);
145
- if (!existingSandbox) {
146
- throw new Error(`Sandbox with ID ${sandboxId} not found`);
147
- }
148
- return existingSandbox;
149
- } else {
150
- return await compute.sandbox.create({
151
- provider,
152
- options: request.options || { runtime: "python" }
153
- });
128
+ const { action, sandboxId } = body;
129
+ if (action === "compute.sandbox.create") {
130
+ const sandbox2 = await compute.sandbox.create({
131
+ provider,
132
+ options: body.options || { runtime: "python" }
133
+ });
134
+ return {
135
+ success: true,
136
+ sandboxId: sandbox2.sandboxId,
137
+ provider: provider.name
138
+ };
139
+ }
140
+ if (action === "compute.sandbox.list") {
141
+ const sandboxes = await compute.sandbox.list(provider);
142
+ return {
143
+ success: true,
144
+ sandboxId: "",
145
+ provider: provider.name,
146
+ sandboxes: sandboxes.map((sb) => ({
147
+ sandboxId: sb.sandboxId,
148
+ provider: sb.provider
149
+ }))
150
+ };
151
+ }
152
+ if (action === "compute.sandbox.destroy") {
153
+ if (!sandboxId) {
154
+ throw new Error("sandboxId is required for destroy action");
154
155
  }
156
+ await compute.sandbox.destroy(provider, sandboxId);
157
+ return {
158
+ success: true,
159
+ sandboxId,
160
+ provider: provider.name
161
+ };
162
+ }
163
+ if (!sandboxId) {
164
+ throw new Error("sandboxId is required for this action");
165
+ }
166
+ const sandbox = await compute.sandbox.getById(provider, sandboxId);
167
+ if (!sandbox) {
168
+ throw new Error(`Sandbox ${sandboxId} not found`);
169
+ }
170
+ if (action === "compute.sandbox.getInfo") {
171
+ const result = await sandbox.getInfo();
172
+ return {
173
+ success: true,
174
+ sandboxId,
175
+ provider: provider.name,
176
+ info: {
177
+ id: result.id,
178
+ provider: result.provider,
179
+ runtime: result.runtime,
180
+ status: result.status,
181
+ createdAt: result.createdAt.toISOString(),
182
+ timeout: result.timeout,
183
+ metadata: result.metadata
184
+ }
185
+ };
186
+ }
187
+ if (action === "compute.sandbox.runCode") {
188
+ if (!body.code) throw new Error("code is required");
189
+ const result = await sandbox.runCode(body.code, body.runtime);
190
+ return {
191
+ success: true,
192
+ sandboxId,
193
+ provider: provider.name,
194
+ result: {
195
+ stdout: result.stdout,
196
+ stderr: result.stderr,
197
+ exitCode: result.exitCode,
198
+ executionTime: result.executionTime
199
+ }
200
+ };
201
+ }
202
+ if (action === "compute.sandbox.runCommand") {
203
+ if (!body.command) throw new Error("command is required");
204
+ const result = await sandbox.runCommand(body.command, body.args);
205
+ return {
206
+ success: true,
207
+ sandboxId,
208
+ provider: provider.name,
209
+ result: {
210
+ stdout: result.stdout,
211
+ stderr: result.stderr,
212
+ exitCode: result.exitCode,
213
+ executionTime: result.executionTime
214
+ }
215
+ };
216
+ }
217
+ if (action === "compute.sandbox.filesystem.readFile") {
218
+ if (!body.path) throw new Error("path is required");
219
+ const result = await sandbox.filesystem.readFile(body.path);
220
+ return {
221
+ success: true,
222
+ sandboxId,
223
+ provider: provider.name,
224
+ fileContent: result
225
+ };
226
+ }
227
+ if (action === "compute.sandbox.filesystem.writeFile") {
228
+ if (!body.path) throw new Error("path is required");
229
+ if (body.content === void 0) throw new Error("content is required");
230
+ await sandbox.filesystem.writeFile(body.path, body.content);
231
+ return { success: true, sandboxId, provider: provider.name };
232
+ }
233
+ if (action === "compute.sandbox.filesystem.mkdir") {
234
+ if (!body.path) throw new Error("path is required");
235
+ await sandbox.filesystem.mkdir(body.path);
236
+ return { success: true, sandboxId, provider: provider.name };
237
+ }
238
+ if (action === "compute.sandbox.filesystem.readdir") {
239
+ if (!body.path) throw new Error("path is required");
240
+ const result = await sandbox.filesystem.readdir(body.path);
241
+ return {
242
+ success: true,
243
+ sandboxId,
244
+ provider: provider.name,
245
+ files: result.map((entry) => ({
246
+ name: entry.name,
247
+ path: entry.path,
248
+ isDirectory: entry.isDirectory,
249
+ size: entry.size,
250
+ lastModified: entry.lastModified.toISOString()
251
+ }))
252
+ };
253
+ }
254
+ if (action === "compute.sandbox.filesystem.exists") {
255
+ if (!body.path) throw new Error("path is required");
256
+ const result = await sandbox.filesystem.exists(body.path);
257
+ return {
258
+ success: true,
259
+ sandboxId,
260
+ provider: provider.name,
261
+ exists: result
262
+ };
263
+ }
264
+ if (action === "compute.sandbox.filesystem.remove") {
265
+ if (!body.path) throw new Error("path is required");
266
+ await sandbox.filesystem.remove(body.path);
267
+ return { success: true, sandboxId, provider: provider.name };
268
+ }
269
+ throw new Error(`Unknown action: ${action}`);
270
+ } catch (error) {
271
+ return {
272
+ success: false,
273
+ error: error instanceof Error ? error.message : "Unknown error occurred",
274
+ sandboxId: body.sandboxId || "",
275
+ provider: provider.name
155
276
  };
156
- switch (request.action) {
157
- // Sandbox operations
158
- case "compute.sandbox.create": {
159
- const sandbox = await compute.sandbox.create({
160
- provider,
161
- options: request.options || { runtime: "python" }
162
- });
163
- return {
164
- success: true,
165
- sandboxId: sandbox.sandboxId,
166
- provider: provider.name
167
- };
168
- }
169
- case "compute.sandbox.destroy": {
170
- if (!request.sandboxId) {
171
- return {
172
- success: false,
173
- error: "Sandbox ID is required for destroy action",
174
- sandboxId: "",
175
- provider: provider.name
176
- };
177
- }
178
- await compute.sandbox.destroy(provider, request.sandboxId);
179
- return {
180
- success: true,
181
- sandboxId: request.sandboxId,
182
- provider: provider.name
183
- };
184
- }
185
- case "compute.sandbox.getInfo": {
186
- if (!request.sandboxId) {
187
- return {
188
- success: false,
189
- error: "Sandbox ID is required for getInfo action",
190
- sandboxId: "",
191
- provider: provider.name
192
- };
193
- }
194
- const sandbox = await getSandbox(request.sandboxId);
195
- const info = await sandbox.getInfo();
196
- return {
197
- success: true,
198
- sandboxId: request.sandboxId,
199
- provider: provider.name,
200
- info: {
201
- id: info.id,
202
- provider: info.provider,
203
- runtime: info.runtime,
204
- status: info.status,
205
- createdAt: info.createdAt.toISOString(),
206
- timeout: info.timeout,
207
- metadata: info.metadata
208
- }
209
- };
210
- }
211
- case "compute.sandbox.list": {
212
- const sandboxes = await compute.sandbox.list(provider);
213
- return {
214
- success: true,
277
+ }
278
+ }
279
+ async function handleComputeRequest(paramsOrRequestOrBody, provider) {
280
+ if (typeof paramsOrRequestOrBody === "object" && "request" in paramsOrRequestOrBody && "provider" in paramsOrRequestOrBody) {
281
+ const params = paramsOrRequestOrBody;
282
+ return await executeAction(params.request, params.provider);
283
+ }
284
+ if (!provider) {
285
+ throw new Error("Provider is required when not using object-style API");
286
+ }
287
+ const requestOrBody = paramsOrRequestOrBody;
288
+ try {
289
+ let body;
290
+ if (requestOrBody instanceof Request) {
291
+ if (requestOrBody.method !== "POST") {
292
+ return Response.json({
293
+ success: false,
294
+ error: "Only POST requests are supported",
215
295
  sandboxId: "",
216
- provider: provider.name,
217
- sandboxes: sandboxes.map((sandbox) => ({
218
- sandboxId: sandbox.sandboxId,
219
- provider: sandbox.provider
220
- }))
221
- };
222
- }
223
- // Code execution
224
- case "compute.sandbox.runCode": {
225
- if (!request.code) {
226
- return {
227
- success: false,
228
- error: "Code is required for runCode action",
229
- sandboxId: request.sandboxId || "",
230
- provider: provider.name
231
- };
232
- }
233
- const sandbox = await getSandbox(request.sandboxId);
234
- const result = await sandbox.runCode(request.code, request.runtime);
235
- return {
236
- success: true,
237
- sandboxId: sandbox.sandboxId,
238
- provider: provider.name,
239
- result: {
240
- stdout: result.stdout,
241
- stderr: result.stderr,
242
- exitCode: result.exitCode,
243
- executionTime: result.executionTime
244
- }
245
- };
246
- }
247
- case "compute.sandbox.runCommand": {
248
- if (!request.command) {
249
- return {
250
- success: false,
251
- error: "Command is required for runCommand action",
252
- sandboxId: request.sandboxId || "",
253
- provider: provider.name
254
- };
255
- }
256
- const sandbox = await getSandbox(request.sandboxId);
257
- const result = await sandbox.runCommand(request.command, request.args);
258
- return {
259
- success: true,
260
- sandboxId: sandbox.sandboxId,
261
- provider: provider.name,
262
- result: {
263
- stdout: result.stdout,
264
- stderr: result.stderr,
265
- exitCode: result.exitCode,
266
- executionTime: result.executionTime
267
- }
268
- };
269
- }
270
- // Filesystem operations
271
- case "compute.sandbox.filesystem.readFile": {
272
- if (!request.sandboxId) {
273
- return {
274
- success: false,
275
- error: "Sandbox ID is required for filesystem operations",
276
- sandboxId: "",
277
- provider: provider.name
278
- };
279
- }
280
- if (!request.path) {
281
- return {
282
- success: false,
283
- error: "File path is required for readFile action",
284
- sandboxId: request.sandboxId,
285
- provider: provider.name
286
- };
287
- }
288
- const sandbox = await getSandbox(request.sandboxId);
289
- const content = await sandbox.filesystem.readFile(request.path);
290
- return {
291
- success: true,
292
- sandboxId: request.sandboxId,
293
- provider: provider.name,
294
- fileContent: content
295
- };
296
- }
297
- case "compute.sandbox.filesystem.writeFile": {
298
- if (!request.sandboxId) {
299
- return {
300
- success: false,
301
- error: "Sandbox ID is required for filesystem operations",
302
- sandboxId: "",
303
- provider: provider.name
304
- };
305
- }
306
- if (!request.path) {
307
- return {
308
- success: false,
309
- error: "File path is required for writeFile action",
310
- sandboxId: request.sandboxId,
311
- provider: provider.name
312
- };
313
- }
314
- if (request.content === void 0) {
315
- return {
316
- success: false,
317
- error: "File content is required for writeFile action",
318
- sandboxId: request.sandboxId,
319
- provider: provider.name
320
- };
321
- }
322
- const sandbox = await getSandbox(request.sandboxId);
323
- await sandbox.filesystem.writeFile(request.path, request.content);
324
- return {
325
- success: true,
326
- sandboxId: request.sandboxId,
327
- provider: provider.name
328
- };
329
- }
330
- case "compute.sandbox.filesystem.mkdir": {
331
- if (!request.sandboxId) {
332
- return {
333
- success: false,
334
- error: "Sandbox ID is required for filesystem operations",
335
- sandboxId: "",
336
- provider: provider.name
337
- };
338
- }
339
- if (!request.path) {
340
- return {
341
- success: false,
342
- error: "Directory path is required for mkdir action",
343
- sandboxId: request.sandboxId,
344
- provider: provider.name
345
- };
346
- }
347
- const sandbox = await getSandbox(request.sandboxId);
348
- await sandbox.filesystem.mkdir(request.path);
349
- return {
350
- success: true,
351
- sandboxId: request.sandboxId,
352
- provider: provider.name
353
- };
354
- }
355
- case "compute.sandbox.filesystem.readdir": {
356
- if (!request.sandboxId) {
357
- return {
358
- success: false,
359
- error: "Sandbox ID is required for filesystem operations",
360
- sandboxId: "",
361
- provider: provider.name
362
- };
363
- }
364
- if (!request.path) {
365
- return {
366
- success: false,
367
- error: "Directory path is required for readdir action",
368
- sandboxId: request.sandboxId,
369
- provider: provider.name
370
- };
371
- }
372
- const sandbox = await getSandbox(request.sandboxId);
373
- const entries = await sandbox.filesystem.readdir(request.path);
374
- return {
375
- success: true,
376
- sandboxId: request.sandboxId,
377
- provider: provider.name,
378
- files: entries.map((entry) => ({
379
- name: entry.name,
380
- path: entry.path,
381
- isDirectory: entry.isDirectory,
382
- size: entry.size,
383
- lastModified: entry.lastModified.toISOString()
384
- }))
385
- };
386
- }
387
- case "compute.sandbox.filesystem.exists": {
388
- if (!request.sandboxId) {
389
- return {
390
- success: false,
391
- error: "Sandbox ID is required for filesystem operations",
392
- sandboxId: "",
393
- provider: provider.name
394
- };
395
- }
396
- if (!request.path) {
397
- return {
398
- success: false,
399
- error: "Path is required for exists action",
400
- sandboxId: request.sandboxId,
401
- provider: provider.name
402
- };
403
- }
404
- const sandbox = await getSandbox(request.sandboxId);
405
- const exists = await sandbox.filesystem.exists(request.path);
406
- return {
407
- success: true,
408
- sandboxId: request.sandboxId,
409
- provider: provider.name,
410
- exists
411
- };
412
- }
413
- case "compute.sandbox.filesystem.remove": {
414
- if (!request.sandboxId) {
415
- return {
416
- success: false,
417
- error: "Sandbox ID is required for filesystem operations",
418
- sandboxId: "",
419
- provider: provider.name
420
- };
421
- }
422
- if (!request.path) {
423
- return {
424
- success: false,
425
- error: "Path is required for remove action",
426
- sandboxId: request.sandboxId,
427
- provider: provider.name
428
- };
429
- }
430
- const sandbox = await getSandbox(request.sandboxId);
431
- await sandbox.filesystem.remove(request.path);
432
- return {
433
- success: true,
434
- sandboxId: request.sandboxId,
435
296
  provider: provider.name
436
- };
297
+ }, { status: 405 });
437
298
  }
438
- // Terminal operations
439
- case "compute.sandbox.terminal.create": {
440
- if (!request.sandboxId) {
441
- return {
442
- success: false,
443
- error: "Sandbox ID is required for terminal operations",
444
- sandboxId: "",
445
- provider: provider.name
446
- };
447
- }
448
- const sandbox = await getSandbox(request.sandboxId);
449
- const terminal = await sandbox.terminal.create(request.terminalOptions);
450
- return {
451
- success: true,
452
- sandboxId: request.sandboxId,
453
- provider: provider.name,
454
- terminal: {
455
- pid: terminal.pid,
456
- command: terminal.command,
457
- status: terminal.status,
458
- cols: terminal.cols,
459
- rows: terminal.rows
460
- }
461
- };
462
- }
463
- case "compute.sandbox.terminal.list": {
464
- if (!request.sandboxId) {
465
- return {
466
- success: false,
467
- error: "Sandbox ID is required for terminal operations",
468
- sandboxId: "",
469
- provider: provider.name
470
- };
471
- }
472
- const sandbox = await getSandbox(request.sandboxId);
473
- const terminals = await sandbox.terminal.list();
474
- return {
475
- success: true,
476
- sandboxId: request.sandboxId,
477
- provider: provider.name,
478
- terminals: terminals.map((terminal) => ({
479
- pid: terminal.pid,
480
- command: terminal.command,
481
- status: terminal.status,
482
- cols: terminal.cols,
483
- rows: terminal.rows
484
- }))
485
- };
486
- }
487
- case "compute.sandbox.terminal.getById": {
488
- if (!request.sandboxId) {
489
- return {
490
- success: false,
491
- error: "Sandbox ID is required for terminal operations",
492
- sandboxId: "",
493
- provider: provider.name
494
- };
495
- }
496
- if (!request.terminalId) {
497
- return {
498
- success: false,
499
- error: "Terminal ID is required for getById action",
500
- sandboxId: request.sandboxId,
501
- provider: provider.name
502
- };
503
- }
504
- const sandbox = await getSandbox(request.sandboxId);
505
- const terminal = await sandbox.terminal.getById(request.terminalId);
506
- if (!terminal) {
507
- return {
508
- success: false,
509
- error: `Terminal with ID ${request.terminalId} not found`,
510
- sandboxId: request.sandboxId,
511
- provider: provider.name
512
- };
513
- }
514
- return {
515
- success: true,
516
- sandboxId: request.sandboxId,
517
- provider: provider.name,
518
- terminal: {
519
- pid: terminal.pid,
520
- command: terminal.command,
521
- status: terminal.status,
522
- cols: terminal.cols,
523
- rows: terminal.rows
524
- }
525
- };
526
- }
527
- case "compute.sandbox.terminal.destroy": {
528
- if (!request.sandboxId) {
529
- return {
530
- success: false,
531
- error: "Sandbox ID is required for terminal operations",
532
- sandboxId: "",
533
- provider: provider.name
534
- };
535
- }
536
- if (!request.terminalId) {
537
- return {
538
- success: false,
539
- error: "Terminal ID is required for destroy action",
540
- sandboxId: request.sandboxId,
541
- provider: provider.name
542
- };
543
- }
544
- const sandbox = await getSandbox(request.sandboxId);
545
- await sandbox.terminal.destroy(request.terminalId);
546
- return {
547
- success: true,
548
- sandboxId: request.sandboxId,
549
- provider: provider.name
550
- };
551
- }
552
- // Terminal I/O operations
553
- case "compute.sandbox.terminal.write": {
554
- if (!request.sandboxId) {
555
- return {
556
- success: false,
557
- error: "Sandbox ID is required for terminal operations",
558
- sandboxId: "",
559
- provider: provider.name
560
- };
561
- }
562
- if (!request.terminalId) {
563
- return {
564
- success: false,
565
- error: "Terminal ID is required for write action",
566
- sandboxId: request.sandboxId,
567
- provider: provider.name
568
- };
569
- }
570
- if (!request.data) {
571
- return {
572
- success: false,
573
- error: "Data is required for write action",
574
- sandboxId: request.sandboxId,
575
- provider: provider.name
576
- };
577
- }
578
- const sandbox = await getSandbox(request.sandboxId);
579
- const terminal = await sandbox.terminal.getById(request.terminalId);
580
- if (!terminal) {
581
- return {
582
- success: false,
583
- error: `Terminal with ID ${request.terminalId} not found`,
584
- sandboxId: request.sandboxId,
585
- provider: provider.name
586
- };
587
- }
588
- await terminal.write(request.data);
589
- return {
590
- success: true,
591
- sandboxId: request.sandboxId,
592
- provider: provider.name
593
- };
594
- }
595
- case "compute.sandbox.terminal.resize": {
596
- if (!request.sandboxId) {
597
- return {
598
- success: false,
599
- error: "Sandbox ID is required for terminal operations",
600
- sandboxId: "",
601
- provider: provider.name
602
- };
603
- }
604
- if (!request.terminalId) {
605
- return {
606
- success: false,
607
- error: "Terminal ID is required for resize action",
608
- sandboxId: request.sandboxId,
609
- provider: provider.name
610
- };
611
- }
612
- if (!request.cols || !request.rows) {
613
- return {
614
- success: false,
615
- error: "Cols and rows are required for resize action",
616
- sandboxId: request.sandboxId,
617
- provider: provider.name
618
- };
619
- }
620
- const sandbox = await getSandbox(request.sandboxId);
621
- const terminal = await sandbox.terminal.getById(request.terminalId);
622
- if (!terminal) {
623
- return {
624
- success: false,
625
- error: `Terminal with ID ${request.terminalId} not found`,
626
- sandboxId: request.sandboxId,
627
- provider: provider.name
628
- };
629
- }
630
- await terminal.resize(request.cols, request.rows);
631
- return {
632
- success: true,
633
- sandboxId: request.sandboxId,
634
- provider: provider.name
635
- };
636
- }
637
- case "compute.sandbox.terminal.kill": {
638
- if (!request.sandboxId) {
639
- return {
640
- success: false,
641
- error: "Sandbox ID is required for terminal operations",
642
- sandboxId: "",
643
- provider: provider.name
644
- };
645
- }
646
- if (!request.terminalId) {
647
- return {
648
- success: false,
649
- error: "Terminal ID is required for kill action",
650
- sandboxId: request.sandboxId,
651
- provider: provider.name
652
- };
653
- }
654
- const sandbox = await getSandbox(request.sandboxId);
655
- const terminal = await sandbox.terminal.getById(request.terminalId);
656
- if (!terminal) {
657
- return {
658
- success: false,
659
- error: `Terminal with ID ${request.terminalId} not found`,
660
- sandboxId: request.sandboxId,
661
- provider: provider.name
662
- };
663
- }
664
- await terminal.kill();
665
- return {
666
- success: true,
667
- sandboxId: request.sandboxId,
668
- provider: provider.name
669
- };
670
- }
671
- default:
672
- return {
299
+ try {
300
+ body = await requestOrBody.json();
301
+ } catch (parseError) {
302
+ return Response.json({
673
303
  success: false,
674
- error: `Unknown action: ${request.action}`,
675
- sandboxId: request.sandboxId || "",
304
+ error: "Invalid JSON in request body",
305
+ sandboxId: "",
676
306
  provider: provider.name
677
- };
307
+ }, { status: 400 });
308
+ }
309
+ } else {
310
+ body = requestOrBody;
678
311
  }
312
+ const result = await executeAction(body, provider);
313
+ return Response.json(result, {
314
+ status: result.success ? 200 : 500
315
+ });
679
316
  } catch (error) {
680
- return {
317
+ return Response.json({
681
318
  success: false,
682
- error: error instanceof Error ? error.message : "Unknown error occurred",
683
- sandboxId: request.sandboxId || "",
319
+ error: error instanceof Error ? error.message : "Request handling failed",
320
+ sandboxId: "",
684
321
  provider: provider.name
685
- };
322
+ }, { status: 500 });
686
323
  }
687
324
  }
688
325
 
689
326
  // src/factory.ts
327
+ var defaultFilesystemMethods = {
328
+ readFile: async (sandbox, path, runCommand) => {
329
+ const result = await runCommand(sandbox, "cat", [path]);
330
+ if (result.exitCode !== 0) {
331
+ throw new Error(`Failed to read file ${path}: ${result.stderr}`);
332
+ }
333
+ return result.stdout.replace(/\n$/, "");
334
+ },
335
+ writeFile: async (sandbox, path, content, runCommand) => {
336
+ const result = await runCommand(sandbox, "sh", ["-c", `echo ${JSON.stringify(content)} > ${JSON.stringify(path)}`]);
337
+ if (result.exitCode !== 0) {
338
+ throw new Error(`Failed to write file ${path}: ${result.stderr}`);
339
+ }
340
+ },
341
+ mkdir: async (sandbox, path, runCommand) => {
342
+ const result = await runCommand(sandbox, "mkdir", ["-p", path]);
343
+ if (result.exitCode !== 0) {
344
+ throw new Error(`Failed to create directory ${path}: ${result.stderr}`);
345
+ }
346
+ },
347
+ readdir: async (sandbox, path, runCommand) => {
348
+ let result = await runCommand(sandbox, "ls", ["-la", path]);
349
+ let hasDetailedOutput = true;
350
+ if (result.exitCode !== 0) {
351
+ result = await runCommand(sandbox, "ls", ["-l", path]);
352
+ }
353
+ if (result.exitCode !== 0) {
354
+ result = await runCommand(sandbox, "ls", [path]);
355
+ hasDetailedOutput = false;
356
+ }
357
+ if (result.exitCode !== 0) {
358
+ throw new Error(`Failed to list directory ${path}: ${result.stderr}`);
359
+ }
360
+ const lines = (result.stdout || "").split("\n").filter((line) => line.trim() && !line.startsWith("total"));
361
+ return lines.map((line) => {
362
+ if (hasDetailedOutput && line.includes(" ")) {
363
+ const parts = line.trim().split(/\s+/);
364
+ const name = parts[parts.length - 1];
365
+ const isDirectory = line.startsWith("d");
366
+ return {
367
+ name,
368
+ path: `${path}/${name}`,
369
+ isDirectory,
370
+ size: parseInt(parts[4]) || 0,
371
+ lastModified: /* @__PURE__ */ new Date()
372
+ };
373
+ } else {
374
+ const name = line.trim();
375
+ return {
376
+ name,
377
+ path: `${path}/${name}`,
378
+ isDirectory: false,
379
+ // Can't determine from simple ls
380
+ size: 0,
381
+ lastModified: /* @__PURE__ */ new Date()
382
+ };
383
+ }
384
+ });
385
+ },
386
+ exists: async (sandbox, path, runCommand) => {
387
+ const result = await runCommand(sandbox, "test", ["-e", path]);
388
+ return result.exitCode === 0;
389
+ },
390
+ remove: async (sandbox, path, runCommand) => {
391
+ const result = await runCommand(sandbox, "rm", ["-rf", path]);
392
+ if (result.exitCode !== 0) {
393
+ throw new Error(`Failed to remove ${path}: ${result.stderr}`);
394
+ }
395
+ }
396
+ };
690
397
  var UnsupportedFileSystem = class {
691
398
  constructor(providerName) {
692
399
  this.providerName = providerName;
@@ -710,155 +417,51 @@ var UnsupportedFileSystem = class {
710
417
  throw new Error(`Filesystem operations are not supported by ${this.providerName}'s sandbox environment. ${this.providerName} sandboxes are designed for code execution only.`);
711
418
  }
712
419
  };
713
- var UnsupportedTerminal = class {
714
- constructor(providerName) {
715
- this.providerName = providerName;
716
- }
717
- async create(_options) {
718
- throw new Error(`Terminal operations are not supported by ${this.providerName}'s sandbox environment. ${this.providerName} sandboxes are designed for code execution only.`);
719
- }
720
- async getById(_terminalId) {
721
- throw new Error(`Terminal operations are not supported by ${this.providerName}'s sandbox environment. ${this.providerName} sandboxes are designed for code execution only.`);
722
- }
723
- async list() {
724
- throw new Error(`Terminal operations are not supported by ${this.providerName}'s sandbox environment. ${this.providerName} sandboxes are designed for code execution only.`);
725
- }
726
- async destroy(_terminalId) {
727
- throw new Error(`Terminal operations are not supported by ${this.providerName}'s sandbox environment. ${this.providerName} sandboxes are designed for code execution only.`);
728
- }
729
- };
730
420
  var SupportedFileSystem = class {
731
- constructor(sandbox, methods) {
421
+ constructor(sandbox, methods, allMethods) {
732
422
  this.sandbox = sandbox;
733
423
  this.methods = methods;
424
+ this.allMethods = allMethods;
734
425
  }
735
426
  async readFile(path) {
736
- return this.methods.readFile(this.sandbox, path);
427
+ return this.methods.readFile(this.sandbox, path, this.allMethods.runCommand);
737
428
  }
738
429
  async writeFile(path, content) {
739
- return this.methods.writeFile(this.sandbox, path, content);
430
+ return this.methods.writeFile(this.sandbox, path, content, this.allMethods.runCommand);
740
431
  }
741
432
  async mkdir(path) {
742
- return this.methods.mkdir(this.sandbox, path);
433
+ return this.methods.mkdir(this.sandbox, path, this.allMethods.runCommand);
743
434
  }
744
435
  async readdir(path) {
745
- return this.methods.readdir(this.sandbox, path);
436
+ return this.methods.readdir(this.sandbox, path, this.allMethods.runCommand);
746
437
  }
747
438
  async exists(path) {
748
- return this.methods.exists(this.sandbox, path);
439
+ return this.methods.exists(this.sandbox, path, this.allMethods.runCommand);
749
440
  }
750
441
  async remove(path) {
751
- return this.methods.remove(this.sandbox, path);
752
- }
753
- };
754
- var GeneratedTerminalSession = class {
755
- constructor(terminal, sandbox, methods, terminalId, command, cols = 80, rows = 24) {
756
- this.terminal = terminal;
757
- this.sandbox = sandbox;
758
- this.methods = methods;
759
- this.pid = parseInt(terminalId);
760
- this.command = command;
761
- this.status = "running";
762
- this.cols = cols;
763
- this.rows = rows;
764
- }
765
- async write(data) {
766
- return this.methods.write(this.sandbox, this.terminal, data);
767
- }
768
- async resize(cols, rows) {
769
- return this.methods.resize(this.sandbox, this.terminal, cols, rows);
770
- }
771
- async kill() {
772
- return this.methods.kill(this.sandbox, this.terminal);
773
- }
774
- };
775
- var SupportedTerminal = class {
776
- constructor(sandbox, methods) {
777
- this.sandbox = sandbox;
778
- this.methods = methods;
779
- }
780
- async create(options) {
781
- let terminalSession;
782
- const createOptions = {
783
- ...options,
784
- onData: (data) => {
785
- if (terminalSession?.onData) {
786
- terminalSession.onData(data);
787
- }
788
- },
789
- onExit: (exitCode) => {
790
- if (terminalSession?.onExit) {
791
- terminalSession.onExit(exitCode);
792
- }
793
- }
794
- };
795
- const result = await this.methods.create(this.sandbox, createOptions);
796
- terminalSession = new GeneratedTerminalSession(
797
- result.terminal,
798
- this.sandbox,
799
- this.methods,
800
- result.terminalId,
801
- options?.command || "bash",
802
- options?.cols || 80,
803
- options?.rows || 24
804
- );
805
- terminalSession.onData = options?.onData;
806
- terminalSession.onExit = options?.onExit;
807
- return terminalSession;
808
- }
809
- async getById(terminalId) {
810
- const result = await this.methods.getById(this.sandbox, terminalId);
811
- if (!result) return null;
812
- return new GeneratedTerminalSession(
813
- result.terminal,
814
- this.sandbox,
815
- this.methods,
816
- result.terminalId,
817
- "bash",
818
- // Default command for existing terminals
819
- 80,
820
- // Default cols
821
- 24
822
- // Default rows
823
- );
824
- }
825
- async list() {
826
- const results = await this.methods.list(this.sandbox);
827
- return results.map((result) => new GeneratedTerminalSession(
828
- result.terminal,
829
- this.sandbox,
830
- this.methods,
831
- result.terminalId,
832
- "bash",
833
- // Default command
834
- 80,
835
- // Default cols
836
- 24
837
- // Default rows
838
- ));
839
- }
840
- async destroy(terminalId) {
841
- return this.methods.destroy(this.sandbox, terminalId);
442
+ return this.methods.remove(this.sandbox, path, this.allMethods.runCommand);
842
443
  }
843
444
  };
844
445
  var GeneratedSandbox = class {
845
- constructor(sandbox, sandboxId, providerName, methods, config, destroyMethod) {
446
+ constructor(sandbox, sandboxId, providerName, methods, config, destroyMethod, providerInstance) {
846
447
  this.sandbox = sandbox;
847
448
  this.methods = methods;
848
449
  this.config = config;
849
450
  this.destroyMethod = destroyMethod;
451
+ this.providerInstance = providerInstance;
850
452
  this.sandboxId = sandboxId;
851
453
  this.provider = providerName;
852
454
  if (methods.filesystem) {
853
- this.filesystem = new SupportedFileSystem(sandbox, methods.filesystem);
455
+ this.filesystem = new SupportedFileSystem(sandbox, methods.filesystem, methods);
854
456
  } else {
855
457
  this.filesystem = new UnsupportedFileSystem(providerName);
856
458
  }
857
- if (methods.terminal) {
858
- this.terminal = new SupportedTerminal(sandbox, methods.terminal);
859
- } else {
860
- this.terminal = new UnsupportedTerminal(providerName);
459
+ }
460
+ getInstance() {
461
+ if (this.methods.getInstance) {
462
+ return this.methods.getInstance(this.sandbox);
861
463
  }
464
+ return this.sandbox;
862
465
  }
863
466
  async runCode(code, runtime) {
864
467
  return await this.methods.runCode(this.sandbox, code, runtime, this.config);
@@ -869,6 +472,12 @@ var GeneratedSandbox = class {
869
472
  async getInfo() {
870
473
  return await this.methods.getInfo(this.sandbox);
871
474
  }
475
+ async getUrl(options) {
476
+ return await this.methods.getUrl(this.sandbox, options);
477
+ }
478
+ getProvider() {
479
+ return this.providerInstance;
480
+ }
872
481
  async kill() {
873
482
  await this.destroy();
874
483
  }
@@ -877,10 +486,11 @@ var GeneratedSandbox = class {
877
486
  }
878
487
  };
879
488
  var GeneratedSandboxManager = class {
880
- constructor(config, providerName, methods) {
489
+ constructor(config, providerName, methods, providerInstance) {
881
490
  this.config = config;
882
491
  this.providerName = providerName;
883
492
  this.methods = methods;
493
+ this.providerInstance = providerInstance;
884
494
  this.activeSandboxes = /* @__PURE__ */ new Map();
885
495
  }
886
496
  async create(options) {
@@ -891,7 +501,8 @@ var GeneratedSandboxManager = class {
891
501
  this.providerName,
892
502
  this.methods,
893
503
  this.config,
894
- this.methods.destroy
504
+ this.methods.destroy,
505
+ this.providerInstance
895
506
  );
896
507
  this.activeSandboxes.set(result.sandboxId, sandbox);
897
508
  return sandbox;
@@ -911,7 +522,8 @@ var GeneratedSandboxManager = class {
911
522
  this.providerName,
912
523
  this.methods,
913
524
  this.config,
914
- this.methods.destroy
525
+ this.methods.destroy,
526
+ this.providerInstance
915
527
  );
916
528
  this.activeSandboxes.set(result.sandboxId, sandbox);
917
529
  return sandbox;
@@ -928,7 +540,8 @@ var GeneratedSandboxManager = class {
928
540
  this.providerName,
929
541
  this.methods,
930
542
  this.config,
931
- this.methods.destroy
543
+ this.methods.destroy,
544
+ this.providerInstance
932
545
  );
933
546
  this.activeSandboxes.set(result.sandboxId, sandbox);
934
547
  }
@@ -947,19 +560,24 @@ var GeneratedProvider = class {
947
560
  this.sandbox = new GeneratedSandboxManager(
948
561
  config,
949
562
  providerConfig.name,
950
- providerConfig.methods.sandbox
563
+ providerConfig.methods.sandbox,
564
+ this
951
565
  );
952
566
  }
953
567
  };
954
568
  function createProvider(providerConfig) {
569
+ if (!providerConfig.methods.sandbox.filesystem) {
570
+ providerConfig.methods.sandbox.filesystem = defaultFilesystemMethods;
571
+ }
955
572
  return (config) => {
956
573
  return new GeneratedProvider(config, providerConfig);
957
574
  };
958
575
  }
959
576
  export {
960
- SandboxManager,
577
+ CommandExitError,
961
578
  compute,
962
579
  createProvider,
963
- handleComputeRequest
580
+ handleComputeRequest,
581
+ isCommandExitError
964
582
  };
965
583
  //# sourceMappingURL=index.mjs.map