Fix hidden OpenCode white page after browser refresh#460
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Root Cause
When a hidden OpenCode pane is hydrated after a browser refresh, two race conditions combine to produce a permanent white page:
Unrecoverable viewport hydrate blocked by hidden check: When a replay gap exceeds the viewport window (
replay_window_exceeded), theisUnrecoverableOpenCodeViewportHydratepredicate requires!hiddenRef.current. A hidden pane can never satisfy this condition, so it never enters the replacement path — it stays stuck showing nothing.Attach race before extensions registry loads: The "Create or attach to backend terminal" useEffect fires before the extensions registry is ready (
shouldWaitForProviderBehavioris true). This causes a premature attach attempt that races with the OpenCode sidecar initialization, producing a broken terminal state.Fix (two parts)
Part 1 — Allow hidden OpenCode viewport hydrations to enter replacement path:
Remove
!hiddenRef.currentfromisUnrecoverableOpenCodeViewportHydrateinsrc/components/TerminalView.tsx. Hidden panes with replay gaps can now triggerbeginOpenCodeReplacementAfterExit, which re-creates the terminal session once the pane becomes visible.Part 2 — Guard create/attach useEffect against provider-behavior wait:
Add
if (shouldWaitForProviderBehavior) returnto the "Create or attach to backend terminal" useEffect. This prevents the attach race until the extensions registry has loaded, ensuring the OpenCode sidecar is ready before any terminal attach is attempted.Tests
test/unit/client/components/TerminalView.lifecycle.test.tsx— 126 tests covering the hidden viewport hydration path and the provider-behavior wait guard.test/e2e-browser/specs/opencode-restart-recovery.spec.ts— 5 Playwright tests covering OpenCode pane recovery across browser refresh, server restart, and hidden-pane association scenarios.Rebase status
Rebased cleanly onto
origin/main(54 commits behind). Only one main commit touchedTerminalView.tsx(#444electron link-clicking, unrelated area). No conflicts.Kata: y1xn