pi-herdr-subagents-lite
Run pi subagents in herdr panes.
Package details
Install pi-herdr-subagents-lite from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:pi-herdr-subagents-lite- Package
pi-herdr-subagents-lite- Version
0.8.0- Published
- Nov 3, 2026
- Downloads
- 2,010/mo · 2,010/wk
- Author
- setwhite
- License
- MIT
- Types
- extension
- Size
- 102.6 KB
- Dependencies
- 0 dependencies · 2 peers
Pi manifest JSON
{
"extensions": [
"./src/index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-herdr-subagents-lite
简体中文 | English
The extension runs subagents as separate pi processes in herdr panes. One tool has two actions: run starts a subagent, and send continues a subagent. Results come back asynchronously. The behavior follows the v1 contract.
Features
- A subagent is a separate process. A human can take over its pane. If the subagent cwd equals the parent cwd, the subagent opens a tab in the same workspace. Otherwise the subagent opens a new workspace.
- Profiles have two layers: Markdown with frontmatter. One layer is global. One layer is per project.
- Results are async and merged.
runreturns at once. Each finished turn reports onesubagent_result. Results insideaggregateWindowMsmerge into one result. Oversize results go to an artifact file. - Questions stay with the human. A child prompt only emits
herdr:blocked. Nothing reaches the parent. The human answers in the child pane. - Nesting is off by default. The extension is not a sandbox. If the profile does not name this tool, child tool sets drop this tool.
Install
pi install npm:pi-herdr-subagents-lite # npm
pi install /path/to/pi-herdr-subagents-lite # local checkout
pi -e /path/to/pi-herdr-subagents-lite/src/index.ts # this process only
The old repository moved into this monorepo. Install from npm.
Do not pass -l. -l writes project settings only, so children started in another workspace never load the package. pi -e is single-process too.
Tested with herdr 0.9.5 and pi 1.4.0, Node >= 22.19. The parent must run inside a herdr pane. Otherwise calls fail with not_in_herdr. Upgrade with pi update --extensions. Remove with pi remove <source>.
Configuration
One global file holds the configuration: <agent-dir>/pi-herdr-subagents-lite/config.json. <agent-dir> defaults to ~/.pi/agent. PI_CODING_AGENT_DIR sets <agent-dir>. The extension does not read a project config.
Defaults and clamp boundaries: src/config/index.ts and test/config/config.test.ts. Key meaning: contract §1.
Minimal config
A missing file means all defaults. To change one value, write only that value:
{
"maxConcurrent": 4
}
Full configuration
The block below lists every key. Each value is the default.
{
// Default true. false = no subagent tool for the model. The bridge has its own switch.
"enabled": true,
// Default "subagent". Must match ^[a-z][a-z0-9_]{0,31}$. The name prefixes each guideline line.
"toolName": "subagent",
// Default "herdr". A plain name resolves from PATH; an absolute path pins a version.
"herdrBin": "herdr",
// Default 16, range 1 and up. At the limit run returns max_concurrent. A child with auto-exit: false keeps its slot after it settles.
"maxConcurrent": 16,
// Default 16384, range 1024 to 1048576. A longer text goes to an artifact file. The message keeps a truncated head and the path.
"maxResultChars": 16384,
// Default 500, range 0 to 10000 milliseconds. 0 = deliver each result at once. A larger value merges more results.
"aggregateWindowMs": 500,
// Default empty = never close. Values: new, resume, fork, quit, reload. A listed reason closes the child tabs on parent shutdown.
"closeChildrenOn": [],
// Default 250, range 50 to 5000 milliseconds. A larger value wakes less often and delivers later.
"inboxPollMs": 250,
// Default 1000, range 100 to 60000 milliseconds. Use while a child works or blocks, or within 30 s of run or send.
"pollIntervalMs": 1000,
// Default 8000, range 100 to 60000 milliseconds. Use when every live child only waits for send. A larger value notices a dead pane later.
"idlePollIntervalMs": 8000,
// Tool text overrides. Each key defaults to unset, which keeps the built-in text shown below.
"prompts": {
// Replaces the built-in description.
"description": "Use run when a task is self-contained and long-running. Use send to pass information to a subagent.",
// The one-line entry in Available tools. Empty = keep the tool out of that list.
"snippet": "",
// Replaces the built-in guideline lines. Keep {{profiles}} to list the profiles.
"guidelines": [
"run only starts; it does not wait. The result arrives later as a message.",
"send only delivers; no state tracking.",
"Available profiles:\n{{profiles}}"
]
},
// Turn pi prompt events into herdr:blocked events.
"bridge": {
// Default true. false = no herdr:blocked events.
"enabled": true,
// Default all five. Prompt kinds that count as blocked: custom, select, confirm, input, editor.
"blockedOn": ["custom", "select", "confirm", "input", "editor"]
}
}
The file is strict JSON and the extension reads it once, so delete the comments and restart pi after a change. An unknown key, a wrong type or an unknown enum value stops the extension at load: pi prints invalid config <path>: <field>: unknown key and exits. A number outside its range clamps to the boundary.
Usage
- Start
piin a herdr pane. - Write a profile (next section).
runtakes the frontmatternameof the profile. - Ask the model to call the tool:
{"action":"run","profile":"explore","task":"Read README.md and answer with its first heading."}
The call returns {"state":"running",...}. The subagent runs in its own tab. A [subagent explore-1] done message arrives later. Do not wait for the message in the same turn. Continue that child with:
{"action":"send","name":"explore-1","message":"Also check the Windows branch."}
Profile
Global profiles live in <agent-dir>/pi-herdr-subagents-lite/profiles/*.md. Project profiles live in .pi/pi-herdr-subagents-lite/profiles/*.md and load once the project is trusted. If a project profile and a global profile share a name, the project profile wins.
---
# Key run takes; the file name is not used
name: explore
description: "Read-only research: read code, answer questions, change nothing"
# Omit to inherit from the parent
# model: provider/model
thinking: low
# Plain names = strict allowlist. +name / -name adjusts the default set. Never mix both
# Omitted = pi defaults minus this tool (nesting off); "" = empty allowlist
tools: read, bash
# Omitted = pi discovery; "" = no skills; a list = only those
skills: ""
# append / replace: body is appended to or replaces the system prompt
# task: body is the task text, no identity file
system-prompt: append
# Shut down and close the tab when settled. It waits while a prompt is open or the inbox has messages
auto-exit: true
# true = hidden from the guidelines; an explicit run still works
disable-model-invocation: false
---
You are a read-only explorer. Answer with file paths and line numbers.
Error codes: contract section 2. Defaults: src/profile/frontmatter.ts and test/profile/. A file without name or with an invalid field stays out of the list. The extension rejects all duplicate names in one layer. run returns profile_invalid with the file, the field and the reason.
The extension ships a bundled example. The file name and the name of the example are both worker. Loading reads profiles/*.md only. On every load the extension makes profiles/examples/ match the bundled examples: it rewrites the bundled files and deletes extra files. So copy the example one level up:
cd <agent-dir>/pi-herdr-subagents-lite/profiles && cp examples/worker.md worker.md
Credits
| Project | Borrowed |
|---|---|
| earendil-works/pi | Extension API, package layout, official examples |
| fyang93/pi-herdr-subagents | Profile field shapes; integration tests on an isolated herdr session |
| modem-dev/pi-herdr-subagents | herdr launch and lifecycle; derived end states |
| purboo/pi-durable-subagents | Async delivery, idempotency, report-once results |
Thank you for the code.
Docs
| Document | Content |
|---|---|
| docs/specs/0001-v1-contract.md | The v1 contract |
| docs/ARCHITECTURE.md | Module boundaries, dependency direction, test seams |
| docs/modules/ | Usage and trade-offs per module |
| docs/GLOSSARY.md | The only source for terms |
| CHANGELOG.md | Release notes |
License
MIT, see LICENSE.