@ferris1225/pi-subagents 3.0.0 → 4.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/README.md CHANGED
@@ -1,457 +1,478 @@
1
- # pi-subagents
2
-
3
- [![npm version](https://img.shields.io/npm/v/@ferris1225/pi-subagents?color=blue)](https://www.npmjs.com/package/@ferris1225/pi-subagents)
4
- [![downloads](https://img.shields.io/npm/dm/@ferris1225/pi-subagents)](https://www.npmjs.com/package/@ferris1225/pi-subagents)
5
- [![license](https://img.shields.io/npm/l/@ferris1225/pi-subagents)](./LICENSE)
6
- ![platform](https://img.shields.io/badge/platform-Windows%20%7C%20macOS%20%7C%20Linux-lightgrey)
7
- ![pi](https://img.shields.io/badge/pi-extension-orange)
8
-
9
- Focused background delegation for [pi](https://pi.dev): `explore` / `worker` /
10
- `cleaner` / `reviewer` agents run in **isolated child processes** and hand their
11
- results back to the main agent automatically. Install it, and the main model
12
- starts using it on its own — no prompt engineering, no babysitting.
13
-
14
- ## 2.0.0direct model handoff and capability-aware thinking
15
-
16
- Version 2 removes backup pools and global thinking strength. Every agent now has
17
- one optional selected model; any model/provider failure hands its retained session
18
- directly to the current main model, while ordinary tool/task failures stay put.
19
- Thinking defaults to Auto and is clamped through Pi's real model capability map.
20
- The setup menu and normalized config drop the obsolete options instead of carrying
21
- compatibility aliases.
22
-
23
- This release also adds semantic routing to a dedicated evidence-first `cleaner`
24
- and makes the active widget show each run's task, effective model/thinking,
25
- activity, and elapsed time. Every dispatch has a stable run id, so work can be
26
- steered while it runs, parked without losing context, resumed after settlement,
27
- retargeted, or forked into another path. Generation ownership keeps startup-race
28
- retries and stale child processes from corrupting the logical thread without
29
- retaining a duplicate event history.
30
-
31
- The common quality loop now runs end to end without waking the main agent between
32
- steps:
33
-
34
- ```text
35
- reviewer (find issues) worker (fix every finding) reviewer (verify) final PASS/FAIL
36
- ```
37
-
38
- Reviews use a single flat findings list — no severity triage. Every reported
39
- finding is fixed before the change is accepted, and each re-review converges on
40
- an open-finding set: the worker's explicit rejections are adjudicated once, only
41
- defects a fix round introduced or exposed are added, and resolved items never
42
- re-open. `maxFixRounds` stays the hard cap, so a chain always settles and wakes
43
- the main agent with the full picture.
44
-
45
- Cleanup stays a separate lifecycle: explicit cleanup intent can dispatch the
46
- evidence-first `cleaner`; any edits still go through the independent `reviewer`
47
- gate.
48
-
49
- Each chain is delivered as one concise completion group whose footer totals the
50
- aggregate token usage and cost of every included run, while full per-run reports
51
- remain available through `subagent_status`. Its parent stays `running`
52
- until the whole chain settles; completed internal rounds leave active status
53
- immediately, so no `done` row keeps accumulating elapsed time. Selected-to-main
54
- model handoffs keep the same retained context, and isolated parallel workers use
55
- detached Git worktrees whose changes are applied back without touching the parent
56
- index.
57
-
58
- ## Highlights
59
-
60
- - **Zero-setup proactive dispatch** the extension injects a delegation directive
61
- into the main system prompt, so the main model sends broad searches to `explore`,
62
- self-contained implementations to `worker`, explicit cleanup intent to `cleaner`,
63
- and pre-commit reviews to `reviewer`. You just use pi; delegation happens by itself.
64
- - **Multimodal work is a model choice, not a mode** — an agent that should see
65
- screenshots, mockups, or its own rendered pages simply gets a multimodal model
66
- through `/subagents-setup` (the picker labels each model `vision` or
67
- `text-only`). The agent reads images with its `read` tool on whatever model it
68
- runs; no per-task flag, no separate vision override.
69
- - **Results come back on their own** — completions are delivered as messages that
70
- wake the main agent automatically, even mid-turn. No polling, no `sleep`, no
71
- "go check" step. `subagent_wait` is a **non-blocking** in-turn lookup by default
72
- (pass `timeoutMs` to block); `subagent_status` inspects runs; `subagent_stop`
73
- cancels one and delivers its partial output.
74
- - **Active-only live widget, as a tree** each queued or running sub-agent gets one compact
75
- width-aware primary line with task, effective model/thinking, and elapsed time; current
76
- activity appears only when present on an indented second line. Auto-fix rounds nest under
77
- the triggering reviewer row that owns the chain, so it is always visible who dispatched
78
- what; no run ids appear here the tree and the task label identify each row:
79
- ```text
80
- reviewer · review diff of src/foo.ts · claude-sonnet-4-5/high · 42s
81
- worker · fix round 1 · src/foo.ts · claude-sonnet-4-5/high · 10s
82
- │ grep cacheKey
83
- reviewer · re-review round 1 · claude-sonnet-4-5/high · 3s
84
- ```
85
- Long tasks and activity paths truncate first (preserving a useful path tail when
86
- possible), groups have no blank rows, and settled/parked runs disappear immediately.
87
- - **Results are not re-narrated** — a sub-agent's completion is shown to you
88
- verbatim, and the main agent is told not to paraphrase it back. It replies with
89
- only its own conclusion or next step, so the same findings are never paid for
90
- twice in tokens.
91
- - **Evidence-first cleanup, not deletion by guesswork** `cleaner` distinguishes
92
- read-only audit wording from explicit apply wording, proves consumers and dynamic
93
- entrypoints before cutting, and treats finding nothing safe as a valid outcome.
94
- It is periodic/intent-driven, never PR-count-driven or an automatic commit gate.
95
- - **A quality gate that closes the loop** when a reviewer returns `REVIEW_FAIL`,
96
- the extension dispatches a worker briefed with the concrete findings, then a
97
- re-review, up to `maxFixRounds` times and only then wakes the main agent.
98
- Every reported finding gets fixed (no severity triage), and re-reviews converge
99
- on an open-finding set instead of ping-ponging: worker rejections are adjudicated
100
- once, only defects the fix round introduced are added, and resolved items never
101
- re-open. Every round stays in the triggering reviewer's cwd, and chains that target the
102
- same repository are serialized so shared-checkout edits cannot race.
103
- - **Direct fallback with real thinking capabilities** each agent has at most
104
- one selected model. An unavailable selection, rate limit, invalid key, quota,
105
- missing model, or provider failure hands directly to the current main model.
106
- A child-only provider adapter forces inner request retries to zero; transient
107
- stream drops still use Pi's outer turn retry, and only a settled model-level
108
- failure hands off, without changing user settings. Auto thinking clamps the
109
- agent preference to the
110
- effective model's real `thinkingLevelMap`; manual setup shows only levels that
111
- model supports.
112
- - **Resumes, retargets, and forks preserve context** every run is session-backed.
113
- `subagent_control` can steer active work, retarget it after a stable abort,
114
- park/resume it under the same run id, or fork a parked/settled checkpoint into
115
- a new independent run. Concurrent resume calls are serialized.
116
- - **Concise but honest completions** group completions end with aggregate token
117
- and cost totals across every included run; failed-tool diagnostics stay out of the
118
- delivered message and remain one `subagent_status` call away. Actual process,
119
- model, and integration failures still surface as failures.
120
- - **Parallel fan-out with filesystem isolation** independent tasks run up to a
121
- configurable limit (default 4). Parallel workers default to detached Git
122
- worktrees; tracked, deleted, untracked, and binary changes are applied back
123
- without touching the parent index. Failed integration keeps recovery artifacts.
124
- - **Recursion is structurally impossible** children are leaf processes; the
125
- `subagent` tool is excluded from their toolset.
126
- - **Zero runtime dependencies** — agents are plain Markdown files; overriding or
127
- adding one is writing a file.
128
- - **Update announcements** when a new configurable feature ships, you are told
129
- about it once (a persisted marker stops the notice from nagging).
130
-
131
- ## What this adds beyond generic subagent dispatch
132
-
133
- This package combines several concrete runtime behaviors rather than only exposing
134
- an undifferentiated child-agent launcher:
135
-
136
- - language-agnostic semantic role guidance for cleanup intent;
137
- - a dedicated evidence-first cleaner, with cleanup kept separate from the
138
- independent reviewer gate;
139
- - isolated, retained threads that can be steered, parked, resumed, retargeted, or
140
- forked under stable run ids;
141
- - the reviewer worker auto-fix reviewer loop, fixing every finding under a
142
- convergence contract with a hard round cap;
143
- - failed-tool diagnostics available by run id through `subagent_status`;
144
- - direct selected→main fallback plus capability-aware Auto thinking;
145
- - detached Git worktree isolation for parallel workers and opt-in write-capable
146
- cleaner runs.
147
-
148
- ## Install
149
-
150
- ```bash
151
- pi install npm:@ferris1225/pi-subagents
152
- ```
153
-
154
- Requires pi **>= 0.83.0**. After installation, open the setup wizard in an
155
- interactive TUI session:
156
-
157
- ```text
158
- /subagents-setup
159
- ```
160
-
161
- Fresh installs enable `explore`, `worker`, `cleaner`, and `reviewer` — you can
162
- start delegating immediately. Existing explicit `enabledAgents` lists are never
163
- silently extended; users upgrading with an existing explicit list get a one-time
164
- notice to opt into `cleaner` with `/subagents-setup`.
165
-
166
- ## The agents
167
-
168
- | Agent | Access | Purpose |
169
- | --- | --- | --- |
170
- | `explore` | Read-only | Fast codebase reconnaissance: broad/open-ended search, multi-file lookups, mapping unfamiliar code. Returns compressed, structured findings. |
171
- | `worker` | Full | Implements, fixes, refactors, and tests a self-contained task end to end, then reports honest verification. |
172
- | `cleaner` | Full | Evidence-first cleanup. Audits and ranks candidates read-only, or applies the smallest proven cuts when removal is explicit; supports worktree isolation. |
173
- | `reviewer` | Read-only | Adversarial pre-commit quality gate: independently reviews worker and cleaner edits, plus plans, proposed solutions, codebase health, and PR/issue validation. |
174
-
175
- Each agent runs in its own isolated `pi` process with a clean context window; it
176
- has no memory of your conversation, so briefs must be self-contained (goal, exact
177
- paths, constraints, expected output).
178
-
179
- ## Usage
180
-
181
- ### Single task
182
-
183
- ```ts
184
- subagent({ agent: "explore", task: "Map the test setup: which files run what, and how is CI wired? Report exact paths." });
185
- subagent({ agent: "worker", task: "Implement X in src/foo.ts, add tests, run npm test." });
186
- subagent({ agent: "cleaner", task: "Audit src/cache for dead code and redundant state; report ranked evidence only." });
187
- subagent({ agent: "cleaner", task: "Remove the proven dead cache adapter, update its tests/docs, and verify the smallest then broad checks." });
188
- subagent({ agent: "reviewer", task: "Review the diff of src/index.ts and tests/load.test.ts for correctness and edge cases." });
189
- ```
190
-
191
- ### Parallel tasks
192
-
193
- ```ts
194
- subagent({
195
- tasks: [
196
- { agent: "explore", task: "Where is the selected-to-main handoff logic?" },
197
- { agent: "worker", task: "Add unit tests for models.ts." },
198
- ],
199
- });
200
- ```
201
-
202
- ### Cleanup routing and lifecycle
203
-
204
- The injected guidance routes `cleaner` by explicit semantic intent in any
205
- language the conversation uses: **code cleanup**, **dead code**, redundancy,
206
- simplification, or over-engineering. Requested periodic maintenance passes also
207
- qualify; PR counts do not, and cleaner is never run automatically as the
208
- pre-commit gate.
209
-
210
- - **Audit mode:** audit/find/report/review wording produces read-only ranked
211
- evidence.
212
- - **Apply mode:** explicit remove/clean/simplify/refactor wording permits the
213
- smallest proven edits plus narrow-then-broad verification.
214
-
215
- ```text
216
- explicit cleanup intent cleaner (audit or apply)
217
- cleaner apply reviewer gate worker auto-fix (on REVIEW_FAIL) → reviewer
218
- ```
219
-
220
- `reviewer` remains the independent gate for non-trivial cleaner edits. The auto-fix
221
- portion runs only when enabled by `maxFixRounds`; cleaner itself is not a pre-commit
222
- hook or a PR-count scheduler.
223
-
224
- ### Image work (screenshots / mockups / designs)
225
-
226
- There is no vision flag or separate vision model. Give the agent a multimodal
227
- model in `/subagents-setup` and name the exact image paths in the task:
228
-
229
- ```ts
230
- subagent({
231
- agent: "reviewer",
232
- task: "Compare the UI in screenshots/settings.png against the mockup design.png; list every visual mismatch.",
233
- });
234
- ```
235
-
236
- The sub-agent reads images with its `read` tool on its configured model; the
237
- setup picker labels each model `vision` or `text-only` so the choice is visible.
238
- The live widget line, dispatch result row, and `subagent_status` all show each
239
- run's effective model id, and a selected→main handoff is labeled with its
240
- origin.
241
-
242
- ### Controlling and stopping
243
-
244
- Dispatch confirmations, tool result rows, and completion blocks all show the
245
- stable `#id`, so a thread remains directly controllable after its live UI is gone
246
- (the widget itself identifies rows by tree position and task instead of ids).
247
-
248
- - `subagent_control` — `steer`, `retarget`, `park`, `resume`, or `fork` a logical
249
- thread by stable run id. Resume accepts an optional replacement objective;
250
- fork creates a new id and leaves the source unchanged. Park active work before
251
- forking it.
252
- - `subagent_wait` in-turn result lookup. **Non-blocking by default**: a settled
253
- run returns immediately; an active run tells the model to end its turn. Pass
254
- `timeoutMs` only when you must stay in the turn.
255
- - `subagent_status` — active/parked/finished runs and full result by run id.
256
- - `subagent_stop` destructive cancellation. It retires that thread's retained
257
- session (independent forks survive) and delivers exactly one aborted partial
258
- result after the run and any worktree integration have quiesced.
259
-
260
- Examples:
261
-
262
- ```ts
263
- subagent_control({ action: "steer", id: 7, instruction: "Check the Windows path too." });
264
- subagent_control({ action: "park", id: 7 });
265
- subagent_control({ action: "resume", id: 7, objective: "Finish the tests." });
266
- subagent_control({ action: "fork", id: 7, objective: "Try the smaller alternative." });
267
- ```
268
-
269
- ### Worktree isolation
270
-
271
- Single tasks default to `isolation: "shared"`. Parallel `worker` tasks default
272
- to `isolation: "worktree"`; opt into shared mode only when a worker must see the
273
- caller's live uncommitted tree. `cleaner` is also write-capable and supports
274
- worktree mode when explicitly requested (its default remains shared). Worktree
275
- mode requires a Git repository with a committed `HEAD` and is rejected for the
276
- read-only `explore` and `reviewer` agents.
277
-
278
- A parked isolated thread keeps its current worktree. Resume it there; fork is
279
- available after that isolated checkpoint settles and its seed is integrated.
280
- Resuming or forking a settled isolated thread creates a fresh worktree, merges a
281
- recorded checkpoint onto the current `HEAD` (including when the seed was already
282
- committed), and clones the Pi session with the new cwd. Forks then integrate only
283
- their unique follow-on edits, so a shared seed is applied once. A run remains
284
- active while final Git integration is in progress and becomes `done` only after
285
- that boundary finishes.
286
-
287
- Every Git operation has a 120-second deadline and process-tree cleanup; captured
288
- Git output and binary patches are capped at 64 MiB. Setup/bound failures surface
289
- instead of hanging. Finalization failures retain the patch/worktree when
290
- available and are recorded in `~/.pi/agent/pi-subagents-recovery.json`; later
291
- sessions show the recovery paths again until the artifacts are removed.
292
-
293
- ## Configuration
294
-
295
- Stored at `~/.pi/agent/pi-subagents.json` (follows `PI_CODING_AGENT_DIR` when
296
- set). `/subagents-setup` has four top-level choices: enable agents, configure one
297
- agent's model/thinking, runtime settings, or full setup.
298
- After one agent's model + thinking picks, the wizard returns to the agent picker
299
- so several agents can be configured in one pass; Esc at any step ends the pass
300
- and keeps every agent already configured. There is no backup pool or global thinking menu. Model pickers show only in-scope
301
- models with configured authentication and display their real supported thinking
302
- levels. Thinking defaults to **Auto**; manual overrides show only levels supported
303
- by that agent's effective model. `notifyOnReviewPass` and `maxResultLines` remain
304
- direct-file settings.
305
-
306
- ```json
307
- {
308
- "enabledAgents": ["explore", "worker", "cleaner", "reviewer"],
309
- "agentModels": {
310
- "explore": "anthropic/claude-haiku-4-5"
311
- },
312
- "agentThinkingLevels": {
313
- "reviewer": "high"
314
- },
315
- "notifyOnReviewPass": false,
316
- "maxResultLines": 80,
317
- "proactiveInjection": true,
318
- "agentScope": "user",
319
- "maxConcurrency": 4,
320
- "maxFixRounds": 2,
321
- "idleTimeoutSec": 90
322
- }
323
- ```
324
-
325
- | Field | Description |
326
- | --- | --- |
327
- | `enabledAgents` | Agent names exposed to discovery and prompt injection. An empty array disables all agents. |
328
- | `agentModels` | Optional selected `provider/model-id` per agent. Missing = current main model. Model-level failure hands directly to current main. |
329
- | `agentThinkingLevels` | Optional manual preference per agent. Missing = Auto (agent frontmatter preference, or `high`, clamped to the effective model's supported levels). |
330
- | `notifyOnReviewPass` | When `true`, a passing reviewer result is delivered without waking the main agent (default `false`). |
331
- | `maxResultLines` | Max lines of a sub-agent result carried in the completion message (default `80`). Longer results are truncated; full text is written to an extension-named temporary `.md`. At session start and on each write, only recognized result files older than 7 days are removed; each canonical project path has its own newest-50 bucket. |
332
- | `proactiveInjection` | Whether to add the delegation directive to the main system prompt. |
333
- | `agentScope` | `user`, `project`, or `both`; controls which user/project agent directories are discovered. |
334
- | `maxConcurrency` | Max sub-agent processes running at once (1–16, default 4), and the max tasks one parallel `subagent` call accepts. Extra work waits in the queue. |
335
- | `maxFixRounds` | Auto-fix rounds when a reviewer returns `REVIEW_FAIL` (default 2; `0` disables the loop). Hard cap: the chain always settles, delivers its condensed summary, and wakes the main agent. |
336
- | `idleTimeoutSec` | Idle watchdog: a sub-agent whose stdout goes silent for this long is terminated; a selected model then hands to current main. `0` disables it. Default 90. |
337
-
338
- ### Model routing and thinking
339
-
340
- ```text
341
- selected agent model current main-window model
342
- ```
343
-
344
- Without a selected model, current main runs immediately; agent frontmatter model
345
- is used only when no main model exists. A selection missing from Pi's live
346
- available catalog is skipped. Any model-level runtime failure rate limit,
347
- quota, invalid key/auth, missing model, provider error, or idle model stream
348
- hands directly to current main, including stream errors that retain partial text.
349
- A child-only Pi extension wraps the selected provider's registered API stream
350
- with `maxRetries: 0` so a deterministic auth/quota miss fails fast. Transient
351
- stream drops such as xAI `terminated` still use Pi's outer turn retry — the
352
- parent does not `abort_retry` them — and only a settled model-level failure
353
- hands off to current main. This uses supported extension/RPC surfaces in Node
354
- and standalone/Bun builds, never rewrites global or project settings, and does
355
- not alter descendant tool environments. Tool/test failures stay on the same
356
- model because they are task failures, not model availability failures. A child is
357
- probed with RPC `get_state` before the first prompt so the 30s command ACK clock
358
- does not include process boot. Only a zero-activity startup miss can retry — a
359
- silent fast exit, a `get_state` handshake timeout, or an initial prompt ACK
360
- timeout before any agent/turn/stream/tool activity. Those transport misses are
361
- not model-level failures and do not hand the task to the main window. An accepted
362
- prompt or any activity forbids replay.
363
-
364
- Auto thinking starts from the Agent's declared preference (`low` for `explore`,
365
- `high` for the other built-ins) and uses Pi's capability map to clamp it to the
366
- actual model. Non-reasoning models resolve to `off`; `xhigh`/`max` appear in setup
367
- only when that model explicitly supports them. A selected→main handoff re-clamps
368
- thinking for the main model.
369
-
370
- ### Choosing an explore model
371
-
372
- Choose a competent fast code model for `explore`, not automatically the cheapest
373
- model. Cheap reconnaissance is useful for mechanical symbol/path discovery, but
374
- a missed dynamic entrypoint or ownership edge can cost more through downstream
375
- rework. Direct main-model handoff handles provider/runtime failure; it cannot
376
- detect a plausible but incomplete answer.
377
-
378
- `explore` therefore returns an index of exact paths, lines, symbols, and explicit
379
- uncertainty. The main agent, worker, or cleaner must re-read load-bearing files
380
- before editing or deciding deletion, security, compatibility, persistence, or
381
- dynamic reachability. Prefer a stronger model or direct specialist for complex
382
- dynamic loading, concurrency, migrations, and security-sensitive code.
383
-
384
- ### Resuming retained context
385
-
386
- Every run stores its Pi session in a private temp directory. A selected→main
387
- handoff resumes that same session, so searches, reads, reasoning, and edits remain
388
- in context. A parked, completed, or failed thread can later be resumed under its
389
- stable id:
390
-
391
- ```ts
392
- subagent_control({ action: "resume", id: 7 });
393
- subagent_control({ action: "resume", id: 7, objective: "Continue with the repaired credentials." });
394
- ```
395
-
396
- Use `fork` when both paths should remain available. `subagent_stop` is the
397
- explicit destructive operation that retires a retained session; otherwise
398
- sessions live until the parent Pi session shuts down.
399
-
400
- ### Configuration migration
401
-
402
- The config file normalizes itself on load — no manual steps after an upgrade.
403
- Configured non-empty agent names are preserved, while invalid and obsolete keys
404
- are removed. This release deletes `agentBackupModels` and global `thinkingLevel`
405
- in addition to older `maxParallelTasks` / `maxSubagentDepth`; per-agent thinking
406
- preferences remain and are capability-clamped at runtime. A pre-existing explicit
407
- `enabledAgents` array is still preserved without appending `cleaner`. Existing
408
- configs without it receive a one-time `/subagents-setup` notice, tracked internally
409
- in `announcedFeatures`.
410
-
411
- ## Agent discovery and overrides
412
-
413
- - Built-in agents ship with the package; user agents live in `~/.pi/agent/agents/`;
414
- project agents in the nearest `.pi/agents/` directory are loaded only when Pi
415
- trusts that project.
416
- - For duplicate names: project overrides user overrides built-in. Keep the
417
- matching filename and `name` field to replace a built-in agent.
418
- - Optional frontmatter: `model` (default model reference), `thinking` (default
419
- thinking strength), `tools` (comma-separated tool allow-list; absent = all
420
- tools). Config overrides win at spawn.
421
-
422
- ## How it stays reliable
423
-
424
- - **Direct model recovery** unavailable selections skip immediately; any
425
- selected-model provider/auth/quota/rate-limit failure hands directly to current
426
- main with thinking re-clamped to the main model.
427
- - **Startup-race retries** a silent zero-activity child exit (concurrent pi
428
- startup lock contention) is relaunched with backoff; only clean silent exits
429
- qualify, so real work is never duplicated.
430
- - **Idle watchdog** — a stalled selected-model stream (no output for
431
- `idleTimeoutSec`) terminates the child and hands the retained session to current
432
- main.
433
- - **Dispatch failures surface** — partial parallel startup reports every failed
434
- item and reason; if none start, the tool throws so Pi records a real tool error.
435
- Dispatch crashes likewise produce a failed result instead of a silent hang.
436
- - **Safe live status** — tool activity is credential-redacted and stripped of terminal control sequences before `subagent_status` can return it.
437
- - **Leaf children** no nested delegation, no runaway trees.
438
-
439
- ## Development
440
-
441
- ```bash
442
- npm install
443
- npm run check
444
- npm test
445
- ```
446
-
447
- The source is modular: `dispatch.ts` (public dispatch contract + auto-fix),
448
- `thread-lifecycle.ts` (queued generations, resume/fork, and isolation settlement),
449
- `rpc-run.ts` / `spawn.ts` (persistent child transport + selected→main handoff),
450
- `worktree.ts` / `session-fork.ts` (filesystem/session branching), `tools.ts`
451
- (wait/status/control/stop), `widget.ts` (active-only TUI status), `announcements.ts`
452
- (recovery and feature notices), and `runtime.ts` (session-scoped ownership). No runtime
453
- dependencies beyond pi peer dependencies.
454
-
455
- ## License
456
-
457
- MIT
1
+ # pi-subagents
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@ferris1225/pi-subagents?color=blue)](https://www.npmjs.com/package/@ferris1225/pi-subagents)
4
+ [![downloads](https://img.shields.io/npm/dm/@ferris1225/pi-subagents)](https://www.npmjs.com/package/@ferris1225/pi-subagents)
5
+ [![license](https://img.shields.io/npm/l/@ferris1225/pi-subagents)](./LICENSE)
6
+ ![platform](https://img.shields.io/badge/platform-Windows%20%7C%20macOS%20%7C%20Linux-lightgrey)
7
+ ![pi](https://img.shields.io/badge/pi-extension-orange)
8
+
9
+ Focused background delegation for [pi](https://pi.dev): `explorer` / `worker` /
10
+ `cleaner` / `reviewer` agents run in **isolated child processes** and hand their
11
+ results back to the main agent automatically. Install it, and the main model
12
+ starts using it on its own — no prompt engineering, no babysitting.
13
+
14
+ ## 4.0.1automatic explorer config migration
15
+
16
+ Version 4 renames the built-in reconnaissance role from `explore` to `explorer`
17
+ without retaining a runtime alias. Version 4.0.1 automatically migrates the old
18
+ name in `enabledAgents`, `agentModels`, and `agentThinkingLevels`, then persists
19
+ the normalized configuration; an already configured `explorer` value wins a
20
+ conflict. `cleaner` is apply-only: explicit cleanup intent authorizes it to prove
21
+ and perform every safe in-scope cut, while generic or read-only assessments go to
22
+ `reviewer` without triggering auto-fix.
23
+
24
+ The main delegation directive is now the single authoritative routing policy;
25
+ duplicated tool guidelines were removed to cut the default parent injection by
26
+ more than half without changing process isolation, worktree rules, retained-session
27
+ fallback, or result handoff. Agent frontmatter model defaults remain because they
28
+ still select a model when no current main model exists; frontmatter comments do not
29
+ enter model context.
30
+
31
+ Every dispatch retains its stable run id and can be steered, parked, resumed,
32
+ retargeted, or forked. The active widget continues to show task, effective model
33
+ and thinking level, activity, and elapsed time.
34
+
35
+ The common quality loop now runs end to end without waking the main agent between
36
+ steps:
37
+
38
+ ```text
39
+ reviewer (find issues) worker (fix every finding) reviewer (verify) final PASS/FAIL
40
+ ```
41
+
42
+ Gate reviews use a single flat findings list no severity triage. Every reported
43
+ finding is fixed before the change is accepted, and each re-review converges on
44
+ an open-finding set: the worker's explicit rejections are adjudicated once, only
45
+ defects a fix round introduced or exposed are added, and resolved items never
46
+ re-open. `maxFixRounds` stays the hard cap, so a chain always settles and wakes
47
+ the main agent with the full picture. Advisory reviewer requests (generic audits,
48
+ code health, plans, and proposed solutions) return evidence without a machine
49
+ verdict, so they never start auto-fix.
50
+
51
+ Cleanup stays a separate lifecycle: only an explicit request authorizing cleanup,
52
+ removal, or simplification edits dispatches the evidence-first `cleaner`. It proves
53
+ candidates, applies every safe in-scope cut end to end, and may validly make zero
54
+ edits; non-trivial changes still go through the independent `reviewer` gate.
55
+
56
+ Each chain is delivered as one concise completion group whose footer totals the
57
+ aggregate token usage and cost of every included run, while full per-run reports
58
+ remain available through `subagent_status`. Its parent stays `running`
59
+ until the whole chain settles; completed internal rounds leave active status
60
+ immediately, so no `done` row keeps accumulating elapsed time. Selected-to-main
61
+ model handoffs keep the same retained context, and isolated parallel workers use
62
+ detached Git worktrees whose changes are applied back without touching the parent
63
+ index.
64
+
65
+ ## Highlights
66
+
67
+ - **Zero-setup proactive dispatch** the extension injects a delegation directive
68
+ into the main system prompt, so the main model sends broad searches to `explorer`,
69
+ self-contained implementations to `worker`, edit-authorizing cleanup to `cleaner`,
70
+ and generic assessments or pre-commit gates to `reviewer`. You just use pi;
71
+ delegation happens by itself.
72
+ - **Multimodal work is a model choice, not a mode** — an agent that should see
73
+ screenshots, mockups, or its own rendered pages simply gets a multimodal model
74
+ through `/subagents-setup` (the picker labels each model `vision` or
75
+ `text-only`). The agent reads images with its `read` tool on whatever model it
76
+ runs; no per-task flag, no separate vision override.
77
+ - **Results come back on their own** completions are delivered as messages that
78
+ wake the main agent automatically, even mid-turn. No polling, no `sleep`, no
79
+ "go check" step. `subagent_wait` is a **non-blocking** in-turn lookup by default
80
+ (pass `timeoutMs` to block); `subagent_status` inspects runs; `subagent_stop`
81
+ cancels one and delivers its partial output.
82
+ - **Active-only live widget, as a tree** — each queued or running sub-agent gets one compact
83
+ width-aware primary line with task, effective model/thinking, and elapsed time; current
84
+ activity appears only when present on an indented second line. Auto-fix rounds nest under
85
+ the triggering reviewer row that owns the chain, so it is always visible who dispatched
86
+ what; no run ids appear here — the tree and the task label identify each row:
87
+ ```text
88
+ reviewer · review diff of src/foo.ts · claude-sonnet-4-5/high · 42s
89
+ worker · fix round 1 · src/foo.ts · claude-sonnet-4-5/high · 10s
90
+ │ grep cacheKey
91
+ reviewer · re-review round 1 · claude-sonnet-4-5/high · 3s
92
+ ```
93
+ Long tasks and activity paths truncate first (preserving a useful path tail when
94
+ possible), groups have no blank rows, and settled/parked runs disappear immediately.
95
+ - **Results are not re-narrated** a sub-agent's completion is shown to you
96
+ verbatim, and the main agent is told not to paraphrase it back. It replies with
97
+ only its own conclusion or next step, so the same findings are never paid for
98
+ twice in tokens.
99
+ - **Evidence-first cleanup, not deletion by guesswork** `cleaner` is apply-only:
100
+ an explicit cleanup request authorizes edits, but each candidate must be proved
101
+ before every safe in-scope cut is applied and verified. Finding nothing safe and
102
+ making zero edits remains valid. Generic/read-only assessments go to `reviewer`;
103
+ cleaner is periodic/intent-driven, never PR-count-driven or an automatic gate.
104
+ - **A quality gate that closes the loop** when a gate reviewer returns
105
+ `REVIEW_FAIL`, the extension dispatches a worker briefed with the concrete
106
+ findings, then a re-review, up to `maxFixRounds` times and only then wakes the
107
+ main agent. Advisory reviewer reports omit that verdict and never trigger edits.
108
+ Every reported finding gets fixed (no severity triage), and re-reviews converge
109
+ on an open-finding set instead of ping-ponging: worker rejections are adjudicated
110
+ once, only defects the fix round introduced are added, and resolved items never
111
+ re-open. Every round stays in the triggering reviewer's cwd, and chains that target the
112
+ same repository are serialized so shared-checkout edits cannot race.
113
+ - **Direct fallback with real thinking capabilities** each agent has at most
114
+ one selected model. An unavailable selection, rate limit, invalid key, quota,
115
+ missing model, or provider failure hands directly to the current main model.
116
+ A child-only provider adapter forces inner request retries to zero; transient
117
+ stream drops still use Pi's outer turn retry, and only a settled model-level
118
+ failure hands off, without changing user settings. Auto thinking clamps the
119
+ agent preference to the
120
+ effective model's real `thinkingLevelMap`; manual setup shows only levels that
121
+ model supports.
122
+ - **Resumes, retargets, and forks preserve context** every run is session-backed.
123
+ `subagent_control` can steer active work, retarget it after a stable abort,
124
+ park/resume it under the same run id, or fork a parked/settled checkpoint into
125
+ a new independent run. Concurrent resume calls are serialized.
126
+ - **Concise but honest completions** — group completions end with aggregate token
127
+ and cost totals across every included run; failed-tool diagnostics stay out of the
128
+ delivered message and remain one `subagent_status` call away. Actual process,
129
+ model, and integration failures still surface as failures.
130
+ - **Parallel fan-out with filesystem isolation** — independent tasks run up to a
131
+ configurable limit (default 4). Parallel workers default to detached Git
132
+ worktrees; tracked, deleted, untracked, and binary changes are applied back
133
+ without touching the parent index. Failed integration keeps recovery artifacts.
134
+ - **Recursion is structurally impossible** — children are leaf processes; the
135
+ `subagent` tool is excluded from their toolset.
136
+ - **Zero runtime dependencies** agents are plain Markdown files; overriding or
137
+ adding one is writing a file.
138
+ - **Update announcements** — when a new configurable feature ships, you are told
139
+ about it once (a persisted marker stops the notice from nagging).
140
+
141
+ ## What this adds beyond generic subagent dispatch
142
+
143
+ This package combines several concrete runtime behaviors rather than only exposing
144
+ an undifferentiated child-agent launcher:
145
+
146
+ - language-agnostic semantic role guidance for cleanup intent;
147
+ - a dedicated evidence-first cleaner, with cleanup kept separate from the
148
+ independent reviewer gate;
149
+ - isolated, retained threads that can be steered, parked, resumed, retargeted, or
150
+ forked under stable run ids;
151
+ - the reviewer → worker auto-fix → reviewer loop, fixing every finding under a
152
+ convergence contract with a hard round cap;
153
+ - failed-tool diagnostics available by run id through `subagent_status`;
154
+ - direct selected→main fallback plus capability-aware Auto thinking;
155
+ - detached Git worktree isolation for parallel workers and opt-in write-capable
156
+ cleaner runs.
157
+
158
+ ## Install
159
+
160
+ ```bash
161
+ pi install npm:@ferris1225/pi-subagents
162
+ ```
163
+
164
+ Requires pi **>= 0.83.0**. After installation, open the setup wizard in an
165
+ interactive TUI session:
166
+
167
+ ```text
168
+ /subagents-setup
169
+ ```
170
+
171
+ Fresh installs enable `explorer`, `worker`, `cleaner`, and `reviewer` you can
172
+ start delegating immediately. Existing explicit `enabledAgents` lists are never
173
+ silently extended; users upgrading with an existing explicit list get a one-time
174
+ notice to opt into `cleaner` with `/subagents-setup`.
175
+
176
+ ## The agents
177
+
178
+ | Agent | Access | Purpose |
179
+ | --- | --- | --- |
180
+ | `explorer` | Read-only | Fast codebase reconnaissance: broad/open-ended search, multi-file lookups, mapping unfamiliar code. Returns compressed, structured retrieval leads. |
181
+ | `worker` | Full | Implements, fixes, refactors, and tests a self-contained task end to end, then reports honest verification. |
182
+ | `cleaner` | Full | Proves and applies every safe in-scope cleanup authorized by an explicit cleanup/removal/simplification request; zero edits is valid. Supports worktree isolation. |
183
+ | `reviewer` | Read-only | Handles generic audits, code health, plans, proposed solutions, PR/issue validation, and independent pre-commit gates. Advisory reports do not trigger auto-fix. |
184
+
185
+ Each agent runs in its own isolated `pi` process with a clean context window; it
186
+ has no memory of your conversation, so briefs must be self-contained (goal, exact
187
+ paths, constraints, expected output).
188
+
189
+ ## Usage
190
+
191
+ ### Single task
192
+
193
+ ```ts
194
+ subagent({ agent: "explorer", task: "Map the test setup: which files run what, and how is CI wired? Report exact paths." });
195
+ subagent({ agent: "worker", task: "Implement X in src/foo.ts, add tests, run npm test." });
196
+ subagent({ agent: "reviewer", task: "Audit src/cache for dead-code candidates and redundant state; report evidence only." });
197
+ subagent({ agent: "cleaner", task: "Clean up src/cache: prove and apply every safe dead-code or redundancy cut, update tests/docs, and verify." });
198
+ subagent({ agent: "reviewer", task: "Gate the diff of src/index.ts and tests/load.test.ts for correctness and edge cases." });
199
+ ```
200
+
201
+ ### Parallel tasks
202
+
203
+ ```ts
204
+ subagent({
205
+ tasks: [
206
+ { agent: "explorer", task: "Where is the selected-to-main handoff logic?" },
207
+ { agent: "worker", task: "Add unit tests for models.ts." },
208
+ ],
209
+ });
210
+ ```
211
+
212
+ ### Cleanup routing and lifecycle
213
+
214
+ The injected guidance sends only explicit, edit-authorizing cleanup intent to
215
+ `cleaner` in whatever language the conversation uses: clean up/remove dead code,
216
+ reduce redundancy, simplify, remove over-engineering, or run a maintenance cleanup
217
+ pass. Cleaner first proves reachability, ownership, history, and boundaries, then
218
+ applies every safe in-scope cut end to end and verifies it. No proven safe cut means
219
+ zero edits, not a forced deletion.
220
+
221
+ Generic or explicitly read-only **audit**, **inspect**, **report**, **review**,
222
+ **code-health**, **plan**, **proposed-solution**, or cleanup-candidate assessment
223
+ requests go to `reviewer`. Those are advisory reviews: they omit the machine
224
+ `REVIEW_PASS` / `REVIEW_FAIL` marker, cannot start auto-fix, and do not authorize
225
+ the main agent to edit. A follow-up change needs an explicit user request. A
226
+ reviewer emits the marker only for an explicit diff/pre-commit acceptance gate.
227
+
228
+ ```text
229
+ explicit edit-authorizing cleanup → cleaner → reviewer gate
230
+ read-only/generic assessment → reviewer advisory report (no auto-fix)
231
+ reviewer gate REVIEW_FAIL → worker auto-fix → reviewer gate
232
+ ```
233
+
234
+ Cleaner is never dispatched by PR count and never acts as the commit gate. The
235
+ auto-fix portion runs only for gate verdicts and only when enabled by
236
+ `maxFixRounds`.
237
+
238
+ ### Image work (screenshots / mockups / designs)
239
+
240
+ There is no vision flag or separate vision model. Give the agent a multimodal
241
+ model in `/subagents-setup` and name the exact image paths in the task:
242
+
243
+ ```ts
244
+ subagent({
245
+ agent: "reviewer",
246
+ task: "Compare the UI in screenshots/settings.png against the mockup design.png; list every visual mismatch.",
247
+ });
248
+ ```
249
+
250
+ The sub-agent reads images with its `read` tool on its configured model; the
251
+ setup picker labels each model `vision` or `text-only` so the choice is visible.
252
+ The live widget line, dispatch result row, and `subagent_status` all show each
253
+ run's effective model id, and a selected→main handoff is labeled with its
254
+ origin.
255
+
256
+ ### Controlling and stopping
257
+
258
+ Dispatch confirmations, tool result rows, and completion blocks all show the
259
+ stable `#id`, so a thread remains directly controllable after its live UI is gone
260
+ (the widget itself identifies rows by tree position and task instead of ids).
261
+
262
+ - `subagent_control` — `steer`, `retarget`, `park`, `resume`, or `fork` a logical
263
+ thread by stable run id. Resume accepts an optional replacement objective;
264
+ fork creates a new id and leaves the source unchanged. Park active work before
265
+ forking it.
266
+ - `subagent_wait` in-turn result lookup. **Non-blocking by default**: a settled
267
+ run returns immediately; an active run tells the model to end its turn. Pass
268
+ `timeoutMs` only when you must stay in the turn.
269
+ - `subagent_status` — active/parked/finished runs and full result by run id.
270
+ - `subagent_stop` — destructive cancellation. It retires that thread's retained
271
+ session (independent forks survive) and delivers exactly one aborted partial
272
+ result after the run and any worktree integration have quiesced.
273
+
274
+ Examples:
275
+
276
+ ```ts
277
+ subagent_control({ action: "steer", id: 7, instruction: "Check the Windows path too." });
278
+ subagent_control({ action: "park", id: 7 });
279
+ subagent_control({ action: "resume", id: 7, objective: "Finish the tests." });
280
+ subagent_control({ action: "fork", id: 7, objective: "Try the smaller alternative." });
281
+ ```
282
+
283
+ ### Worktree isolation
284
+
285
+ Single tasks default to `isolation: "shared"`. Parallel `worker` tasks default
286
+ to `isolation: "worktree"`; opt into shared mode only when a worker must see the
287
+ caller's live uncommitted tree. `cleaner` is also write-capable and supports
288
+ worktree mode when explicitly requested (its default remains shared). Worktree
289
+ mode requires a Git repository with a committed `HEAD` and is rejected for the
290
+ read-only `explorer` and `reviewer` agents.
291
+
292
+ A parked isolated thread keeps its current worktree. Resume it there; fork is
293
+ available after that isolated checkpoint settles and its seed is integrated.
294
+ Resuming or forking a settled isolated thread creates a fresh worktree, merges a
295
+ recorded checkpoint onto the current `HEAD` (including when the seed was already
296
+ committed), and clones the Pi session with the new cwd. Forks then integrate only
297
+ their unique follow-on edits, so a shared seed is applied once. A run remains
298
+ active while final Git integration is in progress and becomes `done` only after
299
+ that boundary finishes.
300
+
301
+ Every Git operation has a 120-second deadline and process-tree cleanup; captured
302
+ Git output and binary patches are capped at 64 MiB. Setup/bound failures surface
303
+ instead of hanging. Finalization failures retain the patch/worktree when
304
+ available and are recorded in `~/.pi/agent/pi-subagents-recovery.json`; later
305
+ sessions show the recovery paths again until the artifacts are removed.
306
+
307
+ ## Configuration
308
+
309
+ Stored at `~/.pi/agent/pi-subagents.json` (follows `PI_CODING_AGENT_DIR` when
310
+ set). `/subagents-setup` has four top-level choices: enable agents, configure one
311
+ agent's model/thinking, runtime settings, or full setup.
312
+ After one agent's model + thinking picks, the wizard returns to the agent picker
313
+ so several agents can be configured in one pass; Esc at any step ends the pass
314
+ and keeps every agent already configured. There is no backup pool or global thinking menu. Model pickers show only in-scope
315
+ models with configured authentication and display their real supported thinking
316
+ levels. Thinking defaults to **Auto**; manual overrides show only levels supported
317
+ by that agent's effective model. `notifyOnReviewPass` and `maxResultLines` remain
318
+ direct-file settings.
319
+
320
+ ```json
321
+ {
322
+ "enabledAgents": ["explorer", "worker", "cleaner", "reviewer"],
323
+ "agentModels": {
324
+ "explorer": "anthropic/claude-haiku-4-5"
325
+ },
326
+ "agentThinkingLevels": {
327
+ "reviewer": "high"
328
+ },
329
+ "notifyOnReviewPass": false,
330
+ "maxResultLines": 80,
331
+ "proactiveInjection": true,
332
+ "agentScope": "user",
333
+ "maxConcurrency": 4,
334
+ "maxFixRounds": 2,
335
+ "idleTimeoutSec": 90
336
+ }
337
+ ```
338
+
339
+ | Field | Description |
340
+ | --- | --- |
341
+ | `enabledAgents` | Agent names exposed to discovery and prompt injection. An empty array disables all agents. |
342
+ | `agentModels` | Optional selected `provider/model-id` per agent. Missing = current main model. Model-level failure hands directly to current main. |
343
+ | `agentThinkingLevels` | Optional manual preference per agent. Missing = Auto (agent frontmatter preference, or `high`, clamped to the effective model's supported levels). |
344
+ | `notifyOnReviewPass` | When `true`, a passing reviewer result is delivered without waking the main agent (default `false`). |
345
+ | `maxResultLines` | Max lines of a sub-agent result carried in the completion message (default `80`). Longer results are truncated; full text is written to an extension-named temporary `.md`. At session start and on each write, only recognized result files older than 7 days are removed; each canonical project path has its own newest-50 bucket. |
346
+ | `proactiveInjection` | Whether to add the delegation directive to the main system prompt. |
347
+ | `agentScope` | `user`, `project`, or `both`; controls which user/project agent directories are discovered. |
348
+ | `maxConcurrency` | Max sub-agent processes running at once (1–16, default 4), and the max tasks one parallel `subagent` call accepts. Extra work waits in the queue. |
349
+ | `maxFixRounds` | Auto-fix rounds when a reviewer returns `REVIEW_FAIL` (default 2; `0` disables the loop). Hard cap: the chain always settles, delivers its condensed summary, and wakes the main agent. |
350
+ | `idleTimeoutSec` | Idle watchdog: a sub-agent whose stdout goes silent for this long is terminated; a selected model then hands to current main. `0` disables it. Default 90. |
351
+
352
+ ### Model routing and thinking
353
+
354
+ ```text
355
+ selected agent model current main-window model
356
+ ```
357
+
358
+ Without a selected model, current main runs immediately; agent frontmatter `model`
359
+ is used only when no main model exists, so the shipped defaults remain behaviorally
360
+ load-bearing. From an agent Markdown file, only the body after frontmatter becomes
361
+ the child's appended system prompt; model-selection comments inside YAML
362
+ frontmatter are parser comments, not model prompt tokens. A selection missing from Pi's live
363
+ available catalog is skipped. Any model-level runtime failure — rate limit,
364
+ quota, invalid key/auth, missing model, provider error, or idle model stream —
365
+ hands directly to current main, including stream errors that retain partial text.
366
+ A child-only Pi extension wraps the selected provider's registered API stream
367
+ with `maxRetries: 0` so a deterministic auth/quota miss fails fast. Transient
368
+ stream drops such as xAI `terminated` still use Pi's outer turn retry — the
369
+ parent does not `abort_retry` them — and only a settled model-level failure
370
+ hands off to current main. This uses supported extension/RPC surfaces in Node
371
+ and standalone/Bun builds, never rewrites global or project settings, and does
372
+ not alter descendant tool environments. Tool/test failures stay on the same
373
+ model because they are task failures, not model availability failures. A child is
374
+ probed with RPC `get_state` before the first prompt so the 30s command ACK clock
375
+ does not include process boot. Only a zero-activity startup miss can retry a
376
+ silent fast exit, a `get_state` handshake timeout, or an initial prompt ACK
377
+ timeout before any agent/turn/stream/tool activity. Those transport misses are
378
+ not model-level failures and do not hand the task to the main window. An accepted
379
+ prompt or any activity forbids replay.
380
+
381
+ Auto thinking starts from the Agent's declared preference (`low` for `explorer`,
382
+ `high` for the other built-ins) and uses Pi's capability map to clamp it to the
383
+ actual model. Non-reasoning models resolve to `off`; `xhigh`/`max` appear in setup
384
+ only when that model explicitly supports them. A selected→main handoff re-clamps
385
+ thinking for the main model.
386
+
387
+ ### Choosing an explorer model
388
+
389
+ Choose a competent fast code model for `explorer`, not automatically the cheapest
390
+ model. Cheap reconnaissance is useful for mechanical symbol/path discovery, but
391
+ a missed dynamic entrypoint or ownership edge can cost more through downstream
392
+ rework. Direct main-model handoff handles provider/runtime failure; it cannot
393
+ detect a plausible but incomplete answer.
394
+
395
+ `explorer` therefore returns an index of exact paths, lines, symbols, and explicit
396
+ uncertainty. The main agent, worker, or cleaner must re-read load-bearing files
397
+ before editing or deciding deletion, security, compatibility, persistence, or
398
+ dynamic reachability. Prefer a stronger model or direct specialist for complex
399
+ dynamic loading, concurrency, migrations, and security-sensitive code.
400
+
401
+ ### Resuming retained context
402
+
403
+ Every run stores its Pi session in a private temp directory. A selected→main
404
+ handoff resumes that same session, so searches, reads, reasoning, and edits remain
405
+ in context. A parked, completed, or failed thread can later be resumed under its
406
+ stable id:
407
+
408
+ ```ts
409
+ subagent_control({ action: "resume", id: 7 });
410
+ subagent_control({ action: "resume", id: 7, objective: "Continue with the repaired credentials." });
411
+ ```
412
+
413
+ Use `fork` when both paths should remain available. `subagent_stop` is the
414
+ explicit destructive operation that retires a retained session; otherwise
415
+ sessions live until the parent Pi session shuts down.
416
+
417
+ ### Configuration migration
418
+
419
+ Config loading normalizes schema fields and removes invalid or obsolete keys,
420
+ including `agentBackupModels`, global `thinkingLevel`, `maxParallelTasks`, and
421
+ `maxSubagentDepth`. Per-agent thinking preferences remain capability-clamped.
422
+
423
+ The built-in reconnaissance role is now `explorer`, with no runtime `explore`
424
+ alias. Config loading automatically renames the old key in `enabledAgents`,
425
+ `agentModels`, and `agentThinkingLevels`, deduplicates an old/new pair, and persists
426
+ the normalized file. When both model or thinking keys are valid, the explicit
427
+ `explorer` value wins. Other configured non-empty names are preserved. A
428
+ pre-existing explicit `enabledAgents` list is also still preserved without
429
+ appending `cleaner`; configs without cleaner receive the existing one-time setup
430
+ notice.
431
+
432
+ ## Agent discovery and overrides
433
+
434
+ - Built-in agents ship with the package; user agents live in `~/.pi/agent/agents/`;
435
+ project agents in the nearest `.pi/agents/` directory are loaded only when Pi
436
+ trusts that project.
437
+ - For duplicate names: project overrides user overrides built-in. Keep the
438
+ matching filename and `name` field to replace a built-in agent.
439
+ - Optional frontmatter: `model` (default model reference), `thinking` (default
440
+ thinking strength), `tools` (comma-separated tool allow-list; absent = all
441
+ tools). Config overrides win at spawn.
442
+
443
+ ## How it stays reliable
444
+
445
+ - **Direct model recovery** — unavailable selections skip immediately; any
446
+ selected-model provider/auth/quota/rate-limit failure hands directly to current
447
+ main with thinking re-clamped to the main model.
448
+ - **Startup-race retries** a silent zero-activity child exit (concurrent pi
449
+ startup lock contention) is relaunched with backoff; only clean silent exits
450
+ qualify, so real work is never duplicated.
451
+ - **Idle watchdog** — a stalled selected-model stream (no output for
452
+ `idleTimeoutSec`) terminates the child and hands the retained session to current
453
+ main.
454
+ - **Dispatch failures surface** — partial parallel startup reports every failed
455
+ item and reason; if none start, the tool throws so Pi records a real tool error.
456
+ Dispatch crashes likewise produce a failed result instead of a silent hang.
457
+ - **Safe live status** — tool activity is credential-redacted and stripped of terminal control sequences before `subagent_status` can return it.
458
+ - **Leaf children** — no nested delegation, no runaway trees.
459
+
460
+ ## Development
461
+
462
+ ```bash
463
+ npm install
464
+ npm run check
465
+ npm test
466
+ ```
467
+
468
+ The source is modular: `dispatch.ts` (public dispatch contract + auto-fix),
469
+ `thread-lifecycle.ts` (queued generations, resume/fork, and isolation settlement),
470
+ `rpc-run.ts` / `spawn.ts` (persistent child transport + selected→main handoff),
471
+ `worktree.ts` / `session-fork.ts` (filesystem/session branching), `tools.ts`
472
+ (wait/status/control/stop), `widget.ts` (active-only TUI status), `announcements.ts`
473
+ (recovery and feature notices), and `runtime.ts` (session-scoped ownership). No runtime
474
+ dependencies beyond pi peer dependencies.
475
+
476
+ ## License
477
+
478
+ MIT