[BUG] Mods: Client onKey gets a lone space as undocumented "space" and unnamed keys (F1, Insert, F12) as raw escape sequences
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (both cases come from the same key-to-
ClientKeyEventmapping) - [x] Observed on 2.1.290; I checked the 2.1.296 build and the mapping is the same (see Version)
What's Wrong?
The ClientKeyEvent.key docs say it is "A special key's name (up, down, left, right, return, tab, backspace, delete, pageup, home, ...) or the character typed". Two kinds of key break that contract.
- A space typed on its own arrives as
key: "space". That name isn't in the docs. When the space arrives in the same input chunk as other text, it is a literal" "instead. Fast typing and IME commits ("녕 ") both do this. So aClienttext editor that inserts non-special keys as text writes the wordspacesome of the time, depending on typing speed and input method. - Keys that have no name arrive as their raw escape sequence. F1 arrives as
key: "\^[OP", Insert as"\^[[2~", F12 as"\^[[24~". If aClientdraws that text, the drawing is refused and theClientgoes down. After that, every keystroke goes to the prompt. In my session, the Shift+Tab that followed switched the permission mode.
The mapping in the bundle appears to name a lone " " as space and, for a key with no single-code-point input, to fall back to sequence.
What Should Happen?
- A lone space should arrive the same way as a space inside a chunk (
" "). Failing that,space, and every other name the engine can produce, should be listed inClientKeyEvent's docs. - Unnamed keys should get a name (
f1tof12,insert, ...) or not be delivered at all. They should never arrive as raw escape sequences posing as "the character typed".
Error Messages/Logs
<plugin>: Client hooks/editor.tsx: returned a tree that does not validate (a text child holds a control character (an escape sequence))
Steps to Reproduce
- Make a mod with a
Panewhose tree holds aClientwith this module:
``js``
export default (props, surface) => {
const { Text } = surface.elements
if (surface.state === undefined) {
surface.setState('')
surface.onKey(k => surface.setState(surface.state + JSON.stringify(k.key) + ' '))
}
return Text({ children: surface.state || 'click here and type' })
}
- Start Claude Code with the fullscreen renderer, open the pane and click the
Client. - Press Space on its own. The
Clientshows"space". In tmux,send-keys -l "a b"shows"a b". - Press F1. The
Clientshows"\^[OP". - Change the module to insert
k.keywithoutJSON.stringifyand press F1 again. TheClientis replaced by the error above, and the next keys go to the prompt.
Claude Model
Not relevant (Haiku 4.5 in the test session)
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.290 (Claude Code). The 2.1.296 darwin-arm64 build has the same mapping.
Platform
Other (Claude Team subscription)
Operating System
macOS 27.0.1
Terminal/Shell
tmux 3.6a, and Orca 1.4.220 (xterm.js)