All mechanics live in the bro CLI. This skill is policy only.
Prereq: bro on PATH or npx -y @broject/bro@0 (major-pinned), plus
bd — up <step> claims and renders prompts through the shared beads
store.
bro fleet agents is the supervisor surface over the orchestrator connectors
(native detached processes, gascity, tmux, docker, …). The agentId
registry in the git common dir makes an agent's identity survive its process — a
respawn reuses the dead agent's id, worktree, and stored prompt.
The docker connector runs each worker in a container — the image comes
from agents.docker.image or the repo's devcontainer (see
agents.docker.* in configuration docs). Worktree, git common dir and
beads store mount at their host paths, so the same registry/claims/exit
contract holds; an unreachable docker daemon degrades the view, never
a stale 'lost' verdict.
The copilot connector dispatches GitHub Copilot coding-agent tasks —
hosted remote workers that open pull requests. The step is claimed into
the shared beads store before dispatch (the remote runner can't reach
it), the registry pins {taskId, pr}, and down best-effort cancels
the backing Actions run — a surviving session is reported, never hidden.
agents.copilot.maxSessions/maxWorkers count remote live tasks via a
cached count that fails closed when stale.
Commands
| Command | What it does |
|---|---|
bro fleet agents status [<id|step>] [--json] [--connector <name>] |
The agent plane across every backend; an arg prints one agent's detail. Degraded backends warn — never a hard failure of the view, but a targeted miss exits non-zero when a backend is degraded ('gone' is only claimed on a healthy read) |
bro fleet agents up [<step>] [--connector <name>] |
No arg: the backend's supervisor up (a supervisor:'none' backend like native is a reported no-op). With <step>: spawn the step's agent — a lost/exited agent is respawned on the same agentId (the beads claim rebinds), a live one is a SpawnError |
bro agents run [<prompt>…] [--prompt-file <f>] [--for <bead>] |
Ad-hoc spawn — mints a phantom adhoc-<hex> step, sends the prompt through the same registry/worktree/quota path as up, and answers status/log/down under the minted id. --for <bead> binds the spawn to the bead's claim instead (live agent or foreign claim refuses; no prompt → the bead's own text). Either way a live agent/session in this repo with a near-identical prompt earns a stderr warning — advisory, the spawn still lands |
bro fleet agents down [<id|step>] [--connector <name>] |
No arg: supervisor down. With a target: stop that one agent — a gone agent exits 0 on a healthy read (stopped <id>); a miss beside a degraded backend reports unverified (exit 1), not 'gone'; a worker that survives the stop signal (TERM-resistant) or whose death the backend cannot confirm also exits 1 and never prints stopped (spec specs/bro-l8c4f.3.md) |
bro fleet agents log <id|step> [--follow] [--lines <N>] |
Tail the agent's recorded .log — the surface for "is it actually working?" status prints the path; log reads it. --follow is tail -F: janitor truncation and remove/respawn-reopen are reported, never silently skipped. stdout is log bytes only — the context header rides stderr |
--connector <name> scopes these subcommands to one backend. Useful
flags on up: --worktree <path> (overrides the
recorded/conventional <repo>--<step> lookup), --prompt-file <file>
(overrides the stored prompt / bead text), --beads-dir <dir>.
With no worktree to resolve, up mints the conventional sibling on
branch work/<step> inside the spawn transition — enter, claim, and
spawn land as one step under the registry lock, so a refusal leaves no
half-entered tree (the remote-only copilot backend skips this).
Policy
- Fleet first, agents second.
bro fleetis the read-only view —lost — respawn?rows are the decision surface;bro fleet agents up <step>is the action behind it. - Respawn preserves identity. Same agentId, same worktree, same stored prompt — a respawned fixer keeps its custom instructions. The claim in the shared beads store moves to the respawning actor.
- Claims are the coordination plane. A step claimed by a live agent refuses a second spawn; a claim held by another actor (or no agent at all) refuses a rebind — release the stale claim first, don't force it.
- Two caps, different axes.
fleet.maxConcurrentcounts bro's own registry agents;agents.<kind>.maxSessionscaps host-wide sessions through a registered session plane —agents.devin.maxSessionscounts live devin CLI sessions (itssession_locks, deduped by pid), interactive sessions included, so a spawn can refuse while the fleet looks empty.agents.<kind>.maxWorkerssplits the count: only spawned workers fill it (devin: aBRO_AGENT_IDenviron badge or a non-terminal stdin), so interactive TTYs stop starving rigs. A spawn counts into a kind when a registered plane detects the resolved command's CLI or the backend setsagents.<backend>.sessionKind; a declared kind with no registered plane refuses loudly. Devin's host-local count misses cloud-sidedevin_session_createsessions — a plane reports only what the host can verify.