Skip to content

Agent-detection override is a no-op: Herdr reads overrides only from ~/.config/herdr/agent-detection/<known-kind>.toml, and cmd needs a Herdr binary update to be a kind #2

Description

@pback34

Summary

The setup action seeds config/agent-detection/cmd.toml, and the README says that makes Herdr recognize the cmd process. On this machine that file has no effect, and it cannot have one: Herdr resolves detection overrides per known agent kind from the platform config dir only, and cmd is not a kind in the Herdr binary. The hook path is what actually works (and works well), so this looks like dead code plus a misleading README line.

Environment

  • Herdr 0.8.2, Linux 7.2.5 (omarchy)
  • herdr agent kinds: pi|claude|codex|gemini|cursor|devin|agy|cline|omp|mastracode|opencode|copilot|kimi|kiro|droid|amp|grok|hermes|kilo|qodercli|qwen|maki — no cmd
  • plugin 0.1.0 @ ce4aa8f2ba31215c3d5b3d7f3455ae7523902664 (same as upstream main today), installed from GitHub
  • Command Code (cmd) on PATH, running in a Herdr pane with the hook installed

What already works

The hook path is solid. ~/.commandcode/settings.json carries SessionStart, PreToolUse, PostToolUse, Stop, and the pane is fully visible to Herdr (trimmed from herdr agent list):

{"agent":"cmd","agent_status":"working","name":"readaway-deepseek","pane_id":"w2:p1",
 "display_agent":"cmd · deepseek/deepseek-v4.1-flash","title":"Code Review",
 "tokens":{"agent_label":"@readaway-deepseek (cmd)","model":"deepseek/deepseek-v4.1-flash"}}

agent get, agent list, agent read and agent wait all resolve it:

$ herdr agent wait w2:p1 --until working --timeout 5000
# exit 0, returns the agent record

What does not work

$ herdr agent prompt w2:p1 "test"
{"error":{"code":"agent_not_ready","message":"agent w2:p1 is not an active named agent"},"id":"cli:agent:prompt"}

Identical by name (agent prompt readaway-deepseek ...). herdr agent explain w2:p1 returns agent_explain_unavailable: agent target w2:p1 does not have a detected agent label.

Why the override cannot help

Three independent reasons, in increasing order of severity:

1. Wrong directory. Herdr reads detection overrides from the platform config dir only. Upstream src/detect/manifest.rs:

fn override_path(agent: Agent) -> Option<PathBuf> {
    Some(
        crate::config::config_dir()
            .join("agent-detection")
            .join(format!("{}.toml", agent_label(agent))),
    )
}

The docs agree: ~/.config/herdr/agent-detection/<agent>.toml. scripts/common.sh::ensure_agent_detection() writes to $HERDR_PLUGIN_CONFIG_DIR/agent-detection/cmd.toml, i.e. ~/.config/herdr/plugins/config/commandcode.integration/agent-detection/cmd.toml on this machine. Nothing in the detection path reads the plugin config dir (HERDR_PLUGIN_CONFIG_DIR appears only in src/plugin_paths.rs, never in src/detect/). Here ~/.config/herdr/agent-detection/ does not even exist.

2. Invalid manifest schema. The fields in the seeded file do not exist in Herdr's detection-manifest schema. The manifest keys are id, version, min_engine_version, updated_at, aliases, rules, and rules are screen-region matchers (region, contains, regex, line_regex, state, priority, visible_*, …) — see any bundled manifest such as src/detect/manifests/claude.toml. There is no [[agent]], name, match_cmdline or alt_cmdline anywhere:

$ strings $(command -v herdr) | grep -c match_cmdline
0
$ herdr api schema --json | grep -o match_cmdline
   # no output

(The file's own comment suggests herdr api schema --json as the way to verify the field names — that check fails.) Herdr's scripts/agent_detection_manifest_check.py would reject it as unknown manifest field(s): agent.

3. Even a schema-correct override cannot register a new agent. override_path takes an Agent enum value, so overrides only replace rules for a kind Herdr already handles. From the Herdr docs: "Remote manifests patch detection rules for agents Herdr already knows how to identify. Adding a completely new agent still requires a Herdr binary update for process detection, labels, and integration behavior." cmd is absent from the binary's kind list and from its strings entirely.

Impact

  • The README claim "seeds an agent-detection override so Herdr recognizes the cmd process" is not what happens. Identity actually comes from the hook's pane report-agent / report-metadata calls.
  • It misdirects debugging. Anyone hitting agent prompt's agent_not_ready will look at detection, when the real cause is that cmd has no input driver in Herdr.
  • Suggested README addition: for cmd, agent prompt and agent send-keys cannot work until Herdr adds the kind, but agent list, agent get, agent wait, agent read and the whole pane surface do. So the working way to hand work to a cmd pane today is pane runpane wait-output --match <sentinel>pane read, with the file-handoff pattern for multi-line prompts. One caveat worth documenting: with the current hook mapping a turn that makes no tool calls can stay idle, so agent wait --until idle can return immediately — treat it as a hint and the sentinel as proof.

Suggested fix

Either drop ensure_agent_detection and config/agent-detection/cmd.toml and correct the README to say identity comes from the hook, or keep them with a note that they need a Herdr version that knows cmd as a kind. Happy to send a PR for whichever you prefer.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions