@oh-my-pi/pi-tui 18.10.0 → 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 (49) hide show
  1. package/CHANGELOG.md +24 -105
  2. package/dist/types/chat/assistant-message.d.ts +1 -1
  3. package/dist/types/chat/user-message.d.ts +3 -2
  4. package/dist/types/chrome/countdown-timer.d.ts +3 -2
  5. package/dist/types/overlays/annotation-overlay.d.ts +19 -0
  6. package/dist/types/overlays/ask-dialog.d.ts +9 -4
  7. package/dist/types/overlays/btw-history-panel.d.ts +2 -6
  8. package/dist/types/overlays/hook-editor.d.ts +7 -2
  9. package/dist/types/overlays/hook-input.d.ts +12 -4
  10. package/dist/types/overlays/jobs-panel.d.ts +8 -7
  11. package/dist/types/overlays/login-dialog.d.ts +8 -3
  12. package/dist/types/overlays/mcp-add-wizard.d.ts +9 -1
  13. package/dist/types/overlays/pause-screen.d.ts +5 -0
  14. package/dist/types/overlays/report-panel.d.ts +5 -1
  15. package/dist/types/overlays/reset-usage-selector.d.ts +7 -5
  16. package/dist/types/overlays/session-account-selector.d.ts +4 -0
  17. package/dist/types/overlays/session-info-overlay.d.ts +7 -3
  18. package/dist/types/overlays/usage-dashboard.d.ts +6 -6
  19. package/dist/types/status-line/context-usage.d.ts +1 -1
  20. package/dist/types/tools/grouped-file-output.d.ts +4 -1
  21. package/package.json +9 -9
  22. package/src/apps/autoresearch-dashboard.ts +440 -27
  23. package/src/chat/assistant-message.ts +41 -13
  24. package/src/chat/user-message.ts +32 -19
  25. package/src/chrome/countdown-timer.ts +3 -3
  26. package/src/native/reconcile.ts +24 -6
  27. package/src/overlays/advisor-config.ts +259 -8
  28. package/src/overlays/annotation-overlay.ts +420 -168
  29. package/src/overlays/ask-dialog.ts +154 -90
  30. package/src/overlays/btw-history-panel.ts +178 -124
  31. package/src/overlays/hook-editor.ts +90 -32
  32. package/src/overlays/hook-input.ts +105 -19
  33. package/src/overlays/jobs-panel.ts +154 -132
  34. package/src/overlays/login-dialog.ts +201 -91
  35. package/src/overlays/mcp-add-wizard.ts +559 -279
  36. package/src/overlays/pause-screen.ts +81 -23
  37. package/src/overlays/plugin-selector.ts +17 -1
  38. package/src/overlays/queue-mode-selector.ts +10 -0
  39. package/src/overlays/report-panel.ts +6 -2
  40. package/src/overlays/reset-usage-selector.ts +130 -21
  41. package/src/overlays/session-account-selector.ts +36 -0
  42. package/src/overlays/session-info-overlay.ts +197 -76
  43. package/src/overlays/show-images-selector.ts +1 -0
  44. package/src/overlays/theme-selector.ts +6 -1
  45. package/src/overlays/thinking-selector.ts +8 -4
  46. package/src/overlays/usage-dashboard.ts +495 -143
  47. package/src/status-line/context-usage.ts +154 -57
  48. package/src/tools/grep.ts +1 -0
  49. package/src/tools/grouped-file-output.ts +11 -2
package/CHANGELOG.md CHANGED
@@ -2,6 +2,29 @@
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
+
5
28
  ## [18.10.0] - 2026-10-12
6
29
 
7
30
  ### Breaking Changes
@@ -2780,108 +2803,4 @@
2780
2803
  - Reserved cursor space for zero padding and corrected end-of-line cursor rendering to prevent wrap glitches
2781
2804
  - Corrected editor end-of-line cursor rendering assertion to use includes() instead of endsWith()
2782
2805
 
