---
status: resolved
parent: "[[002-pi-subagents-map]]"
blocked-by: []
tags:
  - ticket/research
---

# Herdr compatibility research

## Question

How does Herdr discover, display, and control agent processes or sessions, and what does that imply for Pi-spawned subagents that must appear under Herdr's agents section?

## Resolution

## Findings

Herdr has a first-class agent list and snapshot surface.
On this machine, `herdr agent list` returns agents with `agent`, `agent_status`, `cwd`, `foreground_cwd`, `pane_id`, `tab_id`, `terminal_id`, title, workspace, focus, revision, and state-change fields.
`herdr api snapshot` includes the same agent records plus pane, tab, workspace, and layout data.
Citation: local Herdr 0.7.5 CLI output from `herdr agent list` and `herdr api snapshot`.

Herdr's built-in status vocabulary is `idle`, `working`, `blocked`, `done`, and `unknown`.
The API schema defines that enum under `AgentStatus`, and pane records expose `agent_status`.
Citation: `herdr api schema --json`, schema definitions `event.$defs.AgentStatus` and `event.$defs.PaneInfo`.

Herdr exposes both discovery/control commands for agents and lower-level pane metadata APIs.
The CLI help lists `agent list/get/read/send-keys/prompt/rename/focus/wait/attach/start/explain`.
The API schema exposes `pane.report_agent`, `pane.report_agent_session`, and `pane.report_metadata` requests.
`pane.report_metadata` can set `agent`, `display_agent`, `title`, `state_labels`, bounded `tokens`, and TTL, while `pane.report_agent_session` can bind an `agent_session_id` or `agent_session_path` to a pane.
Citation: `herdr agent --help`, `herdr agent start --help`, and `herdr api schema --json` definitions for `PaneReportMetadataParams`, `PaneReportAgentSessionParams`, and request methods.

Herdr has built-in agent integrations, including Pi.
`herdr integration status` says the Pi integration would install to `~/.pi/agent/extensions/herdr-agent-state.ts`, and `herdr integration install --help` lists `pi` as an install target.
This implies that a Pi extension is Herdr's expected path for Pi status reporting.
Citation: `herdr integration status` and `herdr integration install --help`.

Herdr can start supported interactive agents in existing panes, and Pi is one of the supported kinds.
`herdr agent start <NAME> --kind pi --pane <ID>` waits until Herdr detects the expected agent in the same terminal and it is ready for input.
Citation: `herdr agent start --help`.

Firstmate's Herdr backend treats Herdr as a session-provider backend and records a target shaped like `<herdr-session>:<pane-id>`.
Its adapter uses Herdr workspaces/tabs/panes for visible direct reports and explicitly treats label-only matching as insufficient authority for recovery.
Citation: `/tmp/firstmate-research/firstmate/bin/backends/herdr.sh` header and `/tmp/firstmate-research/firstmate/bin/fm-spawn.sh` header from `github.com/kunchenguid/firstmate`.

## Implications

The minimum compatibility bar should be stronger than mere process launch.
A viable Pi subagent solution should create or use Herdr panes/tabs and report enough pane metadata or Pi session metadata for Herdr's agents section to show each child as a Pi agent with useful lifecycle state.

A headless child `pi --mode json` or `pi --mode rpc` process spawned outside Herdr is unlikely to satisfy the visibility requirement by itself, because Herdr's agent list is pane-centered.
The child needs either to run in a Herdr-managed pane or to be deliberately projected/reported into Herdr's pane metadata model.

The likely integration path is one of two shapes: spawn child Pi sessions through Herdr panes and rely on Herdr's Pi integration, or extend the subagent mechanism to call Herdr's pane APIs when starting and updating child sessions.
The latter needs a concrete pane target, so it is still much easier when children are visible Herdr panes.

## Limitations

I did not install Herdr's Pi integration to inspect the generated `herdr-agent-state.ts`, because that would mutate the operator's managed Pi extension directory.
The exact status protocol used by that generated extension remains to be inspected in a later task if needed.
