withruntime 0.23.0 → 0.33.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/COMPATIBILITY.md +66 -5
  2. package/E2B.md +1 -1
  3. package/README.md +36 -2
  4. package/README.src.md +35 -1
  5. package/compatibility-lock.json +3 -3
  6. package/dist/agents/browser.d.ts +12 -0
  7. package/dist/agents/browser.js +12 -0
  8. package/dist/agents/index.d.ts +7 -7
  9. package/dist/agents/index.js +7 -8
  10. package/dist/agents-cli.d.ts +1 -1
  11. package/dist/agents-cli.js +250 -3
  12. package/dist/agents-deploy.d.ts +186 -0
  13. package/dist/agents-deploy.js +752 -0
  14. package/dist/agents-file.d.ts +19 -0
  15. package/dist/agents-file.js +135 -0
  16. package/dist/apps/index.d.ts +10 -0
  17. package/dist/apps/index.js +11 -0
  18. package/dist/apps-cli.d.ts +3 -1
  19. package/dist/apps-cli.js +285 -38
  20. package/dist/blaxel/errors.js +2 -1
  21. package/dist/ci/index.d.ts +13 -0
  22. package/dist/ci/index.js +14 -0
  23. package/dist/ci-cli.d.ts +10 -0
  24. package/dist/ci-cli.js +402 -0
  25. package/dist/ci-import.d.ts +23 -0
  26. package/dist/ci-import.js +565 -0
  27. package/dist/cli.d.ts +18 -7
  28. package/dist/cli.js +775 -85
  29. package/dist/daytona/errors.js +2 -1
  30. package/dist/e2b/errors.js +2 -1
  31. package/dist/e2b/filesystem.d.ts +1 -0
  32. package/dist/e2b/filesystem.js +1 -1
  33. package/dist/e2b/sandbox.d.ts +11 -2
  34. package/dist/e2b/sandbox.js +22 -6
  35. package/dist/errors.d.ts +11 -4
  36. package/dist/errors.js +27 -4
  37. package/dist/fly/index.d.ts +102 -0
  38. package/dist/fly/index.js +930 -0
  39. package/dist/index.d.ts +7 -3
  40. package/dist/machine.d.ts +10 -6
  41. package/dist/machine.js +14 -6
  42. package/dist/modal/index.d.ts +34 -0
  43. package/dist/modal/index.js +128 -22
  44. package/dist/products/agents.d.ts +101 -3
  45. package/dist/products/agents.js +49 -0
  46. package/dist/products/apps.d.ts +206 -10
  47. package/dist/products/apps.js +172 -1
  48. package/dist/products/ci.d.ts +335 -0
  49. package/dist/products/ci.js +108 -0
  50. package/dist/products/index.d.ts +8 -0
  51. package/dist/products/index.js +15 -0
  52. package/dist/products/jobs.d.ts +105 -5
  53. package/dist/products/jobs.js +47 -3
  54. package/dist/products/network.d.ts +13 -0
  55. package/dist/products/observability.d.ts +1 -1
  56. package/dist/products/plans.d.ts +131 -0
  57. package/dist/products/plans.js +24 -0
  58. package/dist/products/reservations.d.ts +108 -0
  59. package/dist/products/reservations.js +41 -0
  60. package/dist/products/resources.d.ts +2 -1
  61. package/dist/products/secrets.d.ts +90 -6
  62. package/dist/products/secrets.js +8 -2
  63. package/dist/proxy.d.ts +3 -3
  64. package/dist/proxy.js +20 -0
  65. package/dist/sandbox.d.ts +29 -1
  66. package/dist/sandbox.js +56 -3
  67. package/dist/snapshots.d.ts +1 -1
  68. package/dist/switched-off.d.ts +5 -0
  69. package/dist/switched-off.js +8 -0
  70. package/dist/tar.d.ts +1 -1
  71. package/dist/tar.js +19 -1
  72. package/dist/transport.d.ts +1 -1
  73. package/dist/transport.js +48 -9
  74. package/dist/types.d.ts +35 -4
  75. package/dist/vercel/errors.d.ts +1 -1
  76. package/dist/vercel/errors.js +2 -1
  77. package/dist/vercel/snapshot.js +4 -2
  78. package/package.json +23 -6
package/COMPATIBILITY.md CHANGED
@@ -28,9 +28,70 @@ as reviewed and unsupported, and `bun run compat:upstream` flags any other relea
28
28
  | Fly Sprites | `@fly/sprites` 0.2.3 | `withruntime/sprites` | `SpritesClient`, create/lookup/list/delete/restart; `exec`, `execFile`, Node streams and event-based `spawn`; attachable native processes; binary/text/JSON files, directory traversal, append, chmod, chown and `asRoot` through sudo, file watches; preview access settings; checkpoints as disk snapshots; domain network policy; session kill; port watcher and port proxy; `APIError` with the vendor's limit codes |