2783
- ## [8.2.0] - 2026-01-24
2784
-
2785
- ### Added
2786
-
2787
- - Added mermaid diagram rendering engine (renderMermaidToPng) with mmdc CLI integration
2788
- - Added terminal graphics encoding (iTerm2/Kitty) for mermaid diagrams with automatic width scaling
2789
- - Added mermaid block extraction and deduplication utilities (extractMermaidBlocks)
2790
-
2791
- ### Changed
2792
-
2793
- - Updated TypeScript configuration for better publish-time configuration handling with tsconfig.publish.json
2794
- - Migrated file system operations from synchronous to asynchronous APIs in autocomplete provider for non-blocking I/O
2795
- - Migrated node module imports from named to namespace imports across all packages for consistency with project guidelines
2796
-
2797
- ### Fixed
2798
-
2799
- - Fixed crash when terminal becomes unavailable (EIO errors) by exiting gracefully instead of throwing
2800
- - Fixed potential errors during emergency terminal restore when terminal is already dead
2801
- - Fixed autocomplete race condition by tracking request ID to prevent stale suggestion results
2802
-
2803
- ## [6.8.3] - 2026-01-21
2804
-
2805
- ### Added
2806
-
2807
- - Added undo support in the editor via `Ctrl+-`
2808
- - Added `Alt+Delete` as a delete-word-forward shortcut
2809
- - Added configurable code block indentation for Markdown rendering
2810
- - Added undo support in the editor via `Ctrl+-`.
2811
- - Added configurable code block indentation for Markdown rendering.
2812
- - Added `Alt+Delete` as a delete-word-forward shortcut.
2813
-
2814
- ### Changed
2815
-
2816
- - Improved fuzzy matching to handle alphanumeric swaps
2817
- - Normalized keybinding definitions to lowercase internally
2818
- - Improved fuzzy matching to handle alphanumeric swaps.
2819
- - Normalized keybinding definitions to lowercase internally.
2820
-
2821
- ### Fixed
2822
-
2823
- - Added legacy terminal support for `Ctrl+` symbol key combinations
2824
- - Added legacy terminal support for `Ctrl+` symbol key combinations.
2825
-
2826
- ## [6.8.1] - 2026-01-20
2827
-
2828
- ### Fixed
2829
-
2830
- - Fixed viewport tracking after partial renders to prevent autocomplete list artifacts
2831
-
2832
- ## [5.6.7] - 2026-01-18
2833
-
2834
- ### Added
2835
-
2836
- - Added configurable editor padding via `editorPaddingX` theme option
2837
- - Added `setMaxHeight()` method to limit editor height with scrolling
2838
- - Added Emacs-style kill ring for text deletion operations
2839
- - Added `Alt+D` keybinding to delete words forward
2840
- - Added `Ctrl+Y` keybinding to yank from kill ring
2841
- - Added `waitForRender()` method to await pending renders
2842
- - Added Focusable interface and hardware cursor marker support for IME positioning
2843
- - Added support for shifted symbol keys in keybindings
2844
-
2845
- ### Changed
2846
-
2847
- - Updated tab bar rendering to wrap text across multiple lines when content exceeds available width
2848
- - Expanded Kitty keyboard protocol coverage for non-Latin layouts and legacy Alt sequences
2849
- - Improved cursor positioning with safer bounds checking
2850
- - Updated editor layout to respect configurable padding
2851
- - Refactored scrolling logic for better viewport management
2852
-
2853
- ### Fixed
2854
-
2855
- - Fixed key detection for shifted symbol characters
2856
- - Fixed backspace handling with additional codepoint support
2857
- - Fixed Alt+letter key combinations for better recognition
2858
-
2859
- ## [5.3.1] - 2026-01-15
2860
-
2861
- ### Fixed
2862
-
2863
- - Fixed rendering issues on Windows by preventing re-entrant renders
2864
-
2865
- ## [5.1.0] - 2026-01-14
2866
-
2867
- ### Added
2868
-
2869
- - Added `pageUp` and `pageDown` key support with `selectPageUp`/`selectPageDown` editor actions
2870
- - Added `isPageUp()` and `isPageDown()` helper functions
2871
- - Added `SizeValue` type for CSS-like overlay sizing (absolute or percentage strings like `"50%"`)
2872
- - Added `OverlayHandle` interface with `hide()`, `setHidden()`, `isHidden()` methods for overlay visibility control
2873
- - Added `visible` callback to `OverlayOptions` for dynamic visibility based on terminal dimensions
2874
- - Added `pad` parameter to `truncateToWidth()` for padding result with spaces to exact width
2875
-
2876
- ### Changed
2877
-
2878
- - Changed `OverlayOptions` to use `SizeValue` type for `width`, `maxHeight`, `row`, and `col` properties
2879
- - Changed `showOverlay()` to return `OverlayHandle` for controlling overlay visibility
2880
- - Removed `widthPercent`, `maxHeightPercent`, `rowPercent`, `colPercent` from `OverlayOptions` (use percentage strings instead)
2881
-
2882
- ### Fixed
2883
-
2884
- - Fixed numbered list items showing "1." for all items when code blocks break list continuity
2885
- - Fixed width overflow protection in overlay compositing to prevent TUI crashes
2886
-
2887
- 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).
@@ -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
  */
