๐ Swarm (structupath.swarm)
Mental model: "Try this task N different ways in parallel, then keep the best." Each agent works in its own git worktree + branch off a recorded base SHA, so agents never collide and main stays clean until you merge. Agents commit locally and never push โ you are the merge gate.
Repo: StructuPath/herdr-swarm ยท Full reference: the repo README
The 5 actions, in order
| # | Action | You do | It does |
|---|---|---|---|
| 1 | Fan out | how many agents (N), preset per slot, the task | N worktrees + swarm/<run>/<slot> branches, task โ .swarm-task.md, launches agents, opens Status |
| 2 | Status | watch; 1โ9 jump into a slot, q quit |
per-slot state + committed/uncommitted counts vs the fork point |
| 3 | Harvest | review + merge, one slot at a time | merges good slots back --no-ff; removes worktree after (branch kept) |
| 4 | Prune | confirm via env flags | deletes fully-merged swarm/* branches (dry-run lists first) |
| โ | Abort | bail anytime | stops agents, removes clean worktrees, keeps branches |
Everyday flow: TUI menu โ Fan out (answer prompts) โ Status (watch) โ Harvest (keep winners) โ Prune (tidy).
Harvest keys (per slot)
1โ9select slot ยทrre-preview ยทqquit- Clean slot โ merged automatically (base drift-checked before every merge)
- Dirty slot โ
wcommit WIP ยทsskip ยทddiscard (typed confirm, snapshot ref saved first) - Conflict โ
sshell into merge tree ยทaabort merge ยทbback out
Prune is gated on purpose (destructive)
HERDR_SWARM_PRUNE_CONFIRM=yes # delete listed merged swarm/* branches
HERDR_SWARM_PRUNE_ACK_REVERTED=yes # also needed for merged-then-reverted
HERDR_SWARM_PRUNE_BACKUPS=yes # delete discard-snapshot backup refs
Prune uses safe git branch -d semantics (never force), refuses branches still checked out in a worktree, and never touches snapshots belonging to the active run.
Scripted / headless fan-out
fanout can not be action-invoked โ panes spawned by the herdr server don't inherit the caller's environment. Call the pane script directly with env overrides:
HERDR_SWARM_SLOTS=3 \
HERDR_SWARM_PRESETS=claude,claude,codex \ # one name = applies to all slots
HERDR_SWARM_TASK_FILE=/path/brief.md \
HERDR_SWARM_DETRITUS=rename \ # delete | rename | abort (leftover branches)
HERDR_WORKSPACE_ID=<repo workspace id> \
bash "$(herdr plugin list --json | jq -r '.plugins[]|select(.id=="structupath.swarm").root')/scripts/fanout-pane.sh"
Harvest (scripts/harvest-step.sh), abort, and prune are also zero-TTY scriptable โ an agent can drive the whole plugin. Presets live in presets.conf (name|kind|args); defaults are claude and codex.
Three things to remember
- Isolation is the point โ own worktree + branch each;
mainuntouched until harvest. - You are the merge gate โ agents commit locally, never push; you decide what lands.
- Cleanup is layered + safe โ abort keeps branches, prune won't force-delete, discards snapshot first.
Sharp edges
- Fresh worktrees lack your env โ
.env,node_modules, build caches are absent; the most likely cause of "all my agents failed instantly." Drop asetup.shin the plugin config dir to prep each worktree automatically. - Squash merges are invisible โ a slot you squash-merged yourself still shows as pending; skip it by hand.
- Closing the parent repo workspace kills swarm agents silently โ committed work survives and stays harvestable.
- 0.7.5 cosmetic quirk โ a finished slot shows
workingin Status until you open Harvest; committed work is harvestable regardless.