Skip to content
Back to skills

Herdr

ASecurity

Control Herdr tabs, panes, and coding agents when Pi runs inside Herdr.

  • 25 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 18, 2026
ai-agentsshellbash

Works with

  • terminal

Security analysis

A100/100

Scanned October 18, 2026

npx -y skills add nikolanovoselec/codeflare --skill herdr --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Herdr?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Herdr
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/nikolanovoselec-herdr/badge)](https://www.skillsdirectory.com/skills/nikolanovoselec-herdr)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: herdr
description: Control Herdr tabs, panes, and coding agents when Pi runs inside Herdr.
disable-model-invocation: true
---

# Herdr control

Use Herdr only for requested UI control or work benefiting from another live terminal or coding agent.

## Gate

Run before any Herdr command:

```bash
if [ "${HERDR_ENV:-}" != "1" ] || [ -z "${HERDR_PANE_ID:-}" ] || [ -z "${HERDR_SOCKET_PATH:-}" ]; then
  echo "not running inside Herdr"
  exit 1
fi
HERDR="${HERDR_BIN_PATH:-herdr}"
timeout 2 "$HERDR" pane current --current >/dev/null
```

If gate fails, continue as normal Codeflare terminal agent. Do not start a Herdr server or invent IDs.

## Fast UI operations

Herdr IDs can become stale after users close tabs or panes. For follow-up UI requests, query current state first when target was not created in same command sequence:

```bash
HERDR="${HERDR_BIN_PATH:-herdr}"
"$HERDR" tab list
"$HERDR" pane list
```

### Tabs

Open tab and start Pi:

```bash
HERDR="${HERDR_BIN_PATH:-herdr}"
if ! agents=$("$HERDR" agent list); then
  exit 1
fi
if ! printf '%s\n' "$agents" \
  | jq -e '.result.agents | type == "array" and all(.[]; (.name == null) or ((.name | type) == "string"))' >/dev/null; then
  exit 1
fi
index=2
while [ "$index" -le 999 ] && printf '%s\n' "$agents" \
  | jq -e --arg name "pi$index" '.result.agents[]? | select(.name == $name)' >/dev/null; do
  index=$((index + 1))
done
test "$index" -le 999
name="pi$index"
created=$("$HERDR" tab create --cwd "$PWD" --label pi)
pane=$(printf '%s\n' "$created" | jq -r '.result.root_pane.pane_id')
"$HERDR" agent start "$name" --kind pi --pane "$pane" --timeout 60000
```

Focus tab by visible number:

```bash
HERDR="${HERDR_BIN_PATH:-herdr}"
tab=$("$HERDR" tab list | jq -r '.result.tabs[] | select(.number == 2) | .tab_id')
test -n "$tab" && "$HERDR" tab focus "$tab"
```

Use returned `tab_id` directly when tab was just created. Do not assume IDs such as `w1:t2` still exist.

### Splits

Direction describes where new pane appears:

- Vertical divider / side-by-side panes: `--direction right`
- Horizontal divider / stacked panes: `--direction down`

Split focused/current pane:

```bash
HERDR="${HERDR_BIN_PATH:-herdr}"
"$HERDR" pane split --current --direction right --cwd "$PWD" --focus
"$HERDR" pane split --current --direction down --cwd "$PWD" --focus
```

`--current` means Pi agent's pane, not necessarily pane currently focused in Herdr UI. To affect UI-focused pane, resolve it from `pane list`:

```bash
HERDR="${HERDR_BIN_PATH:-herdr}"
pane=$("$HERDR" pane list | jq -r '.result.panes[] | select(.focused == true) | .pane_id')
"$HERDR" pane split --pane "$pane" --direction right --cwd "$PWD" --focus
```

Change split orientation when no direct layout command exists: preserve main pane, close disposable shell pane, then split main pane in new direction. Never close a pane with an active agent or process without user confirmation.

Close focused disposable split:

```bash
HERDR="${HERDR_BIN_PATH:-herdr}"
pane=$("$HERDR" pane list | jq -r '.result.panes[] | select(.focused == true) | .pane_id')
if [ "$pane" = "$HERDR_PANE_ID" ]; then
  echo "refusing to close current Pi pane" >&2
  exit 1
fi
"$HERDR" pane close "$pane"
```

Before closing, inspect `agent_status`, `agent`, and process state when safety is uncertain. Never close current Pi pane.

## Agent orchestration

Choose unique lowercase name after checking:

```bash
HERDR="${HERDR_BIN_PATH:-herdr}"
"$HERDR" agent list
```

Create helper without stealing focus:

```bash
HERDR="${HERDR_BIN_PATH:-herdr}"
created=$("$HERDR" tab create --cwd "$PWD" --label helper --no-focus)
pane=$(printf '%s\n' "$created" | jq -r '.result.root_pane.pane_id')
"$HERDR" agent start helper --kind pi --pane "$pane" --timeout 60000
```

Never run current Pi session file in two processes.

Wait until helper can accept work, then prompt:

```bash
HERDR="${HERDR_BIN_PATH:-herdr}"
"$HERDR" agent wait helper --until idle --until done --timeout 120000
"$HERDR" agent prompt helper "Implement focused task and report changed paths" \
  --wait --until idle --until done --until blocked --timeout 120000
```

Blocked agents reject prompts. Read UI, then use `agent send-keys` for deliberate response. Always set timeouts; Herdr waits indefinitely otherwise. Treat `unknown` as unknown, never success.

Steer working helper asynchronously:

```bash
HERDR="${HERDR_BIN_PATH:-herdr}"
"$HERDR" agent prompt helper "Adjust current work using this new constraint"
```

Herdr v0.9.0 requires observed working/blocked activity before `agent prompt --wait` completes for a previously non-working agent. That does not bind completion to steering sent while an agent is already working. Require task-specific completion evidence for that case.

Read results:

```bash
HERDR="${HERDR_BIN_PATH:-herdr}"
"$HERDR" agent read helper --source recent-unwrapped --lines 200
```

For long alternate-screen output, ask helper to write Markdown under `/tmp`, return path, then read file. Reading does not focus tab or mark `done` seen.

Prefer `agent` commands for recognized coding agents. Use `pane run`, `pane wait-output`, and `pane read` for shells, tests, and servers. Keep helper pane open unless work finished and closing intended.

## Avoid command discovery loops

Use these known forms directly:

```bash
HERDR="${HERDR_BIN_PATH:-herdr}"
"$HERDR" tab list
"$HERDR" tab focus <tab_id>
"$HERDR" pane list
"$HERDR" pane split --pane <pane_id> --direction right|down --cwd "$PWD" --focus
"$HERDR" pane close <pane_id>
```

Use `<group> <command> --help` only when requested operation is absent above. After any `pane_not_found` or `tab_not_found`, refresh lists once and retry with resolved ID; do not guess IDs.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.