29
29
  | Freestyle | `freestyle` 0.2.20 | `withruntime/freestyle` | `Freestyle`, VM create/ref/get/list/start/pause/delete/update; command execution, binary/text files and streams, filesystem metadata; native snapshots; explicit deny-all or outbound-public firewall intent |
30
30
  | Morph | `morphcloud` 0.0.20 | `withruntime/morph` | `MorphCloudClient`, images list, snapshot create/get/list/delete/metadata and cached `setup` chains, instance start/boot/get/list/stop/pause/resume/branch/snapshot, metadata, wake-on, TTL at start, streamed exec, HTTP services as previews, file `sync` |
31
- | Modal | `modal` 0.11.1 | `withruntime/modal` | `ModalClient`, app-name grouping, registry images and Dockerfile layers, CPU sandbox create/get/list/name lookup, text/binary process streams and stdin, command completion, filesystem transfer and metadata, tags, encrypted public previews, outbound allowlists, memory snapshot capture |
31
+ | Modal | `modal` 0.11.1 | `withruntime/modal` | `ModalClient`, app-name grouping, registry images and Dockerfile layers, CPU sandbox create/get/list/name lookup, idle timeout, text/binary process streams and stdin, commands as root, command completion, filesystem transfer, metadata and watches, tags, encrypted public previews, outbound domain and CIDR allowlists, filesystem and memory snapshot capture |
32
32
  | Cloudflare | `@cloudflare/sandbox` 0.12.10 (0.x API) | `withruntime/cloudflare` | `getSandbox`, named Runtime sandboxes, explicit execution sessions, text exec and SSE output, background processes, logs/signals/waits, binary/text files, recursive listings, environment updates, signed Runtime previews, conditional Worker Durable Object entry, Worker preview proxy, destruction |
33
33
 
34
+ ### Modal's own examples, live (18 October 2026)
35
+
36
+ Every sandbox example of Modal's JavaScript SDK (`js/examples` at
37
+ `js/v0.11.1`, 26 files; `sandbox-gpu.ts` needs a GPU and the Functions
38
+ examples call deployed Functions, so they are not run) is copied verbatim
39
+ into `tests/fixtures/modal`, with only the import changed, and run against
40
+ real Runtime sandboxes by `scripts/compatibility-modal-examples-live.ts`
41
+ (opt-in, `--run`; each sandbox capped at two cents and five minutes, deleted
42
+ when its example ends). What failed, and what changed:
43
+
44
+ - A layer's `secrets` (`image-building.ts`) stay refused, now naming the
45
+ alternative: a Runtime build keeps its build arguments in the image's build
46
+ plan, history and cache key, so a secret is used at run time
47
+ (`sandboxes.create(app, image, { secrets })` or `runtime.secrets.set`).
48
+ - `idleTimeoutMs` (`sandbox-tunnels.ts`) was refused; it is Runtime's idle
49
+ pause (10 s at least), memory kept. `timeoutMs` under a minute is kept by
50
+ the client, with Runtime's minute as the bound if the client goes away.
51
+ - Commands ran as the sandbox user, so `mkdir /app` failed
52
+ (`sandbox-filesystem-snapshot.ts`); the entrypoint, `exec` and readiness
53
+ probes now run as root, as in a Modal container.
54
+ - `poll()` after the sandbox ended (`sandbox-poll.ts`) threw; it answers the
55
+ exit code it saw, or 137 for a process killed with its sandbox.
56
+ - `experimentalOptions` were refused as unknown; `enable_exit_snapshot`
57
+ refuses naming `snapshotFilesystem()` before `terminate()`.
58
+ - Allowlists were an intersection; Modal's domain and CIDR allowlists are a
59
+ union, and `*.x` also allows `x`.
60
+ - `client.functions`, `functionCalls`, `cls` and `queues` were undefined;
61
+ each call refuses, naming Runtime's alternative.
62
+ - A file watch in Alpine (no python3) failed, and its retry hid why. The
63
+ server now runs the watcher on Runtime's own Python, in every image, and a
64
+ retried start replays the first (`packages/cloud/src/watch/client.ts`).
65
+ - A snapshot of a running sandbox could fail when another call (the
66
+ entrypoint's open output stream) woke it mid-capture. A call's wake now
67
+ waits for the capture (`cloud_wake_waits_for_capture` migration,
68
+ `packages/cloud/src/api/guest-call.ts`).
69
+
70
+ `tests/compat/modal-examples.test.ts` fails on the old adapter.
71
+ `compat-inventory.json` records 226 present, 163 refused and 0 missing of 389.
72
+
73
+ ### Fly Machines API (18 October 2026)
74
+
75
+ Fly publishes no TypeScript SDK for Machines; its users call the REST API at
76
+ `api.machines.dev` with curl or an HTTP client, or through fly-go. So
77
+ `withruntime/fly` answers the HTTP API itself: `machinesApi()` is a fetch
78
+ handler, `serveMachinesApi()` and `npx withruntime fly-api` serve it on a port.
79
+ Of the spec's 29 machine routes, 24 are answered (list, create, get, update,
80
+ delete, start, stop, suspend, restart, wait, exec, signal, ps, events, versions,
81
+ metadata in all six forms, lease get/acquire/release) and 5 refuse: the memory
82
+ limit's get, set and reclaim (resize the machine instead), and cordon and
83
+ uncordon (no services). Apps, the org's machines and the region list are
84
+ answered too. Restart policies `always` and `on-failure` (with `max_retries`)
85
+ are kept by a supervisor loop around the main process. `services`, `mounts`,
86
+ `checks`, `processes`, GPUs, `files` from secrets and regions other than `iad`
87
+ answer 400 naming the alternative.
88
+ Evidence: `tests/compat/fly-contract.test.ts`;
89
+ `scripts/compatibility-fly-docs-live.ts --run`, which runs the 22 curl
90
+ examples of Fly's Machines API pages verbatim
91
+ (`tests/compat/fly-docs/machines-api-examples.sh`, superfly/docs at 15f58f1f,
92
+ read 18 October 2026) and fly-go 0.11.6's flaps client unchanged
93
+ (`tests/compat/fly-go`) on the real API; and `scripts/compatibility-fly-live.ts --run`.
94
+
34
95
  ### Modal 0.11.1 review (16 October 2026)
