agentsclimarketplace

Herdr peer review

Skill Elio2000/herdr-peer-review

Open a second coding agent in a herdr pane and have it review your diff — watchable, auto-approve, read-only. Ships a Claude Code skill for the autonomous review↔revise↔decide loop.

Install
npx -y skills add Elio2000/herdr-peer-review

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • 22 days oldThe repository was created 22 days ago. New is not bad, but a brand new repository carrying a familiar-sounding name is the shape a typosquat arrives in, and there has been no time for anyone else to find a problem with it.
  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Drive a second ("peer") coding agent from Claude inside a herdr session, in a watchable TUI pane, so the user can SEE the multi-agent conversation. Use when running inside herdr and the user asks to have another agent review the current changes / a diff / a file, or to consult / ask another agent ("让 codex/grok review", "问一下另一个 agent", "找 X 咨询一下", "peer review", "第二意见"). The peer agent is a single swappable config knob — codex today, grok / cursor / claude / etc. tomorrow. Completion is detected via herdr's agent-status (agent-agnostic). The peer is ALWAYS launched auto-approve ("YOLO") so the loop never stalls on a prompt and can run unattended / AFK; the peer can also arbitrate decisions to close the loop with no human present. Encodes the project's Claude = Code Agent / peer = Reviewer split.

SKILL.md

18.9 KB, ~4.9k tokens by cl100k_base, as published. Nobody here has run it

peer-agent-via-herdr

Open a peer coding agent (codex now; grok / cursor / claude / … later) in its own herdr pane and drive it from Claude over herdr's socket CLI, keeping the TUI visible so the user watches the exchange live. The peer is one config knob — nothing about "codex" is baked into the flow.

The generic, agent-independent backbone is: pane split → launch the agent → agent send + Enter → wait agent-status … --status donepane read. herdr's screen-manifest state detection gives working/idle/done for common agents without any hook, so the loop is the same regardless of which agent you run; only the launch command and the answer-line marker differ.

Verification status (herdr 0.7.1, macOS):

  • Verified live with codex: the full loop below — launch, agent send + send-keys enter submit, auto workingdone detection, agent read; plus that herdr injects HERDR_ENV=1 / HERDR_PANE_ID into a pane's process (so an in-pane claude and its shells inherit them).
  • Designed-for, not yet verified per agent: grok / cursor / claude / others — the loop is generic but confirm each agent's launch command + answer marker on first use (see the config table).
  • Driving herdr is shell-agnostic (fish and zsh both fine): in the TUI path prompts go to the agent, not the shell, so shell syntax is irrelevant. Only the quiet path injects shell text. Caveat: the peer.sh helpers + the runnable recipe are bash — source them from bash (bash -c '. peer.sh; …'), not from fish. Shell-agnostic refers to the herdr commands, not peer.sh.

Configure the peer agent (the ONE place to change)

⚠️ Collaboration is ALWAYS launched auto-approve ("YOLO"). The entire point is running agents while the user is away from the keyboard — any interactive approval/choice prompt stalls the loop and defeats it. So every peer launch MUST include the agent's no-prompt flags; never launch a bare TUI that can block on a confirmation.

