@oh-my-pi/pi-tui 18.9.2 → 18.10.1

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.
Files changed (59) hide show
  1. package/CHANGELOG.md +53 -105
  2. package/dist/types/app-keybindings.d.ts +5 -0
  3. package/dist/types/chat/assistant-message.d.ts +1 -1
  4. package/dist/types/chat/user-message.d.ts +3 -2
  5. package/dist/types/chrome/countdown-timer.d.ts +3 -2
  6. package/dist/types/debug-server.d.ts +2 -0
  7. package/dist/types/overlays/annotation-overlay.d.ts +19 -0
  8. package/dist/types/overlays/ask-dialog.d.ts +11 -6
  9. package/dist/types/overlays/btw-history-panel.d.ts +2 -6
  10. package/dist/types/overlays/hook-editor.d.ts +7 -2
  11. package/dist/types/overlays/hook-input.d.ts +12 -4
  12. package/dist/types/overlays/jobs-panel.d.ts +8 -7
  13. package/dist/types/overlays/login-dialog.d.ts +8 -3
  14. package/dist/types/overlays/mcp-add-wizard.d.ts +9 -1
  15. package/dist/types/overlays/pause-screen.d.ts +5 -0
  16. package/dist/types/overlays/report-panel.d.ts +5 -1
  17. package/dist/types/overlays/reset-usage-selector.d.ts +7 -5
  18. package/dist/types/overlays/session-account-selector.d.ts +4 -0
  19. package/dist/types/overlays/session-info-overlay.d.ts +7 -3
  20. package/dist/types/overlays/usage-dashboard.d.ts +6 -6
  21. package/dist/types/prompt/composer.d.ts +1 -20
  22. package/dist/types/status-line/context-usage.d.ts +1 -1
  23. package/dist/types/tools/grouped-file-output.d.ts +4 -1
  24. package/dist/types/tui.d.ts +10 -3
  25. package/package.json +9 -9
  26. package/src/app-keybindings.ts +5 -0
  27. package/src/apps/autoresearch-dashboard.ts +440 -27
  28. package/src/chat/assistant-message.ts +41 -13
  29. package/src/chat/user-message.ts +32 -19
  30. package/src/chrome/countdown-timer.ts +3 -3
  31. package/src/chrome/transcript-container.ts +202 -28
  32. package/src/debug-server.ts +51 -69
  33. package/src/hotkeys-markdown.ts +1 -0
  34. package/src/native/reconcile.ts +24 -6
  35. package/src/overlays/advisor-config.ts +259 -8
  36. package/src/overlays/annotation-overlay.ts +420 -168
  37. package/src/overlays/ask-dialog.ts +249 -105
  38. package/src/overlays/btw-history-panel.ts +178 -124
  39. package/src/overlays/hook-editor.ts +90 -32
  40. package/src/overlays/hook-input.ts +105 -19
  41. package/src/overlays/jobs-panel.ts +154 -132
  42. package/src/overlays/login-dialog.ts +201 -91
  43. package/src/overlays/mcp-add-wizard.ts +559 -279
  44. package/src/overlays/pause-screen.ts +81 -23
  45. package/src/overlays/plugin-selector.ts +17 -1
  46. package/src/overlays/queue-mode-selector.ts +10 -0
  47. package/src/overlays/report-panel.ts +6 -2
  48. package/src/overlays/reset-usage-selector.ts +130 -21
  49. package/src/overlays/session-account-selector.ts +36 -0
  50. package/src/overlays/session-info-overlay.ts +197 -76
  51. package/src/overlays/show-images-selector.ts +1 -0
  52. package/src/overlays/theme-selector.ts +6 -1
  53. package/src/overlays/thinking-selector.ts +8 -4
  54. package/src/overlays/usage-dashboard.ts +495 -143
  55. package/src/prompt/composer.ts +35 -72
  56. package/src/status-line/context-usage.ts +154 -57
  57. package/src/tools/grep.ts +1 -0
  58. package/src/tools/grouped-file-output.ts +11 -2
  59. package/src/tui.ts +27 -4
