fix(web): retain diff selection across navigation#22347

merged5
main
GitHub fork: fix/22319-preserve-diff-selection
opened22d agobyAaleo113
View on GitHubTwo-way sync enabledPR last imported 6h ago

Problem

Selecting Uncommitted or a turn in the Diff panel is lost when returning from Settings or another thread: the panel resets to Changes.

Closes #22319.

Change

Remove the navigation-time reset so each thread retains its selected comparison. Remove the exceptions that existed only to work around that reset, including those in the extracted panel actions and commit-link handling.

Includes wrymn's adaptation to main 47f2c8d29e, preserving their original commit and authorship.

Scope and approval

This is a focused fix for the obvious reset in #22319: the selection is already stored per thread, but activating the panel overwrites it. It uses the existing store and adds no setting or persistence format.

Verification

On the integrated tree, 52 focused unit tests and 11 Chromium browser tests passed in the Linux devcontainer, including the new navigation regression. An independent GPT-6-Astra source review found no actionable findings.

The added app/router regression mounts the real app with a fake connection and checks that Uncommitted survives switching between threads, a custom comparison base remains attached to its thread, and a selected turn survives a trip to Settings.

Wrymn reports that this regression fails on baseline with branch instead of unstaged and passes with the fix, alongside 63 tests across six files. Their manual checks used an isolated macOS web client with synthetic Replay chats. See their evidence and verification details.

Baseline after returning to the threadWith the fix
Before: selection resets to ChangesAfter: Uncommitted remains selected

Recordings: before, after.

Packaged Electron and mobile were not tested.

Original fix by aleo113; adaptation by wrymn. Implemented and integrated with GPT-6.1-Sol through the Codex harness in T3 Code; reviewed with GPT-6-Astra.

Fixes pingdotgg/t3code#22319

Checks

22 successful · 16 skipped
All checks passed
df072bf

Added 1 commit

  • fix(web): retain diff selection across navigation7df8ed1
Synced from GitHub

Approvability

Verdict: Approved at 7df8ed1

Macroscope's review found this PR approvable — This is a small, focused web bug fix that removes the navigation-time reset of per-thread diff selections while preserving explicit Changes and timeline-turn selections. The affected behavior is localized to the diff panel and its tests, with no schema, configuration, or sensitive-area changes.

You can add or adjust custom eligibility rules. Learn more.

Synced from GitHub

Explain Change →

Important

Review skipped

Review was skipped as selected files did not have any reviewable changes.

External image Run configuration

External image Commits

Reviewing files that changed from the base of the PR and between 8b2f195b3503f7727fb665f9aef5c1e67b5d238b and df072bfc3944b574f2122a42960763d15642fe6d.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • Trigger review

No actionable comments were generated in the recent review.

Walkthrough

The diff panel no longer uses explicit-open tracking or one-shot keep-selection state to decide when to reset a thread’s Git scope. Commit selection no longer depends on the active panel. A browser test checks diff selections across thread navigation and turn selection after returning from Settings.

Changes: Diff selection state

Layer / File(s)Summary
Simplify commit selection state
apps/web/src/diffPanelStore.ts, apps/web/src/lib/openPullRequestLink.ts, apps/web/src/lib/openPullRequestLink.browser.test.tsx
The store no longer tracks a thread key for preserving selection on open. Commit selection no longer accepts that option, and the pull request link flow no longer checks the active panel before selecting a commit.
Remove activation-triggered selection reset
apps/web/src/components/chat/useRightPanelActions.ts, apps/web/src/components/ChatView.logic.ts, apps/web/src/components/ChatView.tsx, apps/web/src/components/ChatView.browser.test.tsx, apps/web/src/components/DiffPanel.browser.test.tsx
Diff activation and opening turn or tool diffs no longer track explicit opens. ChatView no longer resets the thread’s Git scope when the diff panel opens. The browser test checks per-thread diff selections and turn selection after navigation.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix · Severity of issue fixed: Medium

Suggested reviewers: juliusmarminge, maria-rcks

Merge Risk: External image Minimal · previous review 8b2f1

The changed navigation path retains the selected comparison. No merge-blocking issue was identified.

Architecture risk: External image Low · up to 7df8e

The change affects 1 system.

Changed systems: apps/web

Architecture concerns No architecture-level concerns identified.

Review details

Systems and components

  • observed — apps/web (ui) was modified; 3 changed files map to changed impact.

Before / after behavior

  • observed — Modified behavior in apps/web/src/components/ChatView.logic.test.ts: Added a direct type-only RightPanelSurface import while removing the prior right-panel and diff-panel store imports.
  • observed — Modified behavior in apps/web/src/components/ChatView.logic.test.ts: Removed the unused ScopedThreadRef contract import and the beforeEach test import; retained the remaining contract types and test utilities.
  • observed — Modified behavior in apps/web/src/components/ChatView.logic.test.ts: Removed the resolveExplicitDiffOpenOnActivate import from the test module.
  • observed — Modified behavior in apps/web/src/components/ChatView.logic.test.ts: Deleted the Diff scope across right-panel tab switches test suite, including its store reset setup, explicit diff-opening tracking, and assertions for preserving or resetting diff scope across panel interactions.
Pre-merge checks: Passed 4

Check nameStatusExplanation
Title checkPassedThe title is concise, uses the repository's conventional format, and clearly identifies the main change: retaining Diff selection across navigation.
Description checkPassedThe description includes Problem, Change, Scope and approval, and Verification sections. It explains the reset, the implementation, issue context, focused tests, evidence, limitations, and agent attri…
Linked Issues checkPassedIssue #22319 requires the Diff panel to retain each thread's selected comparison after thread and Settings navigation. ChatView.tsx removes the effect that selected branch when the panel opened. `…
Out of Scope Changes checkPassedThe changes remove the navigation reset, its obsolete keep-on-open state, and related action and commit-link exceptions. The added test directly covers issue #22319. No unrelated setting, persistence …
Full details: Description check

Explanation

The description includes Problem, Change, Scope and approval, and Verification sections. It explains the reset, the implementation, issue context, focused tests, evidence, limitations, and agent attribution.

Full details: Linked Issues check

Explanation

Issue #22319 requires the Diff panel to retain each thread's selected comparison after thread and Settings navigation. ChatView.tsx removes the effect that selected branch when the panel opened. diffPanelStore.ts retains the existing per-thread selection state. The new browser regression verifies unstaged, origin/release, and a selected turn across the required navigation paths.

Full details: Out of Scope Changes check

Explanation

The changes remove the navigation reset, its obsolete keep-on-open state, and related action and commit-link exceptions. The added test directly covers issue #22319. No unrelated setting, persistence format, or feature change is shown.

Finishing Touches

Generate unit tests (beta)

  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
External image Recent review info

External image Run configuration

External image Commits

Reviewing files that changed from the base of the PR and between 6a11f4c5506c692f6176eb142f83317d79924b2f and 8b2f195b3503f7727fb665f9aef5c1e67b5d238b.

External image Files selected for processing: 6

  • apps/web/src/components/ChatView.browser.test.tsx
  • apps/web/src/components/ChatView.logic.ts
  • apps/web/src/components/ChatView.tsx
  • apps/web/src/components/DiffPanel.browser.test.tsx
  • apps/web/src/lib/openPullRequestLink.browser.test.tsx
  • apps/web/src/lib/openPullRequestLink.ts
External image Files with no reviewable changes: 4

  • apps/web/src/components/DiffPanel.browser.test.tsx
  • apps/web/src/lib/openPullRequestLink.browser.test.tsx
  • apps/web/src/components/ChatView.logic.ts
  • apps/web/src/components/ChatView.tsx

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

Added 1 commit

  • fix(web): retain diff selection across chat navigation85989a2
Synced from GitHub

I adapted aleo113's fix to main @ 47f2c8d29e, including the extracted panel actions and commit-link handling: commit 85989a2238.

The commit is based directly on that main revision and is available for updating this PR. I cannot push to the author's fork and have not opened a competing PR.

It removes the navigation reset and its obsolete exceptions. Each thread retains its diff selection; explicit Changes still selects branch scope.

The app/router regression fails on baseline with branch instead of unstaged and passes with the fix. vp run check:changed upstream/main passed, including 63 tests across six files, typechecks, lint, format, unused-code checks, and React Compiler checks. Manual checks used T3's built-in browser on macOS with isolated state and synthetic Replay chats. Packaged Electron and mobile were not tested.

Baseline after return to ACandidate after return to A
Baseline: selection reset to ChangesCandidate: Uncommitted retained

Recordings: baseline, candidate.

Independent GPT-6-Astra review at medium effort found no code blockers after checking the full diff, callers, tests, recorded evidence, and contribution rules. It did not rerun tests or repeat the manual browser checks. This review applies to candidate 85989a2238, not the current PR head.

Update: aleo113 has integrated this candidate in PR head 6a11f4c550, preserving commit 85989a2238 and its authorship. GitHub's comparison shows no file differences between the reviewed candidate and the integrated head. The merge conflicts are resolved. The earlier workflow-approval note concerned the superseded head; checks and maintainer review now apply to the integrated head.

Adapted from aleo113's original fix. Implemented and verified with GPT-6.1-Sol; reviewed with GPT-6-Astra at medium effort, through the Codex harness in T3 Code.

Added 1 commit

  • fix(web): integrate updated diff-selection fix from wrymn6a11f4c
Synced from GitHub

@juliusmarminge I’ve updated this PR with @wrymn’s adaptation to current main. CI now passes, and the navigation regression is covered by an app-level test. Are there any remaining blockers to merging? I noticed the pr:gate-failed label and wanted to check whether anything still needs addressing.

Added 2 commits

  • Merge remote-tracking branch 'origin/main' into fix/22319-preserve-diff-selection8b2f195
  • Merge remote-tracking branch 'origin/main' into fix/22319-preserve-diff-selectiondf072bf

Evidence

Environment for both sides: Chromium web client, 1280×800, light theme, fresh synthetic state and completed replay turns.

Open the review thread's Diff panel and select Uncommitted. Switch to another thread and return. Base resets to Changes; head retains Uncommitted. Then select Turn 1, open Settings and close it: both retain Turn 1.

Browser driver and synthetic seed scenario

AI-assisted; verified with the tests and tools listed above.

Not shown:

  • The reported Turn 1 reset after Settings was not reproduced: opening Settings and closing it retained Turn 1 on both commits.
  • Usage navigation and custom branch comparisons were not exercised; the captured proof covers Uncommitted across thread navigation.