@oh-my-pi/pi-tui 18.13.2 → 18.14.0

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 (245) hide show
  1. package/CHANGELOG.md +40 -54
  2. package/README.md +34 -34
  3. package/dist/types/app-keybindings.d.ts +15 -0
  4. package/dist/types/apps/session-picker.d.ts +5 -0
  5. package/dist/types/charts/chart-plan.d.ts +9 -7
  6. package/dist/types/chat/assistant-message.d.ts +15 -3
  7. package/dist/types/chat/bash-execution.d.ts +2 -0
  8. package/dist/types/chat/display-preferences.d.ts +2 -0
  9. package/dist/types/chat/extension-types.d.ts +31 -0
  10. package/dist/types/chat/reply-write.d.ts +48 -0
  11. package/dist/types/chat/table-chart.d.ts +4 -3
  12. package/dist/types/chat/tool-execution.d.ts +1 -2
  13. package/dist/types/chat/transcript-outline.d.ts +7 -0
  14. package/dist/types/chat/transcript-render-helpers.d.ts +2 -0
  15. package/dist/types/chrome/index.d.ts +1 -0
  16. package/dist/types/chrome/transcript-notice.d.ts +35 -0
  17. package/dist/types/chrome/transcript-status.d.ts +20 -8
  18. package/dist/types/components/editor.d.ts +8 -0
  19. package/dist/types/components/markdown.d.ts +7 -0
  20. package/dist/types/native/blobs.d.ts +2 -1
  21. package/dist/types/native/picker.d.ts +3 -3
  22. package/dist/types/overlays/annotation-overlay.d.ts +7 -1
  23. package/dist/types/overlays/annotation-types.d.ts +28 -0
  24. package/dist/types/overlays/login-dialog.d.ts +5 -1
  25. package/dist/types/overlays/model-browser.d.ts +10 -1
  26. package/dist/types/overlays/oauth-selector.d.ts +23 -0
  27. package/dist/types/overlays/plan-review-overlay.d.ts +2 -0
  28. package/dist/types/overlays/rewind-selector.d.ts +1 -1
  29. package/dist/types/overlays/session-selector.d.ts +22 -2
  30. package/dist/types/prompt/composer.d.ts +41 -4
  31. package/dist/types/prompt/interactive-context-helpers.d.ts +10 -3
  32. package/dist/types/prompt/welcome.d.ts +6 -2
  33. package/dist/types/render/extension-links.d.ts +65 -0
  34. package/dist/types/render/hyperlink.d.ts +25 -7
  35. package/dist/types/render/index.d.ts +1 -0
  36. package/dist/types/setup/scenes/model.d.ts +1 -1
  37. package/dist/types/setup/scenes/outro.d.ts +5 -4
  38. package/dist/types/setup/scenes/sign-in.d.ts +13 -8
  39. package/dist/types/setup/scenes/splash.d.ts +4 -4
  40. package/dist/types/setup/scenes/types.d.ts +16 -1
  41. package/dist/types/setup/startup-splash.d.ts +1 -1
  42. package/dist/types/setup/wizard-overlay.d.ts +11 -7
  43. package/dist/types/setup/wizard.d.ts +5 -1
  44. package/dist/types/status-line/component.d.ts +1 -1
  45. package/dist/types/status-line/context-usage.d.ts +28 -6
  46. package/dist/types/status-line/host.d.ts +6 -2
  47. package/dist/types/theme/theme.d.ts +0 -23
  48. package/dist/types/tools/bash-interactive.d.ts +6 -0
  49. package/dist/types/tools/bash.d.ts +2 -0
  50. package/dist/types/tools/default-renderer.d.ts +6 -4
  51. package/dist/types/tools/irc.d.ts +6 -0
  52. package/dist/types/tools/json-tree.d.ts +23 -4
  53. package/dist/types/tools/lsp.d.ts +2 -0
  54. package/dist/types/tools/mcp.d.ts +6 -5
  55. package/dist/types/tools/native-view.d.ts +1 -1
  56. package/dist/types/tools/renderer.d.ts +2 -0
  57. package/dist/types/tools/streaming-output.d.ts +11 -0
  58. package/dist/types/tools/task.d.ts +9 -1
  59. package/dist/types/tools/url-scheme-host.d.ts +17 -0
  60. package/dist/types/tools/yield.d.ts +1 -1
  61. package/dist/types/tui.d.ts +7 -2
  62. package/package.json +10 -15
  63. package/src/app-keybindings.ts +15 -0
  64. package/src/apps/session-picker.ts +7 -0
  65. package/src/charts/chart-plan.ts +20 -50
  66. package/src/chat/advisor-message.ts +2 -0
  67. package/src/chat/assistant-message.ts +137 -19
  68. package/src/chat/background-tan-message.ts +4 -0
  69. package/src/chat/bash-execution.ts +6 -0
  70. package/src/chat/chat-transcript-builder.ts +58 -28
  71. package/src/chat/compaction-summary-message.ts +2 -1
  72. package/src/chat/display-preferences.ts +3 -0
  73. package/src/chat/extension-types.ts +34 -0
  74. package/src/chat/reply-write.ts +127 -0
  75. package/src/chat/table-chart.ts +10 -4
  76. package/src/chat/tool-execution.ts +20 -13
  77. package/src/chat/transcript-outline.ts +27 -0
  78. package/src/chat/transcript-render-helpers.ts +66 -24
  79. package/src/chrome/index.ts +1 -0
  80. package/src/chrome/transcript-notice.ts +83 -0
  81. package/src/chrome/transcript-status.ts +29 -29
  82. package/src/components/editor.ts +10 -1
  83. package/src/components/markdown.ts +116 -6
  84. package/src/hotkeys-markdown.ts +1 -0
  85. package/src/native/backend.ts +5 -66
  86. package/src/native/blobs.ts +3 -2
  87. package/src/native/picker.ts +3 -3
  88. package/src/overlays/advisor-config.ts +1 -10
  89. package/src/overlays/annotation-overlay.ts +125 -37
  90. package/src/overlays/annotation-types.ts +24 -0
  91. package/src/overlays/hook-selector.ts +2 -2
  92. package/src/overlays/login-dialog.ts +31 -5
  93. package/src/overlays/model-browser.ts +37 -0
  94. package/src/overlays/model-hub.ts +1 -7
  95. package/src/overlays/model-picker.ts +1 -10
  96. package/src/overlays/oauth-selector.ts +44 -6
  97. package/src/overlays/plan-review-overlay.ts +13 -2
  98. package/src/overlays/rewind-selector.ts +29 -12
  99. package/src/overlays/session-selector.ts +305 -39
  100. package/src/overlays/usage-dashboard.ts +5 -12
  101. package/src/prompt/composer.ts +213 -5
  102. package/src/prompt/custom-editor.ts +6 -1
  103. package/src/prompt/emoji-autocomplete.ts +0 -2
  104. package/src/prompt/interactive-context-helpers.ts +29 -4
  105. package/src/prompt/welcome.ts +31 -45
  106. package/src/render/extension-links.ts +214 -0
  107. package/src/render/hyperlink.ts +65 -9
  108. package/src/render/index.ts +1 -0
  109. package/src/setup/scenes/composer.ts +2 -0
  110. package/src/setup/scenes/glyph.ts +2 -0
  111. package/src/setup/scenes/model.ts +192 -29
  112. package/src/setup/scenes/outro.ts +30 -17
  113. package/src/setup/scenes/sign-in.ts +196 -400
  114. package/src/setup/scenes/splash.ts +25 -21
  115. package/src/setup/scenes/theme.ts +2 -0
  116. package/src/setup/scenes/types.ts +18 -1
  117. package/src/setup/startup-splash.ts +8 -7
  118. package/src/setup/wizard-overlay.ts +164 -33
  119. package/src/setup/wizard.ts +11 -2
  120. package/src/status-line/component.ts +4 -10
  121. package/src/status-line/context-usage.ts +72 -21
  122. package/src/status-line/host.ts +6 -2
  123. package/src/terminal.ts +24 -2
  124. package/src/theme/defaults.json +1 -0
  125. package/src/theme/loader.ts +1 -1
  126. package/src/theme/theme.ts +2 -75
  127. package/src/tools/bash-interactive.ts +6 -1
  128. package/src/tools/bash.ts +2 -0
  129. package/src/tools/default-renderer.ts +9 -6
  130. package/src/tools/eval.ts +14 -4
  131. package/src/tools/irc.ts +6 -0
  132. package/src/tools/job-widget.ts +13 -1
  133. package/src/tools/json-tree.ts +132 -42
  134. package/src/tools/lsp.ts +36 -15
  135. package/src/tools/mcp.ts +20 -12
  136. package/src/tools/native-view.ts +1 -1
  137. package/src/tools/renderer.ts +2 -0
  138. package/src/tools/streaming-output.ts +41 -0
  139. package/src/tools/task.ts +59 -17
  140. package/src/tools/url-scheme-host.ts +21 -0
  141. package/src/tools/yield.ts +18 -9
  142. package/src/tui.ts +43 -15
  143. package/THIRD-PARTY-NOTICES.txt +0 -22901
  144. package/dist/types/theme/defaults/index.d.ts +0 -10289
  145. package/src/theme/defaults/alabaster.json +0 -103
  146. package/src/theme/defaults/amethyst.json +0 -106
  147. package/src/theme/defaults/anthracite.json +0 -103
  148. package/src/theme/defaults/basalt.json +0 -101
  149. package/src/theme/defaults/birch.json +0 -105
  150. package/src/theme/defaults/dark-abyss.json +0 -101
  151. package/src/theme/defaults/dark-arctic.json +0 -114
  152. package/src/theme/defaults/dark-aurora.json +0 -105
  153. package/src/theme/defaults/dark-catppuccin.json +0 -117
  154. package/src/theme/defaults/dark-cavern.json +0 -101
  155. package/src/theme/defaults/dark-celestial.json +0 -116
  156. package/src/theme/defaults/dark-copper.json +0 -105
  157. package/src/theme/defaults/dark-cosmos.json +0 -100
  158. package/src/theme/defaults/dark-cyberpunk.json +0 -112
  159. package/src/theme/defaults/dark-dracula.json +0 -108
  160. package/src/theme/defaults/dark-eclipse.json +0 -101
  161. package/src/theme/defaults/dark-ember.json +0 -105
  162. package/src/theme/defaults/dark-equinox.json +0 -100
  163. package/src/theme/defaults/dark-forest.json +0 -106
  164. package/src/theme/defaults/dark-github.json +0 -115
  165. package/src/theme/defaults/dark-gruvbox.json +0 -122
  166. package/src/theme/defaults/dark-lavender.json +0 -105
  167. package/src/theme/defaults/dark-lunar.json +0 -99
  168. package/src/theme/defaults/dark-midnight.json +0 -105
  169. package/src/theme/defaults/dark-monochrome.json +0 -104
  170. package/src/theme/defaults/dark-monokai.json +0 -108
  171. package/src/theme/defaults/dark-nebula.json +0 -100
  172. package/src/theme/defaults/dark-neon-noir.json +0 -110
  173. package/src/theme/defaults/dark-nord.json +0 -108
  174. package/src/theme/defaults/dark-ocean.json +0 -111
  175. package/src/theme/defaults/dark-one.json +0 -110
  176. package/src/theme/defaults/dark-poimandres.json +0 -125
  177. package/src/theme/defaults/dark-rainforest.json +0 -101
  178. package/src/theme/defaults/dark-reef.json +0 -101
  179. package/src/theme/defaults/dark-retro.json +0 -102
  180. package/src/theme/defaults/dark-rose-pine.json +0 -106
  181. package/src/theme/defaults/dark-sakura.json +0 -105
  182. package/src/theme/defaults/dark-slate.json +0 -105
  183. package/src/theme/defaults/dark-solarized.json +0 -107
  184. package/src/theme/defaults/dark-solstice.json +0 -100
  185. package/src/theme/defaults/dark-starfall.json +0 -101
  186. package/src/theme/defaults/dark-sunset.json +0 -109
  187. package/src/theme/defaults/dark-swamp.json +0 -100
  188. package/src/theme/defaults/dark-synthwave.json +0 -113
  189. package/src/theme/defaults/dark-taiga.json +0 -101
  190. package/src/theme/defaults/dark-terminal.json +0 -105
  191. package/src/theme/defaults/dark-tokyo-night.json +0 -111
  192. package/src/theme/defaults/dark-tundra.json +0 -101
  193. package/src/theme/defaults/dark-twilight.json +0 -101
  194. package/src/theme/defaults/dark-volcanic.json +0 -101
  195. package/src/theme/defaults/graphite.json +0 -102
  196. package/src/theme/defaults/index.ts +0 -203
  197. package/src/theme/defaults/light-arctic.json +0 -117
  198. package/src/theme/defaults/light-aurora-day.json +0 -101
  199. package/src/theme/defaults/light-canyon.json +0 -101
  200. package/src/theme/defaults/light-catppuccin.json +0 -116
  201. package/src/theme/defaults/light-cirrus.json +0 -100
  202. package/src/theme/defaults/light-coral.json +0 -105
  203. package/src/theme/defaults/light-cyberpunk.json +0 -106
  204. package/src/theme/defaults/light-dawn.json +0 -100
  205. package/src/theme/defaults/light-dunes.json +0 -101
  206. package/src/theme/defaults/light-eucalyptus.json +0 -105
  207. package/src/theme/defaults/light-forest.json +0 -110
  208. package/src/theme/defaults/light-frost.json +0 -105
  209. package/src/theme/defaults/light-github.json +0 -125
  210. package/src/theme/defaults/light-glacier.json +0 -101
  211. package/src/theme/defaults/light-gruvbox.json +0 -118
  212. package/src/theme/defaults/light-haze.json +0 -100
  213. package/src/theme/defaults/light-honeycomb.json +0 -105
  214. package/src/theme/defaults/light-lagoon.json +0 -101
  215. package/src/theme/defaults/light-lavender.json +0 -105
  216. package/src/theme/defaults/light-meadow.json +0 -101
  217. package/src/theme/defaults/light-mint.json +0 -105
  218. package/src/theme/defaults/light-monochrome.json +0 -111
  219. package/src/theme/defaults/light-ocean.json +0 -109
  220. package/src/theme/defaults/light-one.json +0 -109
  221. package/src/theme/defaults/light-opal.json +0 -101
  222. package/src/theme/defaults/light-orchard.json +0 -101
  223. package/src/theme/defaults/light-paper.json +0 -105
  224. package/src/theme/defaults/light-poimandres.json +0 -125
  225. package/src/theme/defaults/light-prism.json +0 -100
  226. package/src/theme/defaults/light-retro.json +0 -108
  227. package/src/theme/defaults/light-sand.json +0 -105
  228. package/src/theme/defaults/light-savanna.json +0 -101
  229. package/src/theme/defaults/light-solarized.json +0 -112
  230. package/src/theme/defaults/light-soleil.json +0 -100
  231. package/src/theme/defaults/light-sunset.json +0 -109
  232. package/src/theme/defaults/light-synthwave.json +0 -108
  233. package/src/theme/defaults/light-tokyo-night.json +0 -121
  234. package/src/theme/defaults/light-wetland.json +0 -101
  235. package/src/theme/defaults/light-zenith.json +0 -99
  236. package/src/theme/defaults/limestone.json +0 -104
  237. package/src/theme/defaults/mahogany.json +0 -107
  238. package/src/theme/defaults/marble.json +0 -103
  239. package/src/theme/defaults/obsidian.json +0 -101
  240. package/src/theme/defaults/onyx.json +0 -101
  241. package/src/theme/defaults/pearl.json +0 -103
  242. package/src/theme/defaults/porcelain.json +0 -101
  243. package/src/theme/defaults/quartz.json +0 -106
  244. package/src/theme/defaults/sandstone.json +0 -105
  245. package/src/theme/defaults/titanium.json +0 -100
