@itc-steve/pi-herdr

Pi extension for Herdr-visible subagent herds - default-local workers, optional ranked-frontier think, markdown handoff.

Packages

Package details

extensionskill

Install @itc-steve/pi-herdr from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:@itc-steve/pi-herdr
Package
@itc-steve/pi-herdr
Version
1.4.0
Published
Aug 31, 2026
Downloads
793/mo · 195/wk
Author
itc-steve
License
MIT
Types
extension, skill
Size
217.9 KB
Dependencies
0 dependencies · 4 peers
Pi manifest JSON
{
  "extensions": [
    "./index.ts"
  ],
  "skills": [
    "./skills"
  ]
}

Security note

Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.

README

pi-herdr

Pi extension for Herdr-visible subagent herds — default-local workers, optional ranked-frontier think, markdown handoff.

Design intent

Role Who
Orchestration Frontier model (parent session)
Implement / slice Local seat — private, free, clean per-job context, cap = maxModelConcurrent
Isolated review / plan / VERIFY role=think — one job per catalog model; two tasks → one each; next think rotates to the other
User view / permissions Herdr panes (watch, focus, accept)

Requires running inside Herdr (HERDR_ENV=1). Outside Herdr, herd still loads for config/status, but spawn/boot and the herdr tool are inactive.

Install

pi install npm:@itc-steve/pi-herdr

From a local checkout:

pi install /path/to/pi-herdr

Then /reload. Use /herd help for slash usage.

Do not install other herdr packages at the same time (e.g. @ogulcancelik/pi-herdr, pi-custom-herdr). This package vendors the herdr tool and refuses to load if a known competitor appears in Pi settings.

Requirements

  • Pi coding agent
  • Herdr (terminal workspace / agent multiplexer)
  • Models listed in config must already be available to Pi (local vLLM/SGLang, Grok CLI, etc.)

Config

Copy herd.json.example to ~/.pi/agent/herd.json (created automatically on first models / run if missing):

{
  "sessionDir": "~/.pi/agent/herd",
  "maxModelConcurrent": 2,
  "local": {
    "enabled": true,
    "model": "vllm/Qwen/Qwen3.6-27B-FP8",
    "thinking": "medium",
    "preflight": true
  },
  "think": [
    { "model": "grok-cli/grok-4.6", "thinking": "high" },
    { "model": "openai-codex/gpt-5.6-sol", "thinking": "high" }
  ],
  "defaults": {
    "isolation": "none",
    "timeoutMs": 600000,
    "waitForReply": false,
    "requireOutput": true,
    "resultDelivery": "pointer",
    "triggerTurnOnResult": true
  }
}

think[] order is the rank. Put the best frontier first.

Old easy / medium / hard catalogs still parse: remotes fold into think (hard, then medium, then easy). local.maxStreams, preferOn, and whenFull are ignored. Cap is always maxModelConcurrent.

Field reference

Field Meaning
sessionDir Run root (runs/, journals, session JSONL)
maxModelConcurrent Cap on local seats and on in-flight jobs per exact provider/model
local Default implementer: model id, thinking, optional preflight
think Ordered frontier catalog for role=think
defaults.isolation ignored; writers share the tree (owns= is the isolation)
defaults.requireOutput Async spawn must declare output=
defaults.resultDelivery pointer (default: path only) or full (paste reply)
defaults.triggerTurnOnResult One parent turn when the last in-flight job finishes (default true)

Jobs resolved to the local model are tagged local: true so parent, kick text, and herd models all see the seat.

How it works

Default-local + optional think

Spawn Route
no role, or role=do Local. Queue if seats full. Never overflow onto think.
role=think (aliases: review, plan, architect, verify) One in-flight per think model. First → think[0]. Second task or second opinion → the other. Both busy → queue think[0]
model= That model (local id still takes a local seat)

Never dump a whole project on one spawn. Decompose. Parent stays on a frontier model for orchestration; workers get a fresh session and a narrow kick.

One-release shim: difficulty=easy\|medium → do, difficulty=hard → think.

Local seat

  1. Default spawn claims a local seat (cap = maxModelConcurrent).
  2. Extra do jobs wait for a free seat.
  3. Each job gets a fresh sessions/<job>.jsonl.
  4. Kick banner: You are a LOCAL worker. One slice…

Handoff runs

~/.pi/agent/herd/runs/<date>_<slug>/
  instruction.md   context.md   plan.md   progress.md
  meta.json   journal.jsonl
  sessions/<job>.jsonl
  jobs/…
  <your output=.md files>

Shared context is markdown only — panes do not chat to each other. Each spawn opens a background tab in the parent's current workspace. Job tabs stay open after success so you can watch or intervene in Herdr.

Write lanes

Multi-writer fan-out requires disjoint owns= (and optional forbid=). Put Parallel lanes in plan.md first; the tool rejects overlapping owners.

Completion (pointer batching)

Async jobs are monitored in the background.

  • Mid-wave: footer only (herd: N mon +local M) — no parent turn.
  • When the last in-flight job finishes: one batched herd-result with short pointers (output=path), not full reply pastes.
  • Parent should read the artifact if it needs content — do not reassess the whole task from a pointer.
  • Use herd wait / herd collect for a sync barrier. Set resultDelivery=full only if you need reply bodies in-session.

Tools

Tool Role
herd Assign / abort / steer / status local-first subagents
herdr View and control Herdr terminals (workspaces, tabs, panes, worktrees)

Rule: assign work with herd. Use herdr to view/focus/read — never herdr run into a herd job pane to assign work.

herd actions

Action Purpose
models Show local seats + ranked think catalog
status Active monitors / local seats
run create / list / use / show handoff folders
spawn Boot a pane, submit task (async needs output=; role=think optional)
steer / abort Nudge or stop a job
wait / collect Block until idle / harvest reply
close / reset Close panes / clear monitors
journal Soft resume log for the active run

Quick flow

herd run create name=demo goal="Summarize this repo"
herd spawn task="Fill context.md from the repo" output=context.md
herd spawn task="Implement src/client.ts" output=progress-core.md owns=src/client.ts
herd spawn role=think task="Review progress-*.md; note gaps" output=progress-review.md

Exact model override:

herd spawn model=grok-cli/grok-4.6 task="…" output=notes.md

Slash

/herd help
/herd models
/herd status
/herd run create name=<slug> goal="…"
/herd spawn task="…" output=file.md
/herd spawn role=think task="…" output=review.md

herdr (view / control)

Registered only when HERDR_ENV and HERDR_PANE_ID are set (Herdr-managed pane). Actions include workspace/tab/pane lifecycle, read / watch / wait_agent, run / send / stop, worktrees, and notifications. Prefer friendly aliases or ids from herdr list — never invent pane ids.

Skills

Package skills (herd, herdr) teach the launcher default-local vs think and the herd vs herdr split. They install with the package via the Pi skills manifest.

Footer status

While monitors or local streams are active: herd: N mon +local M. Hidden when idle.

Development

npm test

Tests use Node’s built-in runner with --experimental-strip-types (Node ≥ 18).

Changelog

See CHANGELOG.md.

License

MIT. See LICENSE.