35
96
 
36
97
  The pin advances from 0.11.0 to 0.11.1; support remains partial. Both npm
@@ -86,7 +147,7 @@ all 73 inventory items are present or refused, none missing. How it maps:
86
147
  - `branch(n)` is one fork with the snapshot kept: copies keep memory and
87
148
  running processes.
88
149
  - `ttlSeconds` is the time limit (60 to 86400); `ttlAction` stop deletes,
89
- pause pauses. Runtime also pauses an idle sandbox after a minute and wakes
150
+ pause pauses. Runtime also pauses an idle sandbox after five minutes and wakes
90
151
  it on the next request, which Morph does not.
91
152
  - `exposeHttpService` is a preview: public with no `auth_mode` (needs a kept
92
153
  top-up), private with `api_key` (send its token as `x-runtime-preview-token`).
@@ -268,8 +329,8 @@ share the file path and `compat.provider` resource label.
268
329
  ## Evidence that can be repeated locally
269
330
 
270
331
  Run `bun test tests/compat` from the SDK package and run `bun run check-types`.
271
- The test run compiles unchanged typed consumer bodies from
272
- `tests/compat/consumers/workflows.ts.txt` against all ten TypeScript adapters,
332
+ The type check (`tests/compat/consumers/tsconfig.json`) compiles unchanged typed consumer bodies from
333
+ `tests/compat/consumers/workflows.ts` against all ten TypeScript adapters,
273
334
  including E2B's interpreter. Run
274
335
  `bun tests/compat/check-consumers.ts <verified-cache>` to compile the
275
336
  same bodies against the pinned upstream declarations; the script checks each
@@ -341,7 +402,7 @@ Remaining implementation work is tracked only in the repository `WORKLIST.md`.
341
402
  | CodeSandbox | No browser editor/Pitcher protocol, browser-session tokens, interpreters, live VM resizing, fork tier changes, read-only or global editor sessions, or private host-token emulation. Configured tasks run under a guest supervisor and setup steps under a guest runner, both started by the adapter and surviving client disconnects; a task's port must be configured with `task.preview.port`, because automatic task-to-port discovery is refused. Private host-only preview requests fail explicitly; native signed preview URLs remain available. Public port discovery lists registered previews, not all listening sockets. Default workspace is prepared at `/project/sandbox`. Command restart preserves the originating client's captured argv, environment and working directory; a command discovered by another client refuses restart because its private spawn recipe is unavailable. |
