feat(sandbox): clone, seed and boot a workspace inside the sandbox

Closed
SA
3mo ago
+121-1

Fourth of five. Stacked on #6500 → #6497 → #6489.

Gets a provisioned sandbox from empty to serving a real checkout. This is the walking skeleton working end to end.

Verified against a live sandbox

1. provisioning …      https://70df19f5….preview.bl.run
2. bootstrapping (clone + seed + boot) …
3. querying workspaces over the preview URL …
   status 200
   {"name":"e2e sandbox","branch":"master","worktreePath":"/workspace",
    "worktreeExists":true,"projectName":"Hello-World"}

worktreeExists: true is the load-bearing bit — host-service can see the cloned repo on disk, so this is a workspace the client could actually open.

Sandbox run mode

SUPERSET_HOST_RUN_MODE=local|sandbox. In sandbox mode host-service skips connectRelay, which is what keeps a sandbox out of v2_hosts and off the device picker, and lets it sleep — an outbound relay socket would hold it awake against the provider's wake-on-inbound behaviour.

Default is local, so nothing changes for desktop hosts.

Bootstrap order

clone → migrate → seed → start, and the middle step is not optional: host-service creates host.db's schema on first boot, so it has to run once (with a timeout) before the seed has tables to write into.

Rows are written directly rather than through host-service's own create procedures. Those build a worktree off a base repo, and a sandbox's checkout is the workspace — there's nothing to branch from.

Two things worth reviewing

The clone token never persists. It's interpolated into a single git clone command rather than written to a credential file or exported as an env var, so it doesn't outlive the command. cloneToken is nullable so public repos work without one.

The seed is written as a file, not passed to node -e. The first version shelled it in and the JS came back mangled — Expected unicode escape, with a require('node:crypto') fragment I never wrote. sandbox.fs.write sidesteps shell quoting entirely.

Also: the seed SQL originally referenced a kind column on workspaces that doesn't exist. Caught by reading the schema rather than at runtime.

Verification

typecheck 0 · lint 0 · full provision → clone → seed → boot → query cycle run against production Blaxel, sandbox torn down after.


Summary by cubic

Bootstraps a provisioned sandbox to serve a real workspace and adds a sandbox run mode that disables relay registration. Previously host-service connected to the relay whenever RELAY_URL was set; in sandbox mode it now skips the relay so sandboxes stay off the device picker and can sleep.

  • Adds SUPERSET_HOST_RUN_MODE=local|sandbox (default local) and guards relay connection in host-service.

  • Introduces bootstrapSandbox to clone → migrate → seed → start a workspace: clones into /workspace with an optional short‑lived token embedded only in the git clone command (never persisted), runs host-service once with SUPERSET_HOST_RUN_MODE=sandbox to create the schema, seeds /data/host.db by writing and executing /app/seed.cjs (direct DB inserts), then starts host-service detached on port 4879 and verifies it is listening; exported from packages/trpc/src/lib/blaxel.

  • Set SUPERSET_HOST_RUN_MODE=sandbox for cloud sandboxes; no other changes required.