pantheon-opencode 1.5.0-beta.11 → 1.5.0-beta.13
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 +47 -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 +111 -59
- package/src/plugins/tui/dist/tui.d.ts.map +1 -1
- package/src/plugins/tui/dist/tui.js +353 -239
- package/src/plugins/tui/package-lock.json +2 -2
- package/src/plugins/tui/package.json +2 -2
- package/src/plugins/tui/src/index.tsx +415 -201
- package/src/plugins/tui/dist/tui.tsx +0 -3008
package/CHANGELOG.md
CHANGED
|
@@ -18,6 +18,53 @@ 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.13] - 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
|
+
- **TUI status-only — rows simplificadas:** cada linha do painel Delegations passa
|
|
29
|
+
a ser `{glyph} {alias} {elapsed}` + `desc` muted — um glyph de status, uma única
|
|
30
|
+
identidade e o tempo decorrido, com a descrição em tom muted. São 4 glyphs
|
|
31
|
+
(running animado, completed, error, cancelled/retry), sem toggle
|
|
32
|
+
`[Sessão]`/`[Tudo]`, sem prefixos `nat:`/`pan:` e sem losango ◇/◆.
|
|
33
|
+
- **Header `active`/`done`/`failed`:** o cabeçalho do painel resume apenas esses
|
|
34
|
+
três contadores sobre a lista completa (todas as sessões), sem `nat:`/`pan:`.
|
|
35
|
+
- **Ceiling 8:** no máximo 8 linhas visíveis (live-first); o excedente colapsa em
|
|
36
|
+
uma única linha `… +N more`.
|
|
37
|
+
- **Board read (jobs de todas as sessões):** o painel lê o BackgroundJobBoard
|
|
38
|
+
(`.pantheon/board/state.json`), então jobs `pantheon_delegate` de qualquer
|
|
39
|
+
sessão aparecem — não só os filhos nativos da sessão focada.
|
|
40
|
+
- **118 testes TUI delegations:** `tests/pantheon/tui-delegations.test.ts` com
|
|
41
|
+
118/118 passando, cobrindo rows status-only, header active/done/failed, ceiling
|
|
42
|
+
e board read cross-session.
|
|
43
|
+
|
|
44
|
+
## 🐞 Fixed
|
|
45
|
+
|
|
46
|
+
- **Sanitização de dead code:** removidos helpers, tipos e estado órfãos do
|
|
47
|
+
painel Delegations (toggle de escopo `[Sessão]`/`[Tudo]`, prefixos curtos
|
|
48
|
+
`nat:`/`pan:`, glyphs por estado e paginação de arquivo morto) que sobraram do
|
|
49
|
+
refactor status-only.
|
|
50
|
+
- **Board merge preserva sessão conhecida:** um record do board com
|
|
51
|
+
`parentSessionID` vazio não sobrescreve mais a sessão já atribuída à linha.
|
|
52
|
+
## [v1.5.0-beta.12] - 2026-09-14
|
|
53
|
+
|
|
54
|
+
<!-- Add new changes here. Running `node scripts/versioning.mjs apply` will
|
|
55
|
+
move this section to a versioned entry and reset the template below. -->
|
|
56
|
+
|
|
57
|
+
## 🆕 What's New
|
|
58
|
+
|
|
59
|
+
- **TUI lê o board (4º canal):** o painel Delegations passa a ler o
|
|
60
|
+
BackgroundJobBoard via `readBoardState()` — jobs `pantheon_delegate` de todas
|
|
61
|
+
as sessões aparecem, não só os filhos nativos da sessão focada.
|
|
62
|
+
- **Toggle [Sessão]/[Tudo] + chips:** `[Sessão]` (default) mostra só a sessão
|
|
63
|
+
focada, `[Tudo]` mostra jobs de todas as sessões; chips clicáveis no header.
|
|
64
|
+
- **Raw `dist/tui.tsx` removido (bundle-only):** o dist passa a carregar só o
|
|
65
|
+
bundle compilado (`tui.js`); o fonte raw sai do pacote publicado.
|
|
66
|
+
- **117 testes TUI delegations:** `tests/pantheon/tui-delegations.test.ts` com
|
|
67
|
+
117/117 passando, cobrindo board-read, split ativo/recente e toggle de escopo.
|
|
21
68
|
## [v1.5.0-beta.11] - 2026-09-14
|
|
22
69
|
|
|
23
70
|
<!-- 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.13",
|
|
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
package/scripts/dev-tui.sh
CHANGED
|
@@ -20,7 +20,7 @@ command -v npm >/dev/null 2>&1 || { echo "error: npm not found in PATH" >&2; exi
|
|
|
20
20
|
|
|
21
21
|
echo "==> TUI dev source: $TUI_DIR"
|
|
22
22
|
|
|
23
|
-
# 1. Install pinned deps + build dist/tui.js (
|
|
23
|
+
# 1. Install pinned deps + build dist/tui.js (the bundle is the only load path).
|
|
24
24
|
echo "==> Installing TUI dev dependencies (npm ci)"
|
|
25
25
|
npm ci --prefix "$TUI_DIR" --ignore-scripts --no-audit --no-fund
|
|
26
26
|
|
|
@@ -8,8 +8,10 @@ import { isAbsolute, join, resolve } from 'node:path'
|
|
|
8
8
|
import { ROOT, writeIfChanged } from './shared.mjs'
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
|
-
* Copy a plugin's runtime payload (
|
|
12
|
-
* package
|
|
11
|
+
* Copy a plugin's runtime payload (the bundled dist/*, package.json and
|
|
12
|
+
* package-lock.json) from source to destination. Only the bundle is copied —
|
|
13
|
+
* the raw TSX source is never shipped to the destination, so the plugin can
|
|
14
|
+
* be modularized without the loader needing relative imports.
|
|
13
15
|
* @param {string} srcDir - Source plugin directory (e.g. ROOT/src/plugins/tui)
|
|
14
16
|
* @param {string} dstDir - Destination plugin directory
|
|
15
17
|
* @param {object} [options]
|
|
@@ -22,16 +24,11 @@ export function copyPluginFiles(srcDir, dstDir, { dryRun = false } = {}) {
|
|
|
22
24
|
if (!dryRun) mkdirSync(dstDir, { recursive: true })
|
|
23
25
|
if (!dryRun) mkdirSync(join(dstDir, 'dist'), { recursive: true })
|
|
24
26
|
|
|
25
|
-
//
|
|
26
|
-
|
|
27
|
-
if (
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
readFileSync(srcIdx, 'utf8'),
|
|
31
|
-
dryRun,
|
|
32
|
-
)
|
|
33
|
-
if (idxStatus === 'created') result.created++
|
|
34
|
-
else result.skipped++
|
|
27
|
+
// Drop legacy raw copies from previous installs (root index.tsx + dist/tui.tsx).
|
|
28
|
+
// The loader consumes only the bundle, so stale raws must not linger.
|
|
29
|
+
if (!dryRun) {
|
|
30
|
+
rmSync(join(dstDir, 'index.tsx'), { force: true })
|
|
31
|
+
rmSync(join(dstDir, 'dist', 'tui.tsx'), { force: true })
|
|
35
32
|
}
|
|
36
33
|
|
|
37
34
|
// Copy dist/* files
|
package/scripts/sync-tui.mjs
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* If the user hasn't initialized yet → do nothing (silent exit).
|
|
11
11
|
*/
|
|
12
12
|
import { execSync } from 'node:child_process'
|
|
13
|
-
import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from 'node:fs'
|
|
13
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs'
|
|
14
14
|
import { homedir } from 'node:os'
|
|
15
15
|
import { join } from 'node:path'
|
|
16
16
|
import { fileURLToPath, pathToFileURL } from 'node:url'
|
|
@@ -58,9 +58,9 @@ function resolveConfigDir() {
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
/**
|
|
61
|
-
* Copy plugin runtime files (dist/*, package.json,
|
|
62
|
-
*
|
|
63
|
-
*
|
|
61
|
+
* Copy plugin runtime files (the bundled dist/*, package.json,
|
|
62
|
+
* package-lock.json) from srcDir to dstDir. Skips files that are byte-identical.
|
|
63
|
+
* The raw TSX source is never copied — the loader consumes only the bundle.
|
|
64
64
|
* @returns {{ created: number, skipped: number }}
|
|
65
65
|
*/
|
|
66
66
|
function copyPluginFiles(srcDir, dstDir) {
|
|
@@ -69,13 +69,10 @@ function copyPluginFiles(srcDir, dstDir) {
|
|
|
69
69
|
mkdirSync(dstDir, { recursive: true })
|
|
70
70
|
mkdirSync(join(dstDir, 'dist'), { recursive: true })
|
|
71
71
|
|
|
72
|
-
//
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
if (writeIfChanged(join(dstDir, 'index.tsx'), content)) result.created++
|
|
77
|
-
else result.skipped++
|
|
78
|
-
}
|
|
72
|
+
// Drop legacy raw copies from previous installs (root index.tsx + dist/tui.tsx).
|
|
73
|
+
// The loader consumes only the bundle, so stale raws must not linger.
|
|
74
|
+
rmSync(join(dstDir, 'index.tsx'), { force: true })
|
|
75
|
+
rmSync(join(dstDir, 'dist', 'tui.tsx'), { force: true })
|
|
79
76
|
|
|
80
77
|
// dist/*
|
|
81
78
|
const distSrc = join(srcDir, 'dist')
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
* never throw, never send the placeholder).
|
|
11
11
|
*
|
|
12
12
|
* Mirrors the TUI's `src/plugins/tui/src/index.tsx` contract verbatim so both
|
|
13
|
-
* sides agree on what "valid" means. The TUI
|
|
14
|
-
* (dist/tui.
|
|
13
|
+
* sides agree on what "valid" means. The TUI plugin ships as a bundle
|
|
14
|
+
* (dist/tui.js) without the src/pantheon tree, so its local copy is kept
|
|
15
15
|
* in sync — this module is the shared source for `src/pantheon/*` and
|
|
16
16
|
* `src/plugin.ts`.
|
|
17
17
|
*
|
|
@@ -22,8 +22,9 @@ type DelegationEntry = {
|
|
|
22
22
|
read?: boolean;
|
|
23
23
|
/** Internal provenance used to keep a finalized md report authoritative.
|
|
24
24
|
* 'children-only' = a native task() child session with NO board report
|
|
25
|
-
* (
|
|
26
|
-
|
|
25
|
+
* (a native child row); 'md' = board report wins;
|
|
26
|
+
* 'board' = read from .pantheon/board/state.json (cross-session FSM). */
|
|
27
|
+
source?: 'child' | 'live' | 'md' | 'children-only' | 'board';
|
|
27
28
|
};
|
|
28
29
|
/** Parse one delegation report md header into a structured entry.
|
|
29
30
|
* Returns null (skip) when the file is not a recognizable report:
|
|
@@ -49,13 +50,39 @@ declare function readDelegationEntries(dir: string): Promise<DelegationEntry[]>;
|
|
|
49
50
|
* desc — the sort applied by readDelegationEntries). Fail-open: a
|
|
50
51
|
* missing/unreadable directory yields []. */
|
|
51
52
|
declare function readAllDelegationEntries(root: string): Promise<DelegationEntry[]>;
|
|
53
|
+
/** The persisted subset of BackgroundJobRecord the panel consumes. Duck-typed
|
|
54
|
+
* so a corrupt/older record never breaks parsing. */
|
|
55
|
+
type BoardJobRecord = {
|
|
56
|
+
taskID: string;
|
|
57
|
+
parentSessionID: string;
|
|
58
|
+
agent: string;
|
|
59
|
+
description?: string;
|
|
60
|
+
state: string;
|
|
61
|
+
alias: string;
|
|
62
|
+
launchedAt?: number;
|
|
63
|
+
completedAt?: number;
|
|
64
|
+
updatedAt?: number;
|
|
65
|
+
timedOut?: boolean;
|
|
66
|
+
};
|
|
67
|
+
/** The FilePersistence state path: `<root>/.pantheon/board/state.json`. */
|
|
68
|
+
declare function boardStatePath(root: string): string;
|
|
69
|
+
/** Read `.pantheon/board/state.json` (the cross-session job board snapshot).
|
|
70
|
+
* Fail-open: missing file, corrupt JSON, non-array payload or an unreadable
|
|
71
|
+
* path all yield [] — the panel keeps rendering from the other channels. */
|
|
72
|
+
declare function readBoardState(root: string): Promise<BoardJobRecord[]>;
|
|
73
|
+
/** Resolve the PROJECT ROOT used by every pantheon file channel. `directory`
|
|
74
|
+
* wins over `worktree` (the old `resolveDelegationsDir` already did this);
|
|
75
|
+
* an absent/empty root or `/` (no git — e.g. the sandbox test project) falls
|
|
76
|
+
* back to cwd. Standardised here so the delegations md, the board state file
|
|
77
|
+
* and the panel logger all read the SAME root (audit finding: the channels
|
|
78
|
+
* resolved the root independently). Pure — no I/O. */
|
|
79
|
+
declare function resolvePantheonRoot(state: {
|
|
80
|
+
directory?: string;
|
|
81
|
+
worktree?: string;
|
|
82
|
+
} | undefined, cwd?: string): string;
|
|
52
83
|
/** Resolve the directory where the job board writes delegation md reports.
|
|
53
84
|
* The board writes `.pantheon/delegations` RELATIVE to the server cwd,
|
|
54
|
-
* which the TUI exposes as `TuiState.path.directory`.
|
|
55
|
-
* exist on `TuiState.path` (the old `state?.project ?? state?.worktree`
|
|
56
|
-
* resolution was always undefined for the first term) and `worktree` is
|
|
57
|
-
* `/` when there is no git (e.g. the sandbox test project) — a root of
|
|
58
|
-
* `''` or `'/'` must fall back to `process.cwd()`. */
|
|
85
|
+
* which the TUI exposes as `TuiState.path.directory`. */
|
|
59
86
|
declare function resolveDelegationsDir(state: {
|
|
60
87
|
directory?: string;
|
|
61
88
|
worktree?: string;
|
|
@@ -74,17 +101,16 @@ declare function tuiLogPath(projectRoot: string): string;
|
|
|
74
101
|
* mergeDelegationSources. */
|
|
75
102
|
declare function compareDelegationEntries(a: DelegationEntry, b: DelegationEntry): number;
|
|
76
103
|
/** Split the panel list: active jobs (running/retry, stale-marked) first,
|
|
77
|
-
* then the most recent terminal reports
|
|
78
|
-
*
|
|
104
|
+
* then the most recent terminal reports; the remaining tail is collapsed
|
|
105
|
+
* by the View into a single "… +N more" line. Pure — so the history-only panel (no sessionID) is testable
|
|
79
106
|
* without the TUI runtime. */
|
|
80
107
|
declare function splitDelegationList(all: readonly DelegationEntry[], maxRecent?: number, now?: number, staleThresholdMs?: number): {
|
|
81
108
|
active: DelegationEntry[];
|
|
82
109
|
recent: DelegationEntry[];
|
|
83
|
-
archived: DelegationEntry[];
|
|
84
110
|
};
|
|
85
|
-
/**
|
|
86
|
-
* existing tests): active jobs first, then the most
|
|
87
|
-
* reports (capped)
|
|
111
|
+
/** Live-first window used by {@link ceilingDelegationList} (kept for the
|
|
112
|
+
* ceiling helper and existing tests): active jobs first, then the most
|
|
113
|
+
* recent terminal reports (capped). Pure. */
|
|
88
114
|
declare function visibleDelegationList(all: readonly DelegationEntry[], maxTerminal?: number, now?: number, staleThresholdMs?: number): DelegationEntry[];
|
|
89
115
|
/** Default stale-running threshold: 30 minutes. */
|
|
90
116
|
declare const STALE_RUNNING_THRESHOLD_MS: number;
|
|
@@ -101,7 +127,7 @@ declare const IDLE_SILENCE_MS: number;
|
|
|
101
127
|
* delegation is still treated as running by the backend.
|
|
102
128
|
*/
|
|
103
129
|
declare function markStaleIfRunning(entry: DelegationEntry, now: number, thresholdMs?: number): DelegationEntry;
|
|
104
|
-
/** Compact elapsed-time label: "
|
|
130
|
+
/** Compact elapsed-time label, single unit only: "12s"/"3m"/"1h"/"2d" — ticks every
|
|
105
131
|
* second for running jobs. */
|
|
106
132
|
declare function fmtElapsed(ms: number): string;
|
|
107
133
|
/** Elapsed label for one entry: an ACTIVE entry (running/retry/stale-running)
|
|
@@ -122,20 +148,13 @@ declare function delegationSpinnerFrame(now: number): string;
|
|
|
122
148
|
* blocked/paused/scheduled/skipped. There is no `pending` display state: a
|
|
123
149
|
* pre-dispatch tool part maps to `running` in {@link reduceDelegationToolPart}. */
|
|
124
150
|
type DelegationDisplayState = DelegationEntry['state'];
|
|
125
|
-
/** Static glyph per display state. `running` shows its base spinner frame;
|
|
126
|
-
* callers that animate must prefer {@link delegationStateMarker}. Unicode
|
|
127
|
-
* geometric shapes only (no Nerd Font) — shape is an independent channel
|
|
128
|
-
* from color, so rows stay legible without color. */
|
|
129
|
-
declare const DELEGATION_STATE_GLYPHS: Readonly<Record<DelegationDisplayState, string>>;
|
|
130
|
-
declare function delegationStateGlyph(state: DelegationDisplayState): string;
|
|
131
|
-
/** Row marker (`<glyph> `) — the state channel. `running` animates through
|
|
132
|
-
* {@link delegationSpinnerFrame} for the given tick; every other state is
|
|
133
|
-
* static. Pure. */
|
|
134
|
-
declare function delegationStateMarker(state: DelegationDisplayState, now?: number): string;
|
|
135
151
|
/** Semantic tone mapped to the TUI theme at the row ({@link DelegationRow}).
|
|
136
152
|
* Kept separate + pure so the color channel is testable without booting the
|
|
137
153
|
* renderer. */
|
|
138
154
|
type DelegationStateTone = 'warning' | 'error' | 'success' | 'muted';
|
|
155
|
+
/** Color is the ONLY channel separating `stale-running` from a live `running`
|
|
156
|
+
* row — the 4-glyph row design has no dedicated stale shape. Display-only;
|
|
157
|
+
* no behavior change. */
|
|
139
158
|
declare function delegationStateTone(state: DelegationDisplayState): DelegationStateTone;
|
|
140
159
|
type ToolActivity = {
|
|
141
160
|
tool: string;
|
|
@@ -241,7 +260,7 @@ declare function removeDelegationEntry(map: Map<string, LiveDelegationEntry>, pa
|
|
|
241
260
|
* SDK exposes `api.state.part(messageID)`). The native `task` tool spawns a
|
|
242
261
|
* child session with parentID = caller — the same mechanism as
|
|
243
262
|
* pantheon_delegate — so its parts feed the live-map as the native signal
|
|
244
|
-
* (rows
|
|
263
|
+
* (rows come from the children channel). Pure w.r.t. I/O — used
|
|
245
264
|
* by the mount re-scan to re-seed the live map after compaction/attach. */
|
|
246
265
|
declare function collectDelegationToolParts(messages: readonly {
|
|
247
266
|
id?: string;
|
|
@@ -261,6 +280,17 @@ declare function toDelegationEntry(live: LiveDelegationEntry): DelegationEntry;
|
|
|
261
280
|
* terminal md entry is authoritative over a live running entry for the
|
|
262
281
|
* same job (it carries Finalized/timedOut/cancelled from finalize). */
|
|
263
282
|
declare function mergeDelegationSources(live: readonly LiveDelegationEntry[], md: readonly DelegationEntry[]): DelegationEntry[];
|
|
283
|
+
/** Map one persisted board record into the display shape. Returns null for
|
|
284
|
+
* states the panel does not render (reconciled / unknown). Pure. */
|
|
285
|
+
declare function boardRecordToDelegationEntry(record: BoardJobRecord): DelegationEntry | null;
|
|
286
|
+
/** Map a whole board snapshot, dropping unrenderable states. Sorted like every
|
|
287
|
+
* other channel (running first, then most recent). Pure. */
|
|
288
|
+
declare function boardRecordsToDelegationEntries(records: readonly BoardJobRecord[]): DelegationEntry[];
|
|
289
|
+
/** Merge the board over any other channel. The board is AUTHORITATIVE for
|
|
290
|
+
* state/alias/agent (it is the persisted FSM) and it is the only channel
|
|
291
|
+
* that carries jobs from OTHER sessions. Dedup by taskID first, then by
|
|
292
|
+
* (sessionID, alias) — aliases are per parent session. Pure. */
|
|
293
|
+
declare function mergeBoardDelegationSources(base: readonly DelegationEntry[], board: readonly DelegationEntry[]): DelegationEntry[];
|
|
264
294
|
/** Server-aligned session id validity: opencode rejects anything not starting
|
|
265
295
|
* with "ses" (SchemaError). This deliberately mirrors that exact contract —
|
|
266
296
|
* nothing stricter, nothing looser — so a template placeholder ("{sessionID}"),
|
|
@@ -339,28 +369,34 @@ type ChildDelegationLike = {
|
|
|
339
369
|
* (fail-open: a freshly-seen child is assumed active; the 1s poll + md
|
|
340
370
|
* correct it as soon as terminal data exists). */
|
|
341
371
|
declare function childStatusToState(status: string | undefined): 'running' | 'completed' | 'retry';
|
|
342
|
-
/**
|
|
343
|
-
* that split native task() work from pantheon_delegate jobs — the other is
|
|
344
|
-
* {@link delegationIcon}):
|
|
372
|
+
/** Status-only row model: ONE glyph + ONE identity per row.
|
|
345
373
|
*
|
|
346
|
-
*
|
|
347
|
-
*
|
|
348
|
-
*
|
|
349
|
-
*
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
*
|
|
353
|
-
*
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
* Shape
|
|
358
|
-
|
|
359
|
-
declare function
|
|
360
|
-
/** Row
|
|
361
|
-
*
|
|
362
|
-
*
|
|
363
|
-
declare function
|
|
374
|
+
* A row is
|
|
375
|
+
* `{glyph} {alias:7} {elapsed:>5}` plus a muted description line. The short
|
|
376
|
+
* alias (`apo-1`) is the single identity; rows without a board alias show
|
|
377
|
+
* the agent instead (never both). */
|
|
378
|
+
type DelegationRowStatus = 'active' | 'done' | 'failed' | 'retry';
|
|
379
|
+
/** Map every FSM/display state to one of the 4 row kinds. reconciled never
|
|
380
|
+
* reaches the panel (the board parser drops it) but reads as done;
|
|
381
|
+
* cancelled reads as done; startup_failed reads as failed while
|
|
382
|
+
* startup_unknown (no error known) reads as retry. Pure. */
|
|
383
|
+
declare function delegationRowStatus(state: DelegationDisplayState): DelegationRowStatus;
|
|
384
|
+
/** The only 4 glyphs a row may show: animated active, done, failed, retry.
|
|
385
|
+
* Shape is redundant with color (never the only signal). Pure. */
|
|
386
|
+
declare const DELEGATION_ROW_GLYPHS: Readonly<Record<DelegationRowStatus, string>>;
|
|
387
|
+
declare function delegationRowGlyph(status: DelegationRowStatus): string;
|
|
388
|
+
/** Row marker (`<glyph> `) — the single state channel. `active` animates
|
|
389
|
+
* through the 1s spinner for the given tick; every other kind is static.
|
|
390
|
+
* Pure. */
|
|
391
|
+
declare function delegationRowMarker(state: DelegationDisplayState, now?: number): string;
|
|
392
|
+
/** ONE identity per row: the short board alias (`apo-1`); a row without a
|
|
393
|
+
* board alias (native task() child, alias `native-task`) shows the agent
|
|
394
|
+
* instead — never alias + agent stacked. Pure. */
|
|
395
|
+
declare function delegationRowIdentity(entry: DelegationEntry): string;
|
|
396
|
+
/** Fixed alias cell, pad-right + hard-truncate to `width` (default 7) so
|
|
397
|
+
* identities line up across rows. Pure. */
|
|
398
|
+
declare const DELEGATION_ALIAS_WIDTH = 7;
|
|
399
|
+
declare function formatDelegationAlias(identity: string, width?: number): string;
|
|
364
400
|
/** Max description width on the row detail line — the old 180-char slice
|
|
365
401
|
* wrapped the sidebar; 44 keeps one readable line. */
|
|
366
402
|
declare const DELEGATION_DESCRIPTION_MAX = 44;
|
|
@@ -368,21 +404,34 @@ declare const DELEGATION_DESCRIPTION_MAX = 44;
|
|
|
368
404
|
* `max`-length text is left untouched. Grapheme-granular, so an emoji made of
|
|
369
405
|
* several code points is never split into mojibake at the boundary. Pure. */
|
|
370
406
|
declare function truncateDelegationDescription(text: string, max?: number): string;
|
|
371
|
-
/** Fixed elapsed-time box: right-aligned to `width` (default
|
|
372
|
-
* values line up across rows, e.g. `
|
|
407
|
+
/** Fixed elapsed-time box: right-aligned to `width` (default 5) so elapsed
|
|
408
|
+
* values line up across rows, e.g. ` 12s`. A label that already fills
|
|
373
409
|
* the box is returned untouched. Pure. */
|
|
374
|
-
declare const DELEGATION_ELAPSED_WIDTH =
|
|
410
|
+
declare const DELEGATION_ELAPSED_WIDTH = 5;
|
|
375
411
|
declare function formatDelegationElapsed(entry: DelegationEntry, now: number, width?: number): string;
|
|
376
|
-
/**
|
|
377
|
-
*
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
*
|
|
412
|
+
/** Colored left half of a row line: `<marker><alias:7> ` — the state glyph
|
|
413
|
+
* plus the single identity, padded so the muted elapsed column aligns. The
|
|
414
|
+
* row renders this colored lead separately from the muted elapsed tail. Pure. */
|
|
415
|
+
declare function formatDelegationRowLead(entry: DelegationEntry, marker: string): string;
|
|
416
|
+
/** Visible-row ceiling for the panel: the remainder collapses into a single
|
|
417
|
+
* "… +N more" line. Live rows render first, so a running job is never hidden
|
|
418
|
+
* by the cap. */
|
|
419
|
+
declare const DELEGATION_VISIBLE_CEILING = 8;
|
|
420
|
+
/** Header summary: `(N active · M done)` plus `· K failed` only when K > 0.
|
|
421
|
+
* Active counts running/retry AND display-only stale-running (a stale row is
|
|
422
|
+
* still a live job — it must never read as done); failed counts
|
|
423
|
+
* error/startup_failed; cancelled reads as done. Pure. */
|
|
382
424
|
declare function formatDelegationHeader(entries: readonly DelegationEntry[]): string;
|
|
425
|
+
/** Cap the panel: live rows first, then most-recent terminal rows, at most
|
|
426
|
+
* `maxVisible` total. `hidden` is how many were dropped (rendered as
|
|
427
|
+
* "… +N more"). Pure. */
|
|
428
|
+
declare function ceilingDelegationList(all: readonly DelegationEntry[], maxVisible?: number, now?: number): {
|
|
429
|
+
visible: DelegationEntry[];
|
|
430
|
+
hidden: number;
|
|
431
|
+
};
|
|
383
432
|
/** Split a display list into native task() rows vs pantheon_delegate rows.
|
|
384
433
|
* Native = source 'children-only' (no board report); everything else counts
|
|
385
|
-
* as pantheon. Pure — powers the
|
|
434
|
+
* as pantheon. Pure — powers the hooks.log line. */
|
|
386
435
|
declare function countDelegationSources(entries: readonly DelegationEntry[]): {
|
|
387
436
|
native: number;
|
|
388
437
|
pantheon: number;
|
|
@@ -401,15 +450,18 @@ declare function formatPanelLogLine(children: number, pantheon: number, native:
|
|
|
401
450
|
* time.created. A report-less child is a NATIVE task() child (every
|
|
402
451
|
* child of the current session — pantheon_delegate OR the native `task()`
|
|
403
452
|
* tool — carries parentID = caller), so it gets source 'children-only',
|
|
404
|
-
* the internal alias 'native-task'
|
|
453
|
+
* the internal alias 'native-task' instead of a
|
|
405
454
|
* board alias. The 'task nativa' description fallback keeps the row
|
|
406
455
|
* non-empty when the child carries no title.
|
|
407
456
|
* Terminal md state wins over the derived state; a running md defers to
|
|
408
457
|
* the child's live status. A running child is NEVER archived — it always
|
|
409
458
|
* lands in the active split (splitDelegationList active = running/retry).
|
|
459
|
+
* `parentSessionID` (the focused session id) is stamped on report-less
|
|
460
|
+
* children so the row carries its origin session; omit it and they stay
|
|
461
|
+
* unscoped ('').
|
|
410
462
|
* Sorted running-first (compareDelegationEntries).
|
|
411
463
|
* Pure — no I/O. */
|
|
412
|
-
declare function childrenToDelegationEntries(children: readonly ChildDelegationLike[] | undefined, md: readonly DelegationEntry[], now?: number): DelegationEntry[];
|
|
464
|
+
declare function childrenToDelegationEntries(children: readonly ChildDelegationLike[] | undefined, md: readonly DelegationEntry[], now?: number, parentSessionID?: string): DelegationEntry[];
|
|
413
465
|
/** Navigate the TUI to a child session (click/Enter on a delegation row).
|
|
414
466
|
* Returns false when the route API is unavailable or the target id is
|
|
415
467
|
* missing/placeholder — the row stays inert instead of crashing. Only a
|
|
@@ -434,5 +486,5 @@ declare const plugin: TuiPluginModule & {
|
|
|
434
486
|
setup: () => Promise<void>;
|
|
435
487
|
};
|
|
436
488
|
//#endregion
|
|
437
|
-
export { ChildDelegationLike, DELEGATION_DESCRIPTION_MAX, DELEGATION_ELAPSED_WIDTH,
|
|
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 };
|
|
438
490
|
//# sourceMappingURL=tui.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tui.d.ts","names":[],"sources":["../src/index.tsx"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"tui.d.ts","names":[],"sources":["../src/index.tsx"],"mappings":"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"}
|