← CloudflareCONTENT HISTORY

Update to Cloudflare

Snapshot Oct 1, 2026 · 00:02 UTC · version 1.0.1

Collection source: not recorded for this historical snapshot.

WHAT CHANGED · RULE-BASED ANALYSIS

First saved snapshot

No earlier snapshot is available to establish a change.

Compare saved observations

Download comparison JSON
Full technical diff · 0 changed fields
Full snapshot data
{
  "description": "Use when porting a Cloudflare Sandbox app from stable @cloudflare/sandbox to @cloudflare/sandbox@next (Sandbox SDK 1.0 preview), or when the user asks to migrate or upgrade to Sandbox 1.0 / @next. Not for day-to-day stable work (sandbox-stable) or new @next apps (sandbox-next).",
  "included_files": [],
  "name": "sandbox-migrate-to-next",
  "skill_md_contents": "---\nname: sandbox-migrate-to-next\ndescription: Use when porting a Cloudflare Sandbox app from stable @cloudflare/sandbox to @cloudflare/sandbox@next (Sandbox SDK 1.0 preview), or when the user asks to migrate or upgrade to Sandbox 1.0 / @next. Not for day-to-day stable work (sandbox-stable) or new @next apps (sandbox-next).\n---\n\n# Migrate stable → Sandbox SDK 1.0 preview (`@next`)\n\n**Perform** the port. Follow the steps in order. Depth lives in docs—fetch the linked page when a step needs detail.\n\nHuman guide: [Migrate](https://developers.cloudflare.com/sandbox/1-0-preview/migrate/) · [1.0 preview](https://developers.cloudflare.com/sandbox/1-0-preview/)\n\n**New projects** should start on `@next` (**`sandbox-next`**), not this skill. **Day-to-day stable work** → **`sandbox-stable`**. Deprecated-API cleanup **without** moving to `@next` → [2026 deprecation guide](https://developers.cloudflare.com/sandbox/guides/2026-deprecation/) first if needed.\n\nExisting apps should migrate **when you can**, so you are ready when 1.0 becomes the stable release. Do **not** force production cutover without the user agreeing.\n\n**Prefer installed `@next` types and the migrate doc over memory.**\n\n## Workflow\n\n1. **Review** hard rules and the replacement map  \n2. **Audit** the codebase; list hits and target shapes  \n3. **Clarify** with the user (cutover, bridge, Python image, unclear sites)  \n4. **Upgrade** package, image, and code  \n5. **Validate**  \n\nStop after any step that needs a user decision.\n\n## Hard rules\n\n- Worker package and container image must be the **same** `@next` line.  \n- Production cutover uses **immediate** container rollout. Stable and `@next` control protocols are incompatible both ways; gradual rollout leaves a broken mixed window. In-flight container work can stop.  \n- After cutover, `await sandbox.exec(...)` means process **started**, not command **finished**.  \n- Argv is as-is (no implicit shell). Shell syntax needs an explicit shell binary.  \n- Process handles have **no stdin** → terminals for interactive input.  \n- Observation `timeout` / `AbortSignal` cancel the **wait only**, not the process.  \n- No single retry loop for every error.  \n- Do not invent APIs (`gitCheckout` on core, process stdin, string-exec completion helper).  \n- Self-deployed bridge stays on **stable** (not part of the preview line yet).  \n\n## Replacement map\n\n| Stable | `@next` |\n| ------ | ------- |\n| `SANDBOX_TRANSPORT` / `transport` / `setTransport` | Remove — RPC only |\n| `await sandbox.exec(\"cmd\")` → buffered result | `await sandbox.exec(argv)` → handle, then `output` / waits |\n| `execStream` / `startProcess` | Same handle: `logs`, `waitFor*`, `kill` |\n| Default / named sessions | Gone — `cwd`/`env` per launch, or one shell script |\n| `sandbox.terminal(request)` / session terminal | `createTerminal` + `terminal.connect(request)` |\n| xterm `sessionId` | `terminalId` |\n| Interpreter methods on `Sandbox` | `withInterpreter` → `sandbox.interpreter.*` |\n| `gitCheckout` | argv `git` via `exec` |\n| String kill signals | Numeric only |\n| Files, mounts, backups, ports, tunnels, `proxyToSandbox` | Mostly unchanged (ignore session/transport bits on stable pages) |\n\nDepth: [Migrate](https://developers.cloudflare.com/sandbox/1-0-preview/migrate/) · after port, day-to-day → **`sandbox-next`**\n\n## Audit\n\n```sh\nrg 'SANDBOX_TRANSPORT|transport:|setTransport|enableDefaultSession|createSession|getSession|deleteSession|execStream\\(|startProcess\\(|killProcess\\(|sandbox\\.terminal\\(|sessionId|gitCheckout\\(|SandboxTransport|ExecutionSession'\n```\n\nAlso: string `exec(`, `cd` then a later `exec`, bare `createCodeContext` / `runCode` on `Sandbox`.\n\n## Clarify (ask when needed)\n\n- OK to cut production with `--containers-rollout=immediate` (live processes/terminals/streams may stop)?  \n- Self-deployed bridge? Leave on stable.  \n- Python interpreter → **`-python`** image variant?  \n- Call sites not covered by the map?  \n\n## Upgrade\n\n### Package and image\n\n```sh\nnpm install @cloudflare/sandbox@next\n```\n\n```dockerfile\nFROM cloudflare/sandbox:next\n# Python: cloudflare/sandbox:next-python\n```\n\nSame prerelease tag on Worker and image when not on floating `next`.\n\n### Code by area\n\nApply replacements from the map. For each area, implement from the doc—not from stable habits:\n\n| Area | Doc |\n| ---- | --- |\n| Commands / handles / waits | [Processes](https://developers.cloudflare.com/sandbox/1-0-preview/processes/) · [Processes API](https://developers.cloudflare.com/sandbox/1-0-preview/api/processes/) |\n| `cwd` / `env` / secrets | [Environment](https://developers.cloudflare.com/sandbox/1-0-preview/environment/) · [Outbound traffic](https://developers.cloudflare.com/sandbox/guides/outbound-traffic/) |\n| Drop sessions | [Migrate](https://developers.cloudflare.com/sandbox/1-0-preview/migrate/) · [Lifecycle](https://developers.cloudflare.com/sandbox/1-0-preview/lifecycle/) |\n| Terminals | [Terminals](https://developers.cloudflare.com/sandbox/1-0-preview/terminals/) |\n| Interpreter | [Interpreter](https://developers.cloudflare.com/sandbox/1-0-preview/interpreter/) |\n| Errors | [Errors](https://developers.cloudflare.com/sandbox/1-0-preview/errors/) |\n| Durable job across requests | [Process execution — lifetime / durability](https://developers.cloudflare.com/sandbox/1-0-preview/processes/) |\n\n**Commands (shape):**\n\n```ts\n// Before (stable)\nconst result = await sandbox.exec(\"npm test\");\n\n// After (@next)\nconst process = await sandbox.exec([\"/bin/bash\", \"-lc\", \"npm test\"]);\nconst result = await process.output({ encoding: \"utf8\" });\n```\n\n```ts\nconst server = await sandbox.exec([\"/bin/bash\", \"-lc\", \"npm run dev\"], {\n  cwd: \"/workspace/app\",\n});\nawait server.waitForPort(3000, { timeout: 60_000 });\nawait server.kill(); // numeric; default 15\n```\n\n**Terminals (shape):**\n\n```ts\nconst terminal = await sandbox.createTerminal({ command: [\"bash\"], cwd: \"/workspace\" });\nconst t = await sandbox.getTerminal(terminal.id);\nif (!t) return new Response(\"terminal gone\", { status: 410 });\nreturn t.connect(request, { cursor, cols, rows });\n```\n\n**Interpreter (shape):**\n\n```ts\nimport { Sandbox as BaseSandbox } from \"@cloudflare/sandbox\";\nimport { withInterpreter } from \"@cloudflare/sandbox/interpreter\";\n\nexport class Sandbox extends BaseSandbox<Env> {\n  interpreter = withInterpreter(this);\n}\n```\n\n**Git (shape):**\n\n```ts\nconst clone = await sandbox.exec(\n  [\"git\", \"clone\", \"--depth\", \"1\", \"--\", repoUrl, \"/workspace/repo\"],\n  { cwd: \"/workspace\" },\n);\nconst result = await clone.output({ encoding: \"utf8\" });\n```\n\nDelete transport settings entirely. Remove session APIs. Isolate users with **separate sandbox IDs**.\n\n### Deploy cutover\n\nStaging/branch first. Production is **one** deploy of matching Worker + image:\n\n```sh\nnpx wrangler deploy --containers-rollout=immediate\n```\n\nLeave `rollout_active_grace_period` at default `0` (or set `0` if raised). After cutover, pre-deploy process/terminal IDs are invalid. Details: [Migrate](https://developers.cloudflare.com/sandbox/1-0-preview/migrate/) · [Container rollouts](https://developers.cloudflare.com/containers/platform-details/rollouts/)\n\n## Validate\n\n1. Lockfile + Dockerfile on the same `@next` line  \n2. Typecheck against `@next`  \n3. Smoke argv `exec` + `output({ encoding: \"utf8\" })`  \n4. Smoke long process / terminal / interpreter if used  \n5. Errors distinguished: unavailable / interrupted-RPC / stale / local wait  \n6. No live secrets in sandbox env  \n7. Grep again for removed APIs  \n8. Production used `--containers-rollout=immediate`  \n\nThen day-to-day work uses **`sandbox-next`**.\n\n## Red flags — stop and fix\n\n- Mixing `@next` Worker with stable image (or reverse)  \n- Gradual container rollout for this cutover  \n- Treating `await exec` as command completion  \n- Assuming `cd` / exports persist across `exec` calls  \n- One retry wrapper for every error  \n- Inventing `gitCheckout`, process stdin, or undocumented APIs  \n- Keeping pre-cutover process/terminal IDs after deploy  \n- Forcing production cutover without user agreement  \n- Putting live secrets in `setEnvVars` / launch `env`  \n"
}

SHA-256 of public snapshot: de95f9e72f5c0423912705638af7341277decce0cec2ccd9786e006b86dacf14