@ferris1225/pi-subagents 4.3.12 → 4.3.13
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 +7 -0
- package/README.md +4 -13
- package/index.ts +2 -3
- package/package.json +1 -1
- package/src/presentation/announcements.ts +3 -5
- package/src/presentation/status.ts +0 -67
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,13 @@
|
|
|
3
3
|
Release notes for `@ferris1225/pi-subagents`. Only the most recent releases
|
|
4
4
|
are kept here; every published version is preserved as a GitHub Release.
|
|
5
5
|
|
|
6
|
+
## 4.3.13
|
|
7
|
+
|
|
8
|
+
- Remove the `subagents N running · …` activity-count line from the footer.
|
|
9
|
+
Live progress stays visible in the above-editor widget, per-run completion
|
|
10
|
+
notifications, and `subagent_status`; the footer is reserved for the
|
|
11
|
+
per-model cost tally.
|
|
12
|
+
|
|
6
13
|
## 4.3.12
|
|
7
14
|
|
|
8
15
|
- Replace pi's built-in consumption line with a per-model cost footer for the
|
package/README.md
CHANGED
|
@@ -12,6 +12,10 @@ once and your main agent delegates on its own.
|
|
|
12
12
|
|
|
13
13
|
## What's new
|
|
14
14
|
|
|
15
|
+
**4.3.13** — the footer is reserved for the per-model cost tally: the
|
|
16
|
+
`subagents N running` activity-count line is gone, leaving the widget,
|
|
17
|
+
completion notifications, and `subagent_status` for live progress.
|
|
18
|
+
|
|
15
19
|
**4.3.12** — per-model accounting: the main window's consumption line becomes a
|
|
16
20
|
per-model cost footer (token flow, cost, context share, and live `tok/s` per
|
|
17
21
|
`provider/model`), awaited children's usage is no longer folded into the parent
|
|
@@ -355,19 +359,6 @@ for shared-checkout write serialization, or `starting`. The widget is
|
|
|
355
359
|
capped at ten lines: when many runs are live, extra runs collapse into a
|
|
356
360
|
`… +N more` marker so the editor keeps its space.
|
|
357
361
|
|
|
358
|
-
The widget is the detailed surface, but it only pays off while you are looking
|
|
359
|
-
at it. A one-line roll-up in the always-visible footer answers "is anything
|
|
360
|
-
still working?" without opening the widget or asking:
|
|
361
|
-
|
|
362
|
-
```text
|
|
363
|
-
subagents 2 running · 1 repo lane · 3 done
|
|
364
|
-
```
|
|
365
|
-
|
|
366
|
-
It is count-only, keeps the same wait vocabulary as the widget, and works in
|
|
367
|
-
RPC hosts as well as the TUI. Settled counts stay on the line only while a
|
|
368
|
-
sibling is still live (`2 running · 3 done`); the line disappears once nothing
|
|
369
|
-
is active.
|
|
370
|
-
|
|
371
362
|
### Per-model cost footer
|
|
372
363
|
|
|
373
364
|
In TUI sessions the extension replaces pi's built-in consumption line with a
|
package/index.ts
CHANGED
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
* - execution/ — process queue, RPC transport/control, and model handoff
|
|
9
9
|
* - lifecycle/ — durable threads, restoration, controls, and delivery
|
|
10
10
|
* - isolation/ — Git worktrees, recovery, and temporary-state hygiene
|
|
11
|
-
* - presentation/ — announcements, formatting, monitor,
|
|
11
|
+
* - presentation/ — announcements, cost footer/ledger, formatting, monitor,
|
|
12
|
+
* and the active-run widget
|
|
12
13
|
*
|
|
13
14
|
* Also registers the `/subagents-setup` command and a `before_agent_start` hook
|
|
14
15
|
* that injects a delegation directive into the parent system prompt so the main
|
|
@@ -34,7 +35,6 @@ import { registerAnnouncements } from "./src/presentation/announcements.ts";
|
|
|
34
35
|
import { registerMainCostTracking } from "./src/presentation/cost-ledger.ts";
|
|
35
36
|
import { clearCostFooter } from "./src/presentation/cost-footer.ts";
|
|
36
37
|
import { matchRunIds } from "./src/presentation/format.ts";
|
|
37
|
-
import { clearActiveRunsStatus } from "./src/presentation/status.ts";
|
|
38
38
|
import { clearActiveRunsWidget } from "./src/presentation/widget.ts";
|
|
39
39
|
|
|
40
40
|
export { matchRunIds };
|
|
@@ -66,7 +66,6 @@ export default function (pi: ExtensionAPI): void {
|
|
|
66
66
|
);
|
|
67
67
|
|
|
68
68
|
pi.on("session_shutdown", async (_event, ctx) => {
|
|
69
|
-
clearActiveRunsStatus(ctx);
|
|
70
69
|
clearActiveRunsWidget(ctx);
|
|
71
70
|
clearCostFooter(ctx);
|
|
72
71
|
await runtime.shutdown();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ferris1225/pi-subagents",
|
|
3
|
-
"version": "4.3.
|
|
3
|
+
"version": "4.3.13",
|
|
4
4
|
"description": "A managed sub-agent team for pi: scout, artisan, steward, and sentinel roles, one-shot runs, read-only status, and Git worktree isolation.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -8,7 +8,6 @@ import { announceRecoveryRecords, relocateRecoveryManifest } from "../isolation/
|
|
|
8
8
|
import type { SubagentRuntime } from "../lifecycle/runtime.ts";
|
|
9
9
|
import { seedCostLedgerFromSession } from "./cost-ledger.ts";
|
|
10
10
|
import { installCostFooter } from "./cost-footer.ts";
|
|
11
|
-
import { installActiveRunsStatus } from "./status.ts";
|
|
12
11
|
import { installActiveRunsWidget } from "./widget.ts";
|
|
13
12
|
|
|
14
13
|
/** Drop unavailable model overrides back to dynamic main-model routing. */
|
|
@@ -52,10 +51,9 @@ export function registerAnnouncements(pi: ExtensionAPI, runtime: SubagentRuntime
|
|
|
52
51
|
"info",
|
|
53
52
|
);
|
|
54
53
|
}
|
|
55
|
-
// The
|
|
56
|
-
// the
|
|
57
|
-
//
|
|
58
|
-
installActiveRunsStatus(ctx);
|
|
54
|
+
// The widget and the per-model cost footer are TUI-only. Seeding first
|
|
55
|
+
// means the first footer render already carries the reloaded session's
|
|
56
|
+
// per-model spend.
|
|
59
57
|
if (ctx.mode !== "tui") return;
|
|
60
58
|
seedCostLedgerFromSession(ctx);
|
|
61
59
|
installActiveRunsWidget(ctx);
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Persistent footer status line for sub-agent progress.
|
|
3
|
-
*
|
|
4
|
-
* The above-editor widget is the detailed surface, but it only pays off when
|
|
5
|
-
* the user is looking at it: a parent turn that dispatches children and then
|
|
6
|
-
* keeps streaming leaves no trace that anything is still running. The footer
|
|
7
|
-
* is always visible, so one compact roll-up there answers "is anything still
|
|
8
|
-
* working?" without opening the widget or querying runs.
|
|
9
|
-
*
|
|
10
|
-
* It stays deliberately count-only — no elapsed time, no per-run detail — so
|
|
11
|
-
* it carries no time-varying field and needs no refresh timer: every monitor
|
|
12
|
-
* transition already pushes an update. Queued runs keep their wait word
|
|
13
|
-
* (`queued` for a process slot vs `repo lane` for write serialization) because
|
|
14
|
-
* a capacity wait and a serialization wait call for different reactions.
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
18
|
-
import { isRunActiveStatus, monitor, statusLabel, type RunView } from "./monitor.ts";
|
|
19
|
-
import { waitWord } from "./widget.ts";
|
|
20
|
-
|
|
21
|
-
export const SUBAGENTS_STATUS_ID = "pi-subagents";
|
|
22
|
-
|
|
23
|
-
const SEPARATOR = " · ";
|
|
24
|
-
|
|
25
|
-
/** Display order of the count segments: live work first, settled last. */
|
|
26
|
-
const SEGMENT_ORDER = ["running", "interrupting", "starting", "queued", "repo lane", "done", "stopped"];
|
|
27
|
-
|
|
28
|
-
type StatusContext = Pick<ExtensionContext, "hasUI" | "ui">;
|
|
29
|
-
|
|
30
|
-
/** One-line roll-up of live runs plus anything that settled during this turn.
|
|
31
|
-
* Returns undefined when nothing is still active — a done-only leftover must
|
|
32
|
-
* not keep the footer up after the last sibling finishes. */
|
|
33
|
-
export function formatRunStatusLine(runs: readonly RunView[]): string | undefined {
|
|
34
|
-
if (!runs.some((run) => isRunActiveStatus(run.status))) return undefined;
|
|
35
|
-
const counts = new Map<string, number>();
|
|
36
|
-
for (const run of runs) {
|
|
37
|
-
const word = run.status === "queued"
|
|
38
|
-
? waitWord(run)
|
|
39
|
-
: isRunActiveStatus(run.status) || run.status === "done" || run.status === "failed"
|
|
40
|
-
? statusLabel(run.status)
|
|
41
|
-
: undefined;
|
|
42
|
-
if (word) counts.set(word, (counts.get(word) ?? 0) + 1);
|
|
43
|
-
}
|
|
44
|
-
const segments = SEGMENT_ORDER.filter((word) => counts.has(word)).map((word) => `${counts.get(word)} ${word}`);
|
|
45
|
-
return segments.length > 0 ? `subagents ${segments.join(SEPARATOR)}` : undefined;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/** Subscription of the currently installed status line; module-level because
|
|
49
|
-
* the monitor it follows is itself a singleton. */
|
|
50
|
-
let unsubscribe: (() => void) | undefined;
|
|
51
|
-
|
|
52
|
-
/** Install the footer status line. Not installed without a UI host (print and
|
|
53
|
-
* json modes), where setStatus has nowhere to render. */
|
|
54
|
-
export function installActiveRunsStatus(ctx: StatusContext): void {
|
|
55
|
-
if (!ctx.hasUI) return;
|
|
56
|
-
// A second install must not orphan the first subscription.
|
|
57
|
-
clearActiveRunsStatus(ctx);
|
|
58
|
-
const render = (): void => ctx.ui.setStatus(SUBAGENTS_STATUS_ID, formatRunStatusLine(monitor.getRuns()));
|
|
59
|
-
unsubscribe = monitor.subscribe(render);
|
|
60
|
-
render();
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export function clearActiveRunsStatus(ctx: StatusContext): void {
|
|
64
|
-
unsubscribe?.();
|
|
65
|
-
unsubscribe = undefined;
|
|
66
|
-
if (ctx.hasUI) ctx.ui.setStatus(SUBAGENTS_STATUS_ID, undefined);
|
|
67
|
-
}
|