bro

Utility commands

setup, run, sync, cleanup, plugins.

CommandWhat it does
bro setup [--beads] [--skills]Wire bro into the repo: check gh/bd, write bro.config.json, optionally bd init --stealth + formulas + skill wrappers
bro next [--list] [--json]The autonomous loop's scheduler โ€” claims the top ready bead and prints the work order
bro loop [--max N] [--dry-run]The autonomous loop itself โ€” claim โ†’ worktree โ†’ agent โ†’ gate โ†’ close โ†’ repeat
bro run <plan.toml>Execute a plan โ€” kind routes to the owning plugin, its planSchema validates, runPlan executes
bro plan / bro plan validate <file>Plan kinds and their schema versions ยท validate a plan without executing it (same pipeline as bro run, minus runPlan)
bro sync [--pull]Push/pull artifact dirs (.agents, ledger) on refs/bro/data โ€” git memory outside the review surface, never a branch
bro cleanup [--remote] [--dry-run]Delete local branches whose PR merged โ€” merged state comes from gh, not git branch --merged
bro pluginsThe live registry โ€” name, skill, config section, summary
bro wtf <complaint>Capture a complaint as a wtf bead

bro next โ€” the autonomous loop

If the backlog exists, it was already confirmed โ€” an agent shouldn't re-ask "should I continue?" per item. bro next is the scheduler as code: it reads bd ready, claims the top item (priority, then age), and emits the work order:

bro next    โ†’ implement โ†’ PR โ†’ bro act merge โ†’ bd close โ†’ bro next

The agent's loop is run bro next, do what it says, repeat until state: idle โ€” no per-item prompts. What it deliberately never claims:

  • Human gates โ€” beads titled HUMAN GATE โ€ฆ surface as gate: lines for the user to decide, once.
  • Epics โ€” surface as epic: lines; decompose into beads first.
  • Molecule steps โ€” beads with a parent belong to bro convoy.

--list previews without claiming; --json emits { state, queue, gates, epics, moleculeSteps } plus bead when state is task. States: task โ€” a bead was emitted; gated โ€” open items remain but none are claimable (stop for the human, not done); idle โ€” backlog empty.

bro loop โ€” the runner, not just the scheduler

bro next emits one work order; an agent still has to execute the loop. bro loop is the loop as a command: for each claimable bead it creates a sibling worktree (<repo>--<id>, branch loop/<id>), spawns the configured agent with the work-order prompt, then drives the merge gate itself โ€” green โ†’ bro act merge; review threads โ†’ the agent is respawned with the findings (loop.fixRounds caps it); bd close and cleanup on success, a --notes trail on failure.

{ "loop": { "agent": "devin --prompt-file {promptFile} -p --permission-mode dangerous --respect-workspace-trust false" } }

{promptFile} is the work-order file bro writes into the worktree (also works: claude -p "$(cat {promptFile})", codex exec "$(cat {promptFile})"). --dry-run shows the plan before anything is claimed. One runner per repo โ€” claims are atomic, so a second runner wastes agent runs but can't corrupt the queue.

The spawn env pins BEADS_DIR to the runner's store (bd where), so every bd call inside the worktree hits the shared db even when the repo tracks .beads or bd predates common-dir discovery. An agent's bd close is honored as a verdict โ€” a closed bead without a PR tallies closed rather than being reopened as a phantom failure.

bro sync โ€” the data ref

Runtime artifacts (ledger, skills state, memory) shouldn't poison the PR diff reviewers read. bro sync pushes artifact directories to refs/bro/data โ€” a git ref outside refs/heads, so it never shows up as a branch or in a PR. It also runs bd sync โ€” beads state (drill frames, wtfs, the ready queue) has its own Dolt transport, not the data ref (sync.beads: false opts out).

On this page