Skip to content

CLI reference

All commands assume a lazybox binary on your PATH — installed via Homebrew (brew tap AntoineToussaint/lazybox && brew trust AntoineToussaint/lazybox && brew install lazybox) or a contributor source build (see the Quickstart). From a source checkout without a built binary on PATH, substitute cargo run -p lazybox-tui-boot --.

An lb binary ships alongside lazybox — a short alias with the identical entrypoint, so every command below works as lb … too.

For day-to-day development, the Makefile wraps the common flows.

Target What it does
make setup One-time online prep: fetch the checksum-verified pinned Zig 0.16.0 to ~/.cache/lazybox/zig/, cache the Ghostty source and the locked Cargo graph, and prebuild the native terminal dependency so later builds run offline
make run Build and run lazybox
make build Build the workspace
make release Build in release mode
make test Run the test suite
make lint Run clippy
make fmt Format the workspace
make dev Run a side-by-side instance against LAZYBOX_HOME=~/.lazybox-dev
make run-fresh Run with state wiped and the setup wizard re-run
make run-test Run the seeded throwaway instance
Command What it does
cargo build Build
cargo run -p lazybox-tui-boot Build and run the TUI binary
cargo nextest run --workspace Run all tests with the repository’s per-test timeout policy
cargo clippy --workspace --all-targets -- -D warnings Lint, warnings as errors

If you build with cargo directly (no make), put Zig 0.16.0 on your PATH first.

Command What it does
lazybox Default — in-process daemon plus TUI
lazybox --help, -h Print the command overview and exit
lazybox --version, -V Print the version and exit
lazybox --fresh Wipe ~/.lazybox/v2/state.db and re-run the setup wizard
lazybox --test Throwaway tempdir repo with one seeded workspace, no GitHub
lazybox --connect [socket] Connect to a remote daemon over a Unix socket; with no path, defaults to ~/.lazybox/run/daemon.sock
lazybox --connect-relay <box-id> --relay <addr> --box-key <hex> Attach a TUI to a box reached through a rendezvous relay (encrypted, ciphertext-only tunnel); see --connect-relay
lazybox --workspace <key> Preselect a workspace on startup
lazybox --session <id> Preselect a session on startup
lazybox scan [ROOTS...] [--depth N] [--hidden] Find existing git clones and linked worktrees without modifying them
lazybox worktree list Report every managed worktree with its size and orphan reasons, plus the on-disk and reclaimable totals
lazybox worktree gc [--force] [--dry-run] Reclaim the safe orphaned worktrees (confirms first unless --force)
lazybox hook-ingest --backend-key <key> Internal: forward an agent lifecycle hook payload (stdin JSON) to the daemon — lazybox injects this into spawned agents’ hook config; not typically run by hand

lazybox scan is a read-only inventory of git checkouts created outside lazybox. Pass one or more roots directly, or configure scan.roots and run it with no positional arguments:

Terminal window
lazybox scan ~/code ~/work --depth 5
lazybox scan --hidden
Option Effect
[ROOTS...] Directories to walk; overrides scan.roots when present
--depth N Maximum levels below each root; overrides scan.max_depth
--hidden Include dot-directories, which are skipped by default

Results are ordered by recent commit activity and identify the branch, path, linked worktrees, dirty checkouts, and any checkout lazybox already tracks. Lazybox’s own managed worktree directory is excluded. The command is read-only — it only reports what it finds. To import a discovered checkout in place, use the in-app import flow: press x i inside lazybox to scan and link a checkout as a workspace without moving it.

Every workspace opens an isolated git worktree. Over time some are left behind — their PR merged, their branch gone, their session removed — and the disk they hold adds up. lazybox worktree inspects and reclaims the worktrees lazybox provisions, without touching checkouts you created yourself.

Terminal window
lazybox worktree list # read-only report
lazybox worktree gc --dry-run # show what gc would reclaim
lazybox worktree gc # reclaim the safe orphans (confirms first)

list prints every managed worktree with its branch, size, and orphan reasons (tagged DIRTY / UNPUSHED / safe-reclaim), then the totals that make a leak visible: bytes on disk, bytes auto-reclaimable across the safe orphans, and bytes held by orphans that need a look first (no backing bare clone, or uncommitted, unpushed, or locked). Bare clones under repos/ are not counted.

Command What it does
lazybox worktree list Read-only inventory of every managed worktree and the disk totals
lazybox worktree gc Reclaim the safe orphaned worktrees, confirming first
lazybox worktree gc --dry-run Report what gc would reclaim without deleting anything
lazybox worktree gc --force Reclaim without the confirmation prompt

