Read this when:
- you are new to Crabbox and want a working
crabbox runin about ten minutes; - you are evaluating Crabbox for a repo and want to see the shape of a real workflow;
- you want a reference for what a typical onboarding looks like end to end.
This is a cookbook, not a reference. It walks through one repo from install to
crabbox run -- pnpm test. Each step links to deeper docs when you want more.
If you are still deciding whether Crabbox fits your workflow, start with
What Crabbox is.
brew install openclaw/tap/crabboxVerify the install:
crabbox --version
crabbox doctorcrabbox doctor prints one line per check. Local tool checks (git, ssh,
ssh-keygen, rsync) should report ok. It is fine if the broker and provider
checks fail for now - we configure those next.
If you do not use Homebrew, GitHub Releases ship signed archives for macOS, Linux, and Windows. Download the matching archive from https://github.com/openclaw/crabbox/releases.
crabbox login --url https://broker.example.comlogin opens a browser to the GitHub OAuth flow (pass --no-browser to print
the URL for a browser on the same device). The broker exchanges the OAuth code,
verifies your GitHub org membership, and redirects a one-use confirmation to the
CLI's loopback listener before writing the signed token to your user config:
logged in broker=https://broker.example.com provider=hetzner user=alice@example.com org=example-org config=/Users/alice/.config/crabbox/config.yaml
From then on, every crabbox command authenticates automatically. Check your
identity any time:
crabbox whoamiuser=alice@example.com org=example-org auth=user broker=https://broker.example.com
Broker access is deployment-specific. Use the coordinator URL and GitHub org/team allowlist from your team. A completed GitHub OAuth flow can still be rejected when your account is outside that allowlist.
For a personal or third-party installation, pick one path:
- Direct-provider mode - bring your own local cloud credentials when you want a quick private test lane and can accept local cleanup and state instead of broker usage history and shared spend caps.
- Self-hosted coordinator - deploy on Cloudflare Workers or run the portable
Node.js/PostgreSQL service when you want coordinator-owned provider
credentials, active-lease limits, monthly spend caps,
crabbox usage, durable cleanup, and a shared team endpoint. - Request access - only when the broker operator has a defined onboarding path for your org. A team endpoint is not automatically an open broker.
Direct-provider mode skips login entirely:
crabbox doctor --provider hetzner
crabbox run --provider hetzner -- pnpm testSelf-hosting starts by choosing a runtime:
- Cloudflare Workers - Durable Object state, alarms, scheduled cleanup, and optional Cloudflare Access.
- Node.js/PostgreSQL - an ordinary HTTP/WebSocket service, PostgreSQL 13+ state, pg-boss maintenance jobs, and one always-on replica. Treat it as the initial portable runtime and complete the deployment proof before production cutover.
Both use the same provider secrets, auth config, budget limits, API, and portal. See Infrastructure. Browser login needs a GitHub OAuth app and at least one allowed org/team; shared-token automation does not.
For CI environments that cannot open a browser, use shared-token auth:
printf '%s' "$TOKEN" | crabbox login \
--url https://broker.example.com \
--provider aws \
--token-stdinSee Auth and admin for the full identity model.
Inside the repo:
crabbox initinit writes three files (override any path with --config, --workflow, or
--skill; pass --force to overwrite existing files):
.crabbox.yaml repo defaults (profile, class, sync, env)
.github/workflows/crabbox.yml Actions hydration workflow (optional)
.agents/skills/crabbox/SKILL.md agent-facing skill instructions
The generated .crabbox.yaml ships sensible defaults. Adjust the parts that
matter for your repo:
profile: a name for this lane (the template uses<repo>-check);class:standard,fast,large, orbeast(the template usesbeast);sync.exclude: directories that should never be sent to the runner;sync.include: an optional root-relative whitelist — when set, only these paths are synced (after excludes), so you can ship a few paths out of a large repo instead of blacklisting everything else;env.allow: environment variables the remote command is allowed to see.
Pass --detect to scan the repo for test commands and write a jobs.detected
entry you can run with crabbox job run detected.
Then preview what a sync would send:
crabbox sync-plansync-plan prints the file count, total bytes, and the biggest files in the
manifest. If it shows surprises (a dist/ folder, a forgotten .cache/, a
multi-gigabyte asset), tighten sync.exclude and re-run. The first sync to a
fresh runner is bound by this size.
crabbox warmupwarmup acquires a lease, provisions the runner, waits for SSH and tooling to
come up, keeps the lease (--keep, on by default), and prints two lines:
leased cbx_abcdef123456 slug=swift-crab provider=hetzner server=cx... type=ccx... ip=203.0.113.10 idle_timeout=30m0s expires=2026-05-29T17:30:00Z
ready ssh=crabbox@203.0.113.10:2222 network=public workroot=/work/crabbox
The lease is now waiting for commands. Two timers bound its life: the idle timeout (default 30m) and the TTL (default 90m). Whichever fires first releases the box.
Reuse the lease by slug (friendly) or id (the cbx_... handle). Both work
with --id on later commands.
crabbox run --id swift-crab -- pnpm testWhat happens:
- The CLI verifies SSH readiness on the lease.
- It seeds the remote Git tree from your origin and base ref, then rsyncs the dirty working tree on top (a fingerprint short-circuit skips sync when nothing changed).
- It runs the command over SSH, streaming stdout and stderr.
- It heartbeats the broker so the lease does not idle out mid-run.
- It records a
run_...history entry with sync time, command time, exit code, and (on Linux) bounded telemetry samples.
You can omit --id for a one-shot run:
crabbox run -- pnpm testThat acquires a fresh lease, runs the command, and releases the lease when the
command exits. Use one-shot for ad-hoc tests; use warmup + --id for
iterative work on the same box.
crabbox history
crabbox events run_abcdef123456
crabbox logs run_abcdef123456
crabbox results run_abcdef123456history lists recent runs. events prints the ordered event stream (lease,
sync, command, output chunks, finish). logs returns the retained command
output. results parses any JUnit reports the run attached.
If your broker has the portal enabled, /portal/runs/run_abcdef123456 renders
the same data as a browser page.
When you are done:
crabbox stop swift-crabstop releases the lease, deletes the provider machine, removes the local
claim, and frees the reserved cost. If you forget, the broker's idle alarm
releases the lease automatically.
crabbox cleanup --dry-runcleanup sweeps direct-provider leftovers and local state. It is for the
direct-provider path; brokered cleanup is the broker alarm's job.
Keep a lease alive across a longer session:
crabbox warmup --idle-timeout 4h --ttl 8h
crabbox run --id swift-crab -- pnpm test
crabbox run --id swift-crab -- pnpm bench
crabbox stop swift-crabOpen a desktop session:
crabbox warmup --desktop
crabbox vnc --id swift-crab --openOpen a code-server tab:
crabbox warmup --code
crabbox code --id swift-crab --openUse a Mac you already own (static SSH, no provisioning):
# .crabbox.yaml
provider: ssh
target: macos
static:
host: mac-studio.local
user: alice
port: "22"
workRoot: /Users/alice/crabboxcrabbox run -- xcodebuild testOverride the configured default provider and class per command:
crabbox run --provider aws --class beast -- pnpm test- How Crabbox Works - the mental model.
- CLI - the full command surface and exit codes.
- Commands - one page per command.
- Features - one page per feature.
- Configuration - YAML schema and precedence.
- Providers - which provider to pick.
- Provider authoring - add a new provider.
- Troubleshooting - what to do when a step fails.