Warp Drive from the Command Line
Warp Drive from the Command Line
Section titled “Warp Drive from the Command Line”Everything a warp-drive run does from inside a Claude Code session can be started
and steered from a plain terminal — iTerm2 on a laptop, an SSH shell on farm-01,
a systemd timer. This page is the one coherent explanation of that lifecycle:
groom → plan → start → observe → stop → report. It is authored with
bob warp start (#2049) and refreshed by the last requirement of the capability
(#2025); the parts that have not landed yet say so, by issue.
Every command below is a row in scripts/bob/commands.json, and
bob <noun> <verb> --help prints its flags and exit codes without acting — on
every bob warp verb, including stop, wherever --help sits in the argv.
1. Groom
Section titled “1. Groom”bob groom --area warp-drive # DRY-RUN: prints what the pass would changebob groom --area warp-drive --apply # Level 3: apply itbob groom runs the /groom pass headless (claude -p over the inlined command
text, #2051). Without --apply it is an explicit dry run; --apply needs
automation Level 3. Scope it with --area <slug>, --issues N,N or --all.
2. Plan
Section titled “2. Plan”bob plan build --from approved --area warp-drive --name "warp CLI" # prints the plan numberbob plan items 2311 # the ordered itemsbob plan build derives a flight plan once, with no interview,
and writes (or refreshes) its flight-plan issue (#2050). --from farm restricts
it to unattended-eligible work (farm-tick.md).
3. Start
Section titled “3. Start”bob warp start --flightplan 2311 --rdbbob warp start (#2049) launches the run in a tmux session you can attach to:
- Preflight. It runs
bob preflightfirst —bob doctorplusbob ready --dry-runas one verdict. A failure exits 1 with the verdict printed and nothing started. On the BoB source checkout, a failure that is only this machine being behind source is fixed first: when the checkout is the clean main branch and no Claude Code session is live, it runsscripts/deploy.shandbob doctor, then the preflight again. The JSON records it ashost_converged.--no-converge-hostskips it (#2472). - Dashboard. It ensures the project’s monitor is running — the same path as
bob warp viz --no-open: reuse a fresh server or start one on this machine’s resolved bind (a machine that declares"dashboard": {"bind": "tailnet"}in the operator repo’smachines.json, like farm-01, serves on its Tailscale address). A dashboard that fails to start is reported and the run goes on;--no-vizskips the step (#2636). - Session. It creates the detached tmux session
warp-<stem>[-<scope>](the stem is the project; in a linked git worktree it is<project>-<worktree>, so a worktree run keeps its project’s name — #4041) (-fp-N,-issue-N,-area-<slug>, or--session <name>) in the project root, and refuses with exit 3 when that session already exists. - Launch. It sends
claude -a<level> [-rdb] "/warp-drive <scope flags>"into the session’s one window.--leveldefaults to_automation.active_level, else 3;--rdbturns on the remote decision bridge. - Attach line. It prints the session name, the one attach command
(
bob warp attach <project>,attach.commandinwarp-start/1), thetmux -CC attach -t <session>line and the viz URL (viz.url).--attachopens an iTerm2 control-mode window on an interactive Mac. On any other terminal it runsbob warp attachthere, so the terminal follows the run (#3163).
--dry-run runs the preflight without filing anything and prints the plan;
--json emits one warp-start/1 document.
It is not bob warp session start. That verb binds an
integration-branch stream and
launches nothing.
The same engine, scripts/warp-drive/launch.sh, is what bob fork uses per
worktree window and what segment-spawn.sh uses per segment handoff — one
launcher, so a run started any of these ways looks the same to everything below.
4. Observe
Section titled “4. Observe”bob warp status --watch --log # phase, issue, chunk, metrics; redraws in placebob warp log # the phase-transition historybob warp viz --tailnet # the live session graph, served on the tailnetbob viz --tailnet # every project on every machine as tiles, each linking to its graphbob control --tailnet # BoB Control: the same pages behind one navigation (Now, Projects, Fleet, Costs)bob plan status 2311 # plan progress: runnable / gated / donebob warp attach bigbrain # this terminal joins the run and follows itAttach once, follow the run
Section titled “Attach once, follow the run”bob warp attach # the project you are inbob warp attach bigbrain # a project by its name, from any directorybob warp attach ~/projects/bigbrain-drain # or by path (a worktree, say)A long run is a chain of tmux sessions: segment 1 in warp-<stem>[-<scope>],
then one warp-seg-<stem>-<N> per segment.
bob warp attach (#3163) attaches to the one that hosts the run now. When the
run hands off to a new segment, the terminal moves to it. You never type a
segment number.
| Where you run it | What it does |
|---|---|
| iTerm2, also over SSH | tmux -CC attach (control mode). Each segment gets its own -CC attach, so it opens as its own window. |
| Any other terminal | tmux attach. |
| Inside tmux | Switches this tmux client to the run. It never nests an attach. |
While bob warp attach is following a run, it is the only thing that attaches
to it. A segment handoff opens no iTerm2 window of its own, because this
terminal already moves to the new segment. With no follower running, each new
segment opens its own window as before (#3942).
--cc and --plain choose the mode yourself. The follow stops when you
detach (the run goes on, and the same command re-attaches) or when the run
ends. bob warp attach --print prints the session and its tmux line without
attaching. Exit 3 means there is no live run to attach to.
bob warp status|log|viz read the project’s warp-drive state file, so they work
the same against a run started with bob warp start, /warp-drive typed in a
session, or a segment handoff. From another machine, bob warp viz --tailnet
prints a URL reachable over Tailscale. After the server starts, bob warp status keeps
printing that URL on its Viz: row (viz in --json), and bob doctor lists it
too (#2639).
5. Stop
Section titled “5. Stop”bob warp stop # graceful: transitions to abortedbob warp stop --hard # emergency: deletes the state file, no cleanupA graceful stop moves the run to the aborted phase; the session inside the tmux
window then files the abort report (/stop-warp-drive does the whole cleanup
from inside Claude Code). --hard wipes the state file and tears down the run’s
warp-seg-* tmux session, leaving uncommitted work in the tree.
A run that ends, completed or aborted, cleans up after itself (#3163). It kills
its own warp-seg-* sessions, then runs the bob warp reap sweep, which also
removes finished segment sessions other runs left behind. The sweep never
touches a live run, an attached session or the session the run itself is in.
The transition’s response names what it removed as seg_reap, and
WARP_RUN_END_REAP=0 turns the sweep off. Run bob warp reap by hand only for
what is left: an attached session (--yes), or the last segment’s own window
once you have closed it (dry run by default).
The run-end sweep only touches warp-seg-* sessions. A finished
claude /warp-drive REPL in a warp-<project>-fp-<N> session, or an old
interactive Claude session in any other tmux session, is found by running
bob warp reap by hand (#3302):
bob warp reap # dry run: every Claude pane graded stale or livebob warp reap --idle 60 # stale after 60 idle minutes instead of 240bob warp reap --force # stop the stale ones: Escape, /exit, wait, kill the panebob warp reap --force --idle-shells # also kill tmux sessions holding only an idle shellA Claude pane is stale once its window has been idle longer than
_workflow.reap_idle_minutes (240 by default; --idle overrides it). A stale
pane in an attached session, or one whose project has an active warp-drive run,
is listed under “needs –yes” and left alone without it. Sessions that hold only
an idle shell are listed as their own class and killed only with
--idle-shells. A Claude process outside tmux is listed with its PID, age and
tty, and never stopped.
Before any kill — a reaped warp-seg-* pane, a stopped Claude pane, an idle
shell session, the run-end teardown and the segment handoff’s kill of a leaked
session — the pane’s whole scrollback (tmux capture-pane -p -S -) is saved to
<project>/.claude/scrollback/<session>-<pane>-<UTC time>.log (#3552). That
output is the evidence a harness-defect report needs when a run died oddly.
Each save is an action line (saved scrollback <path>); a pane that cannot be
saved — no project above its cwd, or a log that cannot be written — is named
as scrollback not saved for %N: <why>, and the kill goes ahead anyway. The
logs are a declared reap surface (scrollback,
ttl_days: 7), so the residue reaper deletes them after a week and the managed
ignore block keeps them out of git.
The dashboard servers behind bob warp viz and bob viz keep running after
the run ends. bob doctor lists every one on this machine in its dashboards
section: project, port, bind (localhost or tailnet), PID, age and the /warp
link, closing with the /bob fleet link (#2639). It flags a server that started
before the current deploy, or one bound somewhere other than where the project
last asked, and prints the command that stops it (#2563):
bob doctor # INFO dashboards: 2 running, 1 flagged # Fleet: http://farm-01.<tailnet>.ts.net:6952/bobbob dash serve --stop bigbrain # every dashboard server for one project, any port or bindbob dash serve --stop --all # every BoB dashboard server on this machineStopping is idempotent. The next bob warp viz starts a fresh server.
6. Report
Section titled “6. Report”A run ends by filing a session summary — a GitHub issue labelled
session-report,session-summary,warp-drive — with the chunk reports it filed
along the way (chunk-report). From a shell:
gh issue list --label session-report --limit 5bob plan status 2311bob notify "warp run on bigbrain finished" --level infobob notify sends a Telegram message over the bridge from any shell, and prints
the message instead when no bridge is configured (#2048).
7. All of it, unattended: bob tick
Section titled “7. All of it, unattended: bob tick”bob tick --dry-run # every step read-only; the digest is the only artifactbob tick # one live cyclebob tick --pause # later ticks exit 3 as `paused` until --resume (two failed ticks do this themselves, #2055)bob tick (#2054) is steps 1–6 as one command with one exit code, for a
timer. Under a lock on $BOB_HOME/.bob-tick.lock it runs bob groom --all --apply,
bob plan build --from farm, one bob warp start --flightplan N --level 3 --rdb
and waits for its tmux session. The wait is bounded by
_workflow.tick_wall_clock_minutes. It then reconciles the plan, publishes a fleet
snapshot, cuts a nightly and runs bob release promote --auto on BOB_SOURCE,
and runs bob update --channel nightly, which a live session refuses only when
the nightly would rewrite the settings.json hooks (#2746). It ends with a
tick-digest/1 digest at $BOB_HOME/fleet/ticks/<date>.json. What each step
may take and how the night shift stops is farm-tick.md.
The executable description
Section titled “The executable description”tests/test-unattended-path.sh (#2058) is
this page as a test. It builds a scratch git repo at Level 3 and puts a fake
claude and a fake gh on the path, then drives the real bin/bob and engines
through steps 3–5 and §7:
bob warp start --issue 1— the fakeclaudewalks the state machine tocoding.bob warp status— shows the run as active, with its phase, issue and level.bob tick --dry-run— writes the digest and files no issue, PR, tag or commit.bob warp stop— the run aborts, resolves the abort and exits.
It runs under make test on macOS and Linux, and prints a SKIP: reason when
tmux is missing. When this page and that test disagree, the test is right.
See also
Section titled “See also”- Warp-Drive Guide — the loop itself, phases, and the in-session view
- Flight Plan — what
bob plan buildwrites - cdfork Guide — fanning out several runs into worktrees
- CLI reference — every flag and exit code