@@ -1,24 +1,36 @@
1
+ import type { TspSpan } from "@oh-my-pi/pi-wire";
1
2
  import type { NativeNode } from "../native/node.js";
2
3
  import { type ThemeColor } from "../theme/index.js";
3
4
  import { TranscriptBlock } from "./transcript-container.js";
4
- /** One themed run of a status row. */
5
+ import { type NoticeTone } from "./transcript-notice.js";
6
+ /** One themed run of a status row's terminal line. */
5
7
  export interface TranscriptStatusPart {
6
8
  readonly text: string;
7
9
  readonly color: ThemeColor;
8
- /** Glyph art (tree connectors) drawn only in rows; native terminals draw their own structure. */
9
- readonly rowsOnly?: boolean;
10
10
  }
11
- /** One compact transcript status row assembled from themed parts, joined by single spaces. */
11
+ /** A status row in a native terminal: its {@link noticeRow}'s tone, icon and message. */
12
+ export interface TranscriptStatusNative {
13
+ readonly tone: NoticeTone;
14
+ /** Icon name in place of the tone's own. */
15
+ readonly icon?: string;
16
+ readonly message: readonly TspSpan[];
17
+ }
18
+ /**
19
+ * One compact transcript status row: the terminal line's themed parts (joined
20
+ * by single spaces, glyphs and brackets included) and the same row natively.
21
+ */
12
22
  export interface TranscriptStatusRow {
13
23
  readonly parts: readonly (TranscriptStatusPart | undefined)[];
14
24
  readonly indent?: number;
25
+ readonly native: TranscriptStatusNative;
15
26
  }