gc only ever deletes a worktree that is flagged orphaned and passes the safety gate — it never removes one with uncommitted or unpushed work, a lock, or a live session. Orphans that need review are left for the in-app worktree inspector — open the Settings palette (,) and choose Inspect worktrees…, which can force a per-row reclaim. gc also refuses to run while lazybox is open, since a standalone reap can’t see the daemon’s live sessions; quit lazybox first, or reclaim from the inspector.

Command What it does
lazybox server start Start the daemon in the foreground (blocks until shutdown — run it in tmux, nohup, or a service unit)
lazybox server stop Stop the daemon
lazybox server status Report whether the daemon is running
lazybox server api [addr:port] [--insecure-no-auth] Start the HTTP API gateway

The API gateway refuses to start without an auth decision: either set LAZYBOX_API_TOKEN (clients then send Authorization: Bearer <token>), or pass --insecure-no-auth to explicitly serve unauthenticated (a warning is printed).

The listen address resolves in order: the [addr:port] argument, then the LAZYBOX_API_ADDR environment variable, then the default 127.0.0.1:8787. The gateway has no built-in TLS, so non-loopback binds are refused. Forward the loopback port through an encrypted SSH tunnel for remote use. Direct routable transport requires future encryption and principal-scoped authorization.

POST /v1/commands waits for the command handler to finish before returning {"ok":true,"completed":true}. Provider/domain outcomes still arrive as normal events. Streaming requests are connection- and command-bounded, so a client must reconnect after the documented stream limit instead of growing an unbounded daemon queue. GET /v1/workspaces includes a warnings array when an unreadable row was preserved and omitted from the decoded workspace list.

lazybox serve dials out to a rendezvous relay and holds the connection open, so clients can reach this box’s daemon behind NAT — no inbound ports, DNS, or TLS certs. The relay brokers a client to the box by box-id and forwards opaque Noise ciphertext; it executes nothing. The box proves possession of its persistent Ed25519 identity when registering with a hosted relay.

Terminal window
lazybox serve --relay relay.example.com:9443
Option Effect
--relay <host:port> Relay address to dial (or the LAZYBOX_RELAY env var). Required.
--insecure-no-auth Disable the end-to-end Noise channel for loopback testing. Never use this with an internet-facing relay.
--box-id <id> Override the box-id. By default a persistent id is generated on first run and stored at ~/.lazybox/v2/box-id.
--socket <path> Local daemon socket to bridge to (defaults to the standard daemon socket).

Run the daemon (lazybox server start) alongside serve: each brokered client is bridged to that daemon over the local socket.

The encrypted channel uses a persistent X25519 box key that the connecting client pins with --box-key; the relay only sees ciphertext. The separate Ed25519 box identity is used to prove which subscription a hosted relay should check. --insecure-no-auth bypasses the encrypted channel and is only intended for loopback testing.

The relay itself is a separate deployable (lazybox-relay, in crates/relay) and is not part of the client installers.

Command What it does
lazybox slack init Interactively validate and store bot/app tokens, then join the configured anchor channel
lazybox slack doctor Diagnose token, scope, and connectivity issues
lazybox slack prune Archive stale per-workspace channels (Slack has no channel delete)

The command computes a plan, prints it, and prompts before archiving anything.

Option Effect
--dry-run List what would be archived without touching Slack
--yes, -y Skip the confirmation prompt
--older-than DUR Only archive channels stale for at least this long (e.g. 7d)
--workspace KEY Restrict pruning to one workspace’s channels

Link a box to a lazybox-platform organization with a one-time claim code:

Terminal window
lazybox account claim ABCD1234 --name my-dev-box
lazybox account status
Command or option Effect
account claim <code> POST the one-time code, box public key, and display name to /v1/devices/claim, then cache the returned non-secret organization/plan state
--platform-url <url> Override the platform (LAZYBOX_PLATFORM_URL, cached URL, then https://platform.lazybox.ai)
--name <name> Box display name; defaults to the host name
account status Show the linked organization, plan, and cached entitlement without requiring a platform credential

Claim codes and the box private key are never written to config.yaml. lazybox device mint still succeeds for local/self-hosted use when unlinked, but warns that a hosted relay may refuse the credential.

Attach a TUI to a box reached through a rendezvous relay, rather than a local Unix socket. It connects through the relay, runs the end-to-end Noise handshake pinned to the box’s channel key, and drives the daemon over the encrypted, ciphertext-only tunnel. The box side is served by lazybox serve.

Terminal window
lazybox --connect-relay <box-id> --relay relay.example.com:9443 --box-key <hex>
Option Effect
<box-id> The box to reach (first positional argument). Required.
--relay <host:port> Relay address to dial (or the LAZYBOX_RELAY env var). Required.
--box-key <hex> The box’s channel (X25519) key to pin the encrypted channel to. Required.
--smoke Run a one-shot encrypted round-trip check and exit instead of launching the TUI.

Drive a remote dev-box’s lifecycle from the CLI. The box, its placement, and the socket the connect forward carries come from the sandbox config block; each verb’s flags override what’s set there. The same box is what the sidebar r-spawn brings up lazily.

Command What it does
lazybox sandbox ensure Provision the box (Terraform / provider apply) if it doesn’t exist
lazybox sandbox wake (alias start) Wake a stopped box
lazybox sandbox sleep (alias stop) Stop the box to stop billing compute
lazybox sandbox status Report the box’s current lifecycle state
lazybox sandbox connect Bring up the supervised forward carrying the daemon socket + workload ports
lazybox sandbox rebuild Rebuild the box’s lazybox daemon in place
lazybox sandbox destroy Tear the box down (confirms first unless --yes)

Every verb accepts --worktree <key> to address a specific per-key box (default: the one shared box). Verbs also accept the placement/credential overrides that mirror the config block (--provider, --project, --region, --zone, --template, --timeout-seconds, --terraform-dir, --deployment, --user, --remote-socket, --local-socket, --ports, --service-account-key, --impersonate-service-account, --gcloud-config-dir).

Manage provider login credentials stored by lazybox (independent of gh auth).

Command What it does
lazybox auth login [github] Log in via the GitHub OAuth device flow and store the token
lazybox auth status Show the stored login status
lazybox auth logout [github] Remove the stored token

The provider defaults to github. Linear login is not yet implemented — set LINEAR_API_KEY or install the linear CLI for now.

Manage this box’s pairing identity and the credentials paired devices use to reach it over a relay.

Command What it does
lazybox device box [--format base64] Show this box’s pairing identity (box id + public key)
lazybox device mint --name <name> Mint a credential for a new paired device
lazybox device list List paired devices
lazybox device revoke <id> Revoke one device
lazybox device token <id> Reprint a device’s pairing token

The agent-facing surface over the running daemon: lets a spawned agent (or a script) create a workspace in lazybox itself, not just act on the repo.

Terminal window
lazybox workspace create --name "spike auth" --repo owner/repo --agent claude
Command / option Effect
workspace create Create a taskless pre-PR workspace by sending CreateWorkspace to the daemon
--name <name> Workspace display name. Required (non-empty).
--project <key> Target an existing project by key
--repo <owner/repo> Target a repo (an alternative to --project)
--agent <id> Spawn this agent into the fresh workspace so a live session lands in it
--cwd <path> Directory used to infer the project when neither --project nor --repo is given (default: the process cwd)
--socket <path> Daemon socket to send to (defaults to the standard socket)

The project resolves from --project / --repo, else it is inferred from the checkout at --cwd — so an agent running inside a worktree needs only --name. Unlike fire-and-forget hooks, a failure exits non-zero: the caller asked for a workspace and is told if the daemon was unreachable or the project couldn’t be resolved.

Variable Effect
GH_TOKEN, GITHUB_TOKEN GitHub credential (otherwise gh auth token is used)
LINEAR_API_KEY Credential for the Linear provider
SLACK_BOT_TOKEN Slack bot credential; overrides slack.bot_token
SLACK_APP_TOKEN Slack Socket Mode app credential; overrides slack.app_token
RUST_LOG Log filter, e.g. RUST_LOG=lazybox=debug for verbose logs
LAZYBOX_HOME Overrides every path lazybox writes under ~/.lazybox: state, config, worktrees, runtime dir, tmux socket. Logs are separate — they default to /tmp/lazybox.log (override with ui.log_path)
LAZYBOX_RUNTIME_DIR Overrides just the daemon runtime directory (daemon.sock / daemon.pid); wins over LAZYBOX_HOME’s default <home>/run/
LAZYBOX_API_TOKEN Bearer token for lazybox server api (required unless --insecure-no-auth)
LAZYBOX_API_ADDR Listen address for lazybox server api when no [addr:port] argument is given
LAZYBOX_RELAY Relay address for lazybox serve when no --relay is given
LAZYBOX_PLATFORM_URL Platform base URL used by lazybox account claim and hosted relay configuration
LAZYBOX_PLATFORM_API_KEY Platform bearer used by a configured lazybox-relay entitlement gate
Path Contents
~/.lazybox/v2/state.db Persistent state (read/unread, snooze, sessions)
~/.lazybox/config.yaml Configuration (see Configuration)
~/.lazybox/run/daemon.sock Daemon Unix socket (lazybox server start / --connect)
~/.lazybox/snippets.yaml Global snippet library (client-wide launch-directory override: <launch-dir>/.lazybox/snippets.yaml)
/tmp/lazybox.log Logs (override with ui.log_path)
~/.cache/lazybox/zig/ Pinned Zig toolchain from make setup
~/.cache/lazybox/ghostty/ Pinned Ghostty source and Zig package cache used by offline builds