@ferris1225/pi-subagents 0.29.0 → 0.32.2
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 +130 -74
- package/package.json +1 -1
- package/src/agents.ts +8 -13
- package/src/background.ts +59 -6
- package/src/completion.ts +28 -0
- package/src/config.ts +14 -2
- package/src/dispatch.ts +1438 -289
- package/src/format.ts +38 -6
- package/src/index.ts +7 -4
- package/src/inspector-panel.ts +363 -0
- package/src/inspector.ts +369 -0
- package/src/models.ts +192 -50
- package/src/monitor.ts +141 -7
- package/src/prompt.ts +9 -2
- package/src/recovery.ts +145 -0
- package/src/rpc-run.ts +1016 -0
- package/src/runtime.ts +183 -8
- package/src/session-fork.ts +84 -0
- package/src/setup.ts +271 -184
- package/src/spawn.ts +562 -856
- package/src/tools.ts +407 -65
- package/src/trajectory.ts +503 -0
- package/src/ui.ts +32 -16
- package/src/widget.ts +22 -5
- package/src/worktree.ts +687 -0
package/src/widget.ts
CHANGED
|
@@ -14,10 +14,12 @@ import {
|
|
|
14
14
|
deriveActivityState,
|
|
15
15
|
formatElapsed,
|
|
16
16
|
formatUsageCompact,
|
|
17
|
+
isRunActiveStatus,
|
|
17
18
|
monitor,
|
|
18
19
|
statusIcon,
|
|
19
20
|
statusLabel,
|
|
20
21
|
} from "./monitor.ts";
|
|
22
|
+
import { announceRecoveryRecords } from "./recovery.ts";
|
|
21
23
|
import type { SubagentRuntime } from "./runtime.ts";
|
|
22
24
|
|
|
23
25
|
/** Features whose one-time announcement is still pending (keyed by config
|
|
@@ -80,6 +82,9 @@ async function announceNewFeatures(
|
|
|
80
82
|
|
|
81
83
|
export function registerWidget(pi: ExtensionAPI, runtime: SubagentRuntime): void {
|
|
82
84
|
pi.on("session_start", async (_e, ctx) => {
|
|
85
|
+
// Recovery paths survive the old runtime and are shown again in the next
|
|
86
|
+
// UI-capable session before any transient widget state is rebuilt.
|
|
87
|
+
await announceRecoveryRecords(runtime.configPath, ctx);
|
|
83
88
|
if (ctx.mode !== "tui") return;
|
|
84
89
|
await announceNewFeatures(ctx, runtime);
|
|
85
90
|
|
|
@@ -89,7 +94,7 @@ export function registerWidget(pi: ExtensionAPI, runtime: SubagentRuntime): void
|
|
|
89
94
|
const unsub = monitor.subscribe(() => tui.requestRender());
|
|
90
95
|
// Tick once a second so elapsed time stays live while runs are active.
|
|
91
96
|
const timer = setInterval(() => {
|
|
92
|
-
if (monitor.getRuns().some((r) => r.status
|
|
97
|
+
if (monitor.getRuns().some((r) => isRunActiveStatus(r.status))) {
|
|
93
98
|
tui.requestRender();
|
|
94
99
|
}
|
|
95
100
|
}, 1000);
|
|
@@ -110,7 +115,7 @@ export function registerWidget(pi: ExtensionAPI, runtime: SubagentRuntime): void
|
|
|
110
115
|
const isChain = Boolean(r.groupId);
|
|
111
116
|
const chainContinues = isChain && runs[idx + 1]?.groupId === r.groupId;
|
|
112
117
|
const activity =
|
|
113
|
-
r.activity && (r.status
|
|
118
|
+
r.activity && isRunActiveStatus(r.status) ? r.activity : undefined;
|
|
114
119
|
const hasActivity = activity !== undefined;
|
|
115
120
|
const icon = statusIcon(r.status, theme);
|
|
116
121
|
// Chain-internal runs (auto-fix worker/reviewer) are child nodes under
|
|
@@ -126,21 +131,33 @@ export function registerWidget(pi: ExtensionAPI, runtime: SubagentRuntime): void
|
|
|
126
131
|
// uses the accent color, everything else is quiet.
|
|
127
132
|
if (!isChain && lines.length > 0) lines.push("");
|
|
128
133
|
const nodeBranch = isChain ? (chainContinues ? "├─ " : "└─ ") : "";
|
|
129
|
-
|
|
134
|
+
// Content label (task-derived) trails the agent name so concurrent
|
|
135
|
+
// same-agent runs read as what they do, not just their run id. Chain
|
|
136
|
+
// nodes already carry a distinguishing relationLabel.
|
|
137
|
+
const labelPart = !isChain && r.label ? ` ${dim(`· ${r.label}`)}` : "";
|
|
138
|
+
const left = `${dim(nodeBranch)}${icon} ${dim(`#${r.id}`)} ${isChain ? name : theme.fg("accent", theme.bold(name))}${labelPart}`;
|
|
130
139
|
|
|
131
140
|
// Right side: full model ref (provider/model), token usage (in/out +
|
|
132
141
|
// cache read/write), tool count, elapsed, and the soft activity-state
|
|
133
142
|
// annotation (idle / long-running). Trailing the header with a single
|
|
134
143
|
// " · " chain keeps the row compact (no center gap); compactLine
|
|
135
144
|
// clips on overflow, never the right side on its own.
|
|
136
|
-
const model = r.
|
|
145
|
+
const model = r.modelFallbackFrom
|
|
146
|
+
? `${r.model ?? "?"} (pool fallback from ${r.modelFallbackFrom})`
|
|
147
|
+
: (r.model ?? "?");
|
|
137
148
|
const usage = formatUsageCompact(r.usage);
|
|
138
149
|
const tools = r.toolCount ? `${r.toolCount} tool${r.toolCount === 1 ? "" : "s"}` : "";
|
|
139
150
|
const elapsed = formatElapsed(r, now);
|
|
140
151
|
// The round outcome summary leads the metadata so a finished chain
|
|
141
152
|
// row reads as what it did ("fail · src/index.ts · render()",
|
|
142
153
|
// "pass", "src/index.ts · tests/monitor.test.ts").
|
|
143
|
-
const
|
|
154
|
+
const isolation = r.isolation === "worktree" ? `worktree ${r.integrationStatus ?? "active"}` : undefined;
|
|
155
|
+
const relation = r.forkedFromRunId !== undefined
|
|
156
|
+
? `fork of #${r.forkedFromRunId}`
|
|
157
|
+
: (r.forkChildRunIds?.length ?? 0) > 0
|
|
158
|
+
? `forks ${r.forkChildRunIds!.map((id) => `#${id}`).join(",")}`
|
|
159
|
+
: undefined;
|
|
160
|
+
const metaParts = [r.summary, relation, isolation, model, usage, tools, elapsed].filter(Boolean);
|
|
144
161
|
// Running is conveyed by the icon + elapsed; spell out the label only for
|
|
145
162
|
// the other states (ready / done / stopped) so they are unambiguous.
|
|
146
163
|
if (r.status !== "running") metaParts.push(statusLabel(r.status));
|