@oh-my-pi/pi-tui 18.4.5 → 18.4.8
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 +42 -0
- package/dist/types/apps/git/sidebar.d.ts +2 -2
- package/dist/types/chat/recap-notice.d.ts +13 -0
- package/dist/types/components/editor.d.ts +15 -3
- package/dist/types/components/input.d.ts +11 -1
- package/dist/types/native/backend.d.ts +3 -2
- package/dist/types/native/blobs.d.ts +1 -1
- package/dist/types/native/node.d.ts +63 -1
- package/dist/types/overlays/agent-hub-projection.d.ts +9 -0
- package/dist/types/overlays/ask-dialog.d.ts +9 -5
- package/dist/types/overlays/copy-selector.d.ts +0 -23
- package/dist/types/overlays/error-banner.d.ts +5 -2
- package/dist/types/overlays/hook-editor.d.ts +12 -0
- package/dist/types/overlays/jobs-panel.d.ts +25 -1
- package/dist/types/overlays/rewind-selector.d.ts +17 -4
- package/dist/types/prompt/custom-editor.d.ts +16 -8
- package/dist/types/prompt/welcome.d.ts +3 -3
- package/dist/types/status-line/component.d.ts +2 -0
- package/dist/types/status-line/host.d.ts +2 -0
- package/dist/types/status-line/metrics.d.ts +4 -0
- package/dist/types/status-line/types.d.ts +13 -2
- package/dist/types/theme/defaults/index.d.ts +700 -0
- package/dist/types/theme/schema.d.ts +18 -0
- package/dist/types/tui.d.ts +8 -1
- package/package.json +9 -9
- package/src/apps/git/sidebar.ts +15 -2
- package/src/chat/assistant-message.ts +2 -2
- package/src/chat/recap-notice.ts +30 -0
- package/src/chat/tool-execution.ts +19 -3
- package/src/chat/user-message.ts +2 -1
- package/src/components/editor.ts +88 -14
- package/src/components/input.ts +57 -1
- package/src/native/backend.ts +72 -17
- package/src/native/blobs.ts +1 -1
- package/src/native/encode.ts +1 -0
- package/src/native/node.ts +108 -1
- package/src/native/reconcile.ts +5 -4
- package/src/overlays/agent-hub-projection.ts +25 -0
- package/src/overlays/agent-hub.ts +4 -15
- package/src/overlays/ask-dialog.ts +20 -32
- package/src/overlays/copy-selector.ts +6 -6
- package/src/overlays/error-banner.ts +14 -3
- package/src/overlays/hook-editor.ts +59 -6
- package/src/overlays/jobs-panel.ts +132 -49
- package/src/overlays/rewind-selector.ts +235 -332
- package/src/overlays/session-selector.ts +19 -20
- package/src/prompt/custom-editor.ts +119 -30
- package/src/prompt/welcome.ts +4 -33
- package/src/status-line/component.ts +61 -30
- package/src/status-line/host.ts +2 -0
- package/src/status-line/metrics.ts +36 -5
- package/src/status-line/segments.ts +9 -1
- package/src/status-line/types.ts +13 -2
- package/src/terminal.ts +27 -6
- package/src/theme/dark.json +10 -0
- package/src/theme/defaults/alabaster.json +10 -0
- package/src/theme/defaults/amethyst.json +10 -0
- package/src/theme/defaults/anthracite.json +10 -0
- package/src/theme/defaults/basalt.json +10 -0
- package/src/theme/defaults/birch.json +10 -0
- package/src/theme/defaults/dark-abyss.json +10 -0
- package/src/theme/defaults/dark-arctic.json +10 -0
- package/src/theme/defaults/dark-aurora.json +10 -0
- package/src/theme/defaults/dark-catppuccin.json +10 -0
- package/src/theme/defaults/dark-cavern.json +10 -0
- package/src/theme/defaults/dark-celestial.json +10 -0
- package/src/theme/defaults/dark-copper.json +10 -0
- package/src/theme/defaults/dark-cosmos.json +10 -0
- package/src/theme/defaults/dark-cyberpunk.json +10 -0
- package/src/theme/defaults/dark-dracula.json +10 -0
- package/src/theme/defaults/dark-eclipse.json +10 -0
- package/src/theme/defaults/dark-ember.json +10 -0
- package/src/theme/defaults/dark-equinox.json +10 -0
- package/src/theme/defaults/dark-forest.json +10 -0
- package/src/theme/defaults/dark-github.json +10 -0
- package/src/theme/defaults/dark-gruvbox.json +10 -0
- package/src/theme/defaults/dark-lavender.json +10 -0
- package/src/theme/defaults/dark-lunar.json +10 -0
- package/src/theme/defaults/dark-midnight.json +10 -0
- package/src/theme/defaults/dark-monochrome.json +10 -0
- package/src/theme/defaults/dark-monokai.json +10 -0
- package/src/theme/defaults/dark-nebula.json +10 -0
- package/src/theme/defaults/dark-neon-noir.json +10 -0
- package/src/theme/defaults/dark-nord.json +10 -0
- package/src/theme/defaults/dark-ocean.json +10 -0
- package/src/theme/defaults/dark-one.json +10 -0
- package/src/theme/defaults/dark-poimandres.json +10 -0
- package/src/theme/defaults/dark-rainforest.json +10 -0
- package/src/theme/defaults/dark-reef.json +10 -0
- package/src/theme/defaults/dark-retro.json +10 -0
- package/src/theme/defaults/dark-rose-pine.json +10 -0
- package/src/theme/defaults/dark-sakura.json +10 -0
- package/src/theme/defaults/dark-slate.json +10 -0
- package/src/theme/defaults/dark-solarized.json +10 -0
- package/src/theme/defaults/dark-solstice.json +10 -0
- package/src/theme/defaults/dark-starfall.json +10 -0
- package/src/theme/defaults/dark-sunset.json +10 -0
- package/src/theme/defaults/dark-swamp.json +10 -0
- package/src/theme/defaults/dark-synthwave.json +10 -0
- package/src/theme/defaults/dark-taiga.json +10 -0
- package/src/theme/defaults/dark-terminal.json +10 -0
- package/src/theme/defaults/dark-tokyo-night.json +10 -0
- package/src/theme/defaults/dark-tundra.json +10 -0
- package/src/theme/defaults/dark-twilight.json +10 -0
- package/src/theme/defaults/dark-volcanic.json +10 -0
- package/src/theme/defaults/graphite.json +10 -0
- package/src/theme/defaults/light-arctic.json +10 -0
- package/src/theme/defaults/light-aurora-day.json +10 -0
- package/src/theme/defaults/light-canyon.json +10 -0
- package/src/theme/defaults/light-catppuccin.json +10 -0
- package/src/theme/defaults/light-cirrus.json +10 -0
- package/src/theme/defaults/light-coral.json +10 -0
- package/src/theme/defaults/light-cyberpunk.json +10 -0
- package/src/theme/defaults/light-dawn.json +10 -0
- package/src/theme/defaults/light-dunes.json +10 -0
- package/src/theme/defaults/light-eucalyptus.json +10 -0
- package/src/theme/defaults/light-forest.json +10 -0
- package/src/theme/defaults/light-frost.json +10 -0
- package/src/theme/defaults/light-github.json +10 -0
- package/src/theme/defaults/light-glacier.json +10 -0
- package/src/theme/defaults/light-gruvbox.json +10 -0
- package/src/theme/defaults/light-haze.json +10 -0
- package/src/theme/defaults/light-honeycomb.json +10 -0
- package/src/theme/defaults/light-lagoon.json +10 -0
- package/src/theme/defaults/light-lavender.json +10 -0
- package/src/theme/defaults/light-meadow.json +10 -0
- package/src/theme/defaults/light-mint.json +10 -0
- package/src/theme/defaults/light-monochrome.json +10 -0
- package/src/theme/defaults/light-ocean.json +10 -0
- package/src/theme/defaults/light-one.json +10 -0
- package/src/theme/defaults/light-opal.json +10 -0
- package/src/theme/defaults/light-orchard.json +10 -0
- package/src/theme/defaults/light-paper.json +10 -0
- package/src/theme/defaults/light-poimandres.json +10 -0
- package/src/theme/defaults/light-prism.json +10 -0
- package/src/theme/defaults/light-retro.json +10 -0
- package/src/theme/defaults/light-sand.json +10 -0
- package/src/theme/defaults/light-savanna.json +10 -0
- package/src/theme/defaults/light-solarized.json +10 -0
- package/src/theme/defaults/light-soleil.json +10 -0
- package/src/theme/defaults/light-sunset.json +10 -0
- package/src/theme/defaults/light-synthwave.json +10 -0
- package/src/theme/defaults/light-tokyo-night.json +10 -0
- package/src/theme/defaults/light-wetland.json +10 -0
- package/src/theme/defaults/light-zenith.json +10 -0
- package/src/theme/defaults/limestone.json +10 -0
- package/src/theme/defaults/mahogany.json +10 -0
- package/src/theme/defaults/marble.json +10 -0
- package/src/theme/defaults/obsidian.json +10 -0
- package/src/theme/defaults/onyx.json +10 -0
- package/src/theme/defaults/pearl.json +10 -0
- package/src/theme/defaults/porcelain.json +10 -0
- package/src/theme/defaults/quartz.json +10 -0
- package/src/theme/defaults/sandstone.json +10 -0
- package/src/theme/defaults/titanium.json +10 -0
- package/src/theme/light.json +10 -0
- package/src/theme/schema-validation.ts +7 -0
- package/src/theme/schema.ts +18 -0
- package/src/theme/theme-schema.json +30 -0
- package/src/tools/eval.ts +43 -11
- package/src/tools/grouped-file-output.ts +6 -0
- package/src/tui.ts +13 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,48 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [18.4.8] - 2026-10-01
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- Fixed native-terminal (TSP) frames held back by unacknowledged credits waiting for an unrelated render after the 5-second stall fallback expired; a credit-blocked change now renders as soon as the oldest frame counts as stalled.
|
|
10
|
+
|
|
11
|
+
## [18.4.7] - 2026-10-01
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- Added an optional `terminal` section to theme JSON (`background`, `foreground`, `chrome`, `widget`, 16 `ansi` colors) naming the terminal a theme was made for, for hosts that paint the terminal themselves; the built-in themes ported from known schemes (GitHub, Nord, Dracula, Catppuccin, Solarized, Gruvbox, Tokyo Night, One, Monokai, Rosé Pine, Poimandres, Celestial) carry their scheme's.
|
|
16
|
+
|
|
17
|
+
## [18.4.6] - 2026-10-01
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
|
|
21
|
+
- Added a full-page transcript replay experience for Rewind in native terminals, with branching navigation through the conversation.
|
|
22
|
+
- Added agent lineage navigation, including headers and links for moving between a subagent and its ancestors or returning to the main session.
|
|
23
|
+
- Added a Jobs overlay for viewing background jobs.
|
|
24
|
+
- Added OSC 877 protocol support for native TUI surfaces in Windows ConPTY environments.
|
|
25
|
+
- Added customizable native screen layouts through Component.describeScreen and programmatic scrolling for native nodes.
|
|
26
|
+
- Added native-terminal text editing support for selections in the composer and single-line inputs, including undoable host edits and safe handling of stale or token-spanning ranges.
|
|
27
|
+
- Added optional dismissal handling for error banners, including a Dismiss button in native terminal strips.
|
|
28
|
+
|
|
29
|
+
### Changed
|
|
30
|
+
|
|
31
|
+
- Notebook evaluation cells now use dedicated input and output gutters with clearer status indicators.
|
|
32
|
+
- Streaming file operations now remain expanded while running and collapse after execution completes.
|
|
33
|
+
- Improved native-terminal effort indicators, using terminal glyphs where available and block meters as a fallback.
|
|
34
|
+
- Updated native composer navigation when viewing a subagent to show the agent lineage and provide a direct return to the main session.
|
|
35
|
+
- Native `/resume` picker sheets drop the "Resume session" heading and the This folder / All projects tabs: the search placeholder names the scope ("Search sessions in app…", "Search all sessions…") and Tab (the footer's All projects / This folder action) switches it. Picker `title` is now optional on the wire.
|
|
36
|
+
- Updated the native composer's context display to span the window and provide clearer context usage and session-cost information, with shortcuts to the context and usage views.
|
|
37
|
+
- Updated status-line billing summaries to show subagent spend separately from session spend and avoid repeating the same currency or subscription marker for subsequent amounts.
|
|
38
|
+
|
|
39
|
+
### Fixed
|
|
40
|
+
|
|
41
|
+
- Fixed search results so gaps between non-adjacent context runs are displayed correctly.
|
|
42
|
+
- Fixed custom-answer and note prompts in native terminals so questions are shown completely with the correct titles and are no longer truncated or incorrectly wrapped.
|
|
43
|
+
- Fixed text fields in native dialogs to render without a duplicate prompt indicator.
|
|
44
|
+
- Fixed native TUI surfaces falling back to plain text rendering in Tern on Windows by accepting OSC 877 messages received through ConPTY.
|
|
45
|
+
- Fixed streaming edit, patch, and write operation cards so they remain fully visible while running and collapse only after completion.
|
|
46
|
+
|
|
5
47
|
## [18.4.5] - 2026-09-30
|
|
6
48
|
|
|
7
49
|
### Added
|
|
@@ -152,8 +152,8 @@ export declare class Sidebar {
|
|
|
152
152
|
* Pointer actions on the changes sheet: list clicks select (a folder also
|
|
153
153
|
* folds, a second click on the selected file stages it, as the ANSI click
|
|
154
154
|
* does), double clicks activate, the segmented control switches Path/Tree,
|
|
155
|
-
* and the quiet buttons run their row's action
|
|
156
|
-
* sidebar's event.
|
|
155
|
+
* and the quiet buttons run their row's action; selection edits go to the
|
|
156
|
+
* text field being edited. False when not the sidebar's event.
|
|
157
157
|
*/
|
|
158
158
|
handleNativeEvent(event: NativeUiEvent): boolean;
|
|
159
159
|
/** Wheel scroll over the sidebar. */
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { NativeNode } from "../native/node.js";
|
|
2
|
+
import { Container } from "../tui.js";
|
|
3
|
+
/**
|
|
4
|
+
* The idle recap (`recap.*`): where the session stands, written while the user
|
|
5
|
+
* was away. Stays in the transcript like a thought: a dim italic `※ recap:`
|
|
6
|
+
* line in ANSI, a history icon beside the italic thought-coloured text in a
|
|
7
|
+
* native terminal (`omp.recap`).
|
|
8
|
+
*/
|
|
9
|
+
export declare class RecapNotice extends Container {
|
|
10
|
+
#private;
|
|
11
|
+
constructor(recap: string);
|
|
12
|
+
describe(): NativeNode;
|
|
13
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type AutocompleteProvider } from "../autocomplete.js";
|
|
2
2
|
import type { TspEditorDecoration, TspTone } from "@oh-my-pi/pi-wire";
|
|
3
|
-
import type
|
|
3
|
+
import { type DescribeContext, type NativeChild, type NativeNode, type NativeTextEdit, type NativeUiEvent } from "../native/node.js";
|
|
4
4
|
import type { SymbolTheme } from "../symbols.js";
|
|
5
5
|
import { type Component, type Focusable } from "../tui.js";
|
|
6
6
|
import { type VimMode } from "../vim.js";
|
|
@@ -102,11 +102,12 @@ export declare class Editor implements Component, Focusable {
|
|
|
102
102
|
* TSP chrome around the `editor` node (the prompt composer's chips, mode
|
|
103
103
|
* chip, send/stop): the root role, the children with `input` placed where
|
|
104
104
|
* the layout wants it, and the input's keypath for the caret-anchored
|
|
105
|
-
* autocomplete. Unset: a plain `omp.
|
|
105
|
+
* autocomplete. Unset: a plain `omp.field` column over the input (a
|
|
106
|
+
* dialog's text field; only the prompt composer claims `omp.editor`).
|
|
106
107
|
*/
|
|
107
108
|
describeLayout: ((input: NativeNode, cx: DescribeContext) => NativeEditorLayout) | undefined;
|
|
108
109
|
/** TSP placeholder for the empty buffer; natively it replaces the rotating ANSI {@link placeholder} hints. */
|
|
109
|
-
|
|
110
|
+
describePlaceholder: (() => string) | undefined;
|
|
110
111
|
/** Called with the selected text when Visual mode yanks, so hosts can reach the system
|
|
111
112
|
* clipboard — `packages/tui` deliberately has no clipboard dependency of its own. */
|
|
112
113
|
onYank?: (text: string) => void;
|
|
@@ -295,6 +296,17 @@ export declare class Editor implements Component, Focusable {
|
|
|
295
296
|
submit(): void;
|
|
296
297
|
/** Insert text at the current cursor position */
|
|
297
298
|
insertText(text: string): void;
|
|
299
|
+
/** Terminal-side selection edits on the `editor` node (see {@link applyHostEdit}). */
|
|
300
|
+
handleNativeEvent(event: NativeUiEvent): void;
|
|
301
|
+
/**
|
|
302
|
+
* Apply an edit the terminal made over its own selection (TSP `edit`):
|
|
303
|
+
* replace `[from, to)` of the described text with `text` and put the caret
|
|
304
|
+
* at `cursor`, as one undo unit that leaves history browsing and updates
|
|
305
|
+
* autocomplete like typing. A range cutting through an atomic placeholder
|
|
306
|
+
* token takes the whole token. Stale edits (`len` no longer the text's
|
|
307
|
+
* length) are dropped; a pure caret move only moves the caret.
|
|
308
|
+
*/
|
|
309
|
+
applyHostEdit(edit: NativeTextEdit): void;
|
|
298
310
|
/** Delete up to `count` characters immediately before the cursor on the current line.
|
|
299
311
|
* Used to "track back" the auto-repeat spaces that the space-hold push-to-talk gesture
|
|
300
312
|
* optimistically inserts before it recognizes the hold. Capped at the cursor column so it
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type DescribeContext, type NativeNode, type NativeTextEdit, type NativeUiEvent } from "../native/node.js";
|
|
2
2
|
import { SpaceHoldGesture } from "../space-hold.js";
|
|
3
3
|
import { type Component, type Focusable } from "../tui.js";
|
|
4
4
|
/**
|
|
@@ -39,6 +39,16 @@ export declare class Input implements Component, Focusable {
|
|
|
39
39
|
/** Apply terminal paste semantics to text from non-bracketed paste transports
|
|
40
40
|
* (e.g. kitty's OSC 5522 enhanced clipboard read). Mirrors `Editor.pasteText`. */
|
|
41
41
|
pasteText(text: string): void;
|
|
42
|
+
/** Terminal-side selection edits on the `input` node (see {@link applyHostEdit}). */
|
|
43
|
+
handleNativeEvent(event: NativeUiEvent): void;
|
|
44
|
+
/**
|
|
45
|
+
* Apply an edit the terminal made over its own selection (TSP `edit`):
|
|
46
|
+
* replace `[from, to)` with `text` (newlines stripped, as a paste) and put
|
|
47
|
+
* the caret at `cursor`, as one undo unit. Offsets are in the described
|
|
48
|
+
* text, so a masked field's count bullets, one per grapheme. Stale edits
|
|
49
|
+
* (`len` no longer the described length) are dropped.
|
|
50
|
+
*/
|
|
51
|
+
applyHostEdit(edit: NativeTextEdit): void;
|
|
42
52
|
/** Programmatically trigger submission (e.g. for voice submit). */
|
|
43
53
|
submit(): void;
|
|
44
54
|
/** Delete up to `count` characters immediately before the cursor. */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type TspFrame, type TspNode } from "@oh-my-pi/pi-wire";
|
|
2
2
|
import type { Terminal } from "../terminal.js";
|
|
3
|
-
import type { Component, OverlayOptions } from "../tui.js";
|
|
3
|
+
import type { Component, OverlayOptions, RenderScheduler } from "../tui.js";
|
|
4
4
|
import { type TspHello } from "./encode.js";
|
|
5
5
|
import type { DescribeContext, NativeSurface } from "./node.js";
|
|
6
6
|
/** A visible TUI overlay, bottom to top. */
|
|
@@ -34,7 +34,8 @@ export interface NativeBackendOptions {
|
|
|
34
34
|
readonly recordPath?: string;
|
|
35
35
|
/** Log the `rows` fallback count per frame. Defaults to `PI_TUI_NATIVE_STATS=1`. */
|
|
36
36
|
readonly stats?: boolean;
|
|
37
|
-
|
|
37
|
+
/** Clock and timers (stall wake-up); defaults to `Date.now` and unref'd `setTimeout`. */
|
|
38
|
+
readonly scheduler?: RenderScheduler;
|
|
38
39
|
}
|
|
39
40
|
/**
|
|
40
41
|
* The reply a v1 terminal is assumed to give before its real `hello` arrives
|
|
@@ -21,7 +21,7 @@ export declare function getNativeBlob(id: string): NativeBlob | undefined;
|
|
|
21
21
|
* the pixel size probed from the header. Decoding and hashing cost real time,
|
|
22
22
|
* so callers cache the node per payload ({@link NativeImageCache}).
|
|
23
23
|
*/
|
|
24
|
-
export declare function base64ImageNode(data: string, mimeType: string, p?: Omit<TspProps<"image">, "blob" | "w" | "h">, key?: string): NativeNode;
|
|
24
|
+
export declare function base64ImageNode(data: string, mimeType: string, p?: Omit<TspProps<"image">, "blob" | "builtin" | "w" | "h">, key?: string): NativeNode;
|
|
25
25
|
/** `image` nodes for base64 payloads, one per slot key, rebuilt only when the slot's payload changes. */
|
|
26
26
|
export declare class NativeImageCache {
|
|
27
27
|
#private;
|
|
@@ -27,6 +27,11 @@ export type NativeNode = {
|
|
|
27
27
|
* or reordered so their ids and terminal-side view state survive.
|
|
28
28
|
*/
|
|
29
29
|
readonly key?: string;
|
|
30
|
+
/**
|
|
31
|
+
* Scroll the node into view, placed like the `reveal` op, when it is
|
|
32
|
+
* added. Key a node by what it points at to reveal it again on a move.
|
|
33
|
+
*/
|
|
34
|
+
readonly reveal?: "start" | "end" | "nearest";
|
|
30
35
|
};
|
|
31
36
|
}[TspKind];
|
|
32
37
|
/** A child slot: a described node, or a component that describes itself. */
|
|
@@ -55,6 +60,14 @@ export interface NativeSurface {
|
|
|
55
60
|
/** Sticky bottom chrome while live (editor, status line, HUDs). */
|
|
56
61
|
readonly dock: readonly NativeChild[];
|
|
57
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* The screen surface a fullscreen overlay fills as a page of its own (see
|
|
65
|
+
* `Component.describeScreen`): its regions plus the surface `role`, which the
|
|
66
|
+
* terminal exposes to styling.
|
|
67
|
+
*/
|
|
68
|
+
export interface NativeScreen extends NativeSurface {
|
|
69
|
+
readonly role: string;
|
|
70
|
+
}
|
|
58
71
|
/**
|
|
59
72
|
* A user action on a node a component described, routed back to that
|
|
60
73
|
* component. `key` is the node's key path inside the component (`""` for the
|
|
@@ -86,7 +99,56 @@ export type NativeUiEvent = {
|
|
|
86
99
|
readonly key: string;
|
|
87
100
|
readonly item: string;
|
|
88
101
|
readonly value: boolean | number | string | readonly string[] | null;
|
|
89
|
-
}
|
|
102
|
+
}
|
|
103
|
+
/** An edit over the terminal's own selection in an `editor`/`input` node (see {@link NativeTextEdit}). */
|
|
104
|
+
| ({
|
|
105
|
+
readonly type: "edit";
|
|
106
|
+
readonly key: string;
|
|
107
|
+
} & NativeTextEdit);
|
|
108
|
+
/**
|
|
109
|
+
* A primitive edit the terminal made over its own text selection (cut,
|
|
110
|
+
* typing, Backspace/Delete or paste over it, or collapsing it). Offsets are
|
|
111
|
+
* UTF-16 code units into the text last described (lines joined with `"\n"`),
|
|
112
|
+
* the coordinates of the node's `cursor`: replace `[from, to)` with `text`,
|
|
113
|
+
* then put the caret at `cursor` in the resulting text. `from == to` with an
|
|
114
|
+
* empty `text` is a pure caret move. `len` is the length of the text the
|
|
115
|
+
* terminal saw: when the current text differs (keys in flight changed it) the
|
|
116
|
+
* edit is stale and ignored.
|
|
117
|
+
*/
|
|
118
|
+
export interface NativeTextEdit {
|
|
119
|
+
readonly from: number;
|
|
120
|
+
readonly to: number;
|
|
121
|
+
readonly text: string;
|
|
122
|
+
readonly cursor: number;
|
|
123
|
+
readonly len: number;
|
|
124
|
+
}
|
|
125
|
+
/** A {@link NativeTextEdit} checked against the current text and clamped, ready to apply. */
|
|
126
|
+
export interface ResolvedTextEdit {
|
|
127
|
+
/** Replaced range in the current text, widened by the caller's `widen`. */
|
|
128
|
+
readonly from: number;
|
|
129
|
+
readonly to: number;
|
|
130
|
+
/** The cleaned replacement. */
|
|
131
|
+
readonly insert: string;
|
|
132
|
+
/** The whole text after the edit. */
|
|
133
|
+
readonly text: string;
|
|
134
|
+
/** Caret in {@link text}. */
|
|
135
|
+
readonly cursor: number;
|
|
136
|
+
/** Whether the text changes (false: a pure caret move). */
|
|
137
|
+
readonly changed: boolean;
|
|
138
|
+
}
|
|
139
|
+
/** `value` as an integer offset in `[0, max]` (anything non-finite is 0). */
|
|
140
|
+
export declare function clampTextOffset(value: number, max: number): number;
|
|
141
|
+
/**
|
|
142
|
+
* Check `edit` against `current` and resolve it: null when stale (`len`
|
|
143
|
+
* differs), else the range clamped (reversed ends swapped, never splitting a
|
|
144
|
+
* surrogate pair), widened by `widen` when non-empty, the replacement passed
|
|
145
|
+
* through `clean`, and the caret mapped from the text the terminal expects
|
|
146
|
+
* onto the text the edit actually produces.
|
|
147
|
+
*/
|
|
148
|
+
export declare function resolveTextEdit(current: string, edit: NativeTextEdit, clean: (text: string) => string, widen?: (from: number, to: number) => {
|
|
149
|
+
from: number;
|
|
150
|
+
to: number;
|
|
151
|
+
}): ResolvedTextEdit | null;
|
|
90
152
|
/** The expanded state a `toggle` on the component's root node asks for, else undefined. */
|
|
91
153
|
export declare function rootToggleExpanded(event: NativeUiEvent): boolean | undefined;
|
|
92
154
|
/** The last segment of an event keypath (`"split/sidebar/toc"` → `"toc"`). */
|
|
@@ -15,6 +15,15 @@ interface AgentTreeProjection<TRecord extends AgentRecordLike> {
|
|
|
15
15
|
export declare const STATUS_ORDER: Record<AgentStatus, number>;
|
|
16
16
|
/** Exact observer usage for one roster entry. */
|
|
17
17
|
export declare function progressMetrics(observed: ObservableSession | undefined): AgentMetrics | undefined;
|
|
18
|
+
/** Live session whose own messages back a row's metrics when no observer progress exists. */
|
|
19
|
+
export declare function hubFallbackStatsSession<TRecord extends AgentRecordLike>(ref: TRecord, observed: ObservableSession | undefined): NonNullable<TRecord["session"]> | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* One roster row's usage: live observer progress, then persisted history, then
|
|
22
|
+
* the cached fallback read of a live session (populated by {@link aggregateMetrics}).
|
|
23
|
+
*/
|
|
24
|
+
export declare function hubRowMetrics<TRecord extends AgentRecordLike>(ref: TRecord, observed: ObservableSession | undefined, sessionMetrics: WeakMap<object, {
|
|
25
|
+
metrics: AgentMetrics | undefined;
|
|
26
|
+
}>): AgentMetrics | undefined;
|
|
18
27
|
export declare function aggregateMetrics<TRecord extends AgentRecordLike>(args: {
|
|
19
28
|
rows: readonly TRecord[];
|
|
20
29
|
observedById: ReadonlyMap<string, ObservableSession>;
|
|
@@ -45,15 +45,19 @@ export interface ExtensionAskDialogChatResult {
|
|
|
45
45
|
/** Completed dialog action, distinct from cancellation. */
|
|
46
46
|
export type ExtensionAskDialogResult = ExtensionAskDialogSubmitResult | ExtensionAskDialogChatResult;
|
|
47
47
|
import { type DescribeContext, type NativeNode, type NativeUiEvent } from "../native/node.js";
|
|
48
|
-
/**
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
/** What a custom-answer or note prompt asks: the host shows `title` over `question` (`HookEditorOptions.question`). */
|
|
49
|
+
export interface AskDialogPrompt {
|
|
50
|
+
/** `Custom answer`, `Note for <option>`. */
|
|
51
|
+
title: string;
|
|
52
|
+
/** The question being answered, verbatim. */
|
|
53
|
+
question: string;
|
|
54
|
+
}
|
|
51
55
|
interface AskDialogCallbacks {
|
|
52
56
|
onSubmit(result: ExtensionAskDialogSubmitResult): void;
|
|
53
57
|
onCancel(): void;
|
|
54
|
-
onPrompt(
|
|
58
|
+
onPrompt(prompt: AskDialogPrompt, prefill?: string): Promise<string | undefined>;
|
|
55
59
|
/** Prompt that accepts pasted images; without it, prompts use `onPrompt`. */
|
|
56
|
-
onImagePrompt?(
|
|
60
|
+
onImagePrompt?(prompt: AskDialogPrompt, prefill: AskDialogPromptValue | undefined): Promise<AskDialogPromptValue | undefined>;
|
|
57
61
|
}
|
|
58
62
|
interface AskDialogInputGuard {
|
|
59
63
|
isBlocked(): boolean;
|
|
@@ -15,36 +15,13 @@
|
|
|
15
15
|
* mouse selection nor cmd-click.
|
|
16
16
|
*/
|
|
17
17
|
import type { AgentTool } from "@oh-my-pi/pi-agent-core";
|
|
18
|
-
import type { TspPickerColumn, TspPickerItem, TspText } from "@oh-my-pi/pi-wire";
|
|
19
18
|
import { type Component, type TUI } from "../index.js";
|
|
20
19
|
import type { MessageRenderer } from "../chat/extension-types.js";
|
|
21
20
|
import { type TranscriptEntryLike as TranscriptEntry } from "../chat/transcript-entry.js";
|
|
22
21
|
import { type OutlineTarget } from "../chat/transcript-outline.js";
|
|
23
22
|
import type { DescribeContext, NativeNode, NativeUiEvent } from "../native/node.js";
|
|
24
|
-
/** Key of the leading list item that replays the history older than the startup tail. */
|
|
25
|
-
export declare const EARLIER_TURNS_KEY = "earlier";
|
|
26
|
-
/** Leading item of a truncated transcript list; selecting it loads the older turns. */
|
|
27
|
-
export declare const earlierTurnsItem: NativeNode;
|
|
28
|
-
/**
|
|
29
|
-
* One list item per outline target, keyed by the turn's opening entry id:
|
|
30
|
-
* the plain turn summary as label, `detail` (or the entry time) on the right.
|
|
31
|
-
*/
|
|
32
|
-
export declare function turnItem(target: OutlineTarget, detail?: TspText): NativeNode;
|
|
33
23
|
/** Preview of a turn's text: prose as markdown, command/tool output as a plain code block. */
|
|
34
24
|
export declare function turnPreview(target: OutlineTarget, content: string): NativeNode;
|
|
35
|
-
/** The timeline pickers' one fact column: a user turn's clock time. */
|
|
36
|
-
export declare const TIMELINE_COLUMNS: readonly TspPickerColumn[];
|
|
37
|
-
/**
|
|
38
|
-
* The `timeline` picker item of one outline target (rewind, copy), keyed by
|
|
39
|
-
* the turn's opening entry id: user turns carry their `HH:MM`, pure tool turns
|
|
40
|
-
* the tool's role and a `name target` label.
|
|
41
|
-
*/
|
|
42
|
-
export declare function timelineItem(target: OutlineTarget): TspPickerItem;
|
|
43
|
-
/** Timeline picker items for `targets`, reused while `targets` is the same array. */
|
|
44
|
-
export declare class TimelineItems {
|
|
45
|
-
#private;
|
|
46
|
-
of(targets: readonly OutlineTarget[]): TspPickerItem[];
|
|
47
|
-
}
|
|
48
25
|
export interface CopySelectorDeps {
|
|
49
26
|
ui: TUI;
|
|
50
27
|
getTool?: (name: string) => AgentTool | undefined;
|
|
@@ -8,14 +8,17 @@ import type { NativeNode, NativeUiEvent } from "../native/node.js";
|
|
|
8
8
|
* be missed. It is cleared when the next turn starts. The message wraps to the
|
|
9
9
|
* render width and keeps {@link MAX_BANNER_ROWS} rows; the expand hint on the
|
|
10
10
|
* overflow row reveals the full body inline in the transcript.
|
|
11
|
+
*
|
|
12
|
+
* Natively the transcript's error frame always shows the full message, so the
|
|
13
|
+
* strip is only a reminder and offers a Dismiss button that calls `onDismiss`.
|
|
11
14
|
*/
|
|
12
15
|
export declare class ErrorBannerComponent extends Container {
|
|
13
16
|
#private;
|
|
14
|
-
constructor(message: string);
|
|
17
|
+
constructor(message: string, onDismiss?: () => void);
|
|
15
18
|
/**
|
|
16
19
|
* An error-tinted strip pinned above the composer: the message's first line
|
|
17
20
|
* (the transcript's error frame keeps the full message and its actions)
|
|
18
|
-
* and a Details button that unfolds the rest here.
|
|
21
|
+
* and a Details button that unfolds the rest here, then Dismiss.
|
|
19
22
|
*/
|
|
20
23
|
describe(): NativeNode;
|
|
21
24
|
handleNativeEvent(event: NativeUiEvent): void;
|
|
@@ -11,11 +11,23 @@ import type { ImageContent } from "@oh-my-pi/pi-ai";
|
|
|
11
11
|
import { type Focusable, type TUI } from "../index.js";
|
|
12
12
|
import { OverlayPanel } from "../chrome/overlay-box.js";
|
|
13
13
|
import type { DescribeContext, NativeNode } from "../native/node.js";
|
|
14
|
+
/**
|
|
15
|
+
* `prefix` and `question` flattened onto one line, wrapped to the terminal's width and cut to
|
|
16
|
+
* {@link MAX_PROMPT_TITLE_ROWS} rows (the last ends in `…` when cut). For terminal rendering only:
|
|
17
|
+
* native hosts get the question whole ({@link HookEditorOptions.question}).
|
|
18
|
+
*/
|
|
19
|
+
export declare function boundPromptTitle(prefix: string, question: string): string;
|
|
14
20
|
export interface HookEditorOptions {
|
|
15
21
|
/** Edit text with the host's configured external editor. */
|
|
16
22
|
externalEditor?: (text: string) => Promise<string | null>;
|
|
17
23
|
/** When true, use prompt-style keybindings with the legacy ask prompt chrome. */
|
|
18
24
|
promptStyle?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* The question the text answers (the ask tool's custom answers and notes). The terminal
|
|
27
|
+
* shows it after `<title>: `, wrapped and cut to three rows; native hosts put it whole,
|
|
28
|
+
* as markdown, under the title.
|
|
29
|
+
*/
|
|
30
|
+
question?: string;
|
|
19
31
|
/** Allow clipboard images to be attached to this prompt. */
|
|
20
32
|
acceptImages?: boolean;
|
|
21
33
|
/** Images already represented by markers in the prefilled text. */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Component, Container } from "../tui.js";
|
|
2
|
-
import type { DescribeContext, NativeNode } from "../native/node.js";
|
|
2
|
+
import type { DescribeContext, NativeNode, NativeUiEvent } from "../native/node.js";
|
|
3
3
|
/** One async job as the session snapshots it. */
|
|
4
4
|
export interface JobsPanelJob {
|
|
5
5
|
readonly id: string;
|
|
@@ -22,3 +22,27 @@ export declare class JobsPanel extends Container {
|
|
|
22
22
|
constructor(snapshot: JobsPanelSnapshot, nowMs: number, ansi: readonly Component[]);
|
|
23
23
|
describe(cx: DescribeContext): NativeNode;
|
|
24
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* The jobs pill's sheet: a centred `md` glass sheet titled Background jobs
|
|
27
|
+
* that re-reads the session's jobs on every frame, so rows start, settle and
|
|
28
|
+
* move to Recent while it is open. Esc or Close dismisses it; nothing enters
|
|
29
|
+
* the transcript.
|
|
30
|
+
*/
|
|
31
|
+
export declare class JobsSheet implements Component {
|
|
32
|
+
#private;
|
|
33
|
+
readonly nativeOverlay: {
|
|
34
|
+
readonly role: "omp.overlay.jobs";
|
|
35
|
+
readonly size: "md";
|
|
36
|
+
readonly anchor: "center";
|
|
37
|
+
readonly head: "Background jobs";
|
|
38
|
+
};
|
|
39
|
+
/** `load` returns the current jobs; it runs once per frame. */
|
|
40
|
+
constructor(load: () => JobsPanelSnapshot, onClose: () => void);
|
|
41
|
+
describe(cx: DescribeContext): NativeNode;
|
|
42
|
+
/** Rows for a terminal without the native surface: status, label, type and age per job. */
|
|
43
|
+
render(width: number): readonly string[];
|
|
44
|
+
invalidate(): void;
|
|
45
|
+
handleInput(data: string): void;
|
|
46
|
+
/** Close runs what Esc runs. */
|
|
47
|
+
handleNativeEvent(event: NativeUiEvent): void;
|
|
48
|
+
}
|
|
@@ -24,12 +24,16 @@
|
|
|
24
24
|
* filter with the selection kept), Enter rewinds to the outlined item, A loads
|
|
25
25
|
* earlier turns without changing selection (stepping above the oldest replayed
|
|
26
26
|
* turn loads them too), Esc cancels.
|
|
27
|
+
*
|
|
28
|
+
* In a TSP terminal (Tern) the same replay is a page, not a sheet: a screen
|
|
29
|
+
* surface of the transcript's own blocks with `pick`/`drop` marks in place of
|
|
30
|
+
* the dotted outline (see `describeScreen`).
|
|
27
31
|
*/
|
|
28
32
|
import type { AgentTool } from "@oh-my-pi/pi-agent-core";
|
|
29
33
|
import { type Component, type TUI } from "../index.js";
|
|
30
34
|
import type { MessageRenderer } from "../chat/extension-types.js";
|
|
31
35
|
import { type TranscriptEntryLike as TranscriptEntry } from "../chat/transcript-entry.js";
|
|
32
|
-
import type { DescribeContext, NativeNode, NativeUiEvent } from "../native/node.js";
|
|
36
|
+
import type { DescribeContext, NativeNode, NativeScreen, NativeUiEvent } from "../native/node.js";
|
|
33
37
|
/** One alternate branch at a divergence: its root and message path root → most-recent leaf. */
|
|
34
38
|
export interface BranchVariantPath {
|
|
35
39
|
rootId: string;
|
|
@@ -61,9 +65,18 @@ export declare class RewindSelectorComponent implements Component {
|
|
|
61
65
|
invalidate(): void;
|
|
62
66
|
dispose(): void;
|
|
63
67
|
handleInput(data: string): void;
|
|
64
|
-
/**
|
|
65
|
-
|
|
68
|
+
/**
|
|
69
|
+
* The rewind page: the replayed transcript fills a screen surface block by
|
|
70
|
+
* block, as the live one reads, the outlined turn marked `pick` under a
|
|
71
|
+
* "Continue from here" caption (revealed as the outline moves) and what the
|
|
72
|
+
* rewind drops marked `drop`. At a fork the region below it becomes a strip
|
|
73
|
+
* of branch columns, the current path first. The bar is this component's
|
|
74
|
+
* own node, docked under the page, so the filter field keeps the caret.
|
|
75
|
+
*/
|
|
76
|
+
describeScreen(_cx: DescribeContext): NativeScreen;
|
|
77
|
+
/** The bar docked under the page: position, key hints, Cancel and Rewind; the filter field while filtering. */
|
|
78
|
+
describe(_cx: DescribeContext): NativeNode;
|
|
79
|
+
/** The bar's buttons run their keys' paths; everything else belongs to the blocks. */
|
|
66
80
|
handleNativeEvent(event: NativeUiEvent): void;
|
|
67
|
-
describe(cx: DescribeContext): NativeNode;
|
|
68
81
|
render(width: number): readonly string[];
|
|
69
82
|
}
|
|
@@ -20,6 +20,8 @@ export interface ComposerNativeState {
|
|
|
20
20
|
readonly thinking?: string;
|
|
21
21
|
/** A turn is running: the send keycap becomes a Stop button. */
|
|
22
22
|
readonly running: boolean;
|
|
23
|
+
/** The viewed subagent's lineage, outermost first and the viewed agent last; undefined on the main session. */
|
|
24
|
+
readonly viewing?: readonly string[];
|
|
23
25
|
}
|
|
24
26
|
/** Independently switchable prose-assistance features of the composer. */
|
|
25
27
|
export interface SpellingFeatures extends MacOSSpellingFeatures {
|
|
@@ -211,7 +213,8 @@ export declare class CustomEditor extends Editor {
|
|
|
211
213
|
* once after construction (and again after `setEditorComponent` swaps the
|
|
212
214
|
* editor). Passing `undefined` clears any pending frame. */
|
|
213
215
|
setShimmerRepaintHandler(handler: (() => void) | undefined): void;
|
|
214
|
-
|
|
216
|
+
/** Viewing a subagent, the draft goes to it: the placeholder names it. */
|
|
217
|
+
describePlaceholder: () => string;
|
|
215
218
|
/** A shell-mode draft highlights as its language. */
|
|
216
219
|
describeLanguage: () => string | undefined;
|
|
217
220
|
/** Host-owned live state for the TSP composer (shell mode, effort chip, send/stop). */
|
|
@@ -222,16 +225,19 @@ export declare class CustomEditor extends Editor {
|
|
|
222
225
|
composerFacts: ComposerFactsSource | undefined;
|
|
223
226
|
/**
|
|
224
227
|
* The TSP composer: role `omp.editor[.bash|.python]` (tone `pending` while
|
|
225
|
-
* a turn runs) over the context hairline, the
|
|
226
|
-
*
|
|
227
|
-
*
|
|
228
|
-
*
|
|
229
|
-
*
|
|
228
|
+
* a turn runs) over the context hairline, the viewing header while a
|
|
229
|
+
* subagent is focused, the attachment chips, a `line` row of the
|
|
230
|
+
* shell-mode chip and the input, and the `bar`: model chip, effort chip,
|
|
231
|
+
* the other status facts, usage, then send (Stop while a turn runs).
|
|
232
|
+
* Clicks come back as `status.model`, `thinking.cycle`, `submit`,
|
|
233
|
+
* `interrupt` and `focus:<id>` actions.
|
|
230
234
|
*/
|
|
231
|
-
describeLayout: (input: NativeNode,
|
|
235
|
+
describeLayout: (input: NativeNode, cx: DescribeContext) => NativeEditorLayout;
|
|
232
236
|
/**
|
|
233
237
|
* Clicks on the composer's controls take the same paths as their keys: ⇧⇥,
|
|
234
|
-
* ⏎ and Esc; the
|
|
238
|
+
* ⏎ and Esc; the viewing header's links (`focus:<id>`) go to the host,
|
|
239
|
+
* the status facts' clicks (`status.*`) to their source. Selection edits
|
|
240
|
+
* go to the buffer.
|
|
235
241
|
*/
|
|
236
242
|
handleNativeEvent(event: NativeUiEvent): void;
|
|
237
243
|
onEscape?: () => void;
|
|
@@ -260,6 +266,8 @@ export declare class CustomEditor extends Editor {
|
|
|
260
266
|
onCapsLock?: () => void;
|
|
261
267
|
/** Called when left-arrow is pressed while the editor is empty (cursor necessarily at start). */
|
|
262
268
|
onLeftAtStart?: () => void;
|
|
269
|
+
/** Called when the viewing header asks to view agent `id` ({@link MAIN_AGENT_ID}: the main session). */
|
|
270
|
+
onFocusAgent?: (id: string) => void;
|
|
263
271
|
/** Space-bar push-to-talk; set its `handler` to enable it. It is a text-composition gesture, so it
|
|
264
272
|
* stays out of Vim's Normal/Visual modes (where the space bar is the `l` motion) and away from an
|
|
265
273
|
* open autocomplete menu. */
|
|
@@ -44,9 +44,9 @@ export declare class WelcomeComponent implements Component {
|
|
|
44
44
|
invalidate(): void;
|
|
45
45
|
/**
|
|
46
46
|
* A `card` (`omp.welcome`) titled with the app version. The brand column
|
|
47
|
-
* (`omp.welcome.brand`: greeting
|
|
48
|
-
* beside the info column (`omp.welcome.info`: prompt-sigil
|
|
49
|
-
* servers, recent sessions); the tip of the session closes the card. Roles
|
|
47
|
+
* (`omp.welcome.brand`: greeting and the terminal's builtin `omp` mark, which
|
|
48
|
+
* it animates) sits beside the info column (`omp.welcome.info`: prompt-sigil
|
|
49
|
+
* keycaps, LSP servers, recent sessions); the tip of the session closes the card. Roles
|
|
50
50
|
* carry the look (gradient logo, type scale, column hairline); a "[NEW]" tip
|
|
51
51
|
* carries a terminal-clocked shimmering tag.
|
|
52
52
|
*/
|
|
@@ -31,6 +31,8 @@ export declare class StatusLineComponent<TSession extends StatusLineSession = St
|
|
|
31
31
|
getEffectiveSettingsForTest(): EffectiveStatusLineSettings;
|
|
32
32
|
setAutoCompactEnabled(enabled: boolean): void;
|
|
33
33
|
setRunningSubagents(agentIds: readonly string[]): void;
|
|
34
|
+
/** Host-computed spend of the main session's whole subagent tree (Agent Hub projection). */
|
|
35
|
+
setSubagentTreeCost(cost: number): void;
|
|
34
36
|
/**
|
|
35
37
|
* Compatibility shim for callers predating the simplified subagent badge.
|
|
36
38
|
* The status line now intentionally shows only the active count.
|
|
@@ -7,6 +7,8 @@ export interface BillingSummaryOptions {
|
|
|
7
7
|
readonly premiumRequests: number;
|
|
8
8
|
readonly fractionDigits: number;
|
|
9
9
|
readonly pricingPeriod?: "peak" | "off-peak";
|
|
10
|
+
/** Subagent-tree spend, rendered `(+…)` after the session's own spend; `cost` excludes it. */
|
|
11
|
+
readonly subagentCost?: number;
|
|
10
12
|
readonly advisor?: {
|
|
11
13
|
readonly cost: number;
|
|
12
14
|
readonly usingSubscription: boolean;
|
|
@@ -15,5 +17,7 @@ export interface BillingSummaryOptions {
|
|
|
15
17
|
/**
|
|
16
18
|
* Shared billing metric presentation. Callers select precision explicitly so
|
|
17
19
|
* the legacy footer keeps three decimals while current status segments keep two.
|
|
20
|
+
* A unit symbol (`$` or the subscription mark) is printed at most once; later
|
|
21
|
+
* amounts billed the same way render bare.
|
|
18
22
|
*/
|
|
19
23
|
export declare function formatBillingSummary(options: BillingSummaryOptions, uiTheme: Theme): string | undefined;
|
|
@@ -137,6 +137,8 @@ export interface SegmentContext {
|
|
|
137
137
|
orchestrationCacheRead: number;
|
|
138
138
|
premiumRequests: number;
|
|
139
139
|
cost: number;
|
|
140
|
+
/** Portion of `cost` carried by completed subagent task results. */
|
|
141
|
+
subagentCost?: number;
|
|
140
142
|
tokensPerSecond: number | null;
|
|
141
143
|
};
|
|
142
144
|
/** Context usage percent, or null when unknown (e.g. right after compaction). */
|
|
@@ -149,6 +151,11 @@ export interface SegmentContext {
|
|
|
149
151
|
/** Blink phase for the running-speculation pulse; toggled by the component's timer. */
|
|
150
152
|
speculationBlinkOn: boolean;
|
|
151
153
|
subagentCount: number;
|
|
154
|
+
/**
|
|
155
|
+
* Spend of every subagent under the main session (descendants included),
|
|
156
|
+
* from the Agent Hub projection; 0 while a subagent is focused or unknown.
|
|
157
|
+
*/
|
|
158
|
+
subagentTreeCost?: number;
|
|
152
159
|
/**
|
|
153
160
|
* Active processing time accumulated this session, in ms — the union of
|
|
154
161
|
* every `agent_start`→`agent_end` window plus the currently-streaming
|
|
@@ -242,7 +249,11 @@ export interface SegmentView {
|
|
|
242
249
|
* and branch, and the composer the rest.
|
|
243
250
|
*/
|
|
244
251
|
export interface ComposerFacts {
|
|
245
|
-
/**
|
|
252
|
+
/**
|
|
253
|
+
* `meter` (role `omp.composer.context`): context usage along the composer's top edge,
|
|
254
|
+
* the whole window wide, with the speculation and compaction points as icon marks,
|
|
255
|
+
* the share as `label` and the window as `total`.
|
|
256
|
+
*/
|
|
246
257
|
readonly context: NativeNode;
|
|
247
258
|
/** The model chip's label: name plus the advisor, fast-mode and slow-mode marks. */
|
|
248
259
|
readonly model: SegmentView;
|
|
@@ -251,7 +262,7 @@ export interface ComposerFacts {
|
|
|
251
262
|
* segments as `seg`s; the bar's flexible space, so present even when empty.
|
|
252
263
|
*/
|
|
253
264
|
readonly extras: NativeNode;
|
|
254
|
-
/** `text` (role `omp.composer.usage`): the
|
|
265
|
+
/** `text` (role `omp.composer.usage`): the session cost (empty when there is none). */
|
|
255
266
|
readonly usage: NativeNode;
|
|
256
267
|
}
|
|
257
268
|
/** Supplies {@link ComposerFacts} and takes the clicks on them (`status.*` actions). */
|