Commit Graph
14 Commits
Author SHA1 Message Date
can1357 3998d95088 feat: standardized tab expansion to fixed width
- Removed configurable tab width support and the `display.tabWidth` setting across all packages.
- Deleted obsolete utility functions `getIndentation`, `getIndentationNoescape`, and `setDefaultTabWidth`.
- Standardized tab expansion logic to use a fixed `DEFAULT_TAB_WIDTH` globally.
- Cleaned up related configuration schemas, test suites, and internal API signatures to remove path-dependency.
2026-06-19 04:48:41 +02:00
can1357 746efd0c29 fix(tui): resolved leak of re-encoded control bytes during bracketed paste
- Centralized decoding of tmux's `extended-keys` control sequences (`csi-u` and `xterm` formats) into a shared utility.
- Updated the multi-line editor and single-line input to use this decoder, preventing escape tails (e.g., `[27;5;106~`) from leaking into the text buffer.
- Added parity to the single-line input by explicitly stripping any remaining control characters after decoding to ensure data integrity.
2026-06-18 19:54:22 +02:00
0xff26b9a8 d4b01d3a48 fix(tui): handle VS Code keypad digit input 2026-06-16 18:55:23 +08:00
roboomp 336b993126 fix(tui): route enhanced-paste text to the focused Input prompt
On kitty (Linux/Wayland) and any terminal supporting OSC 5522 enhanced
paste, the /login API-key prompt for OpenCode Zen — and any other modal
Input prompt (Perplexity OTP, GitHub Enterprise URL, manual OAuth
redirect URL, …) — silently dropped pasted content. The user could not
paste their API key; on Enter or Esc the key surfaced in the main
prompt.

Cause: InputController.#setupEnhancedPaste enables kitty's enhanced
clipboard protocol on TUI start and consumes the resulting OSC 5522
packets in an addInputListener that runs *before* focus dispatch in
tui.#handleInput. The controller's pasteText callback then routed
unconditionally to this.ctx.editor.pasteText(text) — the main
CustomEditor — even when selector-controller had cleared editorContainer
and focused a temporary Input. The text accumulated in the detached
editor and only resurfaced when the modal was dismissed.

Fix:
- TUI.getFocused() exposes the currently focused component.
- Input.pasteText(text) mirrors Editor.pasteText so any Input can absorb
  a payload from a non-bracketed transport.
- InputController's enhanced-paste callback consults getFocused() and
  routes text to the focused component when it exposes pasteText,
  falling back to the editor only when no modal target is in focus.
- Image pastes refuse with a status message when a modal Input is
  focused, instead of stuffing a binary blob into the hidden editor.

Regression tests in packages/tui/test/input.test.ts and
packages/coding-agent/test/issue-2127-repro.test.ts pin both the new
TUI/Input contract and the InputController routing source.

Fixes #2127
2026-06-08 20:34:50 +00:00
can1357 db0f396601 feat(tui): added terminal cursor mode synced to hardware cursor pref
- Added Input setUseTerminalCursor to render terminal or software cursor.
- Synced focused component cursor mode on focus and preference changes.
- Fixed wrapTextWithAnsi infinite loop on BEL-terminated string escapes.
2026-06-04 05:21:35 +02:00
Leo Kimandcan1357 1c264fc428 fix(tui): NFC-normalize bracketed-paste input (cursor displacement after macOS Finder drag-drop of Korean filenames)
User-visible symptom: drag-dropping a file with Korean characters in its name (e.g., `/Users/leo/Downloads/화면 기록 2026-05-13 오후 8.55.24.mov`) into the OMP input prompt leaves the hardware cursor floating ~5–8 cells past the visible filename. Static — typing immediately after places the new character at the cursor (gap), not at the visible end of the text.

