fix(cli,tui): skip Kitty keyboard protocol push for Ghostty, use modifyOtherKeys only - #88416
Merged
kshitijk4poor merged 2 commits intoAug 20, 2026
Conversation
…herKeys only Ghostty's Kitty disambiguate-mode implementation strips the Alt modifier from the Backspace key — Option+Backspace arrives as bare \x7f instead of the expected \x1b[27;3;127~, breaking backward-kill-word. This was a regression introduced when PR NousResearch#87630 re-added the CSI >1u Kitty protocol push for all allowlisted terminals including Ghostty. Under modifyOtherKeys mode (CSI >4;2m), Ghostty correctly sends \x1b[27;3;127~ for Option+Backspace, which the alias table in pt_input_extras already maps to (Escape, ControlH) = backward-kill-word. Fix: for Ghostty only, push just modifyOtherKeys and skip the Kitty protocol push. All other terminals (iTerm2, WezTerm, kitty, tmux, VS Code) still get the full dual-protocol push. Ghostty upstream tracking: discussion NousResearch#9560, issue NousResearch#9895 (cmd+backspace variant of the same root cause).
kshitijk4poor
force-pushed
the
fix/ghostty-alt-backspace-kitty-protocol
branch
from
August 20, 2026 05:55
67374da to
6fab3aa
Compare
kshitijk4poor
enabled auto-merge (rebase)
August 20, 2026 05:56
kshitijk4poor
disabled auto-merge
August 20, 2026 05:57
Widen the cli.py Ghostty exception to the sibling sites the review found: the Ink TUI pushes CSI >1u at raw-mode entry (App.tsx), on alt-screen exit, and on the extended-keys re-assert path (ink.tsx) for every EXTENDED_KEYS_TERMINALS entry including ghostty - same Alt-stripping bug. New skipKittyKeyboardProtocol() helper in terminal.ts gates the ENABLE push at all 3 sites; the DISABLE (pop) stays unconditional since popping an empty stack is a spec no-op. Also fix the cli.py comment citing the modifyOtherKeys encoding where the kitty CSI-u form (ESC[127;3u) is what the broken path expected, dedupe the quadruplicated Ghostty comment, and update the stale 'mirroring the Ink TUI' docstring. 7 new vitest cases.
kshitijk4poor
force-pushed
the
fix/ghostty-alt-backspace-kitty-protocol
branch
from
August 20, 2026 05:59
6fab3aa to
7f0f496
Compare
kshitijk4poor
enabled auto-merge (rebase)
August 20, 2026 05:59
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Option+Backspace (backward-kill-word) and other Alt-modified combos work again on Ghostty — in BOTH the classic CLI and the Ink TUI. Root cause: Ghostty's Kitty disambiguate-mode implementation strips the Alt modifier from Backspace (Option+Backspace arrives as bare
\x7finstead of the CSI-u form\x1b[127;3uthe protocol calls for — upstream Ghostty bug, see ghostty discussions #9560 / issue #9895). Ghostty implements modifyOtherKeys correctly, so for Ghostty we push onlyESC[>4;2mand skip theESC[>1uKitty push; every other allowlisted terminal keeps the dual push.Changes
cli.py:_GHOSTTY_EXTENDED_ENTER_KEYS_SEQ+ Ghostty gate in_enable_extended_enter_keys(detection matches exactly the two conditions that admit Ghostty through_terminal_supports_extended_enter_keys)ui-tui/.../terminal.ts: newskipKittyKeyboardProtocol()helper — the Ink TUI had the identical bug at 3 write sitesui-tui/.../components/App.tsx,ui-tui/.../ink.tsx: gate theENABLE_KITTY_KEYBOARDpush at raw-mode entry, alt-screen exit re-enable, and the extended-keys re-assert path; the pop (DISABLE_KITTY_KEYBOARD) stays unconditional (popping an empty stack is a spec no-op)Validation
ESC[>1u ESC[>4;2mESC[>4;2monlyESC[>1u ESC[>4;2mESC[>4;2monly\x7f(plain backspace)ESC[27;3;127~→ backward-kill-wordtests/cli/test_ctrl_enter_newline.py: 13 passed; TUIterminal.test.ts: 15 passed;tsc -bclean_TERMINAL_INPUT_MODE_RESET_SEQand the TUI disable paths kept unconditional — cleans leaked state, no-op otherwise