What happens
A program that requests the kitty keyboard protocol (CSI > 1 u) gets no answer and no enhanced key reports from flue, because xterm.js does not implement it. Everything falls back to legacy encoding, where a whole family of chords is indistinguishable:
Codex's TUI is the one in front of us: it is crossterm-based and turns the protocol on when the terminal claims it. Helix, Neovim and any ratatui app do the same.
Why
xterm.js has no CSI-u support — not the kitty flavour and not modifyOtherKeys. It is a long-standing upstream request (xtermjs/xterm.js#4133 and friends) and there is no option to switch on.
Options, none of them small
- Wait for upstream. Cheapest, and the answer if nothing here is urgent.
- Implement it in the seam.
web/src/emulator/xterm.ts already registers parser handlers for the device-query suppression, so the mode-set side is reachable: a CSI-u handler could record the requested flags. The reporting side is harder — it means encoding key events ourselves in the custom key handler and suppressing xterm's own encoding for everything covered, which is most of the keyboard.
- Keep patching the individual chords, the way Shift+Enter is patched today. Works, does not scale, and gets the app's answer wrong for every program that asked for the protocol and believes it got it.
The thing to be careful about whichever way this goes: flue mirrors one pty to several emulators, and the answer to a mode query is already arbitrated — exactly one client may reply (answerQueries, and the note above it explains why). A second protocol to answer for would have to respect the same rule, and a mirror that agreed to enhanced keys while the primary did not would put encodings on the wire that the program is not expecting.
What happens
A program that requests the kitty keyboard protocol (
CSI > 1 u) gets no answer and no enhanced key reports from flue, because xterm.js does not implement it. Everything falls back to legacy encoding, where a whole family of chords is indistinguishable:ESC CR, but only because flue puts it there by hand — see Shift+Enter adds a line, and a session says what it is before it starts #61).Codex's TUI is the one in front of us: it is crossterm-based and turns the protocol on when the terminal claims it. Helix, Neovim and any ratatui app do the same.
Why
xterm.js has no CSI-u support — not the kitty flavour and not
modifyOtherKeys. It is a long-standing upstream request (xtermjs/xterm.js#4133 and friends) and there is no option to switch on.Options, none of them small
web/src/emulator/xterm.tsalready registers parser handlers for the device-query suppression, so the mode-set side is reachable: a CSI-u handler could record the requested flags. The reporting side is harder — it means encoding key events ourselves in the custom key handler and suppressing xterm's own encoding for everything covered, which is most of the keyboard.The thing to be careful about whichever way this goes: flue mirrors one pty to several emulators, and the answer to a mode query is already arbitrated — exactly one client may reply (
answerQueries, and the note above it explains why). A second protocol to answer for would have to respect the same rule, and a mirror that agreed to enhanced keys while the primary did not would put encodings on the wire that the program is not expecting.