{
  "markdown": "# @gannonh/devbox\n\n`@gannonh/devbox` creates an isolated Ubuntu dev container for each Git worktree. Every container has its own network namespace and a desktop you can open in a browser.\n\nThe default image includes Node, Bun, git, `gh`, ripgrep, fd, fzf, tmux, Chromium, and Pi. You can switch the coding agent to Claude Code or Codex. The generated configuration follows the devcontainer specification and also works in Codespaces and Cursor.\n\nDevbox runs containers on your machine by default. It can also run them in a Vercel Sandbox. See [Providers](#providers). Local boxes need `.devcontainer/devcontainer.json`. Run `init` when you want the generated `.devbox/` + `.devcontainer/` default. Vercel boxes need neither.\n\n## Quick start\n\n```bash\nnpx @gannonh/devbox init                         # generate default .devbox/ + .devcontainer/\nnpx @gannonh/devbox my-branch                    # worktree + local container shell\n\nnpx @gannonh/devbox --provider vercel my-branch  # Vercel Sandbox; no init\n```\n\n`init` lists each file it creates. Booting a local box prints its display URL. With OrbStack, the URL has the form `http://<container>.orb.local:6080/vnc.html`. Vercel boxes print an HTTPS URL.\n\nTo run devbox from this repository:\n\n```bash\nnpm run build\nnode dist/cli.js --help\n```\n\n## Requirements\n\n- Node.js 22 or newer\n- OrbStack or another Docker runtime for local boxes. OrbStack provides the `<container>.orb.local` URLs.\n- `@devcontainers/cli` for local boxes, installed with `npm install -g @devcontainers/cli`\n- Git 2.45 or newer for `worktree --relative-paths`\n- An authenticated GitHub CLI, set up with `gh auth login`\n- Host configuration in `~/.pi` if you use Pi\n\n## What devbox changes\n\n- `init` writes `.devbox/` and `.devcontainer/` in the current repository. That pair is the generated local default, not a local-provider requirement. Local boxes need `.devcontainer/devcontainer.json`; they do not need `.devbox/`. If `.devbox/` is missing, `init` overwrites an existing `devcontainer.json`. Vercel boxes need neither. Delete both directories to undo `init`.\n- The local provider runs `docker build` and `docker exec` from the devcontainer configuration. It runs `.devbox/provision.sh` inside the container.\n- Devbox copies the token from `gh auth token` into the box so Git can push. It also copies Pi configuration from `~/.pi`, excluding sessions and the npm cache.\n- Devbox loads project environment variables only when you pass `--env PATH`. It does not copy the dotenv file itself.\n- Local boxes pull base images and install dependencies. Devbox sends no telemetry.\n- The Vercel provider clones the GitHub origin into a Vercel Sandbox and creates HTTPS routes. Anyone with an app route URL can reach that port.\n- Devbox stores provider preferences and metadata under `$XDG_STATE_HOME/devbox`, or `~/.local/state/devbox` when `XDG_STATE_HOME` is unset.\n\nRun `npx @gannonh/devbox <branch> --rm` to remove a box, its worktree, and its branch. Uncommitted work in that worktree may be lost. If you installed the package globally, remove it with `npm uninstall -g @gannonh/devbox`. After removing all boxes, delete the state directory above to clear stored preferences and metadata.\n\n## Commands\n\n```bash\nnpx @gannonh/devbox init                              # generate default .devbox/ + .devcontainer/\nnpx @gannonh/devbox <branch>                          # boot a local box\nnpx @gannonh/devbox <branch> --env PATH               # load dotenv values for this run\nnpx @gannonh/devbox <branch> --attach                 # enter a running box\nnpx @gannonh/devbox <branch> --pause                  # pause it but keep its resources\nnpx @gannonh/devbox <branch> --stop                   # stop the box but keep its resources\nnpx @gannonh/devbox <branch> --rm                     # remove the box, worktree, and branch\nnpx @gannonh/devbox <branch> --url                    # print provider routes\nnpx @gannonh/devbox <branch> --open                   # open the first route\nnpx @gannonh/devbox --list                            # list local boxes\n```\n\n`--attach` reuses the environment stored with the box. Passing `--env` again replaces it. `--pause` pauses a local container and resumes it without restarting the display. On Vercel, pause and stop retain one persistent snapshot, and attach resumes that snapshot without recloning or reinstalling dependencies. `--stop` rejects `--env` because stopping a box transfers no environment values.\n\n## How it works\n\n`npx @gannonh/devbox <branch>` fetches `origin`, creates a worktree from `origin/<default>`, builds the image if needed, starts the container, and opens a shell at `/workspace` as a non-root user. Set `DEVBOX_START_POINT=local` to create the worktree from the local default branch instead.\n\nEach worktree gets a separate container and network namespace, so two worktrees can bind the same port. Xvfb, fluxbox, x11vnc, and noVNC provide the browser desktop. `xdg-open` uses Chromium inside the box, which keeps OAuth consent flows inside the container.\n\n## Coding agents\n\n`.devbox/provision.sh` contains setup blocks for three agents. Pi is enabled by default.\n\n| Agent | Package | Authentication |\n| --- | --- | --- |\n| Pi | `@earendil-works/pi-coding-agent` | copied from host `~/.pi` |\n| Claude Code | `@anthropic-ai/claude-code` | `ANTHROPIC_API_KEY` |\n| Codex | `@openai/codex` | `OPENAI_API_KEY` or `codex --login` |\n\nTo switch agents, enable the matching block in `.devbox/provision.sh`. If you disable Pi, also remove the `~/.pi` mount from `.devcontainer/devcontainer.json`.\n\n## Providers\n\n| Provider | Runs on | Address | Source code |\n| --- | --- | --- | --- |\n| `local` | OrbStack or Docker on your machine | `<container>.orb.local:<port>` with OrbStack | local worktree, including uncommitted files |\n| `vercel` | Vercel Sandbox | Vercel HTTPS routes | authenticated GitHub origin, using pushed commits only |\n\nDevbox remembers the provider for each repository until you pass `--provider` again. It prints a notice before using a remembered Vercel provider.\n\n### Vercel Sandbox\n\nThe Vercel provider runs without a local Docker runtime and makes the display available over HTTPS. Run `init` only if you want `.devbox/post-create.sh` or explicit `forwardPorts`. A missing `devcontainer.json` still exposes noVNC `6080`.\n\n```bash\nnpx @gannonh/devbox --provider vercel my-branch\nnpx @gannonh/devbox my-branch --password\nnpx @gannonh/devbox my-branch --pause\n```\n\nThe Sandbox clones the GitHub origin. Dirty files and unpushed commits remain on your machine.\n\nOn first use, devbox prints the Vercel team and project, then asks for confirmation in a TTY. It checks credentials in this order:\n\n1. `VERCEL_TOKEN`, `VERCEL_TEAM_ID`, and `VERCEL_PROJECT_ID`\n2. `VERCEL_OIDC_TOKEN`\n3. Vercel device authentication scoped by `.vercel/project.json`\n\nThe display URL contains a one-use access code. Opening the complete URL exchanges the code for a session cookie. If the URL is stale or incomplete, run `--password` and enter the printed code in the pairing form.\n\nIn the remote terminal, `Ctrl-C` reaches the foreground process. `Ctrl-]` disconnects without stopping the Sandbox. Each VM session owns one devbox-managed tmux session, so a reconnect reaches the same foreground process while that VM session remains alive. A forced local CLI close has the same reconnect behavior.\n\n`--pause` stops the Vercel Sandbox session and retains its latest snapshot. The next boot or attach restores that snapshot, refreshes GitHub credentials, dotenv values, Pi configuration, display services, and public relays, then opens the terminal without recloning or reinstalling dependencies. The snapshot ID and source session are stored in mode-`0600` host metadata. `--stop` reports the same Vercel snapshot as paused. `--rm` deletes the Sandbox and retained snapshots after verification.\n\nThe terminal shell derives a devbox-owned tmux socket from `sandbox.currentSession().sessionId`. A same-session attach reuses that socket and launches `tmux new-session -A -s devbox`, so user processes survive WebSocket reconnects. A snapshot resume creates a new VM session and a new socket. Processes from the prior VM session end, while runtime setup, display services, and public relays restart. The configured Vercel timeout applies to each new or snapshot-resumed VM session.\n\nVercel Sandbox is a bounded development VM, not continuously available VPS hosting. Use a separately managed VM or Vercel Functions for continuously available services.\n\nAfter checkout, devbox reads `package.json` files without executing them and suggests common application ports such as Vite's `5173`. It also scans npm workspace members. Approved ports become public without recreating the Sandbox. To skip the prompt, pass the ports explicitly:\n\n```bash\nnpx @gannonh/devbox --provider vercel my-branch --expose-ports 5173\n```\n\nOn the boot that creates the sandbox, `--timeout <minutes>` sets the Sandbox timeout (1-1440 minutes; default 60) and `--vcpus <n>` sets the Sandbox vCPUs (1 or an even number up to 32; 2048 MB of memory per vCPU; Vercel defaults to 2). Both are stored per branch like the image, so neither resizes an existing box: changing one later conflicts, and `--rm` plus a fresh boot is the way to change them.\n\n```bash\nnpx @gannonh/devbox --provider vercel my-branch --timeout 90 --vcpus 4\n```\n\nRun your project's ordinary dev command. Devbox publishes each approved port through a small relay inside the sandbox that forwards HTTP and WebSocket traffic to `localhost:<port>`, so a loopback-bound server works without `--host`, and Vite's `server.allowedHosts` check passes without a config change. Until the app starts listening, the URL returns a `502`; it serves the app as soon as the server is up, with no new URL. See [ADR 0007](docs/adrs/0007-relay-backed-public-app-routes.md).\n\nSee the [Vercel provider reference](docs/reference/vercel-provider.md) for command details, configuration order, and recovery behavior.\n\n<details>\n<summary>Runtime image pinning</summary>\n\nVercel Sandboxes boot from an OCI image. Published packages contain the digest of the image that passed their smoke tests. Repository checkouts use the `nightly` channel instead. The source tree contains no digest because `scripts/vercel/emit-image-pin.mjs` writes it into `dist/` during publication.\n\nSet `DEVBOX_VERCEL_IMAGE` to a fully qualified digest to test a locally built image. Published releases reject this override. See the [image supply chain runbook](docs/runbooks/vercel-image-supply-chain.md) for channels, rollback, and cleanup.\n\n</details>\n\n## Maintainer CI and releases\n\n<details>\n<summary>Workflows, secrets, and credentialed checks</summary>\n\nUnit tests cover provider logic without live credentials. Vercel checks run in scheduled or manually dispatched workflows.\n\n| Workflow | Trigger | Checks |\n| --- | --- | --- |\n| CI | every push and pull request | lint, types, build, and tests without credentials |\n| Nightly | scheduled on `main`, or manually dispatched at any ref | image build, publisher and consumer smoke tests, and prerelease publication |\n| Release | manual run from the default branch | stable tag promotion after terminal smoke tests, UAT, and the five-run benchmark |\n\nPull requests receive no cloud credentials. Labels do not authorize credentialed runs. To test a branch against Vercel, dispatch Nightly for that ref. Pass `publish` to install the result as `npx @gannonh/devbox@dev-<branch>`. Credentialed runs require the repository owner and the protected `vercel-provider-smoke` environment.\n\nRepository secrets include the Vercel consumer credential triad, the GitHub fixture token and repository details, and the expected fixture file and content. The workflow maps the Vercel values to `VERCEL_TOKEN`, `VERCEL_TEAM_ID`, and `VERCEL_PROJECT_ID` for the smoke process.\n\nThe smoke run checks the exact Git revision, terminal signal and detach behavior, image identity, and resource cleanup. Evidence contains one-way fingerprints rather than fixture values, tokens, or Vercel IDs. A final redaction step runs before upload, including after failures. If cleanup finds ambiguous duplicate resources, follow the manual procedure in the supply chain runbook instead of running `--rm`.\n\nSee the [Vercel provider convergence issue](https://github.com/gannonh/devbox/issues/7) and the [documentation index](docs/index.md) for design history and maintainer procedures.\n\n</details>\n\n## Status\n\nStable releases publish to the npm `latest` tag after their nightly build passes the release checks above.\n\n## License\n\n[MIT](LICENSE)\n",
  "bytes": 12610,
  "sha": "da2f6ededd6a79621881edf1ba168fe539077ae7851d9affd293ca77362c40ef",
  "repo_slug": "gannonh/devbox",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/okf_gannonh_devbox_docs_index_md_628e7a3e/readme"
}