
Lifecycle
Templates
Templates are baked via
bun run bake:e2b (see scripts/bake-e2b-templates.ts). Verify a baked template with bun run verify:e2b. Source templates are pulled from GitHub via git clone --depth 1 — never bundled into the server image.
Dev server start
PreviewManager.startDevServer() runs in the orchestrator before the agent’s first turn:
- Patch
vite.config.tsso HMR works through the Cloudflare proxy. - Run
npm installifnode_modulesis stale. - Spawn the dev command in the background.
- Poll for the port (
detectPort, preferred8080). - Construct the branded URL —
https://<shortId>.vibelyagent.com. - Emit
preview_urlover SSE/WS so the iframe mounts before the agent has done anything.
bash tool short-circuits any npm run dev the model tries, because issuing it again would steal the port and break HMR.
Preview proxy
The<shortId>.vibelyagent.com URL is served by cloudflare/worker.js, which:
- Proxies the request to the sandbox over its private hostname.
- Strips
X-Frame-OptionsandContent-Security-Policy: frame-ancestorsso the preview can be embedded in the Vibely app’s iframe. - Forwards WebSocket upgrades for HMR.
File persistence
Files written throughwrite or edit are mirrored to Supabase (vibe_files) per turn. loopResult.writtenFiles is the canonical source per-turn — only files the loop saw written are saved, which is fast. As a fallback for bash-only turns (e.g. npm install produced new files), getAllFiles(sandbox) does a full tree scan. Full scans are slow (2–10 s) so they only run when the incremental list is empty.
This is the contract that lets a paused sandbox resume cleanly: every file that matters is in Postgres, not just on the sandbox disk.
404 auto-recovery
The sandbox provider occasionally returns404 for a sandbox we know exists — usually during snapshot rotation or metadata replication. The tool registry handles this transparently:
Sandbox pool
A small pool of pre-warmed sandboxes can be kept ready so new sessions don’t pay the cold-start cost. The switch isSANDBOX_POOL_TARGET, which defaults to 0 — pooling is off unless you ask for it, because an idle sandbox bills continuously. (SANDBOX_POOL_ENABLED is on by default and only gates the feature; the target is what decides whether anything is warmed.) With pooling off, the first request to a new project pays ~5–15 s for sandbox spawn + template hydration; subsequent requests for the same project resume the existing sandbox in <1 s.
Self-hosted sandboxes
SetE2B_DOMAIN=https://your-control-plane to point at your own sandbox control plane instead of the managed cloud. Leave it empty to use the managed one. Every other sandbox env var works the same way against a self-hosted control plane.