Releases: cloudflare/sandbox-sdk
@cloudflare/[email protected]
Patch Changes
-
#446
bbaba54Thanks @whoiskatrin! - Fix heredoc commands (e.g.cat << 'EOF') hanging permanently and making the session unusable for subsequent commands. -
#447
4088435Thanks @ghostwriternr! - Fix three reliability issues: OpenCode readiness probe returning healthy before the binary is ready, file watch race condition where stale watchers could linger after cancellation, and SSE stream handler registering output listeners after replaying buffered logs — causing intermittentwaitForLogtimeouts on HTTP transport.
@cloudflare/[email protected]
Patch Changes
- #427
04b4ccfThanks @ghostwriternr! - Fix local development crash loops after Docker restarts or idle timeouts. The Sandbox now detects stale container state and automatically recovers.
@cloudflare/[email protected]
Patch Changes
-
#402
eb23055Thanks @scuffi! - ImprovereadFile()andreadFileStream()performance by using native syscall file reads instead of shell-based reads.
This increases read transfer speeds and unblocks the max throughput from file streaming.Improving file size handling: calls to
readFile()now return a413: File too large errorif the target file exceeds32 MiB. Previously such files would trigger a generic error; we're now explicit about the limitation and recommend usingreadFileStreamfor larger files. -
#421
1244660Thanks @scuffi! - PatchproxyToSandboxto pass redirect responses to the caller, instead of following them -
#430
364e366Thanks @scuffi! - PatchreadFileto strip MIME type parameters, e.g.text/plain;charset=utf-8->text/plain
@cloudflare/[email protected]
Patch Changes
-
#417
9cbebd8Thanks @whoiskatrin! - Stream backup archive uploads to presigned R2 URLs withcurl -Tinstead of--data-binary.
This avoids large in-memory payload allocation and improves reliability for multi-GB backups. -
#419
35f7d65Thanks @whoiskatrin! - Fix flaky OpenCode E2E test by checking health endpoint readinessChanged
waitForPortto verify/global/healthreturns HTTP 200 instead of just checking if the server accepts connections at/. This ensures the OpenCode server is fully initialized beforecreateOpencodeServerreturns, preventing 500 errors when tests immediately call the health endpoint. -
#418
6994598Thanks @ghostwriternr! - Improve error message when backup upload verification fails due to a local/remote R2 mismatch. When usingwrangler dev, presigned URLs upload to real R2 while theBACKUP_BUCKETbinding defaults to local storage. The error now suggests adding"remote": trueto the R2 binding inwrangler.jsonc. -
#404
c602785Thanks @whoiskatrin! - ImprovewriteFile()performance by using native container file writes instead of shell-based write pipelines.
This reduces write latency for both UTF-8 and base64 payloads while preserving existing encoding behavior. -
#412
5abdb55Thanks @whoiskatrin! - Fix file writes without an explicitencodingso requests use default write options instead of sendingencoding: undefined.
@cloudflare/[email protected]
Patch Changes
-
#396
76284f0Thanks @whoiskatrin! - Add backup and restore API for directory snapshots.createBackup()archives a directory as a compressed squashfs image and uploads it to R2.
restoreBackup()downloads and mounts the archive with copy-on-write semantics via FUSE overlay.Requires R2 presigned URL credentials: set
R2_ACCESS_KEY_ID,R2_SECRET_ACCESS_KEY,
CLOUDFLARE_ACCOUNT_ID, andBACKUP_BUCKET_NAMEas environment variables alongside the
BACKUP_BUCKETR2 binding. Archives transfer directly between the container and R2
at ~24 MB/s upload / ~93 MB/s download. -
#403
bbfc579Thanks @whoiskatrin! - AddproxyToOpencodeServer()to proxy requests directly to a running OpenCode server without web UI redirect behavior. Use this helper for headless API and CLI traffic where raw request forwarding is preferred.
@cloudflare/[email protected]
Patch Changes
- #393
76903adThanks @AshishKumar4! - Fixes the bug where SDK's expected provider string 'cloudflareAIGateway' (camelCase) isn't recognised by opencode, and thus the opencode example fails to work with ai gateway.Also improved the example code with instructions for ai gateway via unified billing
@cloudflare/[email protected]
Patch Changes
-
#366
fa1713eThanks @kevoconnell! - Update the OpenCode integration to use the latest @opencode-ai/sdk (v2) client API. Install @opencode-ai/sdk@^1.1.40 to use OpenCode features. -
#390
1817eafThanks @ghostwriternr! - Fixfetch()losing itsthisbinding when called on the proxy returned bygetSandbox(). This caused preview URL WebSocket routing to fail at runtime.
@cloudflare/[email protected]
Patch Changes
-
#383
0a4592fThanks @ghostwriternr! - Add Alpine-based musl image variant published ascloudflare/sandbox:VERSION-musl.A lightweight (51 MB) functional sandbox for Alpine and musl-based containers. Supports all core SDK methods (
exec, file operations, git, port exposure, bucket mounting). Does not include Python or Node.js runtimes — add them withapk addto enablerunCode().As a base image:
FROM docker.io/cloudflare/sandbox:0.7.2-muslOr copy the binary into your own Alpine image:
COPY --from=docker.io/cloudflare/sandbox:0.7.2-musl /container-server/sandbox /sandbox -
#377
d83642eThanks @ghostwriternr! - Allow port 8787 inexposePort(). It was incorrectly blocked.
@cloudflare/[email protected]
Patch Changes
-
#310
3c03587Thanks @whoiskatrin! - Add terminal support for browser-based terminal UIs.Build interactive terminal experiences by connecting xterm.js to container PTYs via WebSocket. Terminals reconnect automatically with output history preserved, and each session gets its own isolated terminal.
// Proxy WebSocket to container terminal return sandbox.terminal(request, { cols: 80, rows: 24 }); // Multiple isolated terminals in the same sandbox const session = await sandbox.getSession('dev'); return session.terminal(request);
Also exports
@cloudflare/sandbox/xtermwith aSandboxAddonfor xterm.js — handles WebSocket connection, reconnection with exponential backoff, and terminal resize forwarding.import { SandboxAddon } from '@cloudflare/sandbox/xterm'; const addon = new SandboxAddon({ getWebSocketUrl: ({ sandboxId, origin }) => `${origin}/ws/terminal?id=${sandboxId}` }); terminal.loadAddon(addon); addon.connect({ sandboxId: 'my-sandbox' });
@cloudflare/[email protected]
Minor Changes
-
#329
fc1a8eaThanks @mikenomitch! - Add support for custom tokens inexposePort()to enable stable preview URLs across deployments.You can now pass a custom token when exposing ports to maintain consistent preview URLs between container restarts and deployments. This is useful for sharing URLs with users or maintaining stable references in production environments.
// With custom token - URL stays the same across restarts const { url } = await sandbox.exposePort(8080, { hostname: 'example.com', token: 'my_token_v1' // 1-16 chars: a-z, 0-9, _ }); // url: https://8080-sandbox-id-my-token-v1.example.com // Without token - generates random 16-char token (existing behavior) const { url } = await sandbox.exposePort(8080, { hostname: 'example.com' }); // url: https://8080-sandbox-id-abc123random4567.example.com
Custom tokens must be 1-16 characters containing only lowercase letters, numbers, and underscores.
Breaking change: Tokens can no longer contain hyphens. Existing preview URLs with hyphenated tokens (including some auto-generated ones) will stop working until the port is re-exposed.
Patch Changes
-
#347
efdd0d7Thanks @roerohan! - Add Cloudflare AI Gateway support to OpenCode integration. Users can now route AI provider requests through Cloudflare AI Gateway for monitoring, caching, and rate limiting by adding acloudflareAIGatewayprovider configuration withaccountId,gatewayId, and optionalapiToken. -
#342
7da85c0Thanks @ghostwriternr! - Handle undefined environment variables as "unset" in setEnvVarsEnvironment variable APIs now properly handle undefined values:
- String values are exported as before
- undefined/null values now unset the variable (runs
unset VAR)
This enables idiomatic JavaScript patterns:
await sandbox.setEnvVars({ API_KEY: 'new-key', OLD_SECRET: undefined // unsets OLD_SECRET });
Before:
sandbox.setEnvVars({ KEY: undefined })threw a runtime error
After:sandbox.setEnvVars({ KEY: undefined })runsunset KEYTypeScript types now honestly accept
Record<string, string | undefined>.