@sayknow-cli/tui 0.2.2

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 (61) hide show
  1. package/CHANGELOG.md +903 -0
  2. package/README.md +704 -0
  3. package/dist/types/autocomplete.d.ts +82 -0
  4. package/dist/types/bracketed-paste.d.ts +26 -0
  5. package/dist/types/components/box.d.ts +20 -0
  6. package/dist/types/components/cancellable-loader.d.ts +21 -0
  7. package/dist/types/components/editor.d.ts +111 -0
  8. package/dist/types/components/image.d.ts +16 -0
  9. package/dist/types/components/input.d.ts +16 -0
  10. package/dist/types/components/loader.d.ts +14 -0
  11. package/dist/types/components/markdown.d.ts +64 -0
  12. package/dist/types/components/select-list.d.ts +46 -0
  13. package/dist/types/components/settings-list.d.ts +39 -0
  14. package/dist/types/components/spacer.d.ts +11 -0
  15. package/dist/types/components/tab-bar.d.ts +56 -0
  16. package/dist/types/components/text.d.ts +13 -0
  17. package/dist/types/components/truncated-text.d.ts +10 -0
  18. package/dist/types/editor-component.d.ts +36 -0
  19. package/dist/types/fuzzy.d.ts +15 -0
  20. package/dist/types/index.d.ts +26 -0
  21. package/dist/types/keybindings.d.ts +189 -0
  22. package/dist/types/keys.d.ts +208 -0
  23. package/dist/types/kill-ring.d.ts +27 -0
  24. package/dist/types/metrics.d.ts +85 -0
  25. package/dist/types/stdin-buffer.d.ts +50 -0
  26. package/dist/types/symbols.d.ts +23 -0
  27. package/dist/types/terminal-capabilities.d.ts +75 -0
  28. package/dist/types/terminal.d.ts +76 -0
  29. package/dist/types/ttyid.d.ts +9 -0
  30. package/dist/types/tui.d.ts +181 -0
  31. package/dist/types/utils.d.ts +75 -0
  32. package/package.json +74 -0
  33. package/src/autocomplete.ts +896 -0
  34. package/src/bracketed-paste.ts +47 -0
  35. package/src/components/box.ts +173 -0
  36. package/src/components/cancellable-loader.ts +40 -0
  37. package/src/components/editor.ts +2820 -0
  38. package/src/components/image.ts +90 -0
  39. package/src/components/input.ts +465 -0
  40. package/src/components/loader.ts +103 -0
  41. package/src/components/markdown.ts +1061 -0
  42. package/src/components/select-list.ts +249 -0
  43. package/src/components/settings-list.ts +211 -0
  44. package/src/components/spacer.ts +28 -0
  45. package/src/components/tab-bar.ts +175 -0
  46. package/src/components/text.ts +110 -0
  47. package/src/components/truncated-text.ts +61 -0
  48. package/src/editor-component.ts +71 -0
  49. package/src/fuzzy.ts +143 -0
  50. package/src/index.ts +41 -0
  51. package/src/keybindings.ts +279 -0
  52. package/src/keys.ts +537 -0
  53. package/src/kill-ring.ts +46 -0
  54. package/src/metrics.ts +382 -0
  55. package/src/stdin-buffer.ts +444 -0
  56. package/src/symbols.ts +24 -0
  57. package/src/terminal-capabilities.ts +537 -0
  58. package/src/terminal.ts +807 -0
  59. package/src/ttyid.ts +73 -0
  60. package/src/tui.ts +1765 -0
  61. package/src/utils.ts +389 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,903 @@