@@ -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 {};
@@ -101,10 +101,15 @@ export declare class AskDialogComponent implements Component {
101
101
  render(width: number): readonly string[];
102
102
  /**
103
103
  * In the dock, in the composer's place and framed as the composer is: a
104
- * `col` with the prompt editor's root role (`omp.editor`), so the terminal
105
- * gives it the composer's insets and spacing. Not a modal `overlay` sheet:
106
- * one anchored at the bottom covered the transcript rows that explain the
107
- * 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).
108
113
  */
109
114
  describe(cx: DescribeContext): NativeNode;
110
115
  /**
@@ -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. */
@@ -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
@@ -121,9 +121,12 @@ export declare function numberedCode(lines: readonly NumberedLine[], opts?: {
121
121
  * header's suffix or the match count as a chip), then its lines as
122
122
  * {@link numberedCode} with match lines marked and `…` between non-adjacent
123
123
  * runs. Unnumbered body lines stay plain `code`. `maxFiles` keeps only the
124
- * first files (the caller says how many were left out).
124
+ * first files (the caller says how many were left out). `file` owns the lines
125
+ * before any header: a single-file search prints none, yet its lines get the
126
+ * same file row as a directory search's.
125
127
  */
126
128
  export declare function describeGroupedOutput(lines: readonly string[], options?: {
127
129
  lang?: (path: string) => string | undefined;
128
130
  maxFiles?: number;
131
+ file?: string;
129
132
  }): NativeNode[];
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@oh-my-pi/pi-tui",
4
- "version": "18.10.0",
4
+ "version": "18.10.1",
5
5
  "description": "Terminal User Interface library with differential rendering for efficient text-based applications",
6
6
  "homepage": "https://omp.sh",
7
7
  "author": {
@@ -41,14 +41,14 @@
41
41
  "gen:glyphs": "bun scripts/gen-glyphs.ts"
42
42
  },
43
43
  "dependencies": {
44
- "@oh-my-pi/omptype": "18.10.0",
45
- "@oh-my-pi/pi-agent-core": "18.10.0",
46
- "@oh-my-pi/pi-ai": "18.10.0",
47
- "@oh-my-pi/pi-catalog": "18.10.0",
48
- "@oh-my-pi/pi-natives": "18.10.0",
49
- "@oh-my-pi/pi-utils": "18.10.0",
50
- "@oh-my-pi/pi-wire": "18.10.0",
51
- "@oh-my-pi/snapcompact": "18.10.0"
44
+ "@oh-my-pi/omptype": "18.10.1",
45
+ "@oh-my-pi/pi-agent-core": "18.10.1",
46
+ "@oh-my-pi/pi-ai": "18.10.1",
47
+ "@oh-my-pi/pi-catalog": "18.10.1",
48
+ "@oh-my-pi/pi-natives": "18.10.1",
49
+ "@oh-my-pi/pi-utils": "18.10.1",
50
+ "@oh-my-pi/pi-wire": "18.10.1",
51
+ "@oh-my-pi/snapcompact": "18.10.1"
52
52
  },
53
53
  "devDependencies": {
54
54
  "kitty-vt-wasm": "^0.2.0"