Appearance
New Machine Setup Guide
Step-by-step guide to get BoB running on a fresh machine.
Terminal only — runs before BoB/Claude is available. Every command in this guide is a shell command. New-machine setup bootstraps BoB before any Claude Code session exists, so none of these steps has a slash-command equivalent. Run them from a terminal.
Prerequisites
| Dependency | Minimum Version | Install |
|---|---|---|
| macOS or Linux | macOS 13+ / Ubuntu 22+ | — |
| Git | 2.30+ | brew install git or apt install git |
| Node.js | 18+ | brew install node or nvm |
| jq | 1.6+ | brew install jq or apt install jq |
| Claude Code CLI | Latest | npm install -g @anthropic-ai/claude-code |
Step 1: Clone BoB
Clone the BoB source repo to a dedicated projects directory (not ~/.claude/):
bash
git clone git@github.com:paulirv/bigbrain.git ~/projects/bigbrainStep 2: Set Environment Variables
Add to ~/.zshrc or ~/.bashrc:
bash
export BOB_HOME="$HOME/.claude" # Runtime directory (Claude Code reads this)
export BOB_SOURCE="$HOME/projects/bigbrain" # Source repo
export PATH="$HOME/.claude/bin:$PATH" # Deployed entrypoints (cdi, cdb, warp, dev-up, …)(The bob-shell.zsh snippet installed in Step 4 also guards this PATH entry, so the export is belt-and-braces.)
Then reload: source ~/.zshrc
Step 3: Initial Deploy
Deploy from the source repo to ~/.claude/:
bash
# If ~/.claude/ already exists from a previous installation:
bash ~/projects/bigbrain/scripts/deploy.sh --first-run
# For a fresh machine where ~/.claude/ doesn't exist yet:
bash ~/projects/bigbrain/scripts/deploy.shThe deploy script:
- Syncs skills, commands, agents, hooks, scripts, templates, registry to
~/.claude/ - Preserves machine-specific files (settings.json, settings.local.json, CLAUDE.local.md)
- On
--first-run: removes legacy.git/and.claude/dirs from~/.claude/, and retires legacy~/bincd* shims viascripts/migrate-cd-entrypoints.sh(#1194)
BOB_HOME is never a clone.
~/.claude/is pure deploy output plus the protected machine-specific files — first-run setup isdeploy.sh --first-run, nevergit clone. A.git/inside~/.claude/is a stale bootstrap fossil that tooling can mistake for a source checkout (#1476); routine deploys warn about it and the fleet snapshot flags it asbob_home_git_fossil(#1477).
Step 4: Install Shell Integration
bash
bash ~/projects/bigbrain/scripts/bob-install.sh
source ~/.zshrcThis adds one guarded line to ~/.zshrc (#1195):
bash
[ -f "$HOME/.claude/bin/bob-shell.zsh" ] && source "$HOME/.claude/bin/bob-shell.zsh"The sourced snippet — deployed and version-controlled, never hand-edited — defines the claude() wrapper (-a1…-a4, -rdb flags), the cdr alias, and a guarded PATH prepend for ~/.claude/bin. It deliberately defines no aliases for bob provision/bob fork: those are bin/ entrypoints resolved via PATH, and an alias would shadow them.
When claude -aN trusts a directory (#3622). Launching with an automation flag skips Claude Code's trust dialog, so the wrapper records the trust itself — but only for a project the operator manages. A directory is trusted when it has an operator manifest (provisions/<directory name>.json in the operator repo), or when it has no committed .claude/settings.json for trust to switch on. A directory with that file and no manifest — a repo you just cloned — is left untrusted: the wrapper prints the allow rules and hooks the file declares and the command that trusts it deliberately, bash ~/.claude/scripts/lib/trust-workspace.sh --yes <dir>. Provisioning the project (bob provision --init --auto) and launching again trusts it the ordinary way.
Migrating an older machine: if your ~/.zshrc carries the legacy inline wrapper/alias block (fenced by # --- BoB Claude Wrapper ---), just re-run bob-install.sh — it replaces the whole fenced block with the source line. Inline definitions outside the fence must be removed by hand.
Step 5: Put the Deployed Entrypoints on PATH
No per-command symlinks are needed (#1194): the deployed ~/.claude/bin/ directory IS the command surface (bob init, bob dash status, bob promote, bob link, bob dash generate, bob dash serve, bob provision, bob warp, bob dev up, …). Just make sure it's on PATH:
bash
# In ~/.zshrc (bob-install.sh adds this on new machines)
export PATH="$HOME/.claude/bin:$PATH"Migrating an older machine: if hand-made ~/bin shims from an earlier setup exist, they shadow ~/.claude/bin (~/bin usually precedes it on PATH). deploy.sh --first-run retires them automatically, or run the migration directly:
bash
bash "$BOB_SOURCE/scripts/migrate-cd-entrypoints.sh" --dry-run # preview
bash "$BOB_SOURCE/scripts/migrate-cd-entrypoints.sh" # convergeIt backs up every shim it removes to ~/bin/.bob-shim-backup/, refuses to touch files that aren't recognizably BoB's, and is safe to re-run. make check warns if a shadowing shim reappears.
Step 6: Verify Installation
The one-command answer is bob doctor (make check-host from the source checkout, #1921): it grades every deploy-managed surface, every symlink, the toolchain and the settings.json hook wiring on this machine, and names the fix for anything behind — Converged means the machine is what deploy.sh would produce.
bash
bob doctor # exit 0 converged · 1 drift (output names the fix) · 2 errorOr piece by piece:
bash
# Check deployed runtime
ls ~/.claude/skills/ ~/.claude/commands/ ~/.claude/hooks/
# Check source repo
ls ~/projects/bigbrain/scripts/ ~/projects/bigbrain/registry/
# Check CLI tools work
bob dash status --global-only
# Check dependencies
node --version # Should be 18+
jq --version # Should be 1.6+Step 7: Clone Project Repos
bob ready is the one command for starting or resuming a project (#3158). Given an owner/repo it clones into this machine's projects_root (declared in machines.json, default ~/projects) and carries on to READY:
bash
bob ready example/bodmail # clone → bob init → provision → labels → ports → on bob viz, then READY / NOT READYbob ready is idempotent and never prompts — re-run it any time; a NOT READY verdict names the fix per blocker (see bob ready). It never deploys BoB and is never blocked by another project's live run. bob init alone still works, but it is only one of the steps.
Step 8: Publish the Fleet Snapshot on a Timer
audit.js view and bob status --scope fleet report a machine as never until it publishes a snapshot, and as stale once its newest snapshot is older than 24 h. Install the timer once per machine:
bash
node ~/projects/bigbrain/scripts/fleet/audit.js snapshot --install-timer # launchd agent on macOS, systemd user timer on LinuxOn Linux, turn on lingering too, so the user timer keeps firing while nobody is logged in:
bash
loginctl enable-linger "$USER" # if polkit refuses, run it with sudoThe install is idempotent: running it again reports every unit as unchanged. To publish a snapshot right away and check the result, follow Verify an install.
Step 9: Machine-Specific Overrides (Optional)
bash
cat > ~/.claude/CLAUDE.local.md << 'EOF'
# Machine: (your machine name)
- Projects directory: ~/Sites/ (or ~/Work/, etc.)
- Any machine-specific notes here
EOFThis file is gitignored and protected by deploy.sh.
Verification Checklist
- [ ]
echo $BOB_SOURCEshows~/projects/bigbrain - [ ]
bob dash statusshows global tooling inventory - [ ]
bob initis available (which bob) - [ ] Opening Claude Code in any linked project loads BoB's CLAUDE.md
- [ ] Skills are available (start a Claude session, type
/journal) - [ ] Hooks fire (try editing a file on main branch -- should be blocked)
- [ ]
bob doctorprintsINFO snapshot timer: installed (…, every 60 min), andaudit.js view --no-liveshows this machine ascached
Updating BoB
Pull the latest source, then re-deploy:
bash
cd ~/projects/bigbrain && git pull
bash scripts/deploy.sh
make checkThen re-provision active projects from their manifests:
bash
cdr reprovision # disaster-recovery CLI: re-applies every project's manifestFor a single project, cd <project> && bob provision --refresh is enough.
Troubleshooting
Symlinks are broken after clone:
bash
# In the project directory:
bob init # Re-creates all symlinks from BOB_SOURCEbob dash status command not found:
bash
# Check ~/.claude/bin is on PATH (the deployed entrypoints live there)
echo $PATH | tr ':' '\n' | grep claude
# If missing, add to ~/.zshrc:
export PATH="$HOME/.claude/bin:$PATH"
# Then redeploy if ~/.claude/bin/bob itself is absent:
bash ~/projects/bigbrain/scripts/deploy.shHooks not firing: Check that the project's .claude/settings.json references hook paths correctly. Hooks should point to .claude/hooks/*.sh (relative to project root), and those should be symlinks to $BOB_SOURCE/hooks/.
Skills not loading: Skills auto-load from ~/.claude/skills/. If they're missing, re-deploy:
bash
bash ~/projects/bigbrain/scripts/deploy.sh