Charlotte, NC
BlogAugust 15, 2026

Managing AI Coding Agents Across Providers with Herdr

Blake McCarn
Managing AI Coding Agents Across Providers with Herdr
I had reached the point where starting an AI coding agent was the easy part. Claude Code in one terminal. Codex in another. A test watcher somewhere else. One repository checked out twice because I had forgotten which window owned the branch. If I disconnected from the machine doing the work, I had to remember which processes were still alive and where they were running. I started using Herdr to manage AI coding agents across providers because the problem was no longer access to another model. It was keeping the work understandable. Herdr gives me one terminal-native operating layer around the tools I already use. It does not replace their CLIs, flatten their differences, or pretend they share context. It gives their terminals a durable structure and gives me one place to see what is running, what needs input, and what is ready to review. That narrower job is exactly why it works. Herdr's core model is a background server with one or more attached terminal clients. The server owns the actual pane processes. A client renders the session and sends input back. Inside that session, the hierarchy is simple: A workspace is the project-level container. Tabs separate layouts such as agents, logs, servers, and review. Panes are real terminals, so they can run an AI agent, a shell, a test process, or anything else that belongs in a terminal. The distinction matters. Herdr does not need every pane to contain an agent. Tests are still tests. A development server is still a normal process. Provider-native agents keep their own terminal interfaces instead of being squeezed into a generic chat window. I use workspaces for most project separation. Named sessions are a stronger boundary with separate panes, sockets, and runtime state. I reserve them for work that genuinely needs an independent server namespace. Creating a named session for every repository would add structure without adding clarity. Detaching is the first feature that changed my daily workflow. When I detach from a live Herdr server, the panes keep running. That includes shells, agents, tests, and development servers. I can close the terminal, disconnect SSH, or move to another client and attach to the same live session later. This is the same reason terminal multiplexers have remained useful for decades. AI coding agents make the persistence problem more visible because a useful turn can run for several minutes, ask for approval, launch tests, and produce a large result. The terminal window should not be the lifecycle boundary for that work. There is an important limitation here. A client detach and a full server restart are not the same event. Herdr's session-state documentation is explicit: a restart restores the workspace, tab, pane, directory, layout, and focus snapshot, but arbitrary processes do not survive. Supported agents can resume their native conversation sessions when current integrations have reported a valid session reference. A plain test runner or development server comes back as a new shell, not a magically resumed process. That difference keeps the claim honest. Herdr provides strong live persistence while the server remains running, plus structured recovery after a restart. It is not process checkpointing. Running two agents against one working directory is an easy way to create a confusing diff. One agent changes a file while another is reviewing it. A formatter rewrites the same area. A test command sees half of one change and half of another. Git can tell me what changed, but it cannot tell me which terminal thought it owned the checkout. Git worktrees solve the repository side of that problem. Herdr adds a useful operational layer on top. A Herdr worktree action creates or opens a Git worktree as a normal workspace, groups it with the parent repository, and preserves its own tabs and panes. The worktree is not a special agent sandbox. It is an ordinary Git checkout with a clear place in the terminal layout. My preferred shape is one implementation task per worktree-backed workspace. The agent, tests, and review commands for that task all live there. The main checkout stays clean for comparison, release work, or a separate investigation. Herdr also keeps deletion explicit. Closing a workspace removes the Herdr layout state. It does not delete the checkout or branch. Removing the worktree is a separate action, and Git can refuse when the checkout is dirty. That is the right failure mode. Closing a terminal view should never imply deleting uncommitted work. Worktrees do not eliminate merge conflicts. They move those conflicts to the point where I expect them: when independent changes are intentionally combined, not while two agents are editing the same file behind each other's backs. This is where Herdr gets the boundary right. Herdr can discover recognized agents, give them unique names, submit prompts, read their terminal output, focus their panes, and wait on lifecycle state through one agent automation surface. The control operations are consistent even when the agent behind them changes. The provider behavior is not consistent, and Herdr does not claim otherwise. Claude Code still owns its model, conversation, permission system, tools, and native UI. Codex owns its own versions of those things. Authentication remains provider-specific. A prompt sent through Herdr is still a prompt to that provider's CLI, not a conversion into some shared Herdr context format. I already use a similar separation at the model API layer with my self-hosted LiteLLM proxy. LiteLLM standardizes model routing for applications. Herdr standardizes terminal topology and lifecycle for interactive coding tools. Neither layer makes the underlying providers identical. That is a useful platform pattern: standardize the operations that are actually common, and leave provider-specific capabilities where they belong. Before Herdr, checking on parallel agents meant clicking through terminals and interpreting whatever happened to be visible at the bottom of each screen. Herdr tracks five agent states:
  • working means the agent is actively running.
  • blocked means Herdr recognized a visible approval, question, or permission prompt.
  • done means background work settled and I have not viewed it yet.
  • idle means the agent is ready for input and its tab has been seen.
  • unknown means Herdr sees an agent but cannot classify the lifecycle confidently.
