pantheon-opencode 1.5.0-beta.11 → 1.5.0-beta.12
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 +16 -0
- package/package.json +1 -1
- package/plugin.json +1 -1
- package/pyproject.toml +1 -1
- package/scripts/dev-tui.sh +1 -1
- package/scripts/install/plugin.mjs +9 -12
- package/scripts/sync-tui.mjs +8 -11
- package/src/pantheon/session-guard.ts +2 -2
- package/src/plugins/tui/dist/tui.d.ts +69 -8
- package/src/plugins/tui/dist/tui.d.ts.map +1 -1
- package/src/plugins/tui/dist/tui.js +308 -89
- package/src/plugins/tui/package-lock.json +2 -2
- package/src/plugins/tui/package.json +2 -2
- package/src/plugins/tui/src/index.tsx +348 -37
- package/src/plugins/tui/dist/tui.tsx +0 -3008
|
@@ -10,9 +10,10 @@ import { For, Show, createEffect, createMemo, createResource, createSignal, onCl
|
|
|
10
10
|
/**
|
|
11
11
|
* pantheon-tui — Pantheon TUI plugin for opencode.
|
|
12
12
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
13
|
+
* Bundled entry: `tsdown` emits `dist/tui.js`, and the package `exports`
|
|
14
|
+
* (`./tui` → ./dist/tui.js, `./server` → ./dist/server.js) is the ONLY load
|
|
15
|
+
* path — no raw TSX copy is shipped. Because the bundle inlines relative
|
|
16
|
+
* imports, this entry may be split into modules without breaking the loader.
|
|
16
17
|
*
|
|
17
18
|
* Slots:
|
|
18
19
|
* - sidebar_content (order 900) — Pantheon sidebar (header/version/
|
|
@@ -164,7 +165,7 @@ async function detectVersion(api) {
|
|
|
164
165
|
if (ver) return ver;
|
|
165
166
|
}
|
|
166
167
|
} catch {}
|
|
167
|
-
return "1.5.0-beta.
|
|
168
|
+
return "1.5.0-beta.12";
|
|
168
169
|
}
|
|
169
170
|
/**
|
|
170
171
|
* usage-bar — AI subscription usage gauge for the opencode TUI.
|
|
@@ -839,17 +840,74 @@ async function readDelegationEntries(dir) {
|
|
|
839
840
|
async function readAllDelegationEntries(root) {
|
|
840
841
|
return readDelegationEntries(join(root, ".pantheon", "delegations"));
|
|
841
842
|
}
|
|
843
|
+
/** The persisted subset of BackgroundJobRecord the panel consumes. Duck-typed
|
|
844
|
+
* so a corrupt/older record never breaks parsing. */
|
|
845
|
+
/** The FilePersistence state path: `<root>/.pantheon/board/state.json`. */
|
|
846
|
+
function boardStatePath(root) {
|
|
847
|
+
return join(root, ".pantheon", "board", "state.json");
|
|
848
|
+
}
|
|
849
|
+
/** Validate one parsed record, keeping only the fields the panel uses.
|
|
850
|
+
* Returns null for anything without a taskID/state (a corrupt entry is
|
|
851
|
+
* skipped individually — the rest of the snapshot still loads). */
|
|
852
|
+
function normalizeBoardRecord(item) {
|
|
853
|
+
if (typeof item !== "object" || item === null) return null;
|
|
854
|
+
const rec = item;
|
|
855
|
+
if (typeof rec.taskID !== "string" || rec.taskID === "") return null;
|
|
856
|
+
if (typeof rec.state !== "string" || rec.state === "") return null;
|
|
857
|
+
const record = {
|
|
858
|
+
taskID: rec.taskID,
|
|
859
|
+
parentSessionID: typeof rec.parentSessionID === "string" ? rec.parentSessionID : "",
|
|
860
|
+
agent: typeof rec.agent === "string" && rec.agent !== "" ? rec.agent : "agent",
|
|
861
|
+
state: rec.state,
|
|
862
|
+
alias: typeof rec.alias === "string" ? rec.alias : ""
|
|
863
|
+
};
|
|
864
|
+
if (typeof rec.description === "string") record.description = rec.description;
|
|
865
|
+
if (typeof rec.launchedAt === "number" && Number.isFinite(rec.launchedAt)) record.launchedAt = rec.launchedAt;
|
|
866
|
+
if (typeof rec.completedAt === "number" && Number.isFinite(rec.completedAt)) record.completedAt = rec.completedAt;
|
|
867
|
+
if (typeof rec.updatedAt === "number" && Number.isFinite(rec.updatedAt)) record.updatedAt = rec.updatedAt;
|
|
868
|
+
if (typeof rec.timedOut === "boolean") record.timedOut = rec.timedOut;
|
|
869
|
+
return record;
|
|
870
|
+
}
|
|
871
|
+
/** Read `.pantheon/board/state.json` (the cross-session job board snapshot).
|
|
872
|
+
* Fail-open: missing file, corrupt JSON, non-array payload or an unreadable
|
|
873
|
+
* path all yield [] — the panel keeps rendering from the other channels. */
|
|
874
|
+
async function readBoardState(root) {
|
|
875
|
+
let raw;
|
|
876
|
+
try {
|
|
877
|
+
raw = await readFile(boardStatePath(root), "utf8");
|
|
878
|
+
} catch {
|
|
879
|
+
return [];
|
|
880
|
+
}
|
|
881
|
+
let parsed;
|
|
882
|
+
try {
|
|
883
|
+
parsed = JSON.parse(raw);
|
|
884
|
+
} catch {
|
|
885
|
+
return [];
|
|
886
|
+
}
|
|
887
|
+
if (!Array.isArray(parsed)) return [];
|
|
888
|
+
const records = [];
|
|
889
|
+
for (const item of parsed) {
|
|
890
|
+
const record = normalizeBoardRecord(item);
|
|
891
|
+
if (record !== null) records.push(record);
|
|
892
|
+
}
|
|
893
|
+
return records;
|
|
894
|
+
}
|
|
895
|
+
/** Resolve the PROJECT ROOT used by every pantheon file channel. `directory`
|
|
896
|
+
* wins over `worktree` (the old `resolveDelegationsDir` already did this);
|
|
897
|
+
* an absent/empty root or `/` (no git — e.g. the sandbox test project) falls
|
|
898
|
+
* back to cwd. Standardised here so the delegations md, the board state file
|
|
899
|
+
* and the panel logger all read the SAME root (audit finding: the channels
|
|
900
|
+
* resolved the root independently). Pure — no I/O. */
|
|
901
|
+
function resolvePantheonRoot(state, cwd = process.cwd()) {
|
|
902
|
+
const root = state?.directory ?? state?.worktree ?? "";
|
|
903
|
+
if (root === "" || root === "/") return cwd;
|
|
904
|
+
return root;
|
|
905
|
+
}
|
|
842
906
|
/** Resolve the directory where the job board writes delegation md reports.
|
|
843
907
|
* The board writes `.pantheon/delegations` RELATIVE to the server cwd,
|
|
844
|
-
* which the TUI exposes as `TuiState.path.directory`.
|
|
845
|
-
* exist on `TuiState.path` (the old `state?.project ?? state?.worktree`
|
|
846
|
-
* resolution was always undefined for the first term) and `worktree` is
|
|
847
|
-
* `/` when there is no git (e.g. the sandbox test project) — a root of
|
|
848
|
-
* `''` or `'/'` must fall back to `process.cwd()`. */
|
|
908
|
+
* which the TUI exposes as `TuiState.path.directory`. */
|
|
849
909
|
function resolveDelegationsDir(state, cwd = process.cwd()) {
|
|
850
|
-
|
|
851
|
-
if (root === "" || root === "/") return join(cwd, ".pantheon", "delegations");
|
|
852
|
-
return join(root, ".pantheon", "delegations");
|
|
910
|
+
return join(resolvePantheonRoot(state, cwd), ".pantheon", "delegations");
|
|
853
911
|
}
|
|
854
912
|
/** Project root derived from the delegations dir: `<root>/.pantheon/delegations`
|
|
855
913
|
* → `<root>`. Used to point the panel logger at the REAL hooks.log — passing
|
|
@@ -1379,6 +1437,106 @@ function mergeDelegationSources(live, md) {
|
|
|
1379
1437
|
all.sort(compareDelegationEntries);
|
|
1380
1438
|
return all;
|
|
1381
1439
|
}
|
|
1440
|
+
/** Job-board FSM → panel display state. `reconciled` is intentionally absent:
|
|
1441
|
+
* the panel parser rejects it (a reconciled job is done and folded away). */
|
|
1442
|
+
const BOARD_STATE_TO_DISPLAY = {
|
|
1443
|
+
running: "running",
|
|
1444
|
+
completed: "completed",
|
|
1445
|
+
error: "error",
|
|
1446
|
+
startup_failed: "startup_failed",
|
|
1447
|
+
startup_unknown: "startup_unknown",
|
|
1448
|
+
cancelled: "cancelled"
|
|
1449
|
+
};
|
|
1450
|
+
/** Map one persisted board record into the display shape. Returns null for
|
|
1451
|
+
* states the panel does not render (reconciled / unknown). Pure. */
|
|
1452
|
+
function boardRecordToDelegationEntry(record) {
|
|
1453
|
+
const state = BOARD_STATE_TO_DISPLAY[record.state];
|
|
1454
|
+
if (state === void 0) return null;
|
|
1455
|
+
const running = state === "running";
|
|
1456
|
+
return {
|
|
1457
|
+
alias: record.alias !== "" ? record.alias : `job-${record.taskID.slice(0, 8)}`,
|
|
1458
|
+
sessionID: record.parentSessionID,
|
|
1459
|
+
taskID: record.taskID,
|
|
1460
|
+
agent: record.agent,
|
|
1461
|
+
state,
|
|
1462
|
+
startedAt: record.launchedAt ?? record.updatedAt ?? 0,
|
|
1463
|
+
updatedAt: running ? null : record.completedAt ?? record.updatedAt ?? null,
|
|
1464
|
+
timedOut: record.timedOut === true,
|
|
1465
|
+
description: record.description ?? "",
|
|
1466
|
+
source: "board"
|
|
1467
|
+
};
|
|
1468
|
+
}
|
|
1469
|
+
/** Map a whole board snapshot, dropping unrenderable states. Sorted like every
|
|
1470
|
+
* other channel (running first, then most recent). Pure. */
|
|
1471
|
+
function boardRecordsToDelegationEntries(records) {
|
|
1472
|
+
const out = [];
|
|
1473
|
+
for (const record of records) {
|
|
1474
|
+
const entry = boardRecordToDelegationEntry(record);
|
|
1475
|
+
if (entry !== null) out.push(entry);
|
|
1476
|
+
}
|
|
1477
|
+
out.sort(compareDelegationEntries);
|
|
1478
|
+
return out;
|
|
1479
|
+
}
|
|
1480
|
+
/** Merge the board over any other channel. The board is AUTHORITATIVE for
|
|
1481
|
+
* state/alias/agent (it is the persisted FSM) and it is the only channel
|
|
1482
|
+
* that carries jobs from OTHER sessions. Dedup by taskID first, then by
|
|
1483
|
+
* (sessionID, alias) — aliases are per parent session. Pure. */
|
|
1484
|
+
function mergeBoardDelegationSources(base, board) {
|
|
1485
|
+
const key = (sessionID, alias) => `${sessionID}\u0000${alias}`;
|
|
1486
|
+
const byTaskID = /* @__PURE__ */ new Map();
|
|
1487
|
+
const bySessionAlias = /* @__PURE__ */ new Map();
|
|
1488
|
+
const out = [...base];
|
|
1489
|
+
out.forEach((entry, index) => {
|
|
1490
|
+
if (entry.taskID !== void 0) byTaskID.set(entry.taskID, index);
|
|
1491
|
+
bySessionAlias.set(key(entry.sessionID, entry.alias), index);
|
|
1492
|
+
});
|
|
1493
|
+
for (const incoming of board) {
|
|
1494
|
+
const index = (incoming.taskID !== void 0 ? byTaskID.get(incoming.taskID) : void 0) ?? bySessionAlias.get(key(incoming.sessionID, incoming.alias));
|
|
1495
|
+
if (index === void 0) {
|
|
1496
|
+
out.push(incoming);
|
|
1497
|
+
const next = out.length - 1;
|
|
1498
|
+
if (incoming.taskID !== void 0) byTaskID.set(incoming.taskID, next);
|
|
1499
|
+
bySessionAlias.set(key(incoming.sessionID, incoming.alias), next);
|
|
1500
|
+
continue;
|
|
1501
|
+
}
|
|
1502
|
+
out[index] = incoming;
|
|
1503
|
+
}
|
|
1504
|
+
out.sort(compareDelegationEntries);
|
|
1505
|
+
return out;
|
|
1506
|
+
}
|
|
1507
|
+
/** 'session' = focused session only (default); 'all' = every session the
|
|
1508
|
+
* board knows about. */
|
|
1509
|
+
/** api.kv key holding the persisted scope (defaults to 'session'). */
|
|
1510
|
+
const DELEGATION_SCOPE_KV_KEY = "delegations.scope";
|
|
1511
|
+
/** Structural subset of TuiKV — kept local so the pure helpers are testable
|
|
1512
|
+
* without the TUI runtime. */
|
|
1513
|
+
/** Read the persisted scope; anything malformed/absent → 'session'. */
|
|
1514
|
+
function readDelegationScope(kv) {
|
|
1515
|
+
try {
|
|
1516
|
+
return kv?.get?.("delegations.scope", "session") === "all" ? "all" : "session";
|
|
1517
|
+
} catch {
|
|
1518
|
+
return "session";
|
|
1519
|
+
}
|
|
1520
|
+
}
|
|
1521
|
+
/** Persist the scope. Failure is non-fatal — the signal keeps it in memory. */
|
|
1522
|
+
function writeDelegationScope(kv, scope) {
|
|
1523
|
+
try {
|
|
1524
|
+
kv?.set?.(DELEGATION_SCOPE_KV_KEY, scope);
|
|
1525
|
+
} catch {}
|
|
1526
|
+
}
|
|
1527
|
+
/** Keyboard/click toggle target. Pure. */
|
|
1528
|
+
function nextDelegationScope(scope) {
|
|
1529
|
+
return scope === "session" ? "all" : "session";
|
|
1530
|
+
}
|
|
1531
|
+
/** Keep only the focused session's jobs ('session') or all of them ('all').
|
|
1532
|
+
* An empty sessionID marks a current-session child (the children channel is
|
|
1533
|
+
* session-scoped and only fills sessionID from a matching md report), so it
|
|
1534
|
+
* counts as the current session. With no resolved session there is nothing
|
|
1535
|
+
* to scope against — fail-open to the full list. Pure. */
|
|
1536
|
+
function filterDelegationsByScope(entries, scope, sessionID) {
|
|
1537
|
+
if (scope === "all" || sessionID === null) return [...entries];
|
|
1538
|
+
return entries.filter((entry) => entry.sessionID === sessionID || entry.sessionID === "");
|
|
1539
|
+
}
|
|
1382
1540
|
/** Server-aligned session id validity: opencode rejects anything not starting
|
|
1383
1541
|
* with "ses" (SchemaError). This deliberately mirrors that exact contract —
|
|
1384
1542
|
* nothing stricter, nothing looser — so a template placeholder ("{sessionID}"),
|
|
@@ -1761,8 +1919,13 @@ function View(props) {
|
|
|
1761
1919
|
return (b.time?.updated ?? b.updated ?? 0) - ta;
|
|
1762
1920
|
}).slice(0, 8);
|
|
1763
1921
|
});
|
|
1764
|
-
const
|
|
1765
|
-
const panelLog = createTuiLogger(
|
|
1922
|
+
const projectRoot = createMemo(() => resolvePantheonRoot(props.api.state.path));
|
|
1923
|
+
const panelLog = createTuiLogger(projectRoot());
|
|
1924
|
+
const [delegationScope, setDelegationScope] = createSignal(readDelegationScope(props.api.kv));
|
|
1925
|
+
const applyDelegationScope = (scope) => {
|
|
1926
|
+
setDelegationScope(scope);
|
|
1927
|
+
writeDelegationScope(props.api.kv, scope);
|
|
1928
|
+
};
|
|
1766
1929
|
const [childDelegations, setChildDelegations] = createSignal([]);
|
|
1767
1930
|
const [now, setNow] = createSignal(Date.now());
|
|
1768
1931
|
const [animationNow, setAnimationNow] = createSignal(Date.now());
|
|
@@ -1775,17 +1938,23 @@ function View(props) {
|
|
|
1775
1938
|
const state = props.api.state;
|
|
1776
1939
|
let md = [];
|
|
1777
1940
|
try {
|
|
1778
|
-
md = await readAllDelegationEntries(
|
|
1941
|
+
md = await readAllDelegationEntries(projectRoot());
|
|
1779
1942
|
} catch {
|
|
1780
1943
|
md = [];
|
|
1781
1944
|
}
|
|
1945
|
+
let board = [];
|
|
1946
|
+
try {
|
|
1947
|
+
board = boardRecordsToDelegationEntries(await readBoardState(projectRoot()));
|
|
1948
|
+
} catch {
|
|
1949
|
+
board = [];
|
|
1950
|
+
}
|
|
1782
1951
|
const sessionID = resolveCurrentSessionID({
|
|
1783
1952
|
sessionID: props.sessionID,
|
|
1784
1953
|
api: props.api
|
|
1785
1954
|
});
|
|
1786
1955
|
if (sessionID === null) {
|
|
1787
|
-
setChildDelegations(md);
|
|
1788
|
-
panelLog.info(`${formatPanelLogLine(0, 0, 0, md.length, eventRefreshCount)} (no sessionID — history shown)`);
|
|
1956
|
+
setChildDelegations(mergeBoardDelegationSources(md, board));
|
|
1957
|
+
panelLog.info(`${formatPanelLogLine(0, 0, 0, md.length, eventRefreshCount)} (no sessionID — history+board shown)`);
|
|
1789
1958
|
return;
|
|
1790
1959
|
}
|
|
1791
1960
|
let children = [];
|
|
@@ -1809,9 +1978,10 @@ function View(props) {
|
|
|
1809
1978
|
...c,
|
|
1810
1979
|
status: resolveStatus(c.id)
|
|
1811
1980
|
})), md, now());
|
|
1981
|
+
for (const entry of childEntries) if (entry.sessionID === "") entry.sessionID = sessionID;
|
|
1812
1982
|
for (const [k, v] of props.liveStore.map) if (v.alias === null && v.taskID === null && Date.now() - v.startedAt > 3e4) props.liveStore.map.delete(k);
|
|
1813
1983
|
const liveEntries = [...props.liveStore.map.values()].filter((entry) => entry.sessionID === sessionID);
|
|
1814
|
-
setChildDelegations(mergeChildDelegationSources(childEntries, liveEntries));
|
|
1984
|
+
setChildDelegations(mergeBoardDelegationSources(mergeChildDelegationSources(childEntries, liveEntries), board));
|
|
1815
1985
|
const counts = countDelegationSources(childEntries);
|
|
1816
1986
|
panelLog.info(formatPanelLogLine(children.length, counts.pantheon, counts.native, md.length, eventRefreshCount));
|
|
1817
1987
|
} finally {
|
|
@@ -1820,9 +1990,13 @@ function View(props) {
|
|
|
1820
1990
|
})();
|
|
1821
1991
|
return delegationsInflight;
|
|
1822
1992
|
};
|
|
1823
|
-
const
|
|
1993
|
+
const scopedDelegations = createMemo(() => filterDelegationsByScope(childDelegations(), delegationScope(), resolveCurrentSessionID({
|
|
1994
|
+
sessionID: props.sessionID,
|
|
1995
|
+
api: props.api
|
|
1996
|
+
})));
|
|
1997
|
+
const delegationSplit = createMemo(() => splitDelegationList(scopedDelegations()));
|
|
1824
1998
|
const visibleDelegations = createMemo(() => [...delegationSplit().active, ...delegationSplit().recent]);
|
|
1825
|
-
const delegationHeader = createMemo(() => formatDelegationHeader(
|
|
1999
|
+
const delegationHeader = createMemo(() => formatDelegationHeader(scopedDelegations()));
|
|
1826
2000
|
const [archivedPage, setArchivedPage] = createSignal(archivedUiState.page);
|
|
1827
2001
|
const clampArchivedPage = (page, pages) => {
|
|
1828
2002
|
const clamped = Math.max(0, Math.min(page, Math.max(0, pages - 1)));
|
|
@@ -1872,6 +2046,23 @@ function View(props) {
|
|
|
1872
2046
|
if (parts.length > 0 && seedLiveDelegationMap(props.liveStore.map, parts) > 0) props.liveStore.bump();
|
|
1873
2047
|
}
|
|
1874
2048
|
} catch {}
|
|
2049
|
+
try {
|
|
2050
|
+
const keymap = props.api?.keymap;
|
|
2051
|
+
if (typeof keymap?.registerLayer === "function") {
|
|
2052
|
+
const off = keymap.registerLayer({
|
|
2053
|
+
priority: 1e3,
|
|
2054
|
+
commands: [{
|
|
2055
|
+
name: "pantheon.delegations.toggleScope",
|
|
2056
|
+
run: () => applyDelegationScope(nextDelegationScope(delegationScope()))
|
|
2057
|
+
}],
|
|
2058
|
+
bindings: [{
|
|
2059
|
+
key: "ctrl+shift+d",
|
|
2060
|
+
cmd: "pantheon.delegations.toggleScope"
|
|
2061
|
+
}]
|
|
2062
|
+
});
|
|
2063
|
+
if (typeof off === "function") cleanup.push(off);
|
|
2064
|
+
}
|
|
2065
|
+
} catch {}
|
|
1875
2066
|
onCleanup(() => cleanup.forEach((fn) => {
|
|
1876
2067
|
fn();
|
|
1877
2068
|
}));
|
|
@@ -1883,7 +2074,7 @@ function View(props) {
|
|
|
1883
2074
|
return _el$20;
|
|
1884
2075
|
})();
|
|
1885
2076
|
return (() => {
|
|
1886
|
-
var _el$22 = createElement("box"), _el$23 = createElement("text"), _el$24 = createElement("box"), _el$25 = createElement("text"), _el$26 = createElement("text"), _el$28 = createElement("box"), _el$29 = createElement("text"), _el$30 = createElement("text");
|
|
2077
|
+
var _el$22 = createElement("box"), _el$23 = createElement("text"), _el$24 = createElement("box"), _el$25 = createElement("text"), _el$26 = createElement("text"), _el$28 = createElement("box"), _el$29 = createElement("text"), _el$30 = createElement("text"), _el$31 = createElement("text"), _el$33 = createElement("text"), _el$35 = createElement("text"), _el$37 = createElement("text");
|
|
1887
2078
|
insertNode(_el$22, _el$23);
|
|
1888
2079
|
insertNode(_el$22, _el$24);
|
|
1889
2080
|
insertNode(_el$22, _el$28);
|
|
@@ -1896,10 +2087,10 @@ function View(props) {
|
|
|
1896
2087
|
return branch();
|
|
1897
2088
|
},
|
|
1898
2089
|
children: (b) => (() => {
|
|
1899
|
-
var _el$
|
|
1900
|
-
insert(_el$
|
|
1901
|
-
effect((_$p) => setProp(_el$
|
|
1902
|
-
return _el$
|
|
2090
|
+
var _el$40 = createElement("text");
|
|
2091
|
+
insert(_el$40, b);
|
|
2092
|
+
effect((_$p) => setProp(_el$40, "fg", theme().textMuted, _$p));
|
|
2093
|
+
return _el$40;
|
|
1903
2094
|
})()
|
|
1904
2095
|
}), _el$24);
|
|
1905
2096
|
insert(_el$22, createComponent(Show, {
|
|
@@ -1908,37 +2099,37 @@ function View(props) {
|
|
|
1908
2099
|
},
|
|
1909
2100
|
get fallback() {
|
|
1910
2101
|
return (() => {
|
|
1911
|
-
var _el$
|
|
1912
|
-
insertNode(_el$
|
|
1913
|
-
setProp(_el$
|
|
1914
|
-
setProp(_el$
|
|
1915
|
-
insertNode(_el$
|
|
1916
|
-
effect((_$p) => setProp(_el$
|
|
1917
|
-
return _el$
|
|
2102
|
+
var _el$41 = createElement("box"), _el$42 = createElement("text");
|
|
2103
|
+
insertNode(_el$41, _el$42);
|
|
2104
|
+
setProp(_el$41, "flexDirection", "row");
|
|
2105
|
+
setProp(_el$41, "gap", 1);
|
|
2106
|
+
insertNode(_el$42, createTextNode(`Preset: default`));
|
|
2107
|
+
effect((_$p) => setProp(_el$42, "fg", theme().textMuted, _$p));
|
|
2108
|
+
return _el$41;
|
|
1918
2109
|
})();
|
|
1919
2110
|
},
|
|
1920
2111
|
children: (name) => (() => {
|
|
1921
|
-
var _el$
|
|
1922
|
-
insertNode(_el$
|
|
1923
|
-
insertNode(_el$
|
|
1924
|
-
insertNode(_el$
|
|
1925
|
-
setProp(_el$
|
|
1926
|
-
setProp(_el$
|
|
1927
|
-
insertNode(_el$
|
|
1928
|
-
insert(_el$
|
|
1929
|
-
insert(_el$
|
|
2112
|
+
var _el$44 = createElement("box"), _el$45 = createElement("text"), _el$47 = createElement("text"), _el$48 = createElement("text");
|
|
2113
|
+
insertNode(_el$44, _el$45);
|
|
2114
|
+
insertNode(_el$44, _el$47);
|
|
2115
|
+
insertNode(_el$44, _el$48);
|
|
2116
|
+
setProp(_el$44, "flexDirection", "row");
|
|
2117
|
+
setProp(_el$44, "gap", 1);
|
|
2118
|
+
insertNode(_el$45, createTextNode(`⚡ Preset:`));
|
|
2119
|
+
insert(_el$47, name);
|
|
2120
|
+
insert(_el$48, () => `(${preset().source ?? ""})`);
|
|
1930
2121
|
effect((_p$) => {
|
|
1931
|
-
var _v$
|
|
1932
|
-
_v$
|
|
1933
|
-
_v$
|
|
1934
|
-
_v$
|
|
2122
|
+
var _v$17 = theme().textMuted, _v$18 = theme().accent, _v$19 = theme().textMuted;
|
|
2123
|
+
_v$17 !== _p$.e && (_p$.e = setProp(_el$45, "fg", _v$17, _p$.e));
|
|
2124
|
+
_v$18 !== _p$.t && (_p$.t = setProp(_el$47, "fg", _v$18, _p$.t));
|
|
2125
|
+
_v$19 !== _p$.a && (_p$.a = setProp(_el$48, "fg", _v$19, _p$.a));
|
|
1935
2126
|
return _p$;
|
|
1936
2127
|
}, {
|
|
1937
2128
|
e: void 0,
|
|
1938
2129
|
t: void 0,
|
|
1939
2130
|
a: void 0
|
|
1940
2131
|
});
|
|
1941
|
-
return _el$
|
|
2132
|
+
return _el$44;
|
|
1942
2133
|
})()
|
|
1943
2134
|
}), _el$24);
|
|
1944
2135
|
insert(_el$22, createComponent(HR, {}), _el$24);
|
|
@@ -1959,12 +2150,12 @@ function View(props) {
|
|
|
1959
2150
|
},
|
|
1960
2151
|
get fallback() {
|
|
1961
2152
|
return (() => {
|
|
1962
|
-
var _el$
|
|
1963
|
-
insertNode(_el$
|
|
1964
|
-
setProp(_el$
|
|
1965
|
-
insertNode(_el$
|
|
1966
|
-
effect((_$p) => setProp(_el$
|
|
1967
|
-
return _el$
|
|
2153
|
+
var _el$49 = createElement("box"), _el$50 = createElement("text");
|
|
2154
|
+
insertNode(_el$49, _el$50);
|
|
2155
|
+
setProp(_el$49, "marginLeft", 1);
|
|
2156
|
+
insertNode(_el$50, createTextNode(`No recent sessions`));
|
|
2157
|
+
effect((_$p) => setProp(_el$50, "fg", theme().textMuted, _$p));
|
|
2158
|
+
return _el$49;
|
|
1968
2159
|
})();
|
|
1969
2160
|
},
|
|
1970
2161
|
get children() {
|
|
@@ -1989,10 +2180,26 @@ function View(props) {
|
|
|
1989
2180
|
}), _el$28);
|
|
1990
2181
|
insertNode(_el$28, _el$29);
|
|
1991
2182
|
insertNode(_el$28, _el$30);
|
|
2183
|
+
insertNode(_el$28, _el$31);
|
|
2184
|
+
insertNode(_el$28, _el$33);
|
|
2185
|
+
insertNode(_el$28, _el$35);
|
|
2186
|
+
insertNode(_el$28, _el$37);
|
|
1992
2187
|
setProp(_el$28, "onMouseDown", () => setShowDelegations((x) => !x));
|
|
1993
2188
|
setProp(_el$29, "attributes", 1);
|
|
1994
2189
|
insert(_el$29, () => `${showDelegations() ? "▼" : "▶"} Delegations`);
|
|
1995
2190
|
insert(_el$30, () => ` ${delegationHeader()}`);
|
|
2191
|
+
insertNode(_el$31, createTextNode(` `));
|
|
2192
|
+
insertNode(_el$33, createTextNode(`[Sessão]`));
|
|
2193
|
+
setProp(_el$33, "onMouseDown", (e) => {
|
|
2194
|
+
if (typeof e === "object" && e !== null && "stopPropagation" in e) e.stopPropagation();
|
|
2195
|
+
applyDelegationScope("session");
|
|
2196
|
+
});
|
|
2197
|
+
insertNode(_el$35, createTextNode(`/`));
|
|
2198
|
+
insertNode(_el$37, createTextNode(`[Tudo]`));
|
|
2199
|
+
setProp(_el$37, "onMouseDown", (e) => {
|
|
2200
|
+
if (typeof e === "object" && e !== null && "stopPropagation" in e) e.stopPropagation();
|
|
2201
|
+
applyDelegationScope("all");
|
|
2202
|
+
});
|
|
1996
2203
|
insert(_el$22, createComponent(Show, {
|
|
1997
2204
|
get when() {
|
|
1998
2205
|
return showDelegations();
|
|
@@ -2004,19 +2211,19 @@ function View(props) {
|
|
|
2004
2211
|
},
|
|
2005
2212
|
get fallback() {
|
|
2006
2213
|
return (() => {
|
|
2007
|
-
var _el$
|
|
2008
|
-
insertNode(_el$
|
|
2009
|
-
setProp(_el$
|
|
2010
|
-
insertNode(_el$
|
|
2011
|
-
effect((_$p) => setProp(_el$
|
|
2012
|
-
return _el$
|
|
2214
|
+
var _el$52 = createElement("box"), _el$53 = createElement("text");
|
|
2215
|
+
insertNode(_el$52, _el$53);
|
|
2216
|
+
setProp(_el$52, "marginLeft", 1);
|
|
2217
|
+
insertNode(_el$53, createTextNode(`No delegations`));
|
|
2218
|
+
effect((_$p) => setProp(_el$53, "fg", theme().textMuted, _$p));
|
|
2219
|
+
return _el$52;
|
|
2013
2220
|
})();
|
|
2014
2221
|
},
|
|
2015
2222
|
get children() {
|
|
2016
|
-
var _el$
|
|
2017
|
-
setProp(_el$
|
|
2018
|
-
setProp(_el$
|
|
2019
|
-
insert(_el$
|
|
2223
|
+
var _el$39 = createElement("box");
|
|
2224
|
+
setProp(_el$39, "marginLeft", 1);
|
|
2225
|
+
setProp(_el$39, "flexDirection", "column");
|
|
2226
|
+
insert(_el$39, createComponent(For, {
|
|
2020
2227
|
get each() {
|
|
2021
2228
|
return visibleDelegations();
|
|
2022
2229
|
},
|
|
@@ -2033,7 +2240,7 @@ function View(props) {
|
|
|
2033
2240
|
}
|
|
2034
2241
|
})
|
|
2035
2242
|
}), null);
|
|
2036
|
-
insert(_el$
|
|
2243
|
+
insert(_el$39, createComponent(Show, {
|
|
2037
2244
|
get when() {
|
|
2038
2245
|
return delegationSplit().archived.length > 0;
|
|
2039
2246
|
},
|
|
@@ -2045,22 +2252,22 @@ function View(props) {
|
|
|
2045
2252
|
const page = Math.min(archivedPage(), pages - 1);
|
|
2046
2253
|
const slice = archived.slice(page * pageSize, page * pageSize + pageSize);
|
|
2047
2254
|
return (() => {
|
|
2048
|
-
var _el$
|
|
2049
|
-
insertNode(_el$
|
|
2050
|
-
setProp(_el$
|
|
2051
|
-
insertNode(_el$
|
|
2052
|
-
insertNode(_el$
|
|
2053
|
-
insertNode(_el$
|
|
2054
|
-
insertNode(_el$
|
|
2055
|
-
setProp(_el$
|
|
2056
|
-
setProp(_el$
|
|
2057
|
-
insertNode(_el$
|
|
2058
|
-
setProp(_el$
|
|
2059
|
-
insert(_el$
|
|
2060
|
-
insert(_el$
|
|
2061
|
-
insertNode(_el$
|
|
2062
|
-
setProp(_el$
|
|
2063
|
-
insert(_el$
|
|
2255
|
+
var _el$55 = createElement("box"), _el$56 = createElement("box"), _el$57 = createElement("text"), _el$59 = createElement("text"), _el$60 = createElement("text"), _el$61 = createElement("text");
|
|
2256
|
+
insertNode(_el$55, _el$56);
|
|
2257
|
+
setProp(_el$55, "flexDirection", "column");
|
|
2258
|
+
insertNode(_el$56, _el$57);
|
|
2259
|
+
insertNode(_el$56, _el$59);
|
|
2260
|
+
insertNode(_el$56, _el$60);
|
|
2261
|
+
insertNode(_el$56, _el$61);
|
|
2262
|
+
setProp(_el$56, "flexDirection", "row");
|
|
2263
|
+
setProp(_el$56, "marginLeft", 0);
|
|
2264
|
+
insertNode(_el$57, createTextNode(`‹ `));
|
|
2265
|
+
setProp(_el$57, "onMouseDown", () => clampArchivedPage(page - 1, pages));
|
|
2266
|
+
insert(_el$59, () => `Archived (${archived.length}) `);
|
|
2267
|
+
insert(_el$60, `${page + 1}/${pages}`);
|
|
2268
|
+
insertNode(_el$61, createTextNode(` ›`));
|
|
2269
|
+
setProp(_el$61, "onMouseDown", () => clampArchivedPage(page + 1, pages));
|
|
2270
|
+
insert(_el$55, createComponent(For, {
|
|
2064
2271
|
each: slice,
|
|
2065
2272
|
children: (job) => createComponent(DelegationRow, {
|
|
2066
2273
|
get api() {
|
|
@@ -2076,11 +2283,11 @@ function View(props) {
|
|
|
2076
2283
|
})
|
|
2077
2284
|
}), null);
|
|
2078
2285
|
effect((_p$) => {
|
|
2079
|
-
var _v$
|
|
2080
|
-
_v$
|
|
2081
|
-
_v$
|
|
2082
|
-
_v$
|
|
2083
|
-
_v$
|
|
2286
|
+
var _v$20 = theme().textMuted, _v$21 = theme().textMuted, _v$22 = theme().textMuted, _v$23 = theme().textMuted;
|
|
2287
|
+
_v$20 !== _p$.e && (_p$.e = setProp(_el$57, "fg", _v$20, _p$.e));
|
|
2288
|
+
_v$21 !== _p$.t && (_p$.t = setProp(_el$59, "fg", _v$21, _p$.t));
|
|
2289
|
+
_v$22 !== _p$.a && (_p$.a = setProp(_el$60, "fg", _v$22, _p$.a));
|
|
2290
|
+
_v$23 !== _p$.o && (_p$.o = setProp(_el$61, "fg", _v$23, _p$.o));
|
|
2084
2291
|
return _p$;
|
|
2085
2292
|
}, {
|
|
2086
2293
|
e: void 0,
|
|
@@ -2088,30 +2295,42 @@ function View(props) {
|
|
|
2088
2295
|
a: void 0,
|
|
2089
2296
|
o: void 0
|
|
2090
2297
|
});
|
|
2091
|
-
return _el$
|
|
2298
|
+
return _el$55;
|
|
2092
2299
|
})();
|
|
2093
2300
|
})();
|
|
2094
2301
|
}
|
|
2095
2302
|
}), null);
|
|
2096
|
-
return _el$
|
|
2303
|
+
return _el$39;
|
|
2097
2304
|
}
|
|
2098
2305
|
});
|
|
2099
2306
|
}
|
|
2100
2307
|
}), null);
|
|
2101
2308
|
effect((_p$) => {
|
|
2102
|
-
var _v$8 = theme().accent, _v$9 = theme().text, _v$0 = theme().textMuted, _v$1 = theme().text, _v$10 = theme().textMuted;
|
|
2309
|
+
var _v$8 = theme().accent, _v$9 = theme().text, _v$0 = theme().textMuted, _v$1 = theme().text, _v$10 = theme().textMuted, _v$11 = theme().textMuted, _v$12 = delegationScope() === "session" ? theme().accent : theme().textMuted, _v$13 = delegationScope() === "session" ? 1 : void 0, _v$14 = theme().textMuted, _v$15 = delegationScope() === "all" ? theme().accent : theme().textMuted, _v$16 = delegationScope() === "all" ? 1 : void 0;
|
|
2103
2310
|
_v$8 !== _p$.e && (_p$.e = setProp(_el$23, "fg", _v$8, _p$.e));
|
|
2104
2311
|
_v$9 !== _p$.t && (_p$.t = setProp(_el$25, "fg", _v$9, _p$.t));
|
|
2105
2312
|
_v$0 !== _p$.a && (_p$.a = setProp(_el$26, "fg", _v$0, _p$.a));
|
|
2106
2313
|
_v$1 !== _p$.o && (_p$.o = setProp(_el$29, "fg", _v$1, _p$.o));
|
|
2107
2314
|
_v$10 !== _p$.i && (_p$.i = setProp(_el$30, "fg", _v$10, _p$.i));
|
|
2315
|
+
_v$11 !== _p$.n && (_p$.n = setProp(_el$31, "fg", _v$11, _p$.n));
|
|
2316
|
+
_v$12 !== _p$.s && (_p$.s = setProp(_el$33, "fg", _v$12, _p$.s));
|
|
2317
|
+
_v$13 !== _p$.h && (_p$.h = setProp(_el$33, "attributes", _v$13, _p$.h));
|
|
2318
|
+
_v$14 !== _p$.r && (_p$.r = setProp(_el$35, "fg", _v$14, _p$.r));
|
|
2319
|
+
_v$15 !== _p$.d && (_p$.d = setProp(_el$37, "fg", _v$15, _p$.d));
|
|
2320
|
+
_v$16 !== _p$.l && (_p$.l = setProp(_el$37, "attributes", _v$16, _p$.l));
|
|
2108
2321
|
return _p$;
|
|
2109
2322
|
}, {
|
|
2110
2323
|
e: void 0,
|
|
2111
2324
|
t: void 0,
|
|
2112
2325
|
a: void 0,
|
|
2113
2326
|
o: void 0,
|
|
2114
|
-
i: void 0
|
|
2327
|
+
i: void 0,
|
|
2328
|
+
n: void 0,
|
|
2329
|
+
s: void 0,
|
|
2330
|
+
h: void 0,
|
|
2331
|
+
r: void 0,
|
|
2332
|
+
d: void 0,
|
|
2333
|
+
l: void 0
|
|
2115
2334
|
});
|
|
2116
2335
|
return _el$22;
|
|
2117
2336
|
})();
|
|
@@ -2173,6 +2392,6 @@ const plugin = {
|
|
|
2173
2392
|
setup: async () => {}
|
|
2174
2393
|
};
|
|
2175
2394
|
//#endregion
|
|
2176
|
-
export { DELEGATION_DESCRIPTION_MAX, DELEGATION_ELAPSED_WIDTH, DELEGATION_STATE_GLYPHS, IDLE_SILENCE_MS, STALE_RUNNING_THRESHOLD_MS, buildChildrenPath, childStatusToState, childrenToDelegationEntries, collectDelegationToolParts, compareDelegationEntries, countDelegationSources, plugin as default, delegationActivity, delegationActivityLabel, delegationElapsed, delegationIcon, delegationSpinnerFrame, delegationStateGlyph, delegationStateMarker, delegationStateTone, delegationTag, extractToolActivity, fmtElapsed, formatDelegationElapsed, formatDelegationHeader, formatDelegationIdentity, formatDelegationRow, formatPanelLogLine, isValidSessionId, latestToolActivityFor, markStaleIfRunning, mergeChildDelegationSources, mergeDelegationSources, navigateToDelegationSession, panelLogDir, parseDelegationMarkdown, parseDelegationToolPart, readAllDelegationEntries, readDelegationEntries, reduceDelegationToolPart, removeDelegationEntry, resolveCurrentSessionID, resolveDelegationsDir, safeSessionPath, seedLiveDelegationMap, splitDelegationList, toDelegationEntry, trackToolActivity, truncateDelegationDescription, tuiLogPath, visibleDelegationList };
|
|
2395
|
+
export { DELEGATION_DESCRIPTION_MAX, DELEGATION_ELAPSED_WIDTH, DELEGATION_SCOPE_KV_KEY, DELEGATION_STATE_GLYPHS, IDLE_SILENCE_MS, STALE_RUNNING_THRESHOLD_MS, boardRecordToDelegationEntry, boardRecordsToDelegationEntries, boardStatePath, buildChildrenPath, childStatusToState, childrenToDelegationEntries, collectDelegationToolParts, compareDelegationEntries, countDelegationSources, plugin as default, delegationActivity, delegationActivityLabel, delegationElapsed, delegationIcon, delegationSpinnerFrame, delegationStateGlyph, delegationStateMarker, delegationStateTone, delegationTag, extractToolActivity, filterDelegationsByScope, fmtElapsed, formatDelegationElapsed, formatDelegationHeader, formatDelegationIdentity, formatDelegationRow, formatPanelLogLine, isValidSessionId, latestToolActivityFor, markStaleIfRunning, mergeBoardDelegationSources, mergeChildDelegationSources, mergeDelegationSources, navigateToDelegationSession, nextDelegationScope, panelLogDir, parseDelegationMarkdown, parseDelegationToolPart, readAllDelegationEntries, readBoardState, readDelegationEntries, readDelegationScope, reduceDelegationToolPart, removeDelegationEntry, resolveCurrentSessionID, resolveDelegationsDir, resolvePantheonRoot, safeSessionPath, seedLiveDelegationMap, splitDelegationList, toDelegationEntry, trackToolActivity, truncateDelegationDescription, tuiLogPath, visibleDelegationList, writeDelegationScope };
|
|
2177
2396
|
|
|
2178
2397
|
//# 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.12",
|
|
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.12",
|
|
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.12",
|
|
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": {
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"src"
|
|
14
14
|
],
|
|
15
15
|
"scripts": {
|
|
16
|
-
"build": "tsdown
|
|
16
|
+
"build": "tsdown",
|
|
17
17
|
"typecheck": "tsc --noEmit"
|
|
18
18
|
},
|
|
19
19
|
"peerDependencies": {
|