Skip to content

fix(web): preserve panel state across workspace refreshes - #8968

Merged
maria-rcks merged 1 commit into
pingdotgg:mainfrom
maria-rcks:t3code/preserve-diff-collapse-state
Sep 2, 2026
Merged

maria-rcks merged 1 commit into
pingdotgg:mainfrom
maria-rcks:t3code/preserve-diff-collapse-state

fix(web): preserve panel state across workspace refreshes

6ead33d
Select commit
Loading
Failed to load commit list.
MacroscopeApp / Macroscope - UI Consistency succeeded Sep 1, 2026 in 5m 31s

All clear

All clear

Details

Note

Your check run agent prompt is: .macroscope/check-run-agents/ui-consistency.md
More information about how Check Run Agents work can be found in our Help Center.


🔍 Agent activity — 9 tool calls

💭 I'm checking whether this diff affects UI consistency—the changes are mostly logic around diff rendering keys, content versions, file tree reconciliation, and a loader ref, not styling or component primitives, so I'm looking for whether the file tree reconciliation preserves expand state or other visual behavior.

1. browse_code — apps/web/src/components/files/FileBrowserPanel.tsx

2. browse_code — apps/web/src/components/diffs/AnnotatableCodeView.tsx

💭 I'm mostly examining logic correctness here—checking whether the file tree reconciliation preserves expansion state correctly, how path updates batch and order by depth, and whether newly added directories get the right initial expansion semantics. Checking the removal recursion for edge cases with directory prefix matching against sibling paths seems fine on inspection. The real question is whether this touches UI-consistency concerns like visual layout or virtualized scrolling — but this PR doesn't modify component primitives or CSS, just the virtualized shadow-DOM tree logic from @pierre/trees, so I want to dig into the query hook and model.batch semantics to see if expansion state is actually preserved.

3. browse_code — In apps/web, what does useProjectEntriesQuery return for data while loading or refreshing (undefined vs null)? Show its implementation and the underlying query hook's state shape, including whether data becomes undefined/null during a refresh or when the query key changes (e.g. cwd or environmentId change).

4. browse_code — In the @pierre/trees package (node_modules or vendored), what is FileTreeBatchOperation and what does model.batch do vs model.resetPaths? Does batch add/remove preserve existing expansion and selection state? Does an "add" operation for a nested path auto-create missing parent directories, and what happens if operations arrive in an order where a child is added before its parent directory?

💭 I'm realizing that when data goes null on a key change, the guard exits early and leaves previousTreePathsRef holding the old cwd's paths, so once the new cwd's data arrives it ends up diffing old-cwd paths against new-cwd paths—which actually seems like the correct behavior here. But I'm now noticing a real regression: previously with model.resetPaths(treePaths) and treePaths=[], the tree would clear immediately on a key change, whereas now with the early return for null data, the tree keeps showing the previous project's files while the new cwd/environment loads. That's a visible stale-UI issue when switching projects or environments. I want to check whether FileBrowserPanel gets remounted (via a key prop) when the environment or cwd changes, and whether the model itself is reused across those changes -- that would confirm whether this stale-state issue actually surfaces in practice.

5. git_tools — FileBrowserPanel

💭 Since FileBrowserPanel is keyed by environment and directory, remounts happen on key changes, so the null-data concern doesn't leak across projects and the effect logic holds. I'm noticing a discrepancy though—the file at HEAD seems longer than what I saw earlier in the diff, so I need to double check the actual line count for the default export. The line numbers don't match between what I viewed and what grep reports, suggesting I may have looked at a different revision or cached version of the file. Rather than chase that discrepancy further, I'll just verify the effect logic directly against the current HEAD to make sure the line numbers and comments line up correctly.

6. git_tools — previousTreePathsRef|buildFileTreePathUpdates|resetPaths|model.batch

💭 The line numbers check out at HEAD, so that's resolved. Now I'm scanning for UI consistency issues across shared controls, theming, scroll behavior, and layout preservation, checking whether the DiffPanel's loading logic touches any of these areas. Looking at initialExpansion and flattenEmptyDirectories settings, plus the collapsed prop stability across renders — the identity is now stable so collapse state should persist correctly, which seems fine. I'm continuing to trace the conditional loadDiffFiles logic in DiffPanel. I don't see any actual UI-consistency issue here; everything traces back to pre-existing behavior or is unverifiable without deeper library knowledge. Given the schema requires a JSON response, I'll frame this as a clean result with a success status and a summary noting no inconsistencies were found.

7. browse_code — apps/web/src/components/DiffPanel.tsx

8. browse_code — apps/web/src/components/DiffPanel.tsx

💭 I need to check if collapsedDiffFileKeys are persisted somewhere using the old render key format, since switching to identity keys could break that. I should also verify other places still using buildFileDiffRenderKey, like header prefixes, selectedDiffFileKey, and jump-to-file logic, to see if any compare against these identity keys inconsistently.

9. git_tools — buildFileDiffRenderKey|buildFileDiffIdentityKey|collapsedDiffFileKeys|fileKey

💭 I'm noting that PullRequestCodeTab still relies on the older key-building approach, but that's a separate, pre-existing surface the PR didn't intend to touch, so flagging it would overreach into unrelated cleanup. I'm also double-checking that collapse state keying with scopeKey looks consistent within DiffPanel itself. I'm confirming PullRequestCodeTab doesn't consume AnnotatableCodeView directly, so the new fileVersion prop requirement doesn't create an inconsistency there. I'm also checking the loadDiffFiles prop behavior when currentLoadDiffFiles becomes undefined during turn selection, and it seems fine, and the thrown error surfacing in the hunk-expansion UI seems acceptable too. I don't see any UI-consistency violations so far.


Agent Credits: 256 credits

Token usage: 66 uncached input · 1,251,258 cache-read input · 185,305 cache-write input · 26,141 output
Agent Credits may also include non-token charges from external tools such as web research.