Root cause (verified by direct measurement on the user's pasted path):

- macOS Finder drag-drops file paths with Korean characters in NFD form (Conjoining Jamo, U+1100..U+11FF), not NFC (Hangul Syllables, U+AC00..U+D7A3).

- Korean syllable `화` is U+D654 in NFC: 1 char, Bun.stringWidth=2 cells.

- Same syllable in NFD is U+1112 (ᄒ) + U+116A (ᅪ): 2 chars, Bun.stringWidth=3 cells (each conjoining jamo is classified Wide=2 or Narrow=1 separately).

- Terminal emulators correctly combine the NFD sequence into a single visible syllable (2 cells) per Unicode rendering rules.

- Bun's count overcounts by 1–2 cells per syllable. For a path with 6 Korean syllables: ~9 cells overcount → cursor drifts 9 cells past the filename.

- This is the same JS/Rust/terminal width-mismatch class as the earlier Compatibility Jamo issue (U+3131..U+318E from IME composition), but in a different Unicode range — and triggered by macOS Finder, not the IME.

Fix: `Input.#handlePaste` now appends `.normalize("NFC")` to the paste-text cleaning chain. The pasted bytes are converted from NFD → NFC before being inserted into `#value`, so all downstream width arithmetic (cursor positioning, viewport scrolling, padding) sees the same canonical encoding the terminal renders.

Localized to paste-time only — does not change `visibleWidthRaw` semantics, doesn't add per-render overhead, and doesn't touch the Rust width tables. Cost: ~0.5 μs per paste (single `String.normalize("NFC")` call on the pasted content).

Tests: 2 new cases in `packages/tui/test/input.test.ts` covering (a) NFD-encoded path stored as NFC after paste, (b) cursor column matches `visibleWidth(value) + prompt-width` after pasting a Korean filename. Full tui suite: 8 pre-existing failures (overlay-scroll 4 + render-regressions 4) unchanged.
2026-05-25 12:11:15 +02:00
can1357 b60c0cc3ce refactor: migrated tab width resolution to pi-utils with EditorConfig caching
- Extracted tab width resolution from pi-natives to pi-utils with EditorConfig caching support.
- Made tabWidth parameter required in native text functions (visibleWidth, truncateToWidth, wrapTextWithAnsi, sliceWithWidth, extractSegments).
- Removed process-wide tab width state management from pi-natives text module.
- Consolidated wrapper node promotion logic in chunk classification with abbreviated string representations.
- Removed path-clean and pathdiff dependencies from pi-natives.
- Updated all consuming packages to import tab width functions from pi-utils and pass explicit tabWidth parameters.
2026-04-10 14:18:36 +02:00
can1357 9b78a6fa85 refactor(natives): migrated native bindings to NAPI-RS with auto-generated types
- Migrated native bindings from TypeScript wrappers to NAPI-RS generated modules with auto-generated type definitions and runtime enums.
- Replaced chunk tree API with stateful ChunkState class supporting render, edit, and resolve operations with improved error handling.
- Converted callback signatures to error-first pattern (error, result) for shell, PTY, glob, and grep operations.
- Introduced type-safe enums for MacOSAppearance, GrepOutputMode, KeyEventType, ImageFormat, and AstMatchStrictness replacing string literals.
- Refactored chunk tree implementation with dedicated modules for edit, indent, resolve, and state management with comprehensive validation.
- Moved clipboard utilities from native bindings to coding-agent package with improved OSC 52 and Termux compatibility.
2026-04-07 02:00:59 +02:00
e2f87b07ab numpad windows PUA CSI-u codes (#431)
Co-authored-by: Brit <lol@no.com>
2026-03-15 16:38:46 +01:00
can1357 acf4b45062 fix(coding-agent): backported pi-mono changes (5133697..15e0957b0)
packages/ai:
- fix: improve GitHub Copilot OAuth polling and Codex stream recovery
- fix: allow google-vertex authentication via GOOGLE_CLOUD_API_KEY
- fix: send Gemini/Claude provider-specific thinking headers and thought-signature fallbacks correctly
- test: added coverage for Gemini CLI alignment, Codex streaming, and stream edge cases

packages/coding-agent:
- feat: add treeFilterMode setting for the session tree selector default
- fix: prefer later-loaded explicit extensions when commands conflict
- fix: truncate serialized tool results during compaction summarization to prevent overflow
- fix: normalize CRLF in write tool previews
- fix: use shell-based external editor launch on Windows
- test: added compaction serialization and extension runner precedence coverage

packages/tui:
- fix: chain slash-command argument autocomplete after tab-completing the command name
- fix: normalize pasted tabs in Input using configured indentation
- fix: render blockquote lists, tables, and fenced code blocks correctly
- fix: ignore unsupported Kitty CSI-u modifiers and enable modifyOtherKeys fallback cleanup
- test: added editor, input, keys, and markdown regression coverage
2026-03-10 07:27:30 +01:00
50a9f872de fix(tui): fixed windows numpad input (#339)
* fix(tui): fixed windows numpad input

* numlock handles in kitty CSI p2

* fix(tui): preserved modified numlock keypad nav

* fix(tui): restored autocomplete keystroke triggers

---------

Co-authored-by: Brit <lol@no.com>
2026-03-09 15:14:28 +01:00
can1357 7d5a230e26 fix: lowercased tool names in argument parsing
Fixes #324.
2026-03-07 23:53:16 +01:00
can1357 95df9f6f3e fix(tui): added checks to filter out Kitty release events
- Added checks to filter out Kitty release events (event_type 3) in both matches_key_inner and parse_key_inner functions. Added comprehensive tests for both key matching and input handling to verify release events are ignored while press and repeat events are still processed correctly.
Fixes #325
2026-03-07 23:46:01 +01:00
绫andGitHub d8782684f1 fix(tui): improve input wrapping and Unicode word navigation (#287)
* fix(tui): avoid wasting end-of-line width when wrapping wide tokens in TUI editor

* fix(tui): improve wrapping and Unicode word navigation

* fix(tui): avoid crash when input line exceeds terminal width

* chore(tui): fix code lint and formatting
2026-03-04 15:53:53 +01:00