@ferris1225/pi-subagents 2.0.2 → 2.1.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 CHANGED
@@ -338,9 +338,13 @@ parent does not `abort_retry` them — and only a settled model-level failure
338
338
  hands off to current main. This uses supported extension/RPC surfaces in Node
339
339
  and standalone/Bun builds, never rewrites global or project settings, and does
340
340
  not alter descendant tool environments. Tool/test failures stay on the same
341
- model because they are task failures, not model availability failures. Only a truly
342
- zero-activity process startup race can retry; an accepted prompt or any
343
- agent/turn/stream/tool activity forbids replay.
341
+ model because they are task failures, not model availability failures. A child is
342
+ probed with RPC `get_state` before the first prompt so the 30s command ACK clock
343
+ does not include process boot. Only a zero-activity startup miss can retry — a
344
+ silent fast exit, a `get_state` handshake timeout, or an initial prompt ACK
345
+ timeout before any agent/turn/stream/tool activity. Those transport misses are
346
+ not model-level failures and do not hand the task to the main window. An accepted
347
+ prompt or any activity forbids replay.
344
348
 
345
349
  Auto thinking starts from the Agent's declared preference (`low` for `explore`,
346
350
  `high` for the other built-ins) and uses Pi's capability map to clamp it to the
@@ -425,12 +429,13 @@ npm run check
425
429
  npm test
