- Fixed `visibleWidth` parity with native width using `Bun.stringWidth` ANSI stripping.
- Fixed tab and OSC66 width parsing with `s=`/`w=` metadata handling.
- Added ASCII and long-string fast paths in `visibleWidth` for faster width checks.
- Consolidated visible-width regression coverage by replacing removed IME/Arabic/Jamo tests with `visible-width.test.ts`.
- Added `textSizing` terminal capability and `tui.textSizing` setting for Kitty OSC66 scaling.
- Updated OSC66 range and visible-width handling to preserve grapheme slice behavior.
- Updated markdown rendering to apply heading text sizing only when enabled.
- Fixed DECCARA trailing-background fill tracking and DECRPM status 3/4 recognition.
- Added OSC 66 text-sizing utilities and `encodeTextSized` for safe, width-aware span emission.
- Enabled scale-2 OSC 66 output for H1 headings when text sizing is enabled and width permits.
- Handled OSC 66 heading rows as raw output, skipping wrap/background and preserving the reserved blank row.
- Mapped inline heading tokens to plain text to gate OSC 66 heading rendering by measured width.
- Moved `eagerEraseScrollbackRisk` detection into `TerminalInfo` and `terminal-capabilities.ts`, removing the duplicate from `terminal.ts`.
- Added iTerm2 and Apple Terminal to risk detection; required double at-bottom probe before trusting live rebuilds.
- Fixed overlay hide in multiplexer sessions triggering a viewport repaint instead of a stale diff.
- Fixed width-shrink rebuilds leaving old-width fragments in native history before subsequent appends.
- Switched `grapheme_width_str` to compute multi-character widths from `UnicodeWidthStr::width` and then apply the macOS Hangul Compatibility Jamo correction on top of that result.
- Added regression tests in native and TUI text-width tests for VS16 emoji-presentation symbols, keycaps, and related bare-symbol cases.
- Adjusted the AuthStorage codex ranking timeout test fallback to 2s with a 1s elapsed assertion so slow aborted requests cannot mask the fast timeout path.
- Introduced a shared missingSnapshotTagMessage helper and reused it from both hashline patcher and preview validation.
- Required snapshot tags in preview hashline sections for all edits, including head/tail inserts, so preview failures now match apply-time rejections.
- Updated TUI width calculation to strip ANSI escapes before grapheme splitting, preserving styled ZWJ emoji width behavior.
Keep the printable ASCII fast path, but send tabs, ANSI/control sequences, combining marks, and CJK through the same native width engine used by slicing and wrapping. This fixes Bun.stringWidth overcounting Arabic non-spacing marks and the old pure-ASCII tab double count.\n\nConstraint: Bun.stringWidth still reports Arabic combining marks as visible cells on Bun 1.3.14.\nRejected: Strip \p{Mn} in TypeScript | It would still leave tabs and future Unicode width mismatches divergent from native truncation.\nConfidence: high\nScope-risk: narrow\nDirective: Keep visibleWidth, sliceWithWidth, truncateToWidth, and wrapTextWithAnsi on one Unicode width model.\nTested: bun test packages/tui/test/text-utils.test.ts packages/tui/test/visible-width-jamo.test.ts packages/tui/test/wrap-ansi.test.ts packages/tui/test/truncate-to-width.test.ts packages/tui/test/render-regressions.test.ts; bun test packages/tui/test/*.test.ts; bun run check in packages/tui.\nNot-tested: Interactive terminal repaint with a live Arabic transcript.
- Renamed `EllipsisKind` enum to `Ellipsis` across all packages for clearer API naming.
- Refactored Rust text module from 356 to 155 lines with simplified state tracking using u32 ColorVal instead of enum ColorCode and named attribute constants.
- Removed `Env` parameter from public NAPI functions `truncate_to_width` and `extract_segments` to simplify API surface.
- Changed return type of `truncate_to_width` from `JsString` to `Either<JsString, Utf16String>` to support zero-copy returns.
- Removed early return optimization in `truncateToWidth()` function.
- Reordered native module search paths to prioritize repository build artifacts over system paths.
- Changed TextInput type parameter to string in truncateToWidth(), visibleWidth(), sliceWithWidth(), and extractSegments() functions in native bindings.
- Removed TextInput type export from public API of pi-natives package.
- Removed format.ellipsis symbol from theme configuration, replacing all theme-based ellipsis references with hardcoded Unicode ellipsis character (...).
- Removed ellipsis property from SymbolTheme interface in pi-tui package.
- Removed truncateToWidth, sliceWithWidth, and extractSegments wrapper functions from pi-tui public API, now re-exporting directly from pi-natives.
- Added early return optimizations in truncateToWidth() and sliceWithWidth() native functions to skip native calls when possible.
- Added native text utilities in pi-natives (visible width, truncation, slicing, segment extraction)
- Wired pi-tui to use native implementations with short-string JS fast path
- Optimized key matching via cached parsed key ids
- Refactored visual truncation to reuse Text instances
- Reduced theme color lookups by switching from Map to plain records
- Regenerated WASM artifacts
Benchmarks (after vs before, lower is better):
- truncateToWidth/ansi: 20.37ms vs 38.13ms (2000 iters)
- sliceWithWidth/ansi: 5.12ms vs 20.39ms
- extractSegments/ansi: 8.92ms vs 27.60ms
- truncateToVisualLines: 3.51ms vs 411.55ms (500 iters)
- visibleWidth/ansi: 0.24ms vs 0.31ms