342
403
  | Sprites | No control-mode WebSocket protocol, managed services, in-place checkpoint restore (start a new sandbox from the snapshot), checkpoint history filters, network presets (`include`), an allow rule inside a denied wildcard (Runtime's deny always wins), privilege or resource policies, `maxRunAfterDisconnect`, Fly token exchange or Sprite list streaming; each is refused by name. A checkpoint is a Runtime disk snapshot (files, not running processes); the Sprite pauses for the moment it takes. An allow rule makes an allowlist, as Sprites' DNS allowlist does. The port watcher polls `ss` once a second. Session handles use native process IDs, not tmux. The sprite URL maps port 8080. File bytes and process byte streams preserve binary data. |
343
404
  | Freestyle | Provider catalog snapshot slugs are not Runtime snapshots and are refused. Firewall support is limited to an explicit empty rule set or the exact allow-public-outbound shape; arbitrary rule selectors, TLS policies and private networks are refused. No automatic-restart guarantee, retention scheduler, placement constraints, live resize, Linux-user switching, PTY namespace, public IPv6 or account-owned egress address emulation. Native snapshot retention is positive whole days. |
344
- | Modal | CPU sandboxes only; different resource reservation/limit values, fractional CPU, GPU and foreign placement are refused. Named Apps group Runtime sandboxes; they do not deploy Functions. Registry authentication uses Runtime's registry configuration. No Functions/Cls, volumes/bucket mounts, GPU image steps, readiness probes, sidecars, directory mounts, filesystem-only images from snapshots, or snapshot restoration API. Entry-point completion stops the sandbox while the originating client is alive; the native lease remains the bound if that client disappears. A different client can reconnect using the saved entrypoint process ID. |
405
+ | Modal | CPU sandboxes only; different resource reservation/limit values, fractional CPU, GPU and foreign placement are refused. Named Apps group Runtime sandboxes; they do not deploy Functions. Registry authentication uses Runtime's registry configuration. Commands run as root. No Functions/Cls/queues, named secrets, volumes made on first use, GPU image steps, sidecars, connect tokens, proxies, directory or exit snapshots, or snapshot restoration API; each refuses naming the alternative. Entry-point completion stops the sandbox while the originating client is alive; the native lease remains the bound if that client disappears. A different client can reconnect using the saved entrypoint process ID. |
345
406
  | Cloudflare | The conditional Worker entry supplies a Durable Object bridge and custom-hostname preview proxy; infrastructure configuration must still remove the vendor Container declaration and provide Runtime secrets. Cloudflare's examples run live under `wrangler dev` (above); custom preview routing has no live public-hostname acceptance evidence. At most 4 interpreter contexts. No isolated PID namespaces, backup format, terminal WebSocket protocol, custom process IDs or provider cleanup-record semantics. Foreground named sessions use resident Bash; background processes inherit exported state/cwd but do not yet inherit every local variable/function/option. |
346
407
 
347
408
  ## Keeping compatibility current
package/E2B.md CHANGED
@@ -105,6 +105,7 @@ account the key belongs to and where the key came from.
105
105
  | `commands.list`, `kill(pid)`, `sendStdin(pid)`, `closeStdin(pid)`, `connect(pid)` | Runtime's processes. A pid is a number derived from Runtime's process id, not the Linux pid. `commands.list` shows each command as E2B starts it: `cmd` `/bin/bash`, `args` `["-l", "-c", "<your command>"]` (a PTY: `["-i", "-l"]`), the command cut at 256 characters, `envs` empty. |
106
106
  | `pty.create`, `connect`, `sendInput`, `resize`, `kill` (Python snake_case) | Native PTY processes with lossless byte callbacks. A reader timeout or disconnect detaches without killing the process; reconnect resumes reading. |
107
107
  | `files.read(path, { format })` | `files.read`. `text`, `bytes`, `blob` and `stream` (Python: `text`, `bytes`, `stream`). |
108
+ | `downloadUrl(path, opts)`, `uploadUrl(path, opts)` | `files.downloadUrl` and `files.uploadUrl`: a signed link anyone can open with no key, as a string. `useSignatureExpiration` is seconds (60 to 7 days, one hour by default); `user` is ignored. `uploadUrl()` needs a `path`, as a link names one file. |
108
109
  | `files.write(path, data)`, `write([...])`, `writeFiles` | `files.write`. Parent directories are made, and a file that exists is replaced. |
109
110
  | `files.list(path, { depth })` | `files.list`, hidden files included. `owner` and `group` come from native metadata, with `""` for older guests that omit them. `depth` below one throws `InvalidArgumentError` "depth should be at least one". |
110
111
  | `files.makeDir`, `exists`, `getInfo`, `rename`, `remove` | `files.stat`, `mkdir`, `rename` (replacing a file that exists) and `remove` (recursive). A missing file throws `FileNotFoundError`. Entries read as envd gives them: `permissions` begins with the kind's letter (`-rw-r--r--`, `drwxr-xr-x`, `L` for a link), the sandbox user is `user`, and a link's `symlinkTarget` is absolute. |
@@ -143,7 +144,6 @@ before anything happens. The error's `feature` names the gap and its
143
144
  | `volumeMounts`, `Volume` | Runtime volumes: `runtime: { create: { volumes: [{ volumeId, path }] } }`. |
144
145
  | `git` | `commands.run("git ...")`. E2B has deprecated its git module too. |
145
146
  | File `metadata` | Keep it in a file beside the data. |
146
- | `uploadUrl`, `downloadUrl` | `files.write` and `files.read`. |
147
147
  | `runCode(code, { envs })` | A context made with them: `sandbox.runtime.interpreter.contexts.create({ env })`. |
148
148
  | `domain`, `apiUrl`, `sandboxUrl`, `headers`, `proxy`, `debug` | Remove them. `RUNTIME_API_URL` sets Runtime's origin, and `HTTPS_PROXY` sets a proxy. |
149
149
 
package/README.md CHANGED
@@ -55,9 +55,9 @@ The sandbox object does the rest:
55
55
  own tailnet), `metrics` and `mcp` (servers from the MCP catalog, run in the
56
56
  sandbox) for the other products.
