Docs / Plugins

๐Ÿ 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)

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

  1. Isolation is the point โ€” own worktree + branch each; main untouched until harvest.
  2. You are the merge gate โ€” agents commit locally, never push; you decide what lands.
  3. Cleanup is layered + safe โ€” abort keeps branches, prune won't force-delete, discards snapshot first.

Sharp edges