The difference between done and idle is especially useful. It turns "finished somewhere in the background" into a visible review queue. Focusing the tab marks that work as seen. Reading it through the CLI does not. Agent detection is more nuanced than a process-name check. Herdr first identifies the foreground process, then uses either authoritative lifecycle hooks for agents that support them or screen manifests that classify the live bottom of the terminal. Optional integrations can also report native session identity for restore. This is not infallible. Blocked detection is intentionally strict. A new or unusual provider prompt may appear as idle until the detection rules recognize that screen shape. unknown never means success. I treat lifecycle state as a routing signal for attention, not proof that an implementation is correct. That is still much better than guessing from a grid of terminal thumbnails. The most useful multi-provider workflow I have found is deliberately simple: The implementing agent gets a narrow task in an isolated checkout. The review agent gets the branch, diff scope, and review criteria. The test pane runs ordinary repository commands. Herdr keeps each process visible and addressable, but it does not silently pass one provider's memory to another. That last point is important. The review agent starts with its own context. If it needs the implementation plan, I provide the plan or point it at an artifact. If it needs to understand a test failure, it reads the test pane or the repository output. The handoff is explicit. This costs a little more prompt discipline. It also makes the evidence trail much clearer. I can see which provider changed the code, which provider reviewed it, and which command produced the test result without pretending all three shared one mind. My preferred remote pattern is to keep the repository, provider credentials, and long-running processes on an always-on machine, then attach from a thinner client. Herdr supports the traditional path of using OpenSSH to connect to the host and running herdr there. It also supports a local thin-client mode: The local client connects over SSH, starts or attaches to the remote Herdr server, and streams the UI back to the local terminal. The agents and repositories remain on the remote host. Closing the laptop or losing the network disconnects the client, not the remote pane processes. I have used this to attach to a named remote session and inspect an active multi-agent workspace from another machine. The useful part was not novelty. It was continuity. I did not need to recreate terminal layout or ask which branch each process was using. The remote access documentation also exposes a few operational details worth understanding:
  • Remote attach uses normal OpenSSH authentication, so plain SSH access should work first.
  • The local client uses local keybindings by default. Server keybindings are available explicitly.
  • Client and server compatibility matters. I keep them on the same release and check herdr status before debugging stranger symptoms.
  • Integrations have their own versions. herdr integration status shows when one is behind the bundled expectation.
  • A bare local herdr command and a remote named session are different servers. I check the target before assuming I attached to the wrong layout.
None of those are major burdens. They are still part of operating a persistent client/server tool. Herdr ships an agent skill that teaches an agent inside a managed pane how to use the Herdr CLI itself. That opens up a more interesting workflow. An agent can inspect its current workspace, create a sibling pane, start a supported helper agent, run tests in a plain command pane, read output, and wait for another agent to settle. It can coordinate through scoped CLI commands instead of sending blind keystrokes into whatever terminal happens to be focused. The safety boundary matters more than the convenience. The skill first requires HERDR_ENV=1. If that variable is absent, the agent should stop because it is not running inside a Herdr-managed pane. Inside Herdr, the agent also receives explicit workspace, tab, and pane identifiers. The skill prefers --current, returned pane IDs, or unique live agent names instead of relying on UI focus. I want background work to preserve focus and working directory too. A sibling pane should use the caller's directory and --no-focus unless I asked to switch. An agent should not close workspaces, panes, or sessions it did not create, and it should never casually stop the server that owns everyone else's processes. This is the difference between automation and keystroke roulette. The agent gets a scoped control surface with stable identifiers and lifecycle-aware waits. It does not get blanket permission to rearrange or destroy the whole session. Herdr has made multi-agent work easier to operate. It has not made the providers interchangeable. It does not merge provider memories. It does not copy one conversation into another. It does not replace provider authentication, permission prompts, model selection, or usage limits. It does not make an unsupported agent lifecycle-aware, although that agent can still run normally as a terminal process. It also does not decide whether parallel work is a good idea. Two agents can produce two incompatible implementations faster than one agent can produce a coherent one. A clean pane layout does not replace task boundaries, review criteria, or a human decision about what should merge. Status detection has limits, especially when a provider changes its terminal UI. Integrations and remote manifests reduce that lag, but blocked, idle, and unknown are operational hints rather than correctness guarantees. The full restart boundary is another honest limitation. Layout restoration and native agent resume are useful. Arbitrary processes still stop when the server stops. For a six-hour data migration, I still want application-level checkpointing rather than faith in the terminal layer. Herdr gives the tools a consistent operational shell. It does not erase the reasons I chose different tools in the first place.
  • Herdr for persistent terminal sessions, workspaces, tabs, panes, and agent lifecycle control
  • Claude Code and Codex as provider-native coding agents with separate context and permissions
  • Git worktrees for isolated concurrent checkouts
  • OpenSSH for authenticated remote transport
  • Herdr agent integrations for detection and native session identity where supported
  • Herdr agent skill for scoped pane and agent coordination from inside a managed session
  • Repository-native test commands in ordinary terminal panes
The number of coding agents I can start is no longer the interesting metric. The useful question is whether I can tell where each one is working, what it needs, and how its result will be reviewed. Herdr gives me that operational clarity without asking the providers to become the same tool. That is the layer I was missing.
Share this post: