@oh-my-pi/pi-tui 15.7.6 → 15.8.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.
- package/CHANGELOG.md +95 -13
- package/README.md +1 -1
- package/dist/types/terminal-capabilities.d.ts +25 -1
- package/dist/types/terminal.d.ts +26 -29
- package/dist/types/tui.d.ts +14 -3
- package/package.json +3 -3
- package/src/components/markdown.ts +7 -5
- package/src/terminal-capabilities.ts +83 -17
- package/src/terminal.ts +26 -58
- package/src/tui.ts +277 -83
package/CHANGELOG.md
CHANGED
|
@@ -2,14 +2,51 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
-
## [15.
|
|
5
|
+
## [15.8.2] - 2026-06-03
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Added `PI_NO_SYNC_OUTPUT=1` to disable DEC 2026 synchronized-output wrappers for terminals whose implementation is buggy or visually worse, while keeping the renderer's autowrap guards active during paints ([#1765](https://github.com/can1357/oh-my-pi/issues/1765)).
|
|
6
10
|
|
|
7
11
|
### Fixed
|
|
8
12
|
|
|
9
|
-
- Fixed
|
|
13
|
+
- Fixed terminal resizes that land in the same render frame as streamed output splicing a phantom blank row into native scrollback and offsetting every later row by one. A height shrink (or width change carrying an append) with content overflowing the viewport fell through to the differential emitter, whose scroll math is anchored to the pre-resize viewport top and hardware-cursor row — both invalidated by the terminal's own resize reflow. Geometry-changed frames now rebuild native history when the viewport is at (or possibly at) the bottom, and defer non-destructively for a reader confirmed scrolled into history.
|
|
14
|
+
- Fixed Ghostty/kitty/Alacritty-style ED3-risk terminals freezing the prompt after a deferred shrink; focused keyboard input now uses the same explicit user-input viewport opt-in as autocomplete and can repaint immediately instead of waiting for a resize.
|
|
15
|
+
- Deferred eager live scrollback rebuilds under WSL fronted by Windows Terminal (`WT_SESSION` present in a Linux environment) so foreground streaming no longer emits ED3 (`CSI 3 J`) and yanks a reader scrolled into Windows Terminal's host scrollback; deferred rewrites still reconcile at the next prompt-submit checkpoint ([#1610](https://github.com/can1357/oh-my-pi/issues/1610)).
|
|
16
|
+
- Fixed tmux (and screen/zellij) pane history gaining a complete duplicate copy of the transcript every time a deferred offscreen edit was followed by another render. Multiplexer panes never receive a destructive scrollback clear, so the dirty-scrollback rebuild path only appended the full transcript on top of preserved pane history — repeatedly. Live frames inside multiplexers now keep repainting the viewport and leave history reconciliation to explicit checkpoints, which also removes the O(transcript) write amplification per frame.
|
|
17
|
+
- Fixed tmux pane viewports corrupting and pane history duplicating when a resize coincides with rendering: a resize racing a streamed append reached the stale-anchor diff emitters (phantom rows in the pane), a forced render racing a resize replayed the whole transcript into preserved pane history, and the prompt-submit checkpoint did the same after any deferred offscreen edit. Geometry-changed frames inside multiplexers now repaint the viewport in place, and forced-render geometry replays plus checkpoint replays are disabled there — tmux reflows its own pane grid and its history cannot be cleared, only duplicated.
|
|
18
|
+
- Fixed terminal resize events whose dimensions net out unchanged by render time (rapid SIGWINCH round trips during a window drag, coalesced into one 16ms frame) being invisible to the renderer. The terminal reflows its buffer on every resize event — rows move between the viewport and scrollback and can be evicted at the scrollback cap — so diffing against the pre-resize screen splices blank phantom rows into the viewport. The renderer now tracks the resize event itself, not just the dimension delta, and routes such frames through the geometry-change repaint/rebuild paths.
|
|
19
|
+
- Fixed Termux terminal resizes (screen rotation or software-keyboard toggles) displacing or hiding output after the viewport height changed. Content-bearing resizes were routed to the differential emitter, whose scroll math is anchored to the pre-resize viewport, so appended rows landed too low; pure height changes were treated as no-ops, exposing blank rows that later appends could fill without growing native scrollback. Termux resizes now repaint or rebuild at the new geometry like every other non-multiplexer terminal.
|
|
20
|
+
- Fixed the turn-end teardown frame freezing on ED3-risk terminals (Ghostty/kitty/Alacritty/iTerm2): disabling eager scrollback rebuild now takes effect only after the in-flight frame is classified, so the loader/status removal still paints instead of deferring and leaving a stale spinner until the next keystroke.
|
|
21
|
+
- Fixed non-WT ConPTY terminals on Windows (Tabby, Hyper, VS Code, conhost) clearing scrollback and yanking the viewport to the top whenever streaming output or a prompt-submit rebuild arrived while the user was scrolled up. The kernel32 viewport probe describes the ConPTY pseudo-console buffer — which is pinned to the visible grid, invisible to host-UI scrollback — so it reported "at bottom" no matter where the user had scrolled, and the [#1635](https://github.com/can1357/oh-my-pi/issues/1635) fix only distrusted it under `WT_SESSION`, which Tabby and other ConPTY hosts never set. The probe is now removed entirely: every Windows host is treated as viewport-unobservable, live mutations defer destructive rebuilds (no `\x1b[3J`, no viewport movement), and native scrollback reconciles at the prompt-submit checkpoint where the Enter keystroke has already pinned the host viewport to the bottom ([#1746](https://github.com/can1357/oh-my-pi/issues/1746)).
|
|
22
|
+
- Fixed emoji-presentation symbols (a default-text symbol followed by variation-selector-16 `U+FE0F`, e.g. `⚠️`, `ℹ️`, `❤️`, keycaps) measuring as 1 cell instead of 2 in the native width engine on macOS. The native scanner now keeps `UnicodeWidthStr` as the source of truth for multi-codepoint graphemes and applies only the local macOS Hangul Compatibility Jamo character-width delta, preserving VS16/keycap sequence widths without reintroducing jamo cursor drift.
|
|
23
|
+
- Deferred eager live scrollback rebuilds on macOS Terminal.app and iTerm2 so assistant/tool streaming no longer emits ED3 (`CSI 3 J`) while their native viewport position is unobservable, preserving readers scrolled into terminal history ([#1300](https://github.com/can1357/oh-my-pi/issues/1300)).
|
|
24
|
+
- Fixed width-shrink reflow leaving old-width rows in native history so later appends no longer undercount scrollback growth or duplicate wrapped content.
|
|
25
|
+
- Fixed hiding overlays after terminal reflow so stale dialog rows are scrubbed from native scrollback on non-multiplexer terminals.
|
|
26
|
+
|
|
27
|
+
### Removed
|
|
28
|
+
|
|
29
|
+
- Removed `shouldTrustNativeViewportProbe` and `ProcessTerminal`'s kernel32 `GetConsoleScreenBufferInfo` viewport probe. No Windows environment can answer "is the user's viewport at the bottom" truthfully — under ConPTY (every modern host) the pseudo-console buffer is pinned to the visible grid so the probe always read "at bottom", and under legacy conhost the window tracks the output cursor rather than the buffer tail so it always read "scrolled up" — so the probe and its trust gate are gone; `ProcessTerminal` no longer implements the optional `Terminal.isNativeViewportAtBottom`.
|
|
30
|
+
|
|
31
|
+
## [15.8.1] - 2026-06-02
|
|
10
32
|
|
|
11
33
|
### Fixed
|
|
12
34
|
|
|
35
|
+
- Deferred eager live scrollback rebuilds on VTE terminals so GNOME-style Linux terminals do not flash or erase readable scrollback during streaming ([#1719](https://github.com/can1357/oh-my-pi/issues/1719)).
|
|
36
|
+
|
|
37
|
+
## [15.8.0] - 2026-06-02
|
|
38
|
+
|
|
39
|
+
### Fixed
|
|
40
|
+
|
|
41
|
+
- Deferred eager live scrollback rebuilds on POSIX terminals where xterm ED3 (`CSI 3 J`, erase saved lines) can disturb scrolled-up readers during streaming, while keeping direct user-input and checkpoint rebuilds explicit ([#1682](https://github.com/can1357/oh-my-pi/issues/1682)).
|
|
42
|
+
- Fixed TUI shutdown placing the parent shell prompt one row below short rendered content instead of directly on the next line ([#1620](https://github.com/can1357/oh-my-pi/issues/1620)).
|
|
43
|
+
- Stopped painting inline color swatches for 4-digit hex runs in Markdown rendering. The `#RGBA` CSS form collides with hashline `#TAG` snapshot tags (4 hex digits, e.g. `#6C5E`), which were sprouting spurious RGB swatches in prose and codespans. Only `#RGB`, `#RRGGBB`, and `#RRGGBBAA` qualify now.
|
|
44
|
+
|
|
45
|
+
## [15.7.6] - 2026-06-01
|
|
46
|
+
|
|
47
|
+
### Fixed
|
|
48
|
+
|
|
49
|
+
- Fixed native Windows + Windows Terminal freezing the editor on the wrap keystroke, on `/plan`/`/resume`/model-switch/status-line toggles, and on any other offscreen structural mutation until the next prompt submit. The `15.7.5` `#1635` fix routed every viewport-saturating pure-append and structural mutation through `deferredMutation` (a literal no-op) whenever `isNativeViewportAtBottom()` returned `undefined` — which it always does under `WT_SESSION` because the kernel32 probe can't see WT host scrollback. The deferral was only ever meant for the *confirmed-scrolled* case; an unknown viewport now falls back to a non-destructive `viewportRepaint` instead, so the live UI keeps updating without emitting `\x1b[3J` and without yanking a possibly-scrolled reader. Confirmed-scrolled frames (probe returns `false`) still defer.
|
|
13
50
|
- Removed the hard-coded 20-result cap on `@`-prefixed fuzzy file completion in `CombinedAutocompleteProvider.#getFuzzyFileSuggestions`. The dropdown now honors the existing `maxResults: 100` ceiling already configured for `fuzzyFind`, so projects with many files sharing a common stem (e.g. `@controller`, `@test`) surface all relevant matches instead of being silently truncated. ([#1652](https://github.com/can1357/oh-my-pi/issues/1652))
|
|
14
51
|
|
|
15
52
|
## [15.7.5] - 2026-06-01
|
|
@@ -50,6 +87,7 @@
|
|
|
50
87
|
- Fixed slash-command autocomplete repainting when a Windows Terminal session cannot report native scrollback position; live input renders can now bypass the unknown-viewport deferral without weakening background scrollback protection. ([#1550](https://github.com/can1357/oh-my-pi/issues/1550))
|
|
51
88
|
|
|
52
89
|
## [15.6.0] - 2026-05-30
|
|
90
|
+
|
|
53
91
|
### Added
|
|
54
92
|
|
|
55
93
|
- Added autocomplete triggering for internal URL scheme tokens such as `local://` and `skill://` while typing in the editor
|
|
@@ -96,6 +134,7 @@
|
|
|
96
134
|
- Fixed full TUI redraws clearing terminal scrollback with `CSI 3 J`, preserving manual scrollback inspection while active sessions continue updating. ([#1295](https://github.com/can1357/oh-my-pi/issues/1295))
|
|
97
135
|
|
|
98
136
|
## [15.2.3] - 2026-05-22
|
|
137
|
+
|
|
99
138
|
### Added
|
|
100
139
|
|
|
101
140
|
- Added `SettingsList#setItems` to replace the entire settings list with a new items array while automatically clamping selection to a valid index
|
|
@@ -123,6 +162,7 @@
|
|
|
123
162
|
- Restored the `Key` runtime helper on `@oh-my-pi/pi-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.
|
|
124
163
|
|
|
125
164
|
## [15.0.1] - 2026-05-14
|
|
165
|
+
|
|
126
166
|
### Breaking Changes
|
|
127
167
|
|
|
128
168
|
- Increased the minimum required Bun version for the TUI package from >=1.3.7 to >=1.3.14
|
|
@@ -156,6 +196,10 @@
|
|
|
156
196
|
- `SlashCommand.getArgumentCompletions()` may return a `Promise`; results are now awaited and non-array returns are ignored (ports pi-mono `a1e10789`)
|
|
157
197
|
- Fuzzy `@` autocomplete now follows symlinked directories via `ScanOptions.follow_links` plumbed through the native walker (ports pi-mono `780d5367`)
|
|
158
198
|
- 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`)
|
|
199
|
+
- Changed slash-command autocomplete list rendering to combine command hint and description in a single displayed suggestion text
|
|
200
|
+
- Changed render scheduling to throttle `requestRender` calls to roughly 60fps by batching updates
|
|
201
|
+
- Changed terminal input handling to process complete cell-size responses without buffering partial input
|
|
202
|
+
- Changed `KeyId` to accept super-modifier combinations and improve typed key-id validation
|
|
159
203
|
|
|
160
204
|
### Fixed
|
|
161
205
|
|
|
@@ -171,20 +215,11 @@
|
|
|
171
215
|
- Allowed `SlashCommand.getArgumentCompletions` to return asynchronous results by accepting Promise-based completions
|
|
172
216
|
- Added `argumentHint` support to slash command definitions and displayed it in command suggestion descriptions
|
|
173
217
|
- Added support for xterm `modifyOtherKeys` printable key sequences by decoding `CSI 27;mod;key~` into text input
|
|
174
|
-
|
|
175
|
-
### Changed
|
|
176
|
-
|
|
177
|
-
- Changed slash-command autocomplete list rendering to combine command hint and description in a single displayed suggestion text
|
|
178
|
-
- Changed render scheduling to throttle `requestRender` calls to roughly 60fps by batching updates
|
|
179
|
-
- Changed terminal input handling to process complete cell-size responses without buffering partial input
|
|
180
|
-
- Changed `KeyId` to accept super-modifier combinations and improve typed key-id validation
|
|
181
|
-
|
|
182
|
-
### Fixed
|
|
183
|
-
|
|
184
218
|
- Normalized line output during rendering to correct Thai/Lao AM glyph composition for displayed text
|
|
185
219
|
- Fixed duplicated Kitty key input emissions by dropping the matching unmodified follow-up sequence after a Kitty CSI-u printable-key event
|
|
186
220
|
|
|
187
221
|
## [14.9.5] - 2026-05-12
|
|
222
|
+
|
|
188
223
|
### Fixed
|
|
189
224
|
|
|
190
225
|
- Fixed rapidly blinking cursor artifact during task execution by consolidating cursor control sequences into the synchronized output buffer ([#992](https://github.com/can1357/oh-my-pi/issues/992))
|
|
@@ -238,6 +273,7 @@
|
|
|
238
273
|
- Autocomplete fuzzy discovery now accepts optional SearchDb instance for faster searches
|
|
239
274
|
|
|
240
275
|
## [13.16.0] - 2026-03-27
|
|
276
|
+
|
|
241
277
|
### Changed
|
|
242
278
|
|
|
243
279
|
- Updated tab replacement in editor text sanitization to respect configured tab width setting
|
|
@@ -253,6 +289,7 @@
|
|
|
253
289
|
- Fixed editor consuming user-rebound copy keys, preventing custom keybindings from working in the editor
|
|
254
290
|
|
|
255
291
|
## [13.14.1] - 2026-03-21
|
|
292
|
+
|
|
256
293
|
### Added
|
|
257
294
|
|
|
258
295
|
- Added Ctrl+_ as an additional default shortcut for undo
|
|
@@ -273,17 +310,20 @@
|
|
|
273
310
|
- Fixed paste marker expansion to handle special regex replacement tokens ($1, $2, $&, $$, $`, $') literally in pasted content
|
|
274
311
|
|
|
275
312
|
## [13.11.0] - 2026-03-12
|
|
313
|
+
|
|
276
314
|
### Fixed
|
|
277
315
|
|
|
278
316
|
- Fixed OSC 11 background color detection to correctly handle partial escape sequences that arrive mid-buffer, preventing user input from being swallowed
|
|
279
317
|
- Fixed race condition where overlapping OSC 11 queries would be incorrectly cancelled by DA1 sentinels from previous queries
|
|
280
318
|
|
|
281
319
|
## [13.7.5] - 2026-03-04
|
|
320
|
+
|
|
282
321
|
### Changed
|
|
283
322
|
|
|
284
323
|
- Extracted word navigation logic into reusable `moveWordLeft` and `moveWordRight` utility functions for consistent cursor movement across components
|
|
285
324
|
|
|
286
325
|
## [13.6.2] - 2026-03-03
|
|
326
|
+
|
|
287
327
|
### Fixed
|
|
288
328
|
|
|
289
329
|
- Fixed cursor positioning when content shrinks to empty without clearOnShrink enabled
|
|
@@ -293,6 +333,7 @@
|
|
|
293
333
|
### Fixed
|
|
294
334
|
|
|
295
335
|
- 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/can1357/oh-my-pi/issues/228), [#234](https://github.com/can1357/oh-my-pi/issues/234))
|
|
336
|
+
|
|
296
337
|
## [13.5.3] - 2026-03-01
|
|
297
338
|
|
|
298
339
|
### Fixed
|
|
@@ -302,6 +343,7 @@
|
|
|
302
343
|
- Fixed cursor positioning instability when appending content under external cursor relocation by using absolute screen addressing instead of relative cursor movement
|
|
303
344
|
|
|
304
345
|
## [13.5.2] - 2026-03-01
|
|
346
|
+
|
|
305
347
|
### Breaking Changes
|
|
306
348
|
|
|
307
349
|
- Removed `getMermaidImage` callback from MarkdownTheme; replaced with `getMermaidAscii` that accepts ASCII string instead of image data
|
|
@@ -312,6 +354,7 @@
|
|
|
312
354
|
- Mermaid diagrams now render as ASCII text instead of terminal graphics protocol images
|
|
313
355
|
|
|
314
356
|
## [13.5.1] - 2026-03-01
|
|
357
|
+
|
|
315
358
|
### Fixed
|
|
316
359
|
|
|
317
360
|
- Fixed viewport shift handling to prevent stale content when mixed updates remap screen rows
|
|
@@ -339,6 +382,7 @@
|
|
|
339
382
|
|
|
340
383
|
- 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).
|
|
341
384
|
- Fixed scroll overshoot on `stop()` when content fills the viewport by clamping target row movement to valid screen rows.
|
|
385
|
+
|
|
342
386
|
## [13.4.0] - 2026-03-01
|
|
343
387
|
|
|
344
388
|
### Added
|
|
@@ -360,6 +404,7 @@
|
|
|
360
404
|
- 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.
|
|
361
405
|
|
|
362
406
|
## [13.3.8] - 2026-02-28
|
|
407
|
+
|
|
363
408
|
### Breaking Changes
|
|
364
409
|
|
|
365
410
|
- Changed mermaid hash type from string to bigint in `getMermaidImage` callback and `extractMermaidBlocks` return type
|
|
@@ -381,6 +426,7 @@
|
|
|
381
426
|
- Fixed stale viewport rows appearing when terminal height increases by triggering full re-render on height changes
|
|
382
427
|
|
|
383
428
|
## [12.18.0] - 2026-02-21
|
|
429
|
+
|
|
384
430
|
### Fixed
|
|
385
431
|
|
|
386
432
|
- Fixed viewport synchronization issue by clearing scrollback when terminal state becomes desynced during full re-renders
|
|
@@ -409,18 +455,21 @@
|
|
|
409
455
|
- Fixed incremental stale-row clearing to use erase-below semantics in synchronized output, reducing leftover-line artifacts after shrink operations.
|
|
410
456
|
|
|
411
457
|
## [12.9.0] - 2026-02-17
|
|
458
|
+
|
|
412
459
|
### Added
|
|
413
460
|
|
|
414
461
|
- Exported `getTerminalId()` function to get a stable identifier for the current terminal, with support for TTY device paths and terminal multiplexers
|
|
415
462
|
- Exported `getTtyPath()` function to resolve the TTY device path for stdin via POSIX `ttyname(3)`
|
|
416
463
|
|
|
417
464
|
## [12.5.0] - 2026-02-15
|
|
465
|
+
|
|
418
466
|
### Added
|
|
419
467
|
|
|
420
468
|
- Added `cursorOverride` and `cursorOverrideWidth` properties to customize the end-of-text cursor glyph with ANSI-styled strings
|
|
421
469
|
- Added `getUseTerminalCursor()` method to query the terminal cursor mode setting
|
|
422
470
|
|
|
423
471
|
## [11.10.0] - 2026-02-10
|
|
472
|
+
|
|
424
473
|
### Added
|
|
425
474
|
|
|
426
475
|
- Added `hint` property to autocomplete items to display dim ghost text after cursor when item is selected
|
|
@@ -433,6 +482,7 @@
|
|
|
433
482
|
- Updated editor to render inline hint text as dim ghost text after cursor when autocomplete suggestions are active or provider supplies hints
|
|
434
483
|
|
|
435
484
|
## [11.8.0] - 2026-02-10
|
|
485
|
+
|
|
436
486
|
### Added
|
|
437
487
|
|
|
438
488
|
- Added Alt+Y keybinding to cycle through kill ring entries (yank-pop)
|
|
@@ -449,6 +499,7 @@
|
|
|
449
499
|
- Changed undo coalescing in Input component to group consecutive word typing into single undo units
|
|
450
500
|
|
|
451
501
|
## [11.4.1] - 2026-02-06
|
|
502
|
+
|
|
452
503
|
### Fixed
|
|
453
504
|
|
|
454
505
|
- Fixed terminal scrolling when displaying overlays after rendering large content, preventing hundreds of blank lines from being output
|
|
@@ -541,6 +592,7 @@
|
|
|
541
592
|
- Fixed handling of private use Unicode codepoints (U+E000 to U+F8FF) in Kitty key decoding to prevent invalid character interpretation
|
|
542
593
|
|
|
543
594
|
## [9.7.0] - 2026-02-01
|
|
595
|
+
|
|
544
596
|
### Breaking Changes
|
|
545
597
|
|
|
546
598
|
- Removed `Key` helper object from public API; use string literals like `"ctrl+c"` instead of `Key.ctrl("c")`
|
|
@@ -552,6 +604,7 @@
|
|
|
552
604
|
- Simplified `isKeyRelease()` and `isKeyRepeat()` to use regex pattern matching instead of string inclusion checks
|
|
553
605
|
|
|
554
606
|
## [9.6.2] - 2026-02-01
|
|
607
|
+
|
|
555
608
|
### Changed
|
|
556
609
|
|
|
557
610
|
- Renamed `EllipsisKind` enum to `Ellipsis` for clearer API naming
|
|
@@ -565,6 +618,7 @@
|
|
|
565
618
|
- Removed `extractAnsiCode` function from public API
|
|
566
619
|
|
|
567
620
|
## [9.6.1] - 2026-02-01
|
|
621
|
+
|
|
568
622
|
### Changed
|
|
569
623
|
|
|
570
624
|
- Improved performance of key ID parsing with optimized cache lookup strategy
|
|
@@ -575,12 +629,14 @@
|
|
|
575
629
|
- Removed `visibleWidth` benchmark file in favor of Kitty sequence benchmarking
|
|
576
630
|
|
|
577
631
|
## [9.5.0] - 2026-02-01
|
|
632
|
+
|
|
578
633
|
### Changed
|
|
579
634
|
|
|
580
635
|
- Improved fuzzy file search performance by using native implementation instead of spawning external process
|
|
581
636
|
- Replaced external `fd` binary with native fuzzy path search for `@`-prefixed autocomplete
|
|
582
637
|
|
|
583
638
|
## [9.4.0] - 2026-01-31
|
|
639
|
+
|
|
584
640
|
### Added
|
|
585
641
|
|
|
586
642
|
- Exported `padding` utility function for creating space-padded strings efficiently
|
|
@@ -592,59 +648,74 @@
|
|
|
592
648
|
## [9.2.2] - 2026-01-31
|
|
593
649
|
|
|
594
650
|
### Added
|
|
651
|
+
|
|
595
652
|
- Added setAutocompleteMaxVisible() configuration (3-20 items)
|
|
596
653
|
- Added image detection to terminal capabilities (containsImage method)
|
|
597
654
|
- Added stdin monitoring to detect stalled input events and log warnings
|
|
598
655
|
|
|
599
656
|
### Changed
|
|
657
|
+
|
|
600
658
|
- Improved blockquote rendering with text wrapping in Markdown component
|
|
601
659
|
- Restructured terminal capabilities from interface-based to class-based model
|
|
602
660
|
- Improved table column width calculation with word-aware wrapping
|
|
603
661
|
- Refactored text utilities to use native WASM implementations for strings >256 chars with JS fast path
|
|
604
662
|
|
|
605
663
|
### Fixed
|
|
664
|
+
|
|
606
665
|
- Simplified terminal write error handling to mark terminal as dead on any write failure
|
|
607
666
|
- Fixed multi-line strings in renderOutputBlock causing width overflow
|
|
608
667
|
- Fixed slash command autocomplete applying stale completion when typing quickly
|
|
609
668
|
|
|
610
669
|
### Removed
|
|
670
|
+
|
|
611
671
|
- Removed TUI layout engine exports from public API (BoxNode, ColumnNode, LayoutNode, etc.)
|
|
612
672
|
|
|
613
673
|
## [8.12.7] - 2026-01-29
|
|
614
674
|
|
|
615
675
|
### Fixed
|
|
676
|
+
|
|
616
677
|
- Fixed slash command autocomplete applying stale completion when typing quickly
|
|
617
678
|
|
|
618
679
|
## [8.4.1] - 2026-01-25
|
|
619
680
|
|
|
620
681
|
### Added
|
|
682
|
+
|
|
621
683
|
- Added fuzzy match function for autocomplete suggestions
|
|
684
|
+
|
|
622
685
|
## [8.4.0] - 2026-01-25
|
|
623
686
|
|
|
624
687
|
### Changed
|
|
688
|
+
|
|
625
689
|
- Added Ctrl+Backspace as a delete-word-backward keybinding and improved modified backspace matching
|
|
626
690
|
|
|
627
691
|
### Fixed
|
|
692
|
+
|
|
628
693
|
- Terminal gracefully handles write failures by marking dead instead of exiting the process
|
|
629
694
|
- Reserved cursor space for zero padding and corrected end-of-line cursor rendering to prevent wrap glitches
|
|
630
695
|
- Corrected editor end-of-line cursor rendering assertion to use includes() instead of endsWith()
|
|
696
|
+
|
|
631
697
|
## [8.2.0] - 2026-01-24
|
|
632
698
|
|
|
633
699
|
### Added
|
|
700
|
+
|
|
634
701
|
- Added mermaid diagram rendering engine (renderMermaidToPng) with mmdc CLI integration
|
|
635
702
|
- Added terminal graphics encoding (iTerm2/Kitty) for mermaid diagrams with automatic width scaling
|
|
636
703
|
- Added mermaid block extraction and deduplication utilities (extractMermaidBlocks)
|
|
637
704
|
|
|
638
705
|
### Changed
|
|
706
|
+
|
|
639
707
|
- Updated TypeScript configuration for better publish-time configuration handling with tsconfig.publish.json
|
|
640
708
|
- Migrated file system operations from synchronous to asynchronous APIs in autocomplete provider for non-blocking I/O
|
|
641
709
|
- Migrated node module imports from named to namespace imports across all packages for consistency with project guidelines
|
|
642
710
|
|
|
643
711
|
### Fixed
|
|
712
|
+
|
|
644
713
|
- Fixed crash when terminal becomes unavailable (EIO errors) by exiting gracefully instead of throwing
|
|
645
714
|
- Fixed potential errors during emergency terminal restore when terminal is already dead
|
|
646
715
|
- Fixed autocomplete race condition by tracking request ID to prevent stale suggestion results
|
|
716
|
+
|
|
647
717
|
## [6.8.3] - 2026-01-21
|
|
718
|
+
|
|
648
719
|
### Added
|
|
649
720
|
|
|
650
721
|
- Added undo support in the editor via `Ctrl+-`
|
|
@@ -700,6 +771,7 @@
|
|
|
700
771
|
- Fixed Alt+letter key combinations for better recognition
|
|
701
772
|
|
|
702
773
|
## [5.3.1] - 2026-01-15
|
|
774
|
+
|
|
703
775
|
### Fixed
|
|
704
776
|
|
|
705
777
|
- Fixed rendering issues on Windows by preventing re-entrant renders
|
|
@@ -729,27 +801,32 @@
|
|
|
729
801
|
## [4.7.0] - 2026-01-12
|
|
730
802
|
|
|
731
803
|
### Fixed
|
|
804
|
+
|
|
732
805
|
- Remove trailing space padding from Text, Markdown, and TruncatedText components when no background color is set (fixes copied text including unwanted whitespace)
|
|
733
806
|
|
|
734
807
|
## [4.6.0] - 2026-01-12
|
|
735
808
|
|
|
736
809
|
### Added
|
|
810
|
+
|
|
737
811
|
- Add fuzzy matching module (`fuzzyMatch`, `fuzzyFilter`) for command autocomplete
|
|
738
812
|
- Add `getExpandedText()` to editor for expanding paste markers
|
|
739
813
|
- Add backslash+enter newline fallback for terminals without Kitty protocol
|
|
740
814
|
|
|
741
815
|
### Fixed
|
|
816
|
+
|
|
742
817
|
- Remove Kitty protocol query timeout that caused shift+enter delays
|
|
743
818
|
- Add bracketed paste check to prevent false key release/repeat detection
|
|
744
819
|
- Rendering optimizations: only re-render changed lines
|
|
745
820
|
- Refactor input component to use keybindings manager
|
|
746
821
|
|
|
747
822
|
## [4.4.4] - 2026-01-11
|
|
823
|
+
|
|
748
824
|
### Fixed
|
|
749
825
|
|
|
750
826
|
- Fixed Ctrl+Enter sequences to insert new lines in the editor
|
|
751
827
|
|
|
752
828
|
## [4.2.1] - 2026-01-11
|
|
829
|
+
|
|
753
830
|
### Changed
|
|
754
831
|
|
|
755
832
|
- Improved file autocomplete to show directory listing when typing `@` with no query, and fall back to prefix matching when fuzzy search returns no results
|
|
@@ -760,11 +837,13 @@
|
|
|
760
837
|
- Fixed `fd` tool detection to automatically find `fd` or `fdfind` in PATH when not explicitly configured
|
|
761
838
|
|
|
762
839
|
## [4.1.0] - 2026-01-10
|
|
840
|
+
|
|
763
841
|
### Added
|
|
764
842
|
|
|
765
843
|
- Added persistent prompt history storage support via `setHistoryStorage()` method, allowing history to be saved and restored across sessions
|
|
766
844
|
|
|
767
845
|
## [4.0.0] - 2026-01-10
|
|
846
|
+
|
|
768
847
|
### Added
|
|
769
848
|
|
|
770
849
|
- `EditorComponent` interface for custom editor implementations
|
|
@@ -795,6 +874,7 @@
|
|
|
795
874
|
- Fixed text wrapping allowing long whitespace tokens to exceed line width
|
|
796
875
|
|
|
797
876
|
## [3.20.0] - 2026-01-06
|
|
877
|
+
|
|
798
878
|
### Added
|
|
799
879
|
|
|
800
880
|
- Added `isCapsLock` helper function for detecting Caps Lock key press via Kitty protocol
|
|
@@ -826,6 +906,7 @@
|
|
|
826
906
|
- Added support for custom spinner frames in the Loader component
|
|
827
907
|
|
|
828
908
|
## [3.9.1337] - 2026-01-04
|
|
909
|
+
|
|
829
910
|
### Added
|
|
830
911
|
|
|
831
912
|
- Added `setTopBorder()` method to Editor component for displaying custom status content in the top border
|
|
@@ -838,6 +919,7 @@
|
|
|
838
919
|
- Changed cursor style from block to thin blinking bar (▏) at end of line
|
|
839
920
|
|
|
840
921
|
## [1.500.0] - 2026-01-03
|
|
922
|
+
|
|
841
923
|
### Added
|
|
842
924
|
|
|
843
925
|
- Added `getText()` method to Text component for retrieving current text content
|
|
@@ -902,4 +984,4 @@ Initial release under @oh-my-pi scope. See previous releases at [badlogic/pi-mon
|
|
|
902
984
|
|
|
903
985
|
### Fixed
|
|
904
986
|
|
|
905
|
-
- **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))
|
|
987
|
+
- **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))
|
package/README.md
CHANGED
|
@@ -513,7 +513,7 @@ The TUI uses three rendering strategies:
|
|
|
513
513
|
2. **Width Changed or Change Above Viewport**: Clear screen and full re-render
|
|
514
514
|
3. **Normal Update**: Move cursor to first changed line, clear to end, render changed lines
|
|
515
515
|
|
|
516
|
-
All updates are wrapped in **synchronized output** (`\x1b[?2026h` ... `\x1b[?2026l`) for atomic, flicker-free rendering.
|
|
516
|
+
All updates are wrapped in **synchronized output** (`\x1b[?2026h` ... `\x1b[?2026l`) for atomic, flicker-free rendering unless `PI_NO_SYNC_OUTPUT=1` is set. The opt-out removes only the DEC 2026 wrapper; paint writes still guard terminal autowrap to avoid pending-wrap cursor artifacts.
|
|
517
517
|
|
|
518
518
|
## Terminal Interface
|
|
519
519
|
|
|
@@ -16,7 +16,8 @@ export declare class TerminalInfo {
|
|
|
16
16
|
readonly trueColor: boolean;
|
|
17
17
|
readonly hyperlinks: boolean;
|
|
18
18
|
readonly notifyProtocol: NotifyProtocol;
|
|
19
|
-
|
|
19
|
+
readonly eagerEraseScrollbackRisk: boolean;
|
|
20
|
+
constructor(id: TerminalId, imageProtocol: ImageProtocol | null, trueColor: boolean, hyperlinks: boolean, notifyProtocol?: NotifyProtocol, eagerEraseScrollbackRisk?: boolean);
|
|
20
21
|
isImageLine(line: string): boolean;
|
|
21
22
|
formatNotification(message: string): string;
|
|
22
23
|
sendNotification(message: string): void;
|
|
@@ -28,6 +29,29 @@ export declare function isNotificationSuppressed(): boolean;
|
|
|
28
29
|
* Windows Terminal introduced SIXEL support in preview 1.22.
|
|
29
30
|
*/
|
|
30
31
|
export declare function isWindowsTerminalPreviewSixelSupported(env?: NodeJS.ProcessEnv, platform?: NodeJS.Platform): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Whether eager live-frame native scrollback rebuilds are unsafe when the
|
|
34
|
+
* terminal viewport position is unobservable.
|
|
35
|
+
*
|
|
36
|
+
* A TUI history rebuild emits xterm ED3 (`CSI 3 J`, erase saved lines). On the
|
|
37
|
+
* terminals below, ED3 can disturb a reader parked in native scrollback during
|
|
38
|
+
* streaming: kitty/ghostty/alacritty/VTE clamp the scroll offset back to the
|
|
39
|
+
* active tail when saved lines are erased. WezTerm, macOS Terminal.app, and
|
|
40
|
+
* iTerm2 expose scrollback-only clears via ED3/terminfo E3; that still
|
|
41
|
+
* invalidates a reader's scrollback position during live streaming.
|
|
42
|
+
*
|
|
43
|
+
* Windows Terminal erases its host scrollback on ED3 and repositions the
|
|
44
|
+
* viewport against the shortened buffer, so a scrolled-up reader is yanked.
|
|
45
|
+
* Native win32 is excluded here because the renderer guards it with dedicated
|
|
46
|
+
* platform checks (the viewport position is never observable on Windows — see
|
|
47
|
+
* `Terminal.isNativeViewportAtBottom`); a `WT_SESSION` sighting on any other
|
|
48
|
+
* platform means the outer host is Windows Terminal fronting a WSL distro (WT
|
|
49
|
+
* propagates the variable into the Linux environment), where the same ED3
|
|
50
|
+
* yank applies. See #1610.
|
|
51
|
+
*
|
|
52
|
+
* Pure helper for tests and `TERMINAL` trait construction. See #1682 and #1719.
|
|
53
|
+
*/
|
|
54
|
+
export declare function detectTerminalEagerEraseScrollbackRisk(env?: NodeJS.ProcessEnv, platform?: NodeJS.Platform): boolean;
|
|
31
55
|
export declare const TERMINAL_ID: TerminalId;
|
|
32
56
|
export declare const TERMINAL: TerminalInfo;
|
|
33
57
|
/**
|
package/dist/types/terminal.d.ts
CHANGED
|
@@ -30,6 +30,32 @@ export interface Terminal {
|
|
|
30
30
|
/**
|
|
31
31
|
* Returns whether the native terminal viewport is at the scrollback tail when
|
|
32
32
|
* the host exposes that state. `undefined` means the terminal cannot report it.
|
|
33
|
+
*
|
|
34
|
+
* `ProcessTerminal` deliberately does not implement this — no real terminal
|
|
35
|
+
* can answer it truthfully:
|
|
36
|
+
*
|
|
37
|
+
* - POSIX terminals expose no scrollback-position API at all.
|
|
38
|
+
* - Every modern Windows terminal host (Windows Terminal, VS Code, Tabby,
|
|
39
|
+
* Hyper, Alacritty, WezTerm, JetBrains, …) fronts console apps through
|
|
40
|
+
* ConPTY, where kernel32's `GetConsoleScreenBufferInfo` describes the
|
|
41
|
+
* pseudo-console buffer. That buffer is pinned to the visible grid —
|
|
42
|
+
* scrollback lives in the host UI, invisible to console APIs
|
|
43
|
+
* (microsoft/terminal#10191) — so a probe reads "at bottom" no matter
|
|
44
|
+
* where the user scrolled. Trusting it let streaming-time rebuilds emit
|
|
45
|
+
* `\x1b[3J` and yank scrolled readers: #1635 (Windows Terminal), #1746
|
|
46
|
+
* (Tabby and other ConPTY hosts). No env var distinguishes these hosts
|
|
47
|
+
* (Tabby sets none), so trust cannot be conditional on the environment.
|
|
48
|
+
* - Legacy conhost (the only non-ConPTY host) keeps a real scrollback
|
|
49
|
+
* buffer, but its window follows the output cursor: a probe comparing
|
|
50
|
+
* `srWindow.Bottom` against `dwSize.Y - 1` reads "scrolled up" for a user
|
|
51
|
+
* following live output until all ~9001 buffer rows fill, permanently
|
|
52
|
+
* blocking checkpoint scrollback reconciliation.
|
|
53
|
+
*
|
|
54
|
+
* The renderer treats a missing implementation / `undefined` as "unknown":
|
|
55
|
+
* live mutations defer destructive rebuilds and reconcile native scrollback
|
|
56
|
+
* at explicit checkpoints (prompt submit), where the user's keystroke has
|
|
57
|
+
* already pinned the host viewport to the bottom. Only test terminals
|
|
58
|
+
* (xterm.js-backed) implement this with a real answer.
|
|
33
59
|
*/
|
|
34
60
|
isNativeViewportAtBottom?(): boolean | undefined;
|
|
35
61
|
/**
|
|
@@ -41,21 +67,6 @@ export interface Terminal {
|
|
|
41
67
|
/** The last detected terminal appearance, or undefined if not yet known. */
|
|
42
68
|
get appearance(): TerminalAppearance | undefined;
|
|
43
69
|
}
|
|
44
|
-
/**
|
|
45
|
-
* Whether the native console viewport-position probe should be consulted.
|
|
46
|
-
*
|
|
47
|
-
* Returns `true` only on native Windows that is *not* fronted by Windows
|
|
48
|
-
* Terminal. The kernel32 `GetConsoleScreenBufferInfo` API answers about the
|
|
49
|
-
* ConPTY pseudo-console — which is always pinned to its tail — and not about
|
|
50
|
-
* the user-visible scrollback in modern hosts. Treat any such host as
|
|
51
|
-
* unreportable so the renderer falls back to the deferred-rebuild path.
|
|
52
|
-
*
|
|
53
|
-
* Pure helper for unit testing; the runtime call site reads `$env` /
|
|
54
|
-
* `process.platform`. See #1635.
|
|
55
|
-
*/
|
|
56
|
-
export declare function shouldTrustNativeViewportProbe(env?: {
|
|
57
|
-
WT_SESSION?: string | undefined;
|
|
58
|
-
}, platform?: NodeJS.Platform): boolean;
|
|
59
70
|
/**
|
|
60
71
|
* Real terminal using process.stdin/stdout
|
|
61
72
|
*/
|
|
@@ -65,20 +76,6 @@ export declare class ProcessTerminal implements Terminal {
|
|
|
65
76
|
get appearance(): TerminalAppearance | undefined;
|
|
66
77
|
onAppearanceChange(callback: (appearance: TerminalAppearance) => void): void;
|
|
67
78
|
start(onInput: (data: string) => void, onResize: () => void): void;
|
|
68
|
-
/**
|
|
69
|
-
* Returns true when Windows' active console viewport is at the scrollback tail.
|
|
70
|
-
* POSIX terminals do not expose native scrollback position through a standard API.
|
|
71
|
-
*
|
|
72
|
-
* On native Windows running under Windows Terminal (the default modern
|
|
73
|
-
* host), the `kernel32` probe answers about the ConPTY pseudo-console — not
|
|
74
|
-
* the user-visible WT viewport — so it would always read "at bottom" while
|
|
75
|
-
* the user is scrolled up. Return `undefined` there so the renderer falls
|
|
76
|
-
* back to the POSIX-style deferred-rebuild path: streaming mutations stay
|
|
77
|
-
* non-destructive (no `\x1b[3J`), and the rebuild fires at the next prompt
|
|
78
|
-
* checkpoint via {@link TUI.refreshNativeScrollbackIfDirty} where the user
|
|
79
|
-
* is already pinned to the bottom by the editor keystroke. See #1635.
|
|
80
|
-
*/
|
|
81
|
-
isNativeViewportAtBottom(): boolean | undefined;
|
|
82
79
|
drainInput(maxMs?: number, idleMs?: number): Promise<void>;
|
|
83
80
|
stop(): void;
|
|
84
81
|
write(data: string): void;
|
package/dist/types/tui.d.ts
CHANGED
|
@@ -171,9 +171,20 @@ export declare class TUI extends Container {
|
|
|
171
171
|
* non-destructive repaint. This trades the anti-yank guarantee for a clean,
|
|
172
172
|
* duplicate-free history and is meant for windows where output above the fold
|
|
173
173
|
* is actively re-rendering — e.g. a tool whose result is still streaming and
|
|
174
|
-
* re-laying-out rows that have already scrolled into history. A
|
|
175
|
-
*
|
|
176
|
-
* (
|
|
174
|
+
* re-laying-out rows that have already scrolled into history. A terminal that
|
|
175
|
+
* reports a *known*-scrolled viewport still defers, as does native Windows
|
|
176
|
+
* (the viewport is never observable there and ConPTY hosts erase host
|
|
177
|
+
* scrollback on ED3 — #1635/#1746); only the unknown POSIX case is forced to
|
|
178
|
+
* rebuild. POSIX hosts known to disturb scrolled readers on xterm ED3
|
|
179
|
+
* (`CSI 3 J`, erase saved lines) also defer the eager opt-in; checkpoint and
|
|
180
|
+
* direct user-input rebuilds are unaffected.
|
|
181
|
+
*
|
|
182
|
+
* Disabling does not take effect until the next frame has been classified:
|
|
183
|
+
* the event batch that ends a foreground stream both removes its UI rows
|
|
184
|
+
* (loader/status teardown — a shrink) and clears this flag before the
|
|
185
|
+
* throttled render timer fires. If the flag dropped immediately, that
|
|
186
|
+
* teardown frame would hit the ED3-risk idle deferral and freeze on screen
|
|
187
|
+
* (stale spinner) until the next keystroke.
|
|
177
188
|
*/
|
|
178
189
|
setEagerNativeScrollbackRebuild(enabled: boolean): void;
|
|
179
190
|
setFocus(component: Component | null): void;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/pi-tui",
|
|
4
|
-
"version": "15.
|
|
4
|
+
"version": "15.8.2",
|
|
5
5
|
"description": "Terminal User Interface library with differential rendering for efficient text-based applications",
|
|
6
6
|
"homepage": "https://omp.sh",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -37,8 +37,8 @@
|
|
|
37
37
|
"fmt": "biome format --write ."
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@oh-my-pi/pi-natives": "15.
|
|
41
|
-
"@oh-my-pi/pi-utils": "15.
|
|
40
|
+
"@oh-my-pi/pi-natives": "15.8.2",
|
|
41
|
+
"@oh-my-pi/pi-utils": "15.8.2",
|
|
42
42
|
"lru-cache": "11.5.1",
|
|
43
43
|
"marked": "^18.0.4"
|
|
44
44
|
},
|
|
@@ -146,22 +146,24 @@ const DEFAULT_COLOR_SWATCH_GLYPH = "■";
|
|
|
146
146
|
// entities like ☃ and paths like foo#fff) and not trailed by more hex
|
|
147
147
|
// (so over-long runs never produce a misleading swatch). Length/letter rules
|
|
148
148
|
// are enforced in classifyHexColor since the alternation can't express "exactly
|
|
149
|
-
// 3,
|
|
149
|
+
// 3, 6, or 8".
|
|
150
150
|
const HEX_COLOR_REGEX = /(?<![\w#&])#([0-9a-fA-F]{3,8})(?![0-9a-fA-F])/g;
|
|
151
151
|
const HEX_COLOR_EXACT_REGEX = /^#([0-9a-fA-F]{3,8})$/;
|
|
152
152
|
|
|
153
153
|
/**
|
|
154
154
|
* Decide whether a run of hex digits denotes a renderable CSS color.
|
|
155
155
|
*
|
|
156
|
-
* Only the canonical CSS lengths (#RGB, #
|
|
157
|
-
*
|
|
156
|
+
* Only the canonical CSS lengths (#RGB, #RRGGBB, #RRGGBBAA) qualify. The 4-digit
|
|
157
|
+
* #RGBA form is deliberately excluded: it collides with hashline `#TAG` snapshot
|
|
158
|
+
* tags (4 hex digits, e.g. #6C5E), which would otherwise sprout spurious swatches.
|
|
159
|
+
* In `strict` mode (bare prose) a 3-digit run must contain a hex letter, so the
|
|
158
160
|
* far more common short issue/PR references (#123, #1011) don't sprout swatches.
|
|
159
161
|
* Codespans opt out of strictness — the backticks already signal "this is a color".
|
|
160
162
|
*/
|
|
161
163
|
function classifyHexColor(hex: string, strict: boolean): boolean {
|
|
162
164
|
const n = hex.length;
|
|
163
|
-
if (n !== 3 && n !==
|
|
164
|
-
if (strict && n
|
|
165
|
+
if (n !== 3 && n !== 6 && n !== 8) return false;
|
|
166
|
+
if (strict && n === 3 && !/[a-fA-F]/.test(hex)) return false;
|
|
165
167
|
return true;
|
|
166
168
|
}
|
|
167
169
|
|