Herdr
Drive a herdr terminal-agent runtime from swamp.
herdr (https://herdr.dev) is a terminal multiplexer built for AI coding agents: a background server owns persistent workspaces → tabs → panes, recognises the agent running inside each pane, and exposes the whole tree over a local Unix socket. This model turns that fleet into swamp data and swamp methods.
Model:
@magistr/herdr— one instance per herdr server: the local one (default session, a named session, or an explicit socket path), or a server on another host reached over ssh by settingsshHost. The transport is the only difference — every method below works identically against either.Observe:
status— client/server versions, protocol compatibility, socket in use and the named-session inventory. A stopped server is reported, not thrown.snapshot— the whole session in ONE socket round-trip: afleetroll-up (workspaces, tabs, pane count, per-state agent histogram) plus oneagentresource per agent. Filter by workspace id/label and by agent state.read— capture a pane's or agent's output (visible screen, scrollback tail, or the agent classifier's own detection buffer), bounded bymaxOutputBytesand tagged with its pane/tab/workspace.
Drive:
prompt— submit a prompt to many agents in one run, optionally waiting for each to settle.wait-agent— block until agents reach a state (idle/blocked/done).start-agent— launch an agent of a given kind in a pane.send-keys/send-text/run-command— key presses, literal text, and submitted shell commands, fanned out across panes.wait-output— block until a pane's output matches a string or regex.
Shape:
create-workspace,create-tab,split-pane,create-worktree,close,notify.
Server and sessions:
server-stop,server-reload-config(validates config.toml first),server-live-handoff,session-stop,session-delete.agent-manifests,update-agent-manifests(reports exactly which agents moved),reload-agent-manifests.
Idempotent by construction: every mutating method reads herdr's state
first. close on a missing id is a recorded no-op; create-workspace,
create-tab and create-worktree reuse an existing container with the
same label/branch; start-agent leaves a pane that already hosts an agent
running. Re-running any method is safe.
Safe to run from inside the fleet it manages: swamp normally executes in a
herdr pane, so the model reads herdr's own HERDR_PANE_ID / HERDR_TAB_ID
/ HERDR_WORKSPACE_ID to refuse to close the terminal issuing the command
and to skip the caller when a prompt fans out (an agent prompting itself
would wait on its own turn forever).
Transport is the herdr CLI over Deno.Command — never a shell — so every
label, prompt and command travels as one literal argv element. Ids and key
names that would be read as flags are refused before anything is sent. Over
ssh a remote shell is unavoidable, so every argument is POSIX-quoted and the
quoting is proved against a real /bin/sh in the property suite.
Resources
2026.08.08.1
Server lifecycle, and an ssh transport so all of it works against a herdr on another host.
Added
- SSH transport. Setting
sshHostpoints the whole model at a remote herdr server; every existing method works unchanged against it. New global arguments:sshHost,sshUser,sshPort,sshIdentityFile,sshExtraArgs,remoteBinary.sshis invoked withBatchMode=yesandConnectTimeout=10so an unattended run never blocks on a prompt; caller options are placed first, which is what makes them win. - Eight server/session methods:
server-stop,server-reload-config,server-live-handoff,agent-manifests,update-agent-manifests,reload-agent-manifests,session-stop,session-delete. - New
manifestsresource — per-agent detection-manifest version, source (bundled vs remote), and any manifest herdr rejected with a warning. statusnow also reportstarget/remote(which server it talked to) andconfigOk/configDetailfrom herdr's ownconfig check.
Changed
update-agent-manifestsreads the current versions before updating, so itschangedAgentsnames exactly which agents moved. herdr's own output reports only the post-update state, which cannot answer "did anything change?".server-reload-configrefuses to reload a config.toml that fails validation, rather than pushing a broken config into a live fleet.
Security
- Over ssh a remote shell is unavoidable, so every argument is POSIX
single-quoted with no "looks safe, skip it" fast path. The quoting is proved
by round-tripping through a real
/bin/shin the property suite — a hand-written decoder could share a blind spot with the encoder. - The self guard does not fire against a remote fleet.
HERDR_PANE_IDnames a pane on the LOCAL server, and herdr numbers panes per session, so a localw1:p4and a remotew1:p4are unrelated panes that share a string. Matching there would refuse legitimate remote closes and silently skip legitimate remote prompts. server-stoprefuses to stop a LOCAL server that hosts the pane running the method;session-stop/session-deleterefuse the session in use.session-deletealso refuses a still-running session unless forced.
- Has README or module doc2/2earned
- README has a code example1/1earned
- README is substantive1/1earned
- Most symbols documented1/1earned
- No slow types (deprecated)1/1earned
- Dependencies pass trust audit2/2earned
- Has description1/1earned
- Platform support declared (or universal)2/2earned
- License declared1/1earned
- Verified public repository2/2earned