Skip to content

fix(cli,tui): skip Kitty keyboard protocol push for Ghostty, use modifyOtherKeys only - #88416

Merged
kshitijk4poor merged 2 commits into
NousResearch:mainfrom
kshitijk4poor:fix/ghostty-alt-backspace-kitty-protocol
Aug 20, 2026
Merged

fix(cli,tui): skip Kitty keyboard protocol push for Ghostty, use modifyOtherKeys only#88416
kshitijk4poor merged 2 commits into
NousResearch:mainfrom
kshitijk4poor:fix/ghostty-alt-backspace-kitty-protocol

Conversation

@kshitijk4poor

@kshitijk4poor kshitijk4poor commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator

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 \x7f instead of the CSI-u form \x1b[127;3u the protocol calls for — upstream Ghostty bug, see ghostty discussions #9560 / issue #9895). Ghostty implements modifyOtherKeys correctly, so for Ghostty we push only ESC[>4;2m and skip the ESC[>1u Kitty 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: new skipKittyKeyboardProtocol() helper — the Ink TUI had the identical bug at 3 write sites
  • ui-tui/.../components/App.tsx, ui-tui/.../ink.tsx: gate the ENABLE_KITTY_KEYBOARD push 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)
  • Tests: 3 pytest cases (Ghostty via TERM_PROGRAM, via TERM, non-Ghostty regression guard) + 7 vitest cases for the TUI helper

Validation

Before After
Ghostty CLI push ESC[>1u ESC[>4;2m ESC[>4;2m only
Ghostty TUI push (3 sites) ESC[>1u ESC[>4;2m ESC[>4;2m only
Option+Backspace on Ghostty bare \x7f (plain backspace) ESC[27;3;127~ → backward-kill-word
iTerm2 / kitty / WezTerm / tmux dual push dual push (unchanged)
  • 7/7 deterministic real-import probes (Ghostty both detection paths, iTerm2/kitty dual push retained, unknown-terminal no-op, reset seq still pops kitty mode, env=None path)
  • tests/cli/test_ctrl_enter_newline.py: 13 passed; TUI terminal.test.ts: 15 passed; tsc -b clean
  • Kitty pop in _TERMINAL_INPUT_MODE_RESET_SEQ and the TUI disable paths kept unconditional — cleans leaked state, no-op otherwise

@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/cli CLI entry point, hermes_cli/, setup wizard labels Aug 17, 2026
…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
kshitijk4poor force-pushed the fix/ghostty-alt-backspace-kitty-protocol branch from 67374da to 6fab3aa Compare August 20, 2026 05:55
@kshitijk4poor kshitijk4poor changed the title fix(cli): skip Kitty keyboard protocol push for Ghostty, use modifyOtherKeys only fix(cli,tui): skip Kitty keyboard protocol push for Ghostty, use modifyOtherKeys only Aug 20, 2026
@kshitijk4poor
kshitijk4poor enabled auto-merge (rebase) August 20, 2026 05:56
@kshitijk4poor
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
kshitijk4poor force-pushed the fix/ghostty-alt-backspace-kitty-protocol branch from 6fab3aa to 7f0f496 Compare August 20, 2026 05:59
@kshitijk4poor
kshitijk4poor enabled auto-merge (rebase) August 20, 2026 05:59
@kshitijk4poor
kshitijk4poor merged commit 45f1126 into NousResearch:main Aug 20, 2026
60 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cli CLI entry point, hermes_cli/, setup wizard P2 Medium — degraded but workaround exists type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants