A package reproducing 1:1 a working system in which one Claude Code (the coordinator) commands a swarm of other Claude Codes (drones) running in separate herdr panels. The human talks only to the coordinator and never browses drone panels.
Reading this as a Claude who is supposed to set it up on a new machine? Read all of it before you start — the "Why this way and not another" section describes the traps that cost a few burnt drones. The installer is easy; understanding the architecture is what counts.
git clone https://github.com/jmcjm/claude-hivemind.git
cd claude-hivemind
./install.shIdempotent. Every overwritten file lands as *.bak-<timestamp> first. It does six things:
checks requirements, copies the skill, exposes hive in PATH, installs the herdr↔Claude Code
integration, appends a section to ~/.claude/CLAUDE.md, verifies syntax.
Requirements: herdr ≥ 0.8 (tested on 0.8.2 — 0.7.5 removed agent send and the top-level
wait that the old version rode on; for herdr 0.7.x use commit 604848c), claude
(Claude Code CLI), python3, flock. The herdr server must be running — check herdr status.
After installation run the smoke test. It should pass without a single manual click:
hive coord # -> coord: wN:pM
hive spawn testdrone # -> spawn: testdrone ws=.. pane=.. model=opus
hive task testdrone - <<'BRIEF'
# Brief: testdrone
Count the files in the home directory and report the number. Boundaries: read-only.
BRIEF
# -> task: testdrone <- ... (attempt 1) <= MUST say "attempt 1"Now do not poll. Within ~30 s the message HIVE-MAIL: new mail. Run: hive inbox should appear
in the coordinator's prompt on its own. Then:
hive inbox # -> a [finished] entry from drone "testdrone"
hive report testdrone # -> STATUS: DONE + content
hive kill testdrone --purge # or: hive prune, which sweeps every dead drone at onceIf task showed "attempt 2/3" — the drone was losing input, but the retry mechanism worked (OK).
If HIVE-MAIL never arrived — see "Diagnostics" below.
| Path | Role |
|---|---|
~/.claude/skills/hivemind/SKILL.md |
doctrine for the coordinator, loaded automatically |
~/.claude/skills/hivemind/hive |
swarm CLI (a wrapper around herdr) |
~/.claude/skills/hivemind/drone-ping.sh |
drone hook: reports end of turn / needed decision |
~/.claude/skills/hivemind/coord-creed.md |
the eight coordinator rules — single source of truth |
~/.claude/skills/hivemind/coord-creed-inject.sh |
SessionStart hook: after a compaction, re-injects the creed + the live board |
~/.claude/skills/hivemind/coord-compact-brief.sh |
PreCompact hook: tells the summarizer which coordination state must survive |
~/.claude/skills/hivemind/coord-scope.sh |
shared scoping helper — the coordinator hooks fire in one session only |
~/.claude/skills/hivemind/drone-settings.json |
Stop/Notification hooks for drones only |
~/.local/bin/hive |
symlink so drones have hive in PATH |
~/.claude/CLAUDE.md |
the "Hivemind" section — the coordinator's identity |
~/.claude/hooks/herdr-agent-state.sh |
installed by herdr integration install claude |
~/.herdr-hive/drones/<name>/ |
meta.json, brief.md, report.md |
~/.herdr-hive/mail/<recipient>/ |
mailboxes (file = message) |
The global ~/.claude/settings.json receives only the herdr integration hook. Swarm hooks
ride on the drones' --settings, so the human's session is untouched.
Drone = herdr workspace = a panel with an interactive Claude Code on opus. The workspace carries the drone's name, so the human sees the swarm in the sidebar and can take over any panel at any time.
Communication goes through files, not the terminal. Brief → brief.md, result → report.md.
The TUI is read (hive peek) strictly for diagnosis.
Drones call the coordinator, not the other way around. The Stop and Notification hooks mail
the coord mailbox and inject a HIVE-MAIL wake-up straight into the coordinator's prompt. The
coordinator yields the turn and comes back only when there is a reason to — zero polling.
Mail is a directory of files, no daemon and no MTA. Atomic writes (mktemp + mv).
Recipients: coord, a drone name, all. Drones talk to each other over the same channel.
The fleet can span machines. hive coord --remote <ssh-host> on a drone machine forwards its
coord mail over ssh to the coordinator's machine, waking the coordinator's pane there — the
event-driven flow survives across hosts. The coordinator drives the remote fleet with plain
ssh <host> hive spawn/task/report ...; senders arrive tagged <drone>@<host>. Requirements on
the drone machine: hivemind installed, a headless herdr server (herdr server), non-interactive ssh.
Each of these points comes from a burnt drone or a hung coordinator. Do not "simplify" them.
--dangerously-skip-permissions, notacceptEdits. WithacceptEditsa drone stops at the first Bash question (in our case:xargs) and the whole swarm waits. Consequence: the drone will ask about nothing, so boundaries must be in the brief ("read-only", "zero deploys").- No blocking
herdrwaits without a limit. When a drone gets stuck, the coordinator hangs with it and the human loses their only interface.hive waithas a hard timeout and also ends onblocked/dead. - The completion signal is
report.md, not the agent status.idlemeans only "not generating tokens right now" — a drone hanging on a dialog isidletoo. - Swarm variables go through
workspace create --env, becauseagent start(0.8) starts the agent in the existing root pane and has no--envof its own. That is how drones learnHIVE_DRONE. - A fresh drone loses its first input —
SessionStarthooks clear the prompt, andherdr agent promptwithout--waitdoes not confirm receipt.hive taskconfirms delivery (the status must jump toworking) and retries up to 3 times. - The prompt is shared with the human. Sending Enter would send the text the human is typing
right now.
hive task/say/wake_recipientcheck for this and refuse. - But ghost text is not human text. Claude Code suggests ready-made prompts as dimmed text
(SGR
2). A naive detector takes them for input and blocks every idle drone.prompt_pendingreads--format ansiand counts only characters outside dim fragments. - The swarm protocol sits in
--append-system-prompt, not in the brief. When it lived in the brief, drones improvised and usedhive sayinstead ofhive send, bypassing the mailbox and the safeguards. - One wake-up per batch (the
.wake-<who>marker) +flock. Without it, five drones finishing at once all type into one prompt simultaneously and the result is mush.
- Public IDs are short stable handles (
w1,w1:t1,w1:p1); IDs of closed panes are never reused. Always take them from JSON responses. herdr agent *commands are addressed by agent name (= drone name) or pane ID. Name:[a-z][a-z0-9_-]{0,31}, unique among live agents.herdr agent start <name> --kind claude --pane <id>starts in an existing shell pane — zero splits. Drone env enters viaworkspace create --env.herdr agent promptappends Enter atomically and returns immediately; an agent at a dialog →agent_blocked, nothing gets sent.--timeoutworks only with--wait. The oldagent sendand top-levelwaitare gone since 0.7.5.pane readandagent readreturn raw text. A fresh pane can have an empty--source recent— for diagnosis usevisible.herdr pane current --currentgives the caller's pane (hencehive coord).- The trust dialog ("Is this a project you trust?") appears for an untrusted
--cwddespite--dangerously-skip-permissions; herdr reports it asblockedandagent startreturnsagent_not_ready.hive spawndetects and accepts it. - The first spawn on a fresh machine has an extra first-run dialog —
hive spawnhandles it in the bootstrap the same way as the trust dialog. - Statuses:
idle | working | blocked | done | unknown(deadis added byhive).doneis idle after work finished outside UI focus — CLI reads do not clear it. - The official API cheat sheet:
herdr --skill.
| Symptom | Cause | Move |
|---|---|---|
HIVE-MAIL never arrives |
coord.pane points at a previous session's panel |
hive coord, then hive inbox |
HIVE-MAIL never arrives, coord OK |
human has text in the prompt — wake-up withheld | the letter waits in the mailbox: hive inbox |
hive task says the drone did not start |
drone hanging on a dialog | hive peek <drone> |
drone idle, no report |
considered the task done without writing | hive say <drone> "write the report to <path>" |
status dead |
drone killed or crashed | hive revive <drone> — conversation history survives |
drone stuck at a dialog (blocked) |
trust/consent dialog, or its context ran out | hive unblock <drone> |
dead drones pile up in status |
directories outlive the sessions | hive prune --dry-run, then hive prune |
hive revive loses history |
herdr integration missing | herdr integration status → must say claude: current |
| drones bypass the mailbox | old spawn without the system prompt | kill and spawn anew |
- Drone model:
HIVE_MODEL=sonnet hive spawn <name>(defaultopus). - Swarm directory:
HIVE_DIR=/other/path(consistently for all invocations). - Language: the skill and the drones' system prompt are in English — translate
SKILL.mdand$syspromptin thecmd_spawnfunction if the target human speaks another language.