@ferris1225/pi-subagents 4.0.0 → 4.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -12
- package/package.json +1 -1
- package/src/config.ts +36 -6
package/README.md
CHANGED
|
@@ -11,13 +11,15 @@ Focused background delegation for [pi](https://pi.dev): `explorer` / `worker` /
|
|
|
11
11
|
results back to the main agent automatically. Install it, and the main model
|
|
12
12
|
starts using it on its own — no prompt engineering, no babysitting.
|
|
13
13
|
|
|
14
|
-
## 4.0.
|
|
14
|
+
## 4.0.1 — automatic explorer config migration
|
|
15
15
|
|
|
16
16
|
Version 4 renames the built-in reconnaissance role from `explore` to `explorer`
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
without retaining a runtime alias. Version 4.0.1 automatically migrates the old
|
|
18
|
+
name in `enabledAgents`, `agentModels`, and `agentThinkingLevels`, then persists
|
|
19
|
+
the normalized configuration; an already configured `explorer` value wins a
|
|
20
|
+
conflict. `cleaner` is apply-only: explicit cleanup intent authorizes it to prove
|
|
21
|
+
and perform every safe in-scope cut, while generic or read-only assessments go to
|
|
22
|
+
`reviewer` without triggering auto-fix.
|
|
21
23
|
|
|
22
24
|
The main delegation directive is now the single authoritative routing policy;
|
|
23
25
|
duplicated tool guidelines were removed to cut the default parent injection by
|
|
@@ -418,13 +420,14 @@ Config loading normalizes schema fields and removes invalid or obsolete keys,
|
|
|
418
420
|
including `agentBackupModels`, global `thinkingLevel`, `maxParallelTasks`, and
|
|
419
421
|
`maxSubagentDepth`. Per-agent thinking preferences remain capability-clamped.
|
|
420
422
|
|
|
421
|
-
The built-in reconnaissance role is now `explorer
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
the existing one-time setup
|
|
423
|
+
The built-in reconnaissance role is now `explorer`, with no runtime `explore`
|
|
424
|
+
alias. Config loading automatically renames the old key in `enabledAgents`,
|
|
425
|
+
`agentModels`, and `agentThinkingLevels`, deduplicates an old/new pair, and persists
|
|
426
|
+
the normalized file. When both model or thinking keys are valid, the explicit
|
|
427
|
+
`explorer` value wins. Other configured non-empty names are preserved. A
|
|
428
|
+
pre-existing explicit `enabledAgents` list is also still preserved without
|
|
429
|
+
appending `cleaner`; configs without cleaner receive the existing one-time setup
|
|
430
|
+
notice.
|
|
428
431
|
|
|
429
432
|
## Agent discovery and overrides
|
|
430
433
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ferris1225/pi-subagents",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.1",
|
|
4
4
|
"description": "Controllable background sub-agent threads for pi: specialized roles, capability-aware thinking, direct main-model fallback, auto-fix chains, and Git worktree isolation.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
package/src/config.ts
CHANGED
|
@@ -25,6 +25,13 @@ export const DEFAULT_ENABLED_AGENTS: readonly string[] = ["explorer", "worker",
|
|
|
25
25
|
export const AGENT_SCOPE_VALUES = ["user", "project", "both"] as const;
|
|
26
26
|
export type AgentScope = (typeof AGENT_SCOPE_VALUES)[number];
|
|
27
27
|
|
|
28
|
+
const LEGACY_EXPLORER_NAME = "explore";
|
|
29
|
+
const EXPLORER_NAME = "explorer";
|
|
30
|
+
|
|
31
|
+
function migrateAgentName(name: string): string {
|
|
32
|
+
return name === LEGACY_EXPLORER_NAME ? EXPLORER_NAME : name;
|
|
33
|
+
}
|
|
34
|
+
|
|
28
35
|
/** Thinking levels accepted by pi's `--thinking` option. */
|
|
29
36
|
export const THINKING_LEVEL_VALUES = ["off", "minimal", "low", "medium", "high", "xhigh", "max"] as const;
|
|
30
37
|
export type ThinkingLevel = (typeof THINKING_LEVEL_VALUES)[number];
|
|
@@ -156,25 +163,48 @@ export function normalizeConfig(raw: unknown): SubagentsConfig {
|
|
|
156
163
|
const names = raw.enabledAgents.filter(
|
|
157
164
|
(name): name is string => typeof name === "string" && name.trim().length > 0,
|
|
158
165
|
);
|
|
159
|
-
// An explicitly empty array is honored
|
|
160
|
-
config
|
|
166
|
+
// An explicitly empty array is honored. Rename the former built-in key and
|
|
167
|
+
// deduplicate when a config already contains both spellings.
|
|
168
|
+
config.enabledAgents = [...new Set(names.map((name) => migrateAgentName(name.trim())))];
|
|
161
169
|
}
|
|
162
170
|
|
|
163
171
|
if (isRecord(raw.agentModels)) {
|
|
164
|
-
|
|
165
|
-
|
|
172
|
+
const entries = Object.entries(raw.agentModels);
|
|
173
|
+
// A valid explicit new key wins regardless of JSON property order.
|
|
174
|
+
for (const [rawKey, value] of entries) {
|
|
175
|
+
const key = rawKey.trim();
|
|
176
|
+
if (key !== LEGACY_EXPLORER_NAME && isModelReference(value)) {
|
|
177
|
+
config.agentModels[key] = value.trim();
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
if (!Object.hasOwn(config.agentModels, EXPLORER_NAME)) {
|
|
181
|
+
const legacy = entries.find(([key, value]) =>
|
|
182
|
+
key.trim() === LEGACY_EXPLORER_NAME && isModelReference(value)
|
|
183
|
+
);
|
|
184
|
+
if (legacy && isModelReference(legacy[1])) config.agentModels[EXPLORER_NAME] = legacy[1].trim();
|
|
166
185
|
}
|
|
167
186
|
}
|
|
168
187
|
|
|
169
188
|
if (isRecord(raw.agentThinkingLevels)) {
|
|
170
|
-
|
|
189
|
+
const entries = Object.entries(raw.agentThinkingLevels);
|
|
190
|
+
for (const [rawKey, value] of entries) {
|
|
191
|
+
const key = rawKey.trim();
|
|
171
192
|
if (
|
|
193
|
+
key !== LEGACY_EXPLORER_NAME &&
|
|
172
194
|
typeof value === "string" &&
|
|
173
195
|
(THINKING_LEVEL_VALUES as readonly string[]).includes(value)
|
|
174
196
|
) {
|
|
175
|
-
config.agentThinkingLevels[key
|
|
197
|
+
config.agentThinkingLevels[key] = value as ThinkingLevel;
|
|
176
198
|
}
|
|
177
199
|
}
|
|
200
|
+
if (!Object.hasOwn(config.agentThinkingLevels, EXPLORER_NAME)) {
|
|
201
|
+
const legacy = entries.find(([key, value]) =>
|
|
202
|
+
key.trim() === LEGACY_EXPLORER_NAME &&
|
|
203
|
+
typeof value === "string" &&
|
|
204
|
+
(THINKING_LEVEL_VALUES as readonly string[]).includes(value)
|
|
205
|
+
);
|
|
206
|
+
if (legacy) config.agentThinkingLevels[EXPLORER_NAME] = legacy[1] as ThinkingLevel;
|
|
207
|
+
}
|
|
178
208
|
}
|
|
179
209
|
|
|
180
210
|
if (typeof raw.notifyOnReviewPass === "boolean") {
|