@hheei/pi-subagents 0.2.4 → 0.4.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 +35 -20
- package/dist/agent-resolver.d.ts +9 -0
- package/dist/agent-resolver.js +278 -51
- package/dist/builtin-agents.js +50 -37
- package/dist/child-bridge.d.ts +0 -8
- package/dist/child-bridge.js +60 -43
- package/dist/child-control.d.ts +6 -4
- package/dist/child-control.js +251 -47
- package/dist/child-process.d.ts +2 -0
- package/dist/child-process.js +24 -12
- package/dist/commands.d.ts +1 -4
- package/dist/commands.js +1 -52
- package/dist/domain.d.ts +27 -12
- package/dist/domain.js +2 -1
- package/dist/extension.d.ts +7 -6
- package/dist/extension.js +96 -112
- package/dist/host-adapter.d.ts +19 -0
- package/dist/host-adapter.js +140 -1
- package/dist/info.d.ts +9 -0
- package/dist/info.js +80 -0
- package/dist/launch-spec.d.ts +0 -1
- package/dist/launch-spec.js +38 -18
- package/dist/lease.d.ts +83 -0
- package/dist/lease.js +239 -0
- package/dist/mailbox.d.ts +46 -0
- package/dist/mailbox.js +368 -0
- package/dist/manager.d.ts +20 -20
- package/dist/manager.js +421 -398
- package/dist/process-lock.d.ts +11 -0
- package/dist/process-lock.js +55 -0
- package/dist/protocol.d.ts +2 -2
- package/dist/protocol.js +1 -0
- package/dist/registry.d.ts +1 -1
- package/dist/registry.js +99 -82
- package/dist/rpc-events.d.ts +1 -1
- package/dist/rpc-events.js +2 -1
- package/dist/runtime.d.ts +8 -21
- package/dist/runtime.js +61 -83
- package/dist/session-bootstrap.d.ts +2 -1
- package/dist/session-bootstrap.js +22 -14
- package/dist/state-db.d.ts +52 -0
- package/dist/state-db.js +209 -0
- package/dist/state.d.ts +25 -0
- package/dist/state.js +166 -37
- package/dist/status.d.ts +14 -0
- package/dist/status.js +36 -0
- package/dist/tool-activation.d.ts +3 -4
- package/dist/tool-activation.js +13 -215
- package/dist/tool-presentation.d.ts +14 -0
- package/dist/tool-presentation.js +193 -0
- package/dist/tools.d.ts +6 -1
- package/dist/tools.js +134 -180
- package/package.json +6 -6
- package/dist/bridge-client.d.ts +0 -55
- package/dist/bridge-client.js +0 -453
- package/dist/bridge-server.d.ts +0 -72
- package/dist/bridge-server.js +0 -490
- package/dist/session-fork.d.ts +0 -16
- package/dist/session-fork.js +0 -67
- package/dist/widget.d.ts +0 -12
- package/dist/widget.js +0 -149
package/dist/widget.js
DELETED
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
import { truncateToWidth } from "@earendil-works/pi-tui";
|
|
2
|
-
import { registerWidget } from "@hheei/pi-ext-core";
|
|
3
|
-
import { toVisualSubagentState, VISUAL_SUBAGENT_GLYPH, VISUAL_SUBAGENT_TONE, } from "./domain.js";
|
|
4
|
-
const WIDGET_ID = "@hheei/pi-subagents:status";
|
|
5
|
-
const MAX_ROWS = 8;
|
|
6
|
-
const ELAPSED_TICK_MS = 1_000;
|
|
7
|
-
export const SUBAGENT_TERMINAL_DISPLAY_DURATION_MS = 15_000;
|
|
8
|
-
export function isTerminalState(state) {
|
|
9
|
-
return state === "done" || state === "blocked" || state === "error";
|
|
10
|
-
}
|
|
11
|
-
export function isWidgetVisibleChild(child, nowMs = Date.now()) {
|
|
12
|
-
const visual = toVisualSubagentState(child.state, child.interrupted);
|
|
13
|
-
if (visual === "running") {
|
|
14
|
-
return true;
|
|
15
|
-
}
|
|
16
|
-
const updated = Date.parse(child.updatedAt);
|
|
17
|
-
if (!Number.isNaN(updated) && nowMs - updated < SUBAGENT_TERMINAL_DISPLAY_DURATION_MS) {
|
|
18
|
-
return true;
|
|
19
|
-
}
|
|
20
|
-
return false;
|
|
21
|
-
}
|
|
22
|
-
function visibleChildren(children, nowMs = Date.now()) {
|
|
23
|
-
return children.filter((c) => isWidgetVisibleChild(c, nowMs));
|
|
24
|
-
}
|
|
25
|
-
export function formatElapsed(fromIso, nowMs = Date.now()) {
|
|
26
|
-
const from = Date.parse(fromIso);
|
|
27
|
-
if (Number.isNaN(from))
|
|
28
|
-
return "";
|
|
29
|
-
const totalSeconds = Math.max(0, Math.floor((nowMs - from) / 1000));
|
|
30
|
-
if (totalSeconds < 60)
|
|
31
|
-
return `${totalSeconds}s`;
|
|
32
|
-
const hours = Math.floor(totalSeconds / 3600);
|
|
33
|
-
const minutes = Math.floor((totalSeconds % 3600) / 60);
|
|
34
|
-
const seconds = totalSeconds % 60;
|
|
35
|
-
if (hours > 0)
|
|
36
|
-
return `${hours}h ${minutes}m`;
|
|
37
|
-
return `${minutes}m ${seconds}s`;
|
|
38
|
-
}
|
|
39
|
-
export function renderSubagentWidget(children, width, theme, nowMs = Date.now()) {
|
|
40
|
-
const visible = visibleChildren(children, nowMs);
|
|
41
|
-
if (visible.length === 0)
|
|
42
|
-
return [];
|
|
43
|
-
const heading = `🤖 ${theme.fg("text", "Agents:")}`;
|
|
44
|
-
const lines = [truncateToWidth(heading, width, theme.fg("dim", "…"))];
|
|
45
|
-
const rows = visible.slice(0, MAX_ROWS);
|
|
46
|
-
const sep = theme.fg("dim", " · ");
|
|
47
|
-
for (let index = 0; index < rows.length; index++) {
|
|
48
|
-
const child = rows[index];
|
|
49
|
-
if (child === undefined)
|
|
50
|
-
continue;
|
|
51
|
-
const visual = toVisualSubagentState(child.state, child.interrupted);
|
|
52
|
-
const glyph = VISUAL_SUBAGENT_GLYPH[visual];
|
|
53
|
-
const tone = VISUAL_SUBAGENT_TONE[visual];
|
|
54
|
-
const glyphStyled = theme.fg(tone, glyph);
|
|
55
|
-
const idStyled = theme.fg("dim", `#${child.id}`);
|
|
56
|
-
const nameStyled = theme.fg("text", child.displayName ?? child.agent);
|
|
57
|
-
const elapsed = formatElapsed(child.createdAt, isTerminalState(child.state) ? Date.parse(child.updatedAt) : nowMs);
|
|
58
|
-
const timeStyled = theme.fg("dim", elapsed === "" ? "0s" : elapsed);
|
|
59
|
-
const stateStyled = theme.fg(tone, visual);
|
|
60
|
-
const turnsCount = child.usage?.turns ?? 0;
|
|
61
|
-
const turnsLabel = `${turnsCount} turn${turnsCount === 1 ? "" : "s"}`;
|
|
62
|
-
const turnsStyled = theme.fg("dim", turnsLabel);
|
|
63
|
-
let detailText = "";
|
|
64
|
-
if (child.activeTool !== undefined && child.activeTool.trim() !== "") {
|
|
65
|
-
detailText = child.activeTool.trim();
|
|
66
|
-
}
|
|
67
|
-
else if (child.summary !== undefined && child.summary.trim() !== "") {
|
|
68
|
-
detailText = child.summary.replace(/\s+/g, " ").trim();
|
|
69
|
-
}
|
|
70
|
-
const detailStyled = detailText === "" ? "" : `${sep}${theme.fg("dim", detailText)}`;
|
|
71
|
-
const rowContent = `${glyphStyled} ${idStyled} ${nameStyled}${sep}${timeStyled}${sep}${stateStyled}${sep}${turnsStyled}${detailStyled}`;
|
|
72
|
-
lines.push(truncateToWidth(rowContent, width, theme.fg("dim", "…")));
|
|
73
|
-
}
|
|
74
|
-
if (visible.length > MAX_ROWS) {
|
|
75
|
-
lines.push(truncateToWidth(theme.fg("dim", `+${visible.length - MAX_ROWS} more`), width, theme.fg("dim", "…")));
|
|
76
|
-
}
|
|
77
|
-
lines.push("");
|
|
78
|
-
return lines;
|
|
79
|
-
}
|
|
80
|
-
export function createSubagentWidget(pi, context, signal, initial = []) {
|
|
81
|
-
if (context.mode !== "tui")
|
|
82
|
-
return undefined;
|
|
83
|
-
let children = initial;
|
|
84
|
-
let disposed = false;
|
|
85
|
-
let tick;
|
|
86
|
-
const hasRows = () => visibleChildren(children).length > 0;
|
|
87
|
-
const widget = registerWidget(pi, context, signal, {
|
|
88
|
-
id: WIDGET_ID,
|
|
89
|
-
placement: "aboveEditor",
|
|
90
|
-
visible: hasRows(),
|
|
91
|
-
create: (_tui, theme) => ({
|
|
92
|
-
render: (width) => renderSubagentWidget(children, width, theme),
|
|
93
|
-
invalidate: () => undefined,
|
|
94
|
-
dispose: () => undefined,
|
|
95
|
-
}),
|
|
96
|
-
});
|
|
97
|
-
const stopTick = () => {
|
|
98
|
-
if (tick === undefined)
|
|
99
|
-
return;
|
|
100
|
-
clearInterval(tick);
|
|
101
|
-
tick = undefined;
|
|
102
|
-
};
|
|
103
|
-
const syncTick = () => {
|
|
104
|
-
if (disposed || !hasRows()) {
|
|
105
|
-
stopTick();
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
// 仅在有进行中任务或待淡出任务时维持 tick,纯 idle 时静默
|
|
109
|
-
const hasActiveOrExpiring = children.some((child) => isWidgetVisibleChild(child));
|
|
110
|
-
if (!hasActiveOrExpiring) {
|
|
111
|
-
stopTick();
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
if (tick !== undefined)
|
|
115
|
-
return;
|
|
116
|
-
tick = setInterval(() => {
|
|
117
|
-
if (!hasRows()) {
|
|
118
|
-
widget.setVisible(false);
|
|
119
|
-
stopTick();
|
|
120
|
-
}
|
|
121
|
-
else {
|
|
122
|
-
widget.requestRender();
|
|
123
|
-
}
|
|
124
|
-
}, ELAPSED_TICK_MS);
|
|
125
|
-
};
|
|
126
|
-
syncTick();
|
|
127
|
-
signal.addEventListener("abort", stopTick, { once: true });
|
|
128
|
-
return {
|
|
129
|
-
refresh(next) {
|
|
130
|
-
if (disposed)
|
|
131
|
-
return;
|
|
132
|
-
children = next;
|
|
133
|
-
if (!hasRows())
|
|
134
|
-
widget.setVisible(false);
|
|
135
|
-
else {
|
|
136
|
-
widget.setVisible(true);
|
|
137
|
-
widget.requestRender();
|
|
138
|
-
}
|
|
139
|
-
syncTick();
|
|
140
|
-
},
|
|
141
|
-
dispose() {
|
|
142
|
-
if (disposed)
|
|
143
|
-
return;
|
|
144
|
-
disposed = true;
|
|
145
|
-
stopTick();
|
|
146
|
-
widget.dispose();
|
|
147
|
-
},
|
|
148
|
-
};
|
|
149
|
-
}
|