withruntime 0.11.1 → 0.12.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 (176) hide show
  1. package/BLAXEL.md +3 -3
  2. package/COMPATIBILITY.md +74 -9
  3. package/DAYTONA.md +33 -5
  4. package/E2B.md +137 -48
  5. package/README.md +11 -9
  6. package/README.src.md +11 -9
  7. package/VERCEL.md +43 -5
  8. package/compatibility-lock.json +58 -49
  9. package/dist/billing-cli.d.ts +1 -1
  10. package/dist/billing-cli.js +77 -1
  11. package/dist/blaxel/errors.d.ts +14 -0
  12. package/dist/blaxel/errors.js +33 -4
  13. package/dist/blaxel/index.d.ts +2 -2
  14. package/dist/blaxel/index.js +4 -4
  15. package/dist/blaxel/interpreter.d.ts +2 -5
  16. package/dist/blaxel/sandbox.d.ts +15 -7
  17. package/dist/blaxel/sandbox.js +64 -9
  18. package/dist/blaxel/snapshot.d.ts +4 -0
  19. package/dist/blaxel/snapshot.js +4 -0
  20. package/dist/cli/logs.d.ts +21 -0
  21. package/dist/cli/logs.js +188 -0
  22. package/dist/cli/logs.test.d.ts +1 -0
  23. package/dist/cli/logs.test.js +272 -0
  24. package/dist/cli-extras.d.ts +3 -3
  25. package/dist/cli-extras.js +17 -12
  26. package/dist/cli-words.d.ts +10 -1
  27. package/dist/cli-words.js +18 -0
  28. package/dist/cli.d.ts +6 -2
  29. package/dist/cli.js +468 -219
  30. package/dist/client.d.ts +13 -63
  31. package/dist/client.js +35 -124
  32. package/dist/cloudflare/errors.d.ts +143 -0
  33. package/dist/cloudflare/errors.js +167 -0
  34. package/dist/cloudflare/index.d.ts +175 -6
  35. package/dist/cloudflare/index.js +416 -26
  36. package/dist/cloudflare/interpreter.d.ts +119 -0
  37. package/dist/cloudflare/interpreter.js +223 -0
  38. package/dist/cloudflare/streams.d.ts +38 -0
  39. package/dist/cloudflare/streams.js +145 -0
  40. package/dist/cloudflare/watch.d.ts +9 -0
  41. package/dist/cloudflare/watch.js +24 -0
  42. package/dist/codesandbox/index.d.ts +216 -28
  43. package/dist/codesandbox/index.js +478 -78
  44. package/dist/compat/core.d.ts +18 -0
  45. package/dist/compat/core.js +29 -0
  46. package/dist/compat/files.d.ts +1 -0
  47. package/dist/compat/files.js +25 -5
  48. package/dist/daytona/computer-use.d.ts +13 -4
  49. package/dist/daytona/computer-use.js +66 -8
  50. package/dist/daytona/daytona.d.ts +7 -2
  51. package/dist/daytona/daytona.js +31 -5
  52. package/dist/daytona/errors.d.ts +11 -0
  53. package/dist/daytona/errors.js +18 -0
  54. package/dist/daytona/filesystem.js +2 -1
  55. package/dist/daytona/image.d.ts +13 -9
  56. package/dist/daytona/image.js +18 -12
  57. package/dist/daytona/index.d.ts +1 -1
  58. package/dist/daytona/sandbox.d.ts +9 -3
  59. package/dist/daytona/sandbox.js +17 -3
  60. package/dist/domains/index.d.ts +9 -0
  61. package/dist/domains/index.js +10 -0
  62. package/dist/e2b/client.d.ts +15 -2
  63. package/dist/e2b/client.js +61 -7
  64. package/dist/e2b/commands.d.ts +4 -1
  65. package/dist/e2b/commands.js +17 -7
  66. package/dist/e2b/errors.d.ts +43 -2
  67. package/dist/e2b/errors.js +78 -6
  68. package/dist/e2b/filesystem.d.ts +1 -1
  69. package/dist/e2b/filesystem.js +82 -16
  70. package/dist/e2b/index.d.ts +3 -3
  71. package/dist/e2b/index.js +2 -2
  72. package/dist/e2b/sandbox.d.ts +50 -35
  73. package/dist/e2b/sandbox.js +228 -185
  74. package/dist/e2b/unsupported.d.ts +19 -0
  75. package/dist/e2b/unsupported.js +22 -1
  76. package/dist/e2b/users.d.ts +9 -0
  77. package/dist/e2b/users.js +22 -0
  78. package/dist/errors.d.ts +14 -5
  79. package/dist/errors.js +28 -14
  80. package/dist/freestyle/index.d.ts +285 -37
  81. package/dist/freestyle/index.js +656 -144
  82. package/dist/identity.d.ts +3 -0
  83. package/dist/identity.js +27 -0
  84. package/dist/images/index.d.ts +9 -0
  85. package/dist/images/index.js +10 -0
  86. package/dist/index.d.ts +1 -0
  87. package/dist/ips/index.d.ts +9 -0
  88. package/dist/ips/index.js +10 -0
  89. package/dist/jobs/index.d.ts +9 -0
  90. package/dist/jobs/index.js +10 -0
  91. package/dist/keys.js +2 -0
  92. package/dist/login.js +2 -0
  93. package/dist/machine.d.ts +189 -0
  94. package/dist/machine.js +521 -0
  95. package/dist/mcp.js +1 -1
  96. package/dist/modal/index.d.ts +339 -61
  97. package/dist/modal/index.js +781 -121
  98. package/dist/network-cli.d.ts +3 -1
  99. package/dist/network-cli.js +78 -36
  100. package/dist/networks/index.d.ts +11 -0
  101. package/dist/networks/index.js +10 -0
  102. package/dist/openai-agents/index.d.ts +1 -1
  103. package/dist/openai-agents/index.js +1 -1
  104. package/dist/ports/index.d.ts +9 -0
  105. package/dist/ports/index.js +10 -0
  106. package/dist/product-names.d.ts +52 -0
  107. package/dist/product-names.js +164 -0
  108. package/dist/product-renames.d.ts +103 -0
  109. package/dist/product-renames.js +189 -0
  110. package/dist/products/apps.d.ts +176 -0
  111. package/dist/products/apps.js +165 -0
  112. package/dist/products/billing.d.ts +41 -0
  113. package/dist/products/billing.js +13 -0
  114. package/dist/products/browser.d.ts +10 -0
  115. package/dist/products/browsers.d.ts +71 -0
  116. package/dist/products/browsers.js +102 -0
  117. package/dist/products/builds.d.ts +126 -0
  118. package/dist/products/builds.js +221 -0
  119. package/dist/products/index.d.ts +3 -16
  120. package/dist/products/index.js +3 -14
  121. package/dist/products/jobs.d.ts +19 -3
  122. package/dist/products/jobs.js +28 -12
  123. package/dist/products/limits.d.ts +4 -10
  124. package/dist/products/logs.d.ts +245 -0
  125. package/dist/products/logs.js +274 -0
  126. package/dist/products/logs.test.d.ts +1 -0
  127. package/dist/products/logs.test.js +343 -0
  128. package/dist/products/network-products.d.ts +38 -7
  129. package/dist/products/network-products.js +31 -18
  130. package/dist/products/network.d.ts +1 -1
  131. package/dist/products/observability.d.ts +3 -2
  132. package/dist/products/private-network.js +1 -1
  133. package/dist/products/queues.d.ts +149 -0
  134. package/dist/products/queues.js +213 -0
  135. package/dist/products/referrals.d.ts +21 -7
  136. package/dist/products/referrals.js +3 -3
  137. package/dist/products/secrets.d.ts +8 -4
  138. package/dist/products/secrets.js +39 -18
  139. package/dist/products/signed-requests.d.ts +21 -0
  140. package/dist/products/signed-requests.js +11 -0
  141. package/dist/products/streams.d.ts +73 -0
  142. package/dist/products/streams.js +17 -0
  143. package/dist/products/switching.d.ts +37 -10
  144. package/dist/products/switching.js +4 -3
  145. package/dist/products/volumes.d.ts +3 -0
  146. package/dist/record-cli.d.ts +23 -0
  147. package/dist/record-cli.js +308 -0
  148. package/dist/renamed-products.d.ts +38 -0
  149. package/dist/renamed-products.js +34 -0
  150. package/dist/runloop/index.d.ts +9 -2
  151. package/dist/runloop/index.js +29 -8
  152. package/dist/runloop/sdk.d.ts +131 -0
  153. package/dist/runloop/sdk.js +167 -0
  154. package/dist/sandbox.d.ts +10 -94
  155. package/dist/sandbox.js +22 -371
  156. package/dist/sandboxes/index.d.ts +11 -0
  157. package/dist/sandboxes/index.js +12 -0
  158. package/dist/snapshots/index.d.ts +9 -0
  159. package/dist/snapshots/index.js +11 -0
  160. package/dist/snapshots.d.ts +7 -4
  161. package/dist/sprites/index.d.ts +343 -31
  162. package/dist/sprites/index.js +866 -84
  163. package/dist/ssh.d.ts +1 -1
  164. package/dist/ssh.js +11 -11
  165. package/dist/terminal.d.ts +24 -0
  166. package/dist/terminal.js +32 -0
  167. package/dist/transport.d.ts +18 -2
  168. package/dist/transport.js +61 -6
  169. package/dist/tunnel.js +1 -1
  170. package/dist/types.d.ts +116 -8
  171. package/dist/vercel/sandbox.d.ts +1 -2
  172. package/dist/vercel/sandbox.js +6 -5
  173. package/dist/vercel/snapshot.js +10 -2
  174. package/dist/volumes/index.d.ts +9 -0
  175. package/dist/volumes/index.js +10 -0
  176. package/package.json +48 -2
@@ -17,3 +17,22 @@ export declare const waitForFile: Unsupported;
17
17
  export declare const waitForTimeout: Unsupported;
18
18
  export declare const Volume: Unsupported;
19
19
  export declare const Secret: Unsupported;
20
+ export declare const SecretPaginator: Unsupported;
21
+ export declare const Git: Unsupported;
22
+ export declare const ReadyCmd: Unsupported;
23
+ export declare const LogEntry: Unsupported;
24
+ export declare const LogEntryStart: Unsupported;
25
+ export declare const LogEntryEnd: Unsupported;
26
+ export declare const defaultBuildLogger: Unsupported;
27
+ export declare const ConnectionConfig: Unsupported;
28
+ export declare const ApiClient: Unsupported;
29
+ export declare const getSignature: Unsupported;
30
+ /** E2B's "every address" network selector, as E2B defines it. */
31
+ export declare const ALL_TRAFFIC = "0.0.0.0/0";
32
+ /** E2B's volume entry types, as E2B defines them. */
33
+ export declare enum VolumeFileType {
34
+ UNKNOWN = "unknown",
35
+ FILE = "file",
36
+ DIRECTORY = "directory",
37
+ SYMLINK = "symlink"
38
+ }
@@ -15,7 +15,7 @@ export function unsupportedExport(name, alternative) {
15
15
  },
16
16
  });
17
17
  }
18
- const TEMPLATES = "Build a Runtime image instead: `npx withruntime image build --dockerfile e2b.Dockerfile --name <template>` or runtime.images.build({ name, dockerfile | recipe }), then Sandbox.create('<template>').";
18
+ const TEMPLATES = "Build a Runtime image instead: `npx withruntime images build --dockerfile e2b.Dockerfile --name <template>` or runtime.images.build({ name, dockerfile | recipe }), then Sandbox.create('<template>').";
19
19
  export const Template = unsupportedExport("Template builder", TEMPLATES);
20
20
  export const TemplateBase = unsupportedExport("TemplateBase", TEMPLATES);
21
21
  export const waitForPort = unsupportedExport("waitForPort (a template ready check)", TEMPLATES);
@@ -25,3 +25,24 @@ export const waitForFile = unsupportedExport("waitForFile (a template ready chec
25
25
  export const waitForTimeout = unsupportedExport("waitForTimeout (a template ready check)", TEMPLATES);
26
26
  export const Volume = unsupportedExport("Volume", "Use runtime.volumes (Runtime volumes) and mount one with runtime: { create: { volumes: [{ volumeId, path }] } }.");
27
27
  export const Secret = unsupportedExport("Secret", "Use a Runtime secret: `npx withruntime secrets set NAME --host api.example.com`. The sandbox sees a placeholder, and the egress proxy adds the value on HTTPS to that host.");
28
+ export const SecretPaginator = unsupportedExport("SecretPaginator", "List Runtime secrets with `npx withruntime secrets ls` or runtime.secrets.list().");
29
+ export const Git = unsupportedExport("git module (deprecated by E2B too)", "Run git with sandbox.commands.run('git ...'); git is installed.");
30
+ export const ReadyCmd = unsupportedExport("ReadyCmd (a template ready check)", TEMPLATES);
31
+ export const LogEntry = unsupportedExport("LogEntry (template build logs)", TEMPLATES);
32
+ export const LogEntryStart = unsupportedExport("LogEntryStart (template build logs)", TEMPLATES);
33
+ export const LogEntryEnd = unsupportedExport("LogEntryEnd (template build logs)", TEMPLATES);
34
+ export const defaultBuildLogger = unsupportedExport("defaultBuildLogger (template build logs)", TEMPLATES);
35
+ const ENDPOINTS = "This package talks only to Runtime's API through the sandbox's own methods; sandbox.runtime is the Runtime sandbox underneath.";
36
+ export const ConnectionConfig = unsupportedExport("ConnectionConfig", ENDPOINTS);
37
+ export const ApiClient = unsupportedExport("ApiClient (E2B's REST client)", ENDPOINTS);
38
+ export const getSignature = unsupportedExport("getSignature (signed file URLs)", "Use sandbox.files.read and sandbox.files.write.");
39
+ /** E2B's "every address" network selector, as E2B defines it. */
40
+ export const ALL_TRAFFIC = "0.0.0.0/0";
41
+ /** E2B's volume entry types, as E2B defines them. */
42
+ export var VolumeFileType;
43
+ (function (VolumeFileType) {
44
+ VolumeFileType["UNKNOWN"] = "unknown";
45
+ VolumeFileType["FILE"] = "file";
46
+ VolumeFileType["DIRECTORY"] = "directory";
47
+ VolumeFileType["SYMLINK"] = "symlink";
48
+ })(VolumeFileType || (VolumeFileType = {}));
@@ -9,6 +9,15 @@ export declare function runAs(ctx: SandboxContext, user: Username | undefined, o
9
9
  export declare function commandAs(user: string, script: string, cwdGiven: boolean): string[];
10
10
  /** An interactive login shell as `user`, for a PTY. */
11
11
  export declare function shellAs(user: string, cwdGiven: boolean): string[];
12
+ /** A running command as E2B lists it, from the command line Runtime keeps
13
+ * (its words joined by spaces, at most 256 characters): `/bin/bash -l -c
14
+ * <script>` for a command, `/bin/bash -i -l` for a PTY, as E2B starts them,
15
+ * whether it runs as the sandbox user or through `commandAs`. Anything else,
16
+ * started outside this package, is its first word and the rest. */
17
+ export declare function listedAs(command: string): {
18
+ cmd: string;
19
+ args: string[];
20
+ };
12
21
  /** E2B's file calls as another Linux user: each one a short script run with
13
22
  * `sudo -u`, since Runtime's file API acts as the sandbox's own user. Output
14
23
  * streams, so a read of any size comes back whole. */
package/dist/e2b/users.js CHANGED
@@ -62,6 +62,28 @@ export function commandAs(user, script, cwdGiven) {
62
62
  export function shellAs(user, cwdGiven) {
63
63
  return commandAs(user, "exec /bin/bash -i -l", cwdGiven);
64
64
  }
65
+ /** A running command as E2B lists it, from the command line Runtime keeps
66
+ * (its words joined by spaces, at most 256 characters): `/bin/bash -l -c
67
+ * <script>` for a command, `/bin/bash -i -l` for a PTY, as E2B starts them,
68
+ * whether it runs as the sandbox user or through `commandAs`. Anything else,
69
+ * started outside this package, is its first word and the rest. */
70
+ export function listedAs(command) {
71
+ const wrapped = AS_USER.exec(command);
72
+ if (wrapped) {
73
+ const inner = command.slice(wrapped[0].length);
74
+ if (inner === "exec /bin/bash -i -l")
75
+ return { cmd: "/bin/bash", args: ["-i", "-l"] };
76
+ return { cmd: "/bin/bash", args: ["-l", "-c", inner] };
77
+ }
78
+ if (command.startsWith("bash -c "))
79
+ return { cmd: "/bin/bash", args: ["-l", "-c", command.slice(8)] };
80
+ if (command === "/bin/bash -i -l")
81
+ return { cmd: "/bin/bash", args: ["-i", "-l"] };
82
+ const [cmd = "", ...args] = command.split(" ");
83
+ return { cmd, args };
84
+ }
85
+ /** What `commandAs` puts before the script, as the joined command line shows it. */
86
+ const AS_USER = /^sudo -n -E -H -u [^ ]+ -- \/bin\/bash -c (?:cd ~ 2>\/dev\/null\n)?/;
65
87
  /** One `sh -c` script as `user`, with its arguments passed apart, never
66
88
  * pasted into the script. */
67
89
  function script(user, text, ...args) {
package/dist/errors.d.ts CHANGED
@@ -13,8 +13,8 @@ export declare const DELIBERATE: ReadonlySet<string>;
13
13
  * minutes when it has none), however many retries it allows otherwise. */
14
14
  export declare const NOTHING_RAN: ReadonlySet<string>;
15
15
  /** Refusals of a create that clear when a sandbox stops or pauses, or a host
16
- * frees room: the trial's slots, an email domain's trial slots, the account's
17
- * quota and the region's capacity. `sandboxes.create` waits them out, retrying
16
+ * frees room: an account without credit's eight at once and its total, an
17
+ * email domain's, the account's quota and the region's capacity. `sandboxes.create` waits them out, retrying
18
18
  * with the same key and input, for up to `waitForCapacityMs`. */
19
19
  export declare const WAITS_FOR_ROOM: ReadonlySet<string>;
20
20
  export declare class RuntimeError extends Error {
@@ -38,8 +38,8 @@ export declare class RuntimeError extends Error {
38
38
  cause?: unknown;
39
39
  });
40
40
  /** Retrying this exact call (the SDK keeps the key) is safe and may work.
41
- * True for no_capacity and trial_busy as well, which clear by themselves when
42
- * a host frees room or a trial sandbox stops. `sandboxes.create` already
41
+ * True for no_capacity and no_credit_running_limit as well, which clear by themselves when
42
+ * a host frees room or a sandbox without credit stops. `sandboxes.create` already
43
43
  * waits for those (see `waitForCapacityMs`), so seeing one from a create
44
44
  * means the wait ran out or was switched off. */
45
45
  get retryable(): boolean;
@@ -68,7 +68,9 @@ export declare class AccountBlockedError extends RuntimeError {
68
68
  * same idempotencyKey (the SDK does, automatically) settles it safely. */
69
69
  export declare class ConnectionError extends RuntimeError {
70
70
  }
71
- /** Raised by exec({ check: true }) when a command exits non-zero. */
71
+ /** Raised by exec({ check: true }) when a command exits non-zero. Its code
72
+ * is `out_of_memory` when the sandbox's out-of-memory killer ended it, with
73
+ * the result's message and hint. */
72
74
  export declare class CommandError extends RuntimeError {
73
75
  readonly exitCode: number | null;
74
76
  readonly stdout: string;
@@ -78,6 +80,13 @@ export declare class CommandError extends RuntimeError {
78
80
  stdout: string;
79
81
  stderr: string;
80
82
  timedOut?: boolean;
83
+ outOfMemory?: {
84
+ code: string;
85
+ message: string;
86
+ hint: string;
87
+ };
81
88
  });
89
+ /** The same command in the same sandbox runs out of memory again. */
90
+ get retryable(): boolean;
82
91
  }
83
92
  export declare function errorFor(status: number, body: unknown, idempotencyKey?: string): RuntimeError;
package/dist/errors.js CHANGED
@@ -15,6 +15,7 @@ export const DELIBERATE = new Set([
15
15
  "secrets_unavailable",
16
16
  "identity_unavailable",
17
17
  "env_unavailable",
18
+ "resize_unavailable",
18
19
  ]);
19
20
  /** Refusals that guarantee nothing ran: a sandbox running as many commands
20
21
  * as it can (`guest_busy`), and the API's own limits, which answer before any
@@ -22,19 +23,22 @@ export const DELIBERATE = new Set([
22
23
  * safe, so the SDK does, with backoff, until the call's deadline (five
23
24
  * minutes when it has none), however many retries it allows otherwise. */
24
25
  export const NOTHING_RAN = new Set(["guest_busy", "busy", "rate_limited"]);
25
- /** Refusals that pass on their own: a host frees room, a trial slot frees. */
26
- const PASSING = new Set(["no_capacity", "trial_busy"]);
26
+ /** Refusals that pass on their own: a host frees room, a sandbox of an
27
+ * account without credit stops. */
28
+ const PASSING = new Set(["no_capacity", "no_credit_running_limit", "no_credit_total_limit"]);
27
29
  /** Refusals of a create that clear when a sandbox stops or pauses, or a host
28
- * frees room: the trial's slots, an email domain's trial slots, the account's
29
- * quota and the region's capacity. `sandboxes.create` waits them out, retrying
30
+ * frees room: an account without credit's eight at once and its total, an
31
+ * email domain's, the account's quota and the region's capacity. `sandboxes.create` waits them out, retrying
30
32
  * with the same key and input, for up to `waitForCapacityMs`. */
31
33
  export const WAITS_FOR_ROOM = new Set([
32
- "trial_busy",
33
- "trial_domain_limit",
34
- "trial_capacity",
34
+ "no_credit_running_limit",
35
+ "no_credit_total_limit",
36
+ "no_credit_domain_limit",
37
+ "no_credit_capacity_full",
35
38
  "quota_exceeded",
36
39
  "no_capacity",
37
- // A volume whose last sandbox is stopping: free within seconds.
40
+ // A volume whose last sandbox is stopping: free once the stop lets go of
41
+ // its disk, up to about a minute (measured 50 to 60 s, 6 October 2026).
38
42
  "volume_releasing",
39
43
  ]);
40
44
  export class RuntimeError extends Error {
@@ -63,14 +67,14 @@ export class RuntimeError extends Error {
63
67
  this.retryAfterMs = init.retryAfterMs;
64
68
  }
65
69
  /** Retrying this exact call (the SDK keeps the key) is safe and may work.
66
- * True for no_capacity and trial_busy as well, which clear by themselves when
67
- * a host frees room or a trial sandbox stops. `sandboxes.create` already
70
+ * True for no_capacity and no_credit_running_limit as well, which clear by themselves when
71
+ * a host frees room or a sandbox without credit stops. `sandboxes.create` already
68
72
  * waits for those (see `waitForCapacityMs`), so seeing one from a create
69
73
  * means the wait ran out or was switched off. */
70
74
  get retryable() {
71
75
  if (DELIBERATE.has(this.code))
72
76
  return false;
73
- // A fork asking for more copies than the trial runs at once never fits.
77
+ // A fork asking for more copies than an account without credit runs at once never fits.
74
78
  if (PASSING.has(this.code))
75
79
  return this.details?.field !== "count";
76
80
  return [0, 429, 502, 503, 504].includes(this.status);
@@ -102,23 +106,33 @@ export class AccountBlockedError extends RuntimeError {
102
106
  * same idempotencyKey (the SDK does, automatically) settles it safely. */
103
107
  export class ConnectionError extends RuntimeError {
104
108
  }
105
- /** Raised by exec({ check: true }) when a command exits non-zero. */
109
+ /** Raised by exec({ check: true }) when a command exits non-zero. Its code
110
+ * is `out_of_memory` when the sandbox's out-of-memory killer ended it, with
111
+ * the result's message and hint. */
106
112
  export class CommandError extends RuntimeError {
107
113
  exitCode;
108
114
  stdout;
109
115
  stderr;
110
116
  constructor(result) {
117
+ const memory = result.outOfMemory;
111
118
  super({
112
119
  message: result.timedOut
113
120
  ? "Command timed out."
114
- : `Command exited with ${result.exitCode}.${result.stderr ? ` ${result.stderr.trim().slice(-500)}` : ""}`,
115
- code: result.timedOut ? "command_timeout" : "command_failed",
121
+ : memory
122
+ ? `Command exited with ${result.exitCode}. ${memory.message}`
123
+ : `Command exited with ${result.exitCode}.${result.stderr ? ` ${result.stderr.trim().slice(-500)}` : ""}`,
124
+ code: result.timedOut ? "command_timeout" : memory ? memory.code : "command_failed",
116
125
  status: 0,
126
+ ...(memory && !result.timedOut ? { hint: memory.hint } : {}),
117
127
  });
118
128
  this.exitCode = result.exitCode;
119
129
  this.stdout = result.stdout;
120
130
  this.stderr = result.stderr;
121
131
  }
132
+ /** The same command in the same sandbox runs out of memory again. */
133
+ get retryable() {
134
+ return this.code === "out_of_memory" ? false : super.retryable;
135
+ }
122
136
  }
123
137
  export function errorFor(status, body, idempotencyKey) {
124
138
  const error = body?.error ?? {};
@@ -1,14 +1,105 @@
1
1
  import type { Runtime } from "../client.js";
2
- import type { Sandbox } from "../sandbox.js";
3
- import { CompatibilityError, type ClientOptions } from "../compat/core.js";
2
+ import type { Sandbox, Terminal } from "../sandbox.js";
3
+ import type { Snapshot } from "../snapshots.js";
4
+ import { CompatibilityError, type ClientOptions, type Refused, type RefusedAsync } from "../compat/core.js";
4
5
  export { CompatibilityError };
5
6
  export type VmState = "starting" | "running" | "pausing" | "paused" | "stopped";
7
+ export interface FreestyleErrorBody {
8
+ code: string;
9
+ message: string;
10
+ }
11
+ /** What every failed Runtime call becomes, as Freestyle throws it for a
12
+ * non-2xx response: `code` is Runtime's error code in upper case
13
+ * (`NOT_FOUND`), `status` its HTTP status, and `cause` the RuntimeError. */
14
+ export declare class FreestyleApiError extends Error {
15
+ readonly code: string;
16
+ readonly status: number;
17
+ readonly path?: string;
18
+ constructor(status: number, body: FreestyleErrorBody, path?: string);
19
+ }
20
+ export interface FreestyleConnectionError {
21
+ name?: string;
22
+ message?: string;
23
+ code?: string;
24
+ errno?: string | number;
25
+ syscall?: string;
26
+ address?: string;
27
+ port?: number;
28
+ }
29
+ /** What a call that got no answer from Runtime becomes, as Freestyle 0.2.17
30
+ * throws a failed fetch: a TypeError whose `cause` is the RuntimeError
31
+ * ConnectionError and whose `errors` carry it as one entry. */
32
+ export declare class FreestyleTransportError extends TypeError {
33
+ readonly errors: FreestyleConnectionError[];
34
+ constructor(cause: unknown, errors: FreestyleConnectionError[]);
35
+ toJSON(): {
36
+ name: string;
37
+ message: string;
38
+ errors: FreestyleConnectionError[];
39
+ };
40
+ }
41
+ export declare class FirewallRuleValidationError extends Error {
42
+ readonly path: string;
43
+ constructor(path: string, message: string);
44
+ }
45
+ export declare class TlsRuleValidationError extends Error {
46
+ readonly path: string;
47
+ constructor(path: string, message: string);
48
+ }
49
+ export declare class TlsForwardAuthValidationError extends Error {
50
+ readonly path: string;
51
+ constructor(path: string, message: string);
52
+ }
53
+ export declare const FirewallNamespace: Refused;
54
+ export declare const FirewallRulesNamespace: Refused;
55
+ export declare const validateFirewallEndpoint: Refused;
56
+ export declare const validateFirewallRule: Refused;
57
+ export declare const validateFirewallSpec: Refused;
58
+ export declare const TlsNamespace: Refused;
59
+ export declare const TlsRulesNamespace: Refused;
60
+ export declare const TlsForwardAuthNamespace: Refused;
61
+ export declare const hasTlsIdentity: Refused;
62
+ export declare const resolveTlsProtocol: Refused;
63
+ export declare const validateTlsDomain: Refused;
64
+ export declare const validateTlsEndpoint: Refused;
65
+ export declare const validateTlsForwardAuth: Refused;
66
+ export declare const validateTlsMailRoute: Refused;
67
+ export declare const validateTlsRule: Refused;
68
+ export declare const validateTlsSpec: Refused;
69
+ export declare const TunnelsNamespace: Refused;
70
+ export declare const VpcNamespace: Refused;
71
+ export declare const Vpc: Refused;
72
+ export declare const VpcTunnelNamespace: Refused;
73
+ export type FirewallProtocol = "tcp" | "udp" | "icmp";
74
+ export interface FirewallEndpoint {
75
+ vmId?: string;
76
+ vpcId?: string;
77
+ tunnelId?: string;
78
+ cidr?: string;
79
+ public?: true;
80
+ port?: number;
81
+ protocol?: FirewallProtocol;
82
+ }
6
83
  export interface FirewallRule {
7
84
  action: "allow";
8
- source: Record<string, never>;
9
- destination: {
10
- public: true;
11
- };
85
+ source: FirewallEndpoint;
86
+ destination: FirewallEndpoint;
87
+ description?: string;
88
+ }
89
+ export interface FirewallRuleData {
90
+ id: string;
91
+ action: "allow";
92
+ source: FirewallEndpoint;
93
+ destination: FirewallEndpoint;
94
+ description?: string | null;
95
+ dependencies: {
96
+ kind: string;
97
+ id: string;
98
+ slug?: string | null;
99
+ displayName?: string | null;
100
+ }[];
101
+ createdAt: string;
102
+ updatedAt: string;
12
103
  }
13
104
  export interface CreateVmOptions {
14
105
  snapshotId?: string | null;
@@ -27,14 +118,42 @@ export interface ExecOptions {
27
118
  env?: Record<string, string>;
28
119
  stdin?: string;
29
120
  }
121
+ export interface FreestyleOptions extends ClientOptions {
122
+ teamId?: string;
123
+ stackAccessToken?: string;
124
+ identityAccessToken?: string;
125
+ }
30
126
  export declare class Freestyle {
31
127
  readonly vms: VmsNamespace;
32
- constructor(options?: ClientOptions);
128
+ readonly fetch: RefusedAsync;
129
+ constructor(options?: FreestyleOptions);
130
+ get firewall(): never;
131
+ get tls(): never;
132
+ get tunnels(): never;
133
+ get vpc(): never;
33
134
  }
34
- export declare class VmsNamespace {
135
+ export declare class VmSnapshotsNamespace {
35
136
  private readonly runtime;
36
- readonly snapshots: {
37
- get: (id: string) => Promise<{
137
+ constructor(runtime: Runtime);
138
+ /** A snapshot by id or by its slug (Runtime's snapshot name). */
139
+ resolve(id: string): Promise<Snapshot>;
140
+ get(snapshotId: string): Promise<{
141
+ id: string;
142
+ sourceVmId: string;
143
+ slug: string | null;
144
+ displayName: string | null;
145
+ public: boolean;
146
+ createdAt: string;
147
+ updatedAt: string;
148
+ ttlSeconds: number | null;
149
+ }>;
150
+ delete(snapshotId: string): Promise<void>;
151
+ list(options?: {
152
+ sourceVmId?: string;
153
+ limit?: number;
154
+ offset?: number;
155
+ }): Promise<{
156
+ snapshots: {
38
157
  id: string;
39
158
  sourceVmId: string;
40
159
  slug: string | null;
@@ -42,29 +161,31 @@ export declare class VmsNamespace {
42
161
  public: boolean;
43
162
  createdAt: string;
44
163
  updatedAt: string;
45
- ttlSeconds: number;
46
- }>;
47
- delete: (id: string) => Promise<void>;
48
- list: (options?: {
49
- sourceVmId?: string;
50
- limit?: number;
51
- offset?: number;
52
- }) => Promise<{
53
- snapshots: {
54
- id: string;
55
- sourceVmId: string;
56
- slug: string | null;
57
- displayName: string | null;
58
- public: boolean;
59
- createdAt: string;
60
- updatedAt: string;
61
- ttlSeconds: number;
62
- }[];
63
- totalCount: number;
64
- }>;
65
- };
164
+ ttlSeconds: number | null;
165
+ }[];
166
+ totalCount: number;
167
+ }>;
168
+ /** Renames, relabels and re-times a snapshot: slug is its Runtime name,
169
+ * ttlSeconds whole days from now. */
170
+ update(snapshotId: string, options: {
171
+ slug?: string;
172
+ displayName?: string;
173
+ ttlSeconds?: number;
174
+ }): Promise<{
175
+ id: string;
176
+ sourceVmId: string;
177
+ slug: string | null;
178
+ displayName: string | null;
179
+ public: boolean;
180
+ createdAt: string;
181
+ updatedAt: string;
182
+ ttlSeconds: number | null;
183
+ }>;
184
+ }
185
+ export declare class VmsNamespace {
186
+ private readonly runtime;
187
+ readonly snapshots: VmSnapshotsNamespace;
66
188
  constructor(runtime: Runtime);
67
- private resolveSnapshot;
68
189
  create(options: CreateVmOptions): Promise<{
69
190
  vm: Vm;
70
191
  vmId: string;
@@ -89,13 +210,15 @@ export declare class VmsNamespace {
89
210
  };
90
211
  firewallRules: {
91
212
  id: string;
213
+ action: "allow";
92
214
  source: {
93
215
  vmId: string;
94
216
  };
95
- action: "allow";
96
- destination: {
97
- public: true;
98
- };
217
+ destination: FirewallEndpoint;
218
+ description: null;
219
+ dependencies: never[];
220
+ createdAt: string;
221
+ updatedAt: string;
99
222
  }[];
100
223
  tlsRules: never[];
101
224
  }>;
@@ -196,10 +319,118 @@ export declare class VmFilesystem {
196
319
  modified: string;
197
320
  }>;
198
321
  }
322
+ export interface PtySessionInfo {
323
+ sessionId: number;
324
+ state: string;
325
+ createdUnix: number;
326
+ cols: number;
327
+ rows: number;
328
+ exitCode?: number | null;
329
+ linuxUser?: string | null;
330
+ slug?: string | null;
331
+ }
332
+ export interface PtyOpenOptions {
333
+ exec?: string;
334
+ cols?: number;
335
+ rows?: number;
336
+ linuxUser?: string;
337
+ slug?: string;
338
+ }
339
+ export type PtySessionSelector = number | string;
340
+ export interface PtyAttachOptions {
341
+ session: PtySessionSelector;
342
+ linuxUser?: string;
343
+ }
344
+ export interface PtySessionEvents {
345
+ onData?: (data: Uint8Array) => void;
346
+ onExit?: (exitCode: number) => void;
347
+ onClose?: (info: {
348
+ wasClean: boolean;
349
+ code: number;
350
+ reason: string;
351
+ }) => void;
352
+ onError?: (err: unknown) => void;
353
+ }
354
+ /** A session's number: FNV-1a of its process id, 31 bits, never 0. */
355
+ export declare function sessionNumber(processId: string): number;
356
+ export declare class PtySession {
357
+ #private;
358
+ private readonly terminal;
359
+ private readonly sandbox;
360
+ private readonly processId;
361
+ readonly sessionId: number;
362
+ readonly slug: string | undefined;
363
+ readonly created: boolean;
364
+ constructor(terminal: Terminal, sandbox: Sandbox, processId: string, sessionId: number, slug: string | undefined, created: boolean, events: PtySessionEvents);
365
+ private readonly onError;
366
+ write(data: Uint8Array | string): void;
367
+ resize(options: {
368
+ cols: number;
369
+ rows: number;
370
+ }): void;
371
+ signal(sig: "sigint" | "sigkill"): void;
372
+ /** Closes the connection; the shell keeps running and attach() finds it. */
373
+ detach(): void;
374
+ get readyState(): number;
375
+ }
376
+ export declare class VmPty {
377
+ private readonly get;
378
+ constructor(get: () => Promise<Sandbox>);
379
+ private sessions;
380
+ private find;
381
+ private connect;
382
+ open(options?: PtyOpenOptions & PtySessionEvents): Promise<PtySession>;
383
+ attach(options: PtyAttachOptions & PtySessionEvents): Promise<PtySession>;
384
+ list(options?: {
385
+ linuxUser?: string;
386
+ }): Promise<{
387
+ sessions: PtySessionInfo[];
388
+ }>;
389
+ /** Ends a session's shell. An exited session stays in the list. */
390
+ close(session: PtySessionSelector, options?: {
391
+ linuxUser?: string;
392
+ }): Promise<{
393
+ sessionId: number;
394
+ exitCode: number | null | undefined;
395
+ } | {
396
+ sessionId: number;
397
+ exitCode?: undefined;
398
+ }>;
399
+ }
400
+ export declare class VmLinuxUserPty {
401
+ private readonly pty;
402
+ private readonly linuxUser;
403
+ constructor(pty: VmPty, linuxUser: string);
404
+ open(options?: Omit<PtyOpenOptions, "linuxUser"> & PtySessionEvents): Promise<PtySession>;
405
+ attach(options: Omit<PtyAttachOptions, "linuxUser"> & PtySessionEvents): Promise<PtySession>;
406
+ list(): Promise<{
407
+ sessions: PtySessionInfo[];
408
+ }>;
409
+ close(session: PtySessionSelector): Promise<{
410
+ sessionId: number;
411
+ exitCode: number | null | undefined;
412
+ } | {
413
+ sessionId: number;
414
+ exitCode?: undefined;
415
+ }>;
416
+ }
417
+ export declare class VmLinuxUser {
418
+ private readonly vm;
419
+ private readonly linuxUser;
420
+ readonly pty: VmLinuxUserPty;
421
+ constructor(vm: Vm, linuxUser: string);
422
+ exec(options: string | Omit<ExecOptions, "linuxUser">): Promise<{
423
+ stdout: string;
424
+ stderr: string;
425
+ statusCode: number | null;
426
+ }>;
427
+ }
199
428
  export declare class Vm {
200
429
  private readonly runtime;
201
430
  readonly id: string;
202
431
  readonly fs: VmFilesystem;
432
+ readonly pty: VmPty;
433
+ readonly resize: RefusedAsync;
203
434
  constructor(runtime: Runtime, id: string);
204
435
  data(): Promise<{
205
436
  id: string;
@@ -259,6 +490,23 @@ export declare class Vm {
259
490
  updatedAt: string;
260
491
  }>;
261
492
  delete(): Promise<void>;
493
+ /** The VM's outbound rules, read back from its network settings. */
494
+ firewallRules(): Promise<{
495
+ rules: {
496
+ id: string;
497
+ action: "allow";
498
+ source: {
499
+ vmId: string;
500
+ };
501
+ destination: FirewallEndpoint;
502
+ description: null;
503
+ dependencies: never[];
504
+ createdAt: string;
505
+ updatedAt: string;
506
+ }[];
507
+ totalCount: number;
508
+ }>;
509
+ linuxUser(linuxUser: string): VmLinuxUser;
262
510
  update(options: {
263
511
  slug?: string;
264
512
  displayName?: string;
@@ -303,7 +551,7 @@ export declare class Vm {
303
551
  public: boolean;
304
552
  createdAt: string;
305
553
  updatedAt: string;
306
- ttlSeconds: number;
554
+ ttlSeconds: number | null;
307
555
  };
308
556
  }>;
309
557
  }