withruntime 0.9.0 → 0.11.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 (124) hide show
  1. package/BLAXEL.md +4 -4
  2. package/DAYTONA.md +52 -40
  3. package/E2B.md +65 -62
  4. package/README.md +15 -7
  5. package/README.src.md +15 -7
  6. package/VERCEL.md +34 -22
  7. package/compatibility-lock.json +16 -16
  8. package/dist/blaxel/errors.js +1 -1
  9. package/dist/blaxel/lookup.d.ts +3 -2
  10. package/dist/blaxel/lookup.js +3 -2
  11. package/dist/blaxel/pagination.d.ts +2 -2
  12. package/dist/blaxel/pagination.js +45 -17
  13. package/dist/blaxel/preview.d.ts +2 -1
  14. package/dist/blaxel/preview.js +15 -13
  15. package/dist/blaxel/process.js +56 -10
  16. package/dist/blaxel/sandbox.d.ts +2 -0
  17. package/dist/blaxel/sandbox.js +2 -0
  18. package/dist/blaxel/snapshot.js +3 -5
  19. package/dist/cli.d.ts +2 -0
  20. package/dist/cli.js +262 -56
  21. package/dist/client.d.ts +41 -3
  22. package/dist/client.js +67 -11
  23. package/dist/cloudflare/identity.d.ts +7 -0
  24. package/dist/cloudflare/identity.js +13 -0
  25. package/dist/cloudflare/index.d.ts +9 -0
  26. package/dist/cloudflare/index.js +47 -9
  27. package/dist/cloudflare/worker.d.ts +4 -0
  28. package/dist/cloudflare/worker.js +166 -16
  29. package/dist/codesandbox/guest-service.js +57 -20
  30. package/dist/codesandbox/index.js +42 -8
  31. package/dist/compat/core.d.ts +9 -8
  32. package/dist/compat/core.js +60 -21
  33. package/dist/compat/files.js +22 -4
  34. package/dist/compat/lease.d.ts +36 -0
  35. package/dist/compat/lease.js +87 -0
  36. package/dist/credentials.d.ts +6 -1
  37. package/dist/credentials.js +107 -38
  38. package/dist/daytona/computer-use.d.ts +162 -0
  39. package/dist/daytona/computer-use.js +324 -0
  40. package/dist/daytona/context.d.ts +10 -0
  41. package/dist/daytona/context.js +24 -0
  42. package/dist/daytona/daytona.d.ts +20 -0
  43. package/dist/daytona/daytona.js +134 -20
  44. package/dist/daytona/filesystem.d.ts +17 -4
  45. package/dist/daytona/filesystem.js +129 -38
  46. package/dist/daytona/index.d.ts +3 -27
  47. package/dist/daytona/index.js +2 -7
  48. package/dist/daytona/process.d.ts +63 -6
  49. package/dist/daytona/process.js +224 -23
  50. package/dist/daytona/sandbox.d.ts +20 -6
  51. package/dist/daytona/sandbox.js +55 -32
  52. package/dist/e2b/client.d.ts +5 -0
  53. package/dist/e2b/client.js +6 -2
  54. package/dist/e2b/commands.d.ts +43 -12
  55. package/dist/e2b/commands.js +217 -64
  56. package/dist/e2b/errors.d.ts +7 -0
  57. package/dist/e2b/errors.js +20 -0
  58. package/dist/e2b/filesystem.d.ts +2 -1
  59. package/dist/e2b/filesystem.js +43 -6
  60. package/dist/e2b/index.d.ts +3 -2
  61. package/dist/e2b/index.js +2 -1
  62. package/dist/e2b/pty.d.ts +24 -0
  63. package/dist/e2b/pty.js +83 -0
  64. package/dist/e2b/sandbox.d.ts +17 -6
  65. package/dist/e2b/sandbox.js +239 -43
  66. package/dist/e2b/users.d.ts +30 -0
  67. package/dist/e2b/users.js +185 -0
  68. package/dist/file-source.d.ts +16 -0
  69. package/dist/file-source.js +162 -0
  70. package/dist/freestyle/index.d.ts +9 -1
  71. package/dist/freestyle/index.js +38 -5
  72. package/dist/index.d.ts +3 -1
  73. package/dist/login.js +16 -10
  74. package/dist/mcp.d.ts +2 -1
  75. package/dist/mcp.js +6 -1
  76. package/dist/modal/index.js +2 -1
  77. package/dist/network-cli.js +139 -43
  78. package/dist/openai-agents/index.js +9 -45
  79. package/dist/page.d.ts +1 -1
  80. package/dist/page.js +2 -2
  81. package/dist/products/browser.d.ts +60 -0
  82. package/dist/products/browser.js +37 -0
  83. package/dist/products/desktop.d.ts +2 -2
  84. package/dist/products/desktop.js +2 -2
  85. package/dist/products/images.d.ts +3 -1
  86. package/dist/products/images.js +14 -2
  87. package/dist/products/index.d.ts +14 -0
  88. package/dist/products/index.js +12 -0
  89. package/dist/products/network-products.d.ts +7 -0
  90. package/dist/products/network-products.js +3 -0
  91. package/dist/products/observability.d.ts +44 -0
  92. package/dist/products/observability.js +6 -0
  93. package/dist/products/previews.d.ts +8 -2
  94. package/dist/products/previews.js +11 -3
  95. package/dist/products/private-network.d.ts +22 -0
  96. package/dist/products/private-network.js +10 -0
  97. package/dist/products/volumes.d.ts +42 -0
  98. package/dist/products/volumes.js +36 -0
  99. package/dist/products/watch.js +61 -8
  100. package/dist/proxy.js +3 -1
  101. package/dist/runloop/index.d.ts +13 -27
  102. package/dist/runloop/index.js +149 -52
  103. package/dist/sandbox.d.ts +59 -8
  104. package/dist/sandbox.js +479 -68
  105. package/dist/snapshots.d.ts +9 -4
  106. package/dist/sprites/index.js +69 -33
  107. package/dist/tar.d.ts +3 -1
  108. package/dist/tar.js +140 -14
  109. package/dist/transport.d.ts +4 -7
  110. package/dist/transport.js +205 -122
  111. package/dist/types.d.ts +5 -2
  112. package/dist/vercel/command.d.ts +1 -1
  113. package/dist/vercel/command.js +3 -2
  114. package/dist/vercel/errors.d.ts +1 -1
  115. package/dist/vercel/errors.js +7 -1
  116. package/dist/vercel/index.d.ts +1 -7
  117. package/dist/vercel/index.js +1 -3
  118. package/dist/vercel/sandbox-user.d.ts +70 -0
  119. package/dist/vercel/sandbox-user.js +206 -0
  120. package/dist/vercel/sandbox.d.ts +55 -20
  121. package/dist/vercel/sandbox.js +353 -99
  122. package/dist/vercel/snapshot.d.ts +3 -2
  123. package/dist/vercel/snapshot.js +9 -5
  124. package/package.json +2 -1