1
+ # Changelog
2
+
3
+ ## [Unreleased]
4
+
5
+ ## [0.6.0] - 2026-06-18
6
+
7
+ ### Fixed
8
+
9
+ - Normalized canonically decomposed Hangul jamo at the terminal emission boundary so Korean text remains precomposed/stable in VS Code Remote and other terminal renderers that mishandle jamo clusters during repaint (#837).
10
+
11
+ ## [0.5.3] - 2026-06-16
12
+
13
+ ### Fixed
14
+
15
+ - Hardened the TUI for very long-running sessions to stop freezes and unbounded memory growth: `Container.render` emits frame lines via a loop instead of `push(...spread)` so huge (~492k-line) frames no longer throw `RangeError`; the component/container/box `dispose()` lifecycle is reuse-safe (`clear()`/`removeChild()` dispose, `detach*()` does not) across tool/loader/oauth/mcp-wizard/extension-ui components, and the reusable editor is detached before transient hook UI is torn down so it is never disposed by accident; markdown gains a per-code-block highlight LRU cache plus a UTF-8 byte/line highlight cap and assistant-message instance reuse. An opt-in viewport-windowed normalize/diff path (`PI_TUI_VIRTUAL_VIEWPORT`, default off) keeps rendering O(rows) at 100k+ lines while staying byte-identical to the golden output (#716).
16
+
17
+ ## [0.5.1] - 2026-06-14
18
+
19
+ ### Fixed
20
+
21
+ - Fixed Korean/Hangul input composition breaking in Android Termius, where typing `안녕하세요` produced duplicated jamo/syllable residue (`ㅇ아안ㄴ녀녕…`). SKC's startup keyboard reprogramming (Kitty keyboard protocol query `CSI ? u` / push `CSI > 7 u`, and the xterm modifyOtherKeys fallback `CSI > 4 ; 2 m`) disrupts the Android IME's syllable composition. Added a `SKC_TUI_KEYBOARD_PROTOCOL` opt-out (enabled by default): set `SKC_TUI_KEYBOARD_PROTOCOL=0` to leave the keyboard in its default mode so IME composition works, matching terminals/TUIs that never enable these enhanced input modes.
22
+
23
+ ## [0.5.0] - 2026-06-13
24
+
25
+ ### Added
26
+
27
+ - Added process-isolated deterministic render-golden capture fixtures and coverage for editor overlays, rich-text resize, multiplexer viewport repaint, sixel preservation, Termux height diffs, and transcript shrink/clear regressions.
28
+ - Added layout/rendering benchmarks for editor layout, markdown rendering, and frame rendering.
29
+
30
+ ### Changed
31
+
32
+ - Tightened markdown/editor rendering and terminal repaint behavior for the compact tool-block spacing and render-golden stability work.
33
+
34
+ ## [0.4.5] - 2026-06-12
35
+
36
+ - Version aligned with the 0.4.5 monorepo release; no functional changes in this package.
37
+
38
+ ## [0.4.4] - 2026-06-10
39
+
40
+ - Version aligned with the 0.4.4 monorepo release; no functional changes in this package.
41
+
42
+ ## [0.4.3] - 2026-06-10
43
+
44
+ ### Fixed
45
+
46
+ - Fixed Korean (and other multi-byte UTF-8) paste mojibake in terminal input: `StdinBuffer` is now the single raw-stdin decoding boundary using a persistent `StringDecoder`, so multi-byte characters split across stdin read boundaries are reassembled instead of producing U+FFFD. `ProcessTerminal` no longer relies on `process.stdin.setEncoding("utf8")` and forwards raw Buffers; the legacy single-high-byte meta conversion is preserved. (#454)
47
+
48
+ ## [0.4.0] - 2026-06-06
49
+
50
+ ### Changed
51
+
52
+ - Ranked slash command-name suggestions by stronger prefix/token matches before fuzzy fallback ordering, while keeping priority as an intra-tier tie-breaker.
53
+
54
+ ## [0.3.1] - 2026-06-05
55
+
56
+ ### Changed
57
+
58
+ - Added replay-gate helper timing for text-layout utilities so Stage 5 native offload decisions are benchmark-gated by measured hot paths rather than speculative rewrites.
59
+
60
+ ## [0.2.2] - 2026-05-31
61
+
62
+ ### Changed
63
+
64
+ - Refreshed TUI package metadata for the SKC 0.2.2 release.
65
+
66
+ ## [0.2.1] - 2026-05-30
67
+
68
+ ### Fixed
69
+
70
+ - Made TUI terminal writes tolerate `EIO`/closed PTY failures by marking output unavailable, swallowing render/cursor cleanup write errors, and suppressing later render writes after detach.
71
+
72
+ ## [0.2.0] - 2026-05-28
73
+
74
+ ### Changed
75
+
76
+ - Refreshed TUI package metadata for the SKC 0.2.0 release.
77
+
78
+ ## [0.1.3] - 2026-05-28
79
+
80
+ ### Changed
81
+
82
+ - Released the current dev branch fixes with refreshed 0.1.3 package metadata.
83
+
84
+ ## [0.1.2] - 2026-05-28
85
+
86
+ ### Changed
87
+
88
+ - Updated package metadata for the Sayknow-CLI npm publication.
89
+
90
+ ## [15.3.2] - 2026-05-25
91
+
92
+ ### Fixed
93
+
94
+ - Fixed `matchesKey(data, "ctrl+m")` (and the other named-key collisions: `ctrl+h`/`ctrl+i`/`ctrl+j`/`ctrl+[`) returning true for the bare `\r`/`\x08`/`\t`/`\n`/`\x1b` byte terminals send for Enter/Backspace/Tab/Escape in legacy mode. Binding a command to `Ctrl+M` no longer fires when the user presses Enter — the named key wins, and `ctrl+<colliding-letter>` matches only when the terminal disambiguates via the Kitty keyboard protocol or `modifyOtherKeys`. ([#1354](https://github.com/jaybeyond/sayknow-cli/issues/1354))
95
+
96
+ ## [15.2.3] - 2026-05-22
97
+ ### Added
98
+
99
+ - Added `SettingsList#setItems` to replace the entire settings list with a new items array while automatically clamping selection to a valid index
100
+
101
+ ### Changed
102
+
103
+ - Updated `Loader` to drive renders at ~60fps (16ms tick) while keeping spinner-frame advancement at 80ms so shimmer/animated message colorizers update smoothly without altering spinner cadence
104
+
105
+ ## [15.1.9] - 2026-05-21
106
+
107
+ ### Fixed
108
+
109
+ - Fixed terminal probe responses (DA1, kitty keyboard, Mode 2031) leaking into the prompt as keystrokes when the response is split across stdin reads. `ProcessTerminal` now reassembles `\x1b[?<digits>...` private CSI fragments and dispatches the complete response through the existing pattern handlers. ([#1238](https://github.com/jaybeyond/sayknow-cli/issues/1238))
110
+
111
+ ## [15.1.4] - 2026-05-19
112
+
113
+ ### Fixed
114
+
115
+ - Fixed `renderInlineMarkdown` crashing with `TypeError: undefined is not an object (evaluating 'e.replace')` when called with a non-string value during streaming — partial JSON parsing leaves option label fields temporarily unpopulated, causing the ask tool renderer to fail. ([#1176](https://github.com/jaybeyond/sayknow-cli/issues/1176))
116
+
117
+ ## [15.0.2] - 2026-05-15
118
+
119
+ ### Added
120
+
121
+ - Restored the `Key` runtime helper on `@sayknow-cli/tui` to mirror upstream `@mariozechner/pi-tui`'s surface. `Key.enter`, `Key.escape`, `Key.tab`, … return the canonical key-name strings; modifier methods (`Key.ctrl(k)`, `Key.shift(k)`, `Key.ctrlShift(k)`, etc.) build precisely-typed `KeyId` literals like `"ctrl+c"`. Pure runtime convenience for typed key-id construction — plugins built against the upstream package surface that import `Key` (e.g. `@plannotator/pi-extension`, `@juicesharp/rpiv-ask-user-question`) load again now that the specifier shim remaps them onto this package.
122
+
123
+ ## [15.0.1] - 2026-05-14
124
+ ### Breaking Changes
125
+
126
+ - Increased the minimum required Bun version for the TUI package from >=1.3.7 to >=1.3.14
127
+ - Fixed `TerminalInfo.sendNotification` not delivering desktop notifications on macOS. macOS requires per-app notification permission, which terminal emulators (kitty, ghostty, alacritty, …) almost never have, so OSC 9/99 sequences were silently dropped at the OS layer. `sendNotification` now shells out to `alerter` or `terminal-notifier` when either is on `$PATH` (both register their own LSApplication and ship a "Terminal" / `>_` icon). When neither is installed the dispatch is a deliberate no-op + a single `logger.warn` line on the first miss (subsequent dispatches stay silent) so the user can spot the missing binary in `~/.skc/logs/skc.YYYY-MM-DD.log` and `brew install alerter`. Linux/Windows still go through the OSC/Bell path.
128
+ - Fixed `TerminalInfo.formatNotification` losing OSC 9/99 desktop notifications when running inside tmux. The OSC sequence is now wrapped in tmux's DCS passthrough envelope (`\ePtmux;…\e\\` with embedded ESC bytes doubled) when `TMUX` is set, so notifications reach the parent terminal. `set -g allow-passthrough on` is still required on the tmux side for the wrapped sequence to be forwarded. Bell-only terminals are unchanged.
129
+ - Fixed alerter desktop notifications staying on screen indefinitely. `scripts/mac-alerter.sh` previously passed `--timeout 30` (which makes alerter call `removeDeliveredNotification` after 30 s, also purging the Notification Center entry) and forced Alert-style via `--actions "Open"` (persistent until user click). It now ships Banner-style argv (no `--actions`, no `--timeout`): macOS auto-dismisses the toast after ~10 s and archives the entry to Notification Center for later review. Click-to-focus is preserved through `@CONTENTCLICKED` body clicks. NC archival also requires "Show in Notification Center" enabled for Terminal under macOS System Settings → Notifications.
130
+ - Fixed `composeNotificationSubtitle` showing a stale tmux `pane_title` (typically `π: kitty & tmux` or the cwd prefix written before auto-naming runs) instead of the live SKC session name. The SKC-supplied `fallback` is now consulted first for the pane component; the cached tmux pane title is only used when no session name is available. Window name handling is unchanged.
131
+ - Fixed `sendDesktopNotification` always routing through `alerter` / `terminal-notifier` on darwin, even for terminals (ghostty / iTerm2 / wezterm) that surface OSC 9 / OSC 99 as native notifications through their own bundle. The dispatch now prefers the OSC path on darwin when the terminal advertises native macOS notification capability; the fallback only kicks in for kitty / alacritty / vscode / unknown shells whose host app isn't a notification-capable bundle. This unblocks the user-controlled per-app notification settings flow for ghostty / iTerm2 / wezterm — toast style, NC archival, and click-to-focus all attach to the terminal app's own System Settings entry rather than to `com.apple.Terminal` (which `alerter` would post under).
132
+ - Fixed Korean IME composition leaving a growing horizontal gap between typed jamo and the cursor inside the SKC prompt under tmux + ghostty (and other macOS terminals). `Bun.stringWidth` and the underlying UAX#11 East Asian Width tables classify Hangul Compatibility Jamo (U+3131..U+318E — ㄱ ㄴ ㄷ ㄹ ㅁ ㅂ ㅅ ㅇ ㅈ ㅊ ㅋ ㅌ ㅍ ㅎ + filler) as Wide (2 cells), but every macOS terminal we ship to (Ghostty / Terminal.app / iTerm2) actually renders them as a single cell in monospace fonts. `#extractCursorPosition` was computing `col = visibleWidth(beforeMarker)` and feeding the doubled value to `\x1b[(col+1)G`, placing the hardware cursor (and therefore the IME candidate window) `N_jamo` cells past the visible glyph — exactly the gap the user saw growing as they typed. `visibleWidthRaw` now subtracts 1 cell for each Compatibility Jamo character, returning the column count macOS terminals actually use. Hangul Syllables (U+AC00..U+D7A3, e.g. `안`) stay at 2 cells in both Bun and the terminal — unaffected. Other CJK widths (Chinese / Japanese / Halfwidth Hangul) are unchanged. NOTE: the Rust `pi-natives` width tables (used by `sliceWithWidth` / `truncateToWidth` / `wrapTextWithAnsi`) also count Compatibility Jamo as 2 cells; truncation and word-wrap on jamo-heavy lines will still be slightly aggressive. The defect is invisible in normal use because the AI composes Korean as syllables, not jamo, and users type syllables once IME composition completes. A follow-up will reconcile the Rust side.
133
+ - Fixed a brief black-flash flicker in the TUI when streaming long markdown responses inside tmux (especially noticeable in ghostty with multiple panes open). Root cause: when a markdown fence line above the viewport changed between two streaming tokens (e.g. `` ``` `` → `` ```python ``), `#doRender()` would take the `firstChanged < prevViewportTop` branch and emit `\x1b[2J\x1b[H` (full screen clear + cursor home) wrapped in BSU. The BSU envelope can split across PTY reads, leaving tmux briefly displaying a blank pane before the rest of the buffer arrives — multiplied across panes during repaint. The viewport-above branch now calls a new `viewportRefresh()` helper that does cursor-home + per-line `\x1b[2K` + line content (no `\x1b[2J`), so the visible viewport content is repainted without ever clearing the screen. Scrollback above the viewport may briefly show stale rendering, but only of the SAME lines that just changed — invisible during streaming when the user isn't scrolled up. Other full-redraw paths (resize, first render, etc.) keep the hard `fullRender(true)` behavior unchanged.
134
+
135
+ ### Tests
136
+
137
+ - Added `test/no-2k-anywhere.test.ts` — lint guard that scans `packages/tui/src/` for `\x1b[2K` string literals outside comments. The earlier streaming-flicker fix re-introduced the BSU-split flash bug by moving `\x1b[2K`-before-content from `fullRender` to `viewportRefresh` (same anti-pattern in a new location). This test catches that class of regression at CI time so future changes can't silently revive it.
138
+ - Added `test/render-emit-snapshot.test.ts` — four scenario-based byte-snapshot guards (single-line mutation, streaming append, above-viewport mutation triggering `viewportRefresh`, trailing-line clear on shrink). Asserts structural invariants on the EMITTED BYTES from `terminal.write(…)`: no `\x1b[2K`, no `\x1b[2J`, the new content appears, the BSU close `\x1b[?2026l` is present. Catches render-path changes that achieve the right final viewport state via a transient blank frame (which is exactly how the typing-flicker bug slipped past `render-regressions.test.ts`).
139
+ - Added `test/ime-jamo-cursor.test.ts` — six cases asserting the Input component's hardware cursor marker column does not grow at 2× per typed Korean compatibility jamo. Before commit `79e3170c6` typing 14 jamo produced a 14-cell gap between the visible text and the IME candidate window; the test caps the cursor column at `PRSKCT_WIDTH + N_jamo` and asserts the per-keystroke delta is at most 1. NOTE: the Rust `pi-natives` `sliceWithWidth` still treats jamo as 2 cells (binary package, follow-up); the test guard accepts a small residual offset but flags the doubling regression.
140
+
141
+ ## [14.9.8] - 2026-05-12
142
+
143
+ ### Added
144
+
145
+ - Added `Terminal.setProgress(active)` to emit OSC 9;4 progress sequences with a ~1s keepalive interval so Ghostty does not clear the indicator during long-running work (ports pi-mono `a900d251` + `76bc605a`)
146
+ - Added optional `argumentHint?: string` to `SlashCommand`; rendered before the description in the autocomplete dropdown (ports pi-mono `aa25726e`)
147
+ - Added `VirtualTerminal.waitForRender()` test helper for the throttled render pipeline (ports pi-mono `41377ee8`)
148
+
149
+ ### Changed
150
+
151
+ - `ProcessTerminal` `columns`/`rows` getters consult `Bun.env.COLUMNS` / `Bun.env.LINES` before falling back to 80×24, so piped/non-TTY runs honour environment-provided dimensions (ports pi-mono `32f7fc6a`)
152
+ - `requestRender()` non-force calls are coalesced to a ~16ms frame budget; `requestRender(true)` still flushes immediately via `process.nextTick` (ports pi-mono `6f5f37f8`)
153
+ - `KNOWN_TERMINALS.base` / `KNOWN_TERMINALS.trueColor` default `hyperlinks: false`; tmux and screen (`TMUX` env or `TERM` starts with `tmux`/`screen`) force `hyperlinks: false` even when the outer terminal would advertise OSC 8 (adapts pi-mono `30a8a41f`)
154
+ - `SlashCommand.getArgumentCompletions()` may return a `Promise`; results are now awaited and non-array returns are ignored (ports pi-mono `a1e10789`)
155
+ - Fuzzy `@` autocomplete now follows symlinked directories via `ScanOptions.follow_links` plumbed through the native walker (ports pi-mono `780d5367`)
156
+ - Plain `@<query>` (no slash) fuzzy matches by basename only, so `@plan` no longer surfaces every file whose ancestor directories contain `plan` (ports pi-mono `968430f6`)
157
+
158
+ ### Fixed
159
+
160
+ - Fixed editor corruption on Thai Sara Am (U+0E33) and Lao AM (U+0EB3) vowels by normalizing to their compatibility decompositions on the terminal-write path while keeping editor content logically unchanged (ports pi-mono `bc668826` + `338ce3a3` + `20ca45d5`)
161
+ - Fixed cell-size detection (`CSI 6;h;w t` response) to consume only exact replies, so a bare `Escape` keystroke is no longer swallowed while waiting for terminal image metadata (ports pi-mono `49c0d860`)
162
+ - Fixed Kitty CSI-u printable input duplicating on layouts (e.g. Italian) where the terminal also emits the raw character: the immediately-following matching codepoint is now suppressed (ports pi-mono `bdb416cb`)
163
+ - Fixed bracketed-paste CSI-u `Ctrl+<letter>` re-encoding (tmux popup with `extended-keys-format=csi-u`) leaking literal `[<code>;5u` into the editor; control bytes are decoded back to their literal byte before per-char filtering (ports pi-mono `d06db09a`)
164
+ - Fixed xterm `modifyOtherKeys` shifted printable input so uppercase letters inserted via `CSI 27;mod;codepoint~` reach the editor correctly (ports pi-mono `6b55d685`)
165
+ - Fixed `super`-modified Kitty shortcuts (`super+k`, `ctrl+super+enter`, …) to parse and match via the new `KITTY_MOD_SUPER` mask (ports pi-mono `ddb8454c` + `5ed46003`)
166
+ - Fixed `ctrl+alt+<letter>` in tmux falling through to CSI-u / `modifyOtherKeys` when the legacy `ESC<ctrl-char>` form does not match (ports pi-mono `6cf5098f`)
167
+ - Fixed Markdown strikethrough requiring strict `~~text~~` delimiters with non-whitespace boundaries; single tildes no longer render strikethrough (ports pi-mono `db5274b4`)
168
+
169
+ - Allowed `SlashCommand.getArgumentCompletions` to return asynchronous results by accepting Promise-based completions
170
+ - Added `argumentHint` support to slash command definitions and displayed it in command suggestion descriptions
171
+ - Added support for xterm `modifyOtherKeys` printable key sequences by decoding `CSI 27;mod;key~` into text input
172
+
173
+ ### Changed
174
+
175
+ - Changed slash-command autocomplete list rendering to combine command hint and description in a single displayed suggestion text
176
+ - Changed render scheduling to throttle `requestRender` calls to roughly 60fps by batching updates
177
+ - Changed terminal input handling to process complete cell-size responses without buffering partial input
178
+ - Changed `KeyId` to accept super-modifier combinations and improve typed key-id validation
179
+
180
+ ### Fixed
181
+
182
+ - Normalized line output during rendering to correct Thai/Lao AM glyph composition for displayed text
183
+ - Fixed duplicated Kitty key input emissions by dropping the matching unmodified follow-up sequence after a Kitty CSI-u printable-key event
184
+
185
+ ## [14.9.5] - 2026-05-12
186
+ ### Fixed
187
+
188
+ - Fixed rapidly blinking cursor artifact during task execution by consolidating cursor control sequences into the synchronized output buffer ([#992](https://github.com/jaybeyond/sayknow-cli/issues/992))
189
+
190
+ ## [14.5.7] - 2026-04-29
191
+
192
+ ### Fixed
193
+
194
+ - Fixed editor Ctrl+Enter handling to recognize NumLock and keypad Enter variants.
195
+
196
+ ## [14.3.0] - 2026-04-25
197
+
198
+ ### Fixed
199
+
200
+ - Fixed shared Markdown Mermaid fenced-block rendering to resolve diagrams from fenced source text instead of external prerender state
201
+
202
+ ## [14.1.1] - 2026-04-14
203
+
204
+ ### Breaking Changes
205
+
206
+ - Removed the `searchDb` constructor argument from `CombinedAutocompleteProvider`, requiring callers to use the built-in search behavior
207
+
208
+ ### Changed
209
+
210
+ - Changed truncation debug logging to run only when `debugRedraw` is enabled
211
+
212
+ ### Fixed
213
+
214
+ - Fixed viewport jumping during streaming and session swap by tracking actual content height instead of high-water mark
215
+
216
+ ## [14.0.5] - 2026-04-11
217
+
218
+ ### Changed
219
+
220
+ - Updated hash computation to use `Bun.hash()` instead of `Bun.hash.xxHash64()`, which may return `number` in addition to `bigint`
221
+ - Simplified cache key computation in Box component by removing intermediate hash updates and consolidating hash operations
222
+ - Wrapped native text utility functions (`sliceWithWidth`, `truncateToWidth`, `wrapTextWithAnsi`, `extractSegments`) to automatically pass the current default tab width, simplifying the API for consumers
223
+ - Added `getIndentationNoescape` wrapper that uses `process.cwd()` as the project root for relative file paths
224
+ - Re-export `getDefaultTabWidth`, `getIndentation`, and `setDefaultTabWidth` from `@sayknow-cli/utils`; native text helpers still receive tab width via wrappers that read the JS default
225
+
226
+ ## [13.16.1] - 2026-03-27
227
+
228
+ ### Added
229
+
230
+ - Support for optional SearchDb parameter in CombinedAutocompleteProvider constructor for improved fuzzy search performance
231
+ - Fuzzy matching filter for autocomplete suggestions to improve relevance of results
232
+
233
+ ### Changed
234
+
235
+ - Fuzzy discovery now applies fuzzy matching filter to results for improved relevance of autocomplete suggestions
236
+ - Autocomplete fuzzy discovery now accepts optional SearchDb instance for faster searches
237
+
238
+ ## [13.16.0] - 2026-03-27
239
+ ### Changed
240
+
241
+ - Updated tab replacement in editor text sanitization to respect configured tab width setting
242
+
243
+ ## [13.15.0] - 2026-03-23
244
+
245
+ ### Added
246
+
247
+ - Added `renderInlineMarkdown()` function to render inline markdown (bold, italic, code, links, strikethrough) to styled strings
248
+
249
+ ### Fixed
250
+
251
+ - Fixed editor consuming user-rebound copy keys, preventing custom keybindings from working in the editor
252
+
253
+ ## [13.14.1] - 2026-03-21
254
+ ### Added
255
+
256
+ - Added Ctrl+_ as an additional default shortcut for undo
257
+
258
+ ### Fixed
259
+
260
+ - Ensured undo functionality respects user-configured keybindings
261
+
262
+ ## [13.12.0] - 2026-03-14
263
+
264
+ ### Added
265
+
266
+ - Added `moveToMessageStart()` and `moveToMessageEnd()` methods to move cursor to the beginning and end of the entire message
267
+
268
+ ### Fixed
269
+
270
+ - Fixed autocomplete to preserve `./` prefix when completing relative file and directory paths
271
+ - Fixed paste marker expansion to handle special regex replacement tokens ($1, $2, $&, $$, $`, $') literally in pasted content
272
+
273
+ ## [13.11.0] - 2026-03-12
274
+ ### Fixed
275
+
276
+ - Fixed OSC 11 background color detection to correctly handle partial escape sequences that arrive mid-buffer, preventing user input from being swallowed
277
+ - Fixed race condition where overlapping OSC 11 queries would be incorrectly cancelled by DA1 sentinels from previous queries
278
+
279
+ ## [13.7.5] - 2026-03-04
280
+ ### Changed
281
+
282
+ - Extracted word navigation logic into reusable `moveWordLeft` and `moveWordRight` utility functions for consistent cursor movement across components
283
+
284
+ ## [13.6.2] - 2026-03-03
285
+ ### Fixed
286
+
287
+ - Fixed cursor positioning when content shrinks to empty without clearOnShrink enabled
288
+
289
+ ## [13.5.4] - 2026-03-01
290
+
291
+ ### Fixed
292
+
293
+ - Fixed viewport repaint scrollback accounting during resize oscillation to avoid double-scrolling on height shrink and added exact-row scrollback assertions in overlay regression coverage ([#228](https://github.com/jaybeyond/sayknow-cli/issues/228), [#234](https://github.com/jaybeyond/sayknow-cli/issues/234))
294
+ ## [13.5.3] - 2026-03-01
295
+
296
+ ### Fixed
297
+
298
+ - Fixed append rendering logic to correctly handle offscreen header changes during content overflow growth, preserving scroll history integrity
299
+ - Fixed visible tail line updates when appending new content during viewport overflow conditions
300
+ - Fixed cursor positioning instability when appending content under external cursor relocation by using absolute screen addressing instead of relative cursor movement
301
+
302
+ ## [13.5.2] - 2026-03-01
303
+ ### Breaking Changes
304
+
305
+ - Removed `getMermaidImage` callback from MarkdownTheme; replaced with `getMermaidAscii` that accepts ASCII string instead of image data
306
+ - Removed mermaid module exports (`renderMermaidToPng`, `extractMermaidBlocks`, `prerenderMermaidBlocks`, `MermaidImage` interface)
307
+
308
+ ### Changed
309
+
310
+ - Mermaid diagrams now render as ASCII text instead of terminal graphics protocol images
311
+
312
+ ## [13.5.1] - 2026-03-01
313
+ ### Fixed
314
+
315
+ - Fixed viewport shift handling to prevent stale content when mixed updates remap screen rows
316
+
317
+ ## [13.5.0] - 2026-03-01
318
+
319
+ ### Breaking Changes
320
+
321
+ - Removed `PI_TUI_RESIZE_CLEAR_STRATEGY`; resize behavior is no longer configurable between viewport/scrollback modes. The renderer now uses fixed semantics: width changes perform a hard reset (`3J` + full content rewrite), while height changes and diff fallbacks use viewport-scoped repainting.
322
+
323
+ ### Added
324
+
325
+ - Added a new terminal regression suite in `packages/tui/test/render-regressions.test.ts` covering no-op render stability, targeted middle-line diffs, shrink cleanup, width-resize truncation without ghost rows, shrink/grow viewport tail anchoring, scrollback deduplication across forced redraws, overlay restore behavior, and rapid mutation convergence.
326
+ - Expanded `packages/tui/test/overlay-scroll.test.ts` with stress coverage for overflow shrink/regrow cycles, resize oscillation, overlay toggle churn, no-op render loops, and hardware-cursor-only updates while bounding scrollback growth and blank-run artifacts.
327
+
328
+ ### Changed
329
+
330
+ - Refactored render orchestration to explicit `hardReset` and `viewportRepaint` paths, with targeted fallbacks for offscreen diff ranges and unsafe row deltas.
331
+ - Switched startup to `requestRender(true)` so the first frame always initializes renderer state with a forced full path.
332
+ - Replaced legacy viewport bookkeeping (`previousViewportTop`) with `viewportTopRow` tracking and consistent screen-relative cursor calculations.
333
+ - Updated stop-sequence cursor placement to target the visible working area and clamp to terminal bounds before final newline emission.
334
+ - Documented the intentional performance policy of not forcing full repaint on every viewport-top shift, relying on narrower safety guards instead.
335
+
336
+ ### Fixed
337
+
338
+ - Fixed stale/duplicated terminal cursor dedup state by synchronizing `#lastCursorSequence` in all render write paths (hard reset, viewport repaint, deleted-lines clear path, append fast path, and differential path).
339
+ - Fixed scroll overshoot on `stop()` when content fills the viewport by clamping target row movement to valid screen rows.
340
+ ## [13.4.0] - 2026-03-01
341
+
342
+ ### Added
343
+
344
+ - Added `PI_TUI_RESIZE_CLEAR_STRATEGY` environment variable to control terminal behavior on resize: `viewport` (default) clears/redraws the viewport while preserving scrollback, or `scrollback` clears all history
345
+
346
+ ### Changed
347
+
348
+ - Changed resize redraw behavior to use configurable clear semantics (`viewport` vs `scrollback`) while keeping full content rendering for scrollback navigation
349
+
350
+ ### Fixed
351
+
352
+ - Fixed loader component rendering lines wider than terminal width, preventing text overflow and display artifacts
353
+
354
+ ## [13.3.11] - 2026-02-28
355
+
356
+ ### Fixed
357
+
358
+ - Restored terminal image protocol override and fallback detection for image rendering, including `PI_FORCE_IMAGE_PROTOCOL` support and Kitty fallback for screen/tmux/ghostty-style TERM environments.
359
+
360
+ ## [13.3.8] - 2026-02-28
361
+ ### Breaking Changes
362
+
363
+ - Changed mermaid hash type from string to bigint in `getMermaidImage` callback and `extractMermaidBlocks` return type
364
+ - Removed `mime-types` and `@types/mime-types` from dependencies
365
+ - Removed `@xterm/xterm` from dependencies
366
+
367
+ ### Changed
368
+
369
+ - Updated mermaid hash computation to use `Bun.hash.xxHash64()` instead of `Bun.hash().toString(16)`
370
+
371
+ ## [12.19.0] - 2026-02-22
372
+
373
+ ### Added
374
+
375
+ - Added `getTopBorderAvailableWidth()` method to calculate available width for top border content accounting for border characters and padding
376
+
377
+ ### Fixed
378
+
379
+ - Fixed stale viewport rows appearing when terminal height increases by triggering full re-render on height changes
380
+
381
+ ## [12.18.0] - 2026-02-21
382
+ ### Fixed
383
+
384
+ - Fixed viewport synchronization issue by clearing scrollback when terminal state becomes desynced during full re-renders
385
+
386
+ ## [12.12.2] - 2026-02-19
387
+
388
+ ### Fixed
389
+
390
+ - Fixed non-forced full re-renders clearing terminal scrollback history during streaming updates by limiting scrollback clears to explicit forced re-renders.
391
+
392
+ ## [12.12.0] - 2026-02-19
393
+
394
+ ### Added
395
+
396
+ - Added PageUp/PageDown navigation for editor content and autocomplete selection to jump across long wrapped inputs faster.
397
+
398
+ ### Fixed
399
+
400
+ - Fixed history-entry navigation anchoring (Up opens at top, Down opens at bottom) and preserved editor scroll context when max-height changes to keep cursor movement visible in long prompts ([#99](https://github.com/jaybeyond/sayknow-cli/issues/99)).
401
+
402
+ ## [12.11.3] - 2026-02-19
403
+
404
+ ### Fixed
405
+
406
+ - Fixed differential deleted-line rendering when content shrinks to empty so stale first-row content is cleared reliably.
407
+ - Fixed incremental stale-row clearing to use erase-below semantics in synchronized output, reducing leftover-line artifacts after shrink operations.
408
+
409
+ ## [12.9.0] - 2026-02-17
410
+ ### Added
411
+
412
+ - Exported `getTerminalId()` function to get a stable identifier for the current terminal, with support for TTY device paths and terminal multiplexers
413
+ - Exported `getTtyPath()` function to resolve the TTY device path for stdin via POSIX `ttyname(3)`
414
+
415
+ ## [12.5.0] - 2026-02-15
416
+ ### Added
417
+
418
+ - Added `cursorOverride` and `cursorOverrideWidth` properties to customize the end-of-text cursor glyph with ANSI-styled strings
419
+ - Added `getUseTerminalCursor()` method to query the terminal cursor mode setting
420
+
421
+ ## [11.10.0] - 2026-02-10
422
+ ### Added
423
+
424
+ - Added `hint` property to autocomplete items to display dim ghost text after cursor when item is selected
425
+ - Added `getInlineHint()` method to `SlashCommand` interface for providing inline hint text based on argument state
426
+ - Added `getInlineHint()` method to `AutocompleteProvider` interface for displaying dim ghost text after cursor
427
+ - Added `hintStyle` theme option to customize styling of inline hint/ghost text in editor
428
+
429
+ ### Changed
430
+
431
+ - Updated editor to render inline hint text as dim ghost text after cursor when autocomplete suggestions are active or provider supplies hints
432
+
433
+ ## [11.8.0] - 2026-02-10
434
+ ### Added
435
+
436
+ - Added Alt+Y keybinding to cycle through kill ring entries (yank-pop)
437
+ - Added undo support to Input component with Ctrl+Z keybinding
438
+ - Added kill ring support to Input component for Emacs-style kill/yank operations
439
+ - Added yank (Ctrl+Y) and yank-pop (Alt+Y) support to Input component
440
+
441
+ ### Changed
442
+
443
+ - Changed Editor kill ring implementation to use dedicated KillRing class for better state management
444
+ - Changed Editor undo stack to use generic UndoStack class with automatic state cloning
445
+ - Changed kill/yank behavior to properly accumulate consecutive kill operations
446
+ - Changed Input component deletion methods to record killed text in kill ring
447
+ - Changed undo coalescing in Input component to group consecutive word typing into single undo units
448
+
449
+ ## [11.4.1] - 2026-02-06
450
+ ### Fixed
451
+
452
+ - Fixed terminal scrolling when displaying overlays after rendering large content, preventing hundreds of blank lines from being output
453
+
454
+ ## [11.3.0] - 2026-02-06
455
+
456
+ ### Breaking Changes
457
+
458
+ - Removed `getCursorPosition()` method from Component interface and implementations, eliminating hardware cursor positioning support
459
+
460
+ ### Added
461
+
462
+ - Added sticky column behavior for vertical cursor movement, preserving target column when navigating through lines of varying lengths
463
+ - Added `drainInput()` method to Terminal interface to prevent Kitty key release events from leaking to parent shell over slow SSH connections
464
+ - Added `setClearOnShrink()` method to control whether full re-render occurs when content shrinks below working area
465
+ - Added support for hidden paths (e.g., `.pi`, `.github`) in autocomplete while excluding `.git` directories
466
+
467
+ ### Changed
468
+
469
+ - Changed default value of `PI_HARDWARE_CURSOR` environment variable from implicit true to explicit `"1"` for clarity
470
+ - Changed default value of `PI_CLEAR_ON_SHRINK` environment variable from implicit false to explicit `"0"` for clarity
471
+ - Changed TUI to clear screen on startup to prevent shell prompts and status messages from bleeding into the first rendered frame
472
+ - Refactored full-render logic into reusable helper function to reduce code duplication across multiple render paths
473
+ - Changed autocomplete to include hidden paths but filter out `.git` and its contents
474
+ - Changed Input component to properly handle surrogate pairs in Unicode text, preventing cursor display corruption with emoji and multi-byte characters
475
+ - Changed Editor to use `setCursorCol()` for all cursor column updates, enabling sticky column tracking
476
+ - Changed Editor's vertical navigation to implement sticky column logic via `moveToVisualLine()` and `computeVerticalMoveColumn()`
477
+ - Changed Editor's Enter key handling to extract submit logic into `submitValue()` method for better code organization
478
+ - Changed SettingsList to truncate long lines to viewport width, preventing text overflow
479
+ - Changed Terminal's `stop()` method to drain stdin before restoring raw mode, fixing race condition where Ctrl+D could close parent shell over SSH
480
+ - Changed TUI rendering to add `clearOnShrink` option (controlled by `PI_CLEAR_ON_SHRINK` env var) for reducing redraws on slower terminals
481
+ - Changed TUI rendering to detect when extra lines exceed viewport height and trigger full re-render instead of incremental updates
482
+
483
+ ### Fixed
484
+
485
+ - Fixed rendering of extra blank lines when content shrinks by improving cursor positioning logic during line deletion
486
+ - Fixed cursor display position in Input component when scrolling horizontally through long text
487
+ - Fixed Kitty keyboard protocol disable sequence to use safe write method, preventing potential output buffering issues
488
+ - Fixed unnecessary full-screen redraws when changes occur in out-of-view components (e.g., spinners), reducing terminal scroll events and improving performance on slower connections
489
+ - Fixed scrollback clearing behavior to only clear screen instead of scrollback when resizing or shrinking content, preventing loss of terminal history
490
+ - Fixed `.git` directory appearing in autocomplete suggestions when filtering by prefix
491
+ - Fixed cursor position corruption in Input component when displaying text with emoji and combining characters
492
+ - Fixed `.git` directory appearing in autocomplete suggestions
493
+ - Fixed race condition where Kitty key release events could leak to parent shell after TUI exit over slow SSH connections
494
+ - Fixed Editor's word movement (Ctrl+Left/Right) to properly reset sticky column for subsequent vertical navigation
495
+ - Fixed Editor's undo operation to reset sticky column state when restoring cursor position
496
+ - Fixed Editor's right arrow key at end of last line to set sticky column for subsequent up/down navigation
497
+ - Fixed TUI rendering to correctly detect viewport changes and avoid false full-redraws after content shrinks
498
+ - Fixed Kitty protocol key parsing to prefer codepoint over base layout for Latin letters and symbols, fixing keyboard layout issues (e.g., Dvorak)
499
+
500
+ ## [11.0.0] - 2026-02-05
501
+
502
+ ### Added
503
+
504
+ - Introduced `terminal-capabilities.ts` module consolidating terminal detection and image protocol support
505
+ - Added `TerminalInfo` class with methods for detecting image lines and formatting notifications
506
+ - Added `NotifyProtocol` enum supporting Bell, OSC 99, and OSC 9 notification protocols
507
+ - Added `isNotificationSuppressed()` function to check `SKC_NOTIFICATIONS` environment variable
508
+ - Added `TERMINAL` constant providing detected terminal capabilities at runtime
509
+
510
+ ### Changed
511
+
512
+ - Changed notification suppression environment variable from `SKC_NOTIFICATIONS` to `PI_NOTIFICATIONS`
513
+ - Changed TUI write log environment variable from `SKC_TUI_WRITE_LOG` to `PI_TUI_WRITE_LOG`
514
+ - Changed hardware cursor environment variable from `SKC_HARDWARE_CURSOR` to `PI_HARDWARE_CURSOR`
515
+ - Updated environment variable access to use `getEnv()` utility function from `@sayknow-cli/utils` for consistent handling
516
+ - Renamed `TERMINAL_INFO` export to `TERMINAL` for clearer API semantics
517
+ - Reorganized terminal image exports from `terminal-image` to `terminal-capabilities` module
518
+ - Updated all internal references to use `TERMINAL` instead of `TERMINAL_INFO`
519
+
520
+ ### Removed
521
+
522
+ - Removed `terminal-image` module exports from public API (functionality migrated to `terminal-capabilities`)
523
+
524
+ ## [10.5.0] - 2026-02-04
525
+
526
+ ### Fixed
527
+
528
+ - Treated inline image lines with cursor-move prefixes as image sequences to prevent width overflow crashes
529
+
530
+ ## [9.8.0] - 2026-02-01
531
+
532
+ ### Changed
533
+
534
+ - Moved `wrapTextWithAnsi` export to `@sayknow-cli/natives` package
535
+
536
+ ### Fixed
537
+
538
+ - Improved Kitty terminal key sequence parsing to correctly handle text field codepoints in CSI-u sequences
539
+ - Fixed handling of private use Unicode codepoints (U+E000 to U+F8FF) in Kitty key decoding to prevent invalid character interpretation
540
+
541
+ ## [9.7.0] - 2026-02-01
542
+ ### Breaking Changes
543
+
544
+ - Removed `Key` helper object from public API; use string literals like `"ctrl+c"` instead of `Key.ctrl("c")`
545
+ - Removed `KeyEventType` export from public API
546
+
547
+ ### Changed
548
+
549
+ - Migrated key parsing and matching logic to native implementation for improved performance
550
+ - Simplified `isKeyRelease()` and `isKeyRepeat()` to use regex pattern matching instead of string inclusion checks
551
+
552
+ ## [9.6.2] - 2026-02-01
553
+ ### Changed
554
+
555
+ - Renamed `EllipsisKind` enum to `Ellipsis` for clearer API naming
556
+ - Changed hardcoded ellipsis character from theme-configurable to literal "…" in editor truncation
557
+ - Refactored `visibleWidth` function to use caching wrapper around new `visibleWidthRaw` implementation for improved performance
558
+
559
+ ### Removed
560
+
561
+ - Removed `truncateToWidth`, `sliceWithWidth`, and `extractSegments` functions from public API (now re-exported directly from @sayknow-cli/natives)
562
+ - Removed `ellipsis` property from `SymbolTheme` interface
563
+ - Removed `extractAnsiCode` function from public API
564
+
565
+ ## [9.6.1] - 2026-02-01
566
+ ### Changed
567
+
568
+ - Improved performance of key ID parsing with optimized cache lookup strategy
569
+ - Simplified `visibleWidth` calculation to use consistent Bun.stringWidth approach for all string lengths
570
+
571
+ ### Removed
572
+
573
+ - Removed `visibleWidth` benchmark file in favor of Kitty sequence benchmarking
574
+
575
+ ## [9.5.0] - 2026-02-01
576
+ ### Changed
577
+
578
+ - Improved fuzzy file search performance by using native implementation instead of spawning external process
579
+ - Replaced external `fd` binary with native fuzzy path search for `@`-prefixed autocomplete
580
+
581
+ ## [9.4.0] - 2026-01-31
582
+ ### Added
583
+
584
+ - Exported `padding` utility function for creating space-padded strings efficiently
585
+
586
+ ### Changed
587
+
588
+ - Optimized padding operations across all components to use pre-allocated space buffer for better performance
589
+
590
+ ## [9.2.2] - 2026-01-31
591
+
592
+ ### Added
593
+ - Added setAutocompleteMaxVisible() configuration (3-20 items)
594
+ - Added image detection to terminal capabilities (containsImage method)
595
+ - Added stdin monitoring to detect stalled input events and log warnings
596
+
597
+ ### Changed
598
+ - Improved blockquote rendering with text wrapping in Markdown component
599
+ - Restructured terminal capabilities from interface-based to class-based model
600
+ - Improved table column width calculation with word-aware wrapping
601
+ - Refactored text utilities to use native WASM implementations for strings >256 chars with JS fast path
602
+
603
+ ### Fixed
604
+ - Simplified terminal write error handling to mark terminal as dead on any write failure
605
+ - Fixed multi-line strings in renderOutputBlock causing width overflow
606
+ - Fixed slash command autocomplete applying stale completion when typing quickly
607
+
608
+ ### Removed
609
+ - Removed TUI layout engine exports from public API (BoxNode, ColumnNode, LayoutNode, etc.)
610
+
611
+ ## [8.12.7] - 2026-01-29
612
+
613
+ ### Fixed
614
+ - Fixed slash command autocomplete applying stale completion when typing quickly
615
+
616
+ ## [8.4.1] - 2026-01-25
617
+
618
+ ### Added
619
+ - Added fuzzy match function for autocomplete suggestions
620
+ ## [8.4.0] - 2026-01-25
621
+
622
+ ### Changed
623
+ - Added Ctrl+Backspace as a delete-word-backward keybinding and improved modified backspace matching
624
+
625
+ ### Fixed
626
+ - Terminal gracefully handles write failures by marking dead instead of exiting the process
627
+ - Reserved cursor space for zero padding and corrected end-of-line cursor rendering to prevent wrap glitches
628
+ - Corrected editor end-of-line cursor rendering assertion to use includes() instead of endsWith()
629
+ ## [8.2.0] - 2026-01-24
630
+
631
+ ### Added
632
+ - Added mermaid diagram rendering engine (renderMermaidToPng) with mmdc CLI integration
633
+ - Added terminal graphics encoding (iTerm2/Kitty) for mermaid diagrams with automatic width scaling
634
+ - Added mermaid block extraction and deduplication utilities (extractMermaidBlocks)
635
+
636
+ ### Changed
637
+ - Updated TypeScript configuration for better publish-time configuration handling with tsconfig.publish.json
638
+ - Migrated file system operations from synchronous to asynchronous APIs in autocomplete provider for non-blocking I/O
639
+ - Migrated node module imports from named to namespace imports across all packages for consistency with project guidelines
640
+
641
+ ### Fixed
642
+ - Fixed crash when terminal becomes unavailable (EIO errors) by exiting gracefully instead of throwing
643
+ - Fixed potential errors during emergency terminal restore when terminal is already dead
644
+ - Fixed autocomplete race condition by tracking request ID to prevent stale suggestion results
645
+ ## [6.8.3] - 2026-01-21
646
+ ### Added
647
+
648
+ - Added undo support in the editor via `Ctrl+-`
649
+ - Added `Alt+Delete` as a delete-word-forward shortcut
650
+ - Added configurable code block indentation for Markdown rendering
651
+ - Added undo support in the editor via `Ctrl+-`.
652
+ - Added configurable code block indentation for Markdown rendering.
653
+ - Added `Alt+Delete` as a delete-word-forward shortcut.
654
+
655
+ ### Changed
656
+
657
+ - Improved fuzzy matching to handle alphanumeric swaps
658
+ - Normalized keybinding definitions to lowercase internally
659
+ - Improved fuzzy matching to handle alphanumeric swaps.
660
+ - Normalized keybinding definitions to lowercase internally.
661
+
662
+ ### Fixed
663
+
664
+ - Added legacy terminal support for `Ctrl+` symbol key combinations
665
+ - Added legacy terminal support for `Ctrl+` symbol key combinations.
666
+
667
+ ## [6.8.1] - 2026-01-20
668
+
669
+ ### Fixed
670
+
671
+ - Fixed viewport tracking after partial renders to prevent autocomplete list artifacts
672
+
673
+ ## [5.6.7] - 2026-01-18
674
+
675
+ ### Added
676
+
677
+ - Added configurable editor padding via `editorPaddingX` theme option
678
+ - Added `setMaxHeight()` method to limit editor height with scrolling
679
+ - Added Emacs-style kill ring for text deletion operations
680
+ - Added `Alt+D` keybinding to delete words forward
681
+ - Added `Ctrl+Y` keybinding to yank from kill ring
682
+ - Added `waitForRender()` method to await pending renders
683
+ - Added Focusable interface and hardware cursor marker support for IME positioning
684
+ - Added support for shifted symbol keys in keybindings
685
+
686
+ ### Changed
687
+
688
+ - Updated tab bar rendering to wrap text across multiple lines when content exceeds available width
689
+ - Expanded Kitty keyboard protocol coverage for non-Latin layouts and legacy Alt sequences
690
+ - Improved cursor positioning with safer bounds checking
691
+ - Updated editor layout to respect configurable padding
692
+ - Refactored scrolling logic for better viewport management
693
+
694
+ ### Fixed
695
+
696
+ - Fixed key detection for shifted symbol characters
697
+ - Fixed backspace handling with additional codepoint support
698
+ - Fixed Alt+letter key combinations for better recognition
699
+
700
+ ## [5.3.1] - 2026-01-15
701
+ ### Fixed
702
+
703
+ - Fixed rendering issues on Windows by preventing re-entrant renders
704
+
705
+ ## [5.1.0] - 2026-01-14
706
+
707
+ ### Added
708
+
709
+ - Added `pageUp` and `pageDown` key support with `selectPageUp`/`selectPageDown` editor actions
710
+ - Added `isPageUp()` and `isPageDown()` helper functions
711
+ - Added `SizeValue` type for CSS-like overlay sizing (absolute or percentage strings like `"50%"`)
712
+ - Added `OverlayHandle` interface with `hide()`, `setHidden()`, `isHidden()` methods for overlay visibility control
713
+ - Added `visible` callback to `OverlayOptions` for dynamic visibility based on terminal dimensions
714
+ - Added `pad` parameter to `truncateToWidth()` for padding result with spaces to exact width
715
+
716
+ ### Changed
717
+
718
+ - Changed `OverlayOptions` to use `SizeValue` type for `width`, `maxHeight`, `row`, and `col` properties
719
+ - Changed `showOverlay()` to return `OverlayHandle` for controlling overlay visibility
720
+ - Removed `widthPercent`, `maxHeightPercent`, `rowPercent`, `colPercent` from `OverlayOptions` (use percentage strings instead)
721
+
722
+ ### Fixed
723
+
724
+ - Fixed numbered list items showing "1." for all items when code blocks break list continuity
725
+ - Fixed width overflow protection in overlay compositing to prevent TUI crashes
726
+
727
+ ## [4.7.0] - 2026-01-12
728
+
729
+ ### Fixed
730
+ - Remove trailing space padding from Text, Markdown, and TruncatedText components when no background color is set (fixes copied text including unwanted whitespace)
731
+
732
+ ## [4.6.0] - 2026-01-12
733
+
734
+ ### Added
735
+ - Add fuzzy matching module (`fuzzyMatch`, `fuzzyFilter`) for command autocomplete
736
+ - Add `getExpandedText()` to editor for expanding paste markers
737
+ - Add backslash+enter newline fallback for terminals without Kitty protocol
738
+
739
+ ### Fixed
740
+ - Remove Kitty protocol query timeout that caused shift+enter delays
741
+ - Add bracketed paste check to prevent false key release/repeat detection
742
+ - Rendering optimizations: only re-render changed lines
743
+ - Refactor input component to use keybindings manager
744
+
745
+ ## [4.4.4] - 2026-01-11
746
+ ### Fixed
747
+
748
+ - Fixed Ctrl+Enter sequences to insert new lines in the editor
749
+
750
+ ## [4.2.1] - 2026-01-11
751
+ ### Changed
752
+
753
+ - Improved file autocomplete to show directory listing when typing `@` with no query, and fall back to prefix matching when fuzzy search returns no results
754
+
755
+ ### Fixed
756
+
757
+ - Fixed editor redraw glitch when canceling autocomplete suggestions
758
+ - Fixed `fd` tool detection to automatically find `fd` or `fdfind` in PATH when not explicitly configured
759
+
760
+ ## [4.1.0] - 2026-01-10
761
+ ### Added
762
+
763
+ - Added persistent prompt history storage support via `setHistoryStorage()` method, allowing history to be saved and restored across sessions
764
+
765
+ ## [4.0.0] - 2026-01-10
766
+ ### Added
767
+
768
+ - `EditorComponent` interface for custom editor implementations
769
+ - `StdinBuffer` class to split batched stdin into individual sequences
770
+ - Overlay compositing via `TUI.showOverlay()` and `TUI.hideOverlay()` for `ctx.ui.custom()` with `{ overlay: true }`
771
+ - Kitty keyboard protocol flag 2 support for key release events (`isKeyRelease()`, `isKeyRepeat()`, `KeyEventType`)
772
+ - `setKittyProtocolActive()`, `isKittyProtocolActive()` for Kitty protocol state management
773
+ - `kittyProtocolActive` property on Terminal interface to query Kitty protocol state
774
+ - `Component.wantsKeyRelease` property to opt-in to key release events (default false)
775
+ - Input component `onEscape` callback for handling escape key presses
776
+
777
+ ### Changed
778
+
779
+ - Terminal startup now queries Kitty protocol support before enabling event reporting
780
+ - Default editor `newLine` binding now uses `shift+enter` only
781
+
782
+ ### Fixed
783
+
784
+ - Key presses no longer dropped when batched with other events over SSH
785
+ - TUI now filters out key release events by default, preventing double-processing of keys
786
+ - `matchesKey()` now correctly matches Kitty protocol sequences for unmodified letter keys
787
+ - Crash when pasting text with trailing whitespace exceeding terminal width through Markdown rendering
788
+
789
+ ## [3.32.0] - 2026-01-08
790
+
791
+ ### Fixed
792
+
793
+ - Fixed text wrapping allowing long whitespace tokens to exceed line width
794
+
795
+ ## [3.20.0] - 2026-01-06
796
+ ### Added
797
+
798
+ - Added `isCapsLock` helper function for detecting Caps Lock key press via Kitty protocol
799
+ - Added `isCtrlY` helper function for detecting Ctrl+Y keyboard input
800
+ - Added configurable editor keybindings with typed key identifiers and action matching
801
+ - Added word-wrapped editor rendering for long lines
802
+
803
+ ### Changed
804
+
805
+ - Settings list descriptions now wrap to the available width instead of truncating
806
+
807
+ ### Fixed
808
+
809
+ - Fixed Shift+Enter detection in legacy terminals that send ESC+CR sequence
810
+
811
+ ## [3.15.1] - 2026-01-05
812
+
813
+ ### Fixed
814
+
815
+ - Fixed editor cursor blinking by allowing terminal cursor positioning when enabled.
816
+
817
+ ## [3.15.0] - 2026-01-05
818
+
819
+ ### Added
820
+
821
+ - Added `inputCursor` symbol for customizing the text input cursor character
822
+ - Added `symbols` property to `EditorTheme`, `MarkdownTheme`, and `SelectListTheme` interfaces for component-level symbol customization
823
+ - Added `SymbolTheme` interface for customizing UI symbols including cursors, borders, spinners, and box-drawing characters
824
+ - Added support for custom spinner frames in the Loader component
825
+
826
+ ## [3.9.1337] - 2026-01-04
827
+ ### Added
828
+
829
+ - Added `setTopBorder()` method to Editor component for displaying custom status content in the top border
830
+ - Added `getWidth()` method to TUI class for retrieving terminal width
831
+ - Added rounded corner box-drawing characters to Editor component borders
832
+
833
+ ### Changed
834
+
835
+ - Changed Editor component to use proper box borders with vertical side borders instead of horizontal-only borders
836
+ - Changed cursor style from block to thin blinking bar (▏) at end of line
837
+
838
+ ## [1.500.0] - 2026-01-03
839
+ ### Added
840
+
841
+ - Added `getText()` method to Text component for retrieving current text content
842
+
843
+ ## [1.337.1] - 2026-01-02
844
+
845
+ ### Added
846
+
847
+ - TabBar component for horizontal tab navigation
848
+ - Emergency terminal restore to prevent corrupted state on crashes
849
+ - Overhauled UI with welcome screen and powerline footer
850
+ - Theme-configurable HTML export colors
851
+ - `ctx.ui.theme` getter for styling status text with theme colors
852
+
853
+ ### Changed
854
+
855
+ - Forked to @sayknow-cli scope with unified versioning across all packages
856
+
857
+ ### Fixed
858
+
859
+ - Strip OSC 8 hyperlink sequences in `visibleWidth()`
860
+ - Crash on Unicode format characters in `visibleWidth()`
861
+ - Markdown code block syntax highlighting
862
+
863
+ ## [1.337.0] - 2026-01-02
864
+
865
+ Initial release under @sayknow-cli scope. See previous releases at [badlogic/pi-mono](https://github.com/badlogic/pi-mono).
866
+
867
+ ## [0.31.1] - 2026-01-02
868
+
869
+ ### Fixed
870
+
871
+ - `visibleWidth()` now strips OSC 8 hyperlink sequences, fixing text wrapping for clickable links ([#396](https://github.com/badlogic/pi-mono/pull/396) by [@Cursivez](https://github.com/Cursivez))
872
+
873
+ ## [0.31.0] - 2026-01-02
874
+
875
+ ### Added
876
+
877
+ - `isShiftCtrlO()` key detection function for Shift+Ctrl+O (Kitty protocol)
878
+ - `isShiftCtrlD()` key detection function for Shift+Ctrl+D (Kitty protocol)
879
+ - `TUI.onDebug` callback for global debug key handling (Shift+Ctrl+D)
880
+ - `wrapTextWithAnsi()` utility now exported (wraps text to width, preserving ANSI codes)
881
+
882
+ ### Changed
883
+
884
+ - README.md completely rewritten with accurate component documentation, theme interfaces, and examples
885
+ - `visibleWidth()` reimplemented with grapheme-based width calculation, 10x faster on Bun and ~15% faster on Node ([#369](https://github.com/badlogic/pi-mono/pull/369) by [@nathyong](https://github.com/nathyong))
886
+
887
+ ### Fixed
888
+
889
+ - Markdown component now renders HTML tags as plain text instead of silently dropping them ([#359](https://github.com/badlogic/pi-mono/issues/359))
890
+ - Crash in `visibleWidth()` and grapheme iteration when encountering undefined code points ([#372](https://github.com/badlogic/pi-mono/pull/372) by [@HACKE-RC](https://github.com/HACKE-RC))
891
+ - ZWJ emoji sequences (rainbow flag, family, etc.) now render with correct width instead of being split into multiple characters ([#369](https://github.com/badlogic/pi-mono/pull/369) by [@nathyong](https://github.com/nathyong))
892
+
893
+ ## [0.29.0] - 2025-12-25
894
+
895
+ ### Added
896
+
897
+ - **Auto-space before pasted file paths**: When pasting a file path (starting with `/`, `~`, or `.`) and the cursor is after a word character, a space is automatically prepended for better readability. Useful when dragging screenshots from macOS. ([#307](https://github.com/badlogic/pi-mono/pull/307) by [@mitsuhiko](https://github.com/mitsuhiko))
898
+ - **Word navigation for Input component**: Added Ctrl+Left/Right and Alt+Left/Right support for word-by-word cursor movement. ([#306](https://github.com/badlogic/pi-mono/pull/306) by [@kim0](https://github.com/kim0))
899
+ - **Full Unicode input**: Input component now accepts Unicode characters beyond ASCII. ([#306](https://github.com/badlogic/pi-mono/pull/306) by [@kim0](https://github.com/kim0))
900
+
901
+ ### Fixed
902
+
903
+ - **Readline-style Ctrl+W**: Now skips trailing whitespace before deleting the preceding word, matching standard readline behavior. ([#306](https://github.com/badlogic/pi-mono/pull/306) by [@kim0](https://github.com/kim0))