How Herdr Knows What Needs You
Herdr's agent-awareness problem is narrower and more interesting than simply recognizing program names. It must decide what process occupies a pane, whether the live terminal suggests working or waiting, which integration is allowed to author lifecycle state, and how much of that information should reach the sidebar. This chapter follows that evidence chain and separates semantic state from presentation. The result is a practical way to use Herdr's attention surface: treat it as a guide to where to look next, not as an automatic verdict that an agent's work is correct.
Detection starts with the pane's occupant
Herdr begins with the foreground process in a pane. A plain shell, test runner, editor, or server is still a useful terminal, but it is not automatically an agent. When the foreground job matches a known coding-agent executable—or a configured wrapper identifies the agent—Herdr can attach an agent identity to the pane and evaluate the agent's state.
The next signal is the live terminal itself. For agents that rely on screen detection, Herdr reads the recent bottom portion of the pane buffer, where the current interface is being drawn. It evaluates an agent-specific manifest rather than applying one generic rule to every program. A manifest can look for visible text, regular-expression patterns, line-level shapes, and, where available, terminal-title or progress signals emitted through OSC sequences. The purpose of those rules is not to understand the agent's entire transcript. It is to recognize a small set of visible states: an active working display, an idle prompt, or a known approval, question, or permission surface.
The choice of the live bottom buffer is important. A person can scroll up to inspect earlier output, but detection continues to follow the live interface at the bottom. Otherwise, merely reading old text could make Herdr conclude that an agent is still waiting for a question that has already been answered. Full-screen agents create a related boundary: a transcript viewer can display old conversation while the process is not actually at its live prompt. Herdr can mark such a view as unsuitable for a lifecycle update instead of letting history overwrite the current state.
Screen detection is a fallback, not always the highest-authority signal. Some agents expose lifecycle hooks or plugins that tell Herdr when work starts, when a tool requests approval, and when the agent becomes ready again. When a complete lifecycle integration is installed and actively reporting for the pane, its reports author working, blocked, and idle; Herdr does not run a competing screen-based lifecycle decision for that same authority. That avoids a split-brain status in which a hook says “working” while an incidental prompt-like line in the screen says “idle.”
Other integrations have a more limited job. A hook may report a native conversation or session reference without covering every transition in the agent's lifecycle. In that case Herdr can use the reference later to resume the conversation, but it still uses screen manifests to determine whether the agent is working or blocked. A resumable session identifier answers “which conversation should be launched again?” It does not answer “is this conversation currently waiting for a human decision?”
The difference can be made concrete with two otherwise similar panes. Suppose both panes are running coding agents and both integrations have reported a session identifier. One agent may also have a lifecycle-authoritative hook, so its hook events control semantic state. The other may only have a session-start hook, so its current state still comes from the visible terminal. Herdr should not merge those mechanisms merely because both integrations are called “official.” Their authority is different, and the server keeps that difference in its state model.
The manifest itself is also a replaceable evidence source. Herdr bundles rules, can cache compatible remote updates, and permits a local override in the platform configuration directory. A running server loads active rules into memory; an update or explicit reload can change the cache used for subsequent explanations. This gives maintainers a way to respond when an agent changes its screen without requiring a new Herdr binary for every matcher adjustment. It also means a diagnosis should include the active manifest source and version. A result produced by a local override is not the same operational fact as a result produced by the bundled rule.
Process identification has boundaries of its own. A sandbox or virtual machine can hide the real agent from the host, in which case a wrapper can provide an HERDR_AGENT hint for the foreground process. The hint applies to that process, not to every child command inherited from a shell. In restricted Linux environments, Herdr can opt into a best-effort child-process-group inference mode when native foreground detection is unavailable, but the documentation warns that a newer background job can be mistaken for the foreground job. These fallbacks expand compatibility by accepting weaker evidence; they do not erase the uncertainty that came with it.
This is why an explanation view matters operationally. If an agent is shown as idle when a person expected blocked, the first questions are: which process did Herdr identify, which screen snapshot was evaluated, which manifest was active, whether a lifecycle authority suppressed screen rules, and whether an update or local override changed the rule. That sequence is more useful than adding a new label or sending an arbitrary key. It turns a visible symptom into a check of the evidence and authority that produced it.
The state transition is also stabilized rather than treated as a single noisy sample. Terminal output can briefly resemble an idle prompt while an agent is finishing a tool call or redrawing its interface. Herdr's detection path can hold a working-to-plain-idle transition for a short confirmation window, then publish the result when the evidence is stable. This is a small implementation choice with a useful system effect: the sidebar is less likely to flicker between “working” and “idle” because of one incomplete screen update. It does not turn detection into a proof system; it only reduces a known source of transient misclassification.
The resulting authority chain is easier to understand as a sequence than as a list of supported agents.
The diagram's central choice is not “hooks good, screens bad.” It is that one authority should own a particular fact at a time. Screen rules are valuable because they work with agents that have no complete integration. Hooks are valuable when they cover transitions the screen cannot make reliable. Session identity is valuable for restore but is deliberately not promoted into lifecycle authority.
State becomes attention without becoming truth
Herdr presents five user-facing status concepts: working, blocked, idle, done, and unknown. Working means the agent is actively running. Blocked means Herdr has recognized a visible approval, question, or permission surface that needs input. Idle means the agent is ready or waiting without a recognized blocker. Done is an unseen completion in the presentation model, while unknown means an agent is present but Herdr cannot classify its lifecycle confidently.
The strict meaning of blocked is one of the design's most important safeguards. Herdr does not label every prompt-shaped sentence in scrollback as a blocker. For screen-manifest agents, it marks a pane blocked only when the live bottom-buffer shape matches known approval or question UI. If a new agent release changes that shape, the likely initial failure is a false negative: the pane may appear idle until a manifest learns the new screen. That is inconvenient, but it is safer than treating uncertain text as permission to send input or take an action. Unknown likewise does not mean failure or success; it means the status evidence is insufficient.
When no rule matches for a known agent, Herdr can expose the fallback reason default_known_agent_idle_fallback in its explanation output. The agent explain command is therefore more than a name lookup. It can show the selected agent, final state, manifest source and version, the rule that matched, the evidence considered, and why a rule was skipped or fallback was used. If the state looks wrong, the operator has a way to inspect the basis of the decision instead of treating a colored dot as an opaque fact.
The server then rolls the pane-level state upward. A blocked agent makes its pane, tab, and workspace appear blocked. Working activity makes a workspace active. A completion remains done until it has been seen. This rollup changes the navigation problem: the person can begin at the workspace that needs attention rather than opening every terminal in turn. It is an attention index over the runtime, not a replacement for reading the agent's output or reviewing its code.
Consider a workspace with three panes: an agent waiting for permission, a test process still running, and a log shell that has been seen. The workspace-level blocked signal should direct the person toward the permission pane, while the working signal keeps the test activity visible as ongoing. The rollup does not flatten the panes into one state that loses the reason for attention. It points upward for navigation and remains inspectable downward at the pane and agent level.
The same design makes notifications meaningful without making them authoritative. A state transition can tell a person that a decision may be needed, but the person still has to read the terminal surface. If detection falls back to idle because no blocker rule matched, a notification may be absent even though the agent has a new kind of question. If a custom reporter claims blocked incorrectly, the state may be present but still require verification. Herdr's safety posture is therefore conservative at the input boundary: status helps decide where to inspect; it should not silently answer on the user's behalf.
“Done” needs special care when multiple clients are attached. Herdr keeps server-side seen state for CLI and API behavior, while each TUI client tracks which completions it has displayed. Viewing a completion in one client does not necessarily clear another client's Done badge. A CLI status and a particular client's sidebar can therefore disagree without either being broken. They are answering different questions: the server knows whether the completion has been marked seen in the shared runtime, while a client knows what that client has shown to its user.
The same separation appears in custom metadata. An integration or plugin can report a semantic state such as working; that state affects waits, notifications, and workspace rollups. A user hook can instead report a title such as “Refactor authentication,” a display name such as “Claude: auth,” a state label such as “refactoring,” or a token such as “model.” Those values change what the sidebar says, not what Herdr believes about lifecycle. Keeping the two channels separate prevents a descriptive label from accidentally taking over the authority that controls an automated wait.
Asynchronous reporting introduces its own hazards. Reports from hooks can arrive out of order, especially when an agent starts a new session or several events are being processed. Herdr allows a source to provide a monotonically increasing sequence number and ignores stale reports from that source when applying state. Short-lived metadata can carry a time-to-live so a temporary label expires instead of remaining as false context forever. These mechanisms govern arbitration and presentation; they do not validate that a custom reporter is honest or that its interpretation of the agent is correct.
The distinction is useful in a real workflow. Imagine a custom indexer running beside an agent. The indexer can report a summary token such as “indexing” and keep it refreshed while work continues. It should not report the agent as idle merely because the indexer has finished its own scan. Conversely, an official agent hook can report that the coding process is idle while a separate user hook supplies a more readable task title. The semantic channel answers coordination questions; the metadata channel improves orientation.
This is also why Herdr can support agents that are not fully integrated. An unsupported or partially tested agent can still run normally as a terminal process. It may receive less reliable lifecycle awareness, and the sidebar may show unknown or a cautious idle fallback, but Herdr does not need to wrap the agent to preserve its terminal. A custom integration can add reports later if the agent exposes suitable hooks. The extension should be designed around the missing fact—lifecycle, session identity, or presentation—not added simply because the pane looks untidy.
For operators, the practical rule is simple. Use the sidebar to prioritize inspection. When a state matters to an automated decision, identify its authority and inspect the evidence with the CLI or API. Treat a blocked state as a request to look at the approval surface, not as permission to answer automatically. Treat an idle or done state as readiness for the next human action, not as evidence that the agent's change is correct. And treat unknown as a real state with a real cost: the safe response is to read the pane, not to fill the gap with confidence.
Herdr's awareness mechanism therefore completes the server-owned terminal model without replacing it. The process still produces the work; the terminal still contains the evidence; Herdr adds a cautious interpretation and a route to the pane that deserves attention. The next question is what remains true when two such panes are working in parallel and the runtime itself moves through detach, restart, or replacement. A status badge can guide attention, but only a lifecycle model can say what will still be there afterward.