Skip to content
Guide Intermediate 10 min

herdr: orchestrating your coding agents in the terminal

Sébastien Giband · Symfony/TypeScript dev · terminal-first ·
herdr omp (Oh My Pi) tmux Claude Code PHP/Symfony 7 TypeScript/React

TL;DR

herdr is a background server that owns your coding agents' terminals: every pane exposes a state (idle, working, blocked, done), and the CLI and socket let the agent itself drive the herd. This guide says what I do with it daily, the split/wait/read flow, and the verified traps.

herdr coding-agents orchestration terminal multiplexer

This guide is written from a herdr pane: the session writing it runs inside the server, HERDR_ENV=1, like most of my agent sessions. Tested on v0.8.0. I’m not going to re-copy the docs, they’re well done and up to date; I’m going to say what I do with it daily, what it changed, and the traps I fell into.

Why I stopped scrolling my tmux panes

With several coding agent sessions in parallel, the problem is no longer opening terminals, it’s knowing who’s waiting, who’s working, who finished ten minutes ago. A tmux pane is an opaque rectangle: nothing says what the process inside is doing, you scroll, you guess.

Before herdr, I tried teaching tmux about agent state: a hook pushed ● into the status bar when a turn was running, a bell when the agent was waiting for my go-ahead, ✓ when it finished. It half-worked: it only covers one agent, it has to be rewired tool by tool, and it drives nothing. The hack confirmed the need, it didn’t solve it.

herdr changes the abstraction layer: every pane exposes a semantic state (idle, working, blocked, done), detected from the terminal’s real content. When an agent stops and needs an answer, it’s marked; you no longer hunt for the stuck pane one by one.

What herdr is, in one sentence, and what it changes

herdr is a background server written in Rust (one binary, no Electron), Apache 2.0, backed by Y Combinator. The terminals live in the server, not in an app window. Two consequences that change your life:

  • Closing the laptop kills nothing. Sessions keep going, I reattach in the morning from any terminal, including over SSH.
  • The agent drives the tool. The CLI and the socket are the same surface the agent drives: it can create panes, launch other agents, wait for them. More on that below, it’s the point that made me switch.

Installation:

# macOS · Linux
curl -fsSL https://herdr.dev/install.sh | sh

# or homebrew
brew install herdr

Then run herdr (TUI), ctrl+b q detaches, herdr reattaches.

How I organize my space

Four levels, with stable public identifiers:

w1          workspace
w1:t1       tab
w1:p1       pane
term_...    terminal

IDs are opaque strings: read them from JSON responses, never rebuild them from the display. herdr injects the current context into every managed pane (HERDR_WORKSPACE_ID, HERDR_TAB_ID, HERDR_PANE_ID), and --current targets the calling pane, avoiding the focused pane of another client.

My organization: one workspace per active project, one tab per context within the project, one agent per pane. For an isolated issue, I use the herd-issue workflow: a throwaway workspace per issue (worktree + dedicated agent), steered by messages, torn down cleanly once everything is pushed. The throwaway workspace is the difference from tmux: you no longer hesitate to open a context, because you know it will disappear.

The gesture that comes back every hour: launch an agent, wait, read

The full flow, from a shell to a finished agent:

# 1. split right without stealing focus
herdr pane split --current --direction right --no-focus

# 2. name the pane and launch the agent (its interactive TUI)
herdr pane rename w1:p2 "reviewer"
herdr pane run w1:p2 "omp"

# 3. wait for the agent to be ready, then submit the task
herdr agent wait w1:p2 --until idle --timeout 30000
herdr pane run w1:p2 "Review the current diff and report only actionable findings."

# 4. wait for completion, then read the transcript
herdr agent wait w1:p2 --until done --timeout 120000
herdr pane read w1:p2 --source recent-unwrapped --lines 120

