Skip to content

CLI Reference ​

The bh CLI is intentionally small. This page covers every command and flag.

text
bh create <name> [--provider <name>] [--size <name>] [--region <region>] [--image <image>] [--team <team>] [--no-sync]
bh list
bh destroy <name> [--force]
bh rename <old-name> <new-name>
bh move <name> <team>
bh connect <name>
bh run <name> <cmd...>
bh sync up <name>
bh sync down <name> --force
bh status <name>
bh ssh-config install|refresh|uninstall
bh image ls|create|rm [...]
bh team list|create|switch|status|members|invite|boxes [...]
bh size list|plans|create|rm [...]
bh login [--backend-url <url>] [--no-open]
bh logout
bh config
bh version

Box names use lowercase letters, numbers, and hyphens, start and end with a letter or number, and are at most 63 characters.

bh create ​

bash
bh create <name> [options]

Provisions a VM through the backend, waits until the BoxHaven agent and SSH certificate trust are ready, then syncs the current directory to /opt/boxhaven/project.

OptionDescription
--no-syncSkip the create command's initial project sync
--provider <name>Cloud provider for create (defaults to config or backend default)
--size <name>Built-in or team-owned size shortcut; defaults to small
--region <region>Provider region for create, passed through to the provider verbatim
--image <image>Team image name or provider image ID
--team <team>Team that owns the new box (defaults to your active team)
--ssh-user <user>SSH user for create
--backend-url <url>Remote backend API URL for create

bh size ​

bash
bh size list [--provider <name>] [--region <region>] [--team <team>] [--json]
bh size plans [--provider <name>] [--region <region>] [--team <team>] [--json]
bh size create <name> --provider <name> --plan <slug> [--team <team>]
bh size rm <name> [--team <team>]

Both listing commands default to your configured provider, or the backend default. Add --json to return the selected provider, configured providers, sizes, plans, regions, and prices as JSON. Explicit provider, region, and team filters apply.

list shows the three built-in sizes plus the selected team's shortcuts. plans shows available provider plans, including hardware, GPUs, and the provider price with hourly, daily, and monthly estimates. Team owners and admins can create or remove shortcuts.

bh run ​

bash
bh run <name> [--sync] <cmd...>

Runs a command on the box. Interactive commands — claude, codex, gemini, opencode, copilot, pi, and a bare shell, bash, sh, zsh, or fish — start or attach to the box's managed tmux session. Shells with arguments (bash -lc '...') and all other commands run directly over SSH.

bh run does not mirror the local folder, so work done by agents on the box is never overwritten by a routine command. Pass --sync to mirror the local project first (this overwrites box-side edits).

Without a terminal (for example, when launched by another agent with captured output), managed agent commands start detached and return. With a terminal, they attach; press Ctrl-b, then d to disconnect and use bh connect to reattach. If the managed session already exists, another bh run attaches to that session instead of submitting a new task. Inspect the session output to confirm that the model is working; a successful launch is not task completion.

Starting claude or codex forwards your newest local sessions for the current project, so claude --continue on the box resumes the conversation your laptop was having:

bash
bh run work claude --continue

bh connect ​

bash
bh connect <name>

Attaches to the box's managed tmux session over SSH through the backend relay, starting a shell session if none exists. Disconnecting leaves the session running.

bh ssh-config ​

bash
bh ssh-config install
bh ssh-config refresh
bh ssh-config uninstall

install adds a managed include to ~/.ssh/config, creates a persistent device key under ~/.boxhaven/ssh, and writes bh-<name> aliases for ready boxes. These aliases work with ordinary OpenSSH clients:

bash
ssh bh-work
scp ./notes.txt bh-work:/opt/boxhaven/project/
rsync -az ./fixtures/ bh-work:/opt/boxhaven/project/fixtures/

OpenSSH transparently asks bh for a fresh short-lived certificate before using an alias. Box lifecycle commands keep the generated aliases current; refresh fetches the current box list explicitly. uninstall removes the managed include and generated config while retaining the device key.

bh sync ​

bash
bh sync up <name>
bh sync down <name> --force

sync up pushes the local project to /opt/boxhaven/project, mirroring deletions. sync down pulls the box's project back into the local checkout; it overwrites local files by design, so it requires --force. Sync excludes common dependency/cache directories such as node_modules/, .next/, and .venv/ by default and reads additional rsync-style exclude patterns from .boxhavenignore at the project root. Excluded paths are preserved on the receiver even when sync mirrors deletions. Sync completion reports elapsed time, network bytes, changed bytes, and file counts.

.boxhavenignore ​

Both sync directions read .boxhavenignore from the local project root. The file adds one rsync exclude pattern per line; blank lines and # comments are ignored. .gitignore is not used as a sync filter, and ! does not re-include files. Built-in exclusions cannot be reversed by this file.

For example, to keep local credentials, private data, and generated output out of the box when they are not needed by the task:

text
.env
.env.local
/private-data/
/dist/
*.log

