Skip to content

feat(sandbox): support extra host folder mounts on a sandbox - #233

Merged
quickbeard merged 1 commit into
mainfrom
sandbox-mounts-core
Aug 14, 2026
Merged

quickbeard merged 1 commit into
mainfrom
sandbox-mounts-core

Conversation

@quickbeard

Copy link
Copy Markdown
Owner

First of three stacked PRs adding "mount more folders into an existing sandbox" (core → image → desktop/app UI).

What

  • SandboxConfig.mounts?: { path }[] — extra host folders shared into the guest alongside projectDir; shaped as objects so a readOnly flag can be added later without migrating persisted records.
  • New src/mounts.ts: guest-name derivation (/mnt/<sanitized-basename>, in-order dedup, capped so mnt-<name> virtiofs tags stay under the 36-byte limit) and pure validateMountPaths (duplicates — case-insensitive for Windows-shaped paths, nesting in either direction vs the project dir and other mounts, UNC rejection) with discriminated error codes for i18n mapping downstream.
  • controller.updateSandboxMounts(id, mounts) (whole-list replace): hot path via the new optional SandboxProvider.applyMounts — implemented by WSL only, where it is pure wslpath translation and runs before persisting so a bad path never lands in the stored config; restart path everywhere else (persist first so the new set survives a failed restart, restart only a live sandbox). Stopped/failed sandboxes persist for their next start; an update racing a create/reset is rejected rather than aborting the job. No new job kind — restart busy-ness already shows as runtime.kind === "starting".
  • Resolved { path, guestPath }[] travels on RunningSandbox → the ready runtime, so the existing {type:"state"} event is the entire hot-apply signal — no new event kind.
  • Providers: vz appends one virtiofs share per mount and rewrites mounts.json into the config share every start (empty list included, so a stale list from the previous boot cannot survive; the guest side lands in the next PR); bwrap emits --bind pairs and adds mnt to MANAGED_ROOTFS_ENTRIES so mount points are creatable on its tmpfs root; WSL translates via wslpath with zero guest work. Extra mounts whose folder vanished are skipped at start instead of failing it — only projectDir stays fatal.

Tests

cd packages/codev-sandbox && bun test && bun typecheck — 122 pass. New: mounts.test.ts (names/dedup/tag cap/validation matrix), controller coverage (persist-without-start, restart-to-apply, hot apply patches the ready runtime without restarting, failed hot apply persists nothing, mid-job rejection), vz share/manifest/skip assertions, bwrap /mnt bind ordering + managed-entry, WSL skip-at-start + applyMounts throw.

🤖 Generated with Claude Code

SandboxConfig gains an optional mounts list of extra host folders shared
into the guest alongside projectDir. Guest paths are derived at start
(/mnt/<basename> on vz/bwrap, wslpath output on WSL) and travel on
RunningSandbox and the ready runtime so the app always sees what the
guest actually mounted.

The controller's new updateSandboxMounts replaces the list: hot via the
new optional provider applyMounts (WSL only — the distro's namespace is
shared and drives are automounted, so it is pure path translation and
doubles as the validation gate before persisting), otherwise by
restarting a live sandbox. Stopped or failed sandboxes persist the
change for their next start; updates racing a create/reset are rejected
rather than aborting the job.

Provider side: vz appends one virtiofs share per mount and rewrites
mounts.json into the config share every start (empty list included, so
a stale list from the previous boot cannot survive); bwrap adds --bind
pairs and marks mnt as a managed rootfs entry so the mount points are
creatable on its tmpfs root; extra mounts whose folder vanished are
skipped at start instead of failing it — only projectDir stays fatal.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@quickbeard
quickbeard force-pushed the sandbox-mounts-core branch from 40e78e1 to 027741a Compare August 14, 2026 06:30
@quickbeard
quickbeard merged commit 1ffc550 into main Aug 14, 2026
0 of 5 checks passed
@quickbeard
quickbeard deleted the sandbox-mounts-core branch August 14, 2026 06:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant