Skip to content

feat(app): mac terminal keys work in terminals, and shift+enter is a newline in claude code - #118

Merged
sean-brydon merged 3 commits into
mainfrom
feat/mac-terminal-keys
Oct 15, 2026
Merged

sean-brydon merged 3 commits into
mainfrom
feat/mac-terminal-keys

Conversation

@pumfleet

Copy link
Copy Markdown
Contributor

In a Shipyard terminal, ⇧↵ submitted in Claude Code instead of starting a new line, and the Mac's line-editing keys didn't work.

Why: both renderers send a plain \r for ⇧↵. Even if they hadn't, berth's tmux had extended-keys off, so it turned a modified Enter back into \r. ⌥←/→ arrived as CSI 1;3D/C and ⌘←/→ as CSI 1;9D/C, which neither a shell nor Claude Code reads as word or line moves, and ⌘⌫ was a plain backspace.

What changes

  • app/src/lib/terminal-keys.ts (+ unit tests): ⇧↵ → CSI 13;2u on every platform. On a Mac only, ⌥←/→ → ESC b/ESC f, ⌘←/→ → ^A/^E and ⌘⌫ → ^U, as in Ghostty's macOS defaults and iTerm2's natural text editing. The Linux app keeps its Ctrl keys for the shell. The app's own ⌘⌥ arrows and ⌥1–5 are untouched.
  • terminal-view.tsx: a capture listener on the terminal host sends these through the same input path as typed keys, ahead of the renderer.
  • internal/box/sessions.go: set -s extended-keys on (guarded to tmux 3.2+). tmux then sends a modified key only to a program that asked for one (xterm modifyOtherKeys, which Claude Code requests), so bash still gets a plain Enter for ⇧↵. I checked tmux 3.6 by hand: it ignores the kitty keyboard request; modifyOtherKeys is what counts.
  • Docs: a Keys section in Terminals, and a changelog entry under Unreleased. This conflicts trivially with fix(box): new terminals no longer open with a systemd CPUAccounting warning #116's Unreleased heading.

Tested

  • New TestAttachPassesShiftEnter: the program gets CSI 27;2;13~. Without the config line it gets 0d (plain Enter).
  • New e2e/terminal-keys.spec.ts (ghostty and xterm) asserts the exact bytes sent. Without the terminal-view change it fails, getting ;3D.
  • By hand on tmux 3.6 with real Claude Code: ⇧↵ inserts a newline with the new config and submits without it.
  • go vet ./..., go test -race ./internal/box/, pnpm test (500 pass), tsc, typecheck:plugins, check:titles, check:csp, pnpm build, tsc -p e2e, docs-site build.

Note: an agent that's already running asked for modified keys while tmux ignored the request, so ⇧↵ works for it only after it restarts.

🤖 Generated with Claude Code

…newline in claude code

⇧↵ is sent as CSI 13;2u instead of a plain Enter, and berth's tmux turns
on extended-keys (tmux 3.2+), so a program that asked for modified keys
(Claude Code) gets Shift+Enter while a shell still gets Enter. On a Mac,
⌥←/→ move a word (ESC b/f), ⌘←/→ go to the line's ends (^A/^E) and ⌘⌫
deletes back to its start (^U), as in Ghostty and iTerm2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
berth Ready Ready Preview Oct 15, 2026 1:27pm UTC
berth-docs Ready Ready Preview Oct 15, 2026 1:27pm UTC

Request Review

@sean-brydon
sean-brydon merged commit c3e2109 into main Oct 15, 2026
2 of 3 checks passed
@linear-code

linear-code Bot commented Oct 15, 2026

Copy link
Copy Markdown

ENG-6206

This branch was successfully deployed

2 active deployments
Preview – berth-docs — f07d4fb5 Deployed Oct 15, 2026 by vercel[bot]
Preview – berth — f07d4fb5 Deployed Oct 15, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants