feat(mobile): live terminal screen over the relay — WebView xterm, quick keys, PTY reattach
Closed
SA
3mo ago+722+722+012345678901234567890123456789-1-1-0123456789
First surface of the terminal-first mobile direction: a live terminal attached to a host PTY over the relay, at workspace/[id]/terminal/[terminalId] (deep-link only for now — home-screen rows land with the terminals-as-sessions swap after #6328).
Architecture
- The WebSocket lives inside the WebView, next to xterm — PTY bytes never cross the RN bridge. The page (xterm.js + fit addon + a small reconnect runtime, ~403 KiB self-contained HTML generated by
scripts/generate-terminal-html.tsand committed asterminalHtml.generated.ts) speaks the same wire contract as web'sTerminalConnection: binary frames = raw PTY bytes, JSON text frames = control (attached/title/exit/error), client sendsinput/resize,_whoownspreflight before each dial for fly affinity + definitive 403 detection, exponential backoff with a 12-attempt budget,replay=0once bytes have been received. - React Native owns auth and chrome: signs each dial URL with a fresh JWT (
getHostAuthToken, expiry-aware), sets the nav title from the PTY's OSC title, shows connection banners, relays app-resume to the page, and renders a quick-keys row (esc · tab · ⇧tab · arrows · ^C) writing raw bytes through the bridge. - New native dep:
react-native-webview13.16.1 — dev clients need a rebuild (bunx expo run:ios).
Also in this PR
fix(mobile): pinexpo-font56.0.5 — bun resolved 56.0.7 (June 15 batch), whose precompiled framework references aRecord.from(dictionary:appContext:)symbol that doesn't exist in ourexpo-modules-core56.0.15 (June 5 batch) → DYLD missing-symbol crash at launch. Anyone prebuilding from current main hits this.
Verified on simulator (iPhone 16 Pro, full local stack: api + relay + desktop-spawned host-service)
End-to-end, driven via Maestro:
- Deep link opens the screen; xterm renders a live Claude Code TUI streaming over the relay; the PTY's title lands in the native header.
- Input path: tapping the ⇧tab quick key cycled Claude Code's permission mode on the host (auto → manual) and the TUI update streamed back.
- Reattach: leaving and re-opening the deep link resumed the same PTY with a full screen replay (server adopts by terminalId).
- Typecheck (repo-wide) and lint clean.
Known follow-ups
- Soft-keyboard input: tapping the terminal doesn't reliably focus xterm's hidden textarea in WKWebView, so freeform typing needs the planned native input bar writing via
terminal.send/writeInput. Quick keys (the bridge path) work today. - One
[RNScreens] sheetPresentationController is nullredbox appeared on a single deep-link entry and never reproduced; watching for it.
Summary by cubic
Adds a live terminal screen on mobile at workspace/[id]/terminal/[terminalId], powered by xterm in a WebView, with quick keys, reconnect, and session reattach. Also adds required deps and pins expo-font to fix a launch crash; dev clients must rebuild.
-
New Features
- xterm runs inside
WebView; socket lives in-page so PTY bytes don’t cross the RN bridge. - Quick keys row (esc, tab, ⇧tab, arrows, ^C) sends raw bytes to the PTY.
- Reconnect with backoff and reattach by
terminalIdwith replay; exit overlay shows code. - Native chrome: sets title from PTY OSC, shows connection banners; deep-link only for now.
- xterm runs inside
-
Dependencies
- Add
react-native-webview@13.16.1(native change; rebuild dev clients, e.g.bunx expo run:ios). - Add
@xterm/xtermand@xterm/addon-fitfor the generated terminal page (scripts/generate-terminal-html.ts). - Pin
expo-font@56.0.5to avoid a DYLD missing-symbol crash withexpo-modules-core@56.0.15.
- Add
Summary by CodeRabbit
- New Features
- Added mobile terminal access within workspace sessions.
- Added live terminal interaction with connection, loading, offline, error, and ended-session states.
- Added retry and reconnect support for interrupted sessions.
- Added quick-access controls for Escape, Tab, Shift-Tab, arrow keys, and Ctrl-C.
- Added mobile-friendly keyboard handling, terminal resizing, and session close actions.
- Added a dedicated Terminal screen with streamlined navigation and presentation.