@linxiraos/pi-tui 1.4.0 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/CHANGELOG.md +178 -182
  2. package/dist/types/autocomplete.d.ts +6 -0
  3. package/dist/types/components/sparkline.d.ts +34 -0
  4. package/dist/types/index.d.ts +1 -0
  5. package/dist/types/native/describe.d.ts +7 -1
  6. package/dist/types/native/overlay.d.ts +2 -0
  7. package/dist/types/native/tone.d.ts +2 -0
  8. package/dist/types/overlays/agent-hub.d.ts +3 -3
  9. package/dist/types/overlays/approval-dialog.d.ts +15 -1
  10. package/dist/types/overlays/jobs-panel.d.ts +3 -0
  11. package/dist/types/overlays/model-browser.d.ts +1 -1
  12. package/dist/types/render/output-block.d.ts +2 -0
  13. package/dist/types/render/tool-card.d.ts +2 -0
  14. package/dist/types/sixel.d.ts +28 -0
  15. package/dist/types/status-line/host.d.ts +3 -0
  16. package/dist/types/terminal-capabilities.d.ts +5 -0
  17. package/dist/types/tools/bash.d.ts +2 -0
  18. package/dist/types/tools/default-renderer.d.ts +3 -0
  19. package/dist/types/tools/eval.d.ts +9 -8
  20. package/dist/types/tools/irc.d.ts +6 -0
  21. package/dist/types/tools/job-widget.d.ts +226 -0
  22. package/dist/types/tools/json-tree.d.ts +2 -0
  23. package/dist/types/tools/line-ranges.d.ts +8 -1
  24. package/dist/types/tools/mcp.d.ts +23 -0
  25. package/dist/types/tools/output-meta.d.ts +1 -1
  26. package/dist/types/tools/read.d.ts +8 -2
  27. package/dist/types/tools/renderer.d.ts +8 -2
  28. package/dist/types/tools/result-card.d.ts +1 -1
  29. package/dist/types/tools/streaming-output.d.ts +1 -0
  30. package/dist/types/tools/task.d.ts +12 -0
  31. package/dist/types/tools/wait.d.ts +5 -0
  32. package/package.json +9 -9
  33. package/src/autocomplete.d.ts +6 -0
  34. package/src/autocomplete.ts +21 -6
  35. package/src/chat/skill-message.ts +16 -17
  36. package/src/chat/tool-execution.ts +35 -0
  37. package/src/chrome/transcript-container.ts +85 -13
  38. package/src/components/editor.ts +17 -7
  39. package/src/components/image.ts +5 -4
  40. package/src/components/markdown.ts +11 -3
  41. package/src/components/sparkline.d.ts +34 -0
  42. package/src/components/sparkline.ts +89 -0
  43. package/src/index.d.ts +1 -0
  44. package/src/index.ts +1 -0
  45. package/src/native/backend.ts +32 -6
  46. package/src/native/describe.d.ts +7 -1
  47. package/src/native/describe.ts +18 -1
  48. package/src/native/overlay.d.ts +2 -0
  49. package/src/native/overlay.ts +3 -0
  50. package/src/native/tone.d.ts +2 -0
  51. package/src/native/tone.ts +22 -0
  52. package/src/overlays/agent-hub.ts +14 -10
  53. package/src/overlays/agent-transcript-viewer.ts +2 -2
  54. package/src/overlays/agents-hub.ts +2 -1
  55. package/src/overlays/approval-dialog.ts +59 -13
  56. package/src/overlays/hub-frame.ts +2 -1
  57. package/src/overlays/jobs-panel.ts +24 -2
  58. package/src/overlays/model-browser.ts +3 -0
  59. package/src/overlays/model-hub.ts +2 -1
  60. package/src/prompt/attachment-chips.ts +1 -1
  61. package/src/render/output-block.d.ts +2 -0
  62. package/src/render/output-block.ts +25 -12
  63. package/src/render/tool-card.d.ts +2 -0
  64. package/src/render/tool-card.ts +6 -0
  65. package/src/sixel.d.ts +28 -0
  66. package/src/sixel.ts +185 -0
  67. package/src/status-line/component.ts +19 -2
  68. package/src/status-line/host.ts +3 -0
  69. package/src/terminal-capabilities.d.ts +5 -0
  70. package/src/terminal-capabilities.ts +43 -3
  71. package/src/theme/symbols.ts +5 -3
  72. package/src/tools/bash.d.ts +2 -0
  73. package/src/tools/bash.ts +25 -9
  74. package/src/tools/default-renderer.d.ts +3 -0
  75. package/src/tools/default-renderer.ts +54 -17
  76. package/src/tools/eval.d.ts +9 -8
  77. package/src/tools/eval.ts +32 -14
  78. package/src/tools/find.ts +4 -5
  79. package/src/tools/glob.ts +4 -6
  80. package/src/tools/grep.ts +2 -4
  81. package/src/tools/irc.d.ts +6 -0
  82. package/src/tools/irc.ts +6 -0
  83. package/src/tools/job-widget.d.ts +226 -0
  84. package/src/tools/job-widget.ts +1036 -0
  85. package/src/tools/json-tree.d.ts +2 -0
  86. package/src/tools/json-tree.ts +8 -0
  87. package/src/tools/line-ranges.d.ts +8 -1
  88. package/src/tools/line-ranges.ts +23 -13
  89. package/src/tools/mcp.d.ts +23 -0
  90. package/src/tools/mcp.ts +44 -1
  91. package/src/tools/output-meta.d.ts +1 -1
  92. package/src/tools/output-meta.ts +1 -1
  93. package/src/tools/read.d.ts +8 -2
  94. package/src/tools/read.ts +64 -21
  95. package/src/tools/renderer.d.ts +8 -2
  96. package/src/tools/renderer.ts +8 -2
  97. package/src/tools/result-card.d.ts +1 -1
  98. package/src/tools/result-card.ts +1 -2
  99. package/src/tools/streaming-output.d.ts +1 -0
  100. package/src/tools/streaming-output.ts +11 -9
  101. package/src/tools/task.d.ts +12 -0
  102. package/src/tools/task.ts +25 -1
  103. package/src/tools/wait.d.ts +5 -0
  104. package/src/tools/wait.ts +290 -147
  105. package/src/tui.ts +45 -5
package/CHANGELOG.md CHANGED
@@ -1,8 +1,180 @@
1
1
  ## [Unreleased]
2
2
 
3
- ## [1.4.0] - 2026-10-21
3
+ ## [1.4.1] - 2026-10-23
4
4
 