package/CHANGELOG.md CHANGED
@@ -2,6 +2,58 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [18.10.1] - 2026-10-12
6
+
7
+ ### Added
8
+
9
+ - `AssistantMessageComponent`'s native turn footer leads with a Copy icon (`omp.turn.copy`) and a dot instead of the clock icon; it copies the answer's text and shows when the host handles transcript actions
10
+
11
+ ### Changed
12
+
13
+ - `UserMessageComponent`'s native hover toolbar (`omp.user.tools`) leads with Copy and Rewind icon buttons (`copy`, `rewind`) instead of text labels, then a dot and the time, like the turn usage footer
14
+ - `ContextUsageView`'s native body (on terminals with `meter`) leads with the tokens used and the room left before auto-compaction, then one stacked bar ticked at the threshold, the breakdown as rows (`omp.context.cat`, `.cat.free`, `.cat.buffer`: swatch, name, tokens, share; the exact count in the row's `title`) and the snapcompact estimate as labelled rows (`omp.context.snap`); the blocks meter and legend `kv` are gone, and `contextUsageHead` no longer repeats the window size
15
+ - `AskDialogComponent`'s native root is `omp.editor.ask` (collapsed: `omp.editor.ask.hidden`, the countdown, the question as `omp.ask.summary`, Skip and Show): a chosen answer is the `accent`-toned row (a check also carries the check icon) instead of the highlighted one; multi-select Other… is `omp.ask.other.check`; the question tabs check answered questions and say their keys in the strip's `title`; the countdown moves from the head to the action bar beside Hide; the preview is `omp.ask.preview`; the Review tab leads with `omp.ask.notice` and lists answers (`omp.ask.answers`) by question name with inline code mono and no `(Recommended)` suffix; option descriptions run inline code mono, notes ride the row's detail as `em`; Submit/Next's tooltip names only Enter (and Space on a multi-select)
16
+ - `MCPAddWizard`'s native sheet asks one question per step: a phase strip (`omp.mcpAdd.progress` of `omp.mcpAdd.phase`, toned done/current/upcoming and `neutral` when no auth was needed), the question and its lead (`omp.mcpAdd.title`, `omp.mcpAdd.tag` for optional fields, `omp.mcpAdd.lead`), then a mono field with a placeholder and its rule or refusal (`omp.mcpAdd.field`, `tone: "error"`; `omp.mcpAdd.note`), choice rows with icons and mono tags (`omp.mcpAdd.choices`), status lines (`omp.mcpAdd.status`, `omp.mcpAdd.checks`, `omp.mcpAdd.error`) or the review rows (`omp.mcpAdd.summary`). Cancel, Back and Continue / Save server buttons run Ctrl+C, Esc and Enter instead of a key-hint strip. The connection test shows its own busy step, the OAuth client secret field is masked, and the review saves on Enter (no Yes/No choice)
17
+ - `ReportPanel`'s native body carries the role `omp.report.body`
18
+ - `HookInputComponent` describes a dock sheet (`omp.overlay.hook-input` col) like `HookEditorComponent`'s: the title's first line (`omp.hook-input.title`, the countdown as `omp.hook-input.timer`) over its further lines (`omp.hook-input.detail`), the field (`omp.hook-input.field`, `tone: "error"` while a submit was refused) with its placeholder, and Cancel / Submit buttons that run Esc / Enter; the key legend under the field is terminal-only
19
+ - `JobsSheet`'s native body is a master–detail split (`omp.jobs.split`: `omp.jobs.master` | `omp.jobs.detail`): the job list grouped Running / Recent (`omp.jobs.group` labels), each row a type icon tinted by status with its duration, beside the selected job's status pill, live elapsed and Cancel job (`omp.jobs.status`), its task title or command (`omp.jobs.title` / `omp.jobs.command`), facts (`omp.jobs.facts`: agent, directory, pids, exit code, artifact) and output (`omp.jobs.out`, `omp.jobs.nooutput`); the footer counts running and recent jobs (`omp.jobs.summary`), and no jobs shows an empty state (`omp.jobs.empty`). Task jobs no longer draw an `agent` node here
20
+ - `BtwHistoryPanel`'s native sheet is centered and reads like a mail reader: the questions as two-line rows (`omp.btw.history`, list `omp.btw.list` / `omp.btw.list.idle` while the answer has the keys) beside the selected thread (`omp.btw.reader` › `omp.btw.thread` › `omp.btw.turn`: `omp.btw.question` / `omp.btw.followup`, `omp.btw.meta`, `omp.btw.answer`, `omp.btw.error`), the follow-up field under the last answer (`omp.btw.composer`), and footer buttons Stop answer, Copy answer, Close and Follow up (Cancel and Send while composing) in place of the focus labels and key-hint strip; an empty history is an `md` sheet (`omp.btw.empty`)
21
+
22
+ ### Fixed
23
+
24
+ - `CountdownTimer`'s native `elapsed` no longer sends `stopped: 0`, which froze every native countdown (extension input, selector and editor prompts) at zero from the start
25
+ - The native backend's focus now reaches a field inside an `overlay`/`picker` sheet hoisted into the layer from a dock component (the MCP add wizard, login), so that field shows the live caret and focus ring
26
+ - `MCPAddWizard` keeps a refused name or URL in its field, clears a stale refusal on Back, ignores a connection test that settles after the user stepped back, and Edit OAuth settings after a failed sign-in opens the settings again instead of doing nothing
27
+
28
+ ## [18.10.0] - 2026-10-12
29
+
30
+ ### Breaking Changes
31
+
32
+ - Removed `RuntimeChildrenOptions.transient` and `Component.retireDisplacedTranscript`: the composer now bills all chrome below the transcript at the smallest height it has rendered, so no root opts in or out ([#15405](https://github.com/can1357/oh-my-pi/pull/15405) by [@H4vC](https://github.com/H4vC))
33
+
34
+ ### Added
35
+
36
+ - Added the `app.ask.hide` keybinding (default `Alt+H`) and Hide/Show actions on `AskDialogComponent`, which collapse the dialog to a single line while its question stays pending ([#15400](https://github.com/can1357/oh-my-pi/pull/15400) by [@H4vC](https://github.com/H4vC))
37
+
38
+ ### Changed
39
+
40
+ - The `OMP_TUI_DEBUG` control socket now uses the native IPC transport: it is owner-only and no longer replaces a socket another live process is serving.
41
+ - Transcript rows pushed aside by an open dialog, report or HUD now reach scrollback when it closes or newer output pushes them out, instead of while it is open ([#15405](https://github.com/can1357/oh-my-pi/pull/15405) by [@H4vC](https://github.com/H4vC))
42
+ - A transcript block straddling the top of the screen now sends only its off-screen rows to scrollback; the rest stays live ([#15405](https://github.com/can1357/oh-my-pi/pull/15405) by [@H4vC](https://github.com/H4vC))
43
+
44
+ ### Fixed
45
+
46
+ - Fixed blank rows opening under the editor after an ask or other inline dialog, command report or todo/loader HUD closed in a session that had filled the screen; the screen now refills with the transcript ([#15405](https://github.com/can1357/oh-my-pi/pull/15405) by [@H4vC](https://github.com/H4vC))
47
+ - Fixed the editor rising above blank rows when a live tool preview collapses under scrolled-off output; it now stays on the bottom row ([#15405](https://github.com/can1357/oh-my-pi/pull/15405) by [@H4vC](https://github.com/H4vC))
48
+ - Fixed blank rows opening inside a streamed answer when the working loader went away at the end of a turn ([#15405](https://github.com/can1357/oh-my-pi/pull/15405) by [@H4vC](https://github.com/H4vC))
49
+ - Fixed a split transcript block dropping punctuation-only rows it reveals after the split (such as a tool pane's rule line on expand); the seam now stops before them instead of treating them as already committed ([#15420](https://github.com/can1357/oh-my-pi/pull/15420) by [@H4vC](https://github.com/H4vC))
50
+ - Fixed a split transcript block fingerprinting measured rows instead of the bytes committed to scrollback, which could duplicate a SIXEL image prefix once its pending encode landed ([#15420](https://github.com/can1357/oh-my-pi/pull/15420) by [@H4vC](https://github.com/H4vC))
51
+ - Fixed a transcript block straddling the top of the screen losing its off-screen rows when the inline-image limit demoted its images to text in the same frame; those rows now reach scrollback as text
52
+
53
+ ### Removed
54
+
55
+ - Removed `Composer.pinInputToBottom()`; the composer keeps the input on the bottom row by itself ([#15405](https://github.com/can1357/oh-my-pi/pull/15405) by [@H4vC](https://github.com/H4vC))
56
+
5
57
  ## [18.9.2] - 2026-10-11
6
58
 
7
59
  ### Added
@@ -2751,108 +2803,4 @@
2751
2803
  - Reserved cursor space for zero padding and corrected end-of-line cursor rendering to prevent wrap glitches
2752
2804
  - Corrected editor end-of-line cursor rendering assertion to use includes() instead of endsWith()
2753
2805
 
2754
- ## [8.2.0] - 2026-01-24
2755
-
2756
- ### Added
2757
-
2758
- - Added mermaid diagram rendering engine (renderMermaidToPng) with mmdc CLI integration
2759
- - Added terminal graphics encoding (iTerm2/Kitty) for mermaid diagrams with automatic width scaling
2760
- - Added mermaid block extraction and deduplication utilities (extractMermaidBlocks)
2761
-
2762
- ### Changed
2763
-
2764
- - Updated TypeScript configuration for better publish-time configuration handling with tsconfig.publish.json
2765
- - Migrated file system operations from synchronous to asynchronous APIs in autocomplete provider for non-blocking I/O
2766
- - Migrated node module imports from named to namespace imports across all packages for consistency with project guidelines
2767
-
2768
- ### Fixed
2769
-
2770
- - Fixed crash when terminal becomes unavailable (EIO errors) by exiting gracefully instead of throwing
2771
- - Fixed potential errors during emergency terminal restore when terminal is already dead
2772
- - Fixed autocomplete race condition by tracking request ID to prevent stale suggestion results
2773
-
2774
- ## [6.8.3] - 2026-01-21
2775
-
2776
- ### Added
2777
-
2778
- - Added undo support in the editor via `Ctrl+-`
2779
- - Added `Alt+Delete` as a delete-word-forward shortcut
2780
- - Added configurable code block indentation for Markdown rendering
2781
- - Added undo support in the editor via `Ctrl+-`.
2782
- - Added configurable code block indentation for Markdown rendering.
2783
- - Added `Alt+Delete` as a delete-word-forward shortcut.
2784
-
2785
- ### Changed
2786
-
2787
- - Improved fuzzy matching to handle alphanumeric swaps
2788
- - Normalized keybinding definitions to lowercase internally
2789
- - Improved fuzzy matching to handle alphanumeric swaps.
2790
- - Normalized keybinding definitions to lowercase internally.
2791
-
2792
- ### Fixed
2793
-
2794
- - Added legacy terminal support for `Ctrl+` symbol key combinations
2795
- - Added legacy terminal support for `Ctrl+` symbol key combinations.
2796
-
2797
- ## [6.8.1] - 2026-01-20
2798
-
2799
- ### Fixed
2800
-
2801
- - Fixed viewport tracking after partial renders to prevent autocomplete list artifacts
2802
-
2803
- ## [5.6.7] - 2026-01-18
2804
-
2805
- ### Added
2806
-
2807
- - Added configurable editor padding via `editorPaddingX` theme option
2808
- - Added `setMaxHeight()` method to limit editor height with scrolling
2809
- - Added Emacs-style kill ring for text deletion operations
2810
- - Added `Alt+D` keybinding to delete words forward
2811
- - Added `Ctrl+Y` keybinding to yank from kill ring
2812
- - Added `waitForRender()` method to await pending renders
2813
- - Added Focusable interface and hardware cursor marker support for IME positioning
2814
- - Added support for shifted symbol keys in keybindings
2815
-
2816
- ### Changed
2817
-
2818
- - Updated tab bar rendering to wrap text across multiple lines when content exceeds available width
2819
- - Expanded Kitty keyboard protocol coverage for non-Latin layouts and legacy Alt sequences
2820
- - Improved cursor positioning with safer bounds checking
2821
- - Updated editor layout to respect configurable padding
2822
- - Refactored scrolling logic for better viewport management
2823
-
2824
- ### Fixed
2825
-
2826
- - Fixed key detection for shifted symbol characters
2827
- - Fixed backspace handling with additional codepoint support
2828
- - Fixed Alt+letter key combinations for better recognition
2829
-
2830
- ## [5.3.1] - 2026-01-15
2831
-
2832
- ### Fixed
2833
-
2834
- - Fixed rendering issues on Windows by preventing re-entrant renders
2835
-
2836
- ## [5.1.0] - 2026-01-14
2837
-
2838
- ### Added
2839
-
2840
- - Added `pageUp` and `pageDown` key support with `selectPageUp`/`selectPageDown` editor actions
2841
- - Added `isPageUp()` and `isPageDown()` helper functions
2842
- - Added `SizeValue` type for CSS-like overlay sizing (absolute or percentage strings like `"50%"`)
2843
- - Added `OverlayHandle` interface with `hide()`, `setHidden()`, `isHidden()` methods for overlay visibility control
2844
- - Added `visible` callback to `OverlayOptions` for dynamic visibility based on terminal dimensions
2845
- - Added `pad` parameter to `truncateToWidth()` for padding result with spaces to exact width
2846
-
2847
- ### Changed
2848
-
2849
- - Changed `OverlayOptions` to use `SizeValue` type for `width`, `maxHeight`, `row`, and `col` properties
2850
- - Changed `showOverlay()` to return `OverlayHandle` for controlling overlay visibility
2851
- - Removed `widthPercent`, `maxHeightPercent`, `rowPercent`, `colPercent` from `OverlayOptions` (use percentage strings instead)
2852
-
2853
- ### Fixed
2854
-
2855
- - Fixed numbered list items showing "1." for all items when code blocks break list continuity
2856
- - Fixed width overflow protection in overlay compositing to prevent TUI crashes
2857
-
2858
- Older entries are archived in [packages/tui/CHANGELOG.md@60347ef0f214](https://github.com/can1357/oh-my-pi/blob/60347ef0f214fa63df596d143477268da3f0c904/packages/tui/CHANGELOG.md).
2806
+ Older entries are archived in [packages/tui/CHANGELOG.md@89ad0a77d575](https://github.com/can1357/oh-my-pi/blob/89ad0a77d575f01398d3c0a57bc3a22111bef36a/packages/tui/CHANGELOG.md).
@@ -17,6 +17,7 @@ interface AppKeybindings {
17
17
  "app.model.selectTemporary": true;
18
18
  "app.tools.expand": true;
19
19
  "app.tools.toggleVisibility": true;
20
+ "app.ask.hide": true;
20
21
  "app.editor.external": true;
21
22
  "app.message.followUp": true;
22
23
  "app.retry": true;
@@ -238,6 +239,10 @@ export declare const KEYBINDINGS: {
238
239
  readonly defaultKeys: "ctrl+shift+o";
239
240
  readonly description: "Show or hide tool activity";
240
241
  };
242
+ readonly "app.ask.hide": {
243
+ readonly defaultKeys: "alt+h";
244
+ readonly description: "Hide or show a pending ask dialog";
245
+ };
241
246
  readonly "app.editor.external": {
242
247
  readonly defaultKeys: "ctrl+g";
243
248
  readonly description: "Open external editor";
@@ -105,7 +105,7 @@ export declare class AssistantMessageComponent extends Container {
105
105
  * tags it `↺ rewound` (the ANSI render leaves it as it stopped).
106
106
  */
107
107
  markRewound(): void;
108
- /** Mirrors a thinking section collapsed or expanded in the terminal. */
108
+ /** Mirrors a thinking section collapsed or expanded in the terminal; runs its controls' clicks. */
109
109
  handleNativeEvent(event: NativeUiEvent): void;
110
110
  /** Width-independent stable identities for the streamed leading thinking run. */
111
111
  getTranscriptStableRows(): readonly TranscriptStableRow[];
@@ -39,8 +39,9 @@ export declare class UserMessageComponent extends Container implements ReactionT
39
39
  /**
40
40
  * A head-less user-toned frame with the prompt as markdown under its
41
41
  * attached images (titled `#N` like their chips, opening the materialized
42
- * file on click): the fill says "you". A quiet toolbar (time, Copy, Rewind) fades in on hover when the
43
- * host handles transcript actions. The live-steering marker and the
42
+ * file on click): the fill says "you". A quiet footer like a turn's usage line
43
+ * (`⧉ ⏪ · 09:45`: Copy, Rewind, the time sent) fades in at its bottom-left on hover when
44
+ * the host handles transcript actions. The live-steering marker and the
44
45
  * agent's reaction are chips at the bottom-right, so a reaction landing
45
46
  * later updates the frame in place, even deep in scrollback.
46
47
  */
@@ -8,8 +8,9 @@ export declare class CountdownTimer {
8
8
  constructor(timeoutMs: number, tui: TUI | undefined, onTick: (seconds: number) => void, onExpire: () => void);
9
9
  /**
10
10
  * The remaining time as a terminal-clocked `elapsed` node: its age is the
11
- * negative remaining time (the start lies in the future), so it counts up
12
- * toward zero and freezes there at expiry. The age is taken on the first
11
+ * negative remaining time (the start lies in the future), so it counts down
12
+ * to zero and holds there at expiry (no `stopped`: that would freeze it at
13
+ * zero from the start). The age is taken on the first
13
14
  * call after a (re)start, when the node is first written, and the node is
14
15
  * reused until {@link reset}.
15
16
  */
@@ -22,6 +22,8 @@ export interface TuiDebugTree {
22
22
  export declare class TuiDebugServer {
23
23
  #private;
24
24
  constructor(tui: TUI, path: string);
25
+ /** Resolves true once the socket accepts connections, false if listen failed or the server stopped first. */
26
+ get ready(): Promise<boolean>;
25
27
  start(): void;
26
28
  stop(): void;
27
29
  }
@@ -2,6 +2,7 @@ import { type Focusable, type TUI } from "../index.js";
2
2
  import { type KeybindingsManager } from "../app-keybindings.js";
3
3
  import { type Theme } from "../theme/theme.js";
4
4
  import type { CodeReviewAnnotation, CodeReviewOverlayResult, ReviewDiffFile, TextReviewAnnotation, TextReviewOverlayResult, TextReviewSource } from "./annotation-types.js";
5
+ import type { TspSpan } from "@oh-my-pi/pi-wire";
5
6
  import { type NativeNode, type NativeUiEvent } from "../native/node.js";
6
7
  export declare const CONTINUE_CODE_REVIEW_ACTION = "Continue with LLM review";
7
8
  export declare const PASTE_CODE_REVIEW_ACTION = "Paste annotations into prompt";
@@ -21,6 +22,12 @@ export interface TextReviewOverlayCallbacks extends AnnotationOverlayCallbacks {
21
22
  }
22
23
  /** Splits a text source into the overlay's 1-based annotatable lines. */
23
24
  export declare function splitTextLines(text: string): string[];
25
+ /** The native sheet: full-pane glass, titled by the review kind with what is under review after it. */
26
+ interface NativeSheet {
27
+ readonly role: "omp.overlay.codeReview" | "omp.overlay.annotateText";
28
+ readonly size: "full";
29
+ readonly head: TspSpan[];
30
+ }
24
31
  /** A fullscreen, annotated diff picker that only relies on public OMP APIs. */
25
32
  export declare class AnnotationOverlay implements Focusable {
26
33
  #private;
@@ -44,7 +51,19 @@ export declare class AnnotationOverlay implements Focusable {
44
51
  */
45
52
  replaceTextSource(text: string): number;
46
53
  handleInput(data: string): void;
54
+ /**
55
+ * The terminal draws the frame: a full-pane glass sheet titled `Code review`
56
+ * (or `Annotate text`), then what is under review as a quieter subtitle.
57
+ */
58
+ get nativeOverlay(): NativeSheet;
59
+ /**
60
+ * The sheet's body: the file rail (totals over the changed files) beside
61
+ * the current file's diff (text: its numbered lines), the note composer
62
+ * docked under the lines while a note is open, and a footer of key hints
63
+ * and the actions.
64
+ */
47
65
  describe(): NativeNode;
48
66
  handleNativeEvent(event: NativeUiEvent): void;
49
67
  render(width: number): readonly string[];
50
68
  }
69
+ export {};
@@ -88,7 +88,6 @@ export declare class AskDialogComponent implements Component {
88
88
  #private;
89
89
  private readonly callbacks;
90
90
  private readonly options;
91
- readonly retireDisplacedTranscript = true;
92
91
  constructor(questions: ExtensionAskDialogQuestion[], callbacks: AskDialogCallbacks, options?: AskDialogOptions);
93
92
  invalidate(): void;
94
93
  dispose(): void;
@@ -102,17 +101,23 @@ export declare class AskDialogComponent implements Component {
102
101
  render(width: number): readonly string[];
103
102
  /**
104
103
  * In the dock, in the composer's place and framed as the composer is: a
105
- * `col` with the prompt editor's root role (`omp.editor`), so the terminal
106
- * gives it the composer's insets and spacing. Not a modal `overlay` sheet:
107
- * one anchored at the bottom covered the transcript rows that explain the
108
- * question and blocked scrolling until the question was answered.
104
+ * `col` with an `omp.editor.*` root role (`omp.editor.ask`, collapsed
105
+ * `omp.editor.ask.hidden`), so the terminal draws the composer's shell
106
+ * around it. Not a modal `overlay` sheet: one anchored at the bottom
107
+ * covered the transcript rows that explain the question and blocked
108
+ * scrolling until the question was answered.
109
+ *
110
+ * Anatomy: the question tabs (several questions), the question, its
111
+ * answers as radio/check rows, and the action bar as the footer (the
112
+ * countdown, Hide, then Note, Skip and the primary Submit/Next).
109
113
  */
110
114
  describe(cx: DescribeContext): NativeNode;
111
115
  /**
112
116
  * Pointer actions: a tab click switches to it; a click on an answer row is
113
117
  * Enter on it (Space for a multi-select option, so it toggles; its
114
118
  * double-click `activate` is Enter); the action bar's Submit, Note and Skip
115
- * run exactly what Enter, `n` and Esc run on the highlighted row.
119
+ * run exactly what Enter, `n` and Esc run on the highlighted row; Hide/Show
120
+ * collapse and restore the dialog.
116
121
  */
117
122
  handleNativeEvent(event: NativeUiEvent): void;
118
123
  }
@@ -40,12 +40,8 @@ export declare class BtwHistoryPanel implements Component, Focusable {
40
40
  /** Enhanced clipboard pastes belong only to the active composer. */
41
41
  pasteText(text: string): void;
42
42
  handleInput(data: string): void;
43
- /** A large glass sheet titled "BTW history". */
44
- readonly nativeOverlay: {
45
- readonly role: "omp.overlay.btwHistory";
46
- readonly size: "lg";
47
- readonly head: "BTW history";
48
- };
43
+ /** A large glass sheet (the list beside the reader), palette-sized while there is nothing to list. */
44
+ get nativeOverlay(): NonNullable<Component["nativeOverlay"]>;
49
45
  describe(): NativeNode;
50
46
  handleNativeEvent(event: NativeUiEvent): void;
51
47
  render(width: number): readonly string[];
@@ -10,7 +10,7 @@
10
10
  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
- import type { DescribeContext, NativeNode } from "../native/node.js";
13
+ import type { DescribeContext, NativeNode, NativeUiEvent } from "../native/node.js";
14
14
  /**
15
15
  * `prefix` and `question` flattened onto one line, wrapped to the terminal's width and cut to
16
16
  * {@link MAX_PROMPT_TITLE_ROWS} rows (the last ends in `…` when cut). For terminal rendering only:
@@ -58,8 +58,13 @@ export declare class HookEditorComponent extends OverlayPanel implements Focusab
58
58
  /** Focus state mirrored to the nested editor during rendering. */
59
59
  focused: boolean;
60
60
  constructor(tui: TUI, title: string, prefill: string | undefined, onSubmit: (value: string, images?: ImageContent[]) => void, onCancel: () => void, options?: HookEditorOptions);
61
- /** The editor (which describes itself) under the title and detail lines, with the key hints below. */
61
+ /**
62
+ * A sheet in the composer's place: the title (or, answering a question, the question under the
63
+ * prompt's name) over a hairline, the editor, and Open in editor · Cancel · Submit.
64
+ */
62
65
  describe(_cx: DescribeContext): NativeNode;
66
+ /** The action bar's buttons run what their keys run. */
67
+ handleNativeEvent(event: NativeUiEvent): void;
63
68
  /** Keep the nested editor's software/hardware cursor mode aligned with the dialog focus target. */
64
69
  setUseTerminalCursor(useTerminalCursor: boolean): void;
65
70
  /** Render the dialog after forwarding its focus state to the nested editor. */
@@ -1,9 +1,9 @@
1
1
  /**
2
- * Simple text input component for hooks.
2
+ * One-line text prompt an extension (hook) asks the user.
3
3
  */
4
4
  import { type TUI } from "../index.js";
5
5
  import { OverlayPanel } from "../chrome/overlay-box.js";
6
- import type { DescribeContext, NativeNode } from "../native/node.js";
6
+ import type { DescribeContext, NativeNode, NativeUiEvent } from "../native/node.js";
7
7
  export interface HookInputOptions {
8
8
  tui?: TUI;
9
9
  timeout?: number;
@@ -11,13 +11,21 @@ export interface HookInputOptions {
11
11
  }
12
12
  export declare class HookInputComponent extends OverlayPanel {
13
13
  #private;
14
- constructor(title: string, _placeholder: string | undefined, onSubmit: (value: string) => void, onCancel: () => void, opts?: HookInputOptions);
14
+ constructor(title: string, placeholder: string | undefined, onSubmit: (value: string) => void, onCancel: () => void, opts?: HookInputOptions);
15
15
  handleInput(keyData: string): void;
16
16
  /** Route non-bracketed paste transports (e.g. kitty's OSC 5522 enhanced clipboard)
17
17
  * into the inner field, mirroring bracketed-paste semantics. Pasting counts as
18
18
  * interaction, so the timeout countdown resets like any keystroke. */
19
19
  pasteText(text: string): void;
20
+ /** Submit and Cancel run what Enter and the interrupt key run. */
21
+ handleNativeEvent(event: NativeUiEvent): void;
20
22
  dispose(): void;
21
- /** A card over the form, headed by the title plus the countdown `elapsed` while a timeout runs. */
23
+ /**
24
+ * A sheet in the composer's place, built like the extension editor's: the
25
+ * title's first line (the countdown at its end while a timeout runs) over
26
+ * any further lines as detail, the field written on the sheet (tinted, the
27
+ * reason under it, while a submit was refused), and Cancel · Submit, whose
28
+ * keys live in their tooltips.
29
+ */
22
30
  describe(_cx: DescribeContext): NativeNode;
23
31
  }
@@ -42,12 +42,13 @@ export interface JobsSheetSource {
42
42
  }
43
43
  /**
44
44
  * The jobs pill's sheet: a centred `lg` glass sheet titled Background jobs.
45
- * A selectable list of every job (running first) sits over the selected
46
- * job's detail: status and live elapsed (a task job's `agent` node), cwd,
47
- * live pids, exit code, the full command and a tail-following output pane.
48
- * It re-reads the session every frame, so the caller re-renders it on a
49
- * timer while it is open. ↑/↓ select, X cancels the selected running job,
50
- * Esc or Close dismisses; nothing enters the transcript.
45
+ * A master–detail split (it stacks in a narrow pane): the selectable job list,
46
+ * grouped Running / Recent, beside the selected job's detail — a status pill
47
+ * with live elapsed and Cancel job, its command or task, facts (agent, cwd,
48
+ * live pids, exit code, artifact) and a tail-following output pane. With no
49
+ * jobs it shows an empty state. It re-reads the session every frame, so the
50
+ * caller re-renders it on a timer while it is open. ↑/↓ select, X cancels the
51
+ * selected running job, Esc or Close dismisses; nothing enters the transcript.
51
52
  */
52
53
  export declare class JobsSheet implements Component {
53
54
  #private;
@@ -58,7 +59,7 @@ export declare class JobsSheet implements Component {
58
59
  readonly head: "Background jobs";
59
60
  };
60
61
  constructor(source: JobsSheetSource);
61
- describe(cx: DescribeContext): NativeNode;
62
+ describe(_cx: DescribeContext): NativeNode;
62
63
  /** Rows for a terminal without the native surface: one per job, then the selected job's facts and output tail. */
63
64
  render(width: number): readonly string[];
64
65
  invalidate(): void;
@@ -40,9 +40,14 @@ export declare class LoginDialogComponent extends OverlayPanel {
40
40
  showProgress(message: string): void;
41
41
  /**
42
42
  * A glass sheet over the composer (the dialog replaces the editor in the
43
- * dock; the `overlay` hoists into the terminal's layer): numbered steps —
44
- * open or copy the sign-in link, the device code, the live wait, the paste
45
- * field — and Cancel.
43
+ * dock; the `overlay` hoists into the terminal's layer). Top to bottom: one
44
+ * sentence saying what to do, the device code as a large click-to-copy
45
+ * well, the sign-in link as a read-only field with Copy, the questions
46
+ * (answered ones as label/value lines, the live one as a field), and the
47
+ * flow's status — finished stages checked, the current one spinning. The
48
+ * footer holds Cancel and one primary action: Continue while a field waits
49
+ * for an answer (Open sign-in page then leads the footer as a plain
50
+ * button), else Open sign-in page.
46
51
  */
47
52
  describe(): NativeNode;
48
53
  /** Cancel and Continue run what Esc and Enter run. */
@@ -83,8 +83,16 @@ interface MCPAddWizardOAuthOptions {
83
83
  export declare class MCPAddWizard extends OverlayPanel {
84
84
  #private;
85
85
  constructor(deps: MCPAddWizardDeps, onComplete: (name: string, config: MCPAddWizardConfig, scope: Scope) => void, onCancel: () => void, onOAuth?: (authUrl: string, tokenUrl: string, clientId: string, clientSecret: string, scopes: string, options?: MCPAddWizardOAuthOptions) => Promise<MCPAddWizardOAuthResult>, onTestConnection?: (config: MCPAddWizardConfig) => Promise<void>, onRender?: () => void, initialName?: string);
86
+ /**
87
+ * The sheet: the phase strip, the step's title and lead, its body (field,
88
+ * status, summary), its choices, and a footer whose buttons run what
89
+ * Escape, Enter and Ctrl+C run.
90
+ */
86
91
  describe(_cx: DescribeContext): NativeNode;
87
- /** A click on a choice is Enter on it, exactly as highlighting it with the arrows and pressing Enter. */
92
+ /**
93
+ * A click on a choice is Enter on it, exactly as highlighting it with the
94
+ * arrows and pressing Enter; the footer's buttons run what their keys run.
95
+ */
88
96
  handleNativeEvent(event: NativeUiEvent): void;
89
97
  handleInput(keyData: string): void;
90
98
  }
@@ -41,6 +41,11 @@ export declare class PauseScreenComponent implements Component, OverlayFocusOwne
41
41
  readonly anchor: "center";
42
42
  readonly head: "Paused";
43
43
  };
44
+ /**
45
+ * The sheet: a hero (the pause glyph beside the live hold clock and the
46
+ * session it holds), what the hold means as four facts, and a footer that
47
+ * reassures and resumes. The resume keys live in the button's tooltip.
48
+ */
44
49
  describe(): NativeNode;
45
50
  /** Resume runs what Esc/Enter/Space run. */
46
51
  handleNativeEvent(event: NativeUiEvent): void;
@@ -55,7 +55,11 @@ export declare class ReportPanel extends OverlayPanel {
55
55
  render(width: number): readonly string[];
56
56
  /** Text mode: rows the whole box takes at `width` when nothing caps it. */
57
57
  heightAt(width: number): number;
58
- /** The sheet body (the overlay is the frame, and its body the scroller): the report, then Close (Esc). */
58
+ /**
59
+ * The sheet body (the overlay is the frame, and its body the scroller): the
60
+ * report as `omp.report.body`, which the terminal sets on the reading
61
+ * measure, then Close (Esc) as the sheet's footer.
62
+ */
59
63
  describe(): NativeNode;
60
64
  invalidate(): void;
61
65
  /**
@@ -1,6 +1,6 @@
1
1
  import type { UsageResetCreditDetail } from "@oh-my-pi/pi-ai";
2
2
  import { OverlayPanel } from "../chrome/overlay-box.js";
3
- import type { NativeNode, NativeUiEvent } from "../native/node.js";
3
+ import type { DescribeContext, NativeNode, NativeUiEvent } from "../native/node.js";
4
4
  /** One account row with its redeemable rate-limit reset credits. */
5
5
  export interface ResetUsageAccount {
6
6
  label: string;
@@ -33,11 +33,13 @@ export declare class ResetUsageSelectorComponent extends OverlayPanel {
33
33
  #private;
34
34
  constructor(accounts: ResetUsageAccount[], onSelect: (account: ResetUsageAccount) => void, onCancel: () => void);
35
35
  handleInput(keyData: string): void;
36
- describe(): NativeNode;
36
+ describe(cx: DescribeContext): NativeNode;
37
37
  /**
38
- * A click (or double-click) on an account highlights it and presses Enter:
39
- * moving to another account drops a pending confirmation, so spending a
40
- * reset still takes a second activation of the same account.
38
+ * Picker: a row click selects, a double-click or `Spend reset` presses
39
+ * Enter (so spending still takes a second activation, on the confirm
40
+ * strip), the strip's `Keep` drops the confirmation and `Close` cancels.
41
+ * Card list: a click (or double-click) on an account highlights it and
42
+ * presses Enter.
41
43
  */
42
44
  handleNativeEvent(event: NativeUiEvent): void;
43
45
  }
@@ -1,5 +1,6 @@
1
1
  import { type SgrMouseEvent } from "../index.js";
2
2
  import { OverlayPanel } from "../chrome/overlay-box.js";
3
+ import type { DescribeContext, NativeNode, NativeUiEvent } from "../native/node.js";
3
4
  /** Stored account identity rendered and matched by the session account picker. */
4
5
  export interface SessionPinAccount {
5
6
  position: number;
@@ -17,6 +18,9 @@ export interface SessionPinAccount {
17
18
  export declare class SessionAccountSelectorComponent extends OverlayPanel {
18
19
  #private;
19
20
  constructor(providerName: string, accounts: readonly SessionPinAccount[], onSelect: (account: SessionPinAccount) => void, onCancel: () => void);
21
+ describe(cx: DescribeContext): NativeNode | null;
22
+ /** Picker pointer events drive the list exactly as its keys do. */
23
+ handleNativeEvent(event: NativeUiEvent): void;
20
24
  /** Forward keyboard navigation and cancellation when the wrapper owns focus. */
21
25
  handleInput(keyData: string): void;
22
26
  /** Route mouse selection through the title rows into the account list. */
@@ -24,9 +24,13 @@ export declare class SessionInfoOverlay implements Component {
24
24
  setIgnoreTight(ignore: boolean): this;
25
25
  dispose(): void;
26
26
  /**
27
- * The sheet body (the overlay is the frame): the session id in mono
28
- * (click copies), each report heading as a section of key/value rows, a
29
- * context meter after the leading block, and a Close button (Esc).
27
+ * The sheet body (the overlay is the frame), in three tiers: who the session
28
+ * is (the id and file as copyable mono fields), how full its context window
29
+ * is (a meter under a right-aligned figure), then the report's sections as
30
+ * headed groups. Groups of plain counts (Messages, Tokens, Cost) share a
31
+ * two-column stats grid with right-aligned figures and their Total set off
32
+ * last; the rest (Provider, servers) are key/value rows. A Close button (Esc)
33
+ * ends it.
30
34
  */
31
35
  describe(cx: DescribeContext): NativeNode;
32
36
  /** The Close button runs Esc's path. */
@@ -122,12 +122,12 @@ export declare class UsageDashboardComponent implements Component {
122
122
  dispose(): void;
123
123
  render(width: number): readonly string[];
124
124
  /**
125
- * The sheet body (the terminal's `lg` overlay is the frame): a head row
126
- * (checked ago, Overview/Details tabs, Refresh), then either the provider
127
- * grid of frames with window meters and the activity heatmap, or the
128
- * per-provider detail tables, then Close like the other report sheets.
129
- * `meter`/`chart` fall back to `progress`/`table` on terminals without
130
- * them. Rebuilt only when its inputs change.
125
+ * The sheet body (the terminal's `lg` overlay is the frame): a toolbar
126
+ * (Overview/Details, freshness, Refresh), then either the overview — a
127
+ * strip of headline figures, the quota rows per provider, the activity
128
+ * calendar — or the per-provider detail tables, then Close like the other
129
+ * report sheets. `meter`/`chart` fall back to `progress`/`table` on
130
+ * terminals without them. Rebuilt only when its inputs change.
131
131
  */
132
132
  describe(cx: DescribeContext): NativeNode;
133
133
  /** Tab clicks switch views like Enter/Esc; the Refresh button runs `r`; Close closes from either view. */
@@ -50,18 +50,8 @@ export interface ComposerOptions {
50
50
  readonly exit?: (code: number) => void;
51
51
  readonly now?: () => number;
52
52
  }
53
- /** How {@link Composer.setRuntimeChildren} bills below-transcript roots against transcript retirement. */
53
+ /** How {@link Composer.setRuntimeChildren} lays out the roots below the transcript. */
54
54
  export interface RuntimeChildrenOptions {
55
- /**
56
- * Below-transcript roots whose growth is momentary (inline dialogs, a tall
57
- * multi-line editor). They are billed at their smallest height so expansion
58
- * clips the live tail instead of retiring rows a later shrink could not
59
- * reclaim (#11007). Every other root is billed at its current height, so
60
- * settled rows it displaces retire to native scrollback. Decision panels
61
- * declaring `retireDisplacedTranscript` opt out of this floor even when
62
- * mounted as a child of a transient editor container.
63
- */
64
- readonly transient?: readonly Component[];
65
55
  /**
66
56
  * Dock order on a TSP terminal (no status strip; the composer carries its
67
57
  * facts): the native dock stacks HUD pills, the working row and queued messages over
@@ -123,15 +113,6 @@ export declare class Composer implements TerminalFrameProvider, NativeSurfacePro
123
113
  * the screen rows left above them; `undefined` before `root` was laid out.
124
114
  */
125
115
  rowsBelow(root: Component): number | undefined;
126
- /**
127
- * Keep the input on the bottom row while the live rows cannot fill the
128
- * screen, as after an inline decision panel closes. A tall block that just
129
- * left the chrome above the editor (a command report) may have scrolled
130
- * rows into native history that cannot be pulled back; without the pin the
131
- * editor would jump up to where the shorter frame now ends. The pin lifts
132
- * once live rows fill the screen again.
133
- */
134
- pinInputToBottom(): void;
135
116
  /** Compose the bounded mutable viewport and the next ordered history append. */
136
117
  renderFrame(viewport: ViewportSize): TerminalFramePlan;
137
118
  /**
@@ -155,7 +155,7 @@ export declare function computeNonMessageBreakdown(session: NonMessageTokenSourc
155
155
  * session and model.
156
156
  */
157
157
  export declare function computeContextBreakdown(session: ContextUsageSession, options: ContextUsageOptions): ContextBreakdown;
158
- /** The `/context` title: the model and its window once a model is selected. */
158
+ /** The `/context` title: the model once one is selected (the body leads with its window). */
159
159
  export declare function contextUsageHead(breakdown: ContextBreakdown): TspText;
160
160
  /**
161
161
  * Native context-usage panel for terminals without `meter`: the cell grid as