@ferris1225/pi-subagents 2.3.1 → 4.0.0
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 +475 -468
- package/agents/cleaner.md +11 -21
- package/agents/{explore.md → explorer.md} +3 -3
- package/agents/reviewer.md +47 -41
- package/agents/worker.md +3 -3
- package/package.json +1 -1
- package/src/announcements.ts +0 -6
- package/src/config.ts +299 -310
- package/src/dispatch.ts +11 -65
- package/src/index.ts +1 -1
- package/src/models.ts +3 -9
- package/src/monitor.ts +1 -1
- package/src/prompt.ts +74 -61
- package/src/runtime.ts +0 -1
- package/src/setup.ts +438 -463
- package/src/thread-lifecycle.ts +4 -12
package/README.md
CHANGED
|
@@ -1,468 +1,475 @@
|
|
|
1
|
-
# pi-subagents
|
|
2
|
-
|
|
3
|
-
[](https://www.npmjs.com/package/@ferris1225/pi-subagents)
|
|
4
|
-
[](https://www.npmjs.com/package/@ferris1225/pi-subagents)
|
|
5
|
-
[](./LICENSE)
|
|
6
|
-

|
|
7
|
-

|
|
8
|
-
|
|
9
|
-
Focused background delegation for [pi](https://pi.dev): `
|
|
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
|
-
##
|
|
15
|
-
|
|
16
|
-
Version
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
model
|
|
120
|
-
- **
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
- **
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
- **
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
-
|
|
145
|
-
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
subagent({
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
- `
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
subagent_control({ action: "
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
"
|
|
322
|
-
"
|
|
323
|
-
},
|
|
324
|
-
"
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
"
|
|
328
|
-
"
|
|
329
|
-
"
|
|
330
|
-
"
|
|
331
|
-
"
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
|
338
|
-
|
|
|
339
|
-
| `
|
|
340
|
-
| `
|
|
341
|
-
| `
|
|
342
|
-
| `
|
|
343
|
-
| `
|
|
344
|
-
| `
|
|
345
|
-
| `
|
|
346
|
-
| `
|
|
347
|
-
| `
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
thinking
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
`
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
- **
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
1
|
+
# pi-subagents
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@ferris1225/pi-subagents)
|
|
4
|
+
[](https://www.npmjs.com/package/@ferris1225/pi-subagents)
|
|
5
|
+
[](./LICENSE)
|
|
6
|
+

|
|
7
|
+

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