Herdr is the runtime around the coding agent
How an agent-aware terminal multiplexer owns live panes, processes, and lifecycle, and how Agent Factory sits above it as a control plane rather than a second runtime.
| Resource | Link |
|---|---|
| Project | Herdr on GitHub |
| Agent model | Herdr agents documentation |
| Automation | Herdr agent automation |
| Runtime surface | Herdr socket API |
| Implementation | herdr-agent-factory |
| Integration | Herdr integration spec |
| Architecture | Architecture ownership |
Running one coding agent in a terminal is simple. Running five agents across several repositories turns the terminal into an operations problem.
The work is no longer just “send a prompt and read the answer.” The host must know which process owns which workspace, which pane needs attention, whether an agent is waiting or working, how to deliver input without corrupting it, and what should survive a restart. Herdr exists in that layer: an agent-aware terminal multiplexer for operating many real coding-agent sessions at once.
Herdr is not the model and it is not the agent’s planning loop. It is the live runtime around the agent.
A pane is not an agent
A terminal pane is a process container. It can hold a shell, a test runner, a development server, or a coding agent. An agent is a semantic occupant of that pane with an identity, lifecycle, prompt surface, and state signals.
That distinction matters because terminal geometry is not durable product identity. A pane can be split, moved, restored, or closed. The agent inside it can restart, change state, or disappear while the pane remains.
| Layer | Owns | Typical question |
|---|---|---|
| Workspace | Repository grouping and shared live context | Which project is this work part of? |
| Tab | A related set of panes and their aggregate state | Which group of work needs attention? |
| Pane | A real terminal, process, working directory, and output surface | What is running here? |
| Agent | Identity, lifecycle, input, output, and status signals | Is this coding agent ready, working, blocked, or unclassified? |
The UI can show those layers together, but the implementation should keep their identities separate. A pane ID is useful for routing terminal actions. An agent ID is useful for sending a prompt or finding a session. A product record that says why the work exists should not be a cached copy of either.
Why a normal multiplexer is not enough
Traditional terminal multiplexers solve persistence and layout. That is already valuable: processes remain alive when the visible terminal detaches, panes can be arranged around a project, and work can continue without keeping every window open.
An agent multiplexer adds a semantic layer. It can identify panes containing supported agents, surface lifecycle state, roll that state up to tabs and workspaces, and provide an automation surface for creating panes, reading output, sending input, and waiting for changes.
The difference is not that every agent becomes identical. Herdr can still run unsupported agents as ordinary terminal processes. Known agents expose richer signals. Custom integrations can report labels and state through the runtime interface.
State is an observation, not a verdict
Agent status usually comes from more than one signal. A runtime may inspect the foreground process, match terminal output against a screen manifest, receive lifecycle hooks, or accept semantic reports from an integration.
Those signals have different authority. A lifecycle hook can be authoritative while it is installed and reporting. Screen detection can be a fallback. A stale status report should not override a newer process exit. The runtime needs an explicit precedence rule rather than whichever signal arrived last.
| State | Meaning | Safe next action |
|---|---|---|
idle |
Settled and ready for input | Send a prompt if the caller owns the turn |
working |
Actively producing output | Observe; interrupt if needed; do not duplicate input |
blocked |
Herdr recognized an approval or question surface in the agent’s own interface | Focus the pane and answer inside that native surface |
done |
Unseen background work returned to the same ready state as idle |
Treat as settled, not as process exit or product completion |
unknown |
Present but unclassified | Preserve uncertainty; inspect the pane |
done is not “the task is complete.” It is not process exit. A process can return to a prompt after a failed test. An agent can stop because a permission request was denied. Completion still requires host-side evidence such as test results, changed files, or an explicit product decision.
Input needs a delivery contract
Sending text to a terminal is not the same as delivering a prompt to an agent. A prompt can contain newlines, code fences, shell syntax, or a request that should be submitted as one unit. The runtime must define whether input is pasted atomically, whether an enter key is sent separately, and what happens when the pane is not ready.
The caller should target an explicit agent and receive an acknowledgement that the runtime accepted the input. A successful write to a pseudo-terminal proves only that bytes were written. It does not prove that the agent received a complete prompt or started a turn.
Herdr can prompt a working agent; the runtime rejects delivery when the agent is blocked. A control plane can impose a stricter rule. Agent Factory requires a fresh snapshot and a settled idle or done agent before prompt or resume actions. Observation and interruption remain available while the agent is working. Blocked input stays inside the agent’s own interface — there is no parallel approval protocol beside Herdr.
The socket surface makes those steps explicit through agent.get, agent.prompt, agent.wait, and agent.read. A prompt needs a target, a submission rule, and an observable result. A product that requires settled delivery should retry against a later snapshot instead of inventing a lifecycle state.
Events invalidate; they do not decide
Polling every terminal is a poor orchestration strategy. It wastes work while agents are busy and still misses the meaning of a changed screen. A useful runtime combines event-driven invalidation with targeted reads.
The event says that something changed. The snapshot explains what is true now. The pane remains the source of visible truth. The agent integration or detector supplies a semantic interpretation. Keeping both makes failures diagnosable: a status can be wrong without hiding the raw output that produced it.
A product sitting above Herdr should subscribe to workspace, tab, pane, process, and agent events, then re-read a complete snapshot. It should not treat event order as a durable transition log or apply an old payload over a newer observation.
Waiting also needs semantics. “Wait 30 seconds” is a timeout. “Wait until the agent becomes idle or blocked” is a lifecycle operation. The latter can still time out, but the result should say whether the runtime observed a state transition, the process exited, or no trustworthy signal arrived.
The runtime boundary makes parallel work possible
Parallel coding work becomes manageable when the host owns coordination and each agent remains inside its own real terminal process.
| Concern | Runtime responsibility |
|---|---|
| Placement | Create and arrange workspaces, tabs, and panes without stealing focus unexpectedly |
| Process lifecycle | Start, inspect, stop, and clean up child processes |
| Agent identity | Associate a detected or integrated agent with a stable live target |
| Interaction | Deliver prompts, keys, reads, and waits with explicit semantics |
| Observation | Preserve raw output, state evidence, timestamps, and signal authority |
| Recovery | Reattach, restart, or mark a session unknown without inventing success |
The host should not become a second coding agent. It should not rewrite prompts, infer repository intent from a title, or pretend that a pane layout is a durable task database. Those concerns belong in the application using the runtime.
Agent Factory sits above Herdr, not inside it
herdr-agent-factory is the product-shaped proof of that split. It is a macOS control plane: define a Target Agent, isolate a Draft, apply one Environment, record who authorized each managed session, and accept a Version only when evidence meets criteria declared up front.