@@ -93,10 +93,16 @@ export class Devboxes {
93
93
  executions;
94
94
  diskSnapshots;
95
95
  transitions = new Map();
96
- transition(id, operation) {
96
+ transition(id, operation, signal) {
97
+ // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors -- rejects with the caller's abort reason as is, as the upstream SDK does
98
+ if (signal?.aborted)
99
+ return Promise.reject(signal.reason);
97
100
  const pending = (this.transitions.get(id) ?? Promise.resolve())
98
101
  .catch(() => undefined)
99
- .then(operation);
102
+ .then(() => {
103
+ signal?.throwIfAborted();
104
+ return operation();
105
+ });
100
106
  this.transitions.set(id, pending);
101
107
  void pending
102
108
  .finally(() => {
@@ -104,7 +110,23 @@ export class Devboxes {
104
110
  this.transitions.delete(id);
105
111
  })
106
112
  .catch(() => undefined);
107
- return pending;
113
+ if (!signal)
114
+ return pending;
115
+ return new Promise((resolve, reject) => {
116
+ // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors -- rejects with the caller's abort reason as is, as the upstream SDK does
117
+ const abort = () => reject(signal.reason);
118
+ signal.addEventListener("abort", abort, { once: true });
119
+ pending.then((value) => {
120
+ signal.removeEventListener("abort", abort);
121
+ resolve(value);
122
+ }, (error) => {
123
+ signal.removeEventListener("abort", abort);
124
+ // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors -- passes the pending call's own failure through unchanged
125
+ reject(error);
126
+ });
127
+ if (signal.aborted)
128
+ abort();
129
+ });
108
130
  }
109
131
  constructor(runtime) {
110
132
  this.runtime = runtime;
@@ -112,6 +134,7 @@ export class Devboxes {
112
134
  this.diskSnapshots = new DiskSnapshots(runtime);
113
135
  }
114
136
  async create(input = {}, options = {}) {
137
+ options.signal?.throwIfAborted();
115
138
  only("Runloop", input, [
116
139
  "name",
117
140
  "metadata",
@@ -153,22 +176,27 @@ export class Devboxes {
153
176
  idlePauseSeconds: 0,
154
177
  onLeaseEnd: "stop",
155
178
  }, input.environment_variables ?? undefined, async (sandbox) => {
156
- for (const [path, content] of Object.entries(input.file_mounts ?? {}))
157
- await sandbox.files.write(path, content);
179
+ for (const [path, content] of Object.entries(input.file_mounts ?? {})) {
180
+ options.signal?.throwIfAborted();
181
+ await sandbox.files.write(path, content, {
182
+ signal: options.signal,
183
+ timeoutMs: options.timeout,
184
+ });
185
+ }
158
186
  for (const command of p.launch_commands ?? [])
159
187
  await sandbox.exec(command, {
160
- ...(await execOptions(sandbox)),
188
+ ...(await execOptions(sandbox, { signal: options.signal }, nativeOptions(options))),
161
189
  check: true,
162
190
  signal: options.signal,
163
191
  });
164
- });
192
+ }, nativeOptions(options));
165
193
  return view(sandbox);
166
194
  }
167
195
  createAndAwaitRunning(input, options) {
168
196
  return this.create(input, options);
169
197
  }
170
- async retrieve(id) {
171
- return view(await lookup(this.runtime, id));
198
+ async retrieve(id, options = {}) {
199
+ return view(await lookup(this.runtime, id, nativeOptions(options)));
172
200
  }
173
201
  async awaitRunning(id, options = {}) {
174
202
  return this.waitForStatus(id, "running", options);
@@ -237,7 +265,13 @@ export class Devboxes {
237
265
  throw new TypeError("limit must be positive");
238
266
  const values = [];
239
267
  let cursor = null;
268
+ const seenCursors = new Set();
240
269
  do {
270
+ if (cursor !== null) {
271
+ if (seenCursors.has(cursor))
272
+ throw new Error("Pagination returned a repeated cursor");
273
+ seenCursors.add(cursor);
274
+ }
241
275
  const page = await this.runtime.transport.json({
242
276
  method: "GET",
243
277
  path: "/v1/sandboxes",
@@ -268,9 +302,14 @@ export class Devboxes {
268
302
  const data = values.slice(offset, offset + (query.limit ?? 20));
269
303
  return new DevboxViewsCursorIDPage(data, offset + data.length < values.length, query.include_total_count === false ? 0 : values.length, (after) => this.listPage({ ...query, starting_after: after }, options));
270
304
  }
271
- suspend(id) {
305
+ suspend(id, options = {}) {
306
+ // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors -- rejects with the caller's abort reason as is, as the upstream SDK does
307
+ if (options.signal?.aborted)
308
+ return Promise.reject(options.signal.reason);
309
+ if (options.idempotencyKey !== undefined)
310
+ return Promise.reject(new CompatibilityError("Runloop", "caller idempotency keys for compound suspend"));
272
311
  return this.transition(id, async () => {
273
- const s = await lookup(this.runtime, id);
312
+ const s = await lookup(this.runtime, id, nativeOptions(options));
274
313
  if (s.state === "stopped") {
275
314
  if (s.info.persistent && s.info.labels[SUSPENDED] === "true")
276
315
  return view(s);
@@ -278,41 +317,56 @@ export class Devboxes {
278
317
  }
279
318
  // ARCHITECTURE.md section 10: paid disk persistence must be admitted
280
319
  // before stop; an uncertain stop keeps retention enabled to preserve bytes.
281
- await s.update({ persistent: true, labels: { ...s.info.labels, [SUSPENDED]: "true" } });
282
- await s.stop();
320
+ await s.update({ persistent: true, labels: { ...s.info.labels, [SUSPENDED]: "true" } }, nativeOptions(options));
321
+ await s.stop(nativeOptions(options));
283
322
  return view(s);
284
- });
323
+ }, options.signal);
285
324
  }
286
- resume(id) {
325
+ resume(id, options = {}) {
326
+ // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors -- rejects with the caller's abort reason as is, as the upstream SDK does
327
+ if (options.signal?.aborted)
328
+ return Promise.reject(options.signal.reason);
329
+ if (options.idempotencyKey !== undefined)
330
+ return Promise.reject(new CompatibilityError("Runloop", "caller idempotency keys for compound resume"));
287
331
  return this.transition(id, async () => {
288
- const s = await lookup(this.runtime, id);
332
+ const s = await lookup(this.runtime, id, nativeOptions(options));
289
333
  if (s.state === "stopped") {
290
334
  if (!s.info.persistent || s.info.labels[SUSPENDED] !== "true")
291
335
  throw new Error("A shut down Devbox cannot be resumed");
292
- await s.restart();
336
+ await s.restart(nativeOptions(options));
293
337
  }
294
338
  else if (s.state === "paused" || s.state === "pausing") {
295
339
  // Migrate older adapter pauses through the same disk-only boundary.
296
- await s.update({ persistent: true, labels: { ...s.info.labels, [SUSPENDED]: "true" } });
297
- await s.stop();
298
- await s.restart();
340
+ await s.update({ persistent: true, labels: { ...s.info.labels, [SUSPENDED]: "true" } }, nativeOptions(options));
341
+ await s.stop(nativeOptions(options));
342
+ await s.restart(nativeOptions(options));
299
343
  }
300
344
  else
301
- await s.waitFor("running");
345
+ await s.waitFor("running", nativeOptions(options));
302
346
  if (s.info.labels[SUSPENDED] !== undefined) {
303
347
  const labels = { ...s.info.labels };
304
348
  delete labels[SUSPENDED];
305
- await s.update({ labels });
349
+ await s.update({ labels }, nativeOptions(options));
306
350
  }
307
351
  return view(s);
308
- });
352
+ }, options.signal);
309
353
  }
310
- shutdown(id) {
354
+ shutdown(id, params = {}, options = {}) {
355
+ if (requestOptions(params))
356
+ return this.shutdown(id, {}, params);
357
+ // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors -- rejects with the caller's abort reason as is, as the upstream SDK does
358
+ if (options.signal?.aborted)
359
+ return Promise.reject(options.signal.reason);
360
+ if (options.idempotencyKey !== undefined)
361
+ return Promise.reject(new CompatibilityError("Runloop", "caller idempotency keys for compound shutdown"));
362
+ only("Runloop shutdown", params, ["force"]);
363
+ if (params.force !== undefined && params.force !== "false")
364
+ return Promise.reject(new CompatibilityError("Runloop", "forced shutdown during snapshots"));
311
365
  return this.transition(id, async () => {
312
- const s = await lookup(this.runtime, id);
313
- await destroy(s);
366
+ const s = await lookup(this.runtime, id, nativeOptions(options));
367
+ await destroy(s, nativeOptions(options));
314
368
  return view(s);
315
- });
369
+ }, options.signal);
316
370
  }
317
371
  executeSync(id, body, options) {
318
372
  return this.executions.executeSync(id, body, options);
@@ -324,13 +378,15 @@ export class Devboxes {
324
378
  const execution = await this.executeAsync(id, body, options);
325
379
  return this.executions.awaitCompleted(id, execution.execution_id, options);
326
380
  }
327
- async readFileContents(id, body) {
381
+ async readFileContents(id, body, options = {}) {
382
+ options.signal?.throwIfAborted();
328
383
  only("Runloop read", body, ["file_path"]);
329
- return (await lookup(this.runtime, id)).files.readText(body.file_path);
384
+ return (await lookup(this.runtime, id, nativeOptions(options))).files.readText(body.file_path, nativeOptions(options));
330
385
  }
331
- async writeFileContents(id, body) {
386
+ async writeFileContents(id, body, options = {}) {
387
+ options.signal?.throwIfAborted();
332
388
  only("Runloop write", body, ["file_path", "contents"]);
333
- await (await lookup(this.runtime, id)).files.write(body.file_path, body.contents);
389
+ await (await lookup(this.runtime, id, nativeOptions(options))).files.write(body.file_path, body.contents, nativeOptions(options));
334
390
  return result(id, { stdout: "", stderr: "", exitCode: 0, timedOut: false });
335
391
  }
336
392
  async snapshotDisk(id, body = {}, options = {}) {
@@ -364,52 +420,92 @@ export class Executions {
364
420
  only("Runloop execute", body, ["command", "shell_name", "attach_stdin"]);
365
421
  if (body.attach_stdin)
366
422
  throw new TypeError("attach_stdin requires executeAsync");
367
- const s = await lookup(this.runtime, id);
368
- return result(id, await s.exec(await shellCommand(s, body.command, body.shell_name), await execOptions(s, {
423
+ options.signal?.throwIfAborted();
424
+ const s = await lookup(this.runtime, id, nativeOptions(options));
425
+ return result(id, await s.exec(await shellCommand(s, body.command, body.shell_name, {}, nativeOptions(options)), await execOptions(s, {
369
426
  signal: options.signal,
370
427
  timeoutMs: options.timeout,
371
428
  idempotencyKey: options.idempotencyKey,
372
429
  onStdout: () => { },
373
- })));
430
+ }, nativeOptions(options))));
374
431
  }
375
432
  async executeAsync(id, body, options = {}) {
376
433
  only("Runloop execute", body, ["command", "shell_name", "attach_stdin"]);
377
434
  if (body.shell_name && body.attach_stdin)
378
435
  throw new CompatibilityError("Runloop", "interactive stdin in a named shell");
379
- const s = await lookup(this.runtime, id);
380
- const p = await s.spawn(await shellCommand(s, body.command, body.shell_name), {
381
- ...(await execOptions(s, { signal: options.signal, idempotencyKey: options.idempotencyKey })),
436
+ options.signal?.throwIfAborted();
437
+ const s = await lookup(this.runtime, id, nativeOptions(options));
438
+ const p = await s.spawn(await shellCommand(s, body.command, body.shell_name, {}, nativeOptions(options)), {
439
+ ...(await execOptions(s, {
440
+ signal: options.signal,
441
+ idempotencyKey: options.idempotencyKey,
442
+ }, nativeOptions(options))),
382
443
  stdin: body.attach_stdin ? "pipe" : undefined,
444
+ request: nativeOptions(options),
383
445
  });
384
446
  return { devbox_id: id, execution_id: p.id, status: "running" };
385
447
  }
386
- async retrieve(id, execution) {
387
- const p = await (await lookup(this.runtime, id)).processes.get(execution);
448
+ async retrieve(id, execution, query = {}, options = {}) {
449
+ if (requestOptions(query))
450
+ return this.retrieve(id, execution, {}, query);
451
+ options.signal?.throwIfAborted();
452
+ only("Runloop execution retrieve", query, ["last_n"]);
453
+ if (query.last_n !== undefined)
454
+ throw new CompatibilityError("Runloop", "execution output tail selection (last_n)");
455
+ const p = await (await lookup(this.runtime, id, nativeOptions(options))).processes.get(execution, nativeOptions(options));
388
456
  return p.info.state === "running"
389
457
  ? { devbox_id: id, execution_id: execution, status: "running" }
390
- : { ...result(id, await p.wait()), execution_id: execution, status: "completed" };
458
+ : {
459
+ ...result(id, await p.wait({ signal: options.signal })),
460
+ execution_id: execution,
461
+ status: "completed",
462
+ };
391
463
  }
392
464
  async awaitCompleted(id, execution, options = {}) {
393
- const p = await (await lookup(this.runtime, id)).processes.get(execution);
465
+ options.signal?.throwIfAborted();
466
+ const p = await (await lookup(this.runtime, id, nativeOptions(options))).processes.get(execution, nativeOptions(options));
394
467
  return {
395
468
  ...result(id, await p.wait({ signal: options.signal })),
396
469
  execution_id: execution,
397
470
  status: "completed",
398
471
  };
399
472
  }
400
- async kill(id, execution, body = {}) {
473
+ async kill(id, execution, body = {}, options = {}) {
474
+ if (requestOptions(body))
475
+ return this.kill(id, execution, {}, body);
476
+ options.signal?.throwIfAborted();
401
477
  only("Runloop kill", body, ["kill_process_group"]);
402
478
  if (body.kill_process_group)
403
479
  throw new CompatibilityError("Runloop", "kill_process_group");
404
- await (await (await lookup(this.runtime, id)).processes.get(execution)).kill("SIGKILL");
405
- return this.retrieve(id, execution);
406
- }
407
- async sendStdIn(id, execution, body = {}) {
408
- const p = await (await lookup(this.runtime, id)).processes.get(execution);
409
- if (body.text || body.signal === "EOF")
410
- await p.write(body.text ?? "", { eof: body.signal === "EOF" });
411
- if (body.signal === "INTERRUPT")
412
- await p.kill("SIGINT");
480
+ await (await (await lookup(this.runtime, id, nativeOptions(options))).processes.get(execution, nativeOptions(options))).kill("SIGKILL", nativeOptions(options));
481
+ return this.retrieve(id, execution, {}, options);
482
+ }
483
+ async sendStdIn(id, execution, body = {}, options = {}) {
484
+ if (requestOptions(body) &&
485
+ (body.signal === undefined || (typeof body.signal === "object" && body.signal !== null)))
486
+ return this.sendStdIn(id, execution, {}, body);
487
+ options.signal?.throwIfAborted();
488
+ only("Runloop stdin", body, ["text", "signal"]);
489
+ const text = "text" in body ? body.text : undefined;
490
+ const bodySignal = body.signal;
491
+ if (text !== undefined && text !== null && typeof text !== "string")
492
+ throw new TypeError("Runloop stdin text must be a string");
493
+ if (bodySignal !== undefined &&
494
+ bodySignal !== null &&
495
+ bodySignal !== "EOF" &&
496
+ bodySignal !== "INTERRUPT")
497
+ throw new TypeError("Runloop stdin signal must be EOF or INTERRUPT");
498
+ if (options.idempotencyKey !== undefined && (text || bodySignal === "EOF"))
499
+ throw new CompatibilityError("Runloop", "caller idempotency keys for process input; native offsets protect transport retries");
500
+ const p = await (await lookup(this.runtime, id, nativeOptions(options))).processes.get(execution, nativeOptions(options));
501
+ if (text || bodySignal === "EOF")
502
+ await p.write(text ?? "", {
503
+ eof: bodySignal === "EOF",
504
+ signal: options.signal,
505
+ timeoutMs: options.timeout,
506
+ });
507
+ if (bodySignal === "INTERRUPT")
508
+ await p.kill("SIGINT", nativeOptions(options));
413
509
  return { devbox_id: id, execution_id: execution, success: true };
414
510
  }
415
511
  async *streamStdoutUpdates(id, execution, query = {}, options = {}) {
@@ -419,7 +515,8 @@ export class Executions {
419
515
  yield* this.stream(id, execution, "stderr", query, options);
420
516
  }
421
517
  async *stream(id, execution, channel, query, options) {
422
- const p = await (await lookup(this.runtime, id)).processes.get(execution);
518
+ options.signal?.throwIfAborted();
519
+ const p = await (await lookup(this.runtime, id, nativeOptions(options))).processes.get(execution, nativeOptions(options));
423
520
  let offset = 0;
424
521
  const from = Number(query.offset ?? 0);
425
522
  for await (const event of p.output({ signal: options.signal }))
package/dist/sandbox.d.ts CHANGED
@@ -5,6 +5,7 @@ import type { CommandResult, DeletedSandbox, ExecOptions, FileEntry, OutputEvent
5
5
  import { type SandboxExtensions } from "./products/index.js";
6
6
  import type { Snapshot, SnapshotOptions } from "./snapshots.js";
7
7
  import { Tunnel, type PortForward } from "./tunnel.js";
8
+ import type { StreamUploadSource } from "./file-source.js";
8
9
  /** DELETE /v1/sandboxes/{id}, for `sandbox.delete()` and
9
10
  * `runtime.sandboxes.delete(id)`. */
10
11
  export declare function deleteSandbox(t: Transport, id: string, options?: RequestOptions): Promise<DeletedSandbox>;
@@ -67,6 +68,8 @@ export declare class Sandbox implements AsyncDisposable {
67
68
  rows?: number;
68
69
  };
69
70
  outputEncoding?: "utf8" | "base64";
71
+ /** HTTP request options, independently of the process execution deadline. */
72
+ request?: RequestOptions;
70
73
  }): Promise<Process>;
71
74
  /** An interactive terminal over a WebSocket. Bytes you write are typed;
72
75
  * onData receives what the terminal prints. */
@@ -124,6 +127,21 @@ export declare class Sandbox implements AsyncDisposable {
124
127
  switchImage(image: string, options: RequestOptions & {
125
128
  keep: "workspace";
126
129
  }): Promise<this>;
130
+ /** Gives it more or fewer vCPUs or more or less memory by a restart: its id,
131
+ * whole disk, volumes, environment, name and previews stay, and its
132
+ * programs stop, which `restart: true` says you know (snapshot it first to
133
+ * keep its memory too). A running sandbox is paused, or stopped if it is
134
+ * persistent, and comes back running at the new size on the same server; a
135
+ * paused or stopped one is started. Memory bills on the new size from then.
136
+ * Refused, with nothing changed, when the server has no room
137
+ * (`no_capacity`), above your quota or the trial's 2 vCPU and 4 GiB, or
138
+ * while a snapshot or fork of it is being taken. */
139
+ resize(size: {
140
+ vcpu?: number;
141
+ memoryMiB?: number;
142
+ }, options: RequestOptions & {
143
+ restart: true;
144
+ }): Promise<this>;
127
145
  /** Keeps a running sandbox's lease ahead of now, in the background, until
128
146
  * stop() or the returned function ends it: every `everySeconds` (60) it
129
147
  * extends the lease so that `marginSeconds` (600) remain, never more than
@@ -210,8 +228,8 @@ export declare class Processes {
210
228
  private readonly t;
211
229
  private readonly sandboxId;
212
230
  constructor(t: Transport, sandboxId: string);
213
- list(): Promise<ProcessInfo[]>;
214
- get(processId: string): Promise<Process>;
231
+ list(options?: RequestOptions): Promise<ProcessInfo[]>;
232
+ get(processId: string, options?: RequestOptions): Promise<Process>;
215
233
  /** Output events from `cursor` until the process exits, across stream slices. */
216
234
  follow(processId: string, options?: {
217
235
  cursor?: number;
@@ -226,6 +244,13 @@ export declare class Process {
226
244
  info: ProcessInfo;
227
245
  constructor(t: Transport, sandboxId: string, info: ProcessInfo);
228
246
  get id(): string;
247
+ /** The command line as the sandbox reports it. */
248
+ get command(): string;
249
+ /** As of the last answer: spawn, `wait()` or `refresh()`. */
250
+ get state(): ProcessInfo["state"];
251
+ /** null while it runs, and when it was killed or timed out. */
252
+ get exitCode(): number | null;
253
+ toJSON(): ProcessInfo;
229
254
  /** Every output event from the start (or `cursor`) until exit. */
230
255
  output(options?: {
231
256
  cursor?: number;
@@ -241,12 +266,13 @@ export declare class Process {
241
266
  wait(options?: {
242
267
  signal?: AbortSignal;
243
268
  }): Promise<CommandResult>;
244
- /** Sends input. Offsets are tracked for you, so a retried write is never typed twice. */
269
+ /** Sends input. Offsets protect transport retries; signal and timeoutMs cover
270
+ * the whole logical write, including its queue and backpressure. */
245
271
  write(data: string | Uint8Array, options?: {
246
272
  eof?: boolean;
247
- }): Promise<void>;
248
- kill(signal?: "SIGTERM" | "SIGKILL" | "SIGINT" | "SIGHUP" | "SIGQUIT" | "SIGUSR1" | "SIGUSR2"): Promise<void>;
249
- resize(cols: number, rows: number): Promise<void>;
273
+ } & Pick<RequestOptions, "signal" | "timeoutMs">): Promise<void>;
274
+ kill(signal?: "SIGTERM" | "SIGKILL" | "SIGINT" | "SIGHUP" | "SIGQUIT" | "SIGUSR1" | "SIGUSR2", options?: RequestOptions): Promise<void>;
275
+ resize(cols: number, rows: number, options?: RequestOptions): Promise<void>;
250
276
  refresh(): Promise<ProcessInfo>;
251
277
  }
252
278
  export declare class Terminal {
@@ -319,6 +345,18 @@ export declare class Files {
319
345
  path: string;
320
346
  size: number;
321
347
  }>;
348
+ /** Uploads byte streams with bounded memory on Node/Bun. Unknown-length
349
+ * inputs stage once in a private local temporary file; known local files
350
+ * and Blobs avoid that extra disk copy. Paths are local file paths. */
351
+ writeStream(path: string, input: StreamUploadSource | Uint8Array, writeOptions?: RequestOptions & {
352
+ mode?: number;
353
+ onProgress?: (progress: {
354
+ bytesSent: number;
355
+ }) => void;
356
+ }): Promise<{
357
+ path: string;
358
+ size: number;
359
+ }>;
322
360
  /** Directory entries; `depth` goes deeper, `glob` filters (e.g. "**\/*.py"). */
323
361
  list(path?: string, options?: {
324
362
  depth?: number;
@@ -343,6 +381,19 @@ export declare class Files {
343
381
  rename(from: string, to: string, options?: {
344
382
  overwrite?: boolean;
345
383
  } & RequestOptions): Promise<void>;
384
+ /** Packs a directory as archive bytes; `gzip: false` returns plain tar.
385
+ * Exclusions are relative paths, not globs. `user: root` selects guest root. */
386
+ archive(path: string, options?: RequestOptions & {
387
+ gzip?: boolean;
388
+ exclude?: string[];
389
+ user?: "sandbox" | "root";
390
+ }): Promise<Uint8Array>;
391
+ /** Unpacks archive bytes in a directory with the sandbox user's rights by
392
+ * default; `user: root` explicitly selects root inside this guest. */
393
+ unarchive(path: string, bytes: Uint8Array, options?: RequestOptions & {
394
+ gzip?: boolean;
395
+ user?: "sandbox" | "root";
396
+ }): Promise<void>;
346
397
  /** Copies a local file or directory into the sandbox. A directory travels as
347
398
  * one gzipped tar to the API's folder routes, and the sandbox's own `tar`
348
399
  * unpacks it as it arrives, making the folder. */
@@ -350,9 +401,9 @@ export declare class Files {
350
401
  /** Copies a file or directory out of the sandbox. A file streams to disk,
351
402
  * any size, checked against its length; a directory comes as one tar from
352
403
  * the API's folder route. */
353
- download(remotePath: string, localPath: string): Promise<void>;
404
+ download(remotePath: string, localPath: string, options?: RequestOptions): Promise<void>;
354
405
  }
355
406
  export declare function sandboxPage(t: Transport, body: {
356
407
  data: SandboxInfo[];
357
408
  nextCursor: string | null;
358
- }, query: Record<string, unknown>): Page<Sandbox>;
409
+ }, query: Record<string, unknown>, options?: RequestOptions): Page<Sandbox>;