/herdr
Drive the herdr terminal workspace manager: inspect workspaces, tabs, and panes, hand work to sibling coding agents in other panes (distinct from in-session `Agent` subagents), split panes for collaborative file viewing or long-running processes, and correlate panes to Claude
$ 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.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- 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 in other panes (distinct from in-session `Agent` subagents), split panes for collaborative file viewing or long-running processes, and correlate panes to Claude
SKILL.md
herdr.SKILL.mdname: herdr
description: >-
Drive the herdr terminal workspace manager: inspect workspaces, tabs, and panes, hand work to sibling coding agents in other panes (distinct from in-session `Agent` subagents), split panes for collaborative file viewing or long-running processes, and correlate panes to Claude sessions. Load this when the decision to hand a task to another pane's agent arrives mid-task, and when opening a file alongside the user, starting a dev server or log tail the user should watch, capturing another pane's output, or asking what else is running. Pane, tab, workspace, and split are herdr's terms. A request naming one is a herdr request even when it never says herdr.
argument-hint: "[orient | agents | view <file> | read <pane>]"
allowed-tools:
- Bash(bash ${CLAUDE_SKILL_DIR}/scripts/orient.sh)
- Bash(bash ${CLAUDE_SKILL_DIR}/scripts/commands.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 plugin --help:*)
- Bash(herdr worktree --help:*)
- Bash(herdr agent prompt --help:*)
- Bash(herdr agent start --help:*)
- Bash(herdr agent list:*)
- Bash(herdr agent get:*)
- Bash(herdr agent read:*)
- Bash(herdr agent wait:*)
- Bash(herdr agent explain:*)
- Bash(herdr pane list:*)
- Bash(herdr pane get:*)
- Bash(herdr pane current:*)
- Bash(herdr pane read:*)
- Bash(herdr pane layout:*)
- Bash(herdr pane wait-output:*)
- Bash(herdr workspace list:*)
- Bash(herdr worktree list:*)
- Bash(herdr tab list:*)
- Bash(herdr plugin list:*)
- Bash(herdr plugin action list:*)
- Bash(herdr plugin log list:*)
- Bash(herdr plugin config-dir:*)Herdr
herdr manages the terminal workspace this session runs in, including every pane, tab, and sibling coding agent.
Under `HERDR_ENV=1`, a request naming a pane, tab, workspace, or split is about this session's herdr layout.
Command Surface
!`bash ${CLAUDE_SKILL_DIR}/scripts/commands.sh`
For flags not shown above, `herdr <group> <command> --help` is complete: defaults, valid values for every enum flag, preconditions. Where the CLI and this file disagree, the CLI is right and this file is stale.
Bare `herdr` launches or attaches the TUI in this pane. A mutating command in bare form runs on its defaults instead of printing usage, so `herdr workspace create` creates a workspace.
Current Workspace
!`bash ${CLAUDE_SKILL_DIR}/scripts/orient.sh`
Columns are workspace, then `pane agent/status session cwd title`, with `cwd` shown only when it differs from the workspace checkout. That view projects `herdr api snapshot`, which returns workspaces, tabs, panes, layouts, and agents in one call. Prefer it to a sequence of `list` calls, and read it raw when the projection is wrong: `herdr api snapshot | jq .`
If the block reports a failure instead of a workspace listing, stop here and use ordinary tools. Nothing below reaches a server.
Output Formats
Most commands 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"}}Others print plain text, and `jq` on those dies with `Invalid numeric literal`. Terminal content and human explanations are one kind: `pane read`, `agent read`, `agent explain`. Anything reporting local installation instead of live session state is the other: `plugin list`, `plugin config-dir`, `config check`, `integration status`, `server agent-manifests`.
Exit 1 is a server error with JSON on stderr: parse it. Exit 2 is a syntax error, wrong before it reached the server.
Addressing
A pane exists whether or not an agent runs in it. `pane` commands drive the raw terminal, and `agent` commands drive the recognized process inside one.
An agent target is a live agent name or the pane ID hosting it, and nothing else. `agent list` prints a `terminal_id` and an `agent` kind beside those, and either one passed as a target yields `agent_not_found`, indistinguishable from a missing agent.
Your own identity comes from the environment, never from inference: `HERDR_ENV`, `HERDR_PANE_ID`, `HERDR_TAB_ID`, `HERDR_WORKSPACE_ID`, `HERDR_SOCKET_PATH`. `HERDR_ENV=1` marks a pane herdr launched.
Name a target on every command that takes one. Use `--current` for the calling pane, an explicit ID otherwise. A pane command with no target may resolve to the UI-focused pane, which can belong to the user or another client.
IDs are opaque handles shaped `w1` for a workspace, `w1:t1` for a tab, and `w1:p1` for a pane. Read them out of responses rather than composing them: `pane split` returns `.result.pane`, `tab create` returns `.result.tab` and `.result.root_pane`, `workspace create` returns all three. Closed IDs are never reused. `pane move` mints a new workspace-qualified pane ID, so take the pane forward as `.result.move_result.pane.pane_id` and drop `.result.move_result.previous_pane_id`. The moved process keeps the stale ID in its inherited `HERDR_PANE_ID`, so never take a target from there.
Splits
Default to a sibling pane in the current tab under the caller's `$PWD`. A separate workspace, tab, worktree, or directory needs the user to ask for it.
Split `right` on a wide pane and `down` on a tall one, alternating direction across successive splits rather than slicing one axis into an unusable strip. `herdr pane layout --pane "$HERDR_PANE_ID"` reads the shape when it is not obvious.
`--no-focus` keeps the user's cursor where it is. Move focus only when they asked to switch.
Safety
Leave the server alone. `herdr server stop` takes down every pane process the session owns, this one included, so run it only when the user asks for exactly that. Signalling the main herdr process does the same. An experiment needing its own server gets `herdr --session <name>`.
Close only what you opened. A pane y
Read more
name: herdr
description: >-
Drive the herdr terminal workspace manager: inspect workspaces, tabs, and panes, hand work to sibling coding agents in other panes (distinct from in-session `Agent` subagents), split panes for collaborative file viewing or long-running processes, and correlate panes to Claude sessions. Load this when the decision to hand a task to another pane's agent arrives mid-task, and when opening a file alongside the user, starting a dev server or log tail the user should watch, capturing another pane's output, or asking what else is running. Pane, tab, workspace, and split are herdr's terms. A request naming one is a herdr request even when it never says herdr.
argument-hint: "[orient | agents | view <file> | read <pane>]"
allowed-tools:
- Bash(bash ${CLAUDE_SKILL_DIR}/scripts/orient.sh)
- Bash(bash ${CLAUDE_SKILL_DIR}/scripts/commands.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 plugin --help:*)
- Bash(herdr worktree --help:*)
- Bash(herdr agent prompt --help:*)
- Bash(herdr agent start --help:*)
- Bash(herdr agent list:*)
- Bash(herdr agent get:*)
- Bash(herdr agent read:*)
- Bash(herdr agent wait:*)
- Bash(herdr agent explain:*)
- Bash(herdr pane list:*)
- Bash(herdr pane get:*)
- Bash(herdr pane current:*)
- Bash(herdr pane read:*)
- Bash(herdr pane layout:*)
- Bash(herdr pane wait-output:*)
- Bash(herdr workspace list:*)
- Bash(herdr worktree list:*)
- Bash(herdr tab list:*)
- Bash(herdr plugin list:*)
- Bash(herdr plugin action list:*)
- Bash(herdr plugin log list:*)
- Bash(herdr plugin config-dir:*)Herdr
herdr manages the terminal workspace this session runs in, including every pane, tab, and sibling coding agent.
Under `HERDR_ENV=1`, a request naming a pane, tab, workspace, or split is about this session's herdr layout.
Command Surface
!`bash ${CLAUDE_SKILL_DIR}/scripts/commands.sh`
For flags not shown above, `herdr <group> <command> --help` is complete: defaults, valid values for every enum flag, preconditions. Where the CLI and this file disagree, the CLI is right and this file is stale.
Bare `herdr` launches or attaches the TUI in this pane. A mutating command in bare form runs on its defaults instead of printing usage, so `herdr workspace create` creates a workspace.
Current Workspace
!`bash ${CLAUDE_SKILL_DIR}/scripts/orient.sh`
Columns are workspace, then `pane agent/status session cwd title`, with `cwd` shown only when it differs from the workspace checkout. That view projects `herdr api snapshot`, which returns workspaces, tabs, panes, layouts, and agents in one call. Prefer it to a sequence of `list` calls, and read it raw when the projection is wrong: `herdr api snapshot | jq .`
If the block reports a failure instead of a workspace listing, stop here and use ordinary tools. Nothing below reaches a server.
Output Formats
Most commands 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"}}Others print plain text, and `jq` on those dies with `Invalid numeric literal`. Terminal content and human explanations are one kind: `pane read`, `agent read`, `agent explain`. Anything reporting local installation instead of live session state is the other: `plugin list`, `plugin config-dir`, `config check`, `integration status`, `server agent-manifests`.
Exit 1 is a server error with JSON on stderr: parse it. Exit 2 is a syntax error, wrong before it reached the server.
Addressing
A pane exists whether or not an agent runs in it. `pane` commands drive the raw terminal, and `agent` commands drive the recognized process inside one.
An agent target is a live agent name or the pane ID hosting it, and nothing else. `agent list` prints a `terminal_id` and an `agent` kind beside those, and either one passed as a target yields `agent_not_found`, indistinguishable from a missing agent.
Your own identity comes from the environment, never from inference: `HERDR_ENV`, `HERDR_PANE_ID`, `HERDR_TAB_ID`, `HERDR_WORKSPACE_ID`, `HERDR_SOCKET_PATH`. `HERDR_ENV=1` marks a pane herdr launched.
Name a target on every command that takes one. Use `--current` for the calling pane, an explicit ID otherwise. A pane command with no target may resolve to the UI-focused pane, which can belong to the user or another client.
IDs are opaque handles shaped `w1` for a workspace, `w1:t1` for a tab, and `w1:p1` for a pane. Read them out of responses rather than composing them: `pane split` returns `.result.pane`, `tab create` returns `.result.tab` and `.result.root_pane`, `workspace create` returns all three. Closed IDs are never reused. `pane move` mints a new workspace-qualified pane ID, so take the pane forward as `.result.move_result.pane.pane_id` and drop `.result.move_result.previous_pane_id`. The moved process keeps the stale ID in its inherited `HERDR_PANE_ID`, so never take a target from there.
Splits
Default to a sibling pane in the current tab under the caller's `$PWD`. A separate workspace, tab, worktree, or directory needs the user to ask for it.
Split `right` on a wide pane and `down` on a tall one, alternating direction across successive splits rather than slicing one axis into an unusable strip. `herdr pane layout --pane "$HERDR_PANE_ID"` reads the shape when it is not obvious.
`--no-focus` keeps the user's cursor where it is. Move focus only when they asked to switch.
Safety
Leave the server alone. `herdr server stop` takes down every pane process the session owns, this one included, so run it only when the user asks for exactly that. Signalling the main herdr process does the same. An experiment needing its own server gets `herdr --session <name>`.
Close only what you opened. A pane y
My personal plugin marketplace for Claude Code, Anthropic's AI coding assistant.
Repo: bendrucker/claude
Other skills on bendrucker-claude.
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,…
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…
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…
bun
Bun runtime patterns. Use when running bun commands, working with package.json/bun.lock, writing TypeScript scripts under Bun, or developing Claude Code…
agent-team
Orchestrating Claude Code agent teams. Use when creating teams, spawning teammates, assigning tasks, configuring teammate modes, or setting up team quality…