Auto-approve (no stall) and sandbox tightness are separate knobs. --ask-for-approval never stops the stalls; the sandbox decides what the peer may touch. A pure REVIEWER needs no write access — default it to --sandbox read-only (still never stalls, but can't edit files, run scripts, or reach secrets). Widen to workspace-write only for a peer that must ACT, and use --dangerously-bypass-approvals-and-sandbox only on a machine that is already externally sandboxed.

# AGENT_CMD = the FULL launch line, INCLUDING the agent's auto-approve flags (see table).
AGENT_CMD="codex --ask-for-approval never --sandbox read-only"        # REVIEWER: auto-run, cannot write
AGENT_NAME="codex"   # label herdr uses in `agent list` (usually the binary name)
# peer that must ACT (edit/patch): AGENT_CMD="codex --ask-for-approval never --sandbox workspace-write"
# externally-sandboxed box only:   AGENT_CMD="codex --dangerously-bypass-approvals-and-sandbox"
Agentauto-approve ("YOLO") launchherdr integrationanswer markerstatus
codexcodex --ask-for-approval never --sandbox read-only (act: --sandbox workspace-write; full: --dangerously-bypass-approvals-and-sandbox)auto-detected¹ prefix✅ launch+detect verified
claudeclaude --dangerously-skip-permissions (or --permission-mode bypassPermissions)integration install claude(verify)flag verified
cursorits CLI's force/auto flag — verifyintegration install cursor(verify)template
grokits CLI's auto flag, once releasedmaybe via cursor(verify)template

¹ codex state is auto-detected — you don't need herdr integration install codex, and running it can clobber an existing notify hook in ~/.codex/config.toml (e.g. one installed by another tool). For other agents, herdr integration install <name> is fine and improves detection.

Preconditions

# NB: `herdr status server` exits 0 even when the server is down — it prints "status: not
# running". Match the OUTPUT; an exit-code check silently passes and every later call then
# dies with "Connection refused".
herdr status server 2>/dev/null | grep -q "^status: running" || { echo "herdr server not running — skill N/A"; exit 1; }
[ "${HERDR_ENV-}" = 1 ] || echo "warning: HERDR_ENV≠1 (not launched inside a herdr pane); proceeding via socket"  # ${HERDR_ENV-} is set -u safe
command -v "${AGENT_CMD%% *}" >/dev/null || { echo "${AGENT_CMD%% *} not on PATH"; exit 1; }  # first word only — AGENT_CMD includes flags

Spawn a visible peer pane next to Claude

# base pane = Claude's own pane if inside herdr, else the focused pane
BASE="${HERDR_PANE_ID:-$(herdr pane current 2>/dev/null \
    | python3 -c 'import sys,json;print(json.load(sys.stdin)["result"]["pane"]["pane_id"])')}"
[ -n "$BASE" ] || { echo "no base pane resolvable"; exit 1; }
Q=$(herdr pane split "$BASE" --direction right --no-focus \
    | python3 -c 'import sys,json;print(json.load(sys.stdin)["result"]["pane"]["pane_id"])')
echo "peer pane = $Q"    # sits beside Claude; --no-focus keeps you here but both stay visible

Alternative — give the peer its own tab (cleaner isolation; the user flips to it to watch the whole conversation). tab create returns the id at result.root_pane.pane_id (verified):

Q=$(herdr tab create --workspace "${HERDR_WORKSPACE_ID:-$(herdr pane current | python3 -c 'import sys,json;print(json.load(sys.stdin)["result"]["pane"]["workspace_id"])')}" \
    --label peer --no-focus \
    | python3 -c 'import sys,json;print(json.load(sys.stdin)["result"]["root_pane"]["pane_id"])')

Primary flow — interactive TUI (watchable)

herdr pane run "$Q" "$AGENT_CMD"                              # launch the peer agent's TUI
herdr wait agent-status "$Q" --status idle --timeout 30000   # composer ready

# send a focused review/consult prompt (Claude = Code, peer = Reviewer):
herdr agent send "$Q" "Review the current git diff for correctness bugs, data-routing errors and eval regressions. Report [severity] file:line — issue — fix. Separate confirmed bugs from risks."
herdr pane send-keys "$Q" enter                              # submit (send writes literal text, no Enter)

herdr wait agent-status "$Q" --status working --timeout 20000  # best-effort: confirm it picked up
herdr wait agent-status "$Q" --status done    --timeout 900000 # FINISHED (the UI's 'done'; agent-agnostic)
herdr agent read "$Q" --source recent-unwrapped --lines 300    # reading the pane is what acknowledges 'done'

Prefer the hardened wrapper. The commands above are the teaching version; in scripts use peer_launch / peer_ask from peer.sh. They make the waits fatal — a bare wait agent-status … --status done hangs for the entire timeout if the peer exits (goes undetected) instead of reaching done (observed live in the dogfood) — detect a vanished peer, and return answer-only text (stripping the echoed prompt so downstream CHOICE=/VERDICT= parsing can't false-match your own prompt).

Why wait agent-status, not agent wait: wait agent-status is herdr's canonical waiter and the only one whose --status accepts done; agent wait accepts only idle/working/blocked. Semantics (per the official skill): done = the agent finished but you haven't looked yetagent read is the "looked at it" step. This is the agent-agnostic completion signal (verified for codex; works for any agent herdr detects).

  • Multi-turn consult ("咨询"): keep the pane open and just send again — herdr agent send "$Q" "<follow-up>"; herdr pane send-keys "$Q" enter; herdr wait agent-status "$Q" --status done …. The user watches the whole back-and-forth in the pane; Claude relays a summary into this session.
  • Reading the reply: --format text (default) strips ANSI, so the buffer is plain text with light TUI framing. For codex, the agent's answer lines are prefixed and your prompt echoes with ; grep those. For a new agent, eyeball the buffer once and note its marker in the table. If plain text loses structure you need (a TUI feedback loop), read a rendered snapshot instead: herdr agent read "$Q" --format ansi (or pane read … --format ansi).

If herdr can't auto-detect the agent's state

Some agents may not report working/idle (no integration + unrecognized screen). Then: herdr integration install <AGENT_NAME> (improves detection), or fall back to matching the agent's own on-screen "done" cue: herdr wait output "$Q" --match '<per-agent marker>' --source recent --timeout … (match against --source recent, i.e. unwrapped text, so narrow-pane soft-wrapping can't break the match).

Close the loop AFK — delegate the decision, not just the review

The peer can do more than review: when Claude hits a choice point (Claude produced a plan with options A/B/C), hand the decision to the peer so the flow closes with no human present. Frame it as a contract with a machine-parseable answer:

Use the peer_decide helper (peer.sh) — do NOT hand-roll this. The footgun: the prompt itself contains CHOICE=…, and the pane echoes the prompt, so a naïve grep CHOICE= over the buffer matches your own prompt, not the peer's answer. peer_decide (and peer_ask) prepend a unique marker and parse only the text after the last echoed marker line:

pick=$(peer_decide "$Q" "Context: <plan + tradeoffs>. Options: A) … B) … C) …. Choose exactly one.")
# pick is the bare token (e.g. A). Returns nonzero if the peer gave no CHOICE= line — handle that.

If you must do it inline, slice off the echoed prompt before parsing (send with a marker, read pane read --source recent-unwrapped, take lines after the last marker, then grep -oE 'CHOICE=[A-Za-z0-9_.-]+' | tail -1).

Claude then proceeds with the chosen option: Claude writes → peer reviews and arbitrates → Claude continues, no human in the loop. For a fully unattended run:

  • Both sides autonomous: the human launches the driving Claude in bypass too (claude --dangerously-skip-permissions); the peer is already YOLO (config above).
  • Contain the blast radius: run the loop in a throwaway git worktree (herdr worktree …) so a bad auto-decision can't corrupt the main tree.
  • Bound it: cap review↔revise rounds (e.g. ≤ 3) and define a done condition (tests green, or the peer replies LGTM) so the two agents can't ping-pong forever.
  • Escalate the irreversible — don't YOLO it: for one-way doors (git push, deploy, rm -rf, spending money, external network writes) the loop should STOP and page the human instead of auto-approving. That is exactly what the herdr-remote plugin is for (approve from your phone). Everything reversible runs YOLO; only the irreversible waits for you.

Runnable recipe — autonomous review→revise→decide loop (AFK)

Mechanical helpers live in peer.sh next to this file (peer_launch / peer_ask / peer_decide / peer_escalate / peer_close; every herdr call in it is verified). Claude's own coding turns interleave with them. This closes the loop with no human — unless an irreversible action needs sign-off, which pages you instead.

. ~/.claude/skills/peer-agent-via-herdr/peer.sh   # bash only; PEER_AGENT_CMD defaults to codex auto-approve + read-only (reviewer)

# 0) isolate: a throwaway worktree so a bad auto-decision can't touch main
WT="$(mktemp -d)/wt"; git worktree add "$WT" HEAD
# 1) launch the peer (YOLO), pointed at the worktree so it reviews the right tree
Q=$(peer_launch "$WT")

# 2) review ↔ revise, capped at 3 rounds (done-condition = peer says LGTM)
for round in 1 2 3; do
  #   ← Claude edits code in "$WT" here (Claude's own turn) →
  review=$(peer_ask "$Q" "Review the uncommitted changes in this repo for correctness, data-routing and eval-regression bugs. FIRST line must be exactly VERDICT=CLEAN or VERDICT=CHANGES; if CHANGES, list [severity] file:line — issue — fix.") || { echo "peer_ask failed: $?"; break; }
  #   ← Claude reads $review and addresses the findings →
  # $review is answer-only (peer_ask strips the echoed prompt), so this can't match the prompt text:
  printf '%s\n' "$review" | grep -q '^VERDICT=CLEAN' && { echo "peer approved (round $round)"; break; }
done

# 3) decision point → let the peer ARBITRATE (no human)
pick=$(peer_decide "$Q" "Choose the rollout for this change: A) merge to main now  B) open a PR  C) keep on the branch.")
echo "peer chose: $pick"

# 4) irreversible action → escalate instead of YOLO-ing it
case "$pick" in
  A) if ! peer_escalate "$Q" "peer chose to merge $WT into main — approve the push?"; then
       echo "HALTED for human approval — leaving pane $Q + worktree $WT in place; do NOT clean up"
       exit 0    # STOP before cleanup; resume after you approve on your phone / take over the pane
     fi ;;
  *) echo "reversible ($pick) — proceeding autonomously" ;;
