Herding parallel agents on a remote box with herdr

My personal coding setup is a remote Ubuntu box that I connect to via ssh. Pi and Claude Code do the work. I scope down access because Pi runs without permission prompts and I use Claude’s --dangerously-skip-permissions flag. Neovim handles edits, while yazi gives me review and filesystem navigation with git status patched into the file tree. tmux and mosh hold it all together so nothing dies when my connection drops, and it’s been good to me. The Mac in front of me is basically a thin client unless I’m working on something UI-heavy.

The one thing that layer never did well was tell me which agent needed me as I ran more agents in parallel. I’ve been trialling herdr as a replacement for tmux, both on the box and locally on the Mac, and it’s good enough that I’m writing it up.

Herdr is an agent multiplexer that lives in the terminal: a single Rust binary with no Electron (yay, as I save RAM and get better performance!) and no hosted control plane or account behind it. It sits in the gap tmux left for me: knowing natively that pane 2 is a blocked agent session waiting on me.

The problem it solves #

When you run three or four agents in parallel on a remote box, the work that slows you down is figuring out which one needs you right now. In tmux I cycle through windows. One finished ten minutes ago, one is blocked on a question, one is still churning, and the only way to find out is to go and look at each. That checking is the tax you pay for running things in parallel.

herdr puts a sidebar next to your terminal that shows the most urgent agent state in each workspace: blocked, working, done or idle. I can scan one column and jump straight to the workspace waiting on me. After a couple of weeks, that simple bit of awareness is what has kept me using it.

A herdr session mid-task, this one local on my Mac: spaces and agents in the left sidebar, Claude Code working away in the main pane, and a file tree and code preview on the right
A herdr session mid-task, this one local on my Mac: spaces and agents in the left sidebar, Claude Code working away in the main pane, and a file tree and code preview on the right

Installing it #

It’s only a few simple commands to get started:

curl -fsSL https://herdr.dev/install.sh | sh
herdr integration install pi       # lifecycle state + session restore for Pi
herdr integration install claude   # session identity for Claude Code
herdr --version

There’s also brew install herdr (which I personally use), and the quick start walks you through the first session if you want to follow along. The Pi and Claude integrations let herdr restore both agents’ native sessions. Pi reports lifecycle state through its extension, while Claude Code state comes from herdr’s terminal detection.

The layout I run #

It maps cleanly onto the worktree-per-task flow I already use. One herdr workspace per git worktree, with three panes inside each that do the jobs I’d otherwise split across separate tools.

flowchart LR
    subgraph ws["workspace: feat/billing"]
        direction TB
        p0["pane 0: pi or claude (agent, root pane)"]
        p1["pane 1: nvim (edits)"]
        p2["pane 2: yazi (file tree + git status)"]
    end
    subgraph sb["sidebar: most urgent state per workspace"]
        direction TB
        s1["● billing: working"]
        s2["◐ auth: blocked"]
        s3["○ infra: idle"]
        s4["✓ docs: done"]
    end
    s1 -.-> ws

The agent writes in pane 0, I read and edit in nvim in pane 1, and yazi in pane 2 gives me the file tree with git status right in it, which is the job lazygit used to do for me. The diff review itself I hand to herdr-reviewr, a review-sidebar plugin you add with herdr plugin install persiyanov/herdr-reviewr: it shows the agent’s changed files, I select lines and leave comments as cards, and one keystroke sends them back into the agent’s input as path:start-end — comment for the next turn.

I’ve bound reviewr to cmd+r, so I can toggle it from the active workspace without keeping another pane open:

[[keys.command]]
key = "cmd+r"
type = "plugin_action"
command = "persiyanov.reviewr.toggle"

That shortcut has made reviewr a regular part of the loop rather than something I remember to open at the end. I still keep one workspace per worktree, and herdr’s own sidebar shows me per-branch agent state at a glance.

Walking through the keybindings #

The prefix is ctrl+b, the same as tmux, so the muscle memory carries over.

herdr                              # starts or attaches the background session server

# ctrl+b, shift+n   -> new workspace, name it after the branch

cd ~/code/myrepo-billing           # your worktree dir
pi                                  # herdr auto-detects Pi
# or
claude -w feat/billing             # herdr auto-detects Claude Code

# ctrl+b, v   -> split a pane (or minus)
nvim .                             # pane 1
# ctrl+b, v   -> split again
yazi                               # pane 2

# ctrl+b, w   -> switch workspaces
# ctrl+b, c   -> new tab within a workspace for another lane

Detach and reattach is what won me over on a flaky ssh connection:

# ctrl+b, q   -> detach. server and every agent keep running on the box
herdr          # reattach later from any terminal, or your phone

I run herdr on the box and reattach over ssh, and with fallback keepalives on by default a dropped connection doesn’t take the session with it. There’s also a herdr --remote mode that points a local client at an ssh host and streams the remote TUI back, if you’d rather drive it that way.

Letting the agent drive its own panes #

herdr exposes a socket and a CLI API, so an agent can create panes, run commands and wait for output by itself, which tmux never supported cleanly. Its official herdr agent skill checks for HERDR_ENV=1, so it only acts from inside a herdr pane and won’t touch a session it doesn’t own. That lets an orchestrator open fresh panes for its own work instead of making you shuffle terminals by hand; the agent skill docs cover the setup.

What to keep in mind before you commit #

It’s still young and pre-1.0, on the 0.7.x line (I’m running 0.7.3), and the project only started this year. I’ve kept my tmux config around while I trial it. Logs live in ~/.config/herdr/, which has already been useful when something behaves oddly.

The bigger thing to be clear on is what herdr doesn’t do: it’s a multiplexer, and it does not sandbox your agents. If the agent can run commands without asking, the egress allowlist and the least-privilege IAM are still yours to set up, on the machine or around each pane’s session, depending on what you want to isolate. herdr buys you awareness and persistence, but isolation is a separate job and it’s still on you.

Who it’s for #

If you live in VS Code remote-ssh and you only ever have one or two agents going, you probably don’t need this, since the problem it solves isn’t one you have. But if your setup is remote-box-centric like mine and the thing slowing you down is tracking a herd of agents across worktrees, herdr is the most natural fit I’ve come across. The code is on GitHub if you want to read it first, but it’s worth an afternoon to try.

Discussion