@maxiaochao/pi-herdr-subagents

Run inspectable interactive Pi subagent batches through Herdr.

Packages

Package details

extension

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

$ pi install npm:@maxiaochao/pi-herdr-subagents
Package
@maxiaochao/pi-herdr-subagents
Version
0.5.3
Published
Oct 14, 2026
Downloads
2,673/mo · 2,673/wk
Author
maxiaochao
License
unknown
Types
extension
Size
6.6 MB
Dependencies
0 dependencies · 4 peers
Pi manifest JSON
{
  "extensions": [
    "./extensions/herdr-subagents.ts"
  ]
}

Security note

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

README

Herdr Subagents

Run focused Pi subagents in visible, focusable Herdr panes and collect exactly one terminal result per task.

The implementation is intentionally small: one task state machine, one derived run state, and one bounded worker pool. Herdr provides visible panes and navigation; the package only dispatches serial or read-only parallel work, waits for a report, and records the result. It does not add a second workflow engine around Pi.

Herdr Subagents running as visible panes

Demo

https://github.com/user-attachments/assets/8ddf3ae6-a11a-492b-9cae-d9496ba65b67

The reproducible source recording is retained as docs/demo.webm.

Execution contract

herdr_subagents accepts an ordered, non-empty tasks array.

  • concurrency: 1 runs tasks strictly in input order.
  • concurrency: N runs at most N read-only tasks at once.
  • A run containing a write-capable persona must use concurrency: 1; unsafe parallel writes are rejected.
  • One task failing does not cancel its siblings.
  • The tool returns only after every task is completed, failed, or cancelled.
  • There is no background queue, blocked/respond flow, automatic resume, or early failure detach.
{
  "label": "review",
  "concurrency": 2,
  "tasks": [
    { "name": "api", "prompt": "Review the API boundary.", "agent": "reviewer" },
    { "name": "tests", "prompt": "Find missing test coverage.", "agent": "explorer" }
  ]
}

Each task starts a single-task interactive Pi process in its own Herdr pane. Herdr first confirms the interactive Pi is ready, then the prompt is delivered exactly once. Prompt acknowledgement never decides task completion. Panes remain ordinary Herdr panes: they can be focused and inspected while work is running or after it settles. An early-finishing child stays at the Pi UI while sibling tasks continue. After the whole run settles, cleanup closes an unfocused run tab immediately or waits for the user to leave a focused run tab.

Cleanup belongs to the Pi session that created the run. Starting a new Pi session never scans historical runs or closes their recorded Herdr tabs. If Pi terminates before shutdown cleanup runs, any surviving Subagent tab remains visible for explicit inspection or cleanup.

Result protocol

The child must call subagent_report once with a terminal status:

  • completed: the requested work finished.
  • failed: it cannot be completed; include error.

The complete result is stored on disk. The parent receives only the compact summary and document paths.

The child UI renders only the report status and saved size instead of echoing the complete result argument. The parent-facing tool result includes one complete-result path per task; additional consulted-document metadata remains in the durable report.

An atomically renamed attempt report is the authoritative completion signal. Herdr states such as idle, blocked, and done are wake-up hints only. A prompt transport error or Pi retry cannot fail a task while its child process remains alive. If the process exits without a valid report, the task fails explicitly.

Duplicate identical reports are idempotent. A conflicting report for the same task attempt is rejected. Terminal task records are immutable.

State model

The same small state machine is used for every task; there are no separate foreground, background, blocked, resumed, or retry lifecycles.

New task records use:

queued -> running -> completed | failed | cancelled

A run is running while any task is queued or running. Settled aggregate states are completed, failed, partial, or cancelled.

Older records containing starting or blocked remain readable for history and cleanup, but new runs never write those states.

Durable records

Records are stored under:

.pi/herdr-subagents/runs/<sortable-run-id>/
  run.json
  tasks/<order>-<task-id>/
    task.json
    session.jsonl
    system-prompt.md
    report.json
    reports/<attempt-id>.json
    results/<attempt-id>.md

The orchestrator is the only writer of run.json, task.json, and promoted report.json. The child only writes its attempt-scoped result and report.

Control and UI

herdr_subagents_control supports list, status, history, cancel, and cleanup. Follow-up work is a new task or run; settled tasks are never revived.

When exposure is absent, both tools omit the registration field and inherit Pi's default exposure. Set "exposure": "model-only" to keep explicit top-level model calls while excluding Codemode scripts and other nested tools, or "exposure": "direct" to request Pi's direct-and-nested behavior explicitly. Exposure is read when the extension loads, so use /reload or restart Pi after changing it.

Use /herdr-subagents focus <task-number> to focus a running pane. /herdr-subagents active, history, agents, models, and settings provide compact inspection.

Personas and settings

Bundled personas are worker, explorer, analyst, and reviewer. Project personas can be added under .pi/agents/ using the same frontmatter format as the bundled files. Access is declared as read or write and drives concurrency safety.

Settings are read from ~/.pi/agent/herdr-subagents.json and the project-level .pi/herdr-subagents.json, with the project value taking precedence. Optional exposure accepts Pi's model-only or direct; omitting it delegates to Pi. defaultConcurrency, maxConcurrency, and stalledWarningSeconds remain supported.