pi-herdr-agents 2.0.5 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +20 -14
- package/CHANGELOG.md +56 -2
- package/CONTEXT.md +86 -32
- package/README.md +285 -138
- package/RELEASING.md +4 -2
- package/config.json.example +0 -3
- package/docs/README.md +38 -15
- package/docs/adr/0001-btw-ephemeral-side-questions.md +1 -1
- package/docs/adr/0002-agent-workflow-skill-runtime-taxonomy.md +1 -1
- package/docs/adr/0003-installable-role-packs.md +21 -13
- package/docs/adr/0009-remove-workflow-subsystem.md +1 -1
- package/docs/adr/0012-adopt-maestro-seams-in-repo.md +45 -0
- package/docs/adr/0013-pack-neutral-execution-host.md +63 -0
- package/docs/adr/0014-operator-cancel-terminal-intent.md +134 -0
- package/docs/worktree-subagents.md +4 -2
- package/maestro/adapters/fake/fake-harness-adapter.ts +263 -0
- package/{pi-extension/subagents/activity.ts → maestro/adapters/pi/activity-file.ts} +15 -72
- package/{pi-extension/subagents → maestro/adapters/pi/child}/subagent-done.ts +30 -3
- package/{pi-extension/subagents → maestro/adapters/pi}/completion.ts +4 -4
- package/{pi-extension/subagents → maestro/adapters/pi}/launch.ts +386 -328
- package/maestro/adapters/pi/model-registry.ts +46 -0
- package/maestro/adapters/pi/pi-harness-adapter.ts +701 -0
- package/maestro/adapters/pi/process-identity.ts +303 -0
- package/{pi-extension/subagents → maestro/adapters/pi}/session.ts +1 -13
- package/maestro/adapters/pi/task-model-init.ts +55 -0
- package/maestro/core/activity.ts +29 -0
- package/maestro/core/config/model-config.ts +473 -0
- package/{pi-extension/subagents → maestro/core/config}/pane-config.ts +4 -6
- package/{pi-extension/subagents → maestro/core/config}/persistent-config.ts +4 -6
- package/{pi-extension/subagents → maestro/core/config}/role-config.ts +15 -10
- package/{pi-extension/subagents → maestro/core/config}/supervision-config.ts +4 -6
- package/{pi-extension/subagents → maestro/core/config}/task-model-init.ts +45 -58
- package/maestro/core/config/task-model-types.ts +22 -0
- package/maestro/core/harness-adapter.ts +117 -0
- package/maestro/core/index.ts +3 -0
- package/{pi-extension/subagents → maestro/core}/lifecycle.ts +27 -126
- package/maestro/core/roles/discovery.ts +555 -0
- package/{pi-extension/subagents/runtime-routing.ts → maestro/core/routing.ts} +36 -43
- package/maestro/core/shell.ts +3 -0
- package/{pi-extension/subagents → maestro/core}/status.ts +3 -7
- package/{pi-extension/subagents → maestro/core}/supervision.ts +1 -1
- package/maestro/core/surface-provider.ts +185 -0
- package/maestro/core/types.ts +449 -0
- package/maestro/core/worktree-cleanup.ts +374 -0
- package/maestro/core/worktree.ts +93 -0
- package/maestro/runtime/index.ts +44 -0
- package/maestro/runtime/pi-run-session.ts +1210 -0
- package/maestro/runtime/run-session.ts +801 -0
- package/maestro/runtime/surface-retention.ts +6 -0
- package/maestro/runtime/task-model-init.ts +22 -0
- package/maestro/runtime/worktree-operations.ts +627 -0
- package/maestro/surfaces/fake/fake-surface-provider.ts +311 -0
- package/maestro/surfaces/herdr/herdr-surface-provider.ts +200 -0
- package/{pi-extension/subagents → maestro/surfaces/herdr}/herdr.ts +65 -14
- package/{pi-extension/subagents → maestro/surfaces/herdr}/terminal.ts +7 -5
- package/package.json +10 -9
- package/pi-extension/subagents/config-path.ts +5 -1
- package/pi-extension/subagents/index.ts +837 -1789
- package/pi-extension/subagents/model-registry.ts +46 -0
- package/skills/pi-herdr-agents/SKILL.md +276 -0
- package/agents/adversarial-reviewer.md +0 -153
- package/agents/planner.md +0 -87
- package/agents/poteto.md +0 -32
- package/agents/reviewer.md +0 -132
- package/agents/scout.md +0 -105
- package/agents/visual-tester.md +0 -234
- package/agents/worker.md +0 -121
- package/docs/review-evaluation.md +0 -183
- package/pi-extension/subagents/model-config.ts +0 -305
- package/pi-extension/subagents/plan-skill.md +0 -280
- package/pi-extension/subagents/worktree-cleanup.ts +0 -785
- package/skills/orchestrate/SKILL.md +0 -91
- package/skills/orchestrate/adversarial-review-example.js +0 -400
- package/skills/orchestrate/adversarial-review.md +0 -87
- /package/{pi-extension/subagents → maestro/core/config}/type-guards.ts +0 -0
- /package/{pi-extension/subagents → maestro/core}/wake.ts +0 -0
package/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# Pi Herdr Agents
|
|
2
2
|
|
|
3
|
-

|
|
4
|
+
|
|
5
|
+
> **Agents:** the tool list is in [What's Included](#whats-included) and the operating guide is [`skills/pi-herdr-agents/SKILL.md`](skills/pi-herdr-agents/SKILL.md). Contributors: read [`AGENTS.md`](AGENTS.md).
|
|
4
6
|
|
|
5
7
|
Asynchronous subagents for [Pi](https://github.com/earendil-works/pi), running exclusively in [Herdr](https://herdr.dev).
|
|
6
8
|
|
|
@@ -13,8 +15,7 @@ Delegate investigation, implementation, and review without blocking the parent s
|
|
|
13
15
|
- **Live supervision** — track process and turn state in Pi's subagent widget; interrupt one child turn without destroying its session.
|
|
14
16
|
- **Managed worktrees** — isolate writing agents in retained Herdr workspaces with explicit Git ownership and recovery details.
|
|
15
17
|
- **Conversation handoff** — continue the active Pi conversation in a new worktree with `/worktree` while preserving the parent session.
|
|
16
|
-
- **
|
|
17
|
-
- **Reusable roles** — use bundled agents, project or global definitions, and installable role packs.
|
|
18
|
+
- **Pack-neutral roles** — use project or global definitions and installable role packs; this package ships no default roles or workflows.
|
|
18
19
|
- **Persistent specialists** — retain one policy-bound Pi session for sequential, turn-based tasks.
|
|
19
20
|
|
|
20
21
|
## Requirements
|
|
@@ -49,8 +50,33 @@ pi
|
|
|
49
50
|
|
|
50
51
|
Restart or `/reload` Pi after installation. Review package source before installing any Pi package.
|
|
51
52
|
|
|
53
|
+
> **Upgrading from 2.x?** Bundled roles and several commands moved out. See [3.0.0 release notes](#300).
|
|
54
|
+
|
|
55
|
+
## Contents
|
|
56
|
+
|
|
57
|
+
- [Requirements](#requirements), [Install](#install), [Safety and uninstall](#safety-and-uninstall)
|
|
58
|
+
- [Quick start](#quick-start), [Release notes](#release-notes), [How it works](#how-it-works)
|
|
59
|
+
- [What's Included](#whats-included): tools, commands, the operating skill, role packs
|
|
60
|
+
- [Async Subagent Flow](#async-subagent-flow): status, configuration, model routing
|
|
61
|
+
- [Spawning Subagents](#spawning-subagents), [Persistent specialists](#persistent-specialists), [Interrupting](#interrupting-a-running-subagent), [Cancelling](#cancelling-a-running-subagent)
|
|
62
|
+
- [The `/worktree` Workflow](#the-worktree-workflow), [Custom Agents](#custom-agents), [Tool Access Control](#tool-access-control)
|
|
63
|
+
- [Development](#development), [License](#license)
|
|
64
|
+
|
|
65
|
+
## Safety and uninstall
|
|
66
|
+
|
|
67
|
+
- Child agents are real Pi processes running with your user account's permissions, inside Herdr panes. Worktrees isolate Git checkouts, not processes or permissions.
|
|
68
|
+
- The extension creates Herdr panes, tabs and managed worktrees only when a launch asks for them. It never pushes, merges, opens pull requests, deletes branches or removes worktrees on its own; cleanup is an explicit parent action ([worktree cleanup](#explicit-worktree-cleanup)).
|
|
69
|
+
- What it writes: `$PI_CODING_AGENT_DIR/herdr-agents/config.json` (only through `/subagents-init` or the writer tool, never on startup); per-launch artifacts under the parent session's `artifacts/<session-id>/` directory beside Pi's session store, which hold the child's full task text and any `systemPrompt` as Markdown files, activity snapshots and worktree manifests; and the child's own Pi session file. A managed worktree that carries its own `.pi/agent` directory receives that child's session inside the checkout. Treat task text as potentially sensitive when you share or inspect those files.
|
|
70
|
+
- To uninstall: first list and remove any retained worktrees while the extension is still loaded (`/worktree list`, then `/worktree remove <target>`), because those commands leave with the package. Then run `pi remove npm:pi-herdr-agents`, and delete `$PI_CODING_AGENT_DIR/herdr-agents/` and the `artifacts/` directories above if you no longer want the configuration and launch records.
|
|
71
|
+
|
|
52
72
|
## Quick start
|
|
53
73
|
|
|
74
|
+
This package is an execution host and ships no agent roles. Named roles come
|
|
75
|
+
from your project or global definitions or from an installed
|
|
76
|
+
[role pack](#publish-a-role-pack). The `scout` examples below assume one of
|
|
77
|
+
those provides `scout`; see [Migrating from bundled roles](#migrating-from-bundled-roles).
|
|
78
|
+
A bare launch without `agent` needs no role.
|
|
79
|
+
|
|
54
80
|
Ask Pi to delegate naturally:
|
|
55
81
|
|
|
56
82
|
```text
|
|
@@ -74,11 +100,45 @@ Pi can also call the tool directly:
|
|
|
74
100
|
```typescript
|
|
75
101
|
subagent({ name: "Auth scout", agent: "scout", model: "<provider>/<fast-tier-id>", thinking: "low", task: "Map the authentication flow" });
|
|
76
102
|
subagent({ name: "DB scout", agent: "scout", model: "<provider>/<fast-tier-id>", thinking: "low", task: "Map the session schema" });
|
|
77
|
-
//
|
|
103
|
+
// A bare launch needs no installed role.
|
|
104
|
+
subagent({ name: "Auth summary", model: "<provider>/<fast-tier-id>", thinking: "low", task: "Summarize the authentication flow" });
|
|
105
|
+
// All return immediately; each result comes back independently.
|
|
78
106
|
```
|
|
79
107
|
|
|
80
108
|
Use ordinary panes for read-only agents. A single or sequential writer can work in the parent checkout; give each parallel independent writing agent a unique managed worktree. The parent acts as coordinator: decompose work, give each child one bounded outcome with its goal, allowed files, verification, and commit instruction, and keep dependent writes sequential. Children are leaves by default; the parent owns integration and final verification. See [Worktree subagents](docs/worktree-subagents.md).
|
|
81
109
|
|
|
110
|
+
## Release notes
|
|
111
|
+
|
|
112
|
+
[`CHANGELOG.md`](CHANGELOG.md) is generated from Git history on each release.
|
|
113
|
+
Hand-written upgrade notes for breaking releases live here.
|
|
114
|
+
|
|
115
|
+
### 3.0.0
|
|
116
|
+
|
|
117
|
+
3.0.0 makes the host pack-neutral. It also adds conditional task-model writes
|
|
118
|
+
(`expectedConfigRevision`, an advisory lock, and the reported `configRevision`),
|
|
119
|
+
the `pi-herdr-agents` operating skill, and `subagent_cancel`.
|
|
120
|
+
|
|
121
|
+
**Breaking changes.** The package no longer ships the seven former bundled roles,
|
|
122
|
+
`/plan` and its plan skill, or `/skill:orchestrate`; these moved to optional role
|
|
123
|
+
packs. `/iterate`, `/btw`, and `/btw-close` were removed without replacement.
|
|
124
|
+
`roles.bundled` is now a deprecated no-op. A named launch of a role that no
|
|
125
|
+
definition or installed pack supplies now fails before Herdr creates a pane or
|
|
126
|
+
worktree.
|
|
127
|
+
|
|
128
|
+
**Migration.**
|
|
129
|
+
|
|
130
|
+
- Install `pi-herdr-roles` for the six generic roles (`scout`, `planner`,
|
|
131
|
+
`worker`, `reviewer`, `adversarial-reviewer`, `visual-tester`), `/plan`, and
|
|
132
|
+
`/skill:orchestrate`.
|
|
133
|
+
- Install `pi-herdr-pstack` for the `poteto-mode` methodology skill and command.
|
|
134
|
+
It ships no named roles; its delegates are bare.
|
|
135
|
+
- Remove `roles.bundled` from `$PI_CODING_AGENT_DIR/herdr-agents/config.json`.
|
|
136
|
+
- Alternatively, copy a former role's definition into `.pi/agents/` or the
|
|
137
|
+
global agents directory to keep it without a pack.
|
|
138
|
+
|
|
139
|
+
See [Migrating from bundled roles](#migrating-from-bundled-roles) for the full
|
|
140
|
+
mapping and pack-compatibility notes.
|
|
141
|
+
|
|
82
142
|
## How it works
|
|
83
143
|
|
|
84
144
|

|
|
@@ -119,19 +179,24 @@ Subagent tabs, panes, and worktree workspaces are created without stealing keybo
|
|
|
119
179
|
|
|
120
180
|
### Extensions
|
|
121
181
|
|
|
122
|
-
**Subagents** —
|
|
182
|
+
**Subagents** — 10 parent-session tools + 3 commands, plus 2 child-only tools:
|
|
123
183
|
|
|
124
184
|
| Tool | Description |
|
|
125
185
|
| -------------------- | ------------------------------------------------------------------------------------------- |
|
|
126
186
|
| `subagent` | Spawn a sub-agent in a dedicated herdr pane (async — returns immediately) |
|
|
127
187
|
| `subagent_interrupt` | Interrupt a running Pi-backed subagent's current turn |
|
|
188
|
+
| `subagent_cancel` | Cancel a running ordinary subagent: no fallback, one cancelled result after confirmed termination |
|
|
128
189
|
| `subagent_send` | Deliver a follow-up task to an idle persistent specialist |
|
|
129
190
|
| `subagent_stop` | Gracefully stop a persistent specialist after its active task settles |
|
|
130
191
|
| `subagents_list` | List available agent definitions |
|
|
131
192
|
| `worktree_list` | Parent-only inspect-only inventory of managed worktrees and cleanup blockers |
|
|
132
193
|
| `worktree_remove` | Parent-only explicit removal by `target` path, branch, or workspace ID; optional `preserve: true` commits dirty state first |
|
|
133
194
|
| `subagent_resume` | Resume a previous Pi-backed sub-agent session in a new ordinary pane (async) |
|
|
134
|
-
| `subagents_write_task_models` | Parent-only internal tool that validates and atomically writes `models.tasks` preferences |
|
|
195
|
+
| `subagents_write_task_models` | Parent-only internal tool that validates and atomically writes `models.tasks` preferences, optionally conditional on `expectedConfigRevision` |
|
|
196
|
+
|
|
197
|
+
| Skill | Description |
|
|
198
|
+
| ----- | ----------- |
|
|
199
|
+
| `pi-herdr-agents` | Operating guide for this host: launching, supervising, interrupting, cancelling and resuming children, worktrees, persistent specialists, model routing and configuration. Loaded by agents on demand; see `skills/pi-herdr-agents/SKILL.md` |
|
|
135
200
|
|
|
136
201
|
| Pi child-only tool | Description |
|
|
137
202
|
| ---------------- | ------------------------------------------------------------------------- |
|
|
@@ -140,10 +205,6 @@ Subagent tabs, panes, and worktree workspaces are created without stealing keybo
|
|
|
140
205
|
|
|
141
206
|
| Command | Description |
|
|
142
207
|
| -------------------------- | ------------------------------------ |
|
|
143
|
-
| `/plan` | Start a full planning workflow |
|
|
144
|
-
| `/iterate` | Fork into a subagent for quick fixes |
|
|
145
|
-
| `/btw <question>` | Open an ephemeral side-question session in a background tab |
|
|
146
|
-
| `/btw-close` | Close the current BTW session |
|
|
147
208
|
| `/worktree <name> [task]` | Continue this session in a new managed worktree (`/worktree list` lists them) |
|
|
148
209
|
| `/subagent <agent> <task>` | Spawn a named agent directly (`/subagent list` lists available agents) |
|
|
149
210
|
| `/subagents-init [preferences]` | Draft task-category model preferences from the live authenticated registry, with optional ranking preferences |
|
|
@@ -154,47 +215,70 @@ This package distinguishes directly runnable **agent roles**, Pi-native
|
|
|
154
215
|
**skills**, and authenticated Pi **runtimes**. A multi-stage user outcome may
|
|
155
216
|
be a command or skill that composes roles; it is not itself an agent role.
|
|
156
217
|
|
|
157
|
-
The
|
|
218
|
+
The host's own orchestration surfaces are:
|
|
158
219
|
|
|
159
220
|
| Surface | Entry point | Behavior |
|
|
160
221
|
| --- | --- | --- |
|
|
161
|
-
|
|
|
162
|
-
| Iteration | `/iterate` | Opens one interactive full-context Pi fork. |
|
|
163
|
-
| Side question | `/btw`, `/btw-close` | Opens one replaceable interactive Pi side session. |
|
|
222
|
+
| Delegation | `subagent`, `/subagent <agent> <task>` | Launches one bare or named child; results return automatically. |
|
|
164
223
|
| Worktree handoff | `/worktree <name> [task]`, `/worktree list` | Forks the active conversation into a managed worktree. |
|
|
165
|
-
| Orchestrated review | `/skill:orchestrate` | Parent materializes evidence, fans out public reviewers, and synthesizes results. |
|
|
166
|
-
| Adversarial review | `/skill:orchestrate`, `adversarial-reviewer` | Risk-based public discovery, cross-family verification, and parent synthesis. |
|
|
167
224
|
|
|
168
|
-
|
|
169
|
-
|
|
225
|
+
Planning, review, and other multi-stage workflows belong to role packs and
|
|
226
|
+
skills, not to this package. See
|
|
227
|
+
[ADR-0002](docs/adr/0002-agent-workflow-skill-runtime-taxonomy.md),
|
|
228
|
+
[ADR-0009](docs/adr/0009-remove-workflow-subsystem.md), and
|
|
229
|
+
[ADR-0013](docs/adr/0013-pack-neutral-execution-host.md).
|
|
170
230
|
|
|
171
|
-
###
|
|
231
|
+
### Roles and role packs
|
|
172
232
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
| **adversarial-reviewer** | Coordinator role | Exact eligible authenticated Pi models selected by risk and project policy | Runs two routine or three high-risk discovery reviewers, candidate-dependent cross-family verification, and parent synthesis through public asynchronous children. |
|
|
233
|
+
This package is a pack-neutral execution host: it ships no agent roles, no
|
|
234
|
+
`/plan` command, and no planning or review skills. Its one skill,
|
|
235
|
+
`pi-herdr-agents`, is a general operating guide for the host. A named launch resolves
|
|
236
|
+
`agent` from project definitions, global definitions, and roles registered by
|
|
237
|
+
installed role packs, in that precedence order (see below). An empty catalog is
|
|
238
|
+
valid. A bare launch without `agent` always works. An explicitly named role that
|
|
239
|
+
is missing or invalid fails before Herdr creates a pane or worktree; it is never
|
|
240
|
+
silently replaced by a bare agent.
|
|
182
241
|
|
|
183
242
|
All subagents execute through Pi. Claude models remain available through normal
|
|
184
243
|
Pi provider/model routing. Legacy role definitions that contain `cli` fail before
|
|
185
244
|
Herdr creates a pane or worktree; remove `cli` and `cli-model`, then select an
|
|
186
245
|
authenticated Pi `provider/model-id`.
|
|
187
246
|
|
|
188
|
-
|
|
247
|
+
Role packs own their roles' prerequisites, such as a required skill, and must
|
|
248
|
+
document them. This package does not install role packs or prerequisites.
|
|
189
249
|
|
|
190
|
-
|
|
191
|
-
- Adversarial review needs a resolved standalone `reviewer` role, confirmed human-only authorship or known author model families, and enough distinct exact authenticated Pi models to satisfy project author-family exclusion and cross-family verification. Routine discovery uses two distinct IDs; concrete high-risk surfaces use three distinct lenses. The parent materializes pinned evidence before public fan-out. A project-approved reduced topology must disclose omitted coverage.
|
|
192
|
-
- `/plan` uses the bundled scout and planner roles and records ordered tasks in
|
|
193
|
-
`plan.md`; it does not require a researcher role, todo tool, or `write-todos` skill.
|
|
250
|
+
### Migrating from bundled roles
|
|
194
251
|
|
|
195
|
-
|
|
252
|
+
Earlier versions bundled seven roles and two workflows. They have moved to
|
|
253
|
+
separately installed packs or have been removed. Nothing is installed
|
|
254
|
+
automatically, and your global and project role files and `config.json` are not
|
|
255
|
+
modified.
|
|
196
256
|
|
|
197
|
-
|
|
257
|
+
| Former bundled surface | Status | Destination |
|
|
258
|
+
| --- | --- | --- |
|
|
259
|
+
| `scout`, `planner`, `worker`, `reviewer`, `adversarial-reviewer`, `visual-tester` roles | Moved | `pi-herdr-roles` role pack |
|
|
260
|
+
| `/plan` command and its plan skill | Moved | `pi-herdr-roles` |
|
|
261
|
+
| `/skill:orchestrate` and its adversarial-review resources | Moved | `pi-herdr-roles` |
|
|
262
|
+
| `poteto` role | Removed; replaced by the `poteto-mode` skill and `/poteto-mode` command | `pi-herdr-pstack` |
|
|
263
|
+
| `/iterate` | Removed, not relocated | Call `subagent({ name, task, fork: true, interactive: true })` directly |
|
|
264
|
+
| `/btw`, `/btw-close` | Removed, not relocated | None |
|
|
265
|
+
| `roles.bundled` setting | Deprecated no-op | Remove it from `config.json` |
|
|
266
|
+
|
|
267
|
+
Both destination packs are experimental, unpublished candidates; their install
|
|
268
|
+
sources and compatible host versions are not final. Install a role pack with
|
|
269
|
+
`pi install` like any Pi package and enable it beside this extension; a role pack
|
|
270
|
+
stays inert without it. Older versions of this package that still bundle these
|
|
271
|
+
roles, `/plan`, or `orchestrate` collide with the replacement packs: a bundled
|
|
272
|
+
role rejects a same-named pack role, and Pi resolves duplicate commands and
|
|
273
|
+
skills by discovery order. Setting `roles.bundled: false` on an older host only
|
|
274
|
+
removes its roles, not its command or skill. Upgrade the host instead of
|
|
275
|
+
combining an older host with the replacement packs.
|
|
276
|
+
|
|
277
|
+
Existing `models.agents` preferences keyed by role name keep applying when a
|
|
278
|
+
pack or definition supplies that name. To keep a former role without installing
|
|
279
|
+
a pack, copy its definition into `.pi/agents/` or the global agents directory.
|
|
280
|
+
|
|
281
|
+
Roles use model defaults from `config.json` when configured; otherwise
|
|
198
282
|
they inherit the parent model. Thinking defaults still come from agent
|
|
199
283
|
frontmatter or the parent level. This resolution chain remains available as a
|
|
200
284
|
fallback, but orchestrators should explicitly set each child's exact
|
|
@@ -207,17 +291,16 @@ different model family than the author. For ordinary review, prefer a different
|
|
|
207
291
|
authenticated model family. When no other authenticated model family is
|
|
208
292
|
available, ordinary review may use a same-family reviewer in a fresh standalone
|
|
209
293
|
session. Disclose that this review is context-isolated, not cross-family
|
|
210
|
-
independent. Cross-family verification
|
|
211
|
-
|
|
212
|
-
family is a quality escalation, not cross-family
|
|
294
|
+
independent. Cross-family verification must not use this fallback. A stronger
|
|
295
|
+
model in the same family is a quality escalation, not cross-family
|
|
213
296
|
independent review. Family is the independence boundary; project policy may
|
|
214
297
|
separately require a different provider.
|
|
215
298
|
|
|
216
299
|
Discovery loads definitions in **package → global → project** order, so effective
|
|
217
300
|
priority remains **project** (`.pi/agents/`) > **global**
|
|
218
301
|
(`$PI_CODING_AGENT_DIR/agents/`, defaulting to `~/.pi/agent/agents/`) >
|
|
219
|
-
**package**. Package definitions
|
|
220
|
-
|
|
302
|
+
**package**. Package definitions are the roles contributed by installed Pi role
|
|
303
|
+
packs; there is no bundled layer. Both `subagents_list` and `/subagent list` show each
|
|
221
304
|
visible definition's source; contributed roles include their package identity,
|
|
222
305
|
for example `(package:@acme/security-roles)`. A hidden higher-priority definition
|
|
223
306
|
still suppresses a visible lower-priority definition.
|
|
@@ -268,6 +351,7 @@ Projected labels include:
|
|
|
268
351
|
- `stalled` — pane inspection is unhealthy long enough that the parent can no longer trust the run
|
|
269
352
|
- `running` — fallback when only coarse process presence is known (e.g. non-Pi backends)
|
|
270
353
|
- `finalizing` — completion was observed and delivery is in progress; the process elapsed timer freezes here
|
|
354
|
+
- `cancelling…` / `cancel unconfirmed` — a `subagent_cancel` is terminating the run, or its termination could not be confirmed and the run stays live
|
|
271
355
|
|
|
272
356
|
The widget header counts **active** vs **open**:
|
|
273
357
|
|
|
@@ -278,7 +362,7 @@ When `activeCount === 0` (every tracked row is open), the border uses an amber a
|
|
|
278
362
|
|
|
279
363
|
A fixed internal watchdog marks a run as `stalled` when pane inspection fails or the pane disappears without a completion sidecar; valid long-running `active` or `waiting` states do not become `stalled` just because time passes. When a run enters `stalled` or recovers from it, the parent agent receives a steer message so it can react. All other status transitions stay in the widget only.
|
|
280
364
|
|
|
281
|
-
**Interactive subagents stay silent.** Long-running user-driven subagents (
|
|
365
|
+
**Interactive subagents stay silent.** Long-running user-driven subagents (for example, an interactive planning role or a bare `interactive: true` fork) do not wake the parent session on `stalled`/`recovered` transitions — the user is working directly in the subagent's pane, and a steer message there would just burn an orchestrator turn on a no-op "still waiting" ping. The widget still updates normally, and activity snapshots are still recorded/classified regardless of the `interactive` setting. By default, agents with `auto-exit: true` are treated as autonomous and get stall pings; agents without it are treated as interactive and stay quiet. Override per-agent with `interactive: true|false` in frontmatter, or per-spawn with `interactive: true|false` on the tool call.
|
|
282
366
|
|
|
283
367
|
#### Configuration
|
|
284
368
|
|
|
@@ -298,9 +382,6 @@ or re-run `/subagents-init`.
|
|
|
298
382
|
"models": {
|
|
299
383
|
"agents": {}
|
|
300
384
|
},
|
|
301
|
-
"roles": {
|
|
302
|
-
"bundled": true
|
|
303
|
-
},
|
|
304
385
|
"persistent": {
|
|
305
386
|
"maxAgents": 3
|
|
306
387
|
},
|
|
@@ -355,8 +436,8 @@ a reviewer from a different model family than the author. For ordinary review,
|
|
|
355
436
|
prefer a different authenticated model family. When no other authenticated
|
|
356
437
|
model family is available, ordinary review may use a same-family reviewer in a
|
|
357
438
|
fresh standalone session. Disclose that this review is context-isolated, not
|
|
358
|
-
cross-family independent. Cross-family verification
|
|
359
|
-
|
|
439
|
+
cross-family independent. Cross-family verification must not use this fallback.
|
|
440
|
+
Use an exact authenticated
|
|
360
441
|
shortlist `provider/model-id` when the
|
|
361
442
|
authoring family is known; `task:review` does not establish independence. Family
|
|
362
443
|
is the independence boundary; project policy may separately require a different
|
|
@@ -409,11 +490,37 @@ preserving unrelated settings. Its tool schema accepts partial nonempty
|
|
|
409
490
|
categories (omitted categories are removed), rejects empty `tasks: {}` input,
|
|
410
491
|
and rejects exact duplicate refs within a category after trimming;
|
|
411
492
|
IDs remain case-sensitive. Its result includes normalized saved `tasks`,
|
|
412
|
-
`tasksMeta`, `configPath`, and `
|
|
493
|
+
`tasksMeta`, `configPath`, `missingCategories`, and `configRevision`. Init requests all six categories
|
|
413
494
|
and a before/after table based on that saved result, not the unsaved draft. It
|
|
414
495
|
must explain missing categories or changed choices; with no available models,
|
|
415
496
|
it must report the limitation without writing.
|
|
416
497
|
|
|
498
|
+
Optional `expectedConfigRevision` makes a write conditional on the config the
|
|
499
|
+
proposal was read from. A revision is `sha256:` followed by 64 lowercase hex
|
|
500
|
+
digits of the SHA-256 of the exact `config.json` bytes (not normalized JSON or
|
|
501
|
+
only `models.tasks`), or the literal `missing` when the file is absent. Any byte
|
|
502
|
+
change, including whitespace or unrelated settings, makes the revision stale; a
|
|
503
|
+
`missing` revision rejects a file that now exists, and an existing revision
|
|
504
|
+
rejects a file that was removed. A stale revision fails with `Stale task model
|
|
505
|
+
config revision` without replacing configuration: re-read, re-propose, and
|
|
506
|
+
re-approve rather than retrying. Malformed revisions, including `null` and empty
|
|
507
|
+
strings, fail closed. Omitting the field keeps the unconditional write. A write
|
|
508
|
+
to a missing file still seeds from the packaged `config.json.example`.
|
|
509
|
+
`configRevision` is the revision of the exact bytes written and can serve as the
|
|
510
|
+
next precondition.
|
|
511
|
+
|
|
512
|
+
Every writer call, conditional or not, holds an exclusive `config.json.lock`
|
|
513
|
+
sibling while it reads one snapshot, checks the revision, and atomically renames
|
|
514
|
+
a private temporary file into place. A held lock fails immediately with `Task
|
|
515
|
+
model config writer busy`; there are no waits or retries. The lock is never
|
|
516
|
+
broken automatically: after a crash, the error names the recorded owner and
|
|
517
|
+
reports when that process is no longer running, and you remove the lock only
|
|
518
|
+
after confirming that no writer is active. Each call removes only its own lock
|
|
519
|
+
and temporary file. This lock is advisory: it serializes cooperating writers
|
|
520
|
+
but cannot constrain a text editor or another process that ignores it. The
|
|
521
|
+
revision check detects changes made before the snapshot is read; it is not a
|
|
522
|
+
filesystem transaction against arbitrary external writers.
|
|
523
|
+
|
|
417
524
|
`task:<category>` values select subagent models; they are not slash commands and
|
|
418
525
|
do not change the parent model. Ordered authenticated candidate plans resolve
|
|
419
526
|
before launch. Ordinary nonpersistent runs can retry later candidates after
|
|
@@ -426,16 +533,21 @@ review requires a reviewer from a different model family than the author. For
|
|
|
426
533
|
ordinary review, prefer a different authenticated model family. When no other
|
|
427
534
|
authenticated model family is available, ordinary review may use a same-family
|
|
428
535
|
reviewer in a fresh standalone session. Disclose that this review is
|
|
429
|
-
context-isolated, not cross-family independent. Cross-family verification
|
|
430
|
-
|
|
431
|
-
Another route to the same family is not
|
|
536
|
+
context-isolated, not cross-family independent. Cross-family verification
|
|
537
|
+
must not use this fallback. Another route to the same family is not
|
|
432
538
|
independent review. Family is the independence boundary; project policy may
|
|
433
539
|
separately require a different provider. Run `/reload` (or start a new session)
|
|
434
540
|
after writing preferences.
|
|
435
541
|
|
|
436
542
|
Set `persistent.maxAgents` to the maximum concurrently retained persistent specialists. It defaults to `3`; a persistent spawn at the cap is rejected before Herdr creates a pane or workspace, and no specialist is evicted.
|
|
437
543
|
|
|
438
|
-
|
|
544
|
+
`roles.bundled` is deprecated and has no effect because this package ships no
|
|
545
|
+
roles. Existing `true` and `false` values are accepted so that current
|
|
546
|
+
configuration keeps loading; a parent session reports one warning per extension
|
|
547
|
+
load naming the file and asking you to remove the key. The extension never
|
|
548
|
+
rewrites the file. Other values remain configuration errors, as do unknown keys
|
|
549
|
+
under `roles`. Registered role packs are the entire package layer, and global and
|
|
550
|
+
project definitions keep their precedence over them.
|
|
439
551
|
|
|
440
552
|
### Supervision transport
|
|
441
553
|
|
|
@@ -470,7 +582,8 @@ never interrupts, kills, retries, or restarts a child. It identifies `blocked-to
|
|
|
470
582
|
`truncated-turn` (an observed `toolUse` stop with no tool call; its cause is unknown), or
|
|
471
583
|
`generic-no-progress` when neither condition is established, then
|
|
472
584
|
includes the session path and manual recovery options. Ordinary children can be
|
|
473
|
-
interrupted or, after
|
|
585
|
+
interrupted, cancelled with `subagent_cancel`, or, after termination, resumed or
|
|
586
|
+
newly spawned. Persistent
|
|
474
587
|
ordinary-pane specialists can be interrupted or stopped with `subagent_stop` and
|
|
475
588
|
replaced; they cannot be resumed. Managed-worktree children, including persistent
|
|
476
589
|
ones, retain their workspace and continue there only after the previous process
|
|
@@ -490,11 +603,11 @@ was 4.82 s. The benchmark measures `/proc` CPU ticks for the supervisor and
|
|
|
490
603
|
isolated Herdr tree, not parent-model latency; raw samples are written to
|
|
491
604
|
`/tmp/issue29-bench/` by `test/bench/supervision-bench.mjs`.
|
|
492
605
|
|
|
493
|
-
`panes.mode` defaults to `"grouped"` when omitted. Ordinary public `subagent` and `subagent_resume` launches, including bare forks
|
|
606
|
+
`panes.mode` defaults to `"grouped"` when omitted. Ordinary public `subagent` and `subagent_resume` launches, including bare forks, fill extension-owned `Agents`, `Agents 2`, etc. tabs in the target checkout's existing workspace. `panes.maxPerTab` is a positive safe integer, defaults to `4`, and counts all live panes in each owned tab, including user-added panes and retained shells. Overlapping launches in one parent respect this cap. It is independent of `persistent.maxAgents`.
|
|
494
607
|
|
|
495
608
|
Checkout matching uses Herdr's canonical `worktree.checkout_path` and includes descendant directories. Shell working directories do not establish workspace ownership. If no checkout matches (including non-Git directories), placement uses the caller's workspace; overflow never creates a workspace. A reviewer with `cwd` set to a managed checkout joins that workspace without creating another worktree. Resume placement uses the saved session's cwd.
|
|
496
609
|
|
|
497
|
-
Explicit `panes.mode: "tab"` preserves one new tab per ordinary child in the caller's workspace. Explicit `"split"` preserves splits of the stable parent pane. `panes.direction` is `"right"` (default) or `"down"` and applies to grouped and legacy splits. `maxPerTab` does not affect these legacy modes. Managed worktrees retain their separate workspaces
|
|
610
|
+
Explicit `panes.mode: "tab"` preserves one new tab per ordinary child in the caller's workspace. Explicit `"split"` preserves splits of the stable parent pane. `panes.direction` is `"right"` (default) or `"down"` and applies to grouped and legacy splits. `maxPerTab` does not affect these legacy modes. Managed worktrees retain their separate workspaces.
|
|
498
611
|
|
|
499
612
|
Ownership is tracked by returned pane/tab/workspace IDs, never labels. Separate parent processes own separate groups; `/reload` preserves a parent's in-memory ownership, but a full restart does not adopt old tabs. Placement never moves existing panes or renames user tabs. Background launches preserve focus; Herdr may resize sibling panes when splitting or closing. User-added panes are never closed by automatic tab cleanup. An owned tab remains reusable while user panes remain, even after all child panes close.
|
|
500
613
|
|
|
@@ -536,12 +649,15 @@ when the extension starts. Run `/reload` after changing it. Package-root
|
|
|
536
649
|
|
|
537
650
|
## Spawning Subagents
|
|
538
651
|
|
|
652
|
+
Examples that set `agent` assume a role pack or a project/global definition
|
|
653
|
+
supplies that role; this package ships none.
|
|
654
|
+
|
|
539
655
|
```typescript
|
|
540
656
|
// Explicit fast-tier runtime for bounded reconnaissance
|
|
541
657
|
subagent({ name: "Scout", agent: "scout", model: "<provider>/<fast-tier-id>", thinking: "low", task: "Analyze the codebase..." });
|
|
542
658
|
|
|
543
659
|
// Force a full-context fork for this spawn
|
|
544
|
-
subagent({ name: "
|
|
660
|
+
subagent({ name: "Fix", fork: true, model: "<provider>/<mid-tier-id>", thinking: "medium", task: "Fix the bug where..." });
|
|
545
661
|
|
|
546
662
|
// Explicit frontier-tier runtime for architecture work
|
|
547
663
|
subagent({ name: "Planner", agent: "planner", model: "<provider>/<frontier-tier-id>", thinking: "high", task: "Work through the design with me" });
|
|
@@ -572,12 +688,19 @@ subagent({
|
|
|
572
688
|
| `interactive` | boolean | derived | Mark this spawn as interactive (don't wake the parent on stall/recovery). Defaults to the agent's `interactive` frontmatter, otherwise the inverse of `auto-exit`. |
|
|
573
689
|
| `model` | string | configured or parent | Exact authenticated `provider/model-id`, ordered fallback list, or whole-value `task:<category>` (coding, review, recon, qa, architecture, docs). Task routing is tool-only; worktrees use its first authenticated candidate. Resolution is tool argument → agent frontmatter → per-agent config → global config → parent |
|
|
574
690
|
| `thinking` | string | parent level | Pick the model tier first, then set thinking within that model's range: minimal/low for bounded mechanical work, medium for ordinary implementation or review, high+ for architecture, security, or hard diagnosis. Omitting still inherits the parent level; this is a discouraged fallback for orchestrated children. |
|
|
575
|
-
| `systemPrompt` | string | — | Role
|
|
691
|
+
| `systemPrompt` | string | — | Role text for a bare spawn, delivered as a role block at the top of the child's first message (not the system prompt); dropped for `fork: true` children. Named agents keep their definition body |
|
|
576
692
|
| `skills` | string | — | Comma-separated skill names |
|
|
577
693
|
| `tools` | string | — | Comma-separated tool names |
|
|
578
694
|
| `cwd` | string | — | Working directory, or source repository when `worktree` is set (see [Role Folders](#role-folders)) |
|
|
579
695
|
| `worktree` | object \| null | — | Isolated Herdr-managed Git worktree; requires `branch`, with optional `base` (committed `HEAD` by default). Omit or pass `null` to use an ordinary pane in `cwd` when a client requires the property. |
|
|
580
696
|
|
|
697
|
+
A bare spawn's `systemPrompt` is not passed to Pi as a system prompt. The host
|
|
698
|
+
prepends it as a role block to the child's first message, which is delivered
|
|
699
|
+
through a task artifact file referenced with `@path`. A full-context fork
|
|
700
|
+
(`fork: true`) receives only the raw task, so its `systemPrompt` is dropped. Set
|
|
701
|
+
`fork: false` when a bare child must receive reference or role text through
|
|
702
|
+
`systemPrompt`.
|
|
703
|
+
|
|
581
704
|
### Naming coordinated children
|
|
582
705
|
|
|
583
706
|
Before launching a new group, choose a short task slug and label each new child
|
|
@@ -591,7 +714,15 @@ prompts, handoffs, and results.
|
|
|
591
714
|
|
|
592
715
|
Use one worktree per parallel independent writing task; a single or sequential writer can work in the parent checkout, and read-only agents use ordinary panes. Omit `worktree` for an ordinary pane; clients whose generated tool schema requires every property may send `worktree: null` with the same effect. `cwd` selects the source Git repository, `branch` must be unique, and `base` is resolved to an exact commit before creation. If `cwd` is a linked checkout, Herdr provisioning uses the principal checkout while the requested checkout supplies the base SHA and manifest provenance. A successful launch from that linked checkout does not itself authorize cleanup there: cleanup checks the canonical principal/source repository under the invoking parent session's cwd, not `manifest.sourceCwd` or shared Git identity. If cleanup is needed, start the parent Pi session rooted at the principal checkout or an ancestor containing it, then use the normal explicit cleanup flow; changing directories inside an existing Pi session does not change its session cwd. If `base` is omitted, the source checkout's committed `HEAD` is used. Parent-checkout changes that have not been committed are not copied.
|
|
593
716
|
|
|
594
|
-
|
|
717
|
+
Choose a worktree from the task, not from a role name: the extension emits no
|
|
718
|
+
role-specific worktree warnings. Read-only scouting and review normally use an
|
|
719
|
+
ordinary pane; to inspect or review an existing worker result, start an ordinary
|
|
720
|
+
child in that retained worktree path. Do not infer that a role cannot write
|
|
721
|
+
because its `tools` omit `write` or `edit`: a `read,bash` allowlist is not an
|
|
722
|
+
enforced read-only boundary because shell commands can mutate files. Report-only
|
|
723
|
+
roles must restrict Bash to safe inspection and avoid artifact-generating
|
|
724
|
+
verification in the reviewed checkout. Herdr worktree workspaces persist until
|
|
725
|
+
explicitly removed.
|
|
595
726
|
|
|
596
727
|
The child starts at the returned worktree root. Tell writing agents to test and commit when you want a commit-based handoff, and tell them not to push, merge, switch branches, or remove the worktree. The parent owns review and integration.
|
|
597
728
|
|
|
@@ -627,27 +758,41 @@ This sends Escape to the child pane, cancelling the in-progress model turn. The
|
|
|
627
758
|
|
|
628
759
|
`id` and `name` are each optional, but execution requires one usable target: an exact running ID or an exact, unambiguous display name. When both are supplied, `id` is used. Duplicate names are rejected.
|
|
629
760
|
|
|
630
|
-
This is a turn-level interrupt, not a method for forcibly terminating a subagent session.
|
|
761
|
+
This is a turn-level interrupt, not a method for forcibly terminating a subagent session. To end the run, use `subagent_cancel`.
|
|
631
762
|
|
|
632
|
-
|
|
763
|
+
## Cancelling a running subagent
|
|
764
|
+
|
|
765
|
+
Use `subagent_cancel` to end one ordinary (non-persistent) managed run, including an interrupted one:
|
|
766
|
+
|
|
767
|
+
```typescript
|
|
768
|
+
subagent_cancel({ id: "abcd1234" });
|
|
769
|
+
// or
|
|
770
|
+
subagent_cancel({ name: "Scout" });
|
|
771
|
+
```
|
|
772
|
+
|
|
773
|
+
Target resolution matches `subagent_interrupt`: an exact running ID or an exact, unambiguous display name. Persistent specialists are rejected; use `subagent_stop`, whose graceful v1 semantics are unchanged.
|
|
774
|
+
|
|
775
|
+
The cancel intent is recorded before anything is aborted or killed. From then on the run never advances its model shortlist, retries, or recovers, even when terminating the pane makes the watcher observe a lost pane, and even when a fallback launch was already in flight. The result reports one status:
|
|
776
|
+
|
|
777
|
+
| Status | Meaning |
|
|
778
|
+
| --- | --- |
|
|
779
|
+
| `confirmed` | Termination is confirmed. One cancelled result is delivered automatically. |
|
|
780
|
+
| `requested` | A launch or fallback acquisition is still in flight. Its owner is terminated as soon as it is acquired; no later model is tried. |
|
|
781
|
+
| `unconfirmed` | Termination failed (the error is reported). The run stays live, owned, and supervised, and nothing is delivered or cleaned up. Call `subagent_cancel` again to retry. |
|
|
782
|
+
| `already-terminal` | The run already took a natural result or was retired; nothing was cancelled. |
|
|
633
783
|
|
|
634
|
-
|
|
784
|
+
Repeated cancels join an in-flight termination and keep the first request time. The parent receives exactly one `subagent_result` whose details carry `error: "cancelled"` and a `cancellation` record (`requestedAt`, `termination`, `confirmedAt`). Its message says the run was cancelled and lists any models already attempted. It is never presented as a provider failure. A child's natural result taken before the cancel stays authoritative. A cancel while a provider error is still eligible for fallback wins and stops that fallback.
|
|
635
785
|
|
|
636
|
-
|
|
637
|
-
or accessible combinations. The parent pins repository, base/head SHAs, task and
|
|
638
|
-
specification text, author origin, changed-file inventory, and complete diff
|
|
639
|
-
(including deleted and base-only content), then launches two or more fresh
|
|
640
|
-
public reviewer subagents in ordinary panes. Each child receives an exact model
|
|
641
|
-
and thinking level, a role-defined tool allowlist, and the instruction to treat
|
|
642
|
-
all supplied artifacts as untrusted data. Automatic delivery returns every
|
|
643
|
-
review result without polling; the parent synthesizes the outcomes.
|
|
786
|
+
Termination follows surface ownership:
|
|
644
787
|
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
`
|
|
788
|
+
- **Ordinary pane:** the pane is closed. Confirmation is Herdr reporting it absent; closing a Herdr pane terminates its terminal session, but this is not a separate OS process check. Other panes, tabs, and user panes are never closed.
|
|
789
|
+
- **Managed worktree:** the retained root pane, workspace, checkout, branch, commits, and manifest are kept. At launch, the child records its own process identity (PID, kernel start time, boot ID, and PID namespace) beside its session; the parent accepts it only while that process is alive in the parent's PID namespace as the Herdr pane shell or a descendant of it. SIGTERM goes only to that identity, re-verified immediately before the signal. Confirmation requires that identity to no longer exist, or the pane to be gone while it is not known alive. Command-line text and Herdr's foreground list are never evidence, because Pi rewrites its process title. A live identity (for example a suspended Pi), or one whose SIGTERM fails while it is still alive, leaves termination `unconfirmed` even if the pane is gone. An identity that was not captured (including on non-Linux hosts), is unreadable, or whose PID now names another process is never signalled and leaves termination `unconfirmed` unless pane absence confirms it. Every Herdr query and capture wait is bounded by the cancel's deadline (5 seconds); an answer that arrives after the deadline is ignored, even if it settles before the timer runs, and never changes a reported outcome. A retry re-checks, and if the launch capture expired it captures the identity again within its own deadline. The manifest becomes `cancelled` only after confirmed termination (a parent shutdown while unconfirmed records the plain shutdown state), and the normal worktree handoff is delivered. No Git cleanup is performed. See [Worktree subagents](docs/worktree-subagents.md).
|
|
790
|
+
|
|
791
|
+
Do not poll after cancelling; the cancelled result arrives as a steer message. Design rationale: [ADR-0014](docs/adr/0014-operator-cancel-terminal-intent.md).
|
|
792
|
+
|
|
793
|
+
The package ships one host-owned skill, `pi-herdr-agents`, a general operating guide covering launching, lifecycle control, persistent specialists, worktrees, and configuration. Live tool descriptions and this README remain authoritative.
|
|
794
|
+
|
|
795
|
+
---
|
|
651
796
|
|
|
652
797
|
## caller_ping — Child-to-Parent Help Request
|
|
653
798
|
|
|
@@ -689,50 +834,24 @@ await caller_ping({
|
|
|
689
834
|
|
|
690
835
|
---
|
|
691
836
|
|
|
692
|
-
##
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
---
|
|
712
|
-
|
|
713
|
-
## The `/iterate` Workflow
|
|
714
|
-
|
|
715
|
-
For quick, focused work without polluting the main session's context.
|
|
716
|
-
|
|
717
|
-
```
|
|
718
|
-
/iterate Fix the off-by-one error in the pagination logic
|
|
719
|
-
```
|
|
720
|
-
|
|
721
|
-
This always forks the current session into a subagent with full conversation context. It does not inherit an agent default `session-mode`. Make the fix, verify it, and exit to return. The main session gets a summary of what was done.
|
|
722
|
-
|
|
723
|
-
---
|
|
724
|
-
|
|
725
|
-
## The `/btw` Workflow
|
|
726
|
-
|
|
727
|
-
Use `/btw` for a quick side question without adding a turn to the main session:
|
|
728
|
-
|
|
729
|
-
```text
|
|
730
|
-
/btw What did we decide about session cleanup?
|
|
731
|
-
```
|
|
732
|
-
|
|
733
|
-
The extension snapshots the current active conversation branch, opens a non-focused Herdr tab, and starts an interactive Pi session with the same model and thinking level. The answer stays in that tab and is never delivered as a subagent result. A second `/btw` replaces the previous one; `/btw-close` closes it explicitly.
|
|
734
|
-
|
|
735
|
-
BTW shares the current working directory. It treats inherited work as reference context and modifies the workspace only when the side question explicitly requests it. Cleanup is best effort; if closing fails, the tab remains available for manual recovery.
|
|
837
|
+
## Child-context hint (`PI_SUBAGENT_ID`)
|
|
838
|
+
|
|
839
|
+
Every fresh or resumed child launched by this extension, including `fork: true`
|
|
840
|
+
children and persistent specialists, runs with `PI_SUBAGENT_ID` set to its run
|
|
841
|
+
ID. The extension uses it to register the child protocol tools and to omit
|
|
842
|
+
parent-only surfaces (`worktree_list`, `worktree_remove`,
|
|
843
|
+
`subagents_write_task_models`, and `/subagents-init`). A `/worktree <name>`
|
|
844
|
+
handoff starts an ordinary interactive Pi session and does not set it. Pi's own
|
|
845
|
+
`/fork` and `/clone` run in the same process and keep that process's
|
|
846
|
+
environment: the variable is absent in a top-level session and still present
|
|
847
|
+
inside a child.
|
|
848
|
+
|
|
849
|
+
Role packs may read `PI_SUBAGENT_ID` as a context hint, for example to avoid
|
|
850
|
+
restoring parent-only session state inside a delegated child. It is not an
|
|
851
|
+
authentication or security boundary: any process can set it, and shell commands
|
|
852
|
+
and nested processes a child runs inherit it, including a `pi` process started
|
|
853
|
+
from the child's Bash tool. Do not grant or deny privileges based on it. There
|
|
854
|
+
is no other parent/child protocol.
|
|
736
855
|
|
|
737
856
|
---
|
|
738
857
|
|
|
@@ -765,7 +884,6 @@ not disguise a workflow as an agent definition.
|
|
|
765
884
|
| Project | `.pi/agents/<name>.md` | The role belongs to one repository |
|
|
766
885
|
| Global | `$PI_CODING_AGENT_DIR/agents/<name>.md` | The role should be available everywhere; the default root is `~/.pi/agent` |
|
|
767
886
|
| Role pack | An installed Pi package's registered `roles/` directory | The role should be independently installable and shareable |
|
|
768
|
-
| Bundled | This package's `agents/<name>.md` | Contributing a fallback role maintained with `pi-herdr-agents` |
|
|
769
887
|
|
|
770
888
|
The filename stem is the launch key. `name` frontmatter is optional because it
|
|
771
889
|
defaults to the filename stem. If supplied, keep it identical so overrides remain
|
|
@@ -886,9 +1004,10 @@ the files, derives package name/version from the nearest `package.json`, and
|
|
|
886
1004
|
reports invalid paths, missing descriptions, filename/name mismatches, and
|
|
887
1005
|
package-layer collisions in the listing surfaces.
|
|
888
1006
|
|
|
889
|
-
|
|
890
|
-
from multiple role packs are disabled
|
|
891
|
-
order. Use a global or
|
|
1007
|
+
Registered role packs form the whole package layer and have no priority over
|
|
1008
|
+
one another: duplicate role names from multiple role packs are disabled with a
|
|
1009
|
+
diagnostic rather than resolved by extension load order. Use a global or
|
|
1010
|
+
project definition for an intentional override.
|
|
892
1011
|
|
|
893
1012
|
See [ADR-0003](docs/adr/0003-installable-role-packs.md) for the registration seam,
|
|
894
1013
|
collision rules, and rejected alternatives.
|
|
@@ -930,7 +1049,7 @@ Compare definitions against the reference below and verify them with
|
|
|
930
1049
|
| `session-mode` | string | Default child-session mode: `standalone`, `lineage-only`, or `fork` |
|
|
931
1050
|
| `spawning` | boolean | Set exactly `false` to deny all subagent-spawning tools under the exact unquoted key `spawning:`. Only one `true` or `false` declaration is accepted. |
|
|
932
1051
|
| `deny-tools` | string | One non-empty inline comma-separated `pi-herdr-agents` tool list to suppress under the exact unquoted key `deny-tools:`; this is not a universal cross-extension deny list. YAML lists, containers, multiline values, quotes, comments, noncanonical keys, and duplicates are rejected. |
|
|
933
|
-
| `auto-exit` | boolean | Auto-shutdown after Pi fully settles when the latest assistant turn does not end with `stopReason: "aborted"` — no `subagent_done` call needed. User input does not permanently disable auto-exit. Recommended for autonomous
|
|
1052
|
+
| `auto-exit` | boolean | Auto-shutdown after Pi fully settles when the latest assistant turn does not end with `stopReason: "aborted"` — no `subagent_done` call needed. User input does not permanently disable auto-exit. Recommended for autonomous roles; not for interactive ones the user drives. Also determines the default value of `interactive` (see below). |
|
|
934
1053
|
| `interactive` | boolean | Override whether stall/recovery transitions wake the parent session. Defaults to the inverse of `auto-exit`: autonomous agents (`auto-exit: true`) are non-interactive and get stall pings; agents without `auto-exit` are interactive and stay quiet. Explicit values take precedence. |
|
|
935
1054
|
| `persistent` | boolean | Keep this role's specialist session open between tasks. Follow-up work uses `subagent_send`; persistent specialists cannot be resumed in v1. |
|
|
936
1055
|
| `cwd` | string | Default working directory. Absolute paths are unambiguous; relative agent-frontmatter paths resolve from Pi's agent config directory (`PI_CODING_AGENT_DIR` or `~/.pi/agent`), not the project root |
|
|
@@ -938,7 +1057,7 @@ Compare definitions against the reference below and verify them with
|
|
|
938
1057
|
|
|
939
1058
|
---
|
|
940
1059
|
|
|
941
|
-
Discovery still resolves precedence before visibility filtering. If a project-local hidden agent has the same name as a visible global or
|
|
1060
|
+
Discovery still resolves precedence before visibility filtering. If a project-local hidden agent has the same name as a visible global or role-pack agent, the hidden project agent wins and the lower-precedence agent does not appear in `subagents_list`.
|
|
942
1061
|
|
|
943
1062
|
### `session-mode`
|
|
944
1063
|
|
|
@@ -950,7 +1069,7 @@ Choose how a subagent session starts:
|
|
|
950
1069
|
|
|
951
1070
|
`lineage-only` is useful when you want session discovery and fork lineage UX to show the relationship later, but you do **not** want the child to inherit the parent's turns.
|
|
952
1071
|
|
|
953
|
-
`fork: true` on the tool call forces `fork` mode; `fork: false` forces `standalone` mode. Omitting `fork` inherits the agent's frontmatter `session-mode`.
|
|
1072
|
+
`fork: true` on the tool call forces `fork` mode; `fork: false` forces `standalone` mode. Omitting `fork` inherits the agent's frontmatter `session-mode`.
|
|
954
1073
|
|
|
955
1074
|
```yaml
|
|
956
1075
|
---
|
|
@@ -972,8 +1091,8 @@ When set to `true`, the agent session shuts down on Pi's `agent_settled` event u
|
|
|
972
1091
|
|
|
973
1092
|
**When to use:**
|
|
974
1093
|
|
|
975
|
-
- ✅ Autonomous
|
|
976
|
-
- ❌ Interactive
|
|
1094
|
+
- ✅ Autonomous roles, such as scouting, implementation, or review, that run to completion
|
|
1095
|
+
- ❌ Interactive roles or `interactive: true` forks where the user drives the session
|
|
977
1096
|
|
|
978
1097
|
```yaml
|
|
979
1098
|
---
|
|
@@ -986,7 +1105,7 @@ auto-exit: true
|
|
|
986
1105
|
|
|
987
1106
|
Controls whether status transitions (`stalled`, `recovered`) wake the parent session with a steer message.
|
|
988
1107
|
|
|
989
|
-
**Default:** the inverse of `auto-exit`. Autonomous agents (`auto-exit: true`) are non-interactive and ping the parent on stall/recovery; named agents without `auto-exit` are interactive and stay quiet. Bare spawns have no agent definition and default to autonomous auto-exit behavior
|
|
1108
|
+
**Default:** the inverse of `auto-exit`. Autonomous agents (`auto-exit: true`) are non-interactive and ping the parent on stall/recovery; named agents without `auto-exit` are interactive and stay quiet. Bare spawns have no agent definition and default to autonomous auto-exit behavior; they become interactive only when the call passes `interactive: true`.
|
|
990
1109
|
|
|
991
1110
|
**Why it exists:** Interactive agents can run for minutes or hours while the user thinks, types, and reads in the subagent's pane. Child snapshots still update the widget, but stalled/recovered supervision messages rarely need to wake the parent for user-driven sessions. Skipping the steer keeps the parent quiet until the child actually finishes.
|
|
992
1111
|
|
|
@@ -1016,7 +1135,7 @@ Without a restrictive `tools` allowlist or spawning policy, a sub-agent can spaw
|
|
|
1016
1135
|
|
|
1017
1136
|
### `spawning: false`
|
|
1018
1137
|
|
|
1019
|
-
Denies all subagent lifecycle tools (`subagent`, `subagent_interrupt`, `subagent_send`, `subagent_stop`, `subagents_list`, `subagent_resume`):
|
|
1138
|
+
Denies all subagent lifecycle tools (`subagent`, `subagent_interrupt`, `subagent_cancel`, `subagent_send`, `subagent_stop`, `subagents_list`, `subagent_resume`):
|
|
1020
1139
|
|
|
1021
1140
|
```yaml
|
|
1022
1141
|
---
|
|
@@ -1038,15 +1157,13 @@ deny-tools: subagent
|
|
|
1038
1157
|
|
|
1039
1158
|
### Recommended Configuration
|
|
1040
1159
|
|
|
1041
|
-
|
|
|
1160
|
+
| Role shape | `spawning` | Rationale |
|
|
1042
1161
|
| --- | --- | --- |
|
|
1043
|
-
|
|
|
1044
|
-
|
|
|
1045
|
-
|
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
| scout | `false` | Gathers context without delegation. |
|
|
1049
|
-
| visual-tester | `false` | Performs visual QA without delegation. |
|
|
1162
|
+
| Leaf (scouting, implementation, review, QA) | `false` | Performs one bounded responsibility without delegation. |
|
|
1163
|
+
| Coordinator | `true` | Delegates bounded children; a multi-wave coordinator sets `auto-exit: false` so automatic child-result steers drive each wave, then calls `subagent_done`. |
|
|
1164
|
+
| Interactive collaborator | *(default)* | May delegate factual gaps while the user drives the session. |
|
|
1165
|
+
|
|
1166
|
+
Each role pack documents the settings of the roles it ships.
|
|
1050
1167
|
|
|
1051
1168
|
---
|
|
1052
1169
|
|
|
@@ -1095,6 +1212,36 @@ Every sub-agent session displays a compact one-line tools widget summarizing ava
|
|
|
1095
1212
|
|
|
1096
1213
|
## Development
|
|
1097
1214
|
|
|
1215
|
+
### Code map
|
|
1216
|
+
|
|
1217
|
+
The maestro seams remain inside one npm package with the same Pi extension
|
|
1218
|
+
entry point. Pi is the sole real harness and Herdr the sole real surface
|
|
1219
|
+
provider; fakes are for conformance tests only.
|
|
1220
|
+
|
|
1221
|
+
- `pi-extension/subagents/index.ts` — Pi composition root: tools/commands,
|
|
1222
|
+
role-pack event bridge, host policy, widgets, and parent delivery.
|
|
1223
|
+
- `pi-extension/subagents/model-registry.ts`, `config-path.ts` — permanent
|
|
1224
|
+
host-local SDK capability glue and configuration-path conventions.
|
|
1225
|
+
- `maestro/core/` — seam interfaces/types, activity and lifecycle projection,
|
|
1226
|
+
status, routing, wake-ups, and supervision.
|
|
1227
|
+
- `maestro/core/roles/discovery.ts`, `maestro/core/config/` — role discovery,
|
|
1228
|
+
config loaders with injected directories, and task-model init prompt logic.
|
|
1229
|
+
- `maestro/core/worktree.ts`, `maestro/core/worktree-cleanup.ts` — manifest
|
|
1230
|
+
schema/state, handoff types, and cleanup eligibility/formatting.
|
|
1231
|
+
- `maestro/adapters/pi/` — Pi launch, completion, session I/O, activity files,
|
|
1232
|
+
model SDK glue, and registry projection behind `PiHarnessAdapter`;
|
|
1233
|
+
`child/subagent-done.ts` implements the child protocol.
|
|
1234
|
+
- `maestro/surfaces/herdr/` — `HerdrSurfaceProvider`, Herdr CLI driver, and
|
|
1235
|
+
terminal scripts/placement.
|
|
1236
|
+
- `maestro/runtime/` — run ownership, controls/retries, observation,
|
|
1237
|
+
delivery-gated cleanup, Pi composition, worktree operations/handoff, and
|
|
1238
|
+
task-model init composition.
|
|
1239
|
+
- `maestro/adapters/fake/`, `maestro/surfaces/fake/`, `test/maestro/` —
|
|
1240
|
+
conformance fakes, seam tests, and the import dependency-rule test.
|
|
1241
|
+
|
|
1242
|
+
See [ADR-0012](docs/adr/0012-adopt-maestro-seams-in-repo.md), the
|
|
1243
|
+
[glossary](CONTEXT.md), and the [documentation map](docs/README.md).
|
|
1244
|
+
|
|
1098
1245
|
Run local checks:
|
|
1099
1246
|
|
|
1100
1247
|
```bash
|
|
@@ -1129,4 +1276,4 @@ This package builds on earlier open-source work by [HazAT/pi-interactive-subagen
|
|
|
1129
1276
|
|
|
1130
1277
|
## License
|
|
1131
1278
|
|
|
1132
|
-
MIT. Copyright notice retained from the upstream lineage (`HazAT`).
|
|
1279
|
+
MIT, see [LICENSE](LICENSE). Copyright notice retained from the upstream lineage (`HazAT`).
|