esac

# 5) cleanup — only reached when nothing is pending human approval
peer_close "$Q"; git worktree remove "$WT" --force

Guardrails are structural, not optional: worktree isolation (0), round cap + LGTM done-condition (2), peer-arbitrated decision (3), escalate-not-YOLO for the one-way door (4). For a fully unattended run the human also launches the driving Claude with --dangerously-skip-permissions, and (for the phone page in step 4 to reach them) has the herdr-remote relay + herdr-push plugin configured.

Robust one-shot review — codex exec in a visible pane (recommended for reviews)

For a one-shot review (the common "让 codex review 一下" ask), prefer this over the TUI-paste path: the prompt goes as a CLI argument (no fragile paste into a composer that can mangle a long prompt or make the agent exit), and it's still visible — the user watches codex exec stream in the pane. Use the peer_pane + peer_exec helpers (the caller owns the pane, so its id survives $(...)):

. ~/.claude/skills/peer-agent-via-herdr/peer.sh    # bash only
Q=$(peer_pane "$REPO_OR_WORKTREE")                  # fresh bare pane (create it yourself, then close it)
review=$(peer_exec "$Q" "Review the uncommitted changes for correctness/data-routing/eval-regression bugs; report [severity] file:line — issue — fix.")
peer_close "$Q"

