pantheon-opencode 1.5.0-beta.13 → 1.5.0-beta.14
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 +21 -0
- package/package.json +1 -1
- package/plugin.json +1 -1
- package/pyproject.toml +1 -1
- package/src/plugins/tui/dist/tui.d.ts +15 -5
- package/src/plugins/tui/dist/tui.d.ts.map +1 -1
- package/src/plugins/tui/dist/tui.js +45 -18
- package/src/plugins/tui/package-lock.json +2 -2
- package/src/plugins/tui/package.json +1 -1
- package/src/plugins/tui/src/index.tsx +77 -16
package/CHANGELOG.md
CHANGED
|
@@ -18,6 +18,27 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
|
18
18
|
|
|
19
19
|
## ✅ Closed Issues
|
|
20
20
|
|
|
21
|
+
## [v1.5.0-beta.14] - 2026-09-14
|
|
22
|
+
|
|
23
|
+
<!-- Add new changes here. Running `node scripts/versioning.mjs apply` will
|
|
24
|
+
move this section to a versioned entry and reset the template below. -->
|
|
25
|
+
|
|
26
|
+
## 🆕 What's New
|
|
27
|
+
|
|
28
|
+
- **Ordenação active-first:** delegações ativas aparecem antes das concluídas,
|
|
29
|
+
falhas e canceladas no painel TUI.
|
|
30
|
+
- **Overflow active:** quando há mais delegações ativas que o teto visível, o
|
|
31
|
+
excedente ativo permanece representado na linha de overflow.
|
|
32
|
+
|
|
33
|
+
## 🐞 Fixed
|
|
34
|
+
|
|
35
|
+
- **Retenção visual:** concluídas permanecem visíveis por 2 min e falhas por
|
|
36
|
+
10 min antes de saírem do painel; canceladas seguem a retenção configurada.
|
|
37
|
+
|
|
38
|
+
## ⚠️ Known Issues
|
|
39
|
+
|
|
40
|
+
- **Stale running warning:** jobs em estado `running` além do limite esperado
|
|
41
|
+
recebem um aviso visual de stale no painel.
|
|
21
42
|
## [v1.5.0-beta.13] - 2026-09-14
|
|
22
43
|
|
|
23
44
|
<!-- Add new changes here. Running `node scripts/versioning.mjs apply` will
|
package/package.json
CHANGED
package/plugin.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pantheon",
|
|
3
3
|
"publisher": "ils15",
|
|
4
|
-
"version": "1.5.0-beta.
|
|
4
|
+
"version": "1.5.0-beta.14",
|
|
5
5
|
"displayName": "Pantheon",
|
|
6
6
|
"description": "Conductor-Delegate orchestration platform with 14 specialized agents, 21 skills, and OpenCode support.",
|
|
7
7
|
"agents": "./src/agents",
|
package/pyproject.toml
CHANGED
|
@@ -118,6 +118,10 @@ declare const STALE_RUNNING_THRESHOLD_MS: number;
|
|
|
118
118
|
* considered stale. Combined with the stale-running threshold to produce the
|
|
119
119
|
* display-only `stale-running` state. */
|
|
120
120
|
declare const IDLE_SILENCE_MS: number;
|
|
121
|
+
/** Visual-only terminal retention windows. Reports remain on disk and in the
|
|
122
|
+
* board; these constants only control which rows enter the TUI window. */
|
|
123
|
+
declare const DELEGATION_DONE_RETENTION_MS: number;
|
|
124
|
+
declare const DELEGATION_FAILED_RETENTION_MS: number;
|
|
121
125
|
/**
|
|
122
126
|
* Mark a running entry as `stale-running` if it has been running longer than
|
|
123
127
|
* the threshold AND has no recent activity (no `updatedAt` change in the last
|
|
@@ -422,12 +426,14 @@ declare const DELEGATION_VISIBLE_CEILING = 8;
|
|
|
422
426
|
* still a live job — it must never read as done); failed counts
|
|
423
427
|
* error/startup_failed; cancelled reads as done. Pure. */
|
|
424
428
|
declare function formatDelegationHeader(entries: readonly DelegationEntry[]): string;
|
|
425
|
-
/** Cap the panel: live rows first, then most-recent terminal rows, at
|
|
426
|
-
* `maxVisible` total.
|
|
427
|
-
*
|
|
429
|
+
/** Cap the panel: live rows first, then most-recent retained terminal rows, at
|
|
430
|
+
* most `maxVisible` total. Hidden counts describe the retained render list,
|
|
431
|
+
* not expired history. */
|
|
428
432
|
declare function ceilingDelegationList(all: readonly DelegationEntry[], maxVisible?: number, now?: number): {
|
|
429
433
|
visible: DelegationEntry[];
|
|
430
434
|
hidden: number;
|
|
435
|
+
hiddenActive: number;
|
|
436
|
+
hiddenTerminal: number;
|
|
431
437
|
};
|
|
432
438
|
/** Split a display list into native task() rows vs pantheon_delegate rows.
|
|
433
439
|
* Native = source 'children-only' (no board report); everything else counts
|
|
@@ -468,8 +474,12 @@ declare function childrenToDelegationEntries(children: readonly ChildDelegationL
|
|
|
468
474
|
* server-valid session id ("ses...") ever reaches the router, so an
|
|
469
475
|
* unsubstituted "{sessionID}" placeholder can never be routed. */
|
|
470
476
|
declare function navigateToDelegationSession(route: {
|
|
471
|
-
navigate?: (name: string, params?: Record<string, unknown>) => void
|
|
477
|
+
navigate?: (name: string, params?: Record<string, unknown>) => void | PromiseLike<void>;
|
|
472
478
|
} | undefined, taskID: string | undefined): boolean;
|
|
479
|
+
/** Build the mouse handler used by each delegation row. */
|
|
480
|
+
declare function createDelegationRowOpenHandler(route: {
|
|
481
|
+
navigate?: (name: string, params?: Record<string, unknown>) => void | PromiseLike<void>;
|
|
482
|
+
} | undefined, taskID: string | undefined): () => void;
|
|
473
483
|
/** Plugin-level live delegation store shared with the event subscriptions
|
|
474
484
|
* in `tui()`: the map of live entries + a version signal bumped on every
|
|
475
485
|
* mutation. The View subscribes to the version (in an effect) to refresh the
|
|
@@ -486,5 +496,5 @@ declare const plugin: TuiPluginModule & {
|
|
|
486
496
|
setup: () => Promise<void>;
|
|
487
497
|
};
|
|
488
498
|
//#endregion
|
|
489
|
-
export { BoardJobRecord, ChildDelegationLike, DELEGATION_ALIAS_WIDTH, DELEGATION_DESCRIPTION_MAX, DELEGATION_ELAPSED_WIDTH, DELEGATION_ROW_GLYPHS, DELEGATION_VISIBLE_CEILING, DelegationActivity, DelegationDisplayState, DelegationEntry, DelegationRowStatus, DelegationStateTone, DelegationToolPart, IDLE_SILENCE_MS, LiveDelegationEntry, LiveDelegationStore, ParsedDelegationToolPart, STALE_RUNNING_THRESHOLD_MS, ToolActivity, TuiSessionSources, boardRecordToDelegationEntry, boardRecordsToDelegationEntries, boardStatePath, buildChildrenPath, ceilingDelegationList, childStatusToState, childrenToDelegationEntries, collectDelegationToolParts, compareDelegationEntries, countDelegationSources, plugin as default, delegationActivity, delegationActivityLabel, delegationElapsed, delegationRowGlyph, delegationRowIdentity, delegationRowMarker, delegationRowStatus, delegationSpinnerFrame, delegationStateTone, extractToolActivity, fmtElapsed, formatDelegationAlias, formatDelegationElapsed, formatDelegationHeader, formatDelegationRowLead, formatPanelLogLine, isValidSessionId, latestToolActivityFor, markStaleIfRunning, mergeBoardDelegationSources, mergeChildDelegationSources, mergeDelegationSources, navigateToDelegationSession, panelLogDir, parseDelegationMarkdown, parseDelegationToolPart, readAllDelegationEntries, readBoardState, readDelegationEntries, reduceDelegationToolPart, removeDelegationEntry, resolveCurrentSessionID, resolveDelegationsDir, resolvePantheonRoot, safeSessionPath, seedLiveDelegationMap, splitDelegationList, toDelegationEntry, trackToolActivity, truncateDelegationDescription, tuiLogPath, visibleDelegationList };
|
|
499
|
+
export { BoardJobRecord, ChildDelegationLike, DELEGATION_ALIAS_WIDTH, DELEGATION_DESCRIPTION_MAX, DELEGATION_DONE_RETENTION_MS, DELEGATION_ELAPSED_WIDTH, DELEGATION_FAILED_RETENTION_MS, DELEGATION_ROW_GLYPHS, DELEGATION_VISIBLE_CEILING, DelegationActivity, DelegationDisplayState, DelegationEntry, DelegationRowStatus, DelegationStateTone, DelegationToolPart, IDLE_SILENCE_MS, LiveDelegationEntry, LiveDelegationStore, ParsedDelegationToolPart, STALE_RUNNING_THRESHOLD_MS, ToolActivity, TuiSessionSources, boardRecordToDelegationEntry, boardRecordsToDelegationEntries, boardStatePath, buildChildrenPath, ceilingDelegationList, childStatusToState, childrenToDelegationEntries, collectDelegationToolParts, compareDelegationEntries, countDelegationSources, createDelegationRowOpenHandler, plugin as default, delegationActivity, delegationActivityLabel, delegationElapsed, delegationRowGlyph, delegationRowIdentity, delegationRowMarker, delegationRowStatus, delegationSpinnerFrame, delegationStateTone, extractToolActivity, fmtElapsed, formatDelegationAlias, formatDelegationElapsed, formatDelegationHeader, formatDelegationRowLead, formatPanelLogLine, isValidSessionId, latestToolActivityFor, markStaleIfRunning, mergeBoardDelegationSources, mergeChildDelegationSources, mergeDelegationSources, navigateToDelegationSession, panelLogDir, parseDelegationMarkdown, parseDelegationToolPart, readAllDelegationEntries, readBoardState, readDelegationEntries, reduceDelegationToolPart, removeDelegationEntry, resolveCurrentSessionID, resolveDelegationsDir, resolvePantheonRoot, safeSessionPath, seedLiveDelegationMap, splitDelegationList, toDelegationEntry, trackToolActivity, truncateDelegationDescription, tuiLogPath, visibleDelegationList };
|
|
490
500
|
//# sourceMappingURL=tui.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tui.d.ts","names":[],"sources":["../src/index.tsx"],"mappings":";;KAw7BY;;EAEV;;EAEA;;;;EAIA;;EAEA;EACA;;EAUA;;EAEA;EACA;EACA;;EAEA;;;;;EASA;;;;;;;;;;;iBAsBc,wBACd,aACA,oBACA,qBACC;;;;;;iBAkHmB,sBAAsB,cAAc,QAAQ;;;;;;;;iBAwC5C,yBAAyB,eAAe,QAAQ;;;KAc1D;EACV;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;iBAIc,eAAe;;;;iBAiCT,eAAe,eAAe,QAAQ;;;;;;;iBA4B5C,oBACd;EAAS;EAAoB;eAC7B;;;;iBAUc,sBACd;EAAS;EAAoB;eAC7B;;;;;;iBAUc,YAAY;;;iBAMZ,WAAW;;;;iBAOX,yBAAyB,GAAG,iBAAiB,GAAG;;;;;iBAahD,oBACd,cAAc,mBACd,oBACA,cACA;EACG,QAAQ;EAAmB,QAAQ;;;;;
|
|
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.0-beta.
|
|
168
|
+
return "1.5.0-beta.14";
|
|
169
169
|
}
|
|
170
170
|
/**
|
|
171
171
|
* usage-bar — AI subscription usage gauge for the opencode TUI.
|
|
@@ -939,8 +939,13 @@ function compareDelegationEntries(a, b) {
|
|
|
939
939
|
function splitDelegationList(all, maxRecent = 8, now = Date.now(), staleThresholdMs = 1800 * 1e3) {
|
|
940
940
|
const isActiveState = (st) => st === "running" || st === "retry" || st === "stale-running";
|
|
941
941
|
return {
|
|
942
|
-
active: all.filter((d) => isActiveState(d.state)).map((d) => markStaleIfRunning(d, now, staleThresholdMs)),
|
|
943
|
-
recent: all.filter((d) => !isActiveState(d.state)).
|
|
942
|
+
active: all.filter((d) => isActiveState(d.state)).map((d) => markStaleIfRunning(d, now, staleThresholdMs)).sort(compareDelegationEntries),
|
|
943
|
+
recent: all.filter((d) => !isActiveState(d.state)).filter((d) => {
|
|
944
|
+
if (d.updatedAt === null || !Number.isFinite(d.updatedAt)) return true;
|
|
945
|
+
const age = now - d.updatedAt;
|
|
946
|
+
if (age < 0) return true;
|
|
947
|
+
return age < (delegationRowStatus(d.state) === "failed" ? DELEGATION_FAILED_RETENTION_MS : DELEGATION_DONE_RETENTION_MS);
|
|
948
|
+
}).sort(compareDelegationEntries).slice(0, maxRecent)
|
|
944
949
|
};
|
|
945
950
|
}
|
|
946
951
|
/** Live-first window used by {@link ceilingDelegationList} (kept for the
|
|
@@ -956,6 +961,10 @@ const STALE_RUNNING_THRESHOLD_MS = 1800 * 1e3;
|
|
|
956
961
|
* considered stale. Combined with the stale-running threshold to produce the
|
|
957
962
|
* display-only `stale-running` state. */
|
|
958
963
|
const IDLE_SILENCE_MS = 60 * 1e3;
|
|
964
|
+
/** Visual-only terminal retention windows. Reports remain on disk and in the
|
|
965
|
+
* board; these constants only control which rows enter the TUI window. */
|
|
966
|
+
const DELEGATION_DONE_RETENTION_MS = 120 * 1e3;
|
|
967
|
+
const DELEGATION_FAILED_RETENTION_MS = 600 * 1e3;
|
|
959
968
|
/**
|
|
960
969
|
* Mark a running entry as `stale-running` if it has been running longer than
|
|
961
970
|
* the threshold AND has no recent activity (no `updatedAt` change in the last
|
|
@@ -1048,7 +1057,7 @@ function delegationStateTone(state) {
|
|
|
1048
1057
|
case "running":
|
|
1049
1058
|
case "retry":
|
|
1050
1059
|
case "startup_unknown": return "warning";
|
|
1051
|
-
case "stale-running":
|
|
1060
|
+
case "stale-running": return "warning";
|
|
1052
1061
|
case "error":
|
|
1053
1062
|
case "startup_failed": return "error";
|
|
1054
1063
|
case "completed": return "success";
|
|
@@ -1662,14 +1671,20 @@ function formatDelegationHeader(entries) {
|
|
|
1662
1671
|
const tail = failed > 0 ? ` · ${failed} failed` : "";
|
|
1663
1672
|
return `(${active} active · ${done} done${tail})`;
|
|
1664
1673
|
}
|
|
1665
|
-
/** Cap the panel: live rows first, then most-recent terminal rows, at
|
|
1666
|
-
* `maxVisible` total.
|
|
1667
|
-
*
|
|
1674
|
+
/** Cap the panel: live rows first, then most-recent retained terminal rows, at
|
|
1675
|
+
* most `maxVisible` total. Hidden counts describe the retained render list,
|
|
1676
|
+
* not expired history. */
|
|
1668
1677
|
function ceilingDelegationList(all, maxVisible = 8, now = Date.now()) {
|
|
1669
|
-
const
|
|
1678
|
+
const { active, recent } = splitDelegationList(all, all.length, now);
|
|
1679
|
+
const visibleActive = active.slice(0, maxVisible);
|
|
1680
|
+
const visible = [...visibleActive, ...recent.slice(0, Math.max(0, maxVisible - visibleActive.length))];
|
|
1681
|
+
const hiddenActive = Math.max(0, active.length - visibleActive.length);
|
|
1682
|
+
const hiddenTerminal = Math.max(0, recent.length - (visible.length - visibleActive.length));
|
|
1670
1683
|
return {
|
|
1671
1684
|
visible,
|
|
1672
|
-
hidden:
|
|
1685
|
+
hidden: hiddenActive + hiddenTerminal,
|
|
1686
|
+
hiddenActive,
|
|
1687
|
+
hiddenTerminal
|
|
1673
1688
|
};
|
|
1674
1689
|
}
|
|
1675
1690
|
/** Split a display list into native task() rows vs pantheon_delegate rows.
|
|
@@ -1743,8 +1758,19 @@ function childrenToDelegationEntries(children, md, now = Date.now(), parentSessi
|
|
|
1743
1758
|
* unsubstituted "{sessionID}" placeholder can never be routed. */
|
|
1744
1759
|
function navigateToDelegationSession(route, taskID) {
|
|
1745
1760
|
if (typeof route?.navigate !== "function" || !isValidSessionId(taskID)) return false;
|
|
1746
|
-
|
|
1747
|
-
|
|
1761
|
+
try {
|
|
1762
|
+
const navigation = route.navigate("session", { sessionID: taskID });
|
|
1763
|
+
if (navigation !== void 0) Promise.resolve(navigation).catch(() => void 0);
|
|
1764
|
+
return true;
|
|
1765
|
+
} catch {
|
|
1766
|
+
return false;
|
|
1767
|
+
}
|
|
1768
|
+
}
|
|
1769
|
+
/** Build the mouse handler used by each delegation row. */
|
|
1770
|
+
function createDelegationRowOpenHandler(route, taskID) {
|
|
1771
|
+
return () => {
|
|
1772
|
+
navigateToDelegationSession(route, taskID);
|
|
1773
|
+
};
|
|
1748
1774
|
}
|
|
1749
1775
|
/** Silence-by-default panel logger.
|
|
1750
1776
|
* @param projectRoot the PROJECT ROOT — the logger appends to
|
|
@@ -1822,9 +1848,7 @@ function DelegationRow(props) {
|
|
|
1822
1848
|
const elapsed = createMemo(() => formatDelegationElapsed(props.job, props.now));
|
|
1823
1849
|
const description = createMemo(() => truncateDelegationDescription(props.job.description));
|
|
1824
1850
|
const activity = createMemo(() => latestToolActivityFor(latestToolActivity, props.job.taskID, props.now));
|
|
1825
|
-
const open = ()
|
|
1826
|
-
navigateToDelegationSession(props.api.route, props.job.taskID);
|
|
1827
|
-
};
|
|
1851
|
+
const open = createDelegationRowOpenHandler(props.api.route, props.job.taskID);
|
|
1828
1852
|
return (() => {
|
|
1829
1853
|
var _el$13 = createElement("box"), _el$14 = createElement("box"), _el$15 = createElement("text"), _el$16 = createElement("span"), _el$17 = createElement("span");
|
|
1830
1854
|
insertNode(_el$13, _el$14);
|
|
@@ -1988,7 +2012,7 @@ function View(props) {
|
|
|
1988
2012
|
return delegationsInflight;
|
|
1989
2013
|
};
|
|
1990
2014
|
const delegationCeiling = createMemo(() => ceilingDelegationList(childDelegations(), 8, now()));
|
|
1991
|
-
const delegationHeader = createMemo(() => formatDelegationHeader(
|
|
2015
|
+
const delegationHeader = createMemo(() => formatDelegationHeader(delegationCeiling().visible));
|
|
1992
2016
|
onMount(() => {
|
|
1993
2017
|
const cleanup = [];
|
|
1994
2018
|
try {
|
|
@@ -2153,7 +2177,7 @@ function View(props) {
|
|
|
2153
2177
|
setProp(_el$29, "attributes", 1);
|
|
2154
2178
|
insert(_el$29, () => `${showDelegations() ? "▼" : "▶"} Delegations`);
|
|
2155
2179
|
insert(_el$30, (() => {
|
|
2156
|
-
var _c$ = memo(() =>
|
|
2180
|
+
var _c$ = memo(() => delegationCeiling().visible.length > 0);
|
|
2157
2181
|
return () => _c$() ? ` ${delegationHeader()}` : " — idle";
|
|
2158
2182
|
})());
|
|
2159
2183
|
insert(_el$22, createComponent(Show, {
|
|
@@ -2202,7 +2226,10 @@ function View(props) {
|
|
|
2202
2226
|
},
|
|
2203
2227
|
get children() {
|
|
2204
2228
|
var _el$32 = createElement("text");
|
|
2205
|
-
insert(_el$32, () =>
|
|
2229
|
+
insert(_el$32, (() => {
|
|
2230
|
+
var _c$2 = memo(() => delegationCeiling().hiddenActive > 0);
|
|
2231
|
+
return () => _c$2() ? `… +${delegationCeiling().hiddenActive} active` : `… +${delegationCeiling().hiddenTerminal} more`;
|
|
2232
|
+
})());
|
|
2206
2233
|
effect((_$p) => setProp(_el$32, "fg", theme().textMuted, _$p));
|
|
2207
2234
|
return _el$32;
|
|
2208
2235
|
}
|
|
@@ -2287,6 +2314,6 @@ const plugin = {
|
|
|
2287
2314
|
setup: async () => {}
|
|
2288
2315
|
};
|
|
2289
2316
|
//#endregion
|
|
2290
|
-
export { DELEGATION_ALIAS_WIDTH, DELEGATION_DESCRIPTION_MAX, DELEGATION_ELAPSED_WIDTH, DELEGATION_ROW_GLYPHS, DELEGATION_VISIBLE_CEILING, IDLE_SILENCE_MS, STALE_RUNNING_THRESHOLD_MS, boardRecordToDelegationEntry, boardRecordsToDelegationEntries, boardStatePath, buildChildrenPath, ceilingDelegationList, childStatusToState, childrenToDelegationEntries, collectDelegationToolParts, compareDelegationEntries, countDelegationSources, plugin as default, delegationActivity, delegationActivityLabel, delegationElapsed, delegationRowGlyph, delegationRowIdentity, delegationRowMarker, delegationRowStatus, delegationSpinnerFrame, delegationStateTone, extractToolActivity, fmtElapsed, formatDelegationAlias, formatDelegationElapsed, formatDelegationHeader, formatDelegationRowLead, formatPanelLogLine, isValidSessionId, latestToolActivityFor, markStaleIfRunning, mergeBoardDelegationSources, mergeChildDelegationSources, mergeDelegationSources, navigateToDelegationSession, panelLogDir, parseDelegationMarkdown, parseDelegationToolPart, readAllDelegationEntries, readBoardState, readDelegationEntries, reduceDelegationToolPart, removeDelegationEntry, resolveCurrentSessionID, resolveDelegationsDir, resolvePantheonRoot, safeSessionPath, seedLiveDelegationMap, splitDelegationList, toDelegationEntry, trackToolActivity, truncateDelegationDescription, tuiLogPath, visibleDelegationList };
|
|
2317
|
+
export { DELEGATION_ALIAS_WIDTH, DELEGATION_DESCRIPTION_MAX, DELEGATION_DONE_RETENTION_MS, DELEGATION_ELAPSED_WIDTH, DELEGATION_FAILED_RETENTION_MS, DELEGATION_ROW_GLYPHS, DELEGATION_VISIBLE_CEILING, IDLE_SILENCE_MS, STALE_RUNNING_THRESHOLD_MS, boardRecordToDelegationEntry, boardRecordsToDelegationEntries, boardStatePath, buildChildrenPath, ceilingDelegationList, childStatusToState, childrenToDelegationEntries, collectDelegationToolParts, compareDelegationEntries, countDelegationSources, createDelegationRowOpenHandler, plugin as default, delegationActivity, delegationActivityLabel, delegationElapsed, delegationRowGlyph, delegationRowIdentity, delegationRowMarker, delegationRowStatus, delegationSpinnerFrame, delegationStateTone, extractToolActivity, fmtElapsed, formatDelegationAlias, formatDelegationElapsed, formatDelegationHeader, formatDelegationRowLead, formatPanelLogLine, isValidSessionId, latestToolActivityFor, markStaleIfRunning, mergeBoardDelegationSources, mergeChildDelegationSources, mergeDelegationSources, navigateToDelegationSession, panelLogDir, parseDelegationMarkdown, parseDelegationToolPart, readAllDelegationEntries, readBoardState, readDelegationEntries, reduceDelegationToolPart, removeDelegationEntry, resolveCurrentSessionID, resolveDelegationsDir, resolvePantheonRoot, safeSessionPath, seedLiveDelegationMap, splitDelegationList, toDelegationEntry, trackToolActivity, truncateDelegationDescription, tuiLogPath, visibleDelegationList };
|
|
2291
2318
|
|
|
2292
2319
|
//# sourceMappingURL=tui.js.map
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pantheon-tui",
|
|
3
|
-
"version": "1.5.0-beta.
|
|
3
|
+
"version": "1.5.0-beta.14",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "pantheon-tui",
|
|
9
|
-
"version": "1.5.0-beta.
|
|
9
|
+
"version": "1.5.0-beta.14",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@opencode-ai/plugin": ">=1.14.0",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pantheon-tui",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.5.0-beta.
|
|
4
|
+
"version": "1.5.0-beta.14",
|
|
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
7
|
"exports": {
|
|
@@ -1320,7 +1320,22 @@ export function splitDelegationList(
|
|
|
1320
1320
|
const active = all
|
|
1321
1321
|
.filter((d) => isActiveState(d.state))
|
|
1322
1322
|
.map((d) => markStaleIfRunning(d, now, staleThresholdMs))
|
|
1323
|
-
|
|
1323
|
+
.sort(compareDelegationEntries)
|
|
1324
|
+
const terminal = all
|
|
1325
|
+
.filter((d) => !isActiveState(d.state))
|
|
1326
|
+
.filter((d) => {
|
|
1327
|
+
// A missing/invalid finalized timestamp is not evidence that a report is
|
|
1328
|
+
// old. Keep it visible rather than accidentally hiding a terminal job.
|
|
1329
|
+
if (d.updatedAt === null || !Number.isFinite(d.updatedAt)) return true
|
|
1330
|
+
const age = now - d.updatedAt
|
|
1331
|
+
if (age < 0) return true
|
|
1332
|
+
const retention =
|
|
1333
|
+
delegationRowStatus(d.state) === 'failed'
|
|
1334
|
+
? DELEGATION_FAILED_RETENTION_MS
|
|
1335
|
+
: DELEGATION_DONE_RETENTION_MS
|
|
1336
|
+
return age < retention
|
|
1337
|
+
})
|
|
1338
|
+
.sort(compareDelegationEntries)
|
|
1324
1339
|
return {
|
|
1325
1340
|
active,
|
|
1326
1341
|
recent: terminal.slice(0, maxRecent),
|
|
@@ -1348,6 +1363,11 @@ export const STALE_RUNNING_THRESHOLD_MS = 30 * 60 * 1000
|
|
|
1348
1363
|
* display-only `stale-running` state. */
|
|
1349
1364
|
export const IDLE_SILENCE_MS = 60 * 1000
|
|
1350
1365
|
|
|
1366
|
+
/** Visual-only terminal retention windows. Reports remain on disk and in the
|
|
1367
|
+
* board; these constants only control which rows enter the TUI window. */
|
|
1368
|
+
export const DELEGATION_DONE_RETENTION_MS = 2 * 60 * 1000
|
|
1369
|
+
export const DELEGATION_FAILED_RETENTION_MS = 10 * 60 * 1000
|
|
1370
|
+
|
|
1351
1371
|
/**
|
|
1352
1372
|
* Mark a running entry as `stale-running` if it has been running longer than
|
|
1353
1373
|
* the threshold AND has no recent activity (no `updatedAt` change in the last
|
|
@@ -1465,6 +1485,7 @@ export function delegationStateTone(state: DelegationDisplayState): DelegationSt
|
|
|
1465
1485
|
case 'startup_unknown':
|
|
1466
1486
|
return 'warning'
|
|
1467
1487
|
case 'stale-running':
|
|
1488
|
+
return 'warning'
|
|
1468
1489
|
case 'error':
|
|
1469
1490
|
case 'startup_failed':
|
|
1470
1491
|
return 'error'
|
|
@@ -2410,16 +2431,23 @@ export function formatDelegationHeader(entries: readonly DelegationEntry[]): str
|
|
|
2410
2431
|
return `(${active} active · ${done} done${tail})`
|
|
2411
2432
|
}
|
|
2412
2433
|
|
|
2413
|
-
/** Cap the panel: live rows first, then most-recent terminal rows, at
|
|
2414
|
-
* `maxVisible` total.
|
|
2415
|
-
*
|
|
2434
|
+
/** Cap the panel: live rows first, then most-recent retained terminal rows, at
|
|
2435
|
+
* most `maxVisible` total. Hidden counts describe the retained render list,
|
|
2436
|
+
* not expired history. */
|
|
2416
2437
|
export function ceilingDelegationList(
|
|
2417
2438
|
all: readonly DelegationEntry[],
|
|
2418
2439
|
maxVisible = DELEGATION_VISIBLE_CEILING,
|
|
2419
2440
|
now = Date.now(),
|
|
2420
|
-
): { visible: DelegationEntry[]; hidden: number } {
|
|
2421
|
-
const
|
|
2422
|
-
|
|
2441
|
+
): { visible: DelegationEntry[]; hidden: number; hiddenActive: number; hiddenTerminal: number } {
|
|
2442
|
+
const { active, recent } = splitDelegationList(all, all.length, now)
|
|
2443
|
+
const visibleActive = active.slice(0, maxVisible)
|
|
2444
|
+
const visible = [
|
|
2445
|
+
...visibleActive,
|
|
2446
|
+
...recent.slice(0, Math.max(0, maxVisible - visibleActive.length)),
|
|
2447
|
+
]
|
|
2448
|
+
const hiddenActive = Math.max(0, active.length - visibleActive.length)
|
|
2449
|
+
const hiddenTerminal = Math.max(0, recent.length - (visible.length - visibleActive.length))
|
|
2450
|
+
return { visible, hidden: hiddenActive + hiddenTerminal, hiddenActive, hiddenTerminal }
|
|
2423
2451
|
}
|
|
2424
2452
|
|
|
2425
2453
|
/** Split a display list into native task() rows vs pantheon_delegate rows.
|
|
@@ -2522,12 +2550,41 @@ export function childrenToDelegationEntries(
|
|
|
2522
2550
|
* server-valid session id ("ses...") ever reaches the router, so an
|
|
2523
2551
|
* unsubstituted "{sessionID}" placeholder can never be routed. */
|
|
2524
2552
|
export function navigateToDelegationSession(
|
|
2525
|
-
route:
|
|
2553
|
+
route:
|
|
2554
|
+
| {
|
|
2555
|
+
navigate?: (name: string, params?: Record<string, unknown>) => void | PromiseLike<void>
|
|
2556
|
+
}
|
|
2557
|
+
| undefined,
|
|
2526
2558
|
taskID: string | undefined,
|
|
2527
2559
|
): boolean {
|
|
2528
2560
|
if (typeof route?.navigate !== 'function' || !isValidSessionId(taskID)) return false
|
|
2529
|
-
|
|
2530
|
-
|
|
2561
|
+
try {
|
|
2562
|
+
const navigation = route.navigate('session', { sessionID: taskID })
|
|
2563
|
+
if (navigation !== undefined) {
|
|
2564
|
+
// A removed session can reject route.navigate for historical rows. That
|
|
2565
|
+
// rejection is expected and intentionally absorbed so it cannot break
|
|
2566
|
+
// the TUI; the no-op avoids logging sensitive session details.
|
|
2567
|
+
void Promise.resolve(navigation).catch(() => undefined)
|
|
2568
|
+
}
|
|
2569
|
+
return true
|
|
2570
|
+
} catch {
|
|
2571
|
+
// Synchronous router failures are also fail-open for an inert historical row.
|
|
2572
|
+
return false
|
|
2573
|
+
}
|
|
2574
|
+
}
|
|
2575
|
+
|
|
2576
|
+
/** Build the mouse handler used by each delegation row. */
|
|
2577
|
+
export function createDelegationRowOpenHandler(
|
|
2578
|
+
route:
|
|
2579
|
+
| {
|
|
2580
|
+
navigate?: (name: string, params?: Record<string, unknown>) => void | PromiseLike<void>
|
|
2581
|
+
}
|
|
2582
|
+
| undefined,
|
|
2583
|
+
taskID: string | undefined,
|
|
2584
|
+
): () => void {
|
|
2585
|
+
return () => {
|
|
2586
|
+
navigateToDelegationSession(route, taskID)
|
|
2587
|
+
}
|
|
2531
2588
|
}
|
|
2532
2589
|
|
|
2533
2590
|
/* ─── Silence-by-default panel logger ──────────────────────
|
|
@@ -2674,9 +2731,7 @@ function DelegationRow(props: {
|
|
|
2674
2731
|
// Click a row → navigate to the child session (route API guarded in the
|
|
2675
2732
|
// helper). Enter-key binding is left out (per-row keymap wiring is not
|
|
2676
2733
|
// worth the complexity in this sidebar); mouse is enabled in tui.json.
|
|
2677
|
-
const open = ()
|
|
2678
|
-
navigateToDelegationSession(props.api.route, props.job.taskID)
|
|
2679
|
-
}
|
|
2734
|
+
const open = createDelegationRowOpenHandler(props.api.route, props.job.taskID)
|
|
2680
2735
|
|
|
2681
2736
|
return (
|
|
2682
2737
|
<box onMouseDown={open}>
|
|
@@ -2944,7 +2999,9 @@ function View(props: {
|
|
|
2944
2999
|
const delegationCeiling = createMemo(() =>
|
|
2945
3000
|
ceilingDelegationList(childDelegations(), DELEGATION_VISIBLE_CEILING, now()),
|
|
2946
3001
|
)
|
|
2947
|
-
|
|
3002
|
+
// Header counts the same retained rows shown below, so hidden/expired board
|
|
3003
|
+
// history cannot inflate the summary.
|
|
3004
|
+
const delegationHeader = createMemo(() => formatDelegationHeader(delegationCeiling().visible))
|
|
2948
3005
|
|
|
2949
3006
|
// ── Event subscriptions for live session/delegation updates ──
|
|
2950
3007
|
onMount(() => {
|
|
@@ -3090,7 +3147,7 @@ function View(props: {
|
|
|
3090
3147
|
{`${showDelegations() ? '▼' : '▶'} Delegations`}
|
|
3091
3148
|
</text>
|
|
3092
3149
|
<text fg={theme().textMuted}>
|
|
3093
|
-
{
|
|
3150
|
+
{delegationCeiling().visible.length > 0 ? ` ${delegationHeader()}` : ' — idle'}
|
|
3094
3151
|
</text>
|
|
3095
3152
|
</box>
|
|
3096
3153
|
<Show when={showDelegations()}>
|
|
@@ -3114,7 +3171,11 @@ function View(props: {
|
|
|
3114
3171
|
)}
|
|
3115
3172
|
</For>
|
|
3116
3173
|
<Show when={delegationCeiling().hidden > 0}>
|
|
3117
|
-
<text fg={theme().textMuted}>
|
|
3174
|
+
<text fg={theme().textMuted}>
|
|
3175
|
+
{delegationCeiling().hiddenActive > 0
|
|
3176
|
+
? `… +${delegationCeiling().hiddenActive} active`
|
|
3177
|
+
: `… +${delegationCeiling().hiddenTerminal} more`}
|
|
3178
|
+
</text>
|
|
3118
3179
|
</Show>
|
|
3119
3180
|
</box>
|
|
3120
3181
|
</Show>
|