57
57
 
58
- A sandbox pauses itself after 60 seconds with nothing happening in it, keeping
58
+ A sandbox pauses itself after 300 seconds with nothing happening in it, keeping
59
59
  its memory and processes, and the next call wakes it, so an idle sandbox costs
60
- no compute; `idlePauseSeconds` sets 10 to 86,400, or 0 for never.
60
+ no compute; `idlePauseSeconds` sets 60 to 86,400 (a shorter time is raised to 60), or 0 for never.
61
61
 
62
62
  `Sandbox.getOrCreate(name)` returns the sandbox with that name, woken if it is
63
63
  paused, or creates it.
@@ -162,6 +162,24 @@ copies memory and processes. `stop` deletes the sandbox, as Morph's does.
162
162
  SSH, reboot and a time limit set after start throw `CompatibilityError`
163
163
  naming the alternative. `COMPATIBILITY.md` lists every mapping.
164
164
 
165
+ ## Code written for Modal Sandboxes
166
+
167
+ `withruntime/modal` runs code written for Modal's Sandboxes (`modal` 0.11.1).
168
+ Change the import and set `RUNTIME_API_KEY`:
169
+
170
+ ```ts no-run
171
+ import { ModalClient } from "withruntime/modal"; // was: from "modal"
172
+ ```
173
+
174
+ Modal's own sandbox examples run unchanged where they use none of what is
175
+ refused below, and a Modal token is never needed
176
+ or sent. Commands run as root, as in a Modal container. A `timeoutMs` ends the
177
+ sandbox; an `idleTimeoutMs` pauses it with its memory kept, and the next call
178
+ wakes it. GPUs, Modal Functions and queues, named secrets, secrets in image
179
+ build steps (a build keeps no secret: use it at run time), volumes made on
180
+ first use, sidecars, connect tokens, directory and exit snapshots throw
181
+ `CompatibilityError` before anything is created, naming what to use instead.
182
+
165
183
  ## Code written for Cloudflare's Sandbox SDK
166
184
 
167
185
  `withruntime/cloudflare` runs a Worker written for Cloudflare's 0.x
@@ -181,6 +199,22 @@ Cloudflare documents them; backups, tunnels, terminals and outbound
181
199
  interception throw `CompatibilityError` naming the alternative.
182
200
  `COMPATIBILITY.md` lists every mapping.
183
201
 
