Fix restored terminals rendering blank on mobile#8768
Conversation
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Orca <help@stably.ai>
📝 WalkthroughWalkthroughProvider reattach results now include reset or continued output sequence metadata, and IPC spawn paths synchronize runtime PTY sequencing with it. Runtime serialization can use provider-owned buffer snapshots when renderer serialization is unavailable or provider state is preferred. Headless hydration, title handling, sequence rebasing, and alternate-screen tracking were updated for restored PTYs. Tests cover sequencing races, provider snapshot fallback, streaming, cold restore, and alternate-screen state. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Co-authored-by: Orca <help@stably.ai>
There was a problem hiding this comment.
🧹 Nitpick comments (2)
src/shared/terminal-kitty-keyboard-mode-tracker.test.ts (1)
63-69: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winVerify that alternate-screen observation remains sticky.
src/main/runtime/orca-runtime.tsuses this flag to determine whether a switch was ever observed. Assert it remainstrueafter1049l; otherwise a regression could pass this test while skipping provider snapshot reconciliation.Proposed test addition
tracker.scan('\x1b[?1049l') + expect(tracker.hasObservedAlternateScreenSwitch).toBe(true) expect(tracker.isAlternateScreen).toBe(false)src/main/runtime/orca-runtime.test.ts (1)
7407-7613: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winExtract the repeated provider-buffer controller mock into a helper.
The same
{ write, kill, getForegroundProcess, serializeProviderBuffer, hasRendererSerializer: () => false }shape is re-declared inline across six tests. A small factory would cut duplication and keep future controller-contract changes to one place.♻️ Suggested helper
+function createProviderBufferOnlyController( + serializeProviderBuffer: RuntimePtyController['serializeProviderBuffer'] +): RuntimePtyController { + return { + write: () => true, + kill: () => true, + getForegroundProcess: async () => null, + serializeProviderBuffer, + hasRendererSerializer: () => false + } +}Then each test becomes
runtime.setPtyController(createProviderBufferOnlyController(serializeProviderBuffer)).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: ebd83fba-c015-47fa-b1da-08d8c0f58f6b
📒 Files selected for processing (10)
src/main/daemon/daemon-pty-adapter.test.tssrc/main/daemon/daemon-pty-adapter.tssrc/main/ipc/pty.test.tssrc/main/ipc/pty.tssrc/main/providers/types.tssrc/main/runtime/orca-runtime.test.tssrc/main/runtime/orca-runtime.tssrc/main/runtime/rpc/terminal-provider-snapshot-sequence.test.tssrc/shared/terminal-kitty-keyboard-mode-tracker.test.tssrc/shared/terminal-kitty-keyboard-mode-tracker.ts
Summary
Root cause
#6461 intentionally changed mobile worktree/tab selection to avoid navigating the desktop (
notifyClients: false). That exposed an existing state gap for restored terminals: main could discover that a daemon PTY was alive and mark its tab ready, while neither a main-process headless model nor a mounted desktop renderer serializer existed. Mobile subscription therefore emitted an empty initial snapshot until a desktop reveal mounted the pane.This is independent of the cloud relay path and reproduces over a direct local-only connection.
Fix
The serialization order is now:
The local daemon already retains an authoritative buffer for surviving PTYs, so the final fallback can return their history without mounting or focusing desktop UI. Providers that do not implement buffer snapshots, including unsupported native/SSH paths, return
nulland retain the previous behavior.Validation
pnpm exec vitest run --config config/vitest.config.ts src/main/runtime/orca-runtime.test.ts src/main/ipc/pty.test.ts src/main/runtime/mobile-subscribe-integration.test.ts src/main/runtime/rpc/terminal-subscribe-buffer.test.ts— 1,025 passed, 2 skippedpnpm run typecheck:nodepnpm exec oxlint src/main/ipc/pty.ts src/main/ipc/pty.test.ts src/main/runtime/orca-runtime.ts src/main/runtime/orca-runtime.test.tspnpm exec electron-vite build --mode e2eThe simulator flow created nine terminals with unique markers, moved desktop to another workspace, fully quit/relaunched Electron while daemon PTYs survived, and opened the background workspace on mobile. No terminal tab was touched before evidence.
Before: the active restored terminal remained blank after five seconds.
After: the active restored terminal displayed its marker within five seconds while all eight marked desktop panes remained unmounted. The mobile stream emitted a 381-byte, one-chunk initial snapshot.
Made with Orca 🐋