Repository navigation
Description
Summary
Since V2, pressing Shift+Enter in the macOS built-in Terminal (Terminal.app) submits the prompt instead of inserting a newline — even with alt+return explicitly bound to input.newline. This worked in V1 with the same terminal and the same keypress. The V2 input stack (opentui) no longer resolves Terminal.app's ambiguous ESC+CR sequence.
Environment
- opencode version: 0.0.0-beta-17519 (beta)
- OS: Darwin 27.0.0 (macOS, arm64)
- Terminal: Terminal.app (
TERM_PROGRAM=Apple_Terminal,TERM=xterm-256color) - Shell: /bin/zsh
- Install/channel: beta
- Active plugins:
opencode-claude-auth-v2, a custom TUI sidebar plugin (neither affects input handling)
Reproduction
- In macOS Terminal.app, run
opencode2. - Type some text in the prompt.
- Press Shift+Enter.
- The prompt submits instead of inserting a newline.
Raw bytes captured from Terminal.app: pressing Shift+Enter sends ESC + CR (\x1b\r) in raw mode (ESC + LF in cooked mode, i.e. cat -v shows ^[ then a line break). Terminal.app does not support the kitty keyboard protocol, so this is the only encoding it can produce.
Expected Behavior
Shift+Enter inserts a newline. This worked in V1 in the same Terminal.app with the same keypress.
Actual Behavior
Shift+Enter submits the prompt. Only ctrl+j inserts a newline.
Additional Context
Keybind combinations tried in ~/.config/opencode/cli.json (each tested after a full TUI restart):
{ "keybinds": { "input.newline": "shift+return,ctrl+return,alt+return,ctrl+j" } }
{ "keybinds": { "input.newline": "shift+return,ctrl+return,alt+return,alt+linefeed,ctrl+j" } }Neither restores Shift+Enter in Terminal.app. opentui's keypress parser (packages/core/src/lib/parse.keypress.ts) decodes \x1b\r as { name: "return", meta: true } and \x1b\n as { name: "linefeed", meta: true }, so alt+return/alt+linefeed should match — but the event does not reach the keybind matcher as such (or is consumed by the submit path).
Notes:
- V1's default
input_newlineincludedalt+returnand worked in Terminal.app; the V2 default keybind isshift+return,ctrl+return,ctrl+j—alt+returnwas dropped, and re-adding it does not help. - Terminals with kitty keyboard protocol support (Ghostty, Kitty, WezTerm, iTerm2) send an unambiguous Shift+Enter and the default
shift+returnbinding works there — confirming the byte stream is the only difference. - Related earlier reports: Shift-return does not input newline since 1.0 #4046, Starting from opencode 1.1.22, shift+enter and ctrl+enter are not working. #8926, Shift+Enter submits prompt instead of inserting newline #30544, pinned Keybinds #4997. PR fix(prompt-input): handle Shift+Enter before IME check to prevent stuck state #8275 previously fixed similar newline handling in V1.
- Impact: every macOS Terminal.app (and similar non-kitty-protocol terminal) user on V2 loses multiline prompt entry.
Workaround
ctrl+j inserts a newline; Shift+Enter works in kitty-protocol terminals (e.g. Ghostty). Neither is the stock-terminal experience V1 provided.
Activity
github-actions commentedon Aug 18, 2026
This issue might be a duplicate of an existing issue. Please check:
ESC+CRencoding and the kitty keyboard protocol gap.For keybind-related issues, please also check our pinned keybinds documentation: #4997
vbobkov1968 commentedon Oct 27, 2026
Confirming this still reproduces on v2.2.0 (stable), macOS 26.6.2 (arm64), Terminal.app.
I captured the raw bytes in Terminal.app (
stty raw -echo) to verify the encoding claim above:0d(CR) — byte-for-byte identical to plain Enter1b 0d(ESC CR)So Shift+Enter and Option+Enter are not the same sequence here. Option+Enter correctly triggers
input.newlinethrough thealt+returnbinding; Shift+Enter is indistinguishable from Enter at the byte level, so it never reaches the matcher asshift+returnand submits the prompt instead.That points away from the
ESC+CRparsing path and toward the missing fallback: when a bare Return arrives, inspect the physical modifier state (macOSCGEventSource.flagsState/NSEvent.modifierFlags) and treat it as Shift+Enter if Shift is held. Claude Code does exactly this on macOS and works in Terminal.app without setup, per its terminal docs. Ghostty works via the kitty keyboard protocol, which is the current workaround.Repro on v2.2.0: Terminal.app →
opencode→ type text → Shift+Enter submits; Option+Enter andctrl+jinsert a newline.Since this was closed as completed, please treat this as a regression report for 2.2.0 — happy to test a patch.