pantheon-opencode 1.5.0-beta.14 → 1.5.0-beta.15
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 +38 -0
- package/package.json +1 -1
- package/plugin.json +1 -1
- package/pyproject.toml +2 -5
- package/src/agents/zeus.md +4 -26
- package/src/pantheon/background-job-board.ts +4 -4
- package/src/pantheon/delegate-manager.ts +95 -10
- package/src/pantheon/delegation-classifier.ts +3 -4
- package/src/pantheon/delegation-finalize.ts +69 -7
- package/src/pantheon/delegation.ts +16 -4
- package/src/pantheon/presets.d.mts +0 -20
- package/src/pantheon/presets.mjs +0 -64
- package/src/pantheon/toon-codec.ts +1 -1
- package/src/plugin-v2.ts +4 -6
- package/src/plugin.ts +6 -6
- package/src/plugins/pantheon-hooks.ts +1 -1
- package/src/plugins/tui/dist/tui.d.ts +43 -36
- package/src/plugins/tui/dist/tui.d.ts.map +1 -1
- package/src/plugins/tui/dist/tui.js +102 -38
- package/src/plugins/tui/package-lock.json +2 -2
- package/src/plugins/tui/package.json +1 -1
- package/src/plugins/tui/src/index.tsx +168 -67
- package/src/routing.yml +0 -16
- package/scripts/hash_verify.py +0 -192
- package/scripts/test-context-compression.sh +0 -169
- package/src/pantheon/auto-wake.ts +0 -85
- package/src/pantheon/chat-reminders.ts +0 -9
- package/src/pantheon/comment-checker.ts +0 -48
- package/src/pantheon/compaction-assert.ts +0 -160
- package/src/pantheon/compaction-handoff.ts +0 -304
- package/src/pantheon/cost-tracker.ts +0 -108
- package/src/pantheon/dispatch-guard.ts +0 -109
- package/src/pantheon/permission-eval.ts +0 -284
- package/src/pantheon/preemptive-compact.ts +0 -76
- package/src/pantheon/provider-capabilities.ts +0 -221
- package/src/pantheon/provider-stream-tracker.ts +0 -182
- package/src/pantheon/retry-policy.ts +0 -212
- package/src/pantheon/token-opt.ts +0 -689
- package/src/pantheon/v2-events.ts +0 -148
- package/src/pantheon/v2-hooks.ts +0 -287
- package/src/pantheon/v2-tool-definitions.ts +0 -331
- package/src/pantheon/zeus-delegate-with-retry.ts +0 -406
package/src/pantheon/presets.mjs
CHANGED
|
@@ -213,70 +213,6 @@ function loadRoutingYaml(routingPath) {
|
|
|
213
213
|
return routing && typeof routing === 'object' ? routing : null
|
|
214
214
|
}
|
|
215
215
|
|
|
216
|
-
const RETRY_ERROR_TYPES = new Set(['auth', 'rate_limit', 'timeout', 'other'])
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
* Load the R1 per-error-type retry policy from routing.yml (`retry_policy:`).
|
|
220
|
-
* Fail-open: missing/unparseable config yields null (the caller falls back
|
|
221
|
-
* to DEFAULT_RETRY_POLICY) and warns via the optional logger.
|
|
222
|
-
*
|
|
223
|
-
* @param {object} [opts]
|
|
224
|
-
* @param {string} [opts.routingPath]
|
|
225
|
-
* @param {{warn?: Function}} [opts.logger]
|
|
226
|
-
* @returns {Record<string, number>|null} error-type → max retries
|
|
227
|
-
*/
|
|
228
|
-
export function loadRoutingRetryPolicy({ routingPath, logger = console } = {}) {
|
|
229
|
-
try {
|
|
230
|
-
const routing = loadRoutingYaml(routingPath)
|
|
231
|
-
const policy = routing?.retry_policy
|
|
232
|
-
if (!policy || typeof policy !== 'object' || Array.isArray(policy)) return null
|
|
233
|
-
const out = {}
|
|
234
|
-
for (const [type, max] of Object.entries(policy)) {
|
|
235
|
-
if (RETRY_ERROR_TYPES.has(type) && Number.isSafeInteger(max) && max >= 0) {
|
|
236
|
-
out[type] = max
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
return Object.keys(out).length > 0 ? out : null
|
|
240
|
-
} catch (err) {
|
|
241
|
-
const reason = err instanceof Error ? err.message : String(err)
|
|
242
|
-
logger.warn?.(`presets: routing.yml retry_policy unavailable (${reason})`)
|
|
243
|
-
return null
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
/**
|
|
248
|
-
* Load the R1 provider cooldown config from routing.yml (`cooldown:`).
|
|
249
|
-
* Fail-open: missing/unparseable config yields null (caller falls back to
|
|
250
|
-
* DEFAULT_COOLDOWN).
|
|
251
|
-
*
|
|
252
|
-
* @param {object} [opts]
|
|
253
|
-
* @param {string} [opts.routingPath]
|
|
254
|
-
* @param {{warn?: Function}} [opts.logger]
|
|
255
|
-
* @returns {{allowed_fails: number, cooldown_time_seconds: number}|null}
|
|
256
|
-
*/
|
|
257
|
-
export function loadRoutingCooldown({ routingPath, logger = console } = {}) {
|
|
258
|
-
try {
|
|
259
|
-
const routing = loadRoutingYaml(routingPath)
|
|
260
|
-
const cooldown = routing?.cooldown
|
|
261
|
-
if (!cooldown || typeof cooldown !== 'object' || Array.isArray(cooldown)) return null
|
|
262
|
-
const allowedFails = cooldown.allowed_fails
|
|
263
|
-
const cooldownTimeSeconds = cooldown.cooldown_time_seconds
|
|
264
|
-
if (
|
|
265
|
-
!Number.isSafeInteger(allowedFails) ||
|
|
266
|
-
allowedFails < 1 ||
|
|
267
|
-
!Number.isSafeInteger(cooldownTimeSeconds) ||
|
|
268
|
-
cooldownTimeSeconds < 1
|
|
269
|
-
) {
|
|
270
|
-
return null
|
|
271
|
-
}
|
|
272
|
-
return { allowed_fails: allowedFails, cooldown_time_seconds: cooldownTimeSeconds }
|
|
273
|
-
} catch (err) {
|
|
274
|
-
const reason = err instanceof Error ? err.message : String(err)
|
|
275
|
-
logger.warn?.(`presets: routing.yml cooldown unavailable (${reason})`)
|
|
276
|
-
return null
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
|
|
280
216
|
/**
|
|
281
217
|
* Load the R4 per-agent step caps from routing.yml
|
|
282
218
|
* (`agents.<name>.max_steps`). Fail-open: missing config yields {}.
|
|
@@ -53,7 +53,7 @@ function looksNumeric(text: string): boolean {
|
|
|
53
53
|
return INT_RE.test(text) || FLOAT_RE.test(text)
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
/** Nominal chars-per-token ratio (same fixed basis as
|
|
56
|
+
/** Nominal chars-per-token ratio (same fixed basis as toon-codec metering). */
|
|
57
57
|
export const CHARS_PER_TOKEN = 4
|
|
58
58
|
|
|
59
59
|
function charsToTokens(chars: number): number {
|
package/src/plugin-v2.ts
CHANGED
|
@@ -681,12 +681,10 @@ function createV2ToolDefinitionsFromContext(_context: PluginContext): V2ToolDef[
|
|
|
681
681
|
name,
|
|
682
682
|
description: toolDescriptions[name] ?? `Pantheon tool: ${name}`,
|
|
683
683
|
input: { type: 'object' as const, properties: {} },
|
|
684
|
-
// FOLLOW-UP:
|
|
685
|
-
//
|
|
686
|
-
//
|
|
687
|
-
//
|
|
688
|
-
// are likewise unwired. Until then, placeholders resolve to the object
|
|
689
|
-
// shape so the beta host never sees a bare string.
|
|
684
|
+
// FOLLOW-UP: wire the real tool wrappers (costCommand/goalTools) once V1
|
|
685
|
+
// infrastructure is resolvable in the V2 standalone context. Until then,
|
|
686
|
+
// placeholders resolve to the object shape so the beta host never sees a
|
|
687
|
+
// bare string.
|
|
690
688
|
execute: async (_input: Record<string, unknown>, _context: unknown): Promise<V2ToolResult> => {
|
|
691
689
|
return { output: `${name}: ${v2UnavailableMessage}` }
|
|
692
690
|
},
|
package/src/plugin.ts
CHANGED
|
@@ -66,10 +66,10 @@ import { activePresetCandidates, createVisionHandler } from './pantheon/vision.t
|
|
|
66
66
|
const log = createPantheonLogger({ module: 'pantheon-plugin' })
|
|
67
67
|
|
|
68
68
|
// R4: per-agent step caps from routing.yml `agents.<name>.max_steps`
|
|
69
|
-
// (fail-open → {} = no agent capped). R1 retry_policy/cooldown
|
|
70
|
-
//
|
|
71
|
-
//
|
|
72
|
-
//
|
|
69
|
+
// (fail-open → {} = no agent capped). The R1 retry_policy/cooldown block and
|
|
70
|
+
// its presets.mjs loaders were removed together with their only consumer
|
|
71
|
+
// (zeus-delegate-with-retry.ts); the plugin has no retry path (opencode cannot
|
|
72
|
+
// intercept task completion).
|
|
73
73
|
const stepCapTracker = new StepCapTracker(loadRoutingMaxSteps({ logger: log }))
|
|
74
74
|
|
|
75
75
|
// O5: permission.task glob rules from routing.yml `permission.task`
|
|
@@ -517,8 +517,8 @@ const plugin: Plugin = async (input: PluginInput) => {
|
|
|
517
517
|
|
|
518
518
|
// Wave 4 (PR #46): /cost — delegation cost + token visibility. Reads
|
|
519
519
|
// opencode.db read-only via the single node:sqlite backend.
|
|
520
|
-
// Fully wired (
|
|
521
|
-
//
|
|
520
|
+
// Fully wired. (opencode 1.18.x cannot intercept task completion via hooks,
|
|
521
|
+
// so empty-result handling lives in delegation-classifier.ts.)
|
|
522
522
|
const costCommand = createCostCommand()
|
|
523
523
|
const modelCommand = createModelCommand()
|
|
524
524
|
|
|
@@ -783,7 +783,7 @@ function delegationAgent(tool: string, args?: unknown): string {
|
|
|
783
783
|
* panel tracks the child end-to-end. Fire-and-forget and silent: a mirror
|
|
784
784
|
* failure must never surface into the tool call or the transcript.
|
|
785
785
|
* registerLaunchIfAbsent keeps it idempotent against any other dispatcher
|
|
786
|
-
* (
|
|
786
|
+
* (plugin double-load, repeated after-hook firings).
|
|
787
787
|
*/
|
|
788
788
|
function mirrorNativeBackgroundDispatch(
|
|
789
789
|
input: { tool: string; sessionID: string },
|
|
@@ -44,11 +44,12 @@ declare function parseDelegationMarkdown(raw: string, fileAlias?: string, sessio
|
|
|
44
44
|
declare function readDelegationEntries(dir: string): Promise<DelegationEntry[]>;
|
|
45
45
|
/** Read delegation reports from EVERY session under
|
|
46
46
|
* `<root>/.pantheon/delegations/<sessionID>/<alias>.md` — the panel's
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
47
|
+
* ENRICHMENT source. The read is deliberately unfiltered (each entry carries
|
|
48
|
+
* its directory's sessionID, so a taskID match can enrich any channel);
|
|
49
|
+
* callers MUST scope the merged result with {@link filterDelegationsToSession}
|
|
50
|
+
* before rendering — only the active session's reports are shown. Entries are
|
|
51
|
+
* running first, Finalized desc (the sort applied by readDelegationEntries).
|
|
52
|
+
* Fail-open: a missing/unreadable directory yields []. */
|
|
52
53
|
declare function readAllDelegationEntries(root: string): Promise<DelegationEntry[]>;
|
|
53
54
|
/** The persisted subset of BackgroundJobRecord the panel consumes. Duck-typed
|
|
54
55
|
* so a corrupt/older record never breaks parsing. */
|
|
@@ -122,6 +123,11 @@ declare const IDLE_SILENCE_MS: number;
|
|
|
122
123
|
* board; these constants only control which rows enter the TUI window. */
|
|
123
124
|
declare const DELEGATION_DONE_RETENTION_MS: number;
|
|
124
125
|
declare const DELEGATION_FAILED_RETENTION_MS: number;
|
|
126
|
+
/** Alias-less NATIVE task() live entries never receive a board alias (the
|
|
127
|
+
* task tool output carries none), so the 30s alias-less prune in
|
|
128
|
+
* mergeChildDelegationSources must not apply to them — 5 minutes covers a
|
|
129
|
+
* slow child listing while still bounding the live map. */
|
|
130
|
+
declare const NATIVE_LIVE_ALIASLESS_TTL_MS: number;
|
|
125
131
|
/**
|
|
126
132
|
* Mark a running entry as `stale-running` if it has been running longer than
|
|
127
133
|
* the threshold AND has no recent activity (no `updatedAt` change in the last
|
|
@@ -154,11 +160,12 @@ declare function delegationSpinnerFrame(now: number): string;
|
|
|
154
160
|
type DelegationDisplayState = DelegationEntry['state'];
|
|
155
161
|
/** Semantic tone mapped to the TUI theme at the row ({@link DelegationRow}).
|
|
156
162
|
* Kept separate + pure so the color channel is testable without booting the
|
|
157
|
-
* renderer.
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
*
|
|
163
|
+
* renderer. Every display state resolves to one of the three status colors;
|
|
164
|
+
* the row paints its whole content with it (see {@link DelegationRow}). */
|
|
165
|
+
type DelegationStateTone = 'warning' | 'error' | 'success';
|
|
166
|
+
/** Status → color mapping for the whole-row tone. Red = failure, green =
|
|
167
|
+
* terminal, yellow = in flight. The glyph remains a redundant channel so the
|
|
168
|
+
* state stays legible in monochrome. Display-only; no behavior change. */
|
|
162
169
|
declare function delegationStateTone(state: DelegationDisplayState): DelegationStateTone;
|
|
163
170
|
type ToolActivity = {
|
|
164
171
|
tool: string;
|
|
@@ -291,10 +298,29 @@ declare function boardRecordToDelegationEntry(record: BoardJobRecord): Delegatio
|
|
|
291
298
|
* other channel (running first, then most recent). Pure. */
|
|
292
299
|
declare function boardRecordsToDelegationEntries(records: readonly BoardJobRecord[]): DelegationEntry[];
|
|
293
300
|
/** Merge the board over any other channel. The board is AUTHORITATIVE for
|
|
294
|
-
* state/alias/agent (it is the persisted FSM)
|
|
295
|
-
*
|
|
296
|
-
*
|
|
301
|
+
* state/alias/agent (it is the persisted FSM). This merge is intentionally
|
|
302
|
+
* UNSCOPED so the board can enrich an active-session row (dedup by taskID);
|
|
303
|
+
* the caller scopes the merged list with {@link filterDelegationsToSession},
|
|
304
|
+
* which is what keeps other-session board jobs out of the panel. Dedup by
|
|
305
|
+
* taskID first, then by (sessionID, alias) — aliases are per parent session. Pure. */
|
|
297
306
|
declare function mergeBoardDelegationSources(base: readonly DelegationEntry[], board: readonly DelegationEntry[]): DelegationEntry[];
|
|
307
|
+
/** Scope a fully-merged display list to the ACTIVE session only.
|
|
308
|
+
*
|
|
309
|
+
* The panel is session-scoped: rows from other sessions (board snapshot, md
|
|
310
|
+
* history under `.pantheon/delegations/<other-session>/`) and rows with no
|
|
311
|
+
* attributable session (empty sessionID) are DROPPED. The previous
|
|
312
|
+
* cross-session behavior rendered those rows and clicking them led to
|
|
313
|
+
* "Session not found" — there is no cross-session channel anymore.
|
|
314
|
+
*
|
|
315
|
+
* The board/md channels still feed the merge UNFILTERED so the board can
|
|
316
|
+
* ENRICH an active-session row with state/alias/agent (dedup by taskID), but
|
|
317
|
+
* they can never introduce a row for another session: this filter is applied
|
|
318
|
+
* ONCE, after every merge (children + live + md + board).
|
|
319
|
+
*
|
|
320
|
+
* Returns [] when no active session resolves (null/placeholder) — there is no
|
|
321
|
+
* scope to show. Native children always carry the active session id (stamped
|
|
322
|
+
* by `childrenToDelegationEntries`), so they survive the filter. Pure. */
|
|
323
|
+
declare function filterDelegationsToSession(entries: readonly DelegationEntry[], activeSessionID: string | null | undefined): DelegationEntry[];
|
|
298
324
|
/** Server-aligned session id validity: opencode rejects anything not starting
|
|
299
325
|
* with "ses" (SchemaError). This deliberately mirrors that exact contract —
|
|
300
326
|
* nothing stricter, nothing looser — so a template placeholder ("{sessionID}"),
|
|
@@ -394,8 +420,9 @@ declare function delegationRowGlyph(status: DelegationRowStatus): string;
|
|
|
394
420
|
* Pure. */
|
|
395
421
|
declare function delegationRowMarker(state: DelegationDisplayState, now?: number): string;
|
|
396
422
|
/** ONE identity per row: the short board alias (`apo-1`); a row without a
|
|
397
|
-
* board alias (native task() child
|
|
398
|
-
*
|
|
423
|
+
* board alias (native task() child `native-task` / `native-<id>`, or an
|
|
424
|
+
* alias-less native live row `live-<callID>` kept as children-only) shows
|
|
425
|
+
* the agent instead — never alias + agent stacked. Pure. */
|
|
399
426
|
declare function delegationRowIdentity(entry: DelegationEntry): string;
|
|
400
427
|
/** Fixed alias cell, pad-right + hard-truncate to `width` (default 7) so
|
|
401
428
|
* identities line up across rows. Pure. */
|
|
@@ -447,26 +474,6 @@ declare function countDelegationSources(entries: readonly DelegationEntry[]): {
|
|
|
447
474
|
* breakdown (pantheon = children WITH a board report, native = children
|
|
448
475
|
* WITHOUT one). Pure — the View logs the returned string verbatim. */
|
|
449
476
|
declare function formatPanelLogLine(children: number, pantheon: number, native: number, md: number, events: number): string;
|
|
450
|
-
/** Turn child sessions (PRIMARY) enriched with md reports into the display
|
|
451
|
-
* list. One entry per child id (duplicates across re-fetches collapse).
|
|
452
|
-
* The md report is matched by `Task ID` (== child.id) and supplies alias,
|
|
453
|
-
* agent, description, terminal state and duration. A child without a
|
|
454
|
-
* report still renders: description from its title, agent from the child
|
|
455
|
-
* itself (fallback 'agent'), state derived from its status, startedAt from
|
|
456
|
-
* time.created. A report-less child is a NATIVE task() child (every
|
|
457
|
-
* child of the current session — pantheon_delegate OR the native `task()`
|
|
458
|
-
* tool — carries parentID = caller), so it gets source 'children-only',
|
|
459
|
-
* the internal alias 'native-task' instead of a
|
|
460
|
-
* board alias. The 'task nativa' description fallback keeps the row
|
|
461
|
-
* non-empty when the child carries no title.
|
|
462
|
-
* Terminal md state wins over the derived state; a running md defers to
|
|
463
|
-
* the child's live status. A running child is NEVER archived — it always
|
|
464
|
-
* lands in the active split (splitDelegationList active = running/retry).
|
|
465
|
-
* `parentSessionID` (the focused session id) is stamped on report-less
|
|
466
|
-
* children so the row carries its origin session; omit it and they stay
|
|
467
|
-
* unscoped ('').
|
|
468
|
-
* Sorted running-first (compareDelegationEntries).
|
|
469
|
-
* Pure — no I/O. */
|
|
470
477
|
declare function childrenToDelegationEntries(children: readonly ChildDelegationLike[] | undefined, md: readonly DelegationEntry[], now?: number, parentSessionID?: string): DelegationEntry[];
|
|
471
478
|
/** Navigate the TUI to a child session (click/Enter on a delegation row).
|
|
472
479
|
* Returns false when the route API is unavailable or the target id is
|
|
@@ -496,5 +503,5 @@ declare const plugin: TuiPluginModule & {
|
|
|
496
503
|
setup: () => Promise<void>;
|
|
497
504
|
};
|
|
498
505
|
//#endregion
|
|
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 };
|
|
506
|
+
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, NATIVE_LIVE_ALIASLESS_TTL_MS, 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, filterDelegationsToSession, 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 };
|
|
500
507
|
//# 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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"}
|
|
@@ -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.15";
|
|
169
169
|
}
|
|
170
170
|
/**
|
|
171
171
|
* usage-bar — AI subscription usage gauge for the opencode TUI.
|
|
@@ -832,11 +832,12 @@ async function readDelegationEntries(dir) {
|
|
|
832
832
|
}
|
|
833
833
|
/** Read delegation reports from EVERY session under
|
|
834
834
|
* `<root>/.pantheon/delegations/<sessionID>/<alias>.md` — the panel's
|
|
835
|
-
*
|
|
836
|
-
*
|
|
837
|
-
*
|
|
838
|
-
*
|
|
839
|
-
*
|
|
835
|
+
* ENRICHMENT source. The read is deliberately unfiltered (each entry carries
|
|
836
|
+
* its directory's sessionID, so a taskID match can enrich any channel);
|
|
837
|
+
* callers MUST scope the merged result with {@link filterDelegationsToSession}
|
|
838
|
+
* before rendering — only the active session's reports are shown. Entries are
|
|
839
|
+
* running first, Finalized desc (the sort applied by readDelegationEntries).
|
|
840
|
+
* Fail-open: a missing/unreadable directory yields []. */
|
|
840
841
|
async function readAllDelegationEntries(root) {
|
|
841
842
|
return readDelegationEntries(join(root, ".pantheon", "delegations"));
|
|
842
843
|
}
|
|
@@ -965,6 +966,11 @@ const IDLE_SILENCE_MS = 60 * 1e3;
|
|
|
965
966
|
* board; these constants only control which rows enter the TUI window. */
|
|
966
967
|
const DELEGATION_DONE_RETENTION_MS = 120 * 1e3;
|
|
967
968
|
const DELEGATION_FAILED_RETENTION_MS = 600 * 1e3;
|
|
969
|
+
/** Alias-less NATIVE task() live entries never receive a board alias (the
|
|
970
|
+
* task tool output carries none), so the 30s alias-less prune in
|
|
971
|
+
* mergeChildDelegationSources must not apply to them — 5 minutes covers a
|
|
972
|
+
* slow child listing while still bounding the live map. */
|
|
973
|
+
const NATIVE_LIVE_ALIASLESS_TTL_MS = 300 * 1e3;
|
|
968
974
|
/**
|
|
969
975
|
* Mark a running entry as `stale-running` if it has been running longer than
|
|
970
976
|
* the threshold AND has no recent activity (no `updatedAt` change in the last
|
|
@@ -1048,20 +1054,21 @@ function delegationSpinnerFrame(now) {
|
|
|
1048
1054
|
* pre-dispatch tool part maps to `running` in {@link reduceDelegationToolPart}. */
|
|
1049
1055
|
/** Semantic tone mapped to the TUI theme at the row ({@link DelegationRow}).
|
|
1050
1056
|
* Kept separate + pure so the color channel is testable without booting the
|
|
1051
|
-
* renderer.
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
*
|
|
1057
|
+
* renderer. Every display state resolves to one of the three status colors;
|
|
1058
|
+
* the row paints its whole content with it (see {@link DelegationRow}). */
|
|
1059
|
+
/** Status → color mapping for the whole-row tone. Red = failure, green =
|
|
1060
|
+
* terminal, yellow = in flight. The glyph remains a redundant channel so the
|
|
1061
|
+
* state stays legible in monochrome. Display-only; no behavior change. */
|
|
1055
1062
|
function delegationStateTone(state) {
|
|
1056
1063
|
switch (state) {
|
|
1057
1064
|
case "running":
|
|
1058
1065
|
case "retry":
|
|
1059
|
-
case "startup_unknown":
|
|
1066
|
+
case "startup_unknown":
|
|
1060
1067
|
case "stale-running": return "warning";
|
|
1061
1068
|
case "error":
|
|
1062
1069
|
case "startup_failed": return "error";
|
|
1063
|
-
case "completed":
|
|
1064
|
-
case "cancelled": return "
|
|
1070
|
+
case "completed":
|
|
1071
|
+
case "cancelled": return "success";
|
|
1065
1072
|
}
|
|
1066
1073
|
}
|
|
1067
1074
|
/** Bounded tracker: child session id → latest running tool call. */
|
|
@@ -1136,13 +1143,11 @@ function mergeChildDelegationSources(children, live) {
|
|
|
1136
1143
|
bySessionAlias.set(key(entry.sessionID, entry.alias), index);
|
|
1137
1144
|
});
|
|
1138
1145
|
for (const liveEntry of live) {
|
|
1139
|
-
|
|
1146
|
+
const aliaslessTTL = liveEntry.tool === "task" ? NATIVE_LIVE_ALIASLESS_TTL_MS : 3e4;
|
|
1147
|
+
if (liveEntry.alias === null && liveEntry.taskID === null && Date.now() - liveEntry.startedAt > aliaslessTTL) continue;
|
|
1140
1148
|
const incoming = toDelegationEntry(liveEntry);
|
|
1141
1149
|
const isNativeLive = liveEntry.tool === "task" && liveEntry.alias === null;
|
|
1142
|
-
if (isNativeLive)
|
|
1143
|
-
incoming.source = "children-only";
|
|
1144
|
-
incoming.alias = "native-task";
|
|
1145
|
-
}
|
|
1150
|
+
if (isNativeLive) incoming.source = "children-only";
|
|
1146
1151
|
const index = (incoming.taskID !== void 0 ? byTask.get(incoming.taskID) : void 0) ?? (incoming.alias !== "" ? bySessionAlias.get(key(incoming.sessionID, incoming.alias)) : void 0);
|
|
1147
1152
|
if (index === void 0) {
|
|
1148
1153
|
result.push(incoming);
|
|
@@ -1465,10 +1470,29 @@ function boardRecordsToDelegationEntries(records) {
|
|
|
1465
1470
|
out.sort(compareDelegationEntries);
|
|
1466
1471
|
return out;
|
|
1467
1472
|
}
|
|
1473
|
+
/** Active (non-terminal) display states — a job in one of these is still live. */
|
|
1474
|
+
function isActiveDelegationState(state) {
|
|
1475
|
+
return state === "running" || state === "retry" || state === "stale-running";
|
|
1476
|
+
}
|
|
1477
|
+
/** Temporal guard for the board merge (recycled-alias regression): board
|
|
1478
|
+
* aliases recycle across jobs (apo-1 of a previous job), so a board
|
|
1479
|
+
* terminal record only closes a running entry when its Finalized timestamp
|
|
1480
|
+
* is STRICTLY NEWER than the entry it would close. Older/equal/missing
|
|
1481
|
+
* keeps the live entry — when in doubt the live job wins. Pure. */
|
|
1482
|
+
function shouldKeepRunningOverBoardTerminal(existing, incoming) {
|
|
1483
|
+
if (existing === void 0) return false;
|
|
1484
|
+
if (!isActiveDelegationState(existing.state)) return false;
|
|
1485
|
+
if (isActiveDelegationState(incoming.state)) return false;
|
|
1486
|
+
const incomingTs = incoming.updatedAt;
|
|
1487
|
+
if (incomingTs === null) return true;
|
|
1488
|
+
return incomingTs <= (existing.updatedAt ?? existing.startedAt);
|
|
1489
|
+
}
|
|
1468
1490
|
/** Merge the board over any other channel. The board is AUTHORITATIVE for
|
|
1469
|
-
* state/alias/agent (it is the persisted FSM)
|
|
1470
|
-
*
|
|
1471
|
-
*
|
|
1491
|
+
* state/alias/agent (it is the persisted FSM). This merge is intentionally
|
|
1492
|
+
* UNSCOPED so the board can enrich an active-session row (dedup by taskID);
|
|
1493
|
+
* the caller scopes the merged list with {@link filterDelegationsToSession},
|
|
1494
|
+
* which is what keeps other-session board jobs out of the panel. Dedup by
|
|
1495
|
+
* taskID first, then by (sessionID, alias) — aliases are per parent session. Pure. */
|
|
1472
1496
|
function mergeBoardDelegationSources(base, board) {
|
|
1473
1497
|
const key = (sessionID, alias) => `${sessionID}\u0000${alias}`;
|
|
1474
1498
|
const byTaskID = /* @__PURE__ */ new Map();
|
|
@@ -1487,6 +1511,7 @@ function mergeBoardDelegationSources(base, board) {
|
|
|
1487
1511
|
bySessionAlias.set(key(incoming.sessionID, incoming.alias), next);
|
|
1488
1512
|
continue;
|
|
1489
1513
|
}
|
|
1514
|
+
if (shouldKeepRunningOverBoardTerminal(out[index], incoming)) continue;
|
|
1490
1515
|
out[index] = {
|
|
1491
1516
|
...incoming,
|
|
1492
1517
|
sessionID: incoming.sessionID !== "" ? incoming.sessionID : out[index]?.sessionID ?? ""
|
|
@@ -1495,6 +1520,26 @@ function mergeBoardDelegationSources(base, board) {
|
|
|
1495
1520
|
out.sort(compareDelegationEntries);
|
|
1496
1521
|
return out;
|
|
1497
1522
|
}
|
|
1523
|
+
/** Scope a fully-merged display list to the ACTIVE session only.
|
|
1524
|
+
*
|
|
1525
|
+
* The panel is session-scoped: rows from other sessions (board snapshot, md
|
|
1526
|
+
* history under `.pantheon/delegations/<other-session>/`) and rows with no
|
|
1527
|
+
* attributable session (empty sessionID) are DROPPED. The previous
|
|
1528
|
+
* cross-session behavior rendered those rows and clicking them led to
|
|
1529
|
+
* "Session not found" — there is no cross-session channel anymore.
|
|
1530
|
+
*
|
|
1531
|
+
* The board/md channels still feed the merge UNFILTERED so the board can
|
|
1532
|
+
* ENRICH an active-session row with state/alias/agent (dedup by taskID), but
|
|
1533
|
+
* they can never introduce a row for another session: this filter is applied
|
|
1534
|
+
* ONCE, after every merge (children + live + md + board).
|
|
1535
|
+
*
|
|
1536
|
+
* Returns [] when no active session resolves (null/placeholder) — there is no
|
|
1537
|
+
* scope to show. Native children always carry the active session id (stamped
|
|
1538
|
+
* by `childrenToDelegationEntries`), so they survive the filter. Pure. */
|
|
1539
|
+
function filterDelegationsToSession(entries, activeSessionID) {
|
|
1540
|
+
if (!isValidSessionId(activeSessionID)) return [];
|
|
1541
|
+
return entries.filter((entry) => entry.sessionID === activeSessionID);
|
|
1542
|
+
}
|
|
1498
1543
|
/** Server-aligned session id validity: opencode rejects anything not starting
|
|
1499
1544
|
* with "ses" (SchemaError). This deliberately mirrors that exact contract —
|
|
1500
1545
|
* nothing stricter, nothing looser — so a template placeholder ("{sessionID}"),
|
|
@@ -1592,10 +1637,13 @@ function delegationRowMarker(state, now = Date.now()) {
|
|
|
1592
1637
|
return `${status === "active" ? delegationSpinnerFrame(now) : delegationRowGlyph(status)} `;
|
|
1593
1638
|
}
|
|
1594
1639
|
/** ONE identity per row: the short board alias (`apo-1`); a row without a
|
|
1595
|
-
* board alias (native task() child
|
|
1596
|
-
*
|
|
1640
|
+
* board alias (native task() child `native-task` / `native-<id>`, or an
|
|
1641
|
+
* alias-less native live row `live-<callID>` kept as children-only) shows
|
|
1642
|
+
* the agent instead — never alias + agent stacked. Pure. */
|
|
1597
1643
|
function delegationRowIdentity(entry) {
|
|
1598
|
-
if (entry.
|
|
1644
|
+
if (entry.agent === "") return entry.alias;
|
|
1645
|
+
if (entry.alias === "native-task" || entry.alias.startsWith("native-")) return entry.agent;
|
|
1646
|
+
if (entry.alias.startsWith("live-") && entry.source === "children-only") return entry.agent;
|
|
1599
1647
|
return entry.alias;
|
|
1600
1648
|
}
|
|
1601
1649
|
/** Fixed alias cell, pad-right + hard-truncate to `width` (default 7) so
|
|
@@ -1713,11 +1761,13 @@ function formatPanelLogLine(children, pantheon, native, md, events) {
|
|
|
1713
1761
|
* itself (fallback 'agent'), state derived from its status, startedAt from
|
|
1714
1762
|
* time.created. A report-less child is a NATIVE task() child (every
|
|
1715
1763
|
* child of the current session — pantheon_delegate OR the native `task()`
|
|
1716
|
-
* tool — carries parentID = caller), so it gets source 'children-only',
|
|
1717
|
-
*
|
|
1718
|
-
* board alias. The 'task nativa' description fallback
|
|
1719
|
-
* non-empty when the child carries no title.
|
|
1720
|
-
*
|
|
1764
|
+
* tool — carries parentID = caller), so it gets source 'children-only', a
|
|
1765
|
+
* per-child alias 'native-<last4 of the child id>' (one identity per native
|
|
1766
|
+
* row) instead of a board alias. The 'task nativa' description fallback
|
|
1767
|
+
* keeps the row non-empty when the child carries no title.
|
|
1768
|
+
* A FRESH terminal md state wins over the derived state (a stale md report
|
|
1769
|
+
* from a previous incarnation never flips a live child — see
|
|
1770
|
+
* mdTerminalCoversChild); a running md defers to
|
|
1721
1771
|
* the child's live status. A running child is NEVER archived — it always
|
|
1722
1772
|
* lands in the active split (splitDelegationList active = running/retry).
|
|
1723
1773
|
* `parentSessionID` (the focused session id) is stamped on report-less
|
|
@@ -1725,6 +1775,20 @@ function formatPanelLogLine(children, pantheon, native, md, events) {
|
|
|
1725
1775
|
* unscoped ('').
|
|
1726
1776
|
* Sorted running-first (compareDelegationEntries).
|
|
1727
1777
|
* Pure — no I/O. */
|
|
1778
|
+
/** Temporal guard for the children channel (same recycled-alias class as the
|
|
1779
|
+
* board merge): an md terminal report matched by taskID may still belong to
|
|
1780
|
+
* a PREVIOUS job incarnation. Accept it only when its Finalized timestamp
|
|
1781
|
+
* covers the child's latest activity, when either side has no timestamp to
|
|
1782
|
+
* compare, or when both startedAt agree on a single job incarnation.
|
|
1783
|
+
* Pure — no I/O. */
|
|
1784
|
+
function mdTerminalCoversChild(md, child) {
|
|
1785
|
+
const childUpdated = child.time?.updated;
|
|
1786
|
+
if (md.updatedAt !== null && childUpdated !== void 0) {
|
|
1787
|
+
if (md.updatedAt >= childUpdated) return true;
|
|
1788
|
+
return md.startedAt === child.time?.created;
|
|
1789
|
+
}
|
|
1790
|
+
return true;
|
|
1791
|
+
}
|
|
1728
1792
|
function childrenToDelegationEntries(children, md, now = Date.now(), parentSessionID = "") {
|
|
1729
1793
|
const byTaskID = /* @__PURE__ */ new Map();
|
|
1730
1794
|
for (const m of md) if (m.taskID !== void 0 && !byTaskID.has(m.taskID)) byTaskID.set(m.taskID, m);
|
|
@@ -1734,9 +1798,9 @@ function childrenToDelegationEntries(children, md, now = Date.now(), parentSessi
|
|
|
1734
1798
|
if (child.id === "" || seen.has(child.id)) continue;
|
|
1735
1799
|
seen.add(child.id);
|
|
1736
1800
|
const mdEntry = byTaskID.get(child.id);
|
|
1737
|
-
const state = mdEntry !== void 0 && mdEntry.state !== "running" ? mdEntry.state : childStatusToState(child.status);
|
|
1801
|
+
const state = mdEntry !== void 0 && mdEntry.state !== "running" && mdTerminalCoversChild(mdEntry, child) ? mdEntry.state : childStatusToState(child.status);
|
|
1738
1802
|
out.push({
|
|
1739
|
-
alias: mdEntry?.alias ??
|
|
1803
|
+
alias: mdEntry?.alias ?? `native-${child.id.slice(-4)}`,
|
|
1740
1804
|
sessionID: mdEntry?.sessionID ?? parentSessionID,
|
|
1741
1805
|
taskID: child.id,
|
|
1742
1806
|
agent: mdEntry?.agent ?? child.agent ?? "agent",
|
|
@@ -1866,7 +1930,7 @@ function DelegationRow(props) {
|
|
|
1866
1930
|
get children() {
|
|
1867
1931
|
var _el$18 = createElement("text");
|
|
1868
1932
|
insert(_el$18, () => ` ${description()}`);
|
|
1869
|
-
effect((_$p) => setProp(_el$18, "fg",
|
|
1933
|
+
effect((_$p) => setProp(_el$18, "fg", tone(), _$p));
|
|
1870
1934
|
return _el$18;
|
|
1871
1935
|
}
|
|
1872
1936
|
}), null);
|
|
@@ -1877,12 +1941,12 @@ function DelegationRow(props) {
|
|
|
1877
1941
|
children: (a) => (() => {
|
|
1878
1942
|
var _el$19 = createElement("text");
|
|
1879
1943
|
insert(_el$19, () => ` ↳ ${truncateDelegationDescription(`${a().tool}${a().summary !== "" ? ` ${a().summary}` : ""}`)}`);
|
|
1880
|
-
effect((_$p) => setProp(_el$19, "fg",
|
|
1944
|
+
effect((_$p) => setProp(_el$19, "fg", tone(), _$p));
|
|
1881
1945
|
return _el$19;
|
|
1882
1946
|
})()
|
|
1883
1947
|
}), null);
|
|
1884
1948
|
effect((_p$) => {
|
|
1885
|
-
var _v$5 = tone(), _v$6 =
|
|
1949
|
+
var _v$5 = tone(), _v$6 = tone();
|
|
1886
1950
|
_v$5 !== _p$.e && (_p$.e = setProp(_el$16, "fg", _v$5, _p$.e));
|
|
1887
1951
|
_v$6 !== _p$.t && (_p$.t = setProp(_el$17, "fg", _v$6, _p$.t));
|
|
1888
1952
|
return _p$;
|
|
@@ -1975,8 +2039,8 @@ function View(props) {
|
|
|
1975
2039
|
api: props.api
|
|
1976
2040
|
});
|
|
1977
2041
|
if (sessionID === null) {
|
|
1978
|
-
setChildDelegations(mergeBoardDelegationSources(md, board));
|
|
1979
|
-
panelLog.info(`${formatPanelLogLine(0, 0, 0, md.length, eventRefreshCount)} (no sessionID —
|
|
2042
|
+
setChildDelegations(filterDelegationsToSession(mergeBoardDelegationSources(md, board), sessionID));
|
|
2043
|
+
panelLog.info(`${formatPanelLogLine(0, 0, 0, md.length, eventRefreshCount)} (no sessionID — inactive panel)`);
|
|
1980
2044
|
return;
|
|
1981
2045
|
}
|
|
1982
2046
|
let children = [];
|
|
@@ -2002,7 +2066,7 @@ function View(props) {
|
|
|
2002
2066
|
})), md, now(), sessionID);
|
|
2003
2067
|
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);
|
|
2004
2068
|
const liveEntries = [...props.liveStore.map.values()].filter((entry) => entry.sessionID === sessionID);
|
|
2005
|
-
setChildDelegations(mergeBoardDelegationSources(mergeChildDelegationSources(childEntries, liveEntries), board));
|
|
2069
|
+
setChildDelegations(filterDelegationsToSession(mergeBoardDelegationSources(mergeChildDelegationSources(childEntries, liveEntries), board), sessionID));
|
|
2006
2070
|
const counts = countDelegationSources(childEntries);
|
|
2007
2071
|
panelLog.info(formatPanelLogLine(children.length, counts.pantheon, counts.native, md.length, eventRefreshCount));
|
|
2008
2072
|
} finally {
|
|
@@ -2314,6 +2378,6 @@ const plugin = {
|
|
|
2314
2378
|
setup: async () => {}
|
|
2315
2379
|
};
|
|
2316
2380
|
//#endregion
|
|
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 };
|
|
2381
|
+
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, NATIVE_LIVE_ALIASLESS_TTL_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, filterDelegationsToSession, 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 };
|
|
2318
2382
|
|
|
2319
2383
|
//# 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.15",
|
|
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.15",
|
|
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.15",
|
|
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": {
|