The difference with tmux sits in steps 3 and 4: you wait for a state instead of firing keystrokes and hoping. done means “finished and result not yet seen”; idle means “finished and result seen”; blocked means the agent is waiting for an answer, that’s the one you go see. In the morning, it’s spectacular: the pane that finished overnight is done, the one that needs a decision is blocked, the others stayed working. The dashboard tells the night’s story, you scroll nothing.

Orchestrating several agents, concretely

The founding point, the one tmux can’t do: the agent itself drives the multiplexer. The harness’s herdr skill first checks that we’re in a managed pane (HERDR_ENV=1), then exposes split, run, wait and read to the model. Concretely, when a session needs a parallel context (a dev server, a long review, a slow test), it opens a pane with --no-focus, runs the command, waits for the output, reads the result. My focus doesn’t move: background work happens without stealing the screen.

Between agents, same principle: an agent can launch a peer and message it, waiting for it to be genuinely blocked before stepping in. That’s the engine of the herd-issue workflow: an agent works on an isolated worktree, you steer it by messages, it asks for approval before pushing, and the workspace is dismantled when everything is done.

The traps that cost me time

Verified on v0.7.3, to re-check at every version:

  • herdr server reload-config only half-validates: an unknown action in a binding is silently ignored, “applied” proves nothing. Always test the binding after reload.
  • Symbolic keys are QWERTY positions: on an AZERTY keyboard, dead bindings with no message at all. If a shortcut stops responding, that’s probably it.

And the common-sense rules: don’t close a workspace you didn’t create, never kill the main process, don’t run herdr server stop from an active session unless that’s the explicit intent.

The pickers I built on top of it — TV fuzzy pickers for workspaces, tabs and panes, with a live preview per pane — and the full breakdown of these traps (symptom, cause, fix) are public: herdr/.

What it changes day to day

  • In the morning: reattach, and the states tell the night’s story. Who finished, who’s waiting for a decision, who’s still running.
  • During the day: the focus never moves. The agent opens and closes its own panes for background work, I stay on my session.
  • One issue: a throwaway workspace, a dedicated agent, a clean teardown. You no longer hesitate to isolate.
  • In the evening: I close the laptop, the sessions keep going. The constraint “it has to run while I’m here” is gone.

And honesty: the layer is young, config and docs formats still move (migrations exist, which proves it moves), and the plugin ecosystem is younger than tmux’s. I only rely on what I’ve tested.

Where to start?

Three moves, without reorganizing everything:

  1. Install and launch (curl -fsSL https://herdr.dev/install.sh | sh, then herdr), tmux stays on your servers.
  2. Run your usual agent in a pane (claude, codex, opencode, omp, whatever) and detach: ctrl+b q, come back later, the session is still there.
  3. Hand the control to the agent: a skill that checks HERDR_ENV, splits with --no-focus, and waits for a state instead of firing keystrokes.

In practice, the multiplexer stops being a simple container of terminals: it becomes the herd’s cockpit. And as with the rest of the harness, agentic workflow principles and multi-agent context management complete the picture.

Frequently Asked Questions

Do I have to replace tmux?
No. tmux remains my choice on servers (present everywhere, sessions that survive SSH disconnects). herdr takes the local role, where the agents live. The full comparison is in the multiplexers dispatch: one tool per context, not a global replacement.
Which agents does it work with?
About twenty agents are detected out of the box: Claude Code, Codex, Cursor, opencode, Grok, pi, omp and others. herdr doesn't wrap them and doesn't replace them, it owns their terminals. Any shell process stays drivable, even without agent detection.
Does it cost anything?
No. Apache 2.0, open source, a single Rust binary (no Electron), backed by Y Combinator. You pay for the models you run in it, like anywhere else.
Can the agent drive herdr itself?
Yes, that's the founding point. The CLI and the socket expose the same surface the agent drives: it can create panes, start other agents, message them, and wait until an agent is genuinely blocked before stepping in, instead of firing keystrokes and hoping.
Does the work really survive closing the laptop?
Yes. herdr is a background server, the terminals live inside it: closing the lid, dropping the network or restarting the machine, agents keep working and sessions come back. You reattach from any terminal, including over SSH.

Go further