pantheon-opencode 1.5.0 → 1.5.1
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 +22 -0
- package/README.md +63 -2
- package/package.json +2 -2
- package/plugin.json +1 -1
- package/pyproject.toml +2 -1
- package/scripts/doctor.mjs +228 -2
- package/src/agents/mnemosyne.md +11 -1
- package/src/agents/zeus.md +1 -0
- package/src/mcp/memory_mcp_server.py +81 -27
- package/src/plugins/pantheon-hooks.ts +1 -1
- package/src/plugins/tui/dist/tui.d.ts +19 -24
- package/src/plugins/tui/dist/tui.d.ts.map +1 -1
- package/src/plugins/tui/dist/tui.js +22 -81
- package/src/plugins/tui/package-lock.json +5 -2
- package/src/plugins/tui/package.json +4 -1
- package/src/plugins/tui/src/index.tsx +54 -151
- package/src/mcp/toon_codec.py +0 -489
|
@@ -181,7 +181,7 @@ import { getSharedBoard } from '../pantheon/shared-board.ts'
|
|
|
181
181
|
import { type HookPayload, type HookResult, runHook } from './hook-runner.ts'
|
|
182
182
|
|
|
183
183
|
/** Tools that represent a subagent delegation (opencode `task` tool etc.). */
|
|
184
|
-
const DELEGATION_TOOL_RE = /^(task|.*
|
|
184
|
+
const DELEGATION_TOOL_RE = /^(task|.*subagent.*)$/i
|
|
185
185
|
|
|
186
186
|
/**
|
|
187
187
|
* When set to a truthy value ("1" or "debug"), zero-exit audit-hook output is
|
|
@@ -18,8 +18,6 @@ type DelegationEntry = {
|
|
|
18
18
|
updatedAt: number | null;
|
|
19
19
|
timedOut: boolean;
|
|
20
20
|
description: string;
|
|
21
|
-
/** True while the panel is waiting for pantheon_delegation_read. */
|
|
22
|
-
read?: boolean;
|
|
23
21
|
/** Internal provenance used to keep a finalized md report authoritative.
|
|
24
22
|
* 'children-only' = a native task() child session with NO delegate report
|
|
25
23
|
* (a native child row); 'md' = the child has a matching report;
|
|
@@ -145,7 +143,7 @@ declare function fmtElapsed(ms: number): string;
|
|
|
145
143
|
declare function delegationElapsed(entry: DelegationEntry, now: number): string;
|
|
146
144
|
/** The activity labels shown by the animated row. Keeping this pure makes the
|
|
147
145
|
* state machine testable without booting OpenCode's renderer. */
|
|
148
|
-
type DelegationActivity = 'delegating' | 'working' | '
|
|
146
|
+
type DelegationActivity = 'delegating' | 'working' | 'completed' | 'error' | 'cancelled';
|
|
149
147
|
declare function delegationActivity(entry: DelegationEntry): DelegationActivity;
|
|
150
148
|
declare function delegationActivityLabel(entry: DelegationEntry): string;
|
|
151
149
|
/** Return the spinner glyph for the given frame counter. The frame counter
|
|
@@ -217,36 +215,34 @@ type DelegationToolPart = {
|
|
|
217
215
|
};
|
|
218
216
|
};
|
|
219
217
|
};
|
|
220
|
-
/** One live delegation tracked in-memory, keyed by the
|
|
218
|
+
/** One live delegation tracked in-memory, keyed by the task callID. */
|
|
221
219
|
type LiveDelegationEntry = {
|
|
222
|
-
/** Tool call id of the
|
|
220
|
+
/** Tool call id of the task part (stable across events). */
|
|
223
221
|
callID: string;
|
|
224
222
|
/** Part id (for message.part.removed cleanup). */
|
|
225
223
|
partID: string;
|
|
226
224
|
/** Parent session the delegation was launched from. */
|
|
227
225
|
sessionID: string;
|
|
228
|
-
tool: '
|
|
229
|
-
/** Agent name (from the
|
|
226
|
+
tool: 'task';
|
|
227
|
+
/** Agent name (from the task input args). */
|
|
230
228
|
agent: string;
|
|
231
229
|
description: string;
|
|
232
|
-
/** Known
|
|
230
|
+
/** Known once the task completes and its output carries a marker. */
|
|
233
231
|
alias: string | null;
|
|
234
|
-
/** Child session id (parsed from the
|
|
232
|
+
/** Child session id (parsed from the task output, when present). */
|
|
235
233
|
taskID: string | null;
|
|
236
234
|
state: 'running' | 'completed' | 'error' | 'cancelled';
|
|
237
235
|
startedAt: number;
|
|
238
236
|
updatedAt: number | null;
|
|
239
|
-
/** True once a pantheon_delegation_read for this job has been observed. */
|
|
240
|
-
read: boolean;
|
|
241
237
|
};
|
|
242
238
|
/** Result of parsing one tool part into lifecycle-relevant fields. */
|
|
243
239
|
type ParsedDelegationToolPart = {
|
|
244
240
|
callID: string;
|
|
245
241
|
partID: string;
|
|
246
242
|
sessionID: string;
|
|
247
|
-
tool: '
|
|
248
|
-
/**
|
|
249
|
-
agent: string
|
|
243
|
+
tool: 'task';
|
|
244
|
+
/** Agent name from the task input args ('agent' fallback when absent). */
|
|
245
|
+
agent: string;
|
|
250
246
|
description: string;
|
|
251
247
|
status: 'pending' | 'running' | 'completed' | 'error';
|
|
252
248
|
alias: string | null;
|
|
@@ -256,9 +252,8 @@ type ParsedDelegationToolPart = {
|
|
|
256
252
|
};
|
|
257
253
|
/** Extract the tool name + args from a `message.part.updated` part and
|
|
258
254
|
* reduce it to what the panel needs. Returns null for anything that is
|
|
259
|
-
* not
|
|
260
|
-
*
|
|
261
|
-
* or is missing its callID. */
|
|
255
|
+
* not the native `task` subagent tool (parentID === caller mechanism —
|
|
256
|
+
* its children render `nat:`), or is missing its callID. */
|
|
262
257
|
declare function parseDelegationToolPart(part: DelegationToolPart, now?: number): ParsedDelegationToolPart | null;
|
|
263
258
|
/** Apply one tool part to the live map. Returns true when the map changed.
|
|
264
259
|
* Pure w.r.t. I/O — only mutates `map`. */
|
|
@@ -266,14 +261,14 @@ declare function reduceDelegationToolPart(map: Map<string, LiveDelegationEntry>,
|
|
|
266
261
|
/** Remove a live entry by part id (message.part.removed) or call id.
|
|
267
262
|
* Returns true when something was removed. */
|
|
268
263
|
declare function removeDelegationEntry(map: Map<string, LiveDelegationEntry>, partIDOrCallID: string): boolean;
|
|
269
|
-
/** Collect
|
|
264
|
+
/** Collect native task tool parts from a session's messages.
|
|
270
265
|
* Messages may carry their parts inline (duck-typed `msg.parts`); when
|
|
271
266
|
* they don't, the optional `getParts(messageID)` callback is used (the TUI
|
|
272
267
|
* SDK exposes `api.state.part(messageID)`). The native `task` tool spawns a
|
|
273
|
-
* child session with parentID = caller
|
|
274
|
-
*
|
|
275
|
-
*
|
|
276
|
-
*
|
|
268
|
+
* child session with parentID = caller, so its parts feed the live-map as
|
|
269
|
+
* the refresh signal (rows come from the children channel). Pure w.r.t.
|
|
270
|
+
* I/O — used by the mount re-scan to re-seed the live map after
|
|
271
|
+
* compaction/attach. */
|
|
277
272
|
declare function collectDelegationToolParts(messages: readonly {
|
|
278
273
|
id?: string;
|
|
279
274
|
parts?: unknown[];
|
|
@@ -284,7 +279,7 @@ declare function collectDelegationToolParts(messages: readonly {
|
|
|
284
279
|
* the map (0 on the second identical seed — idempotent, no extra bumps). */
|
|
285
280
|
declare function seedLiveDelegationMap(map: Map<string, LiveDelegationEntry>, parts: readonly DelegationToolPart[], now?: number): number;
|
|
286
281
|
/** Convert a live entry into the shared display shape. Alias falls back to
|
|
287
|
-
* a `live-<callID>` prefix while the
|
|
282
|
+
* a `live-<callID>` prefix while the task call has not completed yet. */
|
|
288
283
|
declare function toDelegationEntry(live: LiveDelegationEntry): DelegationEntry;
|
|
289
284
|
/** Combine the live channel with the md (historical) channel into one
|
|
290
285
|
* display list. Dedupes by (sessionID, alias) — aliases are per-parent-
|
|
@@ -467,7 +462,7 @@ declare function ceilingDelegationList(all: readonly DelegationEntry[], maxVisib
|
|
|
467
462
|
hiddenActive: number;
|
|
468
463
|
hiddenTerminal: number;
|
|
469
464
|
};
|
|
470
|
-
/** Split a display list into native task() rows vs
|
|
465
|
+
/** Split a display list into native task() rows vs pantheon report rows.
|
|
471
466
|
* Native = source 'children-only' (no delegate report); everything else counts
|
|
472
467
|
* as pantheon. Pure — powers the hooks.log line. */
|
|
473
468
|
declare function countDelegationSources(entries: readonly DelegationEntry[]): {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tui.d.ts","names":[],"sources":["../src/index.tsx"],"mappings":";;KA07BY;;EAEV;;EAEA;;;;EAIA;;EAEA;EACA;;EAUA;;EAEA;EACA;EACA
|
|
1
|
+
{"version":3,"file":"tui.d.ts","names":[],"sources":["../src/index.tsx"],"mappings":"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"}
|
|
@@ -165,7 +165,7 @@ async function detectVersion(api) {
|
|
|
165
165
|
if (ver) return ver;
|
|
166
166
|
}
|
|
167
167
|
} catch {}
|
|
168
|
-
return "1.5.
|
|
168
|
+
return "1.5.1";
|
|
169
169
|
}
|
|
170
170
|
/**
|
|
171
171
|
* usage-bar — AI subscription usage gauge for the opencode TUI.
|
|
@@ -980,7 +980,6 @@ function delegationActivity(entry) {
|
|
|
980
980
|
if (entry.state === "completed") return "completed";
|
|
981
981
|
if (entry.state === "error" || entry.state === "startup_failed" || entry.state === "startup_unknown") return "error";
|
|
982
982
|
if (entry.state === "cancelled") return "cancelled";
|
|
983
|
-
if (entry.read) return "reading";
|
|
984
983
|
if (entry.alias.startsWith("live-") && entry.taskID === void 0) return "delegating";
|
|
985
984
|
return "working";
|
|
986
985
|
}
|
|
@@ -989,7 +988,6 @@ function delegationActivityLabel(entry) {
|
|
|
989
988
|
switch (delegationActivity(entry)) {
|
|
990
989
|
case "delegating": return "DELEGATING";
|
|
991
990
|
case "working": return "WORKING";
|
|
992
|
-
case "reading": return "READING RESULT";
|
|
993
991
|
case "completed": return entry.timedOut ? "DONE (TIMED OUT)" : "DONE";
|
|
994
992
|
case "error": return "ERROR";
|
|
995
993
|
default: return "CANCELLED";
|
|
@@ -1129,7 +1127,6 @@ function mergeChildDelegationSources(children, live) {
|
|
|
1129
1127
|
if (existing.state !== "running") {
|
|
1130
1128
|
if (liveEntry.alias !== null && existing.alias !== incoming.alias) existing.alias = incoming.alias;
|
|
1131
1129
|
if (incoming.agent !== "agent" && existing.agent !== incoming.agent) existing.agent = incoming.agent;
|
|
1132
|
-
if (incoming.read && !existing.read) existing.read = true;
|
|
1133
1130
|
continue;
|
|
1134
1131
|
}
|
|
1135
1132
|
result[index] = {
|
|
@@ -1142,7 +1139,6 @@ function mergeChildDelegationSources(children, live) {
|
|
|
1142
1139
|
state: incoming.state,
|
|
1143
1140
|
startedAt: Math.min(existing.startedAt, incoming.startedAt),
|
|
1144
1141
|
updatedAt: incoming.updatedAt,
|
|
1145
|
-
read: incoming.read,
|
|
1146
1142
|
source: isNativeLive ? existing.source : "live"
|
|
1147
1143
|
};
|
|
1148
1144
|
}
|
|
@@ -1150,22 +1146,19 @@ function mergeChildDelegationSources(children, live) {
|
|
|
1150
1146
|
return result;
|
|
1151
1147
|
}
|
|
1152
1148
|
/** Duck-typed subset of a tool part (SDK v2 `ToolPart` / `ToolState`). */
|
|
1153
|
-
/** One live delegation tracked in-memory, keyed by the
|
|
1149
|
+
/** One live delegation tracked in-memory, keyed by the task callID. */
|
|
1154
1150
|
/** Result of parsing one tool part into lifecycle-relevant fields. */
|
|
1155
|
-
/** Alias in the
|
|
1151
|
+
/** Alias in the task output: "Delegated to apollo: [apo-1] (task …)". */
|
|
1156
1152
|
const DELEGATE_ALIAS_PATTERN = /\[([a-z]{2,8}-\d+)\]/i;
|
|
1157
|
-
/** Child task id in the
|
|
1153
|
+
/** Child task id in the task output: "(task ses_child_9)". */
|
|
1158
1154
|
const DELEGATE_TASKID_PATTERN = /\(task\s+([a-z0-9_]+)\)/i;
|
|
1159
|
-
/** Plain alias, as passed to pantheon_delegation_read input.id: "apo-1". */
|
|
1160
|
-
const READ_ALIAS_PATTERN = /^[a-z]{2,8}-\d+$/i;
|
|
1161
1155
|
/** Extract the tool name + args from a `message.part.updated` part and
|
|
1162
1156
|
* reduce it to what the panel needs. Returns null for anything that is
|
|
1163
|
-
* not
|
|
1164
|
-
*
|
|
1165
|
-
* or is missing its callID. */
|
|
1157
|
+
* not the native `task` subagent tool (parentID === caller mechanism —
|
|
1158
|
+
* its children render `nat:`), or is missing its callID. */
|
|
1166
1159
|
function parseDelegationToolPart(part, now = Date.now()) {
|
|
1167
1160
|
if (part.type !== "tool") return null;
|
|
1168
|
-
if (part.tool !== "
|
|
1161
|
+
if (part.tool !== "task") return null;
|
|
1169
1162
|
const callID = part.callID;
|
|
1170
1163
|
if (callID === void 0 || callID === "") return null;
|
|
1171
1164
|
const sessionID = part.sessionID ?? "";
|
|
@@ -1175,28 +1168,6 @@ function parseDelegationToolPart(part, now = Date.now()) {
|
|
|
1175
1168
|
const input = state.input ?? {};
|
|
1176
1169
|
const startedAt = state.time?.start ?? now;
|
|
1177
1170
|
const endAt = state.time?.end ?? null;
|
|
1178
|
-
if (part.tool === "pantheon_delegation_read") {
|
|
1179
|
-
const target = typeof input.id === "string" ? input.id : null;
|
|
1180
|
-
let alias = null;
|
|
1181
|
-
let taskID = null;
|
|
1182
|
-
if (target !== null) {
|
|
1183
|
-
if (READ_ALIAS_PATTERN.test(target)) alias = target;
|
|
1184
|
-
else if (target.startsWith("ses_")) taskID = target;
|
|
1185
|
-
}
|
|
1186
|
-
return {
|
|
1187
|
-
callID,
|
|
1188
|
-
partID: part.id ?? "",
|
|
1189
|
-
sessionID,
|
|
1190
|
-
tool: "pantheon_delegation_read",
|
|
1191
|
-
agent: null,
|
|
1192
|
-
description: "",
|
|
1193
|
-
status,
|
|
1194
|
-
alias,
|
|
1195
|
-
taskID,
|
|
1196
|
-
startedAt,
|
|
1197
|
-
endAt
|
|
1198
|
-
};
|
|
1199
|
-
}
|
|
1200
1171
|
const agent = typeof input.agent === "string" ? input.agent : typeof input.subagent_type === "string" ? input.subagent_type : "agent";
|
|
1201
1172
|
const description = typeof input.description === "string" ? input.description : typeof input.prompt === "string" ? input.prompt.slice(0, 120) : "";
|
|
1202
1173
|
let alias = null;
|
|
@@ -1210,7 +1181,7 @@ function parseDelegationToolPart(part, now = Date.now()) {
|
|
|
1210
1181
|
callID,
|
|
1211
1182
|
partID: part.id ?? "",
|
|
1212
1183
|
sessionID,
|
|
1213
|
-
tool:
|
|
1184
|
+
tool: "task",
|
|
1214
1185
|
agent,
|
|
1215
1186
|
description,
|
|
1216
1187
|
status,
|
|
@@ -1220,38 +1191,11 @@ function parseDelegationToolPart(part, now = Date.now()) {
|
|
|
1220
1191
|
endAt
|
|
1221
1192
|
};
|
|
1222
1193
|
}
|
|
1223
|
-
/** Find a live entry by alias or taskID (read parts resolve by id). */
|
|
1224
|
-
function findLiveByTarget(map, alias, taskID) {
|
|
1225
|
-
if (alias === null && taskID === null) return void 0;
|
|
1226
|
-
for (const entry of map.values()) {
|
|
1227
|
-
if (alias !== null && entry.alias === alias) return entry;
|
|
1228
|
-
if (taskID !== null && entry.taskID === taskID) return entry;
|
|
1229
|
-
}
|
|
1230
|
-
}
|
|
1231
1194
|
/** Apply one tool part to the live map. Returns true when the map changed.
|
|
1232
1195
|
* Pure w.r.t. I/O — only mutates `map`. */
|
|
1233
1196
|
function reduceDelegationToolPart(map, part, now = Date.now()) {
|
|
1234
1197
|
const parsed = parseDelegationToolPart(part, now);
|
|
1235
1198
|
if (parsed === null) return false;
|
|
1236
|
-
if (parsed.tool === "pantheon_delegation_read") {
|
|
1237
|
-
const target = findLiveByTarget(map, parsed.alias, parsed.taskID);
|
|
1238
|
-
if (target === void 0) return false;
|
|
1239
|
-
let changed = false;
|
|
1240
|
-
if (!target.read) {
|
|
1241
|
-
target.read = true;
|
|
1242
|
-
changed = true;
|
|
1243
|
-
}
|
|
1244
|
-
if (parsed.status === "completed" && target.state === "running") {
|
|
1245
|
-
target.state = "completed";
|
|
1246
|
-
target.updatedAt = parsed.endAt ?? now;
|
|
1247
|
-
changed = true;
|
|
1248
|
-
} else if (parsed.status === "error" && target.state === "running") {
|
|
1249
|
-
target.state = "error";
|
|
1250
|
-
target.updatedAt = parsed.endAt ?? now;
|
|
1251
|
-
changed = true;
|
|
1252
|
-
}
|
|
1253
|
-
return changed;
|
|
1254
|
-
}
|
|
1255
1199
|
const existing = map.get(parsed.callID);
|
|
1256
1200
|
if (parsed.status === "error") {
|
|
1257
1201
|
if (existing !== void 0 && existing.state === "error" && existing.updatedAt === parsed.endAt) return false;
|
|
@@ -1260,14 +1204,13 @@ function reduceDelegationToolPart(map, part, now = Date.now()) {
|
|
|
1260
1204
|
partID: parsed.partID,
|
|
1261
1205
|
sessionID: parsed.sessionID,
|
|
1262
1206
|
tool: parsed.tool,
|
|
1263
|
-
agent: parsed.agent
|
|
1207
|
+
agent: parsed.agent,
|
|
1264
1208
|
description: parsed.description,
|
|
1265
1209
|
alias: existing?.alias ?? null,
|
|
1266
1210
|
taskID: existing?.taskID ?? null,
|
|
1267
1211
|
state: "error",
|
|
1268
1212
|
startedAt: existing?.startedAt ?? parsed.startedAt,
|
|
1269
|
-
updatedAt: parsed.endAt ?? now
|
|
1270
|
-
read: existing?.read ?? false
|
|
1213
|
+
updatedAt: parsed.endAt ?? now
|
|
1271
1214
|
});
|
|
1272
1215
|
return true;
|
|
1273
1216
|
}
|
|
@@ -1277,14 +1220,13 @@ function reduceDelegationToolPart(map, part, now = Date.now()) {
|
|
|
1277
1220
|
partID: parsed.partID,
|
|
1278
1221
|
sessionID: parsed.sessionID,
|
|
1279
1222
|
tool: parsed.tool,
|
|
1280
|
-
agent: parsed.agent
|
|
1223
|
+
agent: parsed.agent,
|
|
1281
1224
|
description: parsed.description,
|
|
1282
1225
|
alias: parsed.alias,
|
|
1283
1226
|
taskID: parsed.taskID,
|
|
1284
1227
|
state: "running",
|
|
1285
1228
|
startedAt: parsed.startedAt,
|
|
1286
|
-
updatedAt: null
|
|
1287
|
-
read: false
|
|
1229
|
+
updatedAt: null
|
|
1288
1230
|
});
|
|
1289
1231
|
return true;
|
|
1290
1232
|
}
|
|
@@ -1321,14 +1263,14 @@ function removeDelegationEntry(map, partIDOrCallID) {
|
|
|
1321
1263
|
}
|
|
1322
1264
|
return false;
|
|
1323
1265
|
}
|
|
1324
|
-
/** Collect
|
|
1266
|
+
/** Collect native task tool parts from a session's messages.
|
|
1325
1267
|
* Messages may carry their parts inline (duck-typed `msg.parts`); when
|
|
1326
1268
|
* they don't, the optional `getParts(messageID)` callback is used (the TUI
|
|
1327
1269
|
* SDK exposes `api.state.part(messageID)`). The native `task` tool spawns a
|
|
1328
|
-
* child session with parentID = caller
|
|
1329
|
-
*
|
|
1330
|
-
*
|
|
1331
|
-
*
|
|
1270
|
+
* child session with parentID = caller, so its parts feed the live-map as
|
|
1271
|
+
* the refresh signal (rows come from the children channel). Pure w.r.t.
|
|
1272
|
+
* I/O — used by the mount re-scan to re-seed the live map after
|
|
1273
|
+
* compaction/attach. */
|
|
1332
1274
|
function collectDelegationToolParts(messages, getParts) {
|
|
1333
1275
|
const out = [];
|
|
1334
1276
|
for (const msg of messages ?? []) {
|
|
@@ -1338,7 +1280,7 @@ function collectDelegationToolParts(messages, getParts) {
|
|
|
1338
1280
|
if (!parts) continue;
|
|
1339
1281
|
for (const raw of parts) {
|
|
1340
1282
|
const part = raw;
|
|
1341
|
-
if (part?.type === "tool" &&
|
|
1283
|
+
if (part?.type === "tool" && part.tool === "task") out.push(part);
|
|
1342
1284
|
}
|
|
1343
1285
|
}
|
|
1344
1286
|
return out;
|
|
@@ -1353,7 +1295,7 @@ function seedLiveDelegationMap(map, parts, now = Date.now()) {
|
|
|
1353
1295
|
return changed;
|
|
1354
1296
|
}
|
|
1355
1297
|
/** Convert a live entry into the shared display shape. Alias falls back to
|
|
1356
|
-
* a `live-<callID>` prefix while the
|
|
1298
|
+
* a `live-<callID>` prefix while the task call has not completed yet. */
|
|
1357
1299
|
function toDelegationEntry(live) {
|
|
1358
1300
|
return {
|
|
1359
1301
|
alias: live.alias ?? `live-${live.callID.slice(0, 8)}`,
|
|
@@ -1365,7 +1307,6 @@ function toDelegationEntry(live) {
|
|
|
1365
1307
|
updatedAt: live.updatedAt,
|
|
1366
1308
|
timedOut: false,
|
|
1367
1309
|
description: live.description,
|
|
1368
|
-
read: live.read,
|
|
1369
1310
|
source: "live"
|
|
1370
1311
|
};
|
|
1371
1312
|
}
|
|
@@ -1640,7 +1581,7 @@ function ceilingDelegationList(all, maxVisible = 8, now = Date.now()) {
|
|
|
1640
1581
|
hiddenTerminal
|
|
1641
1582
|
};
|
|
1642
1583
|
}
|
|
1643
|
-
/** Split a display list into native task() rows vs
|
|
1584
|
+
/** Split a display list into native task() rows vs pantheon report rows.
|
|
1644
1585
|
* Native = source 'children-only' (no delegate report); everything else counts
|
|
1645
1586
|
* as pantheon. Pure — powers the hooks.log line. */
|
|
1646
1587
|
function countDelegationSources(entries) {
|
|
@@ -1665,8 +1606,8 @@ function formatPanelLogLine(children, pantheon, native, md, events) {
|
|
|
1665
1606
|
* report still renders: description from its title, agent from the child
|
|
1666
1607
|
* itself (fallback 'agent'), state derived from its status, startedAt from
|
|
1667
1608
|
* time.created. A report-less child is a NATIVE task() child (every
|
|
1668
|
-
* child of the current session —
|
|
1669
|
-
*
|
|
1609
|
+
* child of the current session — the native `task()` tool — carries
|
|
1610
|
+
* parentID = caller), so it gets source 'children-only', a
|
|
1670
1611
|
* per-child alias 'native-<last4 of the child id>' (one identity per native
|
|
1671
1612
|
* row) instead of a report alias. The 'task nativa' description fallback
|
|
1672
1613
|
* keeps the row non-empty when the child carries no title.
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pantheon-tui",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.1",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "pantheon-tui",
|
|
9
|
-
"version": "1.5.
|
|
9
|
+
"version": "1.5.1",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@opencode-ai/plugin": ">=1.14.0",
|
|
@@ -18,6 +18,9 @@
|
|
|
18
18
|
"rolldown-plugin-solid": "^0.2.1",
|
|
19
19
|
"tsdown": "^0.22.14"
|
|
20
20
|
},
|
|
21
|
+
"engines": {
|
|
22
|
+
"node": "^22.22.2 || ^24.15.0 || >=26.0.0"
|
|
23
|
+
},
|
|
21
24
|
"peerDependencies": {
|
|
22
25
|
"@opencode-ai/plugin": ">=1.14.0",
|
|
23
26
|
"@opencode-ai/sdk": ">=1.14.0",
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pantheon-tui",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.5.
|
|
4
|
+
"version": "1.5.1",
|
|
5
5
|
"description": "Pantheon TUI plugin — sidebar (version, preset, sessions, real-time delegations) + AI subscription usage gauges incl. OpenCode Go/Zen dollar limits (vendored, MIT)",
|
|
6
6
|
"license": "MIT",
|
|
7
|
+
"engines": {
|
|
8
|
+
"node": "^22.22.2 || ^24.15.0 || >=26.0.0"
|
|
9
|
+
},
|
|
7
10
|
"exports": {
|
|
8
11
|
"./tui": "./dist/tui.js",
|
|
9
12
|
"./server": "./dist/server.js"
|