@ferris1225/pi-subagents 4.3.4 → 4.3.5
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 +15 -0
- package/README.md +59 -66
- package/agents/artisan.md +0 -1
- package/agents/steward.md +1 -2
- package/{src/index.ts → index.ts} +19 -19
- package/package.json +4 -3
- package/src/{config.ts → configuration/config.ts} +19 -24
- package/src/configuration/setup.ts +375 -0
- package/src/configuration/ui.ts +245 -0
- package/src/{agents.ts → delegation/agents.ts} +3 -3
- package/src/{dispatch.ts → delegation/dispatch.ts} +12 -18
- package/src/{prompt.ts → delegation/prompt.ts} +3 -8
- package/src/{background.ts → execution/background.ts} +3 -6
- package/src/execution/rpc-control.ts +200 -0
- package/src/{rpc-run.ts → execution/rpc-run.ts} +11 -199
- package/src/{session-fork.ts → execution/session-fork.ts} +1 -1
- package/src/{spawn.ts → execution/spawn.ts} +10 -8
- package/src/isolation/git-command.ts +147 -0
- package/src/{recovery.ts → isolation/recovery.ts} +1 -1
- package/src/{worktree.ts → isolation/worktree.ts} +10 -147
- package/src/{completion.ts → lifecycle/completion.ts} +2 -2
- package/src/{durable.ts → lifecycle/durable.ts} +3 -3
- package/src/{runtime.ts → lifecycle/runtime.ts} +7 -7
- package/src/{thread-lifecycle.ts → lifecycle/thread-lifecycle.ts} +25 -519
- package/src/lifecycle/thread-restore.ts +250 -0
- package/src/lifecycle/thread-shared.ts +269 -0
- package/src/{tools.ts → lifecycle/tools.ts} +8 -8
- package/src/{announcements.ts → presentation/announcements.ts} +4 -4
- package/src/{format.ts → presentation/format.ts} +3 -3
- package/src/{monitor.ts → presentation/monitor.ts} +2 -2
- package/src/{widget.ts → presentation/widget.ts} +1 -1
- package/agents/sentinel.md +0 -16
- package/src/setup.ts +0 -344
- package/src/ui.ts +0 -160
- /package/src/{models.ts → configuration/models.ts} +0 -0
- /package/src/{temp-hygiene.ts → isolation/temp-hygiene.ts} +0 -0
- /package/src/{status.ts → presentation/status.ts} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,21 @@ Published versions of `@ferris1225/pi-subagents`. Unpublished numbers
|
|
|
4
4
|
(`4.2.3`, `4.2.6`, `4.2.9`–`4.2.11`) never shipped on npm; their changes
|
|
5
5
|
landed in the next published release.
|
|
6
6
|
|
|
7
|
+
## 4.3.5
|
|
8
|
+
|
|
9
|
+
- Restore `/subagents-setup`'s nested menu flow, fuzzy model picker, and disabled
|
|
10
|
+
custom-role discovery.
|
|
11
|
+
- Retire the built-in `sentinel` role and mandatory pre-commit review workflow.
|
|
12
|
+
Config normalization, loading, and saving now remove its enabled/known entries
|
|
13
|
+
and model/thinking overrides while preserving every other custom role.
|
|
14
|
+
- Keep role prompts self-contained: direct diagnosis, test, and cleanup rules remain,
|
|
15
|
+
while external loading directives are removed.
|
|
16
|
+
- Delegate substantial independent phases more proactively while capping the child-process
|
|
17
|
+
pool at six and retaining phase leases, duplicate-dispatch rejection, and single-route delivery.
|
|
18
|
+
- Move the extension assembly to package-root `index.ts`, group `src/` by responsibility,
|
|
19
|
+
and split thread restoration, shared lifecycle coordination, RPC control, and Git command
|
|
20
|
+
execution out of the largest modules. Pi now shows the package name without a `:src` suffix.
|
|
21
|
+
|
|
7
22
|
## 4.3.4
|
|
8
23
|
|
|
9
24
|
- Keep artisan, steward, and sentinel fully usable when Ferris skills are absent.
|
package/README.md
CHANGED
|
@@ -6,15 +6,17 @@
|
|
|
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 isolation. You install it
|
|
11
11
|
once and your main agent delegates on its own.
|
|
12
12
|
|
|
13
13
|
## What's new
|
|
14
14
|
|
|
15
|
-
**4.3.
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
**4.3.5** — restores the nested setup menus, returns to the three built-in roles,
|
|
16
|
+
removes mandatory review/skill directives, delegates independent phases more proactively
|
|
17
|
+
with at most six child processes, and uses a package-root entry so Pi shows the clean
|
|
18
|
+
package name. Existing configs retain custom roles while dropping the retired `sentinel`.
|
|
19
|
+
|
|
18
20
|
See [CHANGELOG.md](./CHANGELOG.md).
|
|
19
21
|
|
|
20
22
|
## Contents
|
|
@@ -41,8 +43,9 @@ at "spawn a child with a prompt" and leave the hard parts — when to delegate,
|
|
|
41
43
|
wide to fan out, what happens when a model dies, how results come
|
|
42
44
|
back — with you. This extension owns them:
|
|
43
45
|
|
|
44
|
-
- The main model gets a cost-aware routing contract and delegates
|
|
45
|
-
context saves more work than its
|
|
46
|
+
- The main model gets a cost-aware routing contract and proactively delegates
|
|
47
|
+
substantial self-contained phases when a fresh context saves more work than its
|
|
48
|
+
handoff costs.
|
|
46
49
|
- One active normalized task and working directory owns its phase, so an exact
|
|
47
50
|
duplicate dispatch is rejected instead of paying twice.
|
|
48
51
|
- Background completions wake the main model; `wait: true` returns the same result
|
|
@@ -63,11 +66,14 @@ Requires **pi >= 0.84.4** and **Node.js >= 22.19.0**.
|
|
|
63
66
|
pi install npm:@ferris1225/pi-subagents
|
|
64
67
|
```
|
|
65
68
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
Pi's extension list shows `@ferris1225/pi-subagents` without an internal source-path suffix.
|
|
70
|
+
|
|
71
|
+
Open pi and run `/subagents-setup`. The original menu flow lets you enable or
|
|
72
|
+
disable roles, configure one role's model and thinking level, or run the full setup
|
|
73
|
+
again. Each screen uses the usual arrow-key/Enter/Esc navigation, and model lists
|
|
74
|
+
remain searchable. Fresh installs select all three. A newly shipped built-in is
|
|
75
|
+
surfaced once without being re-enabled after you deliberately turn it off. Then ask
|
|
76
|
+
for work:
|
|
71
77
|
|
|
72
78
|
```text
|
|
73
79
|
Map how authentication works, fix the refresh race, run the tests, and review the diff.
|
|
@@ -78,18 +84,14 @@ directly when you want exact control.
|
|
|
78
84
|
|
|
79
85
|
## The team
|
|
80
86
|
|
|
81
|
-
| Agent
|
|
82
|
-
|
|
|
83
|
-
| `scout`
|
|
84
|
-
| `artisan`
|
|
85
|
-
| `steward`
|
|
86
|
-
| `sentinel` | Review-only | A post-cleanup adversarial review using standalone evidence gates plus any matching Ferris skills; reports only evidence-backed defects and concrete test gaps. |
|
|
87
|
+
| Agent | Access | Owns |
|
|
88
|
+
| --------- | --------- | ---- |
|
|
89
|
+
| `scout` | Read-only | Broad or unfamiliar code reconnaissance and external research. Returns compact file citations or source URLs as leads, not proof. |
|
|
90
|
+
| `artisan` | Full | One substantial primary change—implementation, fix, refactor, test, or docs—through root cause, affected verification, and local hygiene. |
|
|
91
|
+
| `steward` | Full | One final cleanup and cross-cutting docs/comment sync pass after a broad or multi-writer change. |
|
|
87
92
|
|
|
88
|
-
Role prompts are
|
|
89
|
-
|
|
90
|
-
the canonical source of deeper language, platform, debugging, testing, and audit
|
|
91
|
-
guidance. Artisan and sentinel load matching skills when available; steward uses
|
|
92
|
-
`ferris-audit`; a missing skill never blocks a role or changes its ownership contract.
|
|
93
|
+
Role prompts are self-contained and directly embed root-cause-first diagnosis,
|
|
94
|
+
meaningful test evidence, and bounded cleanup.
|
|
93
95
|
|
|
94
96
|
Custom roles join them with a Markdown file (see [Custom agents](#custom-agents)).
|
|
95
97
|
|
|
@@ -116,11 +118,10 @@ subagent({
|
|
|
116
118
|
});
|
|
117
119
|
```
|
|
118
120
|
|
|
119
|
-
Breadth is the main agent's call, not a configured
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
as slots free.
|
|
121
|
+
Breadth is the main agent's call, not a configured task cap: put every genuinely
|
|
122
|
+
independent unit in one `tasks` array. The runtime paces execution instead, running
|
|
123
|
+
half the machine's cores with a 4–6 child-process bound; wider batches queue and
|
|
124
|
+
start automatically as slots free.
|
|
124
125
|
|
|
125
126
|
An active run leases its normalized task and resolved working directory across
|
|
126
127
|
agent names. Dispatching the same pair again is rejected and names the existing
|
|
@@ -133,26 +134,23 @@ starting its child — alongside the slot capacity. A run that waits for the wri
|
|
|
133
134
|
lane releases its slot first, so serialized writers never starve new dispatches.
|
|
134
135
|
|
|
135
136
|
One child owns one coherent phase. Dependent work starts only after its
|
|
136
|
-
prerequisite delivers.
|
|
137
|
-
|
|
138
|
-
|
|
137
|
+
prerequisite delivers. Main consumes the child's compact result and citations
|
|
138
|
+
without repeating delegated reconnaissance, implementation, or cleanup. Artisan
|
|
139
|
+
owns a complete primary change with affected tests, docs, comments, targeted
|
|
140
|
+
checks, and local hygiene. Scout owns broad code mapping or external research and
|
|
141
|
+
stays read-only.
|
|
139
142
|
|
|
140
|
-
|
|
141
|
-
focused diff gets a bounded cleanup pass inline; a broad or multi-writer diff gets
|
|
143
|
+
A focused diff gets a bounded cleanup pass inline. A broad or multi-writer diff gets
|
|
142
144
|
one `steward` pass that attacks touched dead code, duplication, tangled conditionals,
|
|
143
|
-
needless layers, and spaghetti growth without widening into a
|
|
144
|
-
|
|
145
|
-
available matching skills.
|
|
146
|
-
A review-driven edit repeats that sequence once; unresolved findings block the
|
|
147
|
-
commit. Main inspects the final diff and runs the final gate.
|
|
145
|
+
needless layers, and spaghetti growth without widening into a repository refactor.
|
|
146
|
+
Main inspects the integrated diff and runs the final gate.
|
|
148
147
|
|
|
149
148
|
## Parallel edits
|
|
150
149
|
|
|
151
150
|
- Single tasks use your checkout. Every parallel write-capable agent (`artisan`,
|
|
152
151
|
`steward`, and custom writers) defaults to a detached Git worktree, so
|
|
153
|
-
parallel writers run at the same time. Worktree mode needs a committed `HEAD
|
|
154
|
-
|
|
155
|
-
uncommitted diff.
|
|
152
|
+
parallel writers run at the same time. Worktree mode needs a committed `HEAD`;
|
|
153
|
+
read-only roles such as scout stay on the shared checkout.
|
|
156
154
|
- A role file can pin its own default with `isolation: worktree` or
|
|
157
155
|
`isolation: shared` in the frontmatter. Precedence is an explicit per-dispatch
|
|
158
156
|
`isolation`, then the role's declaration, then the parallel write default.
|
|
@@ -279,17 +277,15 @@ rather than a fabricated number.
|
|
|
279
277
|
## Models, thinking, and tools
|
|
280
278
|
|
|
281
279
|
Each agent runs on the current main model or one picked in `/subagents-setup`,
|
|
282
|
-
which labels vision and text-only models.
|
|
283
|
-
|
|
284
|
-
too. If a selected model is missing, rate-limited, or fails at the provider level,
|
|
285
|
-
the **same retained
|
|
280
|
+
which labels vision and text-only models. If a selected model is missing,
|
|
281
|
+
rate-limited, or fails at the provider level, the **same retained
|
|
286
282
|
session** continues on the main model, so finished searches, reads, and edits
|
|
287
283
|
survive. Ordinary task failures do not trigger a handoff.
|
|
288
284
|
|
|
289
|
-
Thinking is a **role default** — scout `low`, artisan `high`, steward `medium
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
285
|
+
Thinking is a **role default** — scout `low`, artisan `high`, steward `medium` —
|
|
286
|
+
clamped to what the effective model supports. `/subagents-setup` →
|
|
287
|
+
_Configure an agent_ lists only the levels that model supports and marks the role
|
|
288
|
+
default; selecting it clears the stored override. There is no
|
|
293
289
|
Auto choice, no per-dispatch `thinking` flag, and
|
|
294
290
|
no `thinking` field in agent Markdown. Precedence: your setup override > the
|
|
295
291
|
role default, then the model clamp. There is no separate vision mode — assign
|
|
@@ -314,25 +310,19 @@ For external research scout prefers official documentation, specifications, rele
|
|
|
314
310
|
notes, and first-party repositories; it fetches decisive pages rather than citing
|
|
315
311
|
search snippets, records material dates/versions, and marks uncertainty.
|
|
316
312
|
|
|
317
|
-
`sentinel` has an explicit retrieval/documentation list plus a portable shell
|
|
318
|
-
slot for Git inspection and the smallest proving check. It is pinned to `shared`
|
|
319
|
-
so it sees the current uncommitted diff. Its concise prompt uses matching available
|
|
320
|
-
Ferris skills, preserves their owners, and forbids mutation; missing skills do not
|
|
321
|
-
block review. This is a review contract,
|
|
322
|
-
not a hard shell sandbox.
|
|
323
|
-
|
|
324
313
|
## Configuration
|
|
325
314
|
|
|
326
|
-
`/subagents-setup` opens
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
315
|
+
`/subagents-setup` opens the original settings menu: enable or disable roles,
|
|
316
|
+
configure one enabled role's model and thinking level, or walk through a full
|
|
317
|
+
re-setup. `Esc` moves back through the menu stack, and model lists support fuzzy
|
|
318
|
+
search. Built-in and previously configured custom roles remain available in the
|
|
319
|
+
enable menu. Other settings live in
|
|
330
320
|
`~/.pi/agent/pi-subagents.json` (following `PI_CODING_AGENT_DIR`):
|
|
331
321
|
|
|
332
322
|
```json
|
|
333
323
|
{
|
|
334
|
-
"enabledAgents": ["scout", "artisan", "steward"
|
|
335
|
-
"knownAgents": ["scout", "artisan", "steward"
|
|
324
|
+
"enabledAgents": ["scout", "artisan", "steward"],
|
|
325
|
+
"knownAgents": ["scout", "artisan", "steward"],
|
|
336
326
|
"agentModels": { "scout": "anthropic/claude-haiku-4-5" },
|
|
337
327
|
"agentThinkingLevels": { "artisan": "high" },
|
|
338
328
|
"maxResultLines": 40,
|
|
@@ -345,7 +335,7 @@ selection remains inside the overlay and supports fuzzy search. Other settings l
|
|
|
345
335
|
| --------------------- | ------- |
|
|
346
336
|
| `enabledAgents` | Agents available for discovery and delegation. `[]` disables all. |
|
|
347
337
|
| `knownAgents` | Roles already surfaced by setup; retains disabled custom roles and tracks built-in adoption. |
|
|
348
|
-
| `agentModels` | Optional model per agent; missing means
|
|
338
|
+
| `agentModels` | Optional model per agent; missing means the current main model. |
|
|
349
339
|
| `agentThinkingLevels` | Optional setup override per agent; missing means the role default. |
|
|
350
340
|
| `maxResultLines` | Lines kept in a completion message before the artifact takes over. Default `40`. |
|
|
351
341
|
| `agentScope` | Discover `user`, `project`, or `both` agent directories. Default `user`. |
|
|
@@ -354,8 +344,10 @@ selection remains inside the overlay and supports fuzzy search. Other settings l
|
|
|
354
344
|
When at least one role is enabled, the cost-aware delegation directive is injected
|
|
355
345
|
automatically. `enabledAgents` is authoritative after catalog adoption: a newly
|
|
356
346
|
shipped built-in is appended once, then `knownAgents` records that it was surfaced
|
|
357
|
-
so a deliberate later disable remains disabled.
|
|
358
|
-
|
|
347
|
+
so a deliberate later disable remains disabled. On upgrade, the retired `sentinel`
|
|
348
|
+
entry is removed from enabled and known agents plus model and thinking overrides;
|
|
349
|
+
all other custom roles and known-agent entries remain intact. Invalid known fields
|
|
350
|
+
fall back safely, and unknown fields are dropped when canonical config is persisted.
|
|
359
351
|
|
|
360
352
|
At session start, model overrides that pi no longer reports are removed with a
|
|
361
353
|
one-time notice. If pi's own session compaction fails mid-thread, a notice surfaces
|
|
@@ -418,8 +410,9 @@ npm run check
|
|
|
418
410
|
|
|
419
411
|
`npm run check` is `tsc --noEmit` plus the unit tests (`npm test`). There are
|
|
420
412
|
no bundled runtime dependencies; pi and TypeBox are peers. The source is
|
|
421
|
-
|
|
422
|
-
|
|
413
|
+
grouped by responsibility under `src/`: configuration, delegation, execution, isolation,
|
|
414
|
+
lifecycle, and presentation. Thread restoration, shared lifecycle coordination, RPC control,
|
|
415
|
+
and Git command execution live in focused modules rather than oversized catch-all files.
|
|
423
416
|
|
|
424
417
|
## Changelog
|
|
425
418
|
|
package/agents/artisan.md
CHANGED
|
@@ -7,7 +7,6 @@ You own one primary change phase: implementation, fix, refactor, test, or substa
|
|
|
7
7
|
|
|
8
8
|
## Rules
|
|
9
9
|
|
|
10
|
-
- Use matching ferris skills when available: `ferris-debug` for unexplained failures, `ferris-tests` for test changes, and the relevant language or platform skill. Missing skills are not a blocker; the rules below are the fallback contract.
|
|
11
10
|
- For a reported defect or failure, inspect current behavior, confirm the defect before editing, and establish its root cause; a disproved issue means zero edits.
|
|
12
11
|
- Make the smallest coherent root-cause change. Preserve unrelated work and existing conventions; avoid speculative abstractions and unrelated cleanup.
|
|
13
12
|
- Own the complete primary change plus directly affected tests, README/docs, comments, and local diff hygiene. Remove debug output, dead code, stale comments, and other debris introduced in your scope.
|
package/agents/steward.md
CHANGED
|
@@ -3,11 +3,10 @@ name: steward
|
|
|
3
3
|
description: Pre-commit cleanup and cross-cutting docs/comment sync for a completed broad or multi-writer change.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
You own one final hygiene phase after primary writing has finished
|
|
6
|
+
You own one final hygiene phase after primary writing has finished. The task brief is your only context.
|
|
7
7
|
|
|
8
8
|
## Rules
|
|
9
9
|
|
|
10
|
-
- Use `ferris-audit` when available and apply its automatic pre-commit tier. Missing skills are not a blocker; the rules below are the fallback contract and must not widen into repo-wide cleanup.
|
|
11
10
|
- Require a named completed scope such as an uncommitted diff or Git range. Start there; never repeat implementation or reconnaissance, and stop if primary writing is still active.
|
|
12
11
|
- Hunt hard inside the touched scope: dead or unreachable code, unused imports/exports, duplicated facts or branches, debug residue, stale comments, one-off flags, tangled conditionals, pass-through wrappers, cast/optional fallback sprawl, feature logic in shared paths, and growth toward 1000-line files.
|
|
13
12
|
- Prefer deleting branches, state, and layers; otherwise reuse the canonical helper. Never merely move spaghetti. Prove every cut has no live consumer, and keep uncertain dynamic behavior, public APIs, persisted formats, and compatibility.
|
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Assembly point: builds the shared runtime and registers everything.
|
|
5
5
|
* The heavy lifting lives in focused modules:
|
|
6
|
-
* -
|
|
7
|
-
* -
|
|
8
|
-
* -
|
|
9
|
-
* -
|
|
10
|
-
* -
|
|
11
|
-
* -
|
|
6
|
+
* - delegation/ — role discovery, routing prompts, and tool contract
|
|
7
|
+
* - configuration/ — persisted settings, model routes, and setup UI
|
|
8
|
+
* - execution/ — process queue, RPC transport/control, and model handoff
|
|
9
|
+
* - lifecycle/ — durable threads, restoration, controls, and delivery
|
|
10
|
+
* - isolation/ — Git worktrees, recovery, and temporary-state hygiene
|
|
11
|
+
* - presentation/ — announcements, formatting, monitor, status, and widget
|
|
12
12
|
*
|
|
13
13
|
* Also registers the `/subagents-setup` command and a `before_agent_start` hook
|
|
14
14
|
* that injects a delegation directive into the parent system prompt so the main
|
|
@@ -20,19 +20,19 @@
|
|
|
20
20
|
|
|
21
21
|
import { getAgentDir, type ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
22
22
|
import { Text } from "@earendil-works/pi-tui";
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
26
|
-
import { registerSubagentTool } from "./dispatch.ts";
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
import { createRuntime } from "./runtime.ts";
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
32
|
-
import {
|
|
33
|
-
import {
|
|
34
|
-
import {
|
|
35
|
-
import { clearActiveRunsWidget } from "./widget.ts";
|
|
23
|
+
import { getConfigPath, loadConfig } from "./src/configuration/config.ts";
|
|
24
|
+
import { runSetup } from "./src/configuration/setup.ts";
|
|
25
|
+
import { discoverAgents } from "./src/delegation/agents.ts";
|
|
26
|
+
import { registerSubagentTool } from "./src/delegation/dispatch.ts";
|
|
27
|
+
import { buildDelegationDirective } from "./src/delegation/prompt.ts";
|
|
28
|
+
import { currentSubagentDepth } from "./src/execution/spawn.ts";
|
|
29
|
+
import { createRuntime } from "./src/lifecycle/runtime.ts";
|
|
30
|
+
import { bootstrapDurableState } from "./src/lifecycle/thread-restore.ts";
|
|
31
|
+
import { registerLookupTools } from "./src/lifecycle/tools.ts";
|
|
32
|
+
import { registerAnnouncements } from "./src/presentation/announcements.ts";
|
|
33
|
+
import { matchRunIds } from "./src/presentation/format.ts";
|
|
34
|
+
import { clearActiveRunsStatus } from "./src/presentation/status.ts";
|
|
35
|
+
import { clearActiveRunsWidget } from "./src/presentation/widget.ts";
|
|
36
36
|
|
|
37
37
|
export { matchRunIds };
|
|
38
38
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ferris1225/pi-subagents",
|
|
3
|
-
"version": "4.3.
|
|
4
|
-
"description": "A managed sub-agent team for pi: scout, artisan,
|
|
3
|
+
"version": "4.3.5",
|
|
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": {
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
"dead-code"
|
|
26
26
|
],
|
|
27
27
|
"files": [
|
|
28
|
+
"index.ts",
|
|
28
29
|
"src",
|
|
29
30
|
"agents",
|
|
30
31
|
"README.md",
|
|
@@ -33,7 +34,7 @@
|
|
|
33
34
|
],
|
|
34
35
|
"pi": {
|
|
35
36
|
"extensions": [
|
|
36
|
-
"./
|
|
37
|
+
"./index.ts"
|
|
37
38
|
]
|
|
38
39
|
},
|
|
39
40
|
"scripts": {
|
|
@@ -13,11 +13,14 @@ import { dirname, join } from "node:path";
|
|
|
13
13
|
import { getAgentDir, withFileMutationQueue } from "@earendil-works/pi-coding-agent";
|
|
14
14
|
|
|
15
15
|
/** Full catalog of agents shipped with the package (selectable in /subagents-setup). */
|
|
16
|
-
export const BUILTIN_AGENT_NAMES = ["scout", "artisan", "steward"
|
|
16
|
+
export const BUILTIN_AGENT_NAMES = ["scout", "artisan", "steward"] as const;
|
|
17
17
|
|
|
18
|
-
// Historical catalog for configs written before
|
|
19
|
-
// frozen so future built-ins are still recognized as new.
|
|
20
|
-
const
|
|
18
|
+
// Historical catalog for configs written before built-in adoption tracking.
|
|
19
|
+
// Keep this frozen so future built-ins are still recognized as new.
|
|
20
|
+
const INITIAL_AGENT_NAMES = ["scout", "artisan", "steward"] as const;
|
|
21
|
+
|
|
22
|
+
/** Names that used to be built in and must not survive as custom roles. */
|
|
23
|
+
const RETIRED_AGENT_NAMES = new Set(["sentinel"]);
|
|
21
24
|
|
|
22
25
|
/** Agents enabled out of the box on a fresh install. */
|
|
23
26
|
export const DEFAULT_ENABLED_AGENTS: readonly string[] = [...BUILTIN_AGENT_NAMES];
|
|
@@ -38,8 +41,6 @@ export function roleThinkingLevel(agentName: string): ThinkingLevel {
|
|
|
38
41
|
return "low";
|
|
39
42
|
case "artisan":
|
|
40
43
|
return "high";
|
|
41
|
-
case "sentinel":
|
|
42
|
-
return "max";
|
|
43
44
|
case "steward":
|
|
44
45
|
return "medium";
|
|
45
46
|
default:
|
|
@@ -47,14 +48,6 @@ export function roleThinkingLevel(agentName: string): ThinkingLevel {
|
|
|
47
48
|
}
|
|
48
49
|
}
|
|
49
50
|
|
|
50
|
-
/** Sentinel shares artisan's configured model unless it has its own override. */
|
|
51
|
-
export function configuredModelForAgent(
|
|
52
|
-
agentModels: Readonly<Record<string, string>>,
|
|
53
|
-
agentName: string,
|
|
54
|
-
): string | undefined {
|
|
55
|
-
return agentModels[agentName] ?? (agentName === "sentinel" ? agentModels.artisan : undefined);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
51
|
/** Short responsibility line shown next to each built-in in setup lists. */
|
|
59
52
|
export interface AgentProfile {
|
|
60
53
|
/** A few words for picker rows. */
|
|
@@ -76,10 +69,6 @@ export const AGENT_PROFILES: Record<(typeof BUILTIN_AGENT_NAMES)[number], AgentP
|
|
|
76
69
|
summary: "pre-commit finish",
|
|
77
70
|
remark: "Cleans a completed broad or multi-writer diff and synchronizes cross-cutting docs/comments without changing behavior.",
|
|
78
71
|
},
|
|
79
|
-
sentinel: {
|
|
80
|
-
summary: "adversarial review",
|
|
81
|
-
remark: "Challenges every cleaned pre-commit diff with standalone evidence gates plus available matching skills; follows artisan's model with max thinking by default.",
|
|
82
|
-
},
|
|
83
72
|
};
|
|
84
73
|
|
|
85
74
|
export function agentProfile(name: string): AgentProfile | undefined {
|
|
@@ -143,8 +132,7 @@ export const DEFAULT_CONFIG: SubagentsConfig = {
|
|
|
143
132
|
|
|
144
133
|
export const FIRST_RUN_SETUP_HINT =
|
|
145
134
|
"Run /subagents-setup to choose enabled roles, models, and thinking levels. " +
|
|
146
|
-
"
|
|
147
|
-
"Scout maps code or researches external sources, artisan owns the primary change, steward cleans broad final diffs, and sentinel reviews after cleanup before every commit.";
|
|
135
|
+
"Scout maps code or researches external sources, artisan owns the primary change, and steward cleans broad final diffs.";
|
|
148
136
|
|
|
149
137
|
export function getConfigPath(agentDir: string = getAgentDir()): string {
|
|
150
138
|
return join(agentDir, CONFIG_FILE_NAME);
|
|
@@ -181,15 +169,21 @@ export function normalizeConfig(raw: unknown): SubagentsConfig {
|
|
|
181
169
|
|
|
182
170
|
if (Array.isArray(raw.enabledAgents)) {
|
|
183
171
|
const names = raw.enabledAgents.filter(
|
|
184
|
-
(name): name is string =>
|
|
172
|
+
(name): name is string =>
|
|
173
|
+
typeof name === "string" &&
|
|
174
|
+
name.trim().length > 0 &&
|
|
175
|
+
!RETIRED_AGENT_NAMES.has(name.trim()),
|
|
185
176
|
);
|
|
186
177
|
// An explicitly empty array is honored; duplicates collapse.
|
|
187
178
|
config.enabledAgents = [...new Set(names.map((name) => name.trim()))];
|
|
188
179
|
}
|
|
189
180
|
|
|
190
|
-
const rawKnownAgents = Array.isArray(raw.knownAgents) ? raw.knownAgents :
|
|
181
|
+
const rawKnownAgents = Array.isArray(raw.knownAgents) ? raw.knownAgents : INITIAL_AGENT_NAMES;
|
|
191
182
|
config.knownAgents = [...new Set(rawKnownAgents.filter(
|
|
192
|
-
(name): name is string =>
|
|
183
|
+
(name): name is string =>
|
|
184
|
+
typeof name === "string" &&
|
|
185
|
+
name.trim().length > 0 &&
|
|
186
|
+
!RETIRED_AGENT_NAMES.has(name.trim()),
|
|
193
187
|
).map((name) => name.trim()))];
|
|
194
188
|
for (const name of config.enabledAgents) {
|
|
195
189
|
if (!config.knownAgents.includes(name)) config.knownAgents.push(name);
|
|
@@ -198,7 +192,7 @@ export function normalizeConfig(raw: unknown): SubagentsConfig {
|
|
|
198
192
|
if (isRecord(raw.agentModels)) {
|
|
199
193
|
for (const [rawKey, value] of Object.entries(raw.agentModels)) {
|
|
200
194
|
const key = rawKey.trim();
|
|
201
|
-
if (key !== "" && isModelReference(value)) {
|
|
195
|
+
if (key !== "" && !RETIRED_AGENT_NAMES.has(key) && isModelReference(value)) {
|
|
202
196
|
config.agentModels[key] = value.trim();
|
|
203
197
|
}
|
|
204
198
|
}
|
|
@@ -209,6 +203,7 @@ export function normalizeConfig(raw: unknown): SubagentsConfig {
|
|
|
209
203
|
const key = rawKey.trim();
|
|
210
204
|
if (
|
|
211
205
|
key !== "" &&
|
|
206
|
+
!RETIRED_AGENT_NAMES.has(key) &&
|
|
212
207
|
typeof value === "string" &&
|
|
213
208
|
(THINKING_LEVEL_VALUES as readonly string[]).includes(value)
|
|
214
209
|
) {
|