426
430
  ```
427
431
 
428
- The source is modular: `dispatch.ts` (dispatch, controls, isolation, auto-fix),
432
+ The source is modular: `dispatch.ts` (public dispatch contract + auto-fix),
433
+ `thread-lifecycle.ts` (queued generations, resume/fork, and isolation settlement),
429
434
  `rpc-run.ts` / `spawn.ts` (persistent child transport + selected→main handoff),
430
435
  `worktree.ts` / `session-fork.ts` (filesystem/session branching), `tools.ts`
431
436
  (wait/status/control/stop), `widget.ts` (active-only TUI status), `announcements.ts`
432
- (recovery and feature notices), and `runtime.ts` (session-scoped ownership). No runtime dependencies beyond pi peer
433
- dependencies.
437
+ (recovery and feature notices), and `runtime.ts` (session-scoped ownership). No runtime
438
+ dependencies beyond pi peer dependencies.
434
439
 
435
440
  ## License
436
441
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ferris1225/pi-subagents",
3
- "version": "2.0.2",
3
+ "version": "2.1.0",
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",
@@ -1,70 +1,70 @@
1
- /** Session-start recovery and one-time feature announcements. */
2
-
3
- import { stat } from "node:fs/promises";
4
- import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
5
- import { loadConfig, saveConfig } from "./config.ts";
6
- import { announceRecoveryRecords } from "./recovery.ts";
7
- import type { SubagentRuntime } from "./runtime.ts";
8
- import { pruneResultArtifacts } from "./spawn.ts";
9
- import { installActiveRunsWidget } from "./widget.ts";
10
-
11
- const ANNOUNCEMENTS: Array<{
12
- key: string;
13
- condition: (config: Awaited<ReturnType<typeof loadConfig>>) => boolean;
14
- message: string;
15
- }> = [
16
- {
17
- key: "visionModel",
18
- condition: (config) => config.visionModel === undefined,
19
- message:
20
- "pi-subagents: new — a vision-capable model can now handle image tasks (screenshots, mockups, designs). Run /subagents-setup to configure it; until set, vision tasks use the main session's current model.",
21
- },
22
- {
23
- key: "cleanerAgent",
24
- condition: (config) => !config.enabledAgents.includes("cleaner"),
25
- message:
26
- "pi-subagents: new built-in cleaner agent is available for evidence-first code cleanup. Run /subagents-setup to enable it; your existing enabledAgents selection was left unchanged.",
27
- },
28
- ];
29
-
30
- async function announceNewFeatures(
31
- ctx: { ui: { notify: (message: string, kind: "info" | "warning" | "error") => void } },
32
- runtime: SubagentRuntime,
33
- ): Promise<void> {
34
- try {
35
- let configExists = true;
36
- try {
37
- await stat(runtime.configPath);
38
- } catch {
39
- configExists = false;
40
- }
41
- if (!configExists) return;
42
-
43
- const config = await loadConfig(runtime.configPath);
44
- const pending = ANNOUNCEMENTS.filter(
45
- (announcement) =>
46
- announcement.condition(config) && !config.announcedFeatures.includes(announcement.key),
47
- );
48
- if (pending.length === 0) return;
49
- await saveConfig(
50
- {
51
- ...config,
52
- announcedFeatures: [...config.announcedFeatures, ...pending.map((announcement) => announcement.key)],
53
- },
54
- runtime.configPath,
55
- );
56
- for (const announcement of pending) ctx.ui.notify(announcement.message, "info");
57
- } catch {
58
- /* announcement failures are non-fatal */
59
- }
60
- }
61
-
62
- export function registerAnnouncements(pi: ExtensionAPI, runtime: SubagentRuntime): void {
63
- pi.on("session_start", async (_event, ctx) => {
64
- pruneResultArtifacts();
65
- await announceRecoveryRecords(runtime.configPath, ctx);
66
- if (ctx.mode !== "tui") return;
67
- installActiveRunsWidget(ctx);
68
- await announceNewFeatures(ctx, runtime);
69
- });
70
- }
1
+ /** Session-start recovery and one-time feature announcements. */
2
+
3
+ import { stat } from "node:fs/promises";
4
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
5
+ import { loadConfig, saveConfig } from "./config.ts";
6
+ import { announceRecoveryRecords } from "./recovery.ts";
7
+ import type { SubagentRuntime } from "./runtime.ts";
8
+ import { pruneResultArtifacts } from "./spawn.ts";
9
+ import { installActiveRunsWidget } from "./widget.ts";
10
+
11
+ const ANNOUNCEMENTS: Array<{
12
+ key: string;
13
+ condition: (config: Awaited<ReturnType<typeof loadConfig>>) => boolean;
14
+ message: string;
15
+ }> = [
16
+ {
17
+ key: "visionModel",
18
+ condition: (config) => config.visionModel === undefined,
19
+ message:
20
+ "pi-subagents: new — a vision-capable model can now handle image tasks (screenshots, mockups, designs). Run /subagents-setup to configure it; until set, vision tasks use the main session's current model.",
21
+ },
22
+ {
23
+ key: "cleanerAgent",
24
+ condition: (config) => !config.enabledAgents.includes("cleaner"),
25
+ message:
26
+ "pi-subagents: new built-in cleaner agent is available for evidence-first code cleanup. Run /subagents-setup to enable it; your existing enabledAgents selection was left unchanged.",
27
+ },
28
+ ];
29
+
30
+ async function announceNewFeatures(
31
+ ctx: { ui: { notify: (message: string, kind: "info" | "warning" | "error") => void } },
32
+ runtime: SubagentRuntime,
33
+ ): Promise<void> {
34
+ try {
35
+ let configExists = true;
36
+ try {
37
+ await stat(runtime.configPath);
38
+ } catch {
39
+ configExists = false;
40
+ }
41
+ if (!configExists) return;
42
+
43
+ const config = await loadConfig(runtime.configPath);
44
+ const pending = ANNOUNCEMENTS.filter(
45
+ (announcement) =>
46
+ announcement.condition(config) && !config.announcedFeatures.includes(announcement.key),
47
+ );
48
+ if (pending.length === 0) return;
49
+ await saveConfig(
50
+ {
51
+ ...config,
52
+ announcedFeatures: [...config.announcedFeatures, ...pending.map((announcement) => announcement.key)],
53
+ },
54
+ runtime.configPath,
55
+ );
56
+ for (const announcement of pending) ctx.ui.notify(announcement.message, "info");
57
+ } catch {
58
+ /* announcement failures are non-fatal */
59
+ }
60
+ }
61
+
62
+ export function registerAnnouncements(pi: ExtensionAPI, runtime: SubagentRuntime): void {
63
+ pi.on("session_start", async (_event, ctx) => {
64
+ pruneResultArtifacts();
65
+ await announceRecoveryRecords(runtime.configPath, ctx);
66
+ if (ctx.mode !== "tui") return;
67
+ installActiveRunsWidget(ctx);
68
+ await announceNewFeatures(ctx, runtime);
69
+ });
70
+ }