@ferris1225/pi-subagents 4.2.12 → 4.3.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/CHANGELOG.md +76 -0
- package/README.md +104 -64
- package/agents/{executor.md → artisan.md} +5 -12
- package/agents/{explorer.md → scout.md} +2 -3
- package/agents/steward.md +51 -0
- package/package.json +5 -3
- package/src/agents.ts +3 -10
- package/src/announcements.ts +12 -5
- package/src/config.ts +161 -27
- package/src/dispatch.ts +5 -16
- package/src/index.ts +1 -1
- package/src/monitor.ts +2 -2
- package/src/prompt.ts +13 -7
- package/src/setup.ts +121 -101
- package/src/thread-lifecycle.ts +8 -20
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
Published versions of `@ferris1225/pi-subagents`. Unpublished numbers
|
|
4
|
+
(`4.2.3`, `4.2.6`, `4.2.9`–`4.2.11`) never shipped on npm; their changes
|
|
5
|
+
landed in the next published release.
|
|
6
|
+
|
|
7
|
+
## 4.3.0
|
|
8
|
+
|
|
9
|
+
- Built-in team is `scout`, `artisan`, and `steward`. All three stay enabled.
|
|
10
|
+
- `explorer` / `executor` configs rename in place (models and thinking
|
|
11
|
+
overrides follow). `steward` is adopted. That migration is deleted in the
|
|
12
|
+
next major.
|
|
13
|
+
- Artisan owns implement / fix / refactor / test. Steward owns cleanup, docs
|
|
14
|
+
sync, and merge — dispatched only when that work exists.
|
|
15
|
+
- Thinking is a role default (scout low, artisan high, steward medium) that
|
|
16
|
+
`/subagents-setup` can override. Per-call `thinking` and agent-file
|
|
17
|
+
`thinking` are gone. There is no Auto row.
|
|
18
|
+
- First session and first-run setup explain each role and ask for a model.
|
|
19
|
+
- Unit tests cover catalog migration, role prompts, dispatch routing, and
|
|
20
|
+
honest footer / truncation notes.
|
|
21
|
+
|
|
22
|
+
## 4.2.13
|
|
23
|
+
|
|
24
|
+
- README: table of contents, a What's new lead-in, and a pointer at this
|
|
25
|
+
changelog. Release notes describe the live `main` → npm path.
|
|
26
|
+
|
|
27
|
+
## 4.2.12
|
|
28
|
+
|
|
29
|
+
- Executor confirms each named defect on current code before editing.
|
|
30
|
+
- Footer settled counts stay on the line only while a sibling is live, and
|
|
31
|
+
widget truncation no longer lies about what was cut.
|
|
32
|
+
- Merging to `main` publishes an unpublished `package.json` version to npm
|
|
33
|
+
and opens a matching GitHub Release.
|
|
34
|
+
|
|
35
|
+
## 4.2.8
|
|
36
|
+
|
|
37
|
+
- Always-visible footer roll-up: `subagents 2 running · 1 repo lane · 3 done`.
|
|
38
|
+
- `wait: true` streams progress onto the tool card and reports child token
|
|
39
|
+
spend as the call's own usage.
|
|
40
|
+
- Completions are held while context compaction rewrites history, then
|
|
41
|
+
released on success, failure, or abort.
|
|
42
|
+
- A delivered result no longer enters the parent context a second time.
|
|
43
|
+
- Isolated worktrees link `node_modules`.
|
|
44
|
+
- Widget worktree badge is spelled out (`worktree:a91f3c`).
|
|
45
|
+
|
|
46
|
+
## 4.2.7
|
|
47
|
+
|
|
48
|
+
- Executor routing is a single self-contained deliverable; `thinking` can
|
|
49
|
+
be set per dispatch.
|
|
50
|
+
- Child prompt temp directories are removed recursively.
|
|
51
|
+
|
|
52
|
+
## 4.2.5
|
|
53
|
+
|
|
54
|
+
- The threads manifest lives per project, beside that project's artifacts.
|
|
55
|
+
|
|
56
|
+
## 4.2.4
|
|
57
|
+
|
|
58
|
+
- Explorer findings are one-line retrieval leads.
|
|
59
|
+
- Worktree recovery retries cleanup when the patch was already applied.
|
|
60
|
+
|
|
61
|
+
## 4.2.2
|
|
62
|
+
|
|
63
|
+
- A single artifact the main agent must fully absorb stays an inline read;
|
|
64
|
+
re-reads are bounded.
|
|
65
|
+
|
|
66
|
+
## 4.2.1
|
|
67
|
+
|
|
68
|
+
- Upgraded configs prune retired built-in roles so the setup wizard never
|
|
69
|
+
mixes old and new names.
|
|
70
|
+
|
|
71
|
+
## 4.2.0
|
|
72
|
+
|
|
73
|
+
- Built-in team is `explorer` and `executor`. The old
|
|
74
|
+
`worker` / `cleaner` / `documenter` / `synthesizer` / `reviewer` set is
|
|
75
|
+
gone.
|
|
76
|
+
- Live widget splits each run into an identity line and a dim activity line.
|
package/README.md
CHANGED
|
@@ -6,10 +6,41 @@
|
|
|
6
6
|

