Skip to content

Commit eb92ba9

Browse files
nwparkerorca-ide
andauthored
fix(terminal): advertise kitty keyboard protocol for Shift+Enter (#1247)
Orca's terminal already encodes Shift+Enter as the kitty CSI-u sequence `\x1b[13;2u`, but without `vtExtensions.kittyKeyboard` xterm.js never answers the `CSI ? u` probe. CLIs that gate enhanced input on that handshake (Claude Code, Codex, etc.) therefore drop the extended bytes and treat Shift+Enter as a plain Enter — most visibly when running inside tmux, which strips extended-key encodings by default. - Enable `vtExtensions.kittyKeyboard` in the default terminal options (matches VS Code's xtermTerminal). - Lock in the flag with a regression test in pane-lifecycle.test.ts. - Add docs/terminal-extended-keys.md explaining the Orca side and the tmux-side `set -s extended-keys on` + `terminal-features xterm*:extkeys` users need for nested Shift+Enter to reach a CLI. Verified end-to-end in Electron: `cat -v` + Shift+Enter now prints `^[[13;2u`, and `printf '\e[?u'` elicits the expected `CSI ? 0 u` reply from xterm.js. Co-authored-by: Orca <help@stably.ai>
1 parent 2964e2d commit eb92ba9

3 files changed

Lines changed: 87 additions & 1 deletion

File tree

docs/terminal-extended-keys.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Extended Key Chords in the Terminal (Shift+Enter, etc.)
2+
3+
## What Orca sends
4+
5+
Orca's built‑in terminal already encodes extended key chords using the
6+
[kitty keyboard protocol][kitty] (CSI‑u). For example, **Shift+Enter** is sent
7+
as the byte sequence:
8+
9+
```
10+
ESC [ 1 3 ; 2 u (i.e. \x1b[13;2u)
11+
```
12+
13+
See `src/renderer/src/components/terminal-pane/terminal-shortcut-policy.ts`
14+
for the full table.
15+
16+
Orca also advertises kitty‑protocol support to the running program via
17+
`vtExtensions.kittyKeyboard` on xterm.js (see
18+
`src/renderer/src/lib/pane-manager/pane-terminal-options.ts`), so CLIs that
19+
probe with `CSI ? u` learn that the terminal speaks CSI‑u and enable their
20+
enhanced input handlers.
21+
22+
## Why Shift+Enter may not reach your CLI inside tmux
23+
24+
tmux, by default, strips both extended‑key encodings (modifyOtherKeys
25+
`CSI 27 ; 2 ; 13 ~` *and* kitty‑style `CSI 13 ; 2 u`). If you run Claude
26+
Code, Codex, or any other CLI under tmux, Shift+Enter will look like a
27+
plain `Enter` unless tmux is told to pass those bytes through.
28+
29+
Add this to `~/.tmux.conf` (tmux 3.2+):
30+
31+
```tmux
32+
set -s extended-keys on
33+
set -as terminal-features 'xterm*:extkeys'
34+
```
35+
36+
Then reload: `tmux source-file ~/.tmux.conf` (or restart the tmux server).
37+
38+
- `extended-keys on` — tell tmux to accept and forward the extended
39+
encodings instead of collapsing them to the unshifted key.
40+
- `terminal-features 'xterm*:extkeys'` — tell tmux that the surrounding
41+
terminal (Orca, in this case) understands those encodings, so tmux is
42+
willing to emit them.
43+
44+
## Verifying end‑to‑end
45+
46+
Inside an Orca terminal (no tmux), run:
47+
48+
```
49+
cat -v
50+
```
51+
52+
Press **Shift+Enter**. You should see:
53+
54+
```
55+
^[[13;2u
56+
```
57+
58+
That's caret notation for `\x1b[13;2u` — the expected CSI‑u encoding. If
59+
you see `^M` (or a blank newline) instead, either the chord isn't reaching
60+
the terminal (check `keyboard-handlers.ts` / `terminal-shortcut-policy.ts`)
61+
or you're inside tmux without the config above.
62+
63+
Inside tmux after the config, the same `cat -v` test should print the same
64+
`^[[13;2u`.
65+
66+
[kitty]: https://sw.kovidgoyal.net/kitty/keyboard-protocol/

src/renderer/src/lib/pane-manager/pane-lifecycle.test.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,16 @@ describe('buildDefaultTerminalOptions', () => {
5353
it('leaves macOS Option available for keyboard layout characters', () => {
5454
expect(buildDefaultTerminalOptions().macOptionIsMeta).toBe(false)
5555
})
56+
57+
it('advertises kitty keyboard protocol so CLIs enable enhanced key reporting', () => {
58+
// Why: Orca already writes CSI-u bytes for extended key chords like
59+
// Shift+Enter (see terminal-shortcut-policy.ts). CLIs that gate
60+
// enhanced input on a CSI ? u handshake only read those bytes once the
61+
// terminal advertises support. Regressing this flag silently breaks
62+
// Shift+Enter (and other extended chords) in apps like Claude Code and
63+
// Codex, especially when running inside tmux.
64+
expect(buildDefaultTerminalOptions().vtExtensions?.kittyKeyboard).toBe(true)
65+
})
5666
})
5767

5868
describe('attachWebgl', () => {

src/renderer/src/lib/pane-manager/pane-terminal-options.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,16 @@ export function buildDefaultTerminalOptions(): ITerminalOptions {
1616
// Why: on macOS, non-US layouts rely on Option to compose characters like @ and €.
1717
macOptionIsMeta: false,
1818
macOptionClickForcesSelection: true,
19-
drawBoldTextInBrightColors: true
19+
drawBoldTextInBrightColors: true,
20+
// Why: advertise kitty keyboard protocol support so CLIs that probe
21+
// (CSI ? u) know Orca accepts enhanced key reporting. Without this,
22+
// Orca already writes \x1b[13;2u for Shift+Enter (see
23+
// terminal-shortcut-policy.ts), but programs that respect the protocol
24+
// handshake fall back to legacy encodings and ignore the CSI-u byte,
25+
// making chords like Shift+Enter invisible to the app — especially
26+
// noticeable inside tmux. Matches VS Code's xtermTerminal.ts.
27+
vtExtensions: {
28+
kittyKeyboard: true
29+
}
2030
}
2131
}

0 commit comments

Comments
 (0)