5
- - Added a `zetawork` terminal id that resolves to the Kitty image protocol from the environment alone, so images render in the desktop app's own terminal
5
+ - An attached TUI renders the backend's builtin-command output (`command_output`) in its status line and keeps client-only commands, pickers and mirrored switches local
6
+
7
+ ### Breaking Changes
8
+
9
+ - Removed `KeyEventType` export from public API
10
+ - `Editor` constructor now requires `TUI` as first parameter: `new Editor(tui, theme)`. This enables automatic vertical scrolling when content exceeds terminal height. ([#732](https://github.com/badlogic/pi-mono/issues/732))
11
+ - Removed `Key` helper object from public API; use string literals like `"ctrl+c"` instead of `Key.ctrl("c")`
12
+
13
+ ### Added
14
+
15
+ - Added `symbols` property to `EditorTheme`, `MarkdownTheme`, and `SelectListTheme` interfaces for component-level symbol customization
16
+ - Overlay compositing via `TUI.showOverlay()` and `TUI.hideOverlay()` for `ctx.ui.custom()` with `{ overlay: true }`
17
+ - Kitty keyboard protocol flag 2 support for key release events (`isKeyRelease()`, `isKeyRepeat()`, `KeyEventType`)
18
+ - `setKittyProtocolActive()`, `isKittyProtocolActive()` for Kitty protocol state management
19
+ - `kittyProtocolActive` property on Terminal interface to query Kitty protocol state
20
+ - `Component.wantsKeyRelease` property to opt-in to key release events (default false)
21
+ - Input component `onEscape` callback for handling escape key presses
22
+ - Emergency terminal restore to prevent corrupted state on crashes
23
+ - Overhauled UI with welcome screen and powerline footer
24
+ - Theme-configurable HTML export colors
25
+ - `ctx.ui.theme` getter for styling status text with theme colors
26
+ - Added `PI_TUI_WRITE_LOG` environment variable to capture raw ANSI output for debugging
27
+ - Added legacy Alt+letter handling and Alt+D delete word forward support in the editor keymap. ([#810](https://github.com/badlogic/pi-mono/pull/810) by [@Perlence](https://github.com/Perlence))
28
+ - `showOverlay()` now returns `OverlayHandle` with `hide()`, `setHidden(boolean)`, `isHidden()` for programmatic visibility control ([#667](https://github.com/badlogic/pi-mono/pull/667) by [@nicobailon](https://github.com/nicobailon))
29
+ - New exported types: `OverlayAnchor`, `OverlayHandle`, `OverlayMargin`, `OverlayOptions`, `SizeValue` ([#667](https://github.com/badlogic/pi-mono/pull/667) by [@nicobailon](https://github.com/nicobailon))
30
+ - `truncateToWidth()` now accepts optional `pad` parameter to pad result with spaces to exactly `maxWidth` ([#667](https://github.com/badlogic/pi-mono/pull/667) by [@nicobailon](https://github.com/nicobailon))
31
+ - **Experimental:** Overlay compositing for `ctx.ui.custom()` with `{ overlay: true }` option ([#558](https://github.com/badlogic/pi-mono/pull/558) by [@nicobailon](https://github.com/nicobailon))
32
+ - `EditorComponent` interface for custom editor implementations
33
+ - `StdinBuffer` class to split batched stdin into individual sequences (adapted from [OpenTUI](https://github.com/anomalyco/opentui), MIT license)
34
+ - `Editor.getExpandedText()` method that returns text with paste markers expanded to their actual content ([#444](https://github.com/badlogic/pi-mono/pull/444) by [@aliou](https://github.com/aliou))
35
+ - Added mermaid block extraction and deduplication utilities (extractMermaidBlocks)
36
+ - Added `Alt+Delete` as a delete-word-forward shortcut
37
+ - Added configurable code block indentation for Markdown rendering
38
+ - Added undo support in the editor via `Ctrl+-`.
39
+ - Added configurable code block indentation for Markdown rendering.
40
+ - Added `Alt+Delete` as a delete-word-forward shortcut.
41
+ - Added `isPageUp()` and `isPageDown()` helper functions
42
+ - Added `SizeValue` type for CSS-like overlay sizing (absolute or percentage strings like `"50%"`)
43
+ - Added `OverlayHandle` interface with `hide()`, `setHidden()`, `isHidden()` methods for overlay visibility control
44
+ - Added `visible` callback to `OverlayOptions` for dynamic visibility based on terminal dimensions
45
+ - Added `pad` parameter to `truncateToWidth()` for padding result with spaces to exact width
46
+ - `StdinBuffer` class to split batched stdin into individual sequences
47
+ - Added `isCtrlY` helper function for detecting Ctrl+Y keyboard input
48
+ - Added configurable editor keybindings with typed key identifiers and action matching
49
+ - Added word-wrapped editor rendering for long lines
50
+ - Added `getText()` method to Text component for retrieving current text content
51
+ - Added `fullRedraws` readonly property to TUI class for tracking full screen redraws
52
+ - Added `showHardwareCursor` getter and setter to control cursor visibility while keeping IME positioning active. ([#800](https://github.com/badlogic/pi-mono/pull/800) by [@ghoulr](https://github.com/ghoulr))
53
+ - Added Emacs-style kill ring editing with yank and yank-pop keybindings. ([#810](https://github.com/badlogic/pi-mono/pull/810) by [@Perlence](https://github.com/Perlence))
54
+ - `EditorOptions` with optional `paddingX` for horizontal content padding, plus `getPaddingX()`/`setPaddingX()` methods ([#791](https://github.com/badlogic/pi-mono/pull/791) by [@ferologics](https://github.com/ferologics))
55
+ - Expanded keymap coverage for terminal compatibility: added support for Home/End keys in tmux, additional modifier combinations, and improved key sequence parsing ([#752](https://github.com/badlogic/pi-mono/pull/752) by [@richardgill](https://github.com/richardgill))
56
+ - `OverlayOptions.visible` callback for responsive overlays - receives terminal dimensions, return false to hide ([#667](https://github.com/badlogic/pi-mono/pull/667) by [@nicobailon](https://github.com/nicobailon))
57
+ - `pageUp` and `pageDown` key support with `selectPageUp`/`selectPageDown` editor actions ([#662](https://github.com/badlogic/pi-mono/pull/662) by [@aliou](https://github.com/aliou))
58
+ - `fuzzyFilter()` and `fuzzyMatch()` utilities for fuzzy text matching
59
+ - Slash command autocomplete now uses fuzzy matching instead of prefix matching
60
+ - Added setAutocompleteMaxVisible() configuration (3-20 items)
61
+ - Added image detection to terminal capabilities (containsImage method)
62
+ - Added stdin monitoring to detect stalled input events and log warnings
63
+ - Added `pageUp` and `pageDown` key support with `selectPageUp`/`selectPageDown` editor actions
64
+ - Add `getExpandedText()` to editor for expanding paste markers
65
+ - Added `SymbolTheme` interface for customizing UI symbols including cursors, borders, spinners, and box-drawing characters
66
+ - Added support for custom spinner frames in the Loader component
67
+ - Added `setTopBorder()` method to Editor component for displaying custom status content in the top border
68
+ - Added `getWidth()` method to TUI class for retrieving terminal width
69
+ - Added rounded corner box-drawing characters to Editor component borders
70
+ - Added legacy terminal support for Ctrl+symbol keys (Ctrl+\, Ctrl+], Ctrl+-) and their Ctrl+Alt variants. ([#831](https://github.com/badlogic/pi-mono/pull/831) by [@Perlence](https://github.com/Perlence))
71
+ - Kitty keyboard protocol flag 2 support for key release events. New exports: `isKeyRelease(data)`, `isKeyRepeat(data)`, `KeyEventType` type. Terminals supporting Kitty protocol (Kitty, Ghostty, WezTerm) now send proper key-up events.
72
+ - `SettingsListOptions` with `enableSearch` for fuzzy filtering in `SettingsList` ([#643](https://github.com/badlogic/pi-mono/pull/643) by [@ninlds](https://github.com/ninlds))
73
+ - `Editor.insertTextAtCursor(text)` method for programmatic text insertion ([#419](https://github.com/badlogic/pi-mono/issues/419))
74
+ - `EditorKeybindingsManager` for configurable editor keybindings. Components now use `matchesKey()` and keybindings manager instead of individual `isXxx()` functions. ([#405](https://github.com/badlogic/pi-mono/pull/405) by [@hjanuschka](https://github.com/hjanuschka))
75
+
76
+ ### Changed
77
+
78
+ - `UserMessageComponent`'s native hover toolbar (`zeta.user.tools`) leads with Copy and Rewind icon buttons (`copy`, `rewind`) instead of text labels, then a dot and the time, like the turn usage footer
79
+ - `ContextUsageView`'s native body (on terminals with `meter`) leads with the tokens used and the room left before auto-compaction, then one stacked bar ticked at the threshold, the breakdown as rows (`zeta.context.cat`, `.cat.free`, `.cat.buffer`: swatch, name, tokens, share; the exact count in the row's `title`) and the snapcompact estimate as labelled rows (`zeta.context.snap`); the blocks meter and legend `kv` are gone, and `contextUsageHead` no longer repeats the window size
80
+ - `AskDialogComponent`'s native root is `zeta.editor.ask` (collapsed: `zeta.editor.ask.hidden`, the countdown, the question as `zeta.ask.summary`, Skip and Show): a chosen answer is the `accent`-toned row (a check also carries the check icon) instead of the highlighted one; multi-select Other… is `zeta.ask.other.check`; the question tabs check answered questions and say their keys in the strip's `title`; the countdown moves from the head to the action bar beside Hide; the preview is `zeta.ask.preview`; the Review tab leads with `zeta.ask.notice` and lists answers (`zeta.ask.answers`) by question name with inline code mono and no `(Recommended)` suffix; option descriptions run inline code mono, notes ride the row's detail as `em`; Submit/Next's tooltip names only Enter (and Space on a multi-select)
81
+ - `MCPAddWizard`'s native sheet asks one question per step: a phase strip (`zeta.mcpAdd.progress` of `zeta.mcpAdd.phase`, toned done/current/upcoming and `neutral` when no auth was needed), the question and its lead (`zeta.mcpAdd.title`, `zeta.mcpAdd.tag` for optional fields, `zeta.mcpAdd.lead`), then a mono field with a placeholder and its rule or refusal (`zeta.mcpAdd.field`, `tone: "error"`; `zeta.mcpAdd.note`), choice rows with icons and mono tags (`zeta.mcpAdd.choices`), status lines (`zeta.mcpAdd.status`, `zeta.mcpAdd.checks`, `zeta.mcpAdd.error`) or the review rows (`zeta.mcpAdd.summary`). Cancel, Back and Continue / Save server buttons run Ctrl+C, Esc and Enter instead of a key-hint strip. The connection test shows its own busy step, the OAuth client secret field is masked, and the review saves on Enter (no Yes/No choice)
82
+ - `ReportPanel`'s native body carries the role `zeta.report.body`
83
+ - `HookInputComponent` describes a dock sheet (`zeta.overlay.hook-input` col) like `HookEditorComponent`'s: the title's first line (`zeta.hook-input.title`, the countdown as `zeta.hook-input.timer`) over its further lines (`zeta.hook-input.detail`), the field (`zeta.hook-input.field`, `tone: "error"` while a submit was refused) with its placeholder, and Cancel / Submit buttons that run Esc / Enter; the key legend under the field is terminal-only
84
+ - `JobsSheet`'s native body is a master–detail split (`zeta.jobs.split`: `zeta.jobs.master` | `zeta.jobs.detail`): the job list grouped Running / Recent (`zeta.jobs.group` labels), each row a type icon tinted by status with its duration, beside the selected job's status pill, live elapsed and Cancel job (`zeta.jobs.status`), its task title or command (`zeta.jobs.title` / `zeta.jobs.command`), facts (`zeta.jobs.facts`: agent, directory, pids, exit code, artifact) and output (`zeta.jobs.out`, `zeta.jobs.nooutput`); the footer counts running and recent jobs (`zeta.jobs.summary`), and no jobs shows an empty state (`zeta.jobs.empty`). Task jobs no longer draw an `agent` node here
85
+ - `BtwHistoryPanel`'s native sheet is centered and reads like a mail reader: the questions as two-line rows (`zeta.btw.history`, list `zeta.btw.list` / `zeta.btw.list.idle` while the answer has the keys) beside the selected thread (`zeta.btw.reader` › `zeta.btw.thread` › `zeta.btw.turn`: `zeta.btw.question` / `zeta.btw.followup`, `zeta.btw.meta`, `zeta.btw.answer`, `zeta.btw.error`), the follow-up field under the last answer (`zeta.btw.composer`), and footer buttons Stop answer, Copy answer, Close and Follow up (Cancel and Send while composing) in place of the focus labels and key-hint strip; an empty history is an `md` sheet (`zeta.btw.empty`)
86
+ - The `wait` tool's native job rows (`zeta.wait.job`) are a single `row`: badge, id and label, progress and clock, without the output preview or capture notice beneath
87
+ - The native bash run foot reads In background with a live clock (`zeta.run.time` without `stopped`) while a parked job's frames stream (`details.async.state === "running"`, partial), instead of Running
88
+ - Moved `wrapTextWithAnsi` export to `@linxiraos/pi-natives` package
89
+ - Default editor `newLine` binding now uses `shift+enter` only
90
+ - Hardware cursor is now disabled by default for better terminal compatibility. Set `PI_HARDWARE_CURSOR=1` to enable (replaces `PI_NO_HARDWARE_CURSOR=1` which disabled it).
91
+ - Migrated key parsing and matching logic to native implementation for improved performance
92
+ - Simplified `isKeyRelease()` and `isKeyRepeat()` to use regex pattern matching instead of string inclusion checks
93
+ - Refactored `visibleWidth` function to use caching wrapper around new `visibleWidthRaw` implementation for improved performance
94
+ - Improved performance of key ID parsing with optimized cache lookup strategy
95
+ - Simplified `visibleWidth` calculation to use consistent Bun.stringWidth approach for all string lengths
96
+ - Replaced external `fd` binary with native fuzzy path search for `@`-prefixed autocomplete
97
+ - Restructured terminal capabilities from interface-based to class-based model
98
+ - Improved table column width calculation with word-aware wrapping
99
+ - Refactored text utilities to use native WASM implementations for strings >256 chars with JS fast path
100
+ - Added Ctrl+Backspace as a delete-word-backward keybinding and improved modified backspace matching
101
+ - Migrated file system operations from synchronous to asynchronous APIs in autocomplete provider for non-blocking I/O
102
+ - Migrated node module imports from named to namespace imports across all packages for consistency with project guidelines
103
+ - Normalized keybinding definitions to lowercase internally
104
+ - Improved fuzzy matching to handle alphanumeric swaps.
105
+ - Normalized keybinding definitions to lowercase internally.
106
+ - Changed `showOverlay()` to return `OverlayHandle` for controlling overlay visibility
107
+ - Removed `widthPercent`, `maxHeightPercent`, `rowPercent`, `colPercent` from `OverlayOptions` (use percentage strings instead)
108
+ - Improved file autocomplete to show directory listing when typing `@` with no query, and fall back to prefix matching when fuzzy search returns no results
109
+ - Terminal startup now queries Kitty protocol support before enabling event reporting
110
+ - Changed cursor style from block to thin blinking bar (▏) at end of line
111
+ - Editor component now uses word wrapping instead of character-level wrapping for better readability ([#382](https://github.com/badlogic/pi-mono/pull/382) by [@nickseelert](https://github.com/nickseelert))
112
+ - Renamed `EllipsisKind` enum to `Ellipsis` for clearer API naming
113
+ - Changed hardcoded ellipsis character from theme-configurable to literal "…" in editor truncation
114
+ - Improved blockquote rendering with text wrapping in Markdown component
115
+ - Expanded Kitty keyboard protocol coverage for non-Latin layouts and legacy Alt sequences
116
+ - Improved cursor positioning with safer bounds checking
117
+ - Updated editor layout to respect configurable padding
118
+ - Refactored scrolling logic for better viewport management
119
+ - Key detection refactored: consolidated `is*()` functions into generic `matchesKey(data, keyId)` function that accepts key identifiers like `"ctrl+c"`, `"shift+enter"`, `"alt+left"`, etc.
120
+
121
+ ### Fixed
122
+
123
+ - Fixed width overflow protection in overlay compositing to prevent TUI crashes
124
+ - Key presses no longer dropped when batched with other events over SSH
125
+ - Fixed `fd` tool detection to automatically find `fd` or `fdfind` in PATH when not explicitly configured
126
+ - Fixed editor multi-line insertion handling and lastAction tracking ([#945](https://github.com/badlogic/pi-mono/pull/945) by [@Perlence](https://github.com/Perlence))
127
+ - Fixed editor word wrapping to reserve a cursor column ([#934](https://github.com/badlogic/pi-mono/pull/934) by [@Perlence](https://github.com/Perlence))
128
+ - Fixed editor word wrapping to use single-pass backtracking for whitespace handling ([#924](https://github.com/badlogic/pi-mono/pull/924) by [@Perlence](https://github.com/Perlence))
129
+ - Fixed Kitty image ID allocation and cleanup to prevent image ID collisions between modules
130
+ - Fixed viewport tracking and cursor positioning for overlays and content shrink scenarios
131
+ - Autocomplete now allows searches with `/` characters (e.g., `folder1/folder2`) ([#882](https://github.com/badlogic/pi-mono/pull/882) by [@richardgill](https://github.com/richardgill))
132
+ - Directory completions for `@` file attachments no longer add trailing space, allowing continued autocomplete into subdirectories
133
+ - `visibleWidth()` and `extractAnsiCode()` now handle APC escape sequences (`ESC _ ... BEL`), fixing width calculation and string slicing for strings containing cursor markers
134
+ - SelectList now handles multi-line descriptions by replacing newlines with spaces ([#728](https://github.com/badlogic/pi-mono/pull/728) by [@richardgill](https://github.com/richardgill))
135
+ - Reset ANSI styles after each rendered line to prevent style leakage
136
+ - Cursor position tracking when content shrinks with unchanged remaining lines
137
+ - TUI renders with wrong dimensions after suspend/resume if terminal was resized while suspended ([#599](https://github.com/badlogic/pi-mono/issues/599))
138
+ - Pasted content containing Kitty key release patterns (e.g., `:3F` in MAC addresses) was incorrectly filtered out ([#623](https://github.com/badlogic/pi-mono/pull/623) by [@ogulcancelik](https://github.com/ogulcancelik))
139
+ - `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))
140
+
141
+ Older entries are archived in [packages/tui/CHANGELOG.md@9caccab691ce](https://github.com/can1357/oh-my-pi/blob/9caccab691ce575007f4b6bcbaf8f944723d5457/packages/tui/CHANGELOG.md).
142
+ Older entries are archived in [packages/tui/CHANGELOG.md@58141d4e5fa8](https://github.com/can1357/oh-my-pi/blob/58141d4e5fa892166024e2168866c45e0baacde3/packages/tui/CHANGELOG.md).
143
+ - Corrected editor end-of-line cursor rendering assertion to use includes() instead of endsWith()
144
+ - Fixed potential errors during emergency terminal restore when terminal is already dead
145
+ - Fixed autocomplete race condition by tracking request ID to prevent stale suggestion results
146
+ - Added legacy terminal support for `Ctrl+` symbol key combinations
147
+ - Added legacy terminal support for `Ctrl+` symbol key combinations.
148
+ - Fixed backspace handling with additional codepoint support
149
+ - Fixed Alt+letter key combinations for better recognition
150
+ - TUI now filters out key release events by default, preventing double-processing of keys
151
+ - `matchesKey()` now correctly matches Kitty protocol sequences for unmodified letter keys
152
+ - Crash when pasting text with trailing whitespace exceeding terminal width through Markdown rendering
153
+ - Slash command menu now only triggers when the editor input is otherwise empty ([#904](https://github.com/badlogic/pi-mono/issues/904))
154
+ - Center-anchored overlays now stay vertically centered when resizing the terminal taller after a shrink ([#950](https://github.com/badlogic/pi-mono/pull/950) by [@nicobailon](https://github.com/nicobailon))
155
+ - Shift+Space, Shift+Backspace, and Shift+Delete now work correctly in Kitty-protocol terminals (Kitty, WezTerm, etc.) instead of being silently ignored ([#411](https://github.com/badlogic/pi-mono/pull/411) by [@nathyong](https://github.com/nathyong))
156
+ - Improved Kitty terminal key sequence parsing to correctly handle text field codepoints in CSI-u sequences
157
+ - Fixed handling of private use Unicode codepoints (U+E000 to U+F8FF) in Kitty key decoding to prevent invalid character interpretation
158
+ - Simplified terminal write error handling to mark terminal as dead on any write failure
159
+ - Fixed multi-line strings in renderOutputBlock causing width overflow
160
+ - Fixed slash command autocomplete applying stale completion when typing quickly
161
+ - Reserved cursor space for zero padding and corrected end-of-line cursor rendering to prevent wrap glitches
162
+ - Fixed viewport tracking after partial renders to prevent autocomplete list artifacts
163
+ - Rendering optimizations: only re-render changed lines
164
+ - Refactor input component to use keybindings manager
165
+ - Fixed editor cursor blinking by allowing terminal cursor positioning when enabled.
166
+ - Editor no longer corrupts terminal display when text exceeds screen height. Content now scrolls vertically with indicators showing lines above/below the viewport. Max height is 30% of terminal (minimum 5 lines). ([#732](https://github.com/badlogic/pi-mono/issues/732))
167
+ - Cursor now moves to end of content on exit, preventing status line from being overwritten ([#629](https://github.com/badlogic/pi-mono/pull/629) by [@tallshort](https://github.com/tallshort))
168
+ - Slash command autocomplete now triggers for commands starting with `.`, `-`, or `_` (e.g., `/.land`, `/-foo`) ([#422](https://github.com/badlogic/pi-mono/issues/422))
169
+
170
+ ### Removed
171
+
172
+ - The welcome/splash brand art is now generated with the standard FIGlet tool instead of being drawn by hand: `ZETA_LOGO` renders the mark `Z` (the ASCII form of `Ζ`), `ZETA_WORDMARK` renders `Zeta` (both in the standard `ANSI Shadow` font) and `ZETA_SUBLINE` renders the `Linxira-Zeta` identity line in `mini`, with the version under the wordmark. `bun scripts/brand/generate-logo-art.ts` regenerates the three constants from the vendored fonts, and the brand guard fails on any hand-edited glyph.
173
+ - Removed `ellipsis` property from `SymbolTheme` interface
174
+ - Removed `extractAnsiCode` function from public API
175
+ - Removed TUI layout engine exports from public API (BoxNode, ColumnNode, LayoutNode, etc.)
176
+ - Removed `visibleWidth` benchmark file in favor of Kitty sequence benchmarking
177
+ - Removed `truncateToWidth`, `sliceWithWidth`, and `extractSegments` functions from public API (now re-exported directly from @linxiraos/pi-natives)
6
178
 
7
179
  ## [9.5.0] - 2026-02-01
8
180
 
@@ -93,7 +265,6 @@
93
265
  ### Fixed
94
266
 
95
267
  - Fixed numbered list items showing "1." for all items when code blocks break list continuity
96
- - Fixed width overflow protection in overlay compositing to prevent TUI crashes
97
268
 
98
269
  ## [4.6.0] - 2026-01-12
99
270
 
@@ -124,10 +295,6 @@
124
295
 
125
296
  - `EditorComponent` interface for custom editor implementations
126
297
 
127
- ### Fixed
128
-
129
- - Key presses no longer dropped when batched with other events over SSH
130
-
131
298
  ## [3.32.0] - 2026-01-08
132
299
 
133
300
  ### Fixed
@@ -153,7 +320,6 @@
153
320
  ### Added
154
321
 
155
322
  - Added `inputCursor` symbol for customizing the text input cursor character
156
- - Added `symbols` property to `EditorTheme`, `MarkdownTheme`, and `SelectListTheme` interfaces for component-level symbol customization
157
323
 
158
324
  ## [3.9.1337] - 2026-01-04
159
325
 
@@ -187,123 +353,21 @@
187
353
 
188
354
  Initial release under @oh-my-pi scope. See previous releases at [badlogic/pi-mono](https://github.com/badlogic/pi-mono).
189
355
 
356
+ ## [1.4.0] - 2026-10-21
357
+
358
+ - Added a `zetawork` terminal id that resolves to the Kitty image protocol from the environment alone, so images render in the desktop app's own terminal
359
+
190
360
  ## [1.3.2] - 2026-10-19
191
361
 
192
362
  - Version line moves to 1.3.2 with the rest of the suite; no user-visible change in this package.
193
363
 
194
364
  ## [1.3.1] - 2026-10-19
195
365
 
196
- ### Breaking Changes
197
-
198
- - Removed `KeyEventType` export from public API
199
- - `Editor` constructor now requires `TUI` as first parameter: `new Editor(tui, theme)`. This enables automatic vertical scrolling when content exceeds terminal height. ([#732](https://github.com/badlogic/pi-mono/issues/732))
200
- - Removed `Key` helper object from public API; use string literals like `"ctrl+c"` instead of `Key.ctrl("c")`
201
-
202
366
  ### Added
203
367
 
204
368
  - Added `ComposerPreferences.completeScrollback` (default `false`): rows a growing HUD or dialog pushes off screen go straight to scrollback instead of being held back until it shrinks ([#15692](https://github.com/can1357/oh-my-pi/pull/15692) by [@Ilm-Alan](https://github.com/Ilm-Alan))
205
369
  - `AssistantMessageComponent`'s native turn footer leads with a Copy icon (`zeta.turn.copy`) and a dot instead of the clock icon; it copies the answer's text and shows when the host handles transcript actions
206
370
  - Add backslash+enter newline fallback for terminals without Kitty protocol
207
- - Overlay compositing via `TUI.showOverlay()` and `TUI.hideOverlay()` for `ctx.ui.custom()` with `{ overlay: true }`
208
- - Kitty keyboard protocol flag 2 support for key release events (`isKeyRelease()`, `isKeyRepeat()`, `KeyEventType`)
209
- - `setKittyProtocolActive()`, `isKittyProtocolActive()` for Kitty protocol state management
210
- - `kittyProtocolActive` property on Terminal interface to query Kitty protocol state
211
- - `Component.wantsKeyRelease` property to opt-in to key release events (default false)
212
- - Input component `onEscape` callback for handling escape key presses
213
- - Emergency terminal restore to prevent corrupted state on crashes
214
- - Overhauled UI with welcome screen and powerline footer
215
- - Theme-configurable HTML export colors
216
- - `ctx.ui.theme` getter for styling status text with theme colors
217
- - Added `PI_TUI_WRITE_LOG` environment variable to capture raw ANSI output for debugging
218
- - Added legacy Alt+letter handling and Alt+D delete word forward support in the editor keymap. ([#810](https://github.com/badlogic/pi-mono/pull/810) by [@Perlence](https://github.com/Perlence))
219
- - `showOverlay()` now returns `OverlayHandle` with `hide()`, `setHidden(boolean)`, `isHidden()` for programmatic visibility control ([#667](https://github.com/badlogic/pi-mono/pull/667) by [@nicobailon](https://github.com/nicobailon))
220
- - New exported types: `OverlayAnchor`, `OverlayHandle`, `OverlayMargin`, `OverlayOptions`, `SizeValue` ([#667](https://github.com/badlogic/pi-mono/pull/667) by [@nicobailon](https://github.com/nicobailon))
221
- - `truncateToWidth()` now accepts optional `pad` parameter to pad result with spaces to exactly `maxWidth` ([#667](https://github.com/badlogic/pi-mono/pull/667) by [@nicobailon](https://github.com/nicobailon))
222
- - **Experimental:** Overlay compositing for `ctx.ui.custom()` with `{ overlay: true }` option ([#558](https://github.com/badlogic/pi-mono/pull/558) by [@nicobailon](https://github.com/nicobailon))
223
- - `EditorComponent` interface for custom editor implementations
224
- - `StdinBuffer` class to split batched stdin into individual sequences (adapted from [OpenTUI](https://github.com/anomalyco/opentui), MIT license)
225
- - `Editor.getExpandedText()` method that returns text with paste markers expanded to their actual content ([#444](https://github.com/badlogic/pi-mono/pull/444) by [@aliou](https://github.com/aliou))
226
- - Added mermaid block extraction and deduplication utilities (extractMermaidBlocks)
227
- - Added `Alt+Delete` as a delete-word-forward shortcut
228
- - Added configurable code block indentation for Markdown rendering
229
- - Added undo support in the editor via `Ctrl+-`.
230
- - Added configurable code block indentation for Markdown rendering.
231
- - Added `Alt+Delete` as a delete-word-forward shortcut.
232
- - Added `isPageUp()` and `isPageDown()` helper functions
233
- - Added `SizeValue` type for CSS-like overlay sizing (absolute or percentage strings like `"50%"`)
234
- - Added `OverlayHandle` interface with `hide()`, `setHidden()`, `isHidden()` methods for overlay visibility control
235
- - Added `visible` callback to `OverlayOptions` for dynamic visibility based on terminal dimensions
236
- - Added `pad` parameter to `truncateToWidth()` for padding result with spaces to exact width
237
- - `StdinBuffer` class to split batched stdin into individual sequences
238
- - Added `isCtrlY` helper function for detecting Ctrl+Y keyboard input
239
- - Added configurable editor keybindings with typed key identifiers and action matching
240
- - Added word-wrapped editor rendering for long lines
241
- - Added `getText()` method to Text component for retrieving current text content
242
- - Added `fullRedraws` readonly property to TUI class for tracking full screen redraws
243
- - Added `showHardwareCursor` getter and setter to control cursor visibility while keeping IME positioning active. ([#800](https://github.com/badlogic/pi-mono/pull/800) by [@ghoulr](https://github.com/ghoulr))
244
- - Added Emacs-style kill ring editing with yank and yank-pop keybindings. ([#810](https://github.com/badlogic/pi-mono/pull/810) by [@Perlence](https://github.com/Perlence))
245
- - `EditorOptions` with optional `paddingX` for horizontal content padding, plus `getPaddingX()`/`setPaddingX()` methods ([#791](https://github.com/badlogic/pi-mono/pull/791) by [@ferologics](https://github.com/ferologics))
246
- - Expanded keymap coverage for terminal compatibility: added support for Home/End keys in tmux, additional modifier combinations, and improved key sequence parsing ([#752](https://github.com/badlogic/pi-mono/pull/752) by [@richardgill](https://github.com/richardgill))
247
- - `OverlayOptions.visible` callback for responsive overlays - receives terminal dimensions, return false to hide ([#667](https://github.com/badlogic/pi-mono/pull/667) by [@nicobailon](https://github.com/nicobailon))
248
- - `pageUp` and `pageDown` key support with `selectPageUp`/`selectPageDown` editor actions ([#662](https://github.com/badlogic/pi-mono/pull/662) by [@aliou](https://github.com/aliou))
249
- - `fuzzyFilter()` and `fuzzyMatch()` utilities for fuzzy text matching
250
- - Slash command autocomplete now uses fuzzy matching instead of prefix matching
251
- - Added setAutocompleteMaxVisible() configuration (3-20 items)
252
- - Added image detection to terminal capabilities (containsImage method)
253
- - Added stdin monitoring to detect stalled input events and log warnings
254
- - Added `pageUp` and `pageDown` key support with `selectPageUp`/`selectPageDown` editor actions
255
- - Add `getExpandedText()` to editor for expanding paste markers
256
- - Added `SymbolTheme` interface for customizing UI symbols including cursors, borders, spinners, and box-drawing characters
257
- - Added support for custom spinner frames in the Loader component
258
- - Added `setTopBorder()` method to Editor component for displaying custom status content in the top border
259
- - Added `getWidth()` method to TUI class for retrieving terminal width
260
- - Added rounded corner box-drawing characters to Editor component borders
261
- - Added legacy terminal support for Ctrl+symbol keys (Ctrl+\, Ctrl+], Ctrl+-) and their Ctrl+Alt variants. ([#831](https://github.com/badlogic/pi-mono/pull/831) by [@Perlence](https://github.com/Perlence))
262
- - Kitty keyboard protocol flag 2 support for key release events. New exports: `isKeyRelease(data)`, `isKeyRepeat(data)`, `KeyEventType` type. Terminals supporting Kitty protocol (Kitty, Ghostty, WezTerm) now send proper key-up events.
263
-
264
- ### Changed
265
-
266
- - `UserMessageComponent`'s native hover toolbar (`zeta.user.tools`) leads with Copy and Rewind icon buttons (`copy`, `rewind`) instead of text labels, then a dot and the time, like the turn usage footer
267
- - `ContextUsageView`'s native body (on terminals with `meter`) leads with the tokens used and the room left before auto-compaction, then one stacked bar ticked at the threshold, the breakdown as rows (`zeta.context.cat`, `.cat.free`, `.cat.buffer`: swatch, name, tokens, share; the exact count in the row's `title`) and the snapcompact estimate as labelled rows (`zeta.context.snap`); the blocks meter and legend `kv` are gone, and `contextUsageHead` no longer repeats the window size
268
- - `AskDialogComponent`'s native root is `zeta.editor.ask` (collapsed: `zeta.editor.ask.hidden`, the countdown, the question as `zeta.ask.summary`, Skip and Show): a chosen answer is the `accent`-toned row (a check also carries the check icon) instead of the highlighted one; multi-select Other… is `zeta.ask.other.check`; the question tabs check answered questions and say their keys in the strip's `title`; the countdown moves from the head to the action bar beside Hide; the preview is `zeta.ask.preview`; the Review tab leads with `zeta.ask.notice` and lists answers (`zeta.ask.answers`) by question name with inline code mono and no `(Recommended)` suffix; option descriptions run inline code mono, notes ride the row's detail as `em`; Submit/Next's tooltip names only Enter (and Space on a multi-select)
269
- - `MCPAddWizard`'s native sheet asks one question per step: a phase strip (`zeta.mcpAdd.progress` of `zeta.mcpAdd.phase`, toned done/current/upcoming and `neutral` when no auth was needed), the question and its lead (`zeta.mcpAdd.title`, `zeta.mcpAdd.tag` for optional fields, `zeta.mcpAdd.lead`), then a mono field with a placeholder and its rule or refusal (`zeta.mcpAdd.field`, `tone: "error"`; `zeta.mcpAdd.note`), choice rows with icons and mono tags (`zeta.mcpAdd.choices`), status lines (`zeta.mcpAdd.status`, `zeta.mcpAdd.checks`, `zeta.mcpAdd.error`) or the review rows (`zeta.mcpAdd.summary`). Cancel, Back and Continue / Save server buttons run Ctrl+C, Esc and Enter instead of a key-hint strip. The connection test shows its own busy step, the OAuth client secret field is masked, and the review saves on Enter (no Yes/No choice)
270
- - `ReportPanel`'s native body carries the role `zeta.report.body`
271
- - `HookInputComponent` describes a dock sheet (`zeta.overlay.hook-input` col) like `HookEditorComponent`'s: the title's first line (`zeta.hook-input.title`, the countdown as `zeta.hook-input.timer`) over its further lines (`zeta.hook-input.detail`), the field (`zeta.hook-input.field`, `tone: "error"` while a submit was refused) with its placeholder, and Cancel / Submit buttons that run Esc / Enter; the key legend under the field is terminal-only
272
- - `JobsSheet`'s native body is a master–detail split (`zeta.jobs.split`: `zeta.jobs.master` | `zeta.jobs.detail`): the job list grouped Running / Recent (`zeta.jobs.group` labels), each row a type icon tinted by status with its duration, beside the selected job's status pill, live elapsed and Cancel job (`zeta.jobs.status`), its task title or command (`zeta.jobs.title` / `zeta.jobs.command`), facts (`zeta.jobs.facts`: agent, directory, pids, exit code, artifact) and output (`zeta.jobs.out`, `zeta.jobs.nooutput`); the footer counts running and recent jobs (`zeta.jobs.summary`), and no jobs shows an empty state (`zeta.jobs.empty`). Task jobs no longer draw an `agent` node here
273
- - `BtwHistoryPanel`'s native sheet is centered and reads like a mail reader: the questions as two-line rows (`zeta.btw.history`, list `zeta.btw.list` / `zeta.btw.list.idle` while the answer has the keys) beside the selected thread (`zeta.btw.reader` › `zeta.btw.thread` › `zeta.btw.turn`: `zeta.btw.question` / `zeta.btw.followup`, `zeta.btw.meta`, `zeta.btw.answer`, `zeta.btw.error`), the follow-up field under the last answer (`zeta.btw.composer`), and footer buttons Stop answer, Copy answer, Close and Follow up (Cancel and Send while composing) in place of the focus labels and key-hint strip; an empty history is an `md` sheet (`zeta.btw.empty`)
274
- - The `wait` tool's native job rows (`zeta.wait.job`) are a single `row`: badge, id and label, progress and clock, without the output preview or capture notice beneath
275
- - The native bash run foot reads In background with a live clock (`zeta.run.time` without `stopped`) while a parked job's frames stream (`details.async.state === "running"`, partial), instead of Running
276
- - Moved `wrapTextWithAnsi` export to `@linxiraos/pi-natives` package
277
- - Default editor `newLine` binding now uses `shift+enter` only
278
- - Hardware cursor is now disabled by default for better terminal compatibility. Set `PI_HARDWARE_CURSOR=1` to enable (replaces `PI_NO_HARDWARE_CURSOR=1` which disabled it).
279
- - Migrated key parsing and matching logic to native implementation for improved performance
280
- - Simplified `isKeyRelease()` and `isKeyRepeat()` to use regex pattern matching instead of string inclusion checks
281
- - Refactored `visibleWidth` function to use caching wrapper around new `visibleWidthRaw` implementation for improved performance
282
- - Improved performance of key ID parsing with optimized cache lookup strategy
283
- - Simplified `visibleWidth` calculation to use consistent Bun.stringWidth approach for all string lengths
284
- - Replaced external `fd` binary with native fuzzy path search for `@`-prefixed autocomplete
285
- - Restructured terminal capabilities from interface-based to class-based model
286
- - Improved table column width calculation with word-aware wrapping
287
- - Refactored text utilities to use native WASM implementations for strings >256 chars with JS fast path
288
- - Added Ctrl+Backspace as a delete-word-backward keybinding and improved modified backspace matching
289
- - Migrated file system operations from synchronous to asynchronous APIs in autocomplete provider for non-blocking I/O
290
- - Migrated node module imports from named to namespace imports across all packages for consistency with project guidelines
291
- - Normalized keybinding definitions to lowercase internally
292
- - Improved fuzzy matching to handle alphanumeric swaps.
293
- - Normalized keybinding definitions to lowercase internally.
294
- - Changed `showOverlay()` to return `OverlayHandle` for controlling overlay visibility
295
- - Removed `widthPercent`, `maxHeightPercent`, `rowPercent`, `colPercent` from `OverlayOptions` (use percentage strings instead)
296
- - Improved file autocomplete to show directory listing when typing `@` with no query, and fall back to prefix matching when fuzzy search returns no results
297
- - Terminal startup now queries Kitty protocol support before enabling event reporting
298
- - Changed cursor style from block to thin blinking bar (▏) at end of line
299
- - Editor component now uses word wrapping instead of character-level wrapping for better readability ([#382](https://github.com/badlogic/pi-mono/pull/382) by [@nickseelert](https://github.com/nickseelert))
300
- - Renamed `EllipsisKind` enum to `Ellipsis` for clearer API naming
301
- - Changed hardcoded ellipsis character from theme-configurable to literal "…" in editor truncation
302
- - Improved blockquote rendering with text wrapping in Markdown component
303
- - Expanded Kitty keyboard protocol coverage for non-Latin layouts and legacy Alt sequences
304
- - Improved cursor positioning with safer bounds checking
305
- - Updated editor layout to respect configurable padding
306
- - Refactored scrolling logic for better viewport management
307
371
 
308
372
  ### Fixed
309
373
 
@@ -315,59 +379,10 @@ Initial release under @oh-my-pi scope. See previous releases at [badlogic/pi-mon
315
379
  - Fixed inline images in iTerm2 being sized for the wrong cell shape, which left charts smeared or offset ([#16118](https://github.com/can1357/oh-my-pi/pull/16118) by [@galtamam-cmyk](https://github.com/galtamam-cmyk))
316
380
  - Remove trailing space padding from Text, Markdown, and TruncatedText components when no background color is set (fixes copied text including unwanted whitespace)
317
381
  - Fixed Ctrl+Enter sequences to insert new lines in the editor
318
- - Fixed `fd` tool detection to automatically find `fd` or `fdfind` in PATH when not explicitly configured
319
- - Fixed editor multi-line insertion handling and lastAction tracking ([#945](https://github.com/badlogic/pi-mono/pull/945) by [@Perlence](https://github.com/Perlence))
320
- - Fixed editor word wrapping to reserve a cursor column ([#934](https://github.com/badlogic/pi-mono/pull/934) by [@Perlence](https://github.com/Perlence))
321
- - Fixed editor word wrapping to use single-pass backtracking for whitespace handling ([#924](https://github.com/badlogic/pi-mono/pull/924) by [@Perlence](https://github.com/Perlence))
322
- - Fixed Kitty image ID allocation and cleanup to prevent image ID collisions between modules
323
- - Fixed viewport tracking and cursor positioning for overlays and content shrink scenarios
324
- - Autocomplete now allows searches with `/` characters (e.g., `folder1/folder2`) ([#882](https://github.com/badlogic/pi-mono/pull/882) by [@richardgill](https://github.com/richardgill))
325
- - Directory completions for `@` file attachments no longer add trailing space, allowing continued autocomplete into subdirectories
326
- - `visibleWidth()` and `extractAnsiCode()` now handle APC escape sequences (`ESC _ ... BEL`), fixing width calculation and string slicing for strings containing cursor markers
327
- - SelectList now handles multi-line descriptions by replacing newlines with spaces ([#728](https://github.com/badlogic/pi-mono/pull/728) by [@richardgill](https://github.com/richardgill))
328
- - Reset ANSI styles after each rendered line to prevent style leakage
329
- - Cursor position tracking when content shrinks with unchanged remaining lines
330
- - TUI renders with wrong dimensions after suspend/resume if terminal was resized while suspended ([#599](https://github.com/badlogic/pi-mono/issues/599))
331
- - Pasted content containing Kitty key release patterns (e.g., `:3F` in MAC addresses) was incorrectly filtered out ([#623](https://github.com/badlogic/pi-mono/pull/623) by [@ogulcancelik](https://github.com/ogulcancelik))
332
- - `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))
333
-
334
- Older entries are archived in [packages/tui/CHANGELOG.md@9caccab691ce](https://github.com/can1357/oh-my-pi/blob/9caccab691ce575007f4b6bcbaf8f944723d5457/packages/tui/CHANGELOG.md).
335
- Older entries are archived in [packages/tui/CHANGELOG.md@58141d4e5fa8](https://github.com/can1357/oh-my-pi/blob/58141d4e5fa892166024e2168866c45e0baacde3/packages/tui/CHANGELOG.md).
336
- - Corrected editor end-of-line cursor rendering assertion to use includes() instead of endsWith()
337
- - Fixed potential errors during emergency terminal restore when terminal is already dead
338
- - Fixed autocomplete race condition by tracking request ID to prevent stale suggestion results
339
- - Added legacy terminal support for `Ctrl+` symbol key combinations
340
- - Added legacy terminal support for `Ctrl+` symbol key combinations.
341
- - Fixed backspace handling with additional codepoint support
342
- - Fixed Alt+letter key combinations for better recognition
343
- - TUI now filters out key release events by default, preventing double-processing of keys
344
- - `matchesKey()` now correctly matches Kitty protocol sequences for unmodified letter keys
345
- - Crash when pasting text with trailing whitespace exceeding terminal width through Markdown rendering
346
- - Slash command menu now only triggers when the editor input is otherwise empty ([#904](https://github.com/badlogic/pi-mono/issues/904))
347
- - Center-anchored overlays now stay vertically centered when resizing the terminal taller after a shrink ([#950](https://github.com/badlogic/pi-mono/pull/950) by [@nicobailon](https://github.com/nicobailon))
348
- - Shift+Space, Shift+Backspace, and Shift+Delete now work correctly in Kitty-protocol terminals (Kitty, WezTerm, etc.) instead of being silently ignored ([#411](https://github.com/badlogic/pi-mono/pull/411) by [@nathyong](https://github.com/nathyong))
349
- - Improved Kitty terminal key sequence parsing to correctly handle text field codepoints in CSI-u sequences
350
- - Fixed handling of private use Unicode codepoints (U+E000 to U+F8FF) in Kitty key decoding to prevent invalid character interpretation
351
- - Simplified terminal write error handling to mark terminal as dead on any write failure
352
- - Fixed multi-line strings in renderOutputBlock causing width overflow
353
- - Fixed slash command autocomplete applying stale completion when typing quickly
354
- - Reserved cursor space for zero padding and corrected end-of-line cursor rendering to prevent wrap glitches
355
- - Fixed viewport tracking after partial renders to prevent autocomplete list artifacts
356
- - Rendering optimizations: only re-render changed lines
357
- - Refactor input component to use keybindings manager
358
- - Fixed editor cursor blinking by allowing terminal cursor positioning when enabled.
359
- - Editor no longer corrupts terminal display when text exceeds screen height. Content now scrolls vertically with indicators showing lines above/below the viewport. Max height is 30% of terminal (minimum 5 lines). ([#732](https://github.com/badlogic/pi-mono/issues/732))
360
- - Cursor now moves to end of content on exit, preventing status line from being overwritten ([#629](https://github.com/badlogic/pi-mono/pull/629) by [@tallshort](https://github.com/tallshort))
361
- - Slash command autocomplete now triggers for commands starting with `.`, `-`, or `_` (e.g., `/.land`, `/-foo`) ([#422](https://github.com/badlogic/pi-mono/issues/422))
362
382
 
363
383
  ### Removed
364
384
 
365
385
  - `SingleResult` (and the task tool's settled payload) carries the failure diagnostics an agent-driven model switch needs: optional `failureClass` (`usage-limit` / `auth` / `account-policy` / `context-overflow` / `transient` / `aborted` / `unknown`), optional `fallbackCandidates` (other selectors this session could run), and optional `modelChange` (`{ source: "spawn-param" | "wake-param", from?, to }`) recording that a caller-supplied model replaced the default one. All three stay absent unless a run actually reports them.
366
- - The welcome/splash brand art is now generated with the standard FIGlet tool instead of being drawn by hand: `ZETA_LOGO` renders the mark `Z` (the ASCII form of `Ζ`), `ZETA_WORDMARK` renders `Zeta` (both in the standard `ANSI Shadow` font) and `ZETA_SUBLINE` renders the `Linxira-Zeta` identity line in `mini`, with the version under the wordmark. `bun scripts/brand/generate-logo-art.ts` regenerates the three constants from the vendored fonts, and the brand guard fails on any hand-edited glyph.
367
- - Removed `ellipsis` property from `SymbolTheme` interface
368
- - Removed `extractAnsiCode` function from public API
369
- - Removed TUI layout engine exports from public API (BoxNode, ColumnNode, LayoutNode, etc.)
370
- - Removed `visibleWidth` benchmark file in favor of Kitty sequence benchmarking
371
386
 
372
387
  ## [1.3.0] - 2026-10-18
373
388
 
@@ -493,10 +508,6 @@ Older entries are archived in [packages/tui/CHANGELOG.md@58141d4e5fa8](https://g
493
508
 
494
509
  - **Key detection functions removed**: All `isXxx()` key detection functions (`isEnter()`, `isEscape()`, `isCtrlC()`, etc.) have been removed. Use `matchesKey(data, keyId)` instead (e.g., `matchesKey(data, "enter")`, `matchesKey(data, "ctrl+c")`). This affects hooks and custom tools that use `ctx.ui.custom()` with keyboard input handling. ([#405](https://github.com/badlogic/pi-mono/pull/405))
495
510
 
496
- ### Removed
497
-
498
- - Removed `truncateToWidth`, `sliceWithWidth`, and `extractSegments` functions from public API (now re-exported directly from @linxiraos/pi-natives)
499
-
500
511
  ## [1.1.26] - 2026-10-03
501
512
 
502
513
  - 版本线推进至 1.1.26;本版无独立用户可见变化。
@@ -582,10 +593,6 @@ Older entries are archived in [packages/tui/CHANGELOG.md@58141d4e5fa8](https://g
582
593
 
583
594
  ## [0.44.0] - 2026-01-12
584
595
 
585
- ### Added
586
-
587
- - `SettingsListOptions` with `enableSearch` for fuzzy filtering in `SettingsList` ([#643](https://github.com/badlogic/pi-mono/pull/643) by [@ninlds](https://github.com/ninlds))
588
-
589
596
  ### Fixed
590
597
 
591
598
  - Numbered list items showing "1." for all items when code blocks break list continuity ([#660](https://github.com/badlogic/pi-mono/pull/660) by [@ogulcancelik](https://github.com/ogulcancelik))
@@ -630,17 +637,6 @@ Older entries are archived in [packages/tui/CHANGELOG.md@58141d4e5fa8](https://g
630
637
 
631
638
  - Symbol key support in keybinding system: `SymbolKey` type with 32 symbol keys, `Key` constants (e.g., `Key.backtick`, `Key.comma`), updated `matchesKey()` and `parseKey()` to handle symbol input ([#450](https://github.com/badlogic/pi-mono/pull/450) by [@kaofelix](https://github.com/kaofelix))
632
639
 
633
- ## [0.33.0] - 2026-01-04
634
-
635
- ### Added
636
-
637
- - `Editor.insertTextAtCursor(text)` method for programmatic text insertion ([#419](https://github.com/badlogic/pi-mono/issues/419))
638
- - `EditorKeybindingsManager` for configurable editor keybindings. Components now use `matchesKey()` and keybindings manager instead of individual `isXxx()` functions. ([#405](https://github.com/badlogic/pi-mono/pull/405) by [@hjanuschka](https://github.com/hjanuschka))
639
-
640
- ### Changed
641
-
642
- - Key detection refactored: consolidated `is*()` functions into generic `matchesKey(data, keyId)` function that accepts key identifiers like `"ctrl+c"`, `"shift+enter"`, `"alt+left"`, etc.
643
-
644
640
  ## [0.31.1] - 2026-01-02
645
641
 
646
642
  Older entries are archived in [packages/tui/CHANGELOG.md@fa14205f838f](https://github.com/can1357/oh-my-pi/blob/fa14205f838f282fcea048c64fca74026789a492/packages/tui/CHANGELOG.md).
@@ -39,6 +39,12 @@ export interface AutocompleteItem {
39
39
  state?: string;
40
40
  /** Dim hint text shown inline after cursor when this item is selected */
41
41
  hint?: string;
42
+ /**
43
+ * Slash command matched only through its description, not its name or an alias:
44
+ * a browse hit, so Enter submits the typed text instead of running it unless the
45
+ * user moved the selection onto it.
46
+ */
47
+ descriptionMatch?: boolean;
42
48
  }
43
49
  type Awaitable<T> = T | Promise<T>;
44
50
  export interface SlashCommand {
@@ -0,0 +1,34 @@
1
+ /**
2
+ * One-row block sparklines (`▁▂▃▅▇█`) for ANSI renderers: the usage history
3
+ * in `zetacode usage`, a job widget's series in the `wait` card and status line.
4
+ */
5
+ /** Block glyphs from lowest to highest. */
6
+ export declare const SPARK_LEVELS: readonly ["▁", "▂", "▃", "▄", "▅", "▆", "▇", "█"];
7
+ /** How {@link renderSparkline} maps values to glyphs and styles them. */
8
+ export interface SparklineOptions {
9
+ /** Domain low end; values at or below it draw the lowest block. Default 0. */
10
+ readonly min?: number;
11
+ /** Domain high end; values at or above it draw the full block. Default the largest value. */
12
+ readonly max?: number;
13
+ /** Styles one glyph; `fraction` is the value's 0–1 position in the domain. */
14
+ readonly style?: (glyph: string, value: number, fraction: number) => string;
15
+ /** What a missing value draws, already styled. Default a space. */
16
+ readonly gap?: string;
17
+ }
18
+ /** The block glyph for a 0–1 fraction of the domain. */
19
+ export declare function sparkGlyph(fraction: number): string;
20
+ /** One cell per value, oldest first; `undefined` (and non-finite) values draw the gap. */
21
+ export declare function renderSparkline(values: readonly (number | undefined)[], options?: SparklineOptions): string;
22
+ /**
23
+ * `values` squeezed into at most `cells` points by equal-count bucket means,
24
+ * newest bucket last; shorter series come back unchanged.
25
+ */
26
+ export declare function fitSparkValues(values: readonly number[], cells: number): readonly number[];
27
+ /**
28
+ * The largest value per time bucket over `[sinceMs, nowMs]`, `cells` buckets
29
+ * wide; buckets without a point are `undefined` (a gap in the sparkline).
30
+ */
31
+ export declare function peakBuckets(points: Iterable<{
32
+ readonly at: number;
33
+ readonly value: number;
34
+ }>, sinceMs: number, nowMs: number, cells: number): (number | undefined)[];
@@ -25,6 +25,7 @@ export * from "./components/section.js";
25
25
  export * from "./components/select-list.js";
26
26
  export * from "./components/settings-list.js";
27
27
  export * from "./components/spacer.js";
28
+ export * from "./components/sparkline.js";
28
29
  export * from "./components/tab-bar.js";
29
30
  export * from "./components/table.js";
30
31
  export * from "./components/text.js";
@@ -9,7 +9,7 @@
9
9
  * ]);
10
10
  * }
11
11
  */
12
- import type { TspKind, TspProps, TspSpan, TspText } from "@linxiraos/pi-wire";
12
+ import type { TspKind, TspPropNode, TspProps, TspSpan, TspText } from "@linxiraos/pi-wire";
13
13
  import type { NativeChild, NativeNode } from "./node.js";
14
14
  /** A node of any kind. */
15
15
  export declare function node<K extends TspKind>(k: K, p?: TspProps<K>, c?: readonly NativeChild[], key?: string): NativeNode;
@@ -37,6 +37,12 @@ export declare const EMPTY_NODE: NativeNode;
37
37
  export declare function keyed(described: NativeNode, key: string): NativeNode;
38
38
  /** `described` mounted but not laid out when `hidden` (cheap visibility toggles keep ids and view state). */
39
39
  export declare function withHidden(described: NativeNode, hidden: boolean): NativeNode;
40
+ /**
41
+ * A described tree as the node tree a prop carries (a `hovercard`): plain
42
+ * nodes only, since nothing reconciles inside a prop; component children
43
+ * (which describe themselves per frame) are left out.
44
+ */
45
+ export declare function propNode(described: NativeNode): TspPropNode;
40
46
  /** Stable node key for an arbitrary identity string; keys join into `/` keypaths, so identities are hashed. */
41
47
  export declare function stableKey(identity: string): string;
42
48
  /** Drop absent entries (`undefined`, `null`, `false`) from a child list. */
@@ -10,6 +10,8 @@ import type { TspProps, TspSpan, TspText } from "@linxiraos/pi-wire";
10
10
  import { type KeyName } from "../key-hint-format.js";
11
11
  import { type Keybinding } from "../keybindings.js";
12
12
  import type { NativeChild, NativeNode } from "./node.js";
13
+ /** Below this many columns a centered sheet fills the pane instead of floating with margins. */
14
+ export declare const NARROW_SHEET_COLS = 100;
13
15
  /** One footer hint: the keys that trigger it and what it does. */
14
16
  export interface NativeHint {
15
17
  /** Key ids (`"ctrl+o"`, `"escape"`); alternatives render side by side. */
@@ -17,6 +17,8 @@ export interface BackgroundChrome {
17
17
  }
18
18
  /** Map an omp background token to card tone/role. */
19
19
  export declare function backgroundChrome(bg: ThemeBg | undefined): BackgroundChrome;
20
+ /** The omp theme colour an ANSI renderer draws a TSP tone with (the inverse of {@link colorTone}). */
21
+ export declare function toneColor(tone: TspTone): ThemeColor;
20
22
  /**
21
23
  * Tone of an omp colour used as a severity or border colour; undefined for
22
24
  * colours that carry no tone (callers pick their own fallback).
@@ -5,11 +5,11 @@
5
5
  * - Table view: every registered agent except Main (Main IS the ambient
6
6
  * chat), live from the global AgentHubRegistry — status, unread irc count,
7
7
  * current/last task, last activity. Navigate with keys, wheel, hover, and
8
- * click; `r` revives a parked agent, `x` aborts + releases one.
8
+ * click; `r` revives a parked or killed agent, `x` aborts + releases one.
9
9
  * - Chat view: per-agent transcript (incremental session-file tail, absorbed
10
10
  * from the old session observer overlay) plus an input line. Submitting
11
- * revives a parked agent, then prompts/steers it; the message lands in the
12
- * agent's persisted history via the normal prompt path.
11
+ * revives a parked or killed agent, then prompts/steers it; the message
12
+ * lands in the agent's persisted history via the normal prompt path.
13
13
  *
14
14
  * Replaces the old SessionObserverOverlayComponent (ctrl+s observer).
15
15
  */
@@ -1,7 +1,8 @@
1
1
  /**
2
2
  * Tool-approval prompt in the composer's place, presented like the ask
3
3
  * dialog: the approval title and its details over a list of choices —
4
- * Approve, an optional "approve for this session", and Deny — and an action
4
+ * optional grants (led by a toggle that keeps them across sessions), Approve,
5
+ * an optional "approve for this session", and Deny — and an action
5
6
  * bar. The arrows move between the choices and Enter takes the highlighted
6
7
  * one; `app.approval.approve` (Ctrl+Enter by default) approves this call
7
8
  * outright and Esc denies. Enter and the approve chord only arm
@@ -23,6 +24,13 @@ interface ApprovalDialogCallbacks {
23
24
  onApprove(): void;
24
25
  onDeny(): void;
25
26
  }
27
+ /** A choice that approves the call and remembers more than it: a folder, or the exact target. */
28
+ export interface ApprovalDialogGrant {
29
+ /** Label while the grant is remembered for this session. */
30
+ readonly label: string;
31
+ /** Label once the remember toggle keeps it across sessions. */
32
+ readonly alwaysLabel: string;
33
+ }
26
34
  /** The composer mounted beneath the dialog: it receives every key the dialog does not own. */
27
35
  export interface ApprovalDialogDraft {
28
36
  /** True while the composer holds a draft — text, attachments, or a paste still landing: keys then edit and send it. */
@@ -48,6 +56,12 @@ interface ApprovalDialogOptions {
48
56
  label: string;
49
57
  onApprove(): void;
50
58
  };
59
+ /**
60
+ * Grants to offer above Approve, led by a toggle that keeps them across sessions; Approve then
61
+ * reads "Approve Once". `onGrant` gets the chosen grant and whether the toggle was on.
62
+ */
63
+ grants?: readonly ApprovalDialogGrant[];
64
+ onGrant?(grant: ApprovalDialogGrant, always: boolean): void;
51
65
  }
52
66
  export declare class ApprovalDialogComponent implements Component {
53
67
  #private;