Herdr knows what is running now. Git knows the files. Neither knows why the work exists or what “done” means for the product.
Agent Factory connects as a client over Herdr’s control socket. It does not start, stop, restart, update, or kill Herdr. When Herdr is unavailable, the durable product view remains usable, the last runtime observation is labeled, and commands that need live preconditions are disabled.
| Authority | Owns |
|---|---|
| Web UI | Validated projections and typed intents; ephemeral view state only |
| Native host | Window, packaging, security policy, sidecar lifecycle, and opaque transport |
| Rust | Factory ledger, Environments, managed-session lineage, evidence, and Run control |
| Herdr | Live Workspaces, tabs, panes, agents, processes, terminals, topology, and lifecycle |
| Git | Worktrees, branches, HEAD, status, diffs, commits, and tags |
| Orchestrator | Decisions to delegate, iterate, evaluate, escalate, or finish a Run |
A Workspace Binding has zero or one current Factory-managed Herdr Workspace. A Run reuses that Workspace and launches fresh managed sessions; the Run never owns the Workspace. Starting a Run asks Herdr for a fresh Orchestrator session after Rust resolves the selected Environment. Only the Orchestrator receives the per-Run control token. Coding and Evaluation sessions are created when that Orchestrator issues an authenticated command.
A Harness is a Herdr agent kind discovered from Herdr manifests. Agent Factory never probes PATH, never bundles or installs agents, and never treats an unmatched live pane as a managed session. Unassociated agents stay visible as other runtime activity.
This division changes how events are handled. A Herdr event tells Agent Factory that live state changed; Rust re-reads a complete snapshot instead of treating the event as a durable transition. An idle or done label can enable another prompt. It cannot pass success criteria or finish a Run. Completion belongs to the Orchestrator’s authenticated command and the evidence recorded by Agent Factory.
The same boundary preserves human collaboration. A user can focus a live pane, inspect output, interrupt a working agent, or answer its native approval surface without turning terminal text into product history. Closing an Agent Factory pane does not stop a Herdr agent, cancel a Run, or discard its Git worktree.
A safe automation shape
Automation works best when it is narrow and reversible. Resolve an Environment. Ask Herdr to create one session in an explicit Workspace. Wait for a settled snapshot. Send one prompt. Observe state and output. Only then decide whether to send another input, request review, or stop the session.
# Wait for a new turn to be safe under Agent Factory's settled-state policy.
herdr agent wait "$ORCHESTRATOR" --until idle --until done --timeout 120000
# Deliver one prompt and wait for the next observable lifecycle state.
herdr agent prompt "$ORCHESTRATOR" "Review the current diff and report failing tests" --wait --until blocked --until idle --until done --timeout 120000
# Read visible transcript text without interpreting it as a verdict.
herdr agent read "$ORCHESTRATOR" --source recent-unwrapped --lines 120These commands match the current Herdr CLI: the agent target is positional and each accepted wait state uses a separate --until flag. Every step has an explicit target and a recoverable result. The caller can stop after a blocked state instead of blindly sending more keys. Transcript text is read on demand; it is not parsed into tool calls, plans, or a semantic verdict.
What Herdr reveals about agent products
The hardest part of a multi-agent product is not rendering several chat streams. It is making concurrent work observable and controllable without erasing the reality of processes, terminals, permissions, and failures.
Herdr demonstrates a useful middle layer. The terminal remains a real execution surface. The multiplexer adds topology, lifecycle awareness, and automation. The application above it can then provide project semantics, durable records, policy, and completion evidence.
That split prevents two common mistakes: treating a terminal UI as the whole runtime, and treating an agent protocol as if it owned the host environment.
Takeaways
A pane is infrastructure
Keep terminal identity, process ownership, and agent identity separate. They change at different times and need different recovery rules.
Status needs authority
Project Herdr lifecycle without reinterpretation. idle and done are settled; blocked stays in the agent UI; unknown proves neither readiness nor completion.
Input and waits are contracts
A byte write is not a delivered prompt, and a timeout is not a lifecycle transition. A controlling product can require a fresh, settled snapshot before starting a new turn.
The agent remains the agent
Herdr coordinates live processes. Product policy, managed-session lineage, and verification belong in the control plane above it — not in a second runtime.