16
- /** Shared compact status-pill block used by notices and background activity. */
27
+ /**
28
+ * Shared compact status block for background activity and prompt file reads:
29
+ * one themed line per row in a text terminal, one notice row per row natively
30
+ * (`omp.status-block`).
31
+ */
17
32
  export declare class TranscriptStatusBlock extends TranscriptBlock {
18
33
  #private;
19
34
  constructor(rows: readonly TranscriptStatusRow[]);
20
- /** Append a supplemental line such as an artifact warning. */
21
- addLine(parts: readonly (TranscriptStatusPart | undefined)[], indent?: number): void;
22
- /** One wrapped text line per status row. */
23
35
  describe(): NativeNode;
24
36
  }
@@ -98,6 +98,14 @@ export declare class Editor implements Component, Focusable {
98
98
  describeDecorations: ((lines: readonly string[]) => readonly TspEditorDecoration[]) | undefined;
99
99
  /** TSP code language of the buffer (`python`, `bash`): the terminal highlights it in the mono face. */
100
100
  describeLanguage: (() => string | undefined) | undefined;
101
+ /** Label the TSP field to disable host-side editing while another input owner handles raw keys. */
102
+ nativeKeyPassthrough: boolean;
103
+ /**
104
+ * Ask the TSP terminal to keep what is typed into this field and draw it at
105
+ * the caret until this clears, then send it: set while startup cannot read
106
+ * input yet (the prompt composer's deferred-input start).
107
+ */
108
+ nativeTypeahead: boolean;
101
109
  /**
102
110
  * TSP chrome around the `editor` node (the prompt composer's chips, mode
103
111
  * chip, send/stop): the root role, the children with `input` placed where
@@ -10,6 +10,13 @@ import type { Component } from "../tui.js";
10
10
  * byte-identical to rendering `text`.
11
11
  */
12
12
  export declare function streamingMarkdownSource(text: string): string;
13
+ /**
14
+ * Whether `text` ends inside a code fence the source never closed. The
15
+ * renderer still draws such a fence's closing border, so a caller publishing a
16
+ * settled source prefix must drop that fabricated row: it is not a prefix of
17
+ * the live block, which reaches the border only once the closer arrives.
18
+ */
19
+ export declare function endsInsideOpenFence(text: string): boolean;
13
20
  /**
14
21
  * Streaming `md` source for a native terminal, minus a still-growing table row:
15
22
  * the unterminated last line when a GFM table (a run of pipe lines holding a
@@ -29,7 +29,8 @@ export declare function base64ImageNode(data: string, mimeType: string, p?: Omit
29
29
  /**
30
30
  * Props that make an `image` node open the file at `filePath` (as a `file://` URL, the TSP
31
31
  * open-target form): a click zooms the image in the terminal, and the file opens from its
32
- * context menu. Empty without a file.
32
+ * context menu. Always uses a local file URL because the open action runs locally,
33
+ * even when remote file handlers are configured. Empty without a file.
33
34
  */
34
35
  export declare function openableImageProps(filePath: string | undefined): Pick<TspProps<"image">, "href" | "actions">;
35
36
  /**
@@ -16,14 +16,14 @@
16
16
  * the item id and `action` with an action id (plus `value` for
17
17
  * `scope`/`tab`/`strip`). {@link pickerEvent} folds them into one shape.
18
18
  */
19
- import type { TspPickerAction, TspPickerItem, TspPickerProps } from "@oh-my-pi/pi-wire";
19
+ import type { TspPickerAction, TspPickerItem, TspPickerProps, TspProps } from "@oh-my-pi/pi-wire";
20
20
  import type { KeyName } from "../key-hint-format.js";
21
21
  import { type Keybinding } from "../keybindings.js";
22
22
  import type { Input } from "../components/input.js";
23
23
  import type { SelectItem, SelectList } from "../components/select-list.js";
24
24
  import type { NativeChild, NativeNode, NativeUiEvent } from "./node.js";
25
25
  /** The picker sheet; `preview` children fill its preview pane. */
26
- export declare function picker(p: TspPickerProps, preview?: readonly NativeChild[]): NativeNode;
26
+ export declare function picker(p: TspProps<"picker">, preview?: readonly NativeChild[]): NativeNode;
27
27
  /**
28
28
  * A picker's search field from the {@link Input} that edits it: the text and
29
29
  * its caret. `null` hides the field. Memoized pickers MUST key on the caret
@@ -37,7 +37,7 @@ export declare const PICKER_KEY = "picker";
37
37
  * the picker as child {@link PICKER_KEY}, which the reconciler hoists into
38
38
  * `layer`. Route its events with `pickerEvent(event, PICKER_KEY)`.
39
39
  */
40
- export declare function dockedPicker(p: TspPickerProps, preview?: readonly NativeChild[]): NativeNode;
40
+ export declare function dockedPicker(p: TspProps<"picker">, preview?: readonly NativeChild[]): NativeNode;
41
41
  /** Keycap names for one key id (`"alt+enter"` → `["alt", "enter"]`, `"escape"` → `["esc"]`). */
42
42
  export declare function pickerKeys(key: KeyName | string): string[];
43
43
  /** The keycaps of a keybinding's primary key, empty when unbound. */
@@ -1,7 +1,7 @@
1
1
  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
- import type { CodeReviewAnnotation, CodeReviewOverlayResult, ReviewDiffFile, TextReviewAnnotation, TextReviewOverlayResult, TextReviewSource } from "./annotation-types.js";
4
+ import type { AnnotationOverlayDraft, CodeReviewAnnotation, CodeReviewOverlayResult, ReviewDiffFile, TextReviewAnnotation, TextReviewOverlayResult, TextReviewSource } from "./annotation-types.js";
5
5
  import type { TspSpan } from "@oh-my-pi/pi-wire";
6
6
  import { type NativeNode, type NativeUiEvent } from "../native/node.js";
7
7
  export declare const CONTINUE_CODE_REVIEW_ACTION = "Continue with LLM review";
@@ -20,6 +20,8 @@ export interface CodeReviewOverlayCallbacks extends AnnotationOverlayCallbacks {
20
20
  export interface TextReviewOverlayCallbacks extends AnnotationOverlayCallbacks {
21
21
  onComplete(result: TextReviewOverlayResult | undefined): void;
22
22
  }
23
+ /** Clears every note and closes; the host then has nothing to keep. Needs a second confirm. */
24
+ export declare const DISCARD_ANNOTATIONS_ACTION = "Discard notes and close";
23
25
  /** Splits a text source into the overlay's 1-based annotatable lines. */
24
26
  export declare function splitTextLines(text: string): string[];
25
27
  /** The native sheet: full-pane glass, titled by the review kind with what is under review after it. */
@@ -38,6 +40,10 @@ export declare class AnnotationOverlay implements Focusable {
38
40
  setUseTerminalCursor(useTerminalCursor: boolean): void;
39
41
  invalidate(): void;
40
42
  dispose(): void;
43
+ /** Notes, the unfinished note, and any source edit, in the form {@link restoreDraft} replays. */
44
+ getDraft(): AnnotationOverlayDraft;
45
+ /** Replay a draft taken from this same source; anything anchored outside it is dropped. */
46
+ restoreDraft(draft: AnnotationOverlayDraft): void;
41
47
  getAnnotations(): CodeReviewAnnotation[];
42
48
  getTextAnnotations(): TextReviewAnnotation[];
43
49
  /** Repo-relative path of the diff file under the cursor, if this is a code review. */
@@ -84,3 +84,31 @@ export interface TextReviewOverlayResult {
84
84
  /** Source text after an external-editor edit; absent when the source was not edited. */
85
85
  editedText?: string;
86
86
  }
87
+ export type AnnotationOverlayDraft = {
88
+ kind: "diff";
89
+ annotations: {
90
+ fileIndex: number;
91
+ sourceIndex: number;
92
+ annotation: CodeReviewAnnotation;
93
+ }[];
94
+ editor?: {
95
+ fileIndex: number;
96
+ sourceIndex: number;
97
+ scope: "file" | "line";
98
+ editingAnnotationIndex?: number;
99
+ text: string;
100
+ };
101
+ } | {
102
+ kind: "text";
103
+ annotations: {
104
+ sourceIndex: number;
105
+ annotation: TextReviewAnnotation;
106
+ }[];
107
+ editedText?: string;
108
+ editor?: {
109
+ sourceIndex: number;
110
+ scope: "text" | "line";
111
+ editingAnnotationIndex?: number;
112
+ text: string;
113
+ };
114
+ };
@@ -7,7 +7,11 @@ import type { NativeNode, NativeUiEvent } from "../native/node.js";
7
7
  */
8
8
  export declare class LoginDialogComponent extends OverlayPanel {
9
9
  #private;
10
- constructor(tui: TUI, providerId: string, onComplete: (success: boolean, message?: string) => void, openUrl: (url: string) => void);
10
+ constructor(tui: Pick<TUI, "requestRender">, providerId: string, onComplete: (success: boolean, message?: string) => void, openUrl: (url: string) => void);
11
+ /** Focus reaches the live field: it draws the caret (the hardware cursor when the terminal's is on). */
12
+ get focused(): boolean;
13
+ set focused(value: boolean);
14
+ setUseTerminalCursor(useTerminalCursor: boolean): void;
11
15
  get signal(): AbortSignal;
12
16
  /**
13
17
  * Called by the OAuth `onAuth` callback. Renders the full authorization URL
@@ -4,7 +4,7 @@ import type { Component } from "../tui.js";
4
4
  import type { SgrMouseEvent } from "../mouse.js";
5
5
  import { type ConfiguredThinkingLevel } from "../thinking.js";
6
6
  import { type ThemeColor } from "../theme/theme.js";
7
- import type { TspPickerColumn, TspPickerGroup, TspPickerItem, TspPickerMark } from "@oh-my-pi/pi-wire";
7
+ import type { TspPickerColumn, TspPickerGroup, TspPickerItem, TspPickerMark, TspPickerProps } from "@oh-my-pi/pi-wire";
8
8
  import type { NativeChild, NativeNode, NativeUiEvent } from "../native/node.js";
9
9
  /** Canonical display ordering of built-in model roles. */
10
10
  export type ModelRole = "default" | "smol" | "slow" | "vision" | "plan" | "commit" | "tiny" | "memory" | "task" | "advisor" | "widget" | "image" | "web" | "speech" | "dictation" | "judge";
@@ -232,6 +232,8 @@ export interface ModelPickerCatalogue {
232
232
  readonly itemsAdd?: readonly TspPickerItem[];
233
233
  readonly itemsDel?: readonly string[];
234
234
  }
235
+ /** The search, fact-column and row props every model `picker` sheet sends ({@link ModelBrowser.pickerRows}). */
236
+ export type ModelPickerRows = Pick<TspPickerProps, "query" | "cursor" | "columns" | "items" | "itemsAdd" | "itemsDel" | "order" | "hits" | "selected" | "current" | "total">;
235
237
  /** How {@link ModelBrowser.pickerOrder} heads its rows. */
236
238
  export interface ModelPickerGrouping {
237
239
  /** One group per provider after the Recent block (the unfiltered All models view). */
@@ -329,6 +331,13 @@ export declare class ModelBrowser implements Component {
329
331
  get baseCount(): number;
330
332
  /** The selected row's selector, null when nothing selectable is selected. */
331
333
  get pickerSelected(): string | null;
334
+ /**
335
+ * A model picker's search field, fact columns and rows: `catalogue` (from
336
+ * {@link pickerItems}) in `view` order (from {@link pickerOrder}), the
337
+ * selection, and `current` checked. Memoize hosts on its inputs plus
338
+ * {@link query}, {@link cursor} and {@link pickerSelected}.
339
+ */
340
+ pickerRows(catalogue: ModelPickerCatalogue, view: ModelPickerOrder, current: string | undefined): ModelPickerRows;
332
341
  /**
333
342
  * Picker rows for `catalogue`: the same object while the catalogue, roles
334
343
  * and row inputs are unchanged, so typing and scope hops never resend it.
@@ -1,12 +1,30 @@
1
1
  import type { CredentialsApi, KeysApi } from "@oh-my-pi/pi-ai";
2
2
  import { type SgrMouseEvent } from "../index.js";
3
3
  import { OverlayPanel } from "../chrome/overlay-box.js";
4
+ import type { TspText } from "@oh-my-pi/pi-wire";
4
5
  import type { DescribeContext, NativeNode, NativeUiEvent } from "../native/node.js";
5
6
  /** Credential presence and provenance needed by the provider picker. */
6
7
  export interface OAuthSelectorAuthSource {
7
8
  readonly credentials: Pick<CredentialsApi, "has">;
8
9
  readonly keys: Pick<KeysApi, "source">;
9
10
  }
11
+ /**
12
+ * How a host other than `/login` presents the native provider sheet (the
13
+ * setup wizard): its heading, `role` and size, a status line docked above the
14
+ * action bar, and the Esc action that leaves in place of Close (the action's
15
+ * `id` cancels like Esc).
16
+ */
17
+ export interface OAuthSelectorSheet {
18
+ readonly title: string;
19
+ readonly subtitle: TspText;
20
+ readonly role: string;
21
+ readonly size: "md" | "lg";
22
+ readonly status?: TspText;
23
+ readonly leave: {
24
+ readonly id: string;
25
+ readonly label: string;
26
+ };
27
+ }
10
28
  /**
11
29
  * Component that renders an OAuth provider selector.
12
30
  */
@@ -16,8 +34,13 @@ export declare class OAuthSelectorComponent extends OverlayPanel {
16
34
  disabledProviders?: readonly string[];
17
35
  validateAuth?: (providerId: string) => Promise<boolean>;
18
36
  requestRender?: () => void;
37
+ sheet?: OAuthSelectorSheet;
19
38
  });
20
39
  stopValidation(): void;
40
+ /** Replace the native sheet's presentation (a new outcome line, a relabelled leave action). */
41
+ setSheet(sheet: OAuthSelectorSheet): void;
42
+ /** Re-read credential state after a sign-in stored one, keeping the query and selection. */
43
+ refreshAuth(): void;
21
44
  /**
22
45
  * Fit the selector into `lines` rendered rows by shrinking the visible list
23
46
  * window (the window is centered on the selection, so the selected row is
@@ -74,6 +74,8 @@ export interface PlanReviewOverlayOptions {
74
74
  slider?: HookSelectorSlider;
75
75
  /** Display label for the external-editor key, surfaced in the footer help. */
76
76
  externalEditorLabel?: string;
77
+ /** The external editor's name ("Notepad", "nvim") for the native Edit button; `$EDITOR` when unset. */
78
+ externalEditorName?: string;
77
79
  /** Serializable annotations restored into this overlay instance. */
78
80
  annotationState?: PlanReviewAnnotationState;
79
81
  }
@@ -74,7 +74,7 @@ export declare class RewindSelectorComponent implements Component {
74
74
  * of branch columns, the current path first. The bar is this component's
75
75
  * own node, docked under the page, so the filter field keeps the caret.
76
76
  */
77
- describeScreen(_cx: DescribeContext): NativeScreen;
77
+ describeScreen(cx: DescribeContext): NativeScreen;
78
78
  /** The bar docked under the page: position, key hints, Cancel and Rewind; the filter field while filtering. */
79
79
  describe(_cx: DescribeContext): NativeNode;
80
80
  /** The bar's buttons run their keys' paths; everything else belongs to the blocks. */
@@ -71,6 +71,8 @@ declare class SessionList<T extends SessionSelectorEntry> implements Component {
71
71
  onExit: () => void;
72
72
  onToggleScope?: () => void;
73
73
  onDeleteRequest?: (session: T) => void;
74
+ onRenameRequest?: (session: T) => void;
75
+ onPinRequest?: (session: T, pinned: boolean) => void;
74
76
  /** Re-render hook for async list updates (fuzzy scan completion, history merge). */
75
77
  onRequestRender?: () => void;
76
78
  constructor(sessions: T[], showCwd?: boolean, historyMatcher?: SessionHistoryMatcher, getTerminalRows?: () => number, pinnedIds?: ReadonlySet<string>, currentSessionPath?: string | (() => string | undefined));
@@ -79,6 +81,8 @@ declare class SessionList<T extends SessionSelectorEntry> implements Component {
79
81
  /** Cancel pending async search work; idempotent, called on every picker exit path. */
80
82
  dispose(): void;
81
83
  removeSession(sessionPath: string): void;
84
+ /** Update a session's title in place and refresh the visible list, keeping the selection. */
85
+ renameSessionTitle(sessionPath: string, title: string): void;
82
86
  /** Resolve a list-local rendered-line index to a filtered-session index. */
83
87
  hitTestSession(line: number): number | undefined;
84
88
  /** Wheel notch: move the selection one step (clamped, no wrap). */
@@ -93,6 +97,14 @@ declare class SessionList<T extends SessionSelectorEntry> implements Component {
93
97
  resumeSelected(): void;
94
98
  /** Delete / Backspace on an empty query: ask the parent to confirm deleting the selected session. */
95
99
  requestDelete(): void;
100
+ /** F2: ask the parent to rename the selected session. */
101
+ requestRename(): void;
102
+ /** Pin keys: ask the parent to pin or unpin the selected session (default: flip it); no-op when already there. */
103
+ requestPin(pinned?: boolean): void;
104
+ /** Apply a persisted pin change; the list re-partitions and the cursor follows the session. */
105
+ setPinned(sessionId: string, pinned: boolean): void;
106
+ /** Whether the selected session is pinned (picks the pin action's direction). */
107
+ get selectedPinned(): boolean;
96
108
  /** Empty the search query (the empty state's "Clear search"). */
97
109
  clearSearch(): void;
98
110
  get selectedSession(): T | undefined;
@@ -120,6 +132,14 @@ declare class SessionList<T extends SessionSelectorEntry> implements Component {
120
132
  }
121
133
  export interface SessionSelectorOptions<T extends SessionSelectorEntry = SessionSelectorEntry> {
122
134
  onDelete?: (session: T) => Promise<boolean>;
135
+ /**
136
+ * Rename the selected session to a user-supplied title; resolve with the
137
+ * title as stored (the session canonicalizes it) or null when the rename
138
+ * did not happen.
139
+ */
140
+ onRename?: (session: T, title: string) => Promise<string | null>;
141
+ /** Persist the selected session's pin state (pin keys / the picker's Pin action). */
142
+ onSetPinned?: (session: T, pinned: boolean) => Promise<void>;
123
143
  historyMatcher?: SessionHistoryMatcher;
124
144
  /** Loads sessions across all projects for the all-projects scope toggle (Tab). */
125
145
  loadAllSessions?: () => Promise<T[]>;
@@ -188,8 +208,8 @@ export declare class SessionSelectorComponent<T extends SessionSelectorEntry = S
188
208
  /**
189
209
  * With the `picker` kind: the data-first session picker (§4.7). Otherwise
190
210
  * scope `tabs`, loading/error message, then the search `input` and session
191
- * `list` — or the delete-confirmation dialog in their place, as on the ANSI
192
- * path — and the key-hint footer.
211
+ * `list` — or the delete-confirmation / rename dialog in their place, as on
212
+ * the ANSI path — and the key-hint footer.
193
213
  */
194
214
  describe(cx: DescribeContext): NativeNode;
195
215
  /** Picker events (root keypath); fallback: scope tab → toggle scope, click on a session → resume it, exactly like a mouse click. */
@@ -108,12 +108,19 @@ export interface ViewportClickRowTarget {
108
108
  * decides focusability and recency.
109
109
  */
110
110
  export declare function routeViewportClick(spans: readonly ViewportClickSpan[], index: number): string[];
111
+ /** An extension link label drawn on a mutable-viewport line: what a click or hint tag lands on. */
112
+ export interface ViewportLink {
113
+ readonly url: string;
114
+ /** Mutable-viewport line the label is drawn on. */
115
+ readonly row: number;
116
+ /** First cell of the label's part on that line. */
117
+ readonly start: number;
118
+ }
111
119
  /**
112
- * Reserved click-candidate id for the pinned HUD expander row. Checked before
113
- * any registry lookup: its `@…:…` charset cannot collide with generated agent
114
- * ids (word names, numeric and `-N` suffixes, dotted nesting).
120
+ * Called once when link-hint mode ends; `reason` is `"crowded"` when a row held more links than
121
+ * their tags could fit side by side, so no tags were drawn.
115
122
  */
116
- export declare const PINNED_HUD_TOGGLE_ID = "@omp:toggle-pinned-hud";
123
+ export type LinkHintsEnd = (reason?: "crowded") => void;
117
124
  /**
118
125
  * Canonical interactive composer, usable before session/settings exist and updatable in place.
119
126
  * It owns the terminal, welcome header, and editor; InteractiveMode later supplies authoritative
@@ -146,11 +153,35 @@ export declare class Composer implements TerminalFrameProvider, NativeSurfacePro
146
153
  * are never in the viewport). Callers intersect with the live registry.
147
154
  */
148
155
  viewportClickCandidates(index: number): string[];
156
+ /**
157
+ * The extension-owned link label drawn at cell `col` of a mutable-viewport line, or `undefined`.
158
+ * Only links whose scheme an extension registered match; see `extensionLinkLabels`.
159
+ */
160
+ viewportLinkAt(index: number, col: number): ViewportLink | undefined;
149
161
  /**
150
162
  * Point the hover band at a click-candidate id (or clear it). Takes effect
151
163
  * on the next frame; callers repaint only when the target actually changes.
152
164
  */
153
165
  setHoveredClickId(id: string | undefined): void;
166
+ /** How many extension link labels the last frame drew; a label wrapped across rows counts once. */
167
+ viewportLinkCount(): number;
168
+ /**
169
+ * Enter keyboard link-hint mode: the next frame draws a tag over each extension link label it
170
+ * shows. `onEnd` runs once when the mode ends: a pick, a cancel, a key no tag starts with, a
171
+ * repaint that no longer draws the tagged labels where they were, or (`"crowded"`) a row with
172
+ * too many links for their tags to fit side by side.
173
+ */
174
+ startLinkHints(onEnd: LinkHintsEnd): void;
175
+ /** Whether link-hint mode is on. */
176
+ get linkHintsActive(): boolean;
177
+ /**
178
+ * Type one letter of a tag. Returns the link whose whole tag is now typed, `true` while the
179
+ * letters still lead to several tags, and `false` when none starts with them. The mode ends on
180
+ * a pick or a miss.
181
+ */
182
+ typeLinkHint(letter: string): ViewportLink | boolean;
183
+ /** Leave link-hint mode without picking a link. */
184
+ cancelLinkHints(): void;
154
185
  /** Acknowledges one accepted header, replay, or transcript batch. */
155
186
  acknowledgeHistory(id: number): void;
156
187
  /** Render the semantic transcript tail while the terminal borrows its resize buffer. */
@@ -183,6 +214,12 @@ export declare class Composer implements TerminalFrameProvider, NativeSurfacePro
183
214
  setHeaderExtras(before: readonly Component[], after: readonly Component[]): void;
184
215
  /** Update the canonical editor reference after InteractiveMode remounts a custom editor. */
185
216
  setEditor(editor: CustomEditor): void;
217
+ /**
218
+ * End the startup input hold once the app's handlers are wired: the TSP
219
+ * terminal sends the typing it kept, and the keys the TUI held replay
220
+ * ({@link TUI.releaseHeldInput}). Idempotent.
221
+ */
222
+ releaseHeldInput(): void;
186
223
  /**
187
224
  * Mount the session-aware status component into the slot below the editor,
188
225
  * retiring the startup status line; the caller installs the real top-border
@@ -1,13 +1,16 @@
1
1
  /** Shared assistant transcript construction and model-authored link caching. */
2
2
  import type { AssistantMessage, Model } from "@oh-my-pi/pi-ai";
3
3
  import type { ImageBudget } from "../components/image.js";
4
- import type { AssistantThinkingRenderer } from "../chat/extension-types.js";
4
+ import type { AssistantTextRenderer, AssistantThinkingRenderer } from "../chat/extension-types.js";
5
5
  import { AssistantMessageComponent } from "../chat/assistant-message.js";
6
+ import { ReplyWriteComponent } from "../chat/reply-write.js";
6
7
  /** Session display capabilities supplied unchanged by the interactive host. */
7
8
  export interface AssistantMessageSession {
8
9
  readonly model?: Model;
9
10
  readonly extensionRunner?: {
10
11
  getAssistantThinkingRenderers(): readonly AssistantThinkingRenderer[];
12
+ /** Empty while the setting that enables them is off; hosts predating it may omit it. */
13
+ getAssistantTextRenderers?(): readonly AssistantTextRenderer[];
11
14
  };
12
15
  }
13
16
  /** Host state required to construct and refresh assistant transcript segments. */
@@ -42,6 +45,10 @@ export declare function assistantMessageLinkTargets(message: AssistantMessage, t
42
45
  /**
43
46
  * Construct an {@link AssistantMessageComponent} wired to the live context's
44
47
  * thinking/image settings. `message` is omitted for the streaming placeholder
45
- * component and supplied when rendering a persisted turn.
48
+ * component and supplied when rendering a persisted turn. `contentOffset` is
49
+ * the index in the full reply of the first block of a segment drawn after a
50
+ * tool call, so extension text renderers see the reply's own block indexes.
46
51
  */
47
- export declare function createAssistantMessageComponent(ctx: AssistantMessageHost, message?: AssistantMessage, linkTargets?: ReadonlyMap<string, string>): AssistantMessageComponent;
52
+ export declare function createAssistantMessageComponent(ctx: AssistantMessageHost, message?: AssistantMessage, linkTargets?: ReadonlyMap<string, string>, contentOffset?: number): AssistantMessageComponent;
53
+ /** Construct a {@link ReplyWriteComponent} (an `out://` write) drawn like the context's assistant prose. */
54
+ export declare function createReplyWriteComponent(ctx: AssistantMessageHost): ReplyWriteComponent;
@@ -51,10 +51,14 @@ export declare class WelcomeComponent implements Component {
51
51
  setVersion(version: string): void;
52
52
  render(termWidth: number): readonly string[];
53
53
  }
54
+ /**
55
+ * omp's native lockup (`omp.welcome.lockup`, keyed `lockup`): the terminal's
56
+ * builtin `omp` mark, which it draws on, beside the `omp` wordmark with
57
+ * `v<version>` under it. The welcome card and the setup splash show it.
58
+ */
59
+ export declare function lockupNode(version: string): NativeNode;
54
60
  /** Block-grid brand mark shared by the welcome and setup surfaces. */
55
61
  export declare const PI_LOGO: string[];
56
- /** The block-grid brand mark as accent lines; `shimmer` declares the terminal-clocked shine sweep. */
57
- export declare function logoNode(lines: readonly string[], shimmer: boolean): NativeNode;
58
62
  export interface ShineConfig {
59
63
  /** Overall opacity of the shine overlay, in [0, 1]. */
60
64
  strength: number;
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Set the registered schemes (lowercase, without `:`). Bumps {@link extensionLinksVersion} on any
3
+ * change so cached markdown renders are redrawn.
4
+ */
5
+ export declare function setExtensionLinks(next: Iterable<string>): void;
6
+ /** Changes whenever the scheme set changes; part of the markdown render cache key. */
7
+ export declare function extensionLinksVersion(): number;
8
+ /**
9
+ * Whether activating a registered-scheme link (a click or a hint tag) reaches its extension: a
10
+ * scheme is registered and the terminal is plain.
11
+ */
12
+ export declare function extensionLinksRouted(): boolean;
13
+ /**
14
+ * Set by the interactive product: whether the user has a way to pick a link drawn now (a bound
15
+ * hint key, mouse clicks). `undefined` when nothing in this process can pick one.
16
+ */
17
+ export declare function setExtensionLinkPicking(provider: (() => boolean) | undefined): void;
18
+ /**
19
+ * Whether a registered-scheme link drawn now can be activated: links are routed and the product
20
+ * offers a way to pick them. Process-wide, so a UI-less extension runner (a subagent's, whose
21
+ * transcript the user may focus) answers like the interactive one.
22
+ */
23
+ export declare function extensionLinkClicksAvailable(): boolean;
24
+ /** The registered scheme `href` uses, or `undefined` for every other link. */
25
+ export declare function extensionLinkScheme(href: string): string | undefined;
26
+ /**
27
+ * Draw an extension link's label: dotted-underlined (plain underline where the terminal has no
28
+ * styled underlines, re-applied after any style reset inside it) and wrapped in the OSC 8 marker
29
+ * {@link extensionLinkLabels} reads back in a plain terminal; as given in Tern's native view. Never
30
+ * followed by a ` (url)` suffix. `key` tells apart links of one URL drawn near each other; it must
31
+ * not change between renders of the same text, or rows rendered twice stop matching.
32
+ */
33
+ export declare function formatExtensionLink(label: string, href: string, key: string): string;
34
+ /**
35
+ * Tags for `count` links in keyboard link-hint mode: single letters while they suffice, otherwise
36
+ * two letters each, so no tag is a prefix of another. At most the alphabet squared (676) are made;
37
+ * links past that stay untagged.
38
+ */
39
+ export declare function linkHintTags(count: number): string[];
40
+ /**
41
+ * `line` without omp's extension-link markers (the OSC 8 open and close around each label), for
42
+ * terminal output. Every other hyperlink is kept as is.
43
+ */
44
+ export declare function stripExtensionLinkMarkers(line: string): string;
45
+ /** One extension link label drawn on a rendered row (before {@link stripExtensionLinkMarkers}). */
46
+ export interface ExtensionLinkLabel {
47
+ readonly url: string;
48
+ /**
49
+ * The marker's params, unique to each drawn link and repeated on every row a wrapped label
50
+ * spans, so a row's parts of one label can be told from an adjacent label of the same URL.
51
+ */
52
+ readonly id: string;
53
+ /** First 0-based cell the label covers. */
54
+ readonly start: number;
55
+ /** Cell just past the label. */
56
+ readonly end: number;
57
+ /** Whether only blank cells follow the label on its row, so a wrapped label may go on below. */
58
+ readonly endsRow: boolean;
59
+ }
60
+ /**
61
+ * The extension link labels drawn on a rendered row, left to right. Only omp's own markers with a
62
+ * registered scheme match, so ordinary hyperlinks (even of a registered scheme) and rows drawn for
63
+ * a scheme that is no longer registered never do.
64
+ */
65
+ export declare function extensionLinkLabels(line: string): ExtensionLinkLabel[];
@@ -1,14 +1,31 @@
1
1
  import type { TspSpan } from "@oh-my-pi/pi-wire";
2
2
  import { type TerminalId } from "../terminal-capabilities.js";
3
+ export interface FileLinkConfig {
4
+ scheme?: string;
5
+ host?: string;
6
+ }
7
+ interface FileUriOptions {
8
+ line?: number;
9
+ col?: number;
10
+ /** Native image open actions need a local file URL rather than a desktop handler. */
11
+ local?: boolean;
12
+ }
13
+ /**
14
+ * Resolve the remote file-link configuration once at host startup. Passing an
15
+ * explicit object lets SDK hosts and tests configure links without changing the
16
+ * process environment; an empty object restores ordinary file links. An invalid
17
+ * scheme or host logs a warning and keeps ordinary links.
18
+ */
19
+ export declare function applyFileLinkSetting(config?: FileLinkConfig): void;
3
20
  /**
4
- * A `file:` URL for `filePath`, or `undefined` when Node cannot encode it.
21
+ * A file-link target for `filePath`, or `undefined` when Node cannot encode it.
5
22
  *
6
23
  * Node rejects a malformed UNC target (a UNC path escaped twice by its author,
7
24
  * e.g. `\\\wsl.localhost\…`) with `ERR_INVALID_ARG_VALUE: Empty UNC servername`.
8
25
  * A stored session keeps whatever a tool call recorded, so a transcript must
9
26
  * render such a path without a link rather than throw while it rebuilds.
10
27
  */
11
- export declare function tryFileUri(filePath: string): string | undefined;
28
+ export declare function tryFileUri(filePath: string, opts?: FileUriOptions): string | undefined;
12
29
  /**
13
30
  * Build the OSC 8 target for a file path on `terminalId`.
14
31
  *
@@ -23,7 +40,8 @@ export declare function tryFileUri(filePath: string): string | undefined;
23
40
  * The VS Code family instead navigates the documented
24
41
  * `vscode://file/<path>:<line>:<col>` form. Everywhere else the plain `file:`
25
42
  * URI is right, with the location left in the visible text — terminals that
26
- * parse a `path:line:col` suffix resolve that on their own.
43
+ * parse a `path:line:col` suffix resolve that on their own. A configured custom
44
+ * handler takes precedence and receives optional `line`/`col` query parameters.
27
45
  *
28
46
  * Returns `undefined` when `filePath` cannot be encoded — a malformed UNC
29
47
  * target on the `file:` branch, or a lone surrogate on the `vscode://` branch.
@@ -85,9 +103,8 @@ export declare function urlLinkSpan(target: string, displayText: string, s?: str
85
103
  /** Whether native link spans and nodes may carry an `href`: everything but an explicit `off` policy. */
86
104
  export declare function isNativeLinkEnabled(): boolean;
87
105
  /**
88
- * A native link span to a filesystem path as a plain `file://` URI (the
89
- * terminal opens it through the system; the location stays in the visible
90
- * text). Honours an explicit `off` policy.
106
+ * A native link span to a filesystem path using the configured file-link
107
+ * target. Honours an explicit `off` policy.
91
108
  */
92
109
  export declare function fileLinkSpan(filePath: string, displayText: string, s?: string): TspSpan;
93
110
  /**
@@ -101,9 +118,10 @@ export declare function fileLinkSpan(filePath: string, displayText: string, s?:
101
118
  *
102
119
  * @param filePath - Filesystem path
103
120
  * @param displayText - Text to render as the hyperlink anchor (may contain ANSI codes)
104
- * @param opts - Optional line/col position appended as `?line=N&col=M` query params
121
+ * @param opts - Optional line/col position (custom handlers use query params; VS Code uses a path suffix)
105
122
  */
106
123
  export declare function fileHyperlink(filePath: string, displayText: string, opts?: {
107
124
  line?: number;
108
125
  col?: number;
109
126
  }): string;
127
+ export {};
@@ -2,6 +2,7 @@
2
2
  * Public exports for shared TUI components.
3
3
  */
4
4
  export * from "./code-cell.js";
5
+ export * from "./extension-links.js";
5
6
  export * from "./file-list.js";
6
7
  export * from "./hyperlink.js";
7
8
  export * from "./output-block.js";
@@ -1,3 +1,3 @@
1
- import type { SetupScene } from "./types.js";
1
+ import { type SetupScene } from "./types.js";
2
2
  /** Setup step that assigns one available model to the persisted default role. */
3
3
  export declare const modelSetupScene: SetupScene;
@@ -1,9 +1,10 @@
1
1
  import type { NativeNode } from "../../native/node.js";
2
2
  export declare const SETUP_OUTRO_MS = 1200;
3
3
  /**
4
- * Native outro: the shimmering mark, the saved confirmation, and an
5
- * indeterminate progress bar standing in for the timed sweep. A click sends
6
- * the `continue` action.
4
+ * Native outro, centered: the builtin `omp` mark, "You're all set", the
5
+ * default model now in effect (`model`, its display name, when there is
6
+ * one), and an indeterminate progress bar standing in for the timed sweep.
7
+ * A click sends the `continue` action.
7
8
  */
8
- export declare function describeSetupOutro(): NativeNode;
9
+ export declare function describeSetupOutro(model: string | undefined): NativeNode;
9
10
  export declare function renderSetupOutro(width: number, height: number, elapsedMs: number): string[];