@ferris1225/pi-subagents 0.21.0 → 0.22.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.
Files changed (3) hide show
  1. package/README.md +5 -3
  2. package/package.json +53 -53
  3. package/src/setup.ts +41 -28
package/README.md CHANGED
@@ -350,9 +350,11 @@ agent's default — its frontmatter `thinking`, else the global default). The gl
350
350
  When the config already exists, re-running `/subagents-setup` opens a menu whose
351
351
  **Configure an agent (model + thinking)** entry lets you pick one agent and set just its
352
352
  model and thinking strength — so changing a single agent no longer walks every enabled
353
- agent. **Change default thinking strength** sets only the global fallback. The rest of the
354
- menu toggles injection, scope, concurrency, fix rounds, and idle timeout; **Full re-setup**
355
- re-runs the whole first-time wizard.
353
+ agent. After one agent's model + strength picks, the wizard returns to the agent picker
354
+ so several agents can be configured in one pass; Esc at any step ends the pass and keeps
355
+ every agent already configured. **Change default thinking strength** sets only the global
356
+ fallback. The rest of the menu toggles injection, scope, concurrency, fix rounds, and
357
+ idle timeout; **Full re-setup** re-runs the whole first-time wizard.
356
358
 
357
359
  ```json
358
360
  {
package/package.json CHANGED
@@ -1,53 +1,53 @@
1
- {
2
- "name": "@ferris1225/pi-subagents",
3
- "version": "0.21.0",
4
- "description": "Focused sub-agent delegation for pi: explore / worker / reviewer agents in isolated context, with proactive dispatch injection and per-agent model selection.",
5
- "type": "module",
6
- "license": "MIT",
7
- "publishConfig": {
8
- "access": "public"
9
- },
10
- "keywords": [
11
- "pi-package",
12
- "pi-extension",
13
- "subagent",
14
- "sub-agent",
15
- "delegation"
16
- ],
17
- "files": [
18
- "src",
19
- "agents",
20
- "README.md",
21
- "LICENSE"
22
- ],
23
- "pi": {
24
- "extensions": [
25
- "./src/index.ts"
26
- ]
27
- },
28
- "scripts": {
29
- "check": "tsc --noEmit",
30
- "test": "vitest run tests",
31
- "prepack": "npm run check && npm test"
32
- },
33
- "peerDependencies": {
34
- "@earendil-works/pi-agent-core": ">=0.80.6",
35
- "@earendil-works/pi-ai": ">=0.80.6",
36
- "@earendil-works/pi-coding-agent": ">=0.80.6",
37
- "@earendil-works/pi-tui": ">=0.80.6",
38
- "typebox": "*"
39
- },
40
- "devDependencies": {
41
- "@earendil-works/pi-agent-core": "^0.83.0",
42
- "@earendil-works/pi-ai": "^0.83.0",
43
- "@earendil-works/pi-coding-agent": "^0.83.0",
44
- "@earendil-works/pi-tui": "^0.83.0",
45
- "@types/node": "^22.10.0",
46
- "typebox": "^1.3.9",
47
- "typescript": "^5.9.0",
48
- "vitest": "^4.1.0"
49
- },
50
- "engines": {
51
- "node": ">=22.19.0"
52
- }
53
- }
1
+ {
2
+ "name": "@ferris1225/pi-subagents",
3
+ "version": "0.22.0",
4
+ "description": "Focused sub-agent delegation for pi: explore / worker / reviewer agents in isolated context, with proactive dispatch injection and per-agent model selection.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "publishConfig": {
8
+ "access": "public"
9
+ },
10
+ "keywords": [
11
+ "pi-package",
12
+ "pi-extension",
13
+ "subagent",
14
+ "sub-agent",
15
+ "delegation"
16
+ ],
17
+ "files": [
18
+ "src",
19
+ "agents",
20
+ "README.md",
21
+ "LICENSE"
22
+ ],
23
+ "pi": {
24
+ "extensions": [
25
+ "./src/index.ts"
26
+ ]
27
+ },
28
+ "scripts": {
29
+ "check": "tsc --noEmit",
30
+ "test": "vitest run tests",
31
+ "prepack": "npm run check && npm test"
32
+ },
33
+ "peerDependencies": {
34
+ "@earendil-works/pi-agent-core": ">=0.80.6",
35
+ "@earendil-works/pi-ai": ">=0.80.6",
36
+ "@earendil-works/pi-coding-agent": ">=0.80.6",
37
+ "@earendil-works/pi-tui": ">=0.80.6",
38
+ "typebox": "*"
39
+ },
40
+ "devDependencies": {
41
+ "@earendil-works/pi-agent-core": "^0.83.0",
42
+ "@earendil-works/pi-ai": "^0.83.0",
43
+ "@earendil-works/pi-coding-agent": "^0.83.0",
44
+ "@earendil-works/pi-tui": "^0.83.0",
45
+ "@types/node": "^22.10.0",
46
+ "typebox": "^1.3.9",
47
+ "typescript": "^5.9.0",
48
+ "vitest": "^4.1.0"
49
+ },
50
+ "engines": {
51
+ "node": ">=22.19.0"
52
+ }
53
+ }
package/src/setup.ts CHANGED
@@ -76,12 +76,15 @@ async function pickEnabledAgents(
76
76
  );
77
77
  }
78
78
 
79
- /** Single-agent model pick; the inherit option drops any existing override. */
79
+ /** Single-agent model pick; the inherit option drops any existing override.
80
+ * `escNote` describes what Esc does at this pick (whole-wizard cancel in the
81
+ * full setup vs. ending the per-agent loop in the menu). */
80
82
  async function pickAgentModel(
81
83
  ctx: ExtensionCommandContext,
82
84
  name: string,
83
85
  currentRef: string | undefined,
84
86
  refs: readonly string[],
87
+ escNote = "cancels setup",
85
88
  ): Promise<string | typeof INHERIT | undefined> {
86
89
  const items = [
87
90
  {
@@ -95,7 +98,7 @@ async function pickAgentModel(
95
98
  return promptSelectOne(
96
99
  ctx,
97
100
  `Model for "${name}"`,
98
- "Type to filter • ↑/↓ • PgUp/PgDn • Enter selects • Esc cancels setup",
101
+ `Type to filter • ↑/↓ • PgUp/PgDn • Enter selects • Esc ${escNote}`,
99
102
  items,
100
103
  );
101
104
  }
@@ -140,13 +143,16 @@ const THINKING_LEVEL_HINTS: Record<ThinkingLevel, string> = {
140
143
  max: "strongest reasoning",
141
144
  };
142
145
 
143
- /** Single strength pick for one agent; the inherit option keeps the effective default. */
146
+ /** Single strength pick for one agent; the inherit option keeps the effective default.
147
+ * `escNote` describes what Esc does at this pick (whole-wizard cancel in the
148
+ * full setup vs. ending the per-agent loop in the menu). */
144
149
  async function pickAgentStrength(
145
150
  ctx: ExtensionCommandContext,
146
151
  agentName: string,
147
152
  current: ThinkingLevel | undefined,
148
153
  defaultLevel: ThinkingLevel,
149
154
  defaults: ReadonlyMap<string, ThinkingLevel>,
155
+ escNote = "cancels setup",
150
156
  ): Promise<ThinkingLevel | typeof INHERIT | undefined> {
151
157
  const options = THINKING_LEVEL_VALUES.map((level) => ({
152
158
  value: level,
@@ -159,7 +165,7 @@ async function pickAgentStrength(
159
165
  const choice = await promptSelectOne(
160
166
  ctx,
161
167
  `Thinking strength for "${agentName}"?`,
162
- "Type to filter • ↑/↓ • Enter selects • Esc cancels setup",
168
+ `Type to filter • ↑/↓ • Enter selects • Esc ${escNote}`,
163
169
  [{ value: INHERIT, label: inheritLabel }, ...options],
164
170
  );
165
171
  if (choice === undefined) return undefined;
@@ -179,7 +185,7 @@ async function pickAgentToConfigure(
179
185
  return promptSelectOne(
180
186
  ctx,
181
187
  "Configure which agent?",
182
- "Type to filter • ↑/↓ • PgUp/PgDn • Enter selects • Esc cancels",
188
+ "Type to filter • ↑/↓ • PgUp/PgDn • Enter selects • Esc stops",
183
189
  items,
184
190
  );
185
191
  }
@@ -189,7 +195,8 @@ async function pickAgentToConfigure(
189
195
  * its thinking strength. Only that one agent is touched, so re-running the menu
190
196
  * to tweak one agent no longer walks every enabled agent. Both picks offer an
191
197
  * "inherit" option that drops any existing per-agent override for that field.
192
- * Resolves undefined when the user cancels (Esc) at any step.
198
+ * Resolves undefined when the user presses Esc at any step; the caller keeps
199
+ * changes from agents already configured earlier in the same pass.
193
200
  */
194
201
  async function configureOneAgent(
195
202
  ctx: ExtensionCommandContext,
@@ -216,13 +223,13 @@ async function configureOneAgent(
216
223
  if (!modelsAvailable) {
217
224
  ctx.ui.notify("No Pi models are currently available; model override left unchanged.", "warning");
218
225
  } else {
219
- const modelChoice = await pickAgentModel(ctx, name, currentModels[name], refs);
220
- if (modelChoice === undefined) return undefined; // Esc cancels setup
226
+ const modelChoice = await pickAgentModel(ctx, name, currentModels[name], refs, "stops — earlier agent picks are kept");
227
+ if (modelChoice === undefined) return undefined; // Esc ends the loop
221
228
  model = modelChoice;
222
229
  }
223
230
 
224
- const strength = await pickAgentStrength(ctx, name, currentStrengths[name], defaultLevel, defaults);
225
- if (strength === undefined) return undefined; // Esc cancels setup
231
+ const strength = await pickAgentStrength(ctx, name, currentStrengths[name], defaultLevel, defaults, "stops — earlier agent picks are kept");
232
+ if (strength === undefined) return undefined; // Esc ends the loop
226
233
 
227
234
  return { name, model, modelsAvailable, strength };
228
235
  }
@@ -403,27 +410,33 @@ async function runMenu(ctx: ExtensionCommandContext, configPath: string, config:
403
410
  if (enabled === undefined) return notifyCancelled(ctx);
404
411
  next.enabledAgents = enabled;
405
412
  } else if (choice.startsWith("Configure an agent")) {
406
- // Per-agent: pick one agent, then its model and thinking strength. Only that
407
- // agent is touched, so tweaking one no longer walks every enabled agent.
413
+ // Per-agent loop: pick one agent, then its model and thinking strength, then
414
+ // return to the agent picker so several agents can be configured in one
415
+ // pass. Esc at any step ends the loop; agents already configured in this
416
+ // pass are kept.
408
417
  const defaults = builtinThinkingDefaults();
409
- const picked = await configureOneAgent(
410
- ctx,
411
- config.enabledAgents,
412
- config.agentModels,
413
- config.agentThinkingLevels,
414
- config.thinkingLevel,
415
- defaults,
416
- );
417
- if (picked === undefined) return notifyCancelled(ctx);
418
- next.agentModels = { ...config.agentModels };
418
+ let configuredAny = false;
419
419
  next.agentThinkingLevels = { ...config.agentThinkingLevels };
420
- if (picked.modelsAvailable) {
421
- if (picked.model === INHERIT) delete next.agentModels[picked.name];
422
- else next.agentModels[picked.name] = picked.model;
423
- next.agentModels = repairStaleModels(ctx, next.agentModels);
420
+ while (true) {
421
+ const picked = await configureOneAgent(
422
+ ctx,
423
+ next.enabledAgents,
424
+ next.agentModels,
425
+ next.agentThinkingLevels,
426
+ next.thinkingLevel,
427
+ defaults,
428
+ );
429
+ if (picked === undefined) break; // Esc ends the loop
430
+ configuredAny = true;
431
+ if (picked.modelsAvailable) {
432
+ if (picked.model === INHERIT) delete next.agentModels[picked.name];
433
+ else next.agentModels[picked.name] = picked.model;
434
+ }
435
+ if (picked.strength === INHERIT) delete next.agentThinkingLevels[picked.name];
436
+ else next.agentThinkingLevels[picked.name] = picked.strength;
424
437
  }
425
- if (picked.strength === INHERIT) delete next.agentThinkingLevels[picked.name];
426
- else next.agentThinkingLevels[picked.name] = picked.strength;
438
+ if (!configuredAny) return notifyCancelled(ctx);
439
+ next.agentModels = repairStaleModels(ctx, next.agentModels);
427
440
  } else if (choice.startsWith("Change default thinking")) {
428
441
  const thinkingLevel = await pickThinkingLevel(ctx, config.thinkingLevel);
429
442
  if (thinkingLevel === undefined) return notifyCancelled(ctx);