A leading / anchors a pattern to the project root, and a trailing / matches directories. A name such as .env matches at any depth. Excluded files already on the receiver remain there; adding a pattern does not remove a previously uploaded copy. Sync down also mirrors deletions, so use the matching local task directory when retrieving work.

The BoxHaven agent skill bundles this sync guidance for Codex and Claude alongside the box creation, agent, and retrieval workflows.

bh list ​

bash
bh list
bh list --json

Lists your boxes with name, status, team, provider, size, and preview URL. With --json, prints a { "machines": [...] } object containing each box's backend record and the same status label. An empty list is []. Private SSH key and certificate paths are never included. Diagnostics remain on stderr. Status is reported from the machine agent's last heartbeat: creating until bootstrap completes, then online when the agent has been seen within the last five minutes, otherwise offline. An interrupted create with an uncertain provider outcome reports recovery required; destroy that box and create it again instead of attempting to connect.

bh status ​

bash
bh status <name>

Prints the full backend record for one box: provider, public IP, size, region, image, SSH user, preview URL, source and project paths, repo and branch, last sync time, agent last-seen time, and bootstrap state.

bh rename ​

bash
bh rename <old-name> <new-name>

Renames the box record while keeping the underlying provider VM, preview hostname, SSH principal, and agent identity unchanged.

bh move ​

bash
bh move <name> <team>

Moves one of your boxes to another of your teams. See Teams.

bh destroy ​

bash
bh destroy <name> [--force]

Destroys the box and its provider VM. Owners and admins can destroy team boxes; members can only destroy their own (see bh team destroy below for removing a teammate's box). Without --force, the CLI prompts for confirmation in interactive terminals and refuses to continue in noninteractive sessions.

bh image ​

bash
bh image ls [--provider <name>]
bh image create <machine> [--name <name>]
bh image rm <name-or-id> [--provider <name>] [--force]

Images are private to the active team. Names are unique within that team, must start with a letter or number after normalization, and get no added prefix. Ambiguous references that match different images by name and ID return a conflict. Pass an unambiguous name or ID to bh create --image <name-or-id> when creating a box; without --provider image commands use the backend's default provider. bh image rm prompts unless --force is passed. See Images for the full workflow.

bh team ​

bash
bh team list
bh team create <name>
bh team switch <team>
bh team status
bh team members [--team <slug-or-id>]
bh team invite <email> [--role member|admin|owner] [--team <slug-or-id>]
bh team boxes [--team <slug-or-id>]
bh team destroy <box> [--force] [--team <slug-or-id>]

--team is optional when you belong to exactly one team. bh team destroy removes a teammate's box; it requires the owner or admin role and prompts unless --force is passed. See Teams for the team workflow.

bh login ​

bash
bh login [--backend-url <url>] [--no-open]
bh login [--backend-url <url>] --token <token>

First login asks for the backend API URL, with hosted BoxHaven as the Enter-to-accept choice. Later logins reuse the saved URL. Noninteractive first login requires --backend-url or BOXHAVEN_BACKEND_URL.

Without --token, boxhaven opens a browser approval flow and also prints the URL. --no-open prints the browser login URL without trying to open it. --token stores an existing backend session token without calling the login API.

bh logout ​

bash
bh logout

Revokes the backend session and clears the stored token.

bh config ​

bash
bh config

Prints the effective configuration: backend_url, token (redacted), ssh_user, provider, remote_name, command, and setup.

bh version ​

bash
bh version

Prints the CLI version and platform.

All normal commands except help and version periodically refresh the latest public GitHub release in the background. The cached result is reused for 24 hours; a newer release adds one concise notice to standard error, while an offline or failed check produces no warning and never delays the command.

Configuration Files And Environment ​

BoxHaven reads global config from ~/.config/boxhaven/config.toml and project config from .boxhaven.toml:

toml
[remote]
backend_url = "https://api.example.com"
token = "browser-granted-session-token"
ssh_user = "boxhaven"
provider = "hetzner"
setup = [
  "docker compose up -d db"
]

Environment overrides:

  • BOXHAVEN_BACKEND_URL
  • BOXHAVEN_TOKEN
  • GH_TOKEN or GITHUB_TOKEN for GitHub repository access inside remote boxes

bh upgrade ​

bash
bh upgrade
# Select an exact published version:
bh upgrade --version vX.Y.Z

Updates a direct binary installation after verifying its checksum and version. Homebrew users should run brew update && brew upgrade boxhaven; desktop users update the whole app. Existing remote sessions continue running.

bh status NAME also reports the box's runtime protocol and agent fingerprint. Use these when diagnosing an incompatible runtime; existing boxes keep their installed runtime after golden-image updates.

bh preview ​

bash
bh preview work
bh preview work --json

Returns a preview launch URL. Private sandbox previews use a 15-minute BoxHaven team lease; reopen the link through this command after expiry. The desktop requests a fresh link automatically. Provider credentials stay on the backend.

BoxHaven documentation. Source and AGPL-3.0 license text are on GitHub.