Herdr

SkillAI & models

Control live Herdr workspaces, tabs, panes, agents, worktrees, plugins, and waits. Use when running inside Herdr (`HERDR_ENV=1`) to inspect sibling agents, delegate work—including dedicated Pi workspaces—run services, debug agent detection, or coordinate terminal state.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Herdr skill

What this skill tells your AI

The instructions your AI receives, as published by edmundmiller/dotfiles in skills/conditional/herdr/herdr/SKILL.md and read by ahel’s review.

Control the current Herdr session through its high-level CLI wrappers. Prefer semantic agent commands for agent lifecycle and communication; use pane commands for shells, processes, terminal input, and output.

Guard

Check HERDR_ENV=1 before controlling a session. If absent, report that the current pane is not Herdr-managed and stop. Do not infer the focused pane from outside Herdr.

test "${HERDR_ENV:-}" = 1

Treat Herdr IDs as live handles, not durable identifiers. Parse IDs from command responses or use --current; never hard-code example IDs into automation.

Choose the narrowest surface

  1. Harness resource: When herdr:// reads are supported, inspect herdr://status, herdr://snapshot, herdr://workspaces, herdr://tabs?workspace=…, herdr://panes?workspace=…, or herdr://pane/<id>?source=recent&lines=80. This avoids shell parsing.
  2. Agent CLI: Use herdr agent list|get|read|send-keys|prompt|rename|focus|wait|attach|start|explain for detected agents.
  3. Resource CLI: Use workspace, tab, pane, worktree, and integration commands for terminal topology and processes.
  4. Raw API: Use only for protocol clients or event subscriptions. Inspect the installed schema first with herdr api schema --json.

herdr --skill prints the agent skill bundled with the installed binary. Treat it as the version-accurate baseline when installed behavior and this skill disagree.

Read references/cli-map.md for the command map and references/recipes.md for trace-tested coordination and recovery patterns.

Inspect before acting

Start from live state:

herdr agent list
herdr pane current
herdr workspace list

For one agent, gather semantic state, recent output, and detection evidence:

~/.agents/skills/herdr/scripts/agent_context.py <agent-name-or-pane-id> --lines 80

Use agent explain when status is wrong, stuck, or unknown; do not guess from screen text alone.

Coordinate agents semantically

Agent start requires an existing pane sitting at an interactive shell prompt; it never creates layout. Create the pane first, then start the agent in it:

split=$(herdr pane split --current --direction right --cwd "$PWD" --no-focus)
review_pane=$(printf '%s\n' "$split" | ~/.agents/skills/herdr/scripts/extract_ids.py pane)
herdr agent start reviewer --kind omp --pane "$review_pane"
herdr agent prompt reviewer "Review the current changes and report only actionable findings." \
  --wait --timeout 120000
herdr agent read reviewer --source recent-unwrapped --lines 100

Use names only when unique. Otherwise use the pane ID returned by pane split or a fresh agent list response. Agent names match [a-z][a-z0-9_-]{0,31} and must be unique among live agents; use herdr agent rename <pane> <name> to name a manually launched agent.

agent prompt submits the text plus an encoded Enter in one call and honors bracketed paste. Plain --wait waits for the first settled idle, done, or blocked state — that is the default for normal work, so do not restate it as --until done. Use --until only for a state-specific workflow such as waiting for blocked; it requires --wait. From a non-working state, a lifecycle change must be observed within 5s or the call returns agent_prompt_stalled; --wait tracks lifecycle state, not turns.

State meanings: idle = ready for input AND its tab has been seen in the focused UI. done = the same ready state after background work, held until the tab gains focus. Focusing the tab, or targeting the pane/agent with a focus command, marks it seen; CLI reads do not. blocked = an approval or question UI is up. unknown is not a successful completion. A status wait observes agent state, not arbitrary command completion.

Run processes in panes

Use pane primitives for servers, tests, logs, and shells:

SPLIT=$(herdr pane split --current --direction right --no-focus)
# Parse the new pane_id from SPLIT; do not predict it.
herdr pane run <pane-id> "npm run dev"
herdr pane wait-output <pane-id> --match "ready" --timeout 30000
herdr pane read <pane-id> --source recent-unwrapped --lines 40

pane wait-output searches the selected snapshot immediately, including output that already arrived, before it polls — so it is safe for output that may have landed already. Use --match <text> for a literal substring or --regex <pattern> for a Rust regex; omitting --timeout waits indefinitely. Read recent-unwrapped when matching or copying text so soft wraps do not corrupt it. Use --source detection to see the plain-text bottom-buffer snapshot Herdr itself uses for agent detection.

Workspaces, worktrees, and layouts

Use a workspace for a project context, a tab for a subcontext, and a pane for one process. Prefer Herdr worktree commands when isolation is part of the task:

herdr worktree list
herdr worktree create --help
herdr workspace create --cwd /path/to/project --label api --no-focus

Inspect installed help before using less-common worktree/plugin flags; these evolve faster than the core commands. Worktree commands are JSON-only and no longer advertise --json, though the flag is still accepted.

workspace create also creates the first tab and its root pane — parse .result.root_pane.pane_id and use that pane before splitting further. Likewise tab create returns .result.root_pane.

There is no layout export/apply in 0.8.0. Capture herdr pane layout output for reference and script workspace create/pane split sequences that parse returned IDs:

herdr pane layout --current

Input rules

  • Use agent prompt for agent prompts (submits text plus encoded Enter in one call; honors bracketed paste).
  • Use pane run for shell command text followed by Enter.
  • Use pane send-text plus pane send-keys … enter for literal TUI input when no agent adapter applies.
  • Pass key combos such as ctrl+h, shift+tab, or named punctuation. Do not pass configuration strings such as prefix+] to send-keys.
  • Use agent send-keys for agent UI interaction (esc, up, enter, ctrl+c; escape aliases esc). Pane input targets the terminal regardless of occupant; agent input is rejected if the agent no longer controls the pane.

Recovery

  • Re-read IDs after closes, moves, or reconnects.
  • If a command reports an unsupported flag, inspect installed --help; do not continue from stale examples.
  • If config changed but behavior did not, run herdr server reload-config and inspect diagnostics.
  • If agent status is wrong, run herdr agent explain <target> --json before changing detection rules.
  • If an output wait times out, read recent output and agent state before retrying.
  • If a helper cannot reach Herdr, verify HERDR_SOCKET_PATH and HERDR_ENV; never scan unrelated sockets.

Known pitfalls (from session traces)

  • Nonexistent guessed commands: herdr agents, herdr agent status, herdr pane stop, herdr worktree sessions, herdr wait, herdr layout — run herdr <group> --help instead of guessing. Bare herdr is not discovery; it launches or attaches the TUI.
  • Opening a workspace or worktree auto-creates panes; run herdr agent list and reuse an existing idle agent before agent start, to avoid duplicate agents in one workspace.
  • On agent wait timeout (exit 1, JSON on stderr): run herdr agent read <t> --source recent-unwrapped --lines 80 and herdr agent explain <t> --json before retrying; never re-issue the same wait blind. Always pass --timeout — waits are indefinite by default.
  • Full-screen agents may render on the alternate screen, so those rows never enter scrollback: if a larger --lines adds no text, read --source visible after scrolling in the agent, or (fallback only) ask the agent to write its full answer to a temp file and read that.
  • Pane and agent reads set truncated: true when older rows were dropped. Do not answer from a truncated read: raise --lines (capped at 1000; there is no offset flag, so omitted older rows are unrecoverable). If it is still truncated, read a durable file/log or ask the agent to restate the result.
  • After herdr pane rename, also run herdr tab rename — stale tab labels misdirect later targeting; trust agent list cwd/session fields over labels.
  • integration install omp fails with "Pi and OMP resolve to the same extension directory" when run from a wrapped OMP that exports PI_CODING_AGENT_DIR=~/.omp/agent. Clear that variable and let PI_CONFIG_DIR place OMP: PI_CODING_AGENT_DIR= PI_CONFIG_DIR=.omp herdr integration install omp. Pi's own install passes an absolute PI_CODING_AGENT_DIR="$HOME/.pi/agent" and needs no change.

Bundled resources

  • references/cli-map.md — high-level command selection and response rules.
  • references/recipes.md — delegation, service, layout, and failure-recovery recipes.
  • references/pi-workspace.md — dedicated Pi workspace delegation and handoff workflow.
  • scripts/start_pi_workspace.py — create a workspace, launch Pi, and submit a prompt file.
  • scripts/send_prompt_to_pane.py — submit a prompt file to an existing pane.
  • scripts/write_handoff_prompt.py — generate a structured child-agent prompt.
  • scripts/monitor_pane.py and scripts/extract_ids.py — inspect delegated work and parse live IDs.
  • scripts/agent_context.py — bounded JSON snapshot of one agent's metadata, recent output, and detection explanation.
  • herdr --skill — the skill bundled with the installed binary; authoritative for the running version.
  • Upstream reference: https://herdr.dev/docs/agent-automation/ — official automation primitives for herdr 0.8.0.

Signals

GitHub stars
80
Forks
6
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
herdr-edmundmiller
Source
github.com/edmundmiller/dotfiles