fix(preview): show failed browser previews with recovery controls#24440

draft7
main
fix/issue-7212
opened14d agobyJJulius Marminge
View on GitHubTwo-way sync enabledPR last imported 13d ago

Problem

After an agent navigates a floating browser preview to an unavailable local server, the preview remains blank and covers chat content. Its status omits the navigation failure, so the agent cannot distinguish the failed page from an idle browser.

Change

Show the failed address and reason with visible Close and Retry controls. Streamed tabs keep Take control reachable and expose Retry only to the controlling viewer. Failed previews use a readable square frame instead of inheriting an arbitrarily thin page aspect; successful recovery restores the original aspect.

Return the existing navigation failure in an optional navStatus field and preserve the requested address in selected-tab status. A new navigation clears the failure. No settings or persisted state are added.

Scope and approval

Fixes https://github.com/pingdotgg/t3code/issues/7212 GitCafe: https://git.cafe/pingdotgg/t3code/issues/7212

Triaged bug via the automated issue flow. Reproduced on current main in the actual Linux desktop with a Codex-backed thread and a refused localhost navigation. This addresses the reported failed-preview behavior only.

Verification

After merging current main at 73e9c0d0ef29c91820b67cabaa5719fffd622cf1:

  • Server preview tests: 29/29 passed.
  • Shared browser stream tests: 6/6 passed.
  • Web preview layout tests: 17/17 passed.
  • Targeted lint on all eight PR files passed.
  • Contracts, client-runtime, server and web typechecks passed.

The navigation-status regression failed before implementation and passes with the fix. It verifies the refused requested URL and LoadFailed metadata, followed by clearing failure on retry/navigation.

The final proof audit accepts the minimal native and connected matrix with no remaining findings. Captures run the actual app at implementation head 69c6d53c30; the subsequent main merge preserves the fix's added and removed lines verbatim. Main's nearby navigation change wraps the thrown operation error; it does not change the failure metadata or rendering paths proven here. CI for the updated merge head is pending.

Interaction fixtureRecording and trace
Connected 1440×900 light: agent ownership, takeover, Retry while refused, same-URL recovery and page input, Release, Close, chat input, retained-tab recovery/re-float and positional dragContinuous recording, timestamped report and drivers
Connected 390×844 dark: long URL, positional drag, resize to 240×240 and ownership/recovery controlsContinuous recording, independent connected audit
Native Linux Electron 1440×900 light: Close, physical X11 input into the previously covered composer, retained native tab recovery and re-floatContinuous recording, exact attempt and sanitized drivers
Native same-URL recovery, fresh refused Retry, healthy page input and minimum resizeRetained completion report and media

Rendering environments: connected Chrome 148 client / Chrome 154 server, DPR 1, Linux, 1440×900 light and 390×844 dark; native Electron 44.9.3/Chromium 152, Xvfb, GPU disabled, synthetic isolated state. Recordings are after-only supplements to the static before/after pairs below. The matrix accounts for entry points, native and streamed composition, ownership and reverse flows. Native mobile has a separate unchanged floating component. macOS desktop was not run on this Linux host.

Selected top-level status exposes failure metadata; nested tabs[].url normalization is outside this fix. No whole-scene pixel identity is claimed. All seeds and evidence drivers are uploaded beside the recordings, not committed.

Native before/after evidence

Intended visible differences are the error message and recovery controls, hidden failed native contents, and the readable square failed frame. The supplied unmasked diffs also contain clock, scrollbar and some background/transcript layout differences; they do not establish that every changed pixel belongs to this fix. Diff0 is absolute RGB difference amplified 8×; DiffT is max-channel difference greater than 16/255. Both are shown in each linked combined sheet.

Implemented with Claude Opus 5.5 through Claude Agent; triage, runtime evidence and proof review with GPT-6.1-Sol through the Codex harness.

Checks

21 successful · 6 skipped
All checks passed
73e9c0d

Added 6 commits

  • fix(preview): a refused page shows its failure in the floating preview and preview_status202c569
  • fix(web): a refused page stays readable in a short floating preview2fbd4c8
  • Merge main into fix/issue-721269c6d53
  • test(server): reproduce issue 7212, preview status hides a refused navigation991ee02
  • fix(web): a failed page in a wide floating preview keeps room for its errorb06c58a
  • fix(web): a refused server tab keeps Take control reachable before Retryf13cc25
Synced from GitHub

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ProviderMetricMain baselineThis PRImpactPR ceiling
CodexTotal thread wire5.0 KiB5.0 KiB0 B (0.0%)6.8 KiB✅
CodexThread snapshot wire3.8 KiB3.8 KiB0 B (0.0%)4.9 KiB✅
CodexLive turn WebSocket wire1.2 KiB1.2 KiB0 B (0.0%)2.0 KiB✅
CodexLive turn WebSocket decoded20.9 KiB20.9 KiB0 B (0.0%)29.3 KiB✅
CodexLive turn messages220 (0.0%)8✅
ClaudeTotal thread wire5.0 KiB5.0 KiB0 B (0.0%)6.8 KiB✅
ClaudeThread snapshot wire3.8 KiB3.8 KiB0 B (0.0%)4.9 KiB✅
ClaudeLive turn WebSocket wire1.2 KiB1.2 KiB0 B (0.0%)2.0 KiB✅
ClaudeLive turn WebSocket decoded21.2 KiB21.2 KiB0 B (0.0%)29.3 KiB✅
ClaudeLive turn messages220 (0.0%)8✅

Baseline: c79ef8c · PR result: 73e9c0d · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 108.5 KiB
  • Claude decoded thread snapshot: 108.8 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

Added 1 commit

  • Merge origin/main into fix/issue-721273e9c0d