/herdr
Drive the herdr terminal workspace manager: inspect workspaces, tabs, and panes, hand work to sibling coding agents and read their results, split panes for collaborative file viewing, and correlate panes to Claude sessions. Use when coordinating with another agent, opening a
$ npx -y skills add bendrucker/claude --skill herdr --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.
- You can call itInvoke it directly when you want it.
- Slash command
/herdr
Context preview
The summary Claude sees to decide when to auto-load this skill.
Drive the herdr terminal workspace manager: inspect workspaces, tabs, and panes, hand work to sibling coding agents and read their results, split panes for collaborative file viewing, and correlate panes to Claude sessions. Use when coordinating with another agent, opening a
SKILL.md
herdr.SKILL.mdname: herdr
description: >-
Drive the herdr terminal workspace manager: inspect workspaces, tabs, and panes, hand work to sibling coding agents and read their results, split panes for collaborative file viewing, and correlate panes to Claude sessions. Use when coordinating with another agent, opening a file alongside the user, capturing another pane's output, or asking what else is running.
argument-hint: "[orient | agents | view <file> | read <pane>]"
allowed-tools:
- Bash(bash ${CLAUDE_SKILL_DIR}/scripts/orient.sh)
- Bash(herdr api snapshot:*)
- Bash(herdr --help:*)
- Bash(herdr agent --help:*)
- Bash(herdr pane --help:*)
- Bash(herdr workspace --help:*)
- Bash(herdr tab --help:*)
- Bash(herdr worktree --help:*)
- Bash(herdr agent list:*)
- Bash(herdr agent get:*)
- Bash(herdr agent read:*)
- Bash(herdr agent explain:*)
- Bash(herdr pane list:*)
- Bash(herdr pane get:*)
- Bash(herdr pane read:*)
- Bash(herdr workspace list:*)
- Bash(herdr tab list:*)Herdr
herdr manages the terminal workspace this session runs in. It knows every workspace, pane, and sibling coding agent, including which Claude session occupies which pane.
Arguments
`$0` (optional verb) routes to a section: `orient` to [Current Workspace](#current-workspace), `agents` to [Working With Sibling Agents](#working-with-sibling-agents), `view <file>` to [Collaborative File Viewing](#collaborative-file-viewing), `read <pane>` to [Capturing Another Pane](#capturing-another-pane). With no verb, answer from the orientation block below.
Check Help Before Composing a Call
herdr ships roughly weekly. This file deliberately does not restate its command surface, because a copy of `--help` output goes stale between releases.
Before composing any call, run `herdr <group> --help` for the subcommand list and `herdr <group> <command> --help` for its arguments. Leaf help is complete: it prints defaults, enumerates valid values for every enum flag, and states preconditions. Where this file and the CLI disagree, the CLI is right and this file is stale.
The orientation block below prints the running `version` and `protocol`. If either has moved well past what you see in the examples here, trust `--help` over the examples.
Current Workspace
!`bash ${CLAUDE_SKILL_DIR}/scripts/orient.sh`
That view is a projection over `herdr api snapshot`, which returns workspaces, tabs, panes, layouts, and agents in one call. Prefer it to a sequence of `list` calls. When the projection looks wrong or omits something, read the source: `herdr api snapshot | jq .`
If the block reports that herdr is not running, stop here and use ordinary tools. Nothing below will reach a server.
Reading the Output
Structured queries answer with a single-line JSON envelope. Pipe them through `jq -r '.result...'` rather than reading them raw:
{"id":"cli:pane:list","result":{"panes":[...],"type":"pane_list"}}Commands that return terminal content or a human explanation print plain text instead, with no envelope. `pane read`, `agent read`, and `agent explain` are all in that group. Piping those through `jq` fails with a parse error.
Your own identity comes from the environment, never from inference: `HERDR_PANE_ID`, `HERDR_TAB_ID`, `HERDR_WORKSPACE_ID`, `HERDR_SOCKET_PATH`.
Working With Sibling Agents
The most valuable thing herdr offers is a handle on the other agents running alongside you. Each agent pane carries `agent_session.value`, the Claude session UUID. That makes pane-to-session correlation exact, where a title match would only be a guess.
The loop is find, hand off, wait, collect:
herdr agent list | jq -r '.result.agents[] | "\(.pane_id) \(.agent_status) \(.foreground_cwd)"'
herdr agent prompt <target> "the request"
herdr agent wait <target> --until idle --timeout 600000
herdr agent read <target> --source recent --lines 80
`agent read` prints the pane's text directly. It needs no `jq`.
A reference to work by branch, repo, or task usually names a pane already doing it. Match it against the `cwd` and `title` columns in the orientation block, then hand off to that pane instead of duplicating the checkout here.
`herdr agent focus` brings a pane to the foreground for the user. `herdr agent attach` connects to it directly.
Where Agent Status Comes From
For Claude, herdr's integration hook reports only session identity. The `idle`, `working`, `blocked`, and `done` states come from matching the pane's screen against a detection manifest. An unusual or suppressed terminal title therefore reads as `unknown`.
Debug that with `herdr agent explain <pane>`. Do not paper over a detection gap by calling `herdr pane report-agent`, which claims lifecycle authority that belongs to the scraper for Claude panes.
Collaborative File Viewing
When working through a file with the user, open it beside this pane so they watch it change:
pane=$(herdr pane split --direction right --ratio 0.4 --no-focus | jq -r '.result.pane.pane_id')
herdr pane run "$pane" markless --watch path/to/file.md
Use `markless --watch` for markdown and `$EDITOR` for everything else. Keep `--no-focus` so the user's cursor stays where it is.
`pane run` hands the command string to the pane's own interactive shell, which parses it a second time. One command with ordinary quoting survives that. A multi-statement script does not: the pane's zsh re-parses it and dies on a bare `parse error`, and that failure lands in the pane rather than in your tool result. Write anything past a single command to a file and run `bash <path>`.
That shell also inherits the new pane's directory, and mise activates tools per directory. A mise-managed tool available elsewhere can still come back `command not found` here. Confirm the pane actually started the viewer before telling the user to look at it:
herdr pane read "$pane" --source visible --lines 8
Fall back to `glow -w 0` or `bat --paging always` w
Read more
name: herdr
description: >-
Drive the herdr terminal workspace manager: inspect workspaces, tabs, and panes, hand work to sibling coding agents and read their results, split panes for collaborative file viewing, and correlate panes to Claude sessions. Use when coordinating with another agent, opening a file alongside the user, capturing another pane's output, or asking what else is running.
argument-hint: "[orient | agents | view <file> | read <pane>]"
allowed-tools:
- Bash(bash ${CLAUDE_SKILL_DIR}/scripts/orient.sh)
- Bash(herdr api snapshot:*)
- Bash(herdr --help:*)
- Bash(herdr agent --help:*)
- Bash(herdr pane --help:*)
- Bash(herdr workspace --help:*)
- Bash(herdr tab --help:*)
- Bash(herdr worktree --help:*)
- Bash(herdr agent list:*)
- Bash(herdr agent get:*)
- Bash(herdr agent read:*)
- Bash(herdr agent explain:*)
- Bash(herdr pane list:*)
- Bash(herdr pane get:*)
- Bash(herdr pane read:*)
- Bash(herdr workspace list:*)
- Bash(herdr tab list:*)Herdr
herdr manages the terminal workspace this session runs in. It knows every workspace, pane, and sibling coding agent, including which Claude session occupies which pane.
Arguments
`$0` (optional verb) routes to a section: `orient` to [Current Workspace](#current-workspace), `agents` to [Working With Sibling Agents](#working-with-sibling-agents), `view <file>` to [Collaborative File Viewing](#collaborative-file-viewing), `read <pane>` to [Capturing Another Pane](#capturing-another-pane). With no verb, answer from the orientation block below.
Check Help Before Composing a Call
herdr ships roughly weekly. This file deliberately does not restate its command surface, because a copy of `--help` output goes stale between releases.
Before composing any call, run `herdr <group> --help` for the subcommand list and `herdr <group> <command> --help` for its arguments. Leaf help is complete: it prints defaults, enumerates valid values for every enum flag, and states preconditions. Where this file and the CLI disagree, the CLI is right and this file is stale.
The orientation block below prints the running `version` and `protocol`. If either has moved well past what you see in the examples here, trust `--help` over the examples.
Current Workspace
!`bash ${CLAUDE_SKILL_DIR}/scripts/orient.sh`
That view is a projection over `herdr api snapshot`, which returns workspaces, tabs, panes, layouts, and agents in one call. Prefer it to a sequence of `list` calls. When the projection looks wrong or omits something, read the source: `herdr api snapshot | jq .`
If the block reports that herdr is not running, stop here and use ordinary tools. Nothing below will reach a server.
Reading the Output
Structured queries answer with a single-line JSON envelope. Pipe them through `jq -r '.result...'` rather than reading them raw:
{"id":"cli:pane:list","result":{"panes":[...],"type":"pane_list"}}Commands that return terminal content or a human explanation print plain text instead, with no envelope. `pane read`, `agent read`, and `agent explain` are all in that group. Piping those through `jq` fails with a parse error.
Your own identity comes from the environment, never from inference: `HERDR_PANE_ID`, `HERDR_TAB_ID`, `HERDR_WORKSPACE_ID`, `HERDR_SOCKET_PATH`.
Working With Sibling Agents
The most valuable thing herdr offers is a handle on the other agents running alongside you. Each agent pane carries `agent_session.value`, the Claude session UUID. That makes pane-to-session correlation exact, where a title match would only be a guess.
The loop is find, hand off, wait, collect:
herdr agent list | jq -r '.result.agents[] | "\(.pane_id) \(.agent_status) \(.foreground_cwd)"' herdr agent prompt <target> "the request" herdr agent wait <target> --until idle --timeout 600000 herdr agent read <target> --source recent --lines 80
`agent read` prints the pane's text directly. It needs no `jq`.
A reference to work by branch, repo, or task usually names a pane already doing it. Match it against the `cwd` and `title` columns in the orientation block, then hand off to that pane instead of duplicating the checkout here.
`herdr agent focus` brings a pane to the foreground for the user. `herdr agent attach` connects to it directly.
Where Agent Status Comes From
For Claude, herdr's integration hook reports only session identity. The `idle`, `working`, `blocked`, and `done` states come from matching the pane's screen against a detection manifest. An unusual or suppressed terminal title therefore reads as `unknown`.
Debug that with `herdr agent explain <pane>`. Do not paper over a detection gap by calling `herdr pane report-agent`, which claims lifecycle authority that belongs to the scraper for Claude panes.
Collaborative File Viewing
When working through a file with the user, open it beside this pane so they watch it change:
pane=$(herdr pane split --direction right --ratio 0.4 --no-focus | jq -r '.result.pane.pane_id') herdr pane run "$pane" markless --watch path/to/file.md
Use `markless --watch` for markdown and `$EDITOR` for everything else. Keep `--no-focus` so the user's cursor stays where it is.
`pane run` hands the command string to the pane's own interactive shell, which parses it a second time. One command with ordinary quoting survives that. A multi-statement script does not: the pane's zsh re-parses it and dies on a bare `parse error`, and that failure lands in the pane rather than in your tool result. Write anything past a single command to a file and run `bash <path>`.
That shell also inherits the new pane's directory, and mise activates tools per directory. A mise-managed tool available elsewhere can still come back `command not found` here. Confirm the pane actually started the viewer before telling the user to look at it:
herdr pane read "$pane" --source visible --lines 8
Fall back to `glow -w 0` or `bat --paging always` w
Showing the first part of this file.
My personal plugin marketplace for Claude Code, Anthropic's AI coding assistant.
Repo: bendrucker/claude
Other skills on bendrucker-claude.
- /agent-ideas
Harvest agent-tooling ideas from prominent developers.
Open skill - /cleye
Type-safe CLI argument parsing with cleye, the standard parser for this repo's Bun scripts. Use when writing or editing any script that takes arguments (flags, positional parameters, subcommands, --help) instead of reading existing scripts for the pattern.
Open skill - /coverage
Measure Bun test coverage and close gaps on a specific file. Use when adding or editing tests, when asked about coverage, or when the PostToolUse coverage hook reports uncovered lines.
Open skill - /activity
Report real device usage from ActivityWatch. Covers per-app time, window titles, and active vs idle spans. Use when asked "what apps did I use", "how long was I in X", "what did I work on today", "how much was I active vs idle", or to mine usage patterns for automation.
Open skill - /history
Report shell history from atuin's local capture. Covers what commands ran, when, where, and how they exited. Use when asked "what commands did I run", "what was I working on in the terminal", "have I ever run X", "how do I usually invoke X", or about recent shell activity,
Open skill - /bun
Bun runtime patterns. Use when running bun commands, working with package.json/bun.lock, writing TypeScript scripts under Bun, or developing Claude Code plugins.
Open skill