|
|
7
7
|

|
|
8
8
|
|
|
9
|
-
A managed engineering team for [pi](https://github.com/earendil-works/pi):
|
|
9
|
+
A managed engineering team for [pi](https://github.com/earendil-works/pi): three
|
|
10
10
|
focused sub-agents, durable threads, and Git worktree
|
|
11
11
|
isolation. You install it once and your main agent delegates on its own.
|
|
12
12
|
|
|
13
|
+
## What's new
|
|
14
|
+
|
|
15
|
+
**4.3.0** — the team is `scout`, `artisan`, and `steward`. Existing
|
|
16
|
+
`explorer`/`executor` configs migrate. Thinking is a role default you can
|
|
17
|
+
change in `/subagents-setup` (no Auto, no per-call flag). All three roles
|
|
18
|
+
start on. See [CHANGELOG.md](./CHANGELOG.md).
|
|
19
|
+
|
|
20
|
+
**4.2.13** — this page now leads with current changes and keeps the 4.2 line
|
|
21
|
+
in the changelog.
|
|
22
|
+
|
|
23
|
+
**4.2.12**
|
|
24
|
+
|
|
25
|
+
- Confirm-before-fix; honest footer counts; `main` publishes npm + GitHub Release.
|
|
26
|
+
|
|
27
|
+
## Contents
|
|
28
|
+
|
|
29
|
+
- [Why](#why)
|
|
30
|
+
- [Install](#install)
|
|
31
|
+
- [The team](#the-team)
|
|
32
|
+
- [Dispatching work](#dispatching-work)
|
|
33
|
+
- [Parallel edits](#parallel-edits)
|
|
34
|
+
- [Threads: resume, stop](#threads-resume-stop)
|
|
35
|
+
- [Live status and results](#live-status-and-results)
|
|
36
|
+
- [Models, thinking, and tools](#models-thinking-and-tools)
|
|
37
|
+
- [Configuration](#configuration)
|
|
38
|
+
- [Custom agents](#custom-agents)
|
|
39
|
+
- [Storage and cleanup](#storage-and-cleanup)
|
|
40
|
+
- [Development](#development)
|
|
41
|
+
- [Changelog](#changelog)
|
|
42
|
+
- [Release](#release)
|
|
43
|
+
|
|
13
44
|
## Why
|
|
14
45
|
|
|
15
46
|
Delegation is supposed to remove coordination work. Most sub-agent launchers stop
|
|
@@ -37,10 +68,10 @@ Requires **pi >= 0.84.4** and **Node.js >= 22.19.0**.
|
|
|
37
68
|
pi install npm:@ferris1225/pi-subagents
|
|
38
69
|
```
|
|
39
70
|
|
|
40
|
-
Open pi and run `/subagents-setup
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
for work:
|
|
71
|
+
Open pi and run `/subagents-setup`. The first session tells you how: pick a
|
|
72
|
+
model for `scout`, `artisan`, and `steward` (all three stay on). Each row in
|
|
73
|
+
the wizard names the role and what it owns. Thinking has a role default you
|
|
74
|
+
can change there. Then just ask for work:
|
|
44
75
|
|
|
45
76
|
```text
|
|
46
77
|
Map how authentication works, fix the refresh race, run the tests, and review the diff.
|
|
@@ -51,10 +82,11 @@ directly when you want exact control.
|
|
|
51
82
|
|
|
52
83
|
## The team
|
|
53
84
|
|
|
54
|
-
| Agent
|
|
55
|
-
|
|
|
56
|
-
| `
|
|
57
|
-
| `
|
|
85
|
+
| Agent | Access | Best for |
|
|
86
|
+
| ---------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
87
|
+
| `scout` | Read-only | Broad search, unfamiliar-area mapping, symbol and dependency tracing. Returns a retrieval index — never proof. A single artifact the main agent must fully absorb (one issue, one spec) stays an inline read. |
|
|
88
|
+
| `artisan` | Full | One deliverable that changes the repository: implement, fix, refactor, or test — confirmed on current code, then verified, then a result-only handoff. |
|
|
89
|
+
| `steward` | Full | Use only when that work exists: evidence-first cleanup, docs/comment sync, or merging a fan-out's result artifacts into one brief. |
|
|
58
90
|
|
|
59
91
|
Custom roles join them with a Markdown file (see [Custom agents](#custom-agents)).
|
|
60
92
|
|
|
@@ -63,14 +95,15 @@ memory of your conversation, so the brief is its only input. A good brief carrie
|
|
|
63
95
|
the goal, exact paths, constraints, and expected output — which is what the
|
|
64
96
|
injected delegation guidance produces when the main agent dispatches for you.
|
|
65
97
|
A named defect is not yet a change: confirm it on current code before fixing
|
|
66
|
-
or briefing a fix. The
|
|
98
|
+
or briefing a fix. The artisan re-reads before it edits. Steward is
|
|
99
|
+
dispatched only when cleanup, docs sync, or a merge is actually needed.
|
|
67
100
|
|
|
68
101
|
```text
|
|
69
102
|
You
|
|
70
103
|
└─ pi main agent
|
|
71
|
-
├─
|
|
72
|
-
|
|
73
|
-
|
|
104
|
+
├─ scout ─── parallel recon, retrieval leads only
|
|
105
|
+
├─ artisan ─── implement, fix, refactor, or test → verify → deliver
|
|
106
|
+
└─ steward ─── cleanup, docs sync, or merge fan-out results (when needed)
|
|
74
107
|
```
|
|
75
108
|
|
|
76
109
|
## Dispatching work
|
|
@@ -78,17 +111,16 @@ You
|
|
|
78
111
|
```ts
|
|
79
112
|
// One task
|
|
80
113
|
subagent({
|
|
81
|
-
agent: "
|
|
114
|
+
agent: "artisan",
|
|
82
115
|
task: "Fix the cache invalidation bug in src/cache, add regression tests, run the checks.",
|
|
83
116
|
});
|
|
84
117
|
|
|
85
118
|
// Parallel: as many genuinely independent units as the work has
|
|
86
119
|
subagent({
|
|
87
120
|
tasks: [
|
|
88
|
-
{ agent: "
|
|
89
|
-
{ agent: "
|
|
90
|
-
|
|
91
|
-
{ agent: "executor", task: "Run the suite and report failures.", thinking: "low" },
|
|
121
|
+
{ agent: "scout", task: "Trace model fallback from dispatch to completion." },
|
|
122
|
+
{ agent: "artisan", task: "Add edge-case tests for config migration." },
|
|
123
|
+
{ agent: "steward", task: "Merge the result artifacts under results/ into one brief." },
|
|
92
124
|
],
|
|
93
125
|
});
|
|
94
126
|
```
|
|
@@ -112,8 +144,8 @@ main agent inspects the actual changes before calling anything done.
|
|
|
112
144
|
|
|
113
145
|
## Parallel edits
|
|
114
146
|
|
|
115
|
-
- Single tasks use your checkout. Every parallel write-capable agent (`
|
|
116
|
-
and custom writers) defaults to a detached Git worktree, so
|
|
147
|
+
- Single tasks use your checkout. Every parallel write-capable agent (`artisan`,
|
|
148
|
+
`steward`, and custom writers) defaults to a detached Git worktree, so
|
|
117
149
|
parallel writers run at the same time. Worktree mode needs a committed `HEAD`,
|
|
118
150
|
and read-only agents reject it.
|
|
119
151
|
- A role file can pin its own default with `isolation: worktree` or
|
|
@@ -185,12 +217,12 @@ two lines: what it is — agent, task, token flow, cost, provider/model, elapsed
|
|
|
185
217
|
and, dim under the label column, what it is doing right now:
|
|
186
218
|
|
|
187
219
|
```text
|
|
188
|
-
● #12
|
|
220
|
+
● #12 artisan src/cache.ts · worktree:a91f3c · ↑5.2k ↓41.0k R210.0k W6.1k $1.9400 · 12m06s
|
|
189
221
|
↳ edit src/auth.ts
|
|
190
|
-
● #15
|
|
222
|
+
● #15 scout src/models.ts · ↑1.2k ↓8.4k R31.0k W1.1k $0.0900 · openai/gpt-5-mini · 3m07s
|
|
191
223
|
↳ grep fallback
|
|
192
|
-
○ #23
|
|
193
|
-
○ #24
|
|
224
|
+
○ #23 artisan src/config.ts · repo lane
|
|
225
|
+
○ #24 artisan ↻ tests/config.test.ts · queued · 5m02s
|
|
194
226
|
```
|
|
195
227
|
|
|
196
228
|
Telemetry drops leftmost-first when a row runs out of width (badge, wait
|
|
@@ -242,14 +274,13 @@ is missing, rate-limited, or fails at the provider level, the **same retained
|
|
|
242
274
|
session** continues on the main model, so finished searches, reads, and edits
|
|
243
275
|
survive. Ordinary task failures do not trigger a handoff.
|
|
244
276
|
|
|
245
|
-
Thinking
|
|
246
|
-
effective model supports. `/subagents-setup` →
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
vision mode — assign a multimodal model and name the image paths in the task.
|
|
277
|
+
Thinking is a **role default** — scout `low`, artisan `high`, steward
|
|
278
|
+
`medium` — clamped to what the effective model supports. `/subagents-setup` →
|
|
279
|
+
_Configure an agent_ lists only the levels that model supports, with the role
|
|
280
|
+
default marked. There is no Auto choice, no per-dispatch `thinking` flag, and
|
|
281
|
+
no `thinking` field in agent Markdown. Precedence: your setup override > the
|
|
282
|
+
role default, then the model clamp. There is no separate vision mode — assign
|
|
283
|
+
a multimodal model and name the image paths in the task.
|
|
253
284
|
|
|
254
285
|
Every dispatch, resume, retry, and fallback snapshots the parent's
|
|
255
286
|
currently active tools. A role with no explicit list inherits the full set. An
|
|
@@ -269,16 +300,17 @@ child cannot run.
|
|
|
269
300
|
|
|
270
301
|
## Configuration
|
|
271
302
|
|
|
272
|
-
`/subagents-setup` stays one level deep:
|
|
273
|
-
|
|
303
|
+
`/subagents-setup` stays one level deep: the team (all three stay on), plus a
|
|
304
|
+
model and optional thinking override per agent. First run explains each role
|
|
305
|
+
before you pick models. Everything else is config-file only, stored at
|
|
274
306
|
`~/.pi/agent/pi-subagents.json` (following `PI_CODING_AGENT_DIR`):
|
|
275
307
|
|
|
276
308
|
```json
|
|
277
309
|
{
|
|
278
|
-
"enabledAgents": ["
|
|
279
|
-
"knownAgents": ["
|
|
280
|
-
"agentModels": { "
|
|
281
|
-
"agentThinkingLevels": { "
|
|
310
|
+
"enabledAgents": ["scout", "artisan", "steward"],
|
|
311
|
+
"knownAgents": ["scout", "artisan", "steward"],
|
|
312
|
+
"agentModels": { "scout": "anthropic/claude-haiku-4-5" },
|
|
313
|
+
"agentThinkingLevels": { "artisan": "high" },
|
|
282
314
|
"maxResultLines": 40,
|
|
283
315
|
"agentScope": "user",
|
|
284
316
|
"idleTimeoutSec": 90
|
|
@@ -290,7 +322,7 @@ strength per agent. Everything else is config-file only, stored at
|
|
|
290
322
|
| `enabledAgents` | Agents available for discovery and delegation. `[]` disables all. |
|
|
291
323
|
| `knownAgents` | Built-ins this config has seen; automatic bookkeeping — never edit it. |
|
|
292
324
|
| `agentModels` | Optional `provider/model-id` per agent; missing = current main model. |
|
|
293
|
-
| `agentThinkingLevels` | Optional
|
|
325
|
+
| `agentThinkingLevels` | Optional setup override per agent; missing = the role default. |
|
|
294
326
|
| `maxResultLines` | Lines kept in a completion message before the artifact takes over. Default `40`. |
|
|
295
327
|
| `agentScope` | Discover `user`, `project`, or `both` agent directories. Default `user`. |
|
|
296
328
|
| `idleTimeoutSec` | Seconds without child RPC output before termination; `0` disables. Default `90`. |
|
|
@@ -299,20 +331,22 @@ The delegation directive is always injected; there is no toggle. Invalid values
|
|
|
299
331
|
fall back safely, and stale keys — including the former `proactiveInjection`,
|
|
300
332
|
`maxConcurrency`, `maxFixRounds`, and `notifyOnReviewPass` knobs — are dropped
|
|
301
333
|
automatically. Built-in roles a newer package no longer ships (such as the
|
|
302
|
-
retired `worker`/`cleaner`/`documenter`/`synthesizer`/`reviewer` set
|
|
334
|
+
retired `worker`/`cleaner`/`documenter`/`synthesizer`/`reviewer` set, and the
|
|
335
|
+
renamed `explorer`/`executor` names after they have been mapped) are pruned
|
|
303
336
|
from `enabledAgents`, `knownAgents`, and the model/thinking tables at first
|
|
304
337
|
load, so the setup wizard never mixes old and new roles; custom agents are
|
|
305
|
-
untouched.
|
|
338
|
+
untouched. A 4.2 config that still says `explorer`/`executor` is rewritten to
|
|
339
|
+
`scout`/`artisan` and gains `steward`; their model and thinking overrides move
|
|
340
|
+
with the names. That rename lives in `src/config.ts` and will be deleted in
|
|
341
|
+
the next major. At session
|
|
306
342
|
start, model overrides pi no longer reports are removed with a one-time notice. If
|
|
307
343
|
pi's own session compaction fails mid-thread, a notice surfaces the error and the
|
|
308
344
|
automatic retry instead of failing quietly.
|
|
309
345
|
|
|
310
346
|
Agents shipped by a newer package version turn themselves on at the next
|
|
311
|
-
session
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
(`knownAgents` is what tells the two cases apart). Enabling a role in
|
|
315
|
-
`/subagents-setup` adopts the same explorer route.
|
|
347
|
+
session. Scout, artisan, and steward stay enabled even if a stale allow-list
|
|
348
|
+
left one off. A one-shot notice then points at `/subagents-setup` so you can
|
|
349
|
+
pick a model for each.
|
|
316
350
|
|
|
317
351
|
## Custom agents
|
|
318
352
|
|
|
@@ -324,17 +358,15 @@ Built-ins ship with the package. Add or replace them with Markdown files:
|
|
|
324
358
|
|
|
325
359
|
```yaml
|
|
326
360
|
---
|
|
327
|
-
name:
|
|
361
|
+
name: scout
|
|
328
362
|
description: Fast read-only codebase reconnaissance
|
|
329
|
-
thinking: low
|
|
330
363
|
isolation: shared
|
|
331
364
|
tools: read, bash
|
|
332
365
|
---
|
|
333
366
|
…additional system prompt…
|
|
334
367
|
```
|
|
335
368
|
|
|
336
|
-
`description` is the routing line the main model reads
|
|
337
|
-
role's Auto preference, which a wizard choice overrides. `isolation` pins the
|
|
369
|
+
`description` is the routing line the main model reads. `isolation` pins the
|
|
338
370
|
role's default boundary as described under [Parallel edits](#parallel-edits).
|
|
339
371
|
Models come only from `/subagents-setup`; an agent file cannot pin one. An
|
|
340
372
|
explicit `tools` list is the capability boundary, and omitting it inherits the
|
|
@@ -370,27 +402,35 @@ npm install
|
|
|
370
402
|
npm run check
|
|
371
403
|
```
|
|
372
404
|
|
|
373
|
-
|
|
405
|
+
`npm run check` is `tsc --noEmit` plus the unit tests (`npm test`). There are
|
|
406
|
+
no bundled runtime dependencies; pi and TypeBox are peers. The source is
|
|
374
407
|
split by responsibility: dispatch policy, thread lifecycle, RPC
|
|
375
408
|
transport, worktree integration, completion delivery, tools, and TUI status.
|
|
376
409
|
|
|
377
|
-
##
|
|
410
|
+
## Changelog
|
|
378
411
|
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
Do not `npm publish` from a laptop.
|
|
412
|
+
The 4.3 line lives in [CHANGELOG.md](./CHANGELOG.md). Latest published
|
|
413
|
+
version is **4.3.0**.
|
|
382
414
|
|
|
383
|
-
|
|
415
|
+
| Version | What changed |
|
|
416
|
+
| ------- | ------------ |
|
|
417
|
+
| 4.3.0 | Team is `scout` + `artisan` + `steward`; role thinking defaults; config migrate. |
|
|
418
|
+
| 4.2.13 | README navigation, What's new, and this changelog. |
|
|
419
|
+
| 4.2.12 | Confirm-before-fix; honest footer counts; `main` publishes npm + GitHub Release. |
|
|
420
|
+
| 4.2.8 | Footer roll-up; wait-path token usage; hold completions across compaction. |
|
|
421
|
+
| 4.2.7 | Sharper executor routing; per-dispatch `thinking`. |
|
|
422
|
+
| 4.2.5 | Per-project threads manifest. |
|
|
423
|
+
| 4.2.4 | One-line explorer findings; recovery cleanup retry. |
|
|
424
|
+
| 4.2.2 | Single-artifact reads stay inline. |
|
|
425
|
+
| 4.2.1 | Prune retired roles from upgraded configs. |
|
|
426
|
+
| 4.2.0 | Team is `explorer` + `executor`; two-line live widget. |
|
|
384
427
|
|
|
385
|
-
|
|
386
|
-
[npm package page](https://www.npmjs.com/package/@ferris1225/pi-subagents)
|
|
387
|
-
add a GitHub Actions trusted publisher for `MCapricorns/pi-subagents` with
|
|
388
|
-
workflow filename `publish.yml` (no path, environment left blank).
|
|
389
|
-
2. **Token:** create an npm automation token and store it as the repository
|
|
390
|
-
Actions secret `NPM_TOKEN`.
|
|
428
|
+
## Release
|
|
391
429
|
|
|
392
|
-
|
|
393
|
-
|
|
430
|
+
Merging to `main` publishes `@ferris1225/pi-subagents` when `package.json`
|
|
431
|
+
carries a version npm does not have yet, then opens a matching GitHub Release.
|
|
432
|
+
Do not `npm publish` from a laptop. The workflow is
|
|
433
|
+
`.github/workflows/publish.yml` (npm trusted publisher or `NPM_TOKEN`).
|
|
394
434
|
|
|
395
435
|
## License
|
|
396
436
|
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
3
|
-
description: A self-contained unit that changes the repository
|
|
4
|
-
thinking: high
|
|
2
|
+
name: artisan
|
|
3
|
+
description: A self-contained unit that changes the repository — implement, fix, refactor, or test — carried through verification to a result-only handoff.
|
|
5
4
|
# No `tools` field => inherits all tools (full capability).
|
|
6
5
|
---
|
|
7
6
|
|
|
8
|
-
You are an
|
|
7
|
+
You are an artisan with full capabilities in an isolated context window. You own one delegated implementation task end to end so the main conversation stays clean. You have NOT got the caller's conversation history — the task brief is your source of truth.
|
|
9
8
|
|
|
10
9
|
Repository instructions (AGENTS.md) and any skills available in this session apply to you as to any agent: follow their process for the domains they own (language style, tests, debugging, cleanup discipline, verification). Where a skill covers the same ground as this brief, the skill's discipline wins — except for the release boundary below, which always wins.
|
|
11
10
|
|
|
11
|
+
Cleanup, documentation sync, and merging fan-out results belong to `steward`. If the brief is only that work, do not improvise it here — say so and stop.
|
|
12
|
+
|
|
12
13
|
## Procedure
|
|
13
14
|
|
|
14
15
|
1. **Context.** Read the brief fully, plus referenced files and images, before acting. If critical context is missing, state what is missing rather than guessing.
|
|
@@ -17,14 +18,6 @@ Repository instructions (AGENTS.md) and any skills available in this session app
|
|
|
17
18
|
4. **Implement.** Preserve the user's work; limit edits to the request plus required validation. Follow the project's error handling, naming, and style. Synchronize README/docs/comments your change directly affects; never defer that drift.
|
|
18
19
|
5. **Verify.** Run the project's format/build/tests when they exist. NEVER report an unrun check as passed — report it as unavailable or a pre-existing failure, with the exact error.
|
|
19
20
|
|
|
20
|
-
## Conditional playbooks
|
|
21
|
-
|
|
22
|
-
Skip both unless the brief matches one.
|
|
23
|
-
|
|
24
|
-
**Cleanup** (dead code, duplication, simplification): a candidate is not a deletion. Re-read the load-bearing files and repeat the decisive searches yourself — never inherit proof from another agent's report — and search the whole repository for consumers first. Keep a candidate when a real consumer exists, dynamic reachability is unresolved, or the cut removes a user capability, public API, persisted format, or compatibility path the brief did not explicitly approve. Finding no safe cut and making zero edits is valid.
|
|
25
|
-
|
|
26
|
-
**Merging inputs** (result artifacts, reports, logs): read every named input fully before writing, deduplicate restatements into one attributed entry, and report surviving conflicts side by side instead of averaging them away. Stay within the named inputs; report what they cannot answer as a gap.
|
|
27
|
-
|
|
28
21
|
## Boundaries
|
|
29
22
|
|
|
30
23
|
- Never commit, push, publish, tag, release, or bump a package version — the caller owns every release action, even when repository instructions normally automate release after green checks.
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: scout
|
|
3
3
|
description: Fast read-only reconnaissance for broad or multi-file search in unfamiliar areas; returns exact paths and compressed findings as retrieval leads.
|
|
4
4
|
tools: read, grep, find, ls, bash
|
|
5
5
|
# At launch, this shell slot follows the parent and parent-active plugin tools
|
|
6
6
|
# are appended; the listed non-shell Pi built-ins remain the permission boundary.
|
|
7
|
-
thinking: low
|
|
8
7
|
---
|
|
9
8
|
|
|
10
|
-
You are
|
|
9
|
+
You are a scout: a fast, read-only reconnaissance specialist. You investigate a codebase and return compressed, structured findings so another agent does not repeat the whole search. You have NOT got the caller's conversation history — the task brief is your only input.
|
|
11
10
|
|
|
12
11
|
## Hard constraints
|
|
13
12
|
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: steward
|
|
3
|
+
description: Condenses a finished change or a pile of inputs — evidence-first cleanup, docs/comment sync, or merging fan-out results into one brief.
|
|
4
|
+
# No `tools` field => inherits all tools (full capability).
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
You are a steward: you tidy, document, or fold inputs together so the caller does not. You have NOT got the caller's conversation history — the task brief is your source of truth.
|
|
8
|
+
|
|
9
|
+
Pick one mode from the brief and skip the others. Finding nothing safe to do and making zero edits is valid.
|
|
10
|
+
|
|
11
|
+
## Cleanup
|
|
12
|
+
|
|
13
|
+
A candidate is not a deletion. Re-read the load-bearing files and repeat the decisive searches yourself — never inherit proof from another agent's report — and search the whole repository for consumers first. Keep a candidate when a real consumer exists, dynamic reachability is unresolved, or the cut removes a user capability, public API, persisted format, or compatibility path the brief did not explicitly approve.
|
|
14
|
+
|
|
15
|
+
Honor an explicit scope (uncommitted diff, Git range, directory). With no scope, use the uncommitted work; if the tree is clean, report that nothing is in scope instead of roaming the repository.
|
|
16
|
+
|
|
17
|
+
## Docs sync
|
|
18
|
+
|
|
19
|
+
Update comments, README, examples, and user docs to match the code. Never change runtime behavior to make the documentation true. Prefer the current implementation over another document. Do not start a standalone docs pass the brief did not ask for.
|
|
20
|
+
|
|
21
|
+
## Merging inputs
|
|
22
|
+
|
|
23
|
+
Read every named input fully before writing. Deduplicate restatements into one attributed entry. Report surviving conflicts side by side instead of averaging them away. Stay within the named inputs; report what they cannot answer as a gap.
|
|
24
|
+
|
|
25
|
+
## Boundaries
|
|
26
|
+
|
|
27
|
+
- Never commit, push, publish, tag, release, or bump a package version — the caller owns every release action.
|
|
28
|
+
- Children are leaf processes: you cannot dispatch sub-agents.
|
|
29
|
+
- Implementation, fixes, refactors, and tests belong to `artisan`. If the brief is only that work, say so and stop.
|
|
30
|
+
|
|
31
|
+
## Output format
|
|
32
|
+
|
|
33
|
+
Return only the concrete outcome. Do not repeat the task brief, the investigation, or the tool chronology.
|
|
34
|
+
|
|
35
|
+
## Completed
|
|
36
|
+
|
|
37
|
+
What was done, in a few lines. For a merge, one brief with conflicts and gaps (omit empty sections).
|
|
38
|
+
|
|
39
|
+
## Files Changed
|
|
40
|
+
|
|
41
|
+
- `path/to/file.ts` — what changed. Omit when the mode was read-only merge.
|
|
42
|
+
|
|
43
|
+
## Verification
|
|
44
|
+
|
|
45
|
+
Which checks you ACTUALLY ran and their result. State explicitly anything you could not run and why.
|
|
46
|
+
|
|
47
|
+
## Notes (only when material)
|
|
48
|
+
|
|
49
|
+
Unresolved blockers, kept candidates that need a product decision, or gaps in the inputs. Omit when nothing actionable.
|
|
50
|
+
|
|
51
|
+
Keep the final response comfortably below the 40-line delivery cap unless the result genuinely requires more.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ferris1225/pi-subagents",
|
|
3
|
-
"version": "4.
|
|
4
|
-
"description": "A managed sub-agent team for pi:
|
|
3
|
+
"version": "4.3.0",
|
|
4
|
+
"description": "A managed sub-agent team for pi: scout, artisan, and steward roles, durable threads, model fallback, and Git worktree isolation.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
"src",
|
|
29
29
|
"agents",
|
|
30
30
|
"README.md",
|
|
31
|
+
"CHANGELOG.md",
|
|
31
32
|
"LICENSE"
|
|
32
33
|
],
|
|
33
34
|
"pi": {
|
|
@@ -36,7 +37,8 @@
|
|
|
36
37
|
]
|
|
37
38
|
},
|
|
38
39
|
"scripts": {
|
|
39
|
-
"check": "tsc --noEmit",
|
|
40
|
+
"check": "tsc --noEmit && npm test",
|
|
41
|
+
"test": "node --experimental-transform-types --test test/*.test.ts",
|
|
40
42
|
"prepack": "npm run check"
|
|
41
43
|
},
|
|
42
44
|
"peerDependencies": {
|
package/src/agents.ts
CHANGED
|
@@ -15,7 +15,7 @@ import { type Dirent, existsSync, readdirSync, readFileSync, statSync } from "no
|
|
|
15
15
|
import { dirname, join } from "node:path";
|
|
16
16
|
import { fileURLToPath } from "node:url";
|
|
17
17
|
import { CONFIG_DIR_NAME, getAgentDir, parseFrontmatter } from "@earendil-works/pi-coding-agent";
|
|
18
|
-
import {
|
|
18
|
+
import { type AgentScope } from "./config.ts";
|
|
19
19
|
import type { IsolationMode } from "./worktree.ts";
|
|
20
20
|
|
|
21
21
|
export type AgentSource = "builtin" | "user" | "project";
|
|
@@ -26,8 +26,6 @@ export interface AgentConfig {
|
|
|
26
26
|
tools?: string[];
|
|
27
27
|
/** Model ref this run was routed to; filled in by dispatch, never declared by the agent file. */
|
|
28
28
|
model?: string;
|
|
29
|
-
/** Per-agent default thinking strength (frontmatter `thinking`); config override wins. */
|
|
30
|
-
thinking?: ThinkingLevel;
|
|
31
29
|
/** Role-declared default isolation (frontmatter `isolation`); an explicit
|
|
32
30
|
* per-call request wins, and `worktree` applies to write-capable roles only. */
|
|
33
31
|
isolation?: IsolationMode;
|
|
@@ -94,8 +92,8 @@ export function resolveAgentTools(
|
|
|
94
92
|
export function isWriteCapableAgent(
|
|
95
93
|
agent: Pick<AgentConfig, "name" | "tools">,
|
|
96
94
|
): boolean {
|
|
97
|
-
if (agent.name === "
|
|
98
|
-
if (agent.name === "
|
|
95
|
+
if (agent.name === "scout") return false;
|
|
96
|
+
if (agent.name === "artisan" || agent.name === "steward") return true;
|
|
99
97
|
if (!agent.tools) return true;
|
|
100
98
|
return agent.tools.includes("edit") || agent.tools.includes("write");
|
|
101
99
|
}
|
|
@@ -145,10 +143,6 @@ function loadAgentsFromDir(dir: string, source: AgentSource): AgentConfig[] {
|
|
|
145
143
|
?.split(",")
|
|
146
144
|
.map((t) => t.trim())
|
|
147
145
|
.filter(Boolean);
|
|
148
|
-
const rawThinking = str(frontmatter.thinking)?.trim();
|
|
149
|
-
const thinking = (THINKING_LEVEL_VALUES as readonly string[]).includes(rawThinking ?? "")
|
|
150
|
-
? (rawThinking as ThinkingLevel)
|
|
151
|
-
: undefined;
|
|
152
146
|
const rawIsolation = str(frontmatter.isolation)?.trim();
|
|
153
147
|
const isolation = rawIsolation === "worktree" || rawIsolation === "shared"
|
|
154
148
|
? (rawIsolation as IsolationMode)
|
|
@@ -158,7 +152,6 @@ function loadAgentsFromDir(dir: string, source: AgentSource): AgentConfig[] {
|
|
|
158
152
|
name,
|
|
159
153
|
description,
|
|
160
154
|
tools: tools && tools.length > 0 ? tools : undefined,
|
|
161
|
-
...(thinking ? { thinking } : {}),
|
|
162
155
|
...(isolation ? { isolation } : {}),
|
|
163
156
|
systemPrompt: body,
|
|
164
157
|
source,
|
package/src/announcements.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
4
4
|
import { existsSync } from "node:fs";
|
|
5
|
-
import { loadConfig, saveConfig } from "./config.ts";
|
|
5
|
+
import { FIRST_RUN_SETUP_HINT, loadConfig, saveConfig } from "./config.ts";
|
|
6
6
|
import { availableModelsInScope, filterUnavailableModelOverrides } from "./models.ts";
|
|
7
7
|
import { announceRecoveryRecords } from "./recovery.ts";
|
|
8
8
|
import type { SubagentRuntime } from "./runtime.ts";
|
|
@@ -39,13 +39,20 @@ async function migrateUnavailableAgentModels(
|
|
|
39
39
|
export function registerAnnouncements(pi: ExtensionAPI, runtime: SubagentRuntime): void {
|
|
40
40
|
pi.on("session_start", async (_event, ctx) => {
|
|
41
41
|
if (!existsSync(runtime.configPath)) {
|
|
42
|
-
ctx.ui.notify(
|
|
43
|
-
"pi-subagents: no configuration yet — run /subagents-setup to pick agents, models, and thinking strengths. Defaults (all built-in agents on the main model) apply until then.",
|
|
44
|
-
"info",
|
|
45
|
-
);
|
|
42
|
+
ctx.ui.notify(`pi-subagents: ${FIRST_RUN_SETUP_HINT}`, "info");
|
|
46
43
|
}
|
|
47
44
|
await announceRecoveryRecords(runtime.configPath, ctx);
|
|
48
45
|
await migrateUnavailableAgentModels(ctx, runtime);
|
|
46
|
+
try {
|
|
47
|
+
const config = await loadConfig(runtime.configPath);
|
|
48
|
+
if (config.pendingSetupNotice) {
|
|
49
|
+
ctx.ui.notify(`pi-subagents: ${config.pendingSetupNotice}`, "info");
|
|
50
|
+
const { pendingSetupNotice: _cleared, ...rest } = config;
|
|
51
|
+
await saveConfig(rest, runtime.configPath);
|
|
52
|
+
}
|
|
53
|
+
} catch {
|
|
54
|
+
/* notice is non-fatal */
|
|
55
|
+
}
|
|
49
56
|
// Restore starts at extension load and session_start fires right behind
|
|
50
57
|
// it, so without this the notice reports whatever the race left behind.
|
|
51
58
|
await runtime.durableRestore;
|