202
+ ## Code written for Fly Machines
203
+
204
+ `withruntime/fly` answers Fly's Machines API (`api.machines.dev`) with Runtime
205
+ sandboxes, so code in any language moves by changing one address:
206
+
207
+ ```sh no-run
208
+ npx withruntime fly-api # http://127.0.0.1:4280, as your Runtime login
209
+ ```
210
+
211
+ Point `FLY_API_HOSTNAME` (as in Fly's own examples), fly-go's
212
+ `FLY_FLAPS_BASE_URL` or any client's base URL there; `machinesApi()` is the same
213
+ as a fetch handler for your own server. A Machine's image is built once with
214
+ its `init` and `files`, the image's command is its main process, and its
215
+ restart policy is kept. The Fly token is never sent anywhere. Services, mounts,
216
+ checks and other regions answer 400 naming the alternative.
217
+
184
218
  ## Agent frameworks
185
219
 
186
220
  `withruntime/openai-agents` is a sandbox client for the OpenAI Agents SDK's
package/README.src.md CHANGED
@@ -59,7 +59,7 @@ The sandbox object does the rest:
59
59
 
60
60
  A sandbox pauses itself after {{idle-pause}} with nothing happening in it, keeping
61
61
  its memory and processes, and the next call wakes it, so an idle sandbox costs
62
- no compute; `idlePauseSeconds` sets {{idle-pause-min}} to {{idle-pause-max}}, or 0 for never.
62
+ no compute; `idlePauseSeconds` sets {{idle-pause-min}} to {{idle-pause-max}} (a shorter time is raised to {{idle-pause-min}}), or 0 for never.
63
63
 
64
64
  `Sandbox.getOrCreate(name)` returns the sandbox with that name, woken if it is
65
65
  paused, or creates it.
@@ -164,6 +164,24 @@ copies memory and processes. `stop` deletes the sandbox, as Morph's does.
164
164
  SSH, reboot and a time limit set after start throw `CompatibilityError`
165
165
  naming the alternative. `COMPATIBILITY.md` lists every mapping.
166
166
 
167
+ ## Code written for Modal Sandboxes
168
+
169
+ `withruntime/modal` runs code written for Modal's Sandboxes (`modal` 0.11.1).
170
+ Change the import and set `RUNTIME_API_KEY`:
171
+
172
+ ```ts no-run
173
+ import { ModalClient } from "withruntime/modal"; // was: from "modal"
174
+ ```
175
+
176
+ Modal's own sandbox examples run unchanged where they use none of what is
177
+ refused below, and a Modal token is never needed
178
+ or sent. Commands run as root, as in a Modal container. A `timeoutMs` ends the
179
+ sandbox; an `idleTimeoutMs` pauses it with its memory kept, and the next call
180
+ wakes it. GPUs, Modal Functions and queues, named secrets, secrets in image
181
+ build steps (a build keeps no secret: use it at run time), volumes made on
182
+ first use, sidecars, connect tokens, directory and exit snapshots throw
183
+ `CompatibilityError` before anything is created, naming what to use instead.
184
+
167
185
  ## Code written for Cloudflare's Sandbox SDK
168
186
 
169
187
  `withruntime/cloudflare` runs a Worker written for Cloudflare's 0.x
@@ -183,6 +201,22 @@ Cloudflare documents them; backups, tunnels, terminals and outbound
183
201
  interception throw `CompatibilityError` naming the alternative.
184
202
  `COMPATIBILITY.md` lists every mapping.
185
203
 
204
+ ## Code written for Fly Machines
205
+
206
+ `withruntime/fly` answers Fly's Machines API (`api.machines.dev`) with Runtime
207
+ sandboxes, so code in any language moves by changing one address:
208
+
209
+ ```sh no-run
210
+ npx withruntime fly-api # http://127.0.0.1:4280, as your Runtime login
211
+ ```
212
+
213
+ Point `FLY_API_HOSTNAME` (as in Fly's own examples), fly-go's
214
+ `FLY_FLAPS_BASE_URL` or any client's base URL there; `machinesApi()` is the same
215
+ as a fetch handler for your own server. A Machine's image is built once with
216
+ its `init` and `files`, the image's command is its main process, and its
217
+ restart policy is kept. The Fly token is never sent anywhere. Services, mounts,
218
+ checks and other regions answer 400 naming the alternative.
219
+
186
220
  ## Agent frameworks
187
221
 
188
222
  `withruntime/openai-agents` is a sandbox client for the OpenAI Agents SDK's
@@ -248,10 +248,10 @@
248
248
  {
249
249
  "registry": "pypi",
250
250
  "name": "prime-sandboxes",
251
- "version": "0.4.6",
251
+ "version": "0.4.7",
252
252
  "artifacts": {
253
- "prime_sandboxes-0.4.6-py3-none-any.whl": "sha256-e97c6e70c032e0b6d7defdb26d6192a02643ad279af1a4726ebceb35ee89d70c",
254
- "prime_sandboxes-0.4.6.tar.gz": "sha256-23204a465500e9c20639e3043e92d703712d8c80b94d6434bfeb82c787102915"
253
+ "prime_sandboxes-0.4.7-py3-none-any.whl": "sha256-309600da3ee596ce36ed75a7b0956d7883f3e4fc385f026e80c9df887ea1a948",
254
+ "prime_sandboxes-0.4.7.tar.gz": "sha256-72382facabe083b5f9618bfcc057cf1b0211fe103d66cad06d0310567b416adb"
255
255
  }
256
256
  }
257
257
  ]
@@ -0,0 +1,12 @@
1
+ /** `withruntime/agents` in a browser or a worker (package.json's "browser"
2
+ * condition): the client and the deploy's check, without the runtime.yml
3
+ * loader, which reads the file system (agents-file.ts). Node and Bun get
4
+ * index.ts, this and the loader. */
5
+ import { type RuntimeOptions } from "../client.js";
6
+ export type * from "../products/agents.js";
7
+ export type * from "../agents-deploy.js";
8
+ export { AGENT_TEMPLATES, AGENT_USES } from "../products/agents.js";
9
+ import { type AgentsClient } from "../agents-deploy.js";
10
+ export { checkAgentsFile, MANAGED_LABEL, withDeploy } from "../agents-deploy.js";
11
+ /** `runtime.agents` of a client made with `options`, with `deploy`. */
12
+ export declare function agents(options?: RuntimeOptions): AgentsClient;
@@ -0,0 +1,12 @@
1
+ /** `withruntime/agents` in a browser or a worker (package.json's "browser"
2
+ * condition): the client and the deploy's check, without the runtime.yml
3
+ * loader, which reads the file system (agents-file.ts). Node and Bun get
4
+ * index.ts, this and the loader. */
5
+ import { Runtime } from "../client.js";
6
+ export { AGENT_TEMPLATES, AGENT_USES } from "../products/agents.js";
7
+ import { withDeploy } from "../agents-deploy.js";
8
+ export { checkAgentsFile, MANAGED_LABEL, withDeploy } from "../agents-deploy.js";
9
+ /** `runtime.agents` of a client made with `options`, with `deploy`. */
10
+ export function agents(options) {
11
+ return withDeploy(new Runtime(options).agents);
12
+ }
@@ -1,11 +1,11 @@
1
1
  /** `withruntime/agents`: Agents alone. A harness in a sandbox of its own per
2
2
  * session, on your own model key. In a private beta.
3
3
  *
4
- * import { agents } from "withruntime/agents";
4
+ * import { agents, loadAgentsFile } from "withruntime/agents";
5
5
  * const client = agents(); // RUNTIME_API_KEY, or this machine's saved connection
6
- */
7
- import { Runtime, type RuntimeOptions } from "../client.js";
8
- export type * from "../products/agents.js";
9
- export { AGENT_TEMPLATES, AGENT_USES } from "../products/agents.js";
10
- /** `runtime.agents` of a client made with `options`. */
11
- export declare function agents(options?: RuntimeOptions): Runtime["agents"];
6
+ * await client.deploy(loadAgentsFile("runtime.yml"), { dryRun: true }); // what CI runs
7
+ *
8
+ * A browser or worker bundle gets browser.ts instead: all of this but the
9
+ * runtime.yml loader, which reads the file system. */
10
+ export * from "./browser.js";
11
+ export { AGENTS_FILE, loadAgentsFile, parseAgentsFile } from "../agents-file.js";
@@ -1,12 +1,11 @@
1
1
  /** `withruntime/agents`: Agents alone. A harness in a sandbox of its own per
2
2
  * session, on your own model key. In a private beta.
3
3
  *
4
- * import { agents } from "withruntime/agents";
4
+ * import { agents, loadAgentsFile } from "withruntime/agents";
5
5
  * const client = agents(); // RUNTIME_API_KEY, or this machine's saved connection
6
- */
7
- import { Runtime } from "../client.js";
8
- export { AGENT_TEMPLATES, AGENT_USES } from "../products/agents.js";
9
- /** `runtime.agents` of a client made with `options`. */
10
- export function agents(options) {
11
- return new Runtime(options).agents;
12
- }
6
+ * await client.deploy(loadAgentsFile("runtime.yml"), { dryRun: true }); // what CI runs
7
+ *
8
+ * A browser or worker bundle gets browser.ts instead: all of this but the
9
+ * runtime.yml loader, which reads the file system. */
10
+ export * from "./browser.js";
11
+ export { AGENTS_FILE, loadAgentsFile, parseAgentsFile } from "../agents-file.js";
@@ -5,6 +5,6 @@ type Out = {
5
5
  write: (text: string) => void;
6
6
  error: (text: string) => void;
7
7
  };
8
- export declare const AGENT_HELP = "runtime agents <command>\n\n An agent runs a harness (Claude Code, Codex, Gemini CLI, or your own code on\n an agents SDK) in a sandbox of its own for each session, on your model key.\n In a private beta: outside it, each command says how to ask to join.\n\n templates The harnesses and uses to start from\n create <name> (--template <harness> | --command \"<cmd>\") [--use support|team]\n [--instructions <text> | --instructions-file <path>] [--secret NAME]...\n [--env KEY=VALUE]... [--image <image> | --snapshot <id>] [--vcpu n] [--memory n]\n [--max-concurrent n] [--idle-pause n] [--label key=value]...\n Make an agent; prints its id. --secret names an egress\n secret it may use: its model key, of any provider\n ls Your agents\n get <agent> One agent, in full (an id or its name)\n update <agent> [the options of create] A new version: what you give changes, the rest stays\n rm <agent> Delete it, its triggers, and stop its sessions\n start <agent> <words...> [--key <key>] [--follow]\n A session with these words, or the open one with the\n key (such as customer:42); --follow prints its log\n until it ends\n send <session> <words...> Words into a session\n events <session> [--after <seq>] [--follow] A session's log; --follow until it ends\n sessions [--agent <agent>] [--state <state>]...\n Sessions, newest first\n sessions delete <session> Delete an ended session and its log; its history is\n storage, kept until you delete it\n stop <session> Stop a session\n triggers <agent> Its triggers\n triggers add <agent> --kind <slack|github|schedule|webhook> --config '<json>'\n triggers pause <triggerId> --why <words> Refuse its events, saying why; nothing else is held\n triggers resume <triggerId>\n triggers rm <triggerId>\n\n A subscription is for your own team's agents; an agent that serves your\n customers uses an API key.\n\nExamples\n printf %s \"$ANTHROPIC_API_KEY\" | runtime secrets set ANTHROPIC_API_KEY --host api.anthropic.com\n runtime agents create helper --template claude-code --use support --instructions \"Answer briefly.\"\n runtime agents start helper \"How do I reset my password?\" --key customer:42 --follow\n";
8
+ export declare const AGENT_HELP = "runtime agents <command>\n\n An agent runs a harness (Claude Code, Codex, Gemini CLI, or your own code on\n an agents SDK) in a sandbox of its own for each session, on your model key.\n In a private beta: outside it, each command says how to ask to join.\n\n templates The harnesses and uses to start from\n init [name] [--template <harness>] [--use support|team] [--file runtime.yml]\n Write a starter agents: section into runtime.yml\n deploy [--file runtime.yml] [--dry-run] [--prune [--prune-memory]]\n Make your agents match runtime.yml: create, update\n (a new version only when it changed) and set\n triggers; one line per change. --prune deletes the\n agents a deploy made that the file no longer names,\n with their triggers; one holding memory files only\n with --prune-memory too, which deletes them for good\n create <name> (--template <harness> | --command \"<cmd>\") [--use support|team]\n [--instructions <text> | --instructions-file <path>] [--secret NAME]...\n [--env KEY=VALUE]... [--image <image> | --snapshot <id>] [--vcpu n] [--memory n]\n [--max-concurrent n] [--idle-pause n] [--label key=value]...\n Make an agent; prints its id. --secret names an egress\n secret it may use: its model key, of any provider\n ls Your agents\n get <agent> One agent, in full (an id or its name)\n update <agent> [the options of create] A new version: what you give changes, the rest stays\n rm <agent> Delete it, its triggers, and stop its sessions\n start <agent> <words...> [--key <key>] [--follow]\n A session with these words, or the open one with the\n key (such as customer:42); --follow prints its log\n until it ends\n send <session> <words...> Words into a session\n events <session> [--after <seq>] [--follow] A session's log; --follow until it ends\n sessions [--agent <agent>] [--state <state>]...\n Sessions, newest first\n sessions delete <session> Delete an ended session and its log; its history is\n storage, kept until you delete it\n stop <session> Stop a session\n triggers <agent> Its triggers\n triggers add <agent> --kind <slack|github|schedule|webhook> --config '<json>'\n triggers pause <triggerId> --why <words> Refuse its events, saying why; nothing else is held\n triggers resume <triggerId>\n triggers rm <triggerId>\n memory ls <agent> [--scope <key>] [--prefix <path>]\n Its memory files, with their scope (shared or a key)\n memory search <agent> <words...> [--scope <key>] [--limit n]\n Files whose words match, best first\n memory cat <agent> <path> [--scope <key>] A file's text\n memory put <agent> <path> [<file> | - | --content <text>] [--scope <key>]\n Seed or replace a file (from a file, or - for stdin)\n memory rm <agent> <path> [--scope <key>] Delete a file\n Without --scope: the shared memory, which every\n session reads and only a shared agent's write\n\n A subscription is for your own team's agents; an agent that serves your\n customers uses an API key.\n\nExamples\n printf %s \"$ANTHROPIC_API_KEY\" | runtime secrets set ANTHROPIC_API_KEY --host api.anthropic.com\n runtime agents create helper --template claude-code --use support --instructions \"Answer briefly.\"\n runtime agents start helper \"How do I reset my password?\" --key customer:42 --follow\n runtime agents memory put helper faq/refunds.md refunds.md\n runtime agents init --template claude-code && runtime agents deploy --dry-run\n";
9
9
  export declare function agentsCommand(argv: string[], env: NodeJS.ProcessEnv, out: Out, client: () => Promise<Runtime>, kit: CliKit): Promise<number>;
10
10
  export {};