@narumitw/pi-subagents 3.4.1 → 3.4.3
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 +147 -0
- package/README.md +17 -11
- package/dist/chunks/{settings-ui-24GHO6E2.ts → settings-ui-KOX3DMZP.ts} +4 -1
- package/dist/chunks/{settings-ui-24GHO6E2.ts.map → settings-ui-KOX3DMZP.ts.map} +2 -2
- package/dist/index.ts +48 -20
- package/dist/index.ts.map +2 -2
- package/package.json +8 -7
- package/src/message-renderers.ts +4 -10
- package/src/settings-ui.ts +3 -0
- package/src/tools.ts +10 -6
- package/src/widget-renderer.ts +33 -2
- package/src/widget.ts +7 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@narumitw/pi-subagents",
|
|
3
|
-
"version": "3.4.
|
|
3
|
+
"version": "3.4.3",
|
|
4
4
|
"description": "Subagent jobs with asynchronous main-agent messaging for Pi.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
"dist",
|
|
19
19
|
"docs",
|
|
20
20
|
"README.md",
|
|
21
|
+
"CHANGELOG.md",
|
|
21
22
|
"LICENSE"
|
|
22
23
|
],
|
|
23
24
|
"pi": {
|
|
@@ -39,12 +40,12 @@
|
|
|
39
40
|
"typebox": "*"
|
|
40
41
|
},
|
|
41
42
|
"devDependencies": {
|
|
42
|
-
"@earendil-works/pi-ai": "1.
|
|
43
|
-
"@earendil-works/pi-coding-agent": "1.
|
|
44
|
-
"@earendil-works/pi-tui": "1.
|
|
45
|
-
"@types/node": "26.6.
|
|
43
|
+
"@earendil-works/pi-ai": "1.5.0",
|
|
44
|
+
"@earendil-works/pi-coding-agent": "1.5.0",
|
|
45
|
+
"@earendil-works/pi-tui": "1.5.0",
|
|
46
|
+
"@types/node": "26.6.6",
|
|
46
47
|
"esbuild": "0.28.2",
|
|
47
|
-
"typebox": "1.4.
|
|
48
|
+
"typebox": "1.4.4",
|
|
48
49
|
"typescript": "7.0.2"
|
|
49
50
|
},
|
|
50
51
|
"repository": {
|
|
@@ -53,7 +54,7 @@
|
|
|
53
54
|
"directory": "packages/pi-subagents"
|
|
54
55
|
},
|
|
55
56
|
"dependencies": {
|
|
56
|
-
"@narumitw/pi-tui-kit": "^0.
|
|
57
|
+
"@narumitw/pi-tui-kit": "^0.70.0",
|
|
57
58
|
"ignore": "^7.0.14"
|
|
58
59
|
}
|
|
59
60
|
}
|
package/src/message-renderers.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ExtensionAPI, getMarkdownTheme
|
|
1
|
+
import { type ExtensionAPI, getMarkdownTheme } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import { Box, type Component, Markdown, Spacer, Text } from "@earendil-works/pi-tui";
|
|
3
3
|
import { sanitizeTerminalText } from "./message-broker.js";
|
|
4
4
|
|
|
@@ -31,15 +31,9 @@ export function registerMessageRenderers(pi: ExtensionAPI): void {
|
|
|
31
31
|
new Spacer(1),
|
|
32
32
|
];
|
|
33
33
|
if (!options.expanded) {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
theme.fg("dim", keyText("app.tools.expand")) +
|
|
38
|
-
theme.fg("customMessageText", " to expand)"),
|
|
39
|
-
0,
|
|
40
|
-
0,
|
|
41
|
-
),
|
|
42
|
-
);
|
|
34
|
+
const expansionKey = options.keyText?.("app.tools.expand");
|
|
35
|
+
const hint = expansionKey ? theme.fg("muted", ` (${expansionKey} to expand)`) : "";
|
|
36
|
+
children.push(new Text(theme.fg("customMessageText", summary) + hint, 0, 0));
|
|
43
37
|
} else {
|
|
44
38
|
const content =
|
|
45
39
|
typeof message.content === "string"
|
package/src/settings-ui.ts
CHANGED
|
@@ -127,6 +127,9 @@ export async function showSubagentSettings(
|
|
|
127
127
|
() => complete("back"),
|
|
128
128
|
);
|
|
129
129
|
return {
|
|
130
|
+
get capturesViewportInput() {
|
|
131
|
+
return list.capturesViewportInput;
|
|
132
|
+
},
|
|
130
133
|
render(width: number) {
|
|
131
134
|
if (!current()) complete("stale");
|
|
132
135
|
renderedWidth = Number.isFinite(width) ? Math.max(0, Math.floor(width)) : 0;
|
package/src/tools.ts
CHANGED
|
@@ -60,9 +60,11 @@ const SpawnParameters = Type.Object(
|
|
|
60
60
|
),
|
|
61
61
|
tools: Type.Optional(
|
|
62
62
|
Type.Array(
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
Type.Unsafe<(typeof CHILD_CORE_TOOL_NAMES)[number]>(
|
|
64
|
+
StringEnum(CHILD_CORE_TOOL_NAMES, {
|
|
65
|
+
description: "Available Pi core child work tool name.",
|
|
66
|
+
}),
|
|
67
|
+
),
|
|
66
68
|
{
|
|
67
69
|
description: "Child work tools. Defaults to read, grep, find, and ls. Communication tools are always added.",
|
|
68
70
|
maxItems: MAX_TOOLS,
|
|
@@ -114,9 +116,11 @@ const SpawnParameters = Type.Object(
|
|
|
114
116
|
),
|
|
115
117
|
),
|
|
116
118
|
thinkingLevel: Type.Optional(
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
119
|
+
Type.Unsafe<SubagentThinkingLevel>(
|
|
120
|
+
StringEnum(SUBAGENT_THINKING_LEVELS, {
|
|
121
|
+
description: "Child thinking level. Defaults to the main agent's effective level.",
|
|
122
|
+
}),
|
|
123
|
+
),
|
|
120
124
|
),
|
|
121
125
|
timeout: Type.Optional(Type.Number({ description: "Timeout in seconds (optional, no default timeout)" })),
|
|
122
126
|
},
|
package/src/widget-renderer.ts
CHANGED
|
@@ -25,15 +25,46 @@ export function subagentWidgetRowBudget(rows: number): number {
|
|
|
25
25
|
: 0;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
+
export function subagentWidgetSummary(snapshot: SubagentWidgetSnapshot, maxRows: number): string {
|
|
29
|
+
const { jobs, items, mode } = snapshot;
|
|
30
|
+
const budget = normalizeRowBudget(maxRows);
|
|
31
|
+
if (!isVisible(snapshot) || budget === 0) return "";
|
|
32
|
+
// Compact mode intentionally has no job rows; only removed jobs are omitted.
|
|
33
|
+
const shown = mode === "compact" ? items.length : Math.min(items.length, budget - 1);
|
|
34
|
+
const omitted = jobs.length - shown;
|
|
35
|
+
const removed = jobs.length - items.length;
|
|
36
|
+
const running = jobs.filter((job) => job.state === "running").length;
|
|
37
|
+
const counts = `${running} running · ${jobs.length - running} queued`;
|
|
38
|
+
return `${counts}${omitted > 0 ? ` · ${omitted} not shown${removed > 0 ? ` (${removed} removed)` : ""}` : ""}`;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function normalizeRowBudget(maxRows: number): number {
|
|
42
|
+
return Number.isFinite(maxRows) ? Math.max(0, Math.floor(maxRows)) : 0;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function isVisible({ jobs, items, settings, mode }: SubagentWidgetSnapshot): boolean {
|
|
46
|
+
return settings.showWidget && mode !== "hidden" && jobs.length > 0 && items.length > 0;
|
|
47
|
+
}
|
|
48
|
+
|
|
28
49
|
export function renderSubagentWidgetSnapshot(
|
|
29
50
|
snapshot: SubagentWidgetSnapshot,
|
|
30
51
|
theme: Theme,
|
|
31
52
|
width: number,
|
|
32
53
|
maxRows: number,
|
|
54
|
+
includeHeader = true,
|
|
33
55
|
): string[] {
|
|
34
56
|
const { jobs, items, settings, mode } = snapshot;
|
|
35
|
-
const budget =
|
|
36
|
-
if (!
|
|
57
|
+
const budget = normalizeRowBudget(maxRows);
|
|
58
|
+
if (!isVisible(snapshot) || budget < (includeHeader ? 2 : 1)) return [];
|
|
59
|
+
// Named TUI publishers put the counts in the divider, not in a body heading.
|
|
60
|
+
if (!includeHeader) {
|
|
61
|
+
const shown = mode === "compact" ? [] : items.slice(0, budget - 1);
|
|
62
|
+
return new EditorStatusWidget({
|
|
63
|
+
theme,
|
|
64
|
+
renderBody: () =>
|
|
65
|
+
shown.map(({ value, mode: itemMode }) => renderJob(value, theme, settings, itemMode === "compact")),
|
|
66
|
+
}).render(width);
|
|
67
|
+
}
|
|
37
68
|
const running = jobs.filter((job) => job.state === "running").length;
|
|
38
69
|
const counts = `Subagents · ${jobs.length} active · ${running} running · ${jobs.length - running} queued`;
|
|
39
70
|
const removed = jobs.length - items.length;
|
package/src/widget.ts
CHANGED
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
renderSubagentWidgetSnapshot,
|
|
18
18
|
type SubagentWidgetSnapshot,
|
|
19
19
|
subagentWidgetRowBudget,
|
|
20
|
+
subagentWidgetSummary,
|
|
20
21
|
} from "./widget-renderer.js";
|
|
21
22
|
|
|
22
23
|
export { renderSubagentWidget } from "./widget-renderer.js";
|
|
@@ -175,10 +176,12 @@ export function createSubagentWidgetController(runtime: SubagentRuntime): Subage
|
|
|
175
176
|
view = createEditorStatusView({ onChange: publish, canCompact: () => settings.showWidget && jobs.length > 0 });
|
|
176
177
|
publisher = createEditorStatusPublisher({
|
|
177
178
|
key: SUBAGENT_WIDGET_KEY,
|
|
179
|
+
name: "Subagents",
|
|
178
180
|
context: ctx,
|
|
179
181
|
isCurrent,
|
|
182
|
+
summary: (snapshot, _width, rows) => subagentWidgetSummary(snapshot, subagentWidgetRowBudget(rows)),
|
|
180
183
|
render: (snapshot, theme, width, rows) =>
|
|
181
|
-
renderSubagentWidgetSnapshot(snapshot, theme, width, subagentWidgetRowBudget(rows)),
|
|
184
|
+
renderSubagentWidgetSnapshot(snapshot, theme, width, subagentWidgetRowBudget(rows), false),
|
|
182
185
|
});
|
|
183
186
|
// The owner records public preparation/run hooks while settings load.
|
|
184
187
|
// General busy state also includes navigation and manual compaction.
|
|
@@ -189,7 +192,9 @@ export function createSubagentWidgetController(runtime: SubagentRuntime): Subage
|
|
|
189
192
|
controls = {
|
|
190
193
|
state: () => ({ mode: ownedView.mode, pinned: ownedView.pinned, trigger: ownedView.trigger }),
|
|
191
194
|
setMode: (mode) => {
|
|
192
|
-
if (isCurrent())
|
|
195
|
+
if (!isCurrent()) return;
|
|
196
|
+
if (mode !== "hidden") publisher?.setCollapsed(false);
|
|
197
|
+
ownedView.setMode(mode);
|
|
193
198
|
},
|
|
194
199
|
setPinned: (pinned) => {
|
|
195
200
|
if (isCurrent()) ownedView.setPinned(pinned);
|