Two footguns this design avoids (both hit live in dogfooding):

  • Long promptpeer_exec delivers the prompt via a stdin file (codex exec - < file), not on the command line; a long prompt on the pane run command line gets truncated and codex never runs.
  • Completion — it polls pane process-info until the codex process leaves the foreground. Do not wait output --match 'tokens used': a review's own text can contain "tokens used" so the waiter matches the review body, not codex's footer. (codex exec also isn't reliably agent-detected — flickers idle then vanishes — so wait agent-status doesn't work for it either.)

Launch in a git repo (codex trusts it; avoids a trust-prompt / early exit). Other agents may have no exec equivalent — use the TUI flow.

Golden rules (footguns hit live — do not skip)

  1. Re-query IDs every time; never cache. Panes and whole workspaces churn mid-session (observed w1w2; a pane went pane_not_found). IDs look like w2:p3 / w2:t1, not 1-1.
  2. A freshly split pane is NOT ready — pane run types into whatever is there. pane split returns before the pane's login shell is usable, and pane run sends text blind. Two live failures: (a) the shell is still running rc subprocesses (sw_vers, from oh-my-zsh's startup) — pane process-info shows the subprocess as foreground, and your text goes to it; (b) an rc that asks something ([oh-my-zsh] Would you like to update? [Y/n]) eats the first characterscodex exec … became odex exec …command not found, and the review silently never ran. pane run also doesn't clear a stale/errored line, which concatenates into your command. So always: poll pane process-info until the foreground argv0 is the shell itself, then send-keys ctrl+c (dismiss a prompt) + ctrl+u (clear the line), and only then pane run. peer.sh's _run_clean does exactly this — use peer_launch/peer_exec and you get it free.
  3. Any shell text you send must appear only in OUTPUT if you match on it, and be valid in the pane's shell. Only the quiet path sends shell text. The pane runs the user's login shell — fish needs (math "6 x 7"), zsh/bash need $((6*7)); check echo $SHELL and pick accordingly. The TUI flow avoids this entirely (prompts go to the agent).
  4. Keep the peer pane open while the user wants to watch/take over. herdr agent attach "$Q" --takeover lets them jump in; the pane survives laptop-close / ssh — that persistence + live visibility is the whole reason to use this over an in-band review.

Cleanup

Leave the pane open for the user to read/continue. When truly done, quit the agent then close:

herdr pane send-keys "$Q" ctrl+c     # twice if needed, or the agent's own /quit + enter
herdr pane close "$Q"

Notes

  • Thin specialization over the official general herdr skill (herdr ships one at SKILL.md; install it alongside this one) — lean on it for the general primitive reference: the full command set, the --source recent (unwrapped) vs recent-unwrapped matching semantics, --format ansi snapshots, and the JSON id contract (pane split → result.pane.pane_id, tab create → result.tab + result.root_pane, workspace create → result.workspace/tab/root_pane). This skill only adds the peer-review/consult workflow + config table + role split; don't re-teach primitives.
  • Role convention: Claude = Code Agent, peer = Reviewer. Feed the peer focused review/consult prompts and relay its findings — don't have it edit files. Pin this in your project's CLAUDE.md / AGENTS.md so the split survives across sessions.

What ships with it: 7 files

23.8 KB alongside SKILL.md, 4 of them executable

scripts/

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.