fix(preview): keep one browser page across thread switches

Closed
T3
4d ago
+1577-70

Agents and the Browser panel can show different pages for one tab when the desktop attaches late. Hidden desktop screenshots can also wait forever and block later browser tools.

Keep the existing headless page and stream it to every client. A late desktop attach cannot replace its cookies, DOM, form state, downloads, or recording. Native tabs still render in the desktop. Hidden native captures request frames even when their thread shell is missing; active turns retain their frame lease. Captures stop waiting after five seconds, without blocking later actions or starting overlapping captures.

Replacement for #18584. The six original commits and their authorship are preserved. Reuses Davide Sala's streaming work from #18217, with co-author credit, excluding its separate profile-recovery change. Fixes #16901.

Verification

  • 154 focused tests across 11 files pass. Tests cover late attach, preserved downloads and recordings, close/retry races, native frame leases, and the next action after capture timeout.
  • Server, desktop, web, and contracts typechecks pass. Scoped lint and formatting pass with existing React warnings.
  • One integrated check against isolated test state: sign in, type and save a note, close the panel, switch threads, return, and reopen. The same page state remains.
  • Real Electron hidden-webview fixture: capture stayed pending without frame-request delivery, then completed in 196 ms with delivery. This uses the actual host, relay, renderer lease, and webview style. It does not exercise the entire packaged desktop IPC chain.
  • Web/desktop panel and floating preview paths updated. Remote and mobile clients keep streaming through the existing server path; native mobile was not tested. No provider-specific behavior or user guidance changes.

Evidence

Reported split before the fix:

Reported split: one tab, two pages

After closing the panel and switching threads, sign-in and saved page state remain:

Same signed-in page after returning

· Hidden native capture

New evidence is hosted externally because the available Browser profile is not signed in to GitHub for attachment upload. No evidence files are committed.

Original work by Theo Browne with Claude Opus 5.5 in Claude Code. Streaming contribution by Davide Sala. Reworked and verified with GPT-6.1 Sol in Codex.