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

fix(web): preserve panel state across workspace refreshes#8968
maria-rcks merged 1 commit into
pingdotgg:mainfrom
maria-rcks:t3code/preserve-diff-collapse-state

Conversation

@maria-rcks

@maria-rcksmaria-rcks commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

Workspace refreshes no longer reset collapsed diff files or rebuild the file tree. The diff now separates stable file identity from per-file content versions, while the file browser applies incremental path changes so unchanged elements stay mounted.

Verified with 12 focused tests, targeted lint and formatting, web typecheck, and the matched UI evidence below.

Evidence

Base: state lost after refreshBranch: state preserved after refresh
Base after refresh expands both filesBranch after refresh keeps five files collapsed

Watch the real-app agent edit test

Real app flow: the branch diff stays open while GPT-5.6-Sol edits the expanded file; the other files remain collapsed through the live refresh.

Written with gpt-5.6-sol in the Codex harness.


Note

Low Risk
UI state and reconciliation logic only; no auth, data persistence, or API contract changes. Risk is mainly regressions in diff rendering or file tree sync after refresh.

Overview
Workspace refreshes no longer wipe collapsed diff files or rebuild the entire file tree from scratch. The diff panel now tracks each file with a stable identity key (previous + current paths) separate from a per-file content version, so unchanged files keep collapse state and only edited files get a new render version in AnnotatableCodeView.

DiffPanel also exposes loadDiffFiles through a stable ref-backed callback so CodeView options do not churn when the git loader is recreated on refresh.

The file browser applies incremental path add/remove batches via buildFileTreePathUpdates instead of resetPaths on every entry refresh; the first successful load still resets the tree. It skips reconciliation until entries have loaded (entriesQuery.data !== null).

Reviewed by Cursor Bugbot for commit 6ead33d. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Preserve diff panel and file tree state across workspace refreshes

  • DiffPanel now identifies diff files by previous/current path via buildFileDiffIdentityKey instead of the cache key, and computes a per-file content version with buildFileDiffContentVersion so only changed files re-render.
  • AnnotatableCodeView prepends fileVersion into its item version hash, limiting reconciliation to files whose diff content actually changed.
  • FileBrowserPanel replaces full tree resets with incremental batched updates: new buildFileTreePathUpdates computes a minimal set of add/remove operations, collapsing deleted subtrees into a single recursive remove.
  • Risk: previousTreePathsRef in FileBrowserPanel.tsx now starts as null; first population calls model.resetPaths while subsequent updates rely on buildFileTreePathUpdates correctness — any path-order mismatch could produce stale tree nodes.

Macroscope summarized 6ead33d.

Summary by CodeRabbit

  • Bug Fixes

    • Improved diff rendering so file identity remains stable while content updates refresh correctly.
    • Preserved code annotations and view state more reliably when file contents change.
    • Improved file browser synchronization by applying only incremental path changes.
    • Correctly handles deleted folders and unchanged file trees.
  • Tests

    • Added coverage for diff versioning and file tree path reconciliation.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 31, 2026
Comment threadapps/web/src/lib/diffRendering.ts
@coderabbitai

coderabbitaiBot commented Aug 31, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Team

Run ID: f012d321-79f9-4510-947c-39c0108b6084

📥 Commits

Reviewing files that changed from the base of the PR and between 41adccc and cbb0b3d.

📒 Files selected for processing (7)
  • apps/web/src/components/DiffPanel.tsx
  • apps/web/src/components/diffs/AnnotatableCodeView.tsx
  • apps/web/src/components/files/FileBrowserPanel.tsx
  • apps/web/src/components/files/fileTreePathReconciliation.test.ts
  • apps/web/src/components/files/fileTreePathReconciliation.ts
  • apps/web/src/lib/diffRendering.test.ts
  • apps/web/src/lib/diffRendering.ts

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


📝 Walkthrough

Walkthrough

The diff view now separates file identity from content versioning and stabilizes file loading callbacks. The file browser now reconciles tree paths incrementally, including recursive subtree removal.

Changes

Diff reconciliation

Layer / File(s)Summary
Diff identity and content versioning
apps/web/src/lib/diffRendering.ts, apps/web/src/lib/diffRendering.test.ts, apps/web/src/components/DiffPanel.tsx, apps/web/src/components/diffs/AnnotatableCodeView.tsx
The diff view uses stable identity keys and deterministic content versions. Content versions now affect annotatable code view item versions. Tests cover unchanged and changed files across diff versions.
Diff content loader stability
apps/web/src/components/DiffPanel.tsx
The current file-content loader is tracked separately from a stable callback. The callback delegates through a ref and throws when no loader is available.

File tree reconciliation

Layer / File(s)Summary
Incremental file tree synchronization
apps/web/src/components/files/FileBrowserPanel.tsx, apps/web/src/components/files/fileTreePathReconciliation.ts, apps/web/src/components/files/fileTreePathReconciliation.test.ts
The file browser resets paths only on the first populated run. Later changes use batched additions and removals. Deleted directory subtrees use recursive removal, with tests for changed, deleted, and identical paths.

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

Merge Risk:⚪ Minimal · up to cbb0b

This change preserves diff collapse state and incrementally updates the file tree during workspace refreshes; no actionable merge-blocking risk remains after normal checks and review.

Suggested reviewers:juliusmarminge, stienswout

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 18.18% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 11 functions across 7 files.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
Title check✅ PassedThe title clearly and concisely describes the primary change: preserving panel state across workspace refreshes.
Description check✅ PassedThe description explains what changed, why it changed, verification performed, and UI evidence. It omits the template headings and checklist, but it provides the required information and is substantia…
Full details: Description check

Explanation

The description explains what changed, why it changed, verification performed, and UI evidence. It omits the template headings and checklist, but it provides the required information and is substantially complete.

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@macroscopeapp

macroscopeappBot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 6ead33d

Macroscope's review found this PR approvable — This is a focused web bug fix that preserves existing file-tree and diff-panel state during refreshes using localized reconciliation and per-file rendering versions. The changes are self-contained, tested, and introduce no schema, security, billing, deployment, or static-analysis configuration impact.

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

macroscopeapp[bot]
macroscopeappBot previously approved these changes Aug 31, 2026
@maria-rcks
maria-rcksforce-pushed the t3code/preserve-diff-collapse-state branch from cbb0b3d to ad8549aCompareSeptember 1, 2026 16:55

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit ad8549a. Configure here.

Comment threadapps/web/src/components/DiffPanel.tsx
@maria-rcks
maria-rcksforce-pushed the t3code/preserve-diff-collapse-state branch from ad8549a to 6ead33dCompareSeptember 1, 2026 17:09
@macroscopeapp
macroscopeappBot dismissed their stale reviewSeptember 1, 2026 17:09

Dismissing prior approval to re-evaluate 6ead33d

@maria-rcks
maria-rcks merged commit f2a914b into pingdotgg:mainSep 2, 2026
26 of 27 checks passed
dascapytal1559 added a commit to dascapytal1559/t3code that referenced this pull request Sep 2, 2026
Conflict resolutions:
- Claude $skill: adopt upstream's last-block dispatch (pingdotgg#9128). Drop the
fork's in-place $→/ rewrite on the Claude send path so the dispatcher
still sees $ tokens. Ultrathink wrapping a leading $skill is now safe
(prefix in the leading text block, command block still starts with
/name). Keep the Grok $→/ rewrite.
- Mobile composer menus: keep cwd-scoped composerSkills; apply upstream's
user-invocable filter and dedupe on that list. Path search now imports
from state/queries (upstream deleted the dedicated hook).
- Files surface: keep lazy explorer listDirectory/readDirectoryChildren;
adopt upstream's expandHomePathWith. Legacy (non-lazy) tree uses
incremental path updates (pingdotgg#8968) plus the fork's symlink badges and
ignored git status.
- Tilde paths: skip ~/ inline-code candidates in the shared
markdownLinks helper upstream extracted from web.
Pre-sync fork: backup/upstream-test-drive-pre-sync-20260902 (d4f79f8).
github-actionsBot added a commit to omarcresp/t3code-flake that referenced this pull request Sep 2, 2026
## What's Changed
* perf(client-runtime): keep turn and checkpoint refs stable while streaming by @t3dotgg in pingdotgg/t3code#9145
* perf(clients): lease sidebar status by visibility by @StiensWout in pingdotgg/t3code#9052
* fix(desktop): show newest changes in nightly previews by @t3dotgg in pingdotgg/t3code#9138
* fix(settings): sync auto-settle and other shared preferences across environments by @t3dotgg in pingdotgg/t3code#9147
* fix(server): prevent accidental service downgrades by @t3dotgg in pingdotgg/t3code#5302
* fix(server): keep attachments until the command commits by @t3dotgg in pingdotgg/t3code#7941
* fix(claude): preview images read from the workspace by @t3dotgg in pingdotgg/t3code#9119
* fix(web): keep generated muted foreground dimmer than entered text by @flamboh in pingdotgg/t3code#9113
* fix(clients): stop repeating expanded commands by @t3dotgg in pingdotgg/t3code#9120
* fix(grok): health check, model selection, and stop all work against the real CLI by @t3dotgg in pingdotgg/t3code#9154
* perf(web): halve the cold-start bundle by splitting Clerk and cold routes by @StiensWout in pingdotgg/t3code#9058
* feat(desktop): update the desktop app on remote Macs from the Update button by @t3dotgg in pingdotgg/t3code#6554
* test(server): measure shell, second client, and reconnect transfer by @t3dotgg in pingdotgg/t3code#9157
* fix(web): project default model works on the hosted app by @juliusmarminge in pingdotgg/t3code#9142
* fix(web): darken neutral control surfaces by @maria-rcks in pingdotgg/t3code#9064
* fix(web): preserve panel state across workspace refreshes by @maria-rcks in pingdotgg/t3code#8968
* feat(files): open markdown, HTML, and PDF files outside the workspace by @juliusmarminge in pingdotgg/t3code#9140
* feat(web): render HTML and PDF files in the file viewer by @juliusmarminge in pingdotgg/t3code#9143
* fix(web): compact project settings actions by @maria-rcks in pingdotgg/t3code#9160
* fix(web): browse folders from file breadcrumbs by @404khai in pingdotgg/t3code#8910
## New Contributors
* @404khai made their first contribution in pingdotgg/t3code#8910
**Full Changelog**: pingdotgg/t3code@v0.0.39-nightly.20260902.1252...v0.0.39-nightly.20260902.1253
Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.39-nightly.20260902.1253
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@maria-rcks
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
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

fix(web): preserve panel state across workspace refreshes#8968
maria-rcks merged 1 commit into
pingdotgg:mainfrom
maria-rcks:t3code/preserve-diff-collapse-state

Conversation

@maria-rcks

@maria-rcksmaria-rcks commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

Workspace refreshes no longer reset collapsed diff files or rebuild the file tree. The diff now separates stable file identity from per-file content versions, while the file browser applies incremental path changes so unchanged elements stay mounted.

Verified with 12 focused tests, targeted lint and formatting, web typecheck, and the matched UI evidence below.

Evidence

Base: state lost after refreshBranch: state preserved after refresh
Base after refresh expands both filesBranch after refresh keeps five files collapsed

Watch the real-app agent edit test

Real app flow: the branch diff stays open while GPT-5.6-Sol edits the expanded file; the other files remain collapsed through the live refresh.

Written with gpt-5.6-sol in the Codex harness.


Note

Low Risk
UI state and reconciliation logic only; no auth, data persistence, or API contract changes. Risk is mainly regressions in diff rendering or file tree sync after refresh.

Overview
Workspace refreshes no longer wipe collapsed diff files or rebuild the entire file tree from scratch. The diff panel now tracks each file with a stable identity key (previous + current paths) separate from a per-file content version, so unchanged files keep collapse state and only edited files get a new render version in AnnotatableCodeView.

DiffPanel also exposes loadDiffFiles through a stable ref-backed callback so CodeView options do not churn when the git loader is recreated on refresh.

The file browser applies incremental path add/remove batches via buildFileTreePathUpdates instead of resetPaths on every entry refresh; the first successful load still resets the tree. It skips reconciliation until entries have loaded (entriesQuery.data !== null).

Reviewed by Cursor Bugbot for commit 6ead33d. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Preserve diff panel and file tree state across workspace refreshes

  • DiffPanel now identifies diff files by previous/current path via buildFileDiffIdentityKey instead of the cache key, and computes a per-file content version with buildFileDiffContentVersion so only changed files re-render.
  • AnnotatableCodeView prepends fileVersion into its item version hash, limiting reconciliation to files whose diff content actually changed.
  • FileBrowserPanel replaces full tree resets with incremental batched updates: new buildFileTreePathUpdates computes a minimal set of add/remove operations, collapsing deleted subtrees into a single recursive remove.
  • Risk: previousTreePathsRef in FileBrowserPanel.tsx now starts as null; first population calls model.resetPaths while subsequent updates rely on buildFileTreePathUpdates correctness — any path-order mismatch could produce stale tree nodes.

Macroscope summarized 6ead33d.

Summary by CodeRabbit

  • Bug Fixes

    • Improved diff rendering so file identity remains stable while content updates refresh correctly.
    • Preserved code annotations and view state more reliably when file contents change.
    • Improved file browser synchronization by applying only incremental path changes.
    • Correctly handles deleted folders and unchanged file trees.
  • Tests

    • Added coverage for diff versioning and file tree path reconciliation.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 31, 2026
Comment threadapps/web/src/lib/diffRendering.ts
@coderabbitai

coderabbitaiBot commented Aug 31, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Team

Run ID: f012d321-79f9-4510-947c-39c0108b6084

📥 Commits

Reviewing files that changed from the base of the PR and between 41adccc and cbb0b3d.

📒 Files selected for processing (7)
  • apps/web/src/components/DiffPanel.tsx
  • apps/web/src/components/diffs/AnnotatableCodeView.tsx
  • apps/web/src/components/files/FileBrowserPanel.tsx
  • apps/web/src/components/files/fileTreePathReconciliation.test.ts
  • apps/web/src/components/files/fileTreePathReconciliation.ts
  • apps/web/src/lib/diffRendering.test.ts
  • apps/web/src/lib/diffRendering.ts

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


📝 Walkthrough

Walkthrough

The diff view now separates file identity from content versioning and stabilizes file loading callbacks. The file browser now reconciles tree paths incrementally, including recursive subtree removal.

Changes

Diff reconciliation

Layer / File(s)Summary
Diff identity and content versioning
apps/web/src/lib/diffRendering.ts, apps/web/src/lib/diffRendering.test.ts, apps/web/src/components/DiffPanel.tsx, apps/web/src/components/diffs/AnnotatableCodeView.tsx
The diff view uses stable identity keys and deterministic content versions. Content versions now affect annotatable code view item versions. Tests cover unchanged and changed files across diff versions.
Diff content loader stability
apps/web/src/components/DiffPanel.tsx
The current file-content loader is tracked separately from a stable callback. The callback delegates through a ref and throws when no loader is available.

File tree reconciliation

Layer / File(s)Summary
Incremental file tree synchronization
apps/web/src/components/files/FileBrowserPanel.tsx, apps/web/src/components/files/fileTreePathReconciliation.ts, apps/web/src/components/files/fileTreePathReconciliation.test.ts
The file browser resets paths only on the first populated run. Later changes use batched additions and removals. Deleted directory subtrees use recursive removal, with tests for changed, deleted, and identical paths.

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

Merge Risk:⚪ Minimal · up to cbb0b

This change preserves diff collapse state and incrementally updates the file tree during workspace refreshes; no actionable merge-blocking risk remains after normal checks and review.

Suggested reviewers:juliusmarminge, stienswout

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 18.18% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 11 functions across 7 files.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
Title check✅ PassedThe title clearly and concisely describes the primary change: preserving panel state across workspace refreshes.
Description check✅ PassedThe description explains what changed, why it changed, verification performed, and UI evidence. It omits the template headings and checklist, but it provides the required information and is substantia…
Full details: Description check

Explanation

The description explains what changed, why it changed, verification performed, and UI evidence. It omits the template headings and checklist, but it provides the required information and is substantially complete.

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@macroscopeapp

macroscopeappBot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 6ead33d

Macroscope's review found this PR approvable — This is a focused web bug fix that preserves existing file-tree and diff-panel state during refreshes using localized reconciliation and per-file rendering versions. The changes are self-contained, tested, and introduce no schema, security, billing, deployment, or static-analysis configuration impact.

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

macroscopeapp[bot]
macroscopeappBot previously approved these changes Aug 31, 2026
@maria-rcks
maria-rcksforce-pushed the t3code/preserve-diff-collapse-state branch from cbb0b3d to ad8549aCompareSeptember 1, 2026 16:55

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit ad8549a. Configure here.

Comment threadapps/web/src/components/DiffPanel.tsx
@maria-rcks
maria-rcksforce-pushed the t3code/preserve-diff-collapse-state branch from ad8549a to 6ead33dCompareSeptember 1, 2026 17:09
@macroscopeapp
macroscopeappBot dismissed their stale reviewSeptember 1, 2026 17:09

Dismissing prior approval to re-evaluate 6ead33d

@maria-rcks
maria-rcks merged commit f2a914b into pingdotgg:mainSep 2, 2026
26 of 27 checks passed
dascapytal1559 added a commit to dascapytal1559/t3code that referenced this pull request Sep 2, 2026
Conflict resolutions:
- Claude $skill: adopt upstream's last-block dispatch (pingdotgg#9128). Drop the
fork's in-place $→/ rewrite on the Claude send path so the dispatcher
still sees $ tokens. Ultrathink wrapping a leading $skill is now safe
(prefix in the leading text block, command block still starts with
/name). Keep the Grok $→/ rewrite.
- Mobile composer menus: keep cwd-scoped composerSkills; apply upstream's
user-invocable filter and dedupe on that list. Path search now imports
from state/queries (upstream deleted the dedicated hook).
- Files surface: keep lazy explorer listDirectory/readDirectoryChildren;
adopt upstream's expandHomePathWith. Legacy (non-lazy) tree uses
incremental path updates (pingdotgg#8968) plus the fork's symlink badges and
ignored git status.
- Tilde paths: skip ~/ inline-code candidates in the shared
markdownLinks helper upstream extracted from web.
Pre-sync fork: backup/upstream-test-drive-pre-sync-20260902 (d4f79f8).
github-actionsBot added a commit to omarcresp/t3code-flake that referenced this pull request Sep 2, 2026
## What's Changed
* perf(client-runtime): keep turn and checkpoint refs stable while streaming by @t3dotgg in pingdotgg/t3code#9145
* perf(clients): lease sidebar status by visibility by @StiensWout in pingdotgg/t3code#9052
* fix(desktop): show newest changes in nightly previews by @t3dotgg in pingdotgg/t3code#9138
* fix(settings): sync auto-settle and other shared preferences across environments by @t3dotgg in pingdotgg/t3code#9147
* fix(server): prevent accidental service downgrades by @t3dotgg in pingdotgg/t3code#5302
* fix(server): keep attachments until the command commits by @t3dotgg in pingdotgg/t3code#7941
* fix(claude): preview images read from the workspace by @t3dotgg in pingdotgg/t3code#9119
* fix(web): keep generated muted foreground dimmer than entered text by @flamboh in pingdotgg/t3code#9113
* fix(clients): stop repeating expanded commands by @t3dotgg in pingdotgg/t3code#9120
* fix(grok): health check, model selection, and stop all work against the real CLI by @t3dotgg in pingdotgg/t3code#9154
* perf(web): halve the cold-start bundle by splitting Clerk and cold routes by @StiensWout in pingdotgg/t3code#9058
* feat(desktop): update the desktop app on remote Macs from the Update button by @t3dotgg in pingdotgg/t3code#6554
* test(server): measure shell, second client, and reconnect transfer by @t3dotgg in pingdotgg/t3code#9157
* fix(web): project default model works on the hosted app by @juliusmarminge in pingdotgg/t3code#9142
* fix(web): darken neutral control surfaces by @maria-rcks in pingdotgg/t3code#9064
* fix(web): preserve panel state across workspace refreshes by @maria-rcks in pingdotgg/t3code#8968
* feat(files): open markdown, HTML, and PDF files outside the workspace by @juliusmarminge in pingdotgg/t3code#9140
* feat(web): render HTML and PDF files in the file viewer by @juliusmarminge in pingdotgg/t3code#9143
* fix(web): compact project settings actions by @maria-rcks in pingdotgg/t3code#9160
* fix(web): browse folders from file breadcrumbs by @404khai in pingdotgg/t3code#8910
## New Contributors
* @404khai made their first contribution in pingdotgg/t3code#8910
**Full Changelog**: pingdotgg/t3code@v0.0.39-nightly.20260902.1252...v0.0.39-nightly.20260902.1253
Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.39-nightly.20260902.1253
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@maria-rcks
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
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

fix(web): preserve panel state across workspace refreshes#8968
maria-rcks merged 1 commit into
pingdotgg:mainfrom
maria-rcks:t3code/preserve-diff-collapse-state

Conversation

@maria-rcks

@maria-rcksmaria-rcks commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

Workspace refreshes no longer reset collapsed diff files or rebuild the file tree. The diff now separates stable file identity from per-file content versions, while the file browser applies incremental path changes so unchanged elements stay mounted.

Verified with 12 focused tests, targeted lint and formatting, web typecheck, and the matched UI evidence below.

Evidence

Base: state lost after refreshBranch: state preserved after refresh
Base after refresh expands both filesBranch after refresh keeps five files collapsed

Watch the real-app agent edit test

Real app flow: the branch diff stays open while GPT-5.6-Sol edits the expanded file; the other files remain collapsed through the live refresh.

Written with gpt-5.6-sol in the Codex harness.


Note

Low Risk
UI state and reconciliation logic only; no auth, data persistence, or API contract changes. Risk is mainly regressions in diff rendering or file tree sync after refresh.

Overview
Workspace refreshes no longer wipe collapsed diff files or rebuild the entire file tree from scratch. The diff panel now tracks each file with a stable identity key (previous + current paths) separate from a per-file content version, so unchanged files keep collapse state and only edited files get a new render version in AnnotatableCodeView.

DiffPanel also exposes loadDiffFiles through a stable ref-backed callback so CodeView options do not churn when the git loader is recreated on refresh.

The file browser applies incremental path add/remove batches via buildFileTreePathUpdates instead of resetPaths on every entry refresh; the first successful load still resets the tree. It skips reconciliation until entries have loaded (entriesQuery.data !== null).

Reviewed by Cursor Bugbot for commit 6ead33d. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Preserve diff panel and file tree state across workspace refreshes

  • DiffPanel now identifies diff files by previous/current path via buildFileDiffIdentityKey instead of the cache key, and computes a per-file content version with buildFileDiffContentVersion so only changed files re-render.
  • AnnotatableCodeView prepends fileVersion into its item version hash, limiting reconciliation to files whose diff content actually changed.
  • FileBrowserPanel replaces full tree resets with incremental batched updates: new buildFileTreePathUpdates computes a minimal set of add/remove operations, collapsing deleted subtrees into a single recursive remove.
  • Risk: previousTreePathsRef in FileBrowserPanel.tsx now starts as null; first population calls model.resetPaths while subsequent updates rely on buildFileTreePathUpdates correctness — any path-order mismatch could produce stale tree nodes.

Macroscope summarized 6ead33d.

Summary by CodeRabbit

  • Bug Fixes

    • Improved diff rendering so file identity remains stable while content updates refresh correctly.
    • Preserved code annotations and view state more reliably when file contents change.
    • Improved file browser synchronization by applying only incremental path changes.
    • Correctly handles deleted folders and unchanged file trees.
  • Tests

    • Added coverage for diff versioning and file tree path reconciliation.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 31, 2026
Comment threadapps/web/src/lib/diffRendering.ts
@coderabbitai

coderabbitaiBot commented Aug 31, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Team

Run ID: f012d321-79f9-4510-947c-39c0108b6084

📥 Commits

Reviewing files that changed from the base of the PR and between 41adccc and cbb0b3d.

📒 Files selected for processing (7)
  • apps/web/src/components/DiffPanel.tsx
  • apps/web/src/components/diffs/AnnotatableCodeView.tsx
  • apps/web/src/components/files/FileBrowserPanel.tsx
  • apps/web/src/components/files/fileTreePathReconciliation.test.ts
  • apps/web/src/components/files/fileTreePathReconciliation.ts
  • apps/web/src/lib/diffRendering.test.ts
  • apps/web/src/lib/diffRendering.ts

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


📝 Walkthrough

Walkthrough

The diff view now separates file identity from content versioning and stabilizes file loading callbacks. The file browser now reconciles tree paths incrementally, including recursive subtree removal.

Changes

Diff reconciliation

Layer / File(s)Summary
Diff identity and content versioning
apps/web/src/lib/diffRendering.ts, apps/web/src/lib/diffRendering.test.ts, apps/web/src/components/DiffPanel.tsx, apps/web/src/components/diffs/AnnotatableCodeView.tsx
The diff view uses stable identity keys and deterministic content versions. Content versions now affect annotatable code view item versions. Tests cover unchanged and changed files across diff versions.
Diff content loader stability
apps/web/src/components/DiffPanel.tsx
The current file-content loader is tracked separately from a stable callback. The callback delegates through a ref and throws when no loader is available.

File tree reconciliation

Layer / File(s)Summary
Incremental file tree synchronization
apps/web/src/components/files/FileBrowserPanel.tsx, apps/web/src/components/files/fileTreePathReconciliation.ts, apps/web/src/components/files/fileTreePathReconciliation.test.ts
The file browser resets paths only on the first populated run. Later changes use batched additions and removals. Deleted directory subtrees use recursive removal, with tests for changed, deleted, and identical paths.

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

Merge Risk:⚪ Minimal · up to cbb0b

This change preserves diff collapse state and incrementally updates the file tree during workspace refreshes; no actionable merge-blocking risk remains after normal checks and review.

Suggested reviewers:juliusmarminge, stienswout

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 18.18% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 11 functions across 7 files.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
Title check✅ PassedThe title clearly and concisely describes the primary change: preserving panel state across workspace refreshes.
Description check✅ PassedThe description explains what changed, why it changed, verification performed, and UI evidence. It omits the template headings and checklist, but it provides the required information and is substantia…
Full details: Description check

Explanation

The description explains what changed, why it changed, verification performed, and UI evidence. It omits the template headings and checklist, but it provides the required information and is substantially complete.

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@macroscopeapp

macroscopeappBot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 6ead33d

Macroscope's review found this PR approvable — This is a focused web bug fix that preserves existing file-tree and diff-panel state during refreshes using localized reconciliation and per-file rendering versions. The changes are self-contained, tested, and introduce no schema, security, billing, deployment, or static-analysis configuration impact.

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

macroscopeapp[bot]
macroscopeappBot previously approved these changes Aug 31, 2026
@maria-rcks
maria-rcksforce-pushed the t3code/preserve-diff-collapse-state branch from cbb0b3d to ad8549aCompareSeptember 1, 2026 16:55

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit ad8549a. Configure here.

Comment threadapps/web/src/components/DiffPanel.tsx
@maria-rcks
maria-rcksforce-pushed the t3code/preserve-diff-collapse-state branch from ad8549a to 6ead33dCompareSeptember 1, 2026 17:09
@macroscopeapp
macroscopeappBot dismissed their stale reviewSeptember 1, 2026 17:09

Dismissing prior approval to re-evaluate 6ead33d

@maria-rcks
maria-rcks merged commit f2a914b into pingdotgg:mainSep 2, 2026
26 of 27 checks passed
dascapytal1559 added a commit to dascapytal1559/t3code that referenced this pull request Sep 2, 2026
Conflict resolutions:
- Claude $skill: adopt upstream's last-block dispatch (pingdotgg#9128). Drop the
fork's in-place $→/ rewrite on the Claude send path so the dispatcher
still sees $ tokens. Ultrathink wrapping a leading $skill is now safe
(prefix in the leading text block, command block still starts with
/name). Keep the Grok $→/ rewrite.
- Mobile composer menus: keep cwd-scoped composerSkills; apply upstream's
user-invocable filter and dedupe on that list. Path search now imports
from state/queries (upstream deleted the dedicated hook).
- Files surface: keep lazy explorer listDirectory/readDirectoryChildren;
adopt upstream's expandHomePathWith. Legacy (non-lazy) tree uses
incremental path updates (pingdotgg#8968) plus the fork's symlink badges and
ignored git status.
- Tilde paths: skip ~/ inline-code candidates in the shared
markdownLinks helper upstream extracted from web.
Pre-sync fork: backup/upstream-test-drive-pre-sync-20260902 (d4f79f8).
github-actionsBot added a commit to omarcresp/t3code-flake that referenced this pull request Sep 2, 2026
## What's Changed
* perf(client-runtime): keep turn and checkpoint refs stable while streaming by @t3dotgg in pingdotgg/t3code#9145
* perf(clients): lease sidebar status by visibility by @StiensWout in pingdotgg/t3code#9052
* fix(desktop): show newest changes in nightly previews by @t3dotgg in pingdotgg/t3code#9138
* fix(settings): sync auto-settle and other shared preferences across environments by @t3dotgg in pingdotgg/t3code#9147
* fix(server): prevent accidental service downgrades by @t3dotgg in pingdotgg/t3code#5302
* fix(server): keep attachments until the command commits by @t3dotgg in pingdotgg/t3code#7941
* fix(claude): preview images read from the workspace by @t3dotgg in pingdotgg/t3code#9119
* fix(web): keep generated muted foreground dimmer than entered text by @flamboh in pingdotgg/t3code#9113
* fix(clients): stop repeating expanded commands by @t3dotgg in pingdotgg/t3code#9120
* fix(grok): health check, model selection, and stop all work against the real CLI by @t3dotgg in pingdotgg/t3code#9154
* perf(web): halve the cold-start bundle by splitting Clerk and cold routes by @StiensWout in pingdotgg/t3code#9058
* feat(desktop): update the desktop app on remote Macs from the Update button by @t3dotgg in pingdotgg/t3code#6554
* test(server): measure shell, second client, and reconnect transfer by @t3dotgg in pingdotgg/t3code#9157
* fix(web): project default model works on the hosted app by @juliusmarminge in pingdotgg/t3code#9142
* fix(web): darken neutral control surfaces by @maria-rcks in pingdotgg/t3code#9064
* fix(web): preserve panel state across workspace refreshes by @maria-rcks in pingdotgg/t3code#8968
* feat(files): open markdown, HTML, and PDF files outside the workspace by @juliusmarminge in pingdotgg/t3code#9140
* feat(web): render HTML and PDF files in the file viewer by @juliusmarminge in pingdotgg/t3code#9143
* fix(web): compact project settings actions by @maria-rcks in pingdotgg/t3code#9160
* fix(web): browse folders from file breadcrumbs by @404khai in pingdotgg/t3code#8910
## New Contributors
* @404khai made their first contribution in pingdotgg/t3code#8910
**Full Changelog**: pingdotgg/t3code@v0.0.39-nightly.20260902.1252...v0.0.39-nightly.20260902.1253
Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.39-nightly.20260902.1253
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@maria-rcks
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
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

fix(web): preserve panel state across workspace refreshes#8968
maria-rcks merged 1 commit into
pingdotgg:mainfrom
maria-rcks:t3code/preserve-diff-collapse-state

Conversation

@maria-rcks

@maria-rcksmaria-rcks commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

Workspace refreshes no longer reset collapsed diff files or rebuild the file tree. The diff now separates stable file identity from per-file content versions, while the file browser applies incremental path changes so unchanged elements stay mounted.

Verified with 12 focused tests, targeted lint and formatting, web typecheck, and the matched UI evidence below.

Evidence

Base: state lost after refreshBranch: state preserved after refresh
Base after refresh expands both filesBranch after refresh keeps five files collapsed

Watch the real-app agent edit test

Real app flow: the branch diff stays open while GPT-5.6-Sol edits the expanded file; the other files remain collapsed through the live refresh.

Written with gpt-5.6-sol in the Codex harness.


Note

Low Risk
UI state and reconciliation logic only; no auth, data persistence, or API contract changes. Risk is mainly regressions in diff rendering or file tree sync after refresh.

Overview
Workspace refreshes no longer wipe collapsed diff files or rebuild the entire file tree from scratch. The diff panel now tracks each file with a stable identity key (previous + current paths) separate from a per-file content version, so unchanged files keep collapse state and only edited files get a new render version in AnnotatableCodeView.

DiffPanel also exposes loadDiffFiles through a stable ref-backed callback so CodeView options do not churn when the git loader is recreated on refresh.

The file browser applies incremental path add/remove batches via buildFileTreePathUpdates instead of resetPaths on every entry refresh; the first successful load still resets the tree. It skips reconciliation until entries have loaded (entriesQuery.data !== null).

Reviewed by Cursor Bugbot for commit 6ead33d. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Preserve diff panel and file tree state across workspace refreshes

  • DiffPanel now identifies diff files by previous/current path via buildFileDiffIdentityKey instead of the cache key, and computes a per-file content version with buildFileDiffContentVersion so only changed files re-render.
  • AnnotatableCodeView prepends fileVersion into its item version hash, limiting reconciliation to files whose diff content actually changed.
  • FileBrowserPanel replaces full tree resets with incremental batched updates: new buildFileTreePathUpdates computes a minimal set of add/remove operations, collapsing deleted subtrees into a single recursive remove.
  • Risk: previousTreePathsRef in FileBrowserPanel.tsx now starts as null; first population calls model.resetPaths while subsequent updates rely on buildFileTreePathUpdates correctness — any path-order mismatch could produce stale tree nodes.

Macroscope summarized 6ead33d.

Summary by CodeRabbit

  • Bug Fixes

    • Improved diff rendering so file identity remains stable while content updates refresh correctly.
    • Preserved code annotations and view state more reliably when file contents change.
    • Improved file browser synchronization by applying only incremental path changes.
    • Correctly handles deleted folders and unchanged file trees.
  • Tests

    • Added coverage for diff versioning and file tree path reconciliation.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 31, 2026
Comment threadapps/web/src/lib/diffRendering.ts
@coderabbitai

coderabbitaiBot commented Aug 31, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Team

Run ID: f012d321-79f9-4510-947c-39c0108b6084

📥 Commits

Reviewing files that changed from the base of the PR and between 41adccc and cbb0b3d.

📒 Files selected for processing (7)
  • apps/web/src/components/DiffPanel.tsx
  • apps/web/src/components/diffs/AnnotatableCodeView.tsx
  • apps/web/src/components/files/FileBrowserPanel.tsx
  • apps/web/src/components/files/fileTreePathReconciliation.test.ts
  • apps/web/src/components/files/fileTreePathReconciliation.ts
  • apps/web/src/lib/diffRendering.test.ts
  • apps/web/src/lib/diffRendering.ts

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


📝 Walkthrough

Walkthrough

The diff view now separates file identity from content versioning and stabilizes file loading callbacks. The file browser now reconciles tree paths incrementally, including recursive subtree removal.

Changes

Diff reconciliation

Layer / File(s)Summary
Diff identity and content versioning
apps/web/src/lib/diffRendering.ts, apps/web/src/lib/diffRendering.test.ts, apps/web/src/components/DiffPanel.tsx, apps/web/src/components/diffs/AnnotatableCodeView.tsx
The diff view uses stable identity keys and deterministic content versions. Content versions now affect annotatable code view item versions. Tests cover unchanged and changed files across diff versions.
Diff content loader stability
apps/web/src/components/DiffPanel.tsx
The current file-content loader is tracked separately from a stable callback. The callback delegates through a ref and throws when no loader is available.

File tree reconciliation

Layer / File(s)Summary
Incremental file tree synchronization
apps/web/src/components/files/FileBrowserPanel.tsx, apps/web/src/components/files/fileTreePathReconciliation.ts, apps/web/src/components/files/fileTreePathReconciliation.test.ts
The file browser resets paths only on the first populated run. Later changes use batched additions and removals. Deleted directory subtrees use recursive removal, with tests for changed, deleted, and identical paths.

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

Merge Risk:⚪ Minimal · up to cbb0b

This change preserves diff collapse state and incrementally updates the file tree during workspace refreshes; no actionable merge-blocking risk remains after normal checks and review.

Suggested reviewers:juliusmarminge, stienswout

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 18.18% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 11 functions across 7 files.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
Title check✅ PassedThe title clearly and concisely describes the primary change: preserving panel state across workspace refreshes.
Description check✅ PassedThe description explains what changed, why it changed, verification performed, and UI evidence. It omits the template headings and checklist, but it provides the required information and is substantia…
Full details: Description check

Explanation

The description explains what changed, why it changed, verification performed, and UI evidence. It omits the template headings and checklist, but it provides the required information and is substantially complete.

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@macroscopeapp

macroscopeappBot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 6ead33d

Macroscope's review found this PR approvable — This is a focused web bug fix that preserves existing file-tree and diff-panel state during refreshes using localized reconciliation and per-file rendering versions. The changes are self-contained, tested, and introduce no schema, security, billing, deployment, or static-analysis configuration impact.

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

macroscopeapp[bot]
macroscopeappBot previously approved these changes Aug 31, 2026
@maria-rcks
maria-rcksforce-pushed the t3code/preserve-diff-collapse-state branch from cbb0b3d to ad8549aCompareSeptember 1, 2026 16:55

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit ad8549a. Configure here.

Comment threadapps/web/src/components/DiffPanel.tsx
@maria-rcks
maria-rcksforce-pushed the t3code/preserve-diff-collapse-state branch from ad8549a to 6ead33dCompareSeptember 1, 2026 17:09
@macroscopeapp
macroscopeappBot dismissed their stale reviewSeptember 1, 2026 17:09

Dismissing prior approval to re-evaluate 6ead33d

@maria-rcks
maria-rcks merged commit f2a914b into pingdotgg:mainSep 2, 2026
26 of 27 checks passed
dascapytal1559 added a commit to dascapytal1559/t3code that referenced this pull request Sep 2, 2026
Conflict resolutions:
- Claude $skill: adopt upstream's last-block dispatch (pingdotgg#9128). Drop the
fork's in-place $→/ rewrite on the Claude send path so the dispatcher
still sees $ tokens. Ultrathink wrapping a leading $skill is now safe
(prefix in the leading text block, command block still starts with
/name). Keep the Grok $→/ rewrite.
- Mobile composer menus: keep cwd-scoped composerSkills; apply upstream's
user-invocable filter and dedupe on that list. Path search now imports
from state/queries (upstream deleted the dedicated hook).
- Files surface: keep lazy explorer listDirectory/readDirectoryChildren;
adopt upstream's expandHomePathWith. Legacy (non-lazy) tree uses
incremental path updates (pingdotgg#8968) plus the fork's symlink badges and
ignored git status.
- Tilde paths: skip ~/ inline-code candidates in the shared
markdownLinks helper upstream extracted from web.
Pre-sync fork: backup/upstream-test-drive-pre-sync-20260902 (d4f79f8).
github-actionsBot added a commit to omarcresp/t3code-flake that referenced this pull request Sep 2, 2026
## What's Changed
* perf(client-runtime): keep turn and checkpoint refs stable while streaming by @t3dotgg in pingdotgg/t3code#9145
* perf(clients): lease sidebar status by visibility by @StiensWout in pingdotgg/t3code#9052
* fix(desktop): show newest changes in nightly previews by @t3dotgg in pingdotgg/t3code#9138
* fix(settings): sync auto-settle and other shared preferences across environments by @t3dotgg in pingdotgg/t3code#9147
* fix(server): prevent accidental service downgrades by @t3dotgg in pingdotgg/t3code#5302
* fix(server): keep attachments until the command commits by @t3dotgg in pingdotgg/t3code#7941
* fix(claude): preview images read from the workspace by @t3dotgg in pingdotgg/t3code#9119
* fix(web): keep generated muted foreground dimmer than entered text by @flamboh in pingdotgg/t3code#9113
* fix(clients): stop repeating expanded commands by @t3dotgg in pingdotgg/t3code#9120
* fix(grok): health check, model selection, and stop all work against the real CLI by @t3dotgg in pingdotgg/t3code#9154
* perf(web): halve the cold-start bundle by splitting Clerk and cold routes by @StiensWout in pingdotgg/t3code#9058
* feat(desktop): update the desktop app on remote Macs from the Update button by @t3dotgg in pingdotgg/t3code#6554
* test(server): measure shell, second client, and reconnect transfer by @t3dotgg in pingdotgg/t3code#9157
* fix(web): project default model works on the hosted app by @juliusmarminge in pingdotgg/t3code#9142
* fix(web): darken neutral control surfaces by @maria-rcks in pingdotgg/t3code#9064
* fix(web): preserve panel state across workspace refreshes by @maria-rcks in pingdotgg/t3code#8968
* feat(files): open markdown, HTML, and PDF files outside the workspace by @juliusmarminge in pingdotgg/t3code#9140
* feat(web): render HTML and PDF files in the file viewer by @juliusmarminge in pingdotgg/t3code#9143
* fix(web): compact project settings actions by @maria-rcks in pingdotgg/t3code#9160
* fix(web): browse folders from file breadcrumbs by @404khai in pingdotgg/t3code#8910
## New Contributors
* @404khai made their first contribution in pingdotgg/t3code#8910
**Full Changelog**: pingdotgg/t3code@v0.0.39-nightly.20260902.1252...v0.0.39-nightly.20260902.1253
Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.39-nightly.20260902.1253
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@maria-rcks
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
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

fix(web): preserve panel state across workspace refreshes#8968
maria-rcks merged 1 commit into
pingdotgg:mainfrom
maria-rcks:t3code/preserve-diff-collapse-state

Conversation

@maria-rcks

@maria-rcksmaria-rcks commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

Workspace refreshes no longer reset collapsed diff files or rebuild the file tree. The diff now separates stable file identity from per-file content versions, while the file browser applies incremental path changes so unchanged elements stay mounted.

Verified with 12 focused tests, targeted lint and formatting, web typecheck, and the matched UI evidence below.

Evidence

Base: state lost after refreshBranch: state preserved after refresh
Base after refresh expands both filesBranch after refresh keeps five files collapsed

Watch the real-app agent edit test

Real app flow: the branch diff stays open while GPT-5.6-Sol edits the expanded file; the other files remain collapsed through the live refresh.

Written with gpt-5.6-sol in the Codex harness.


Note

Low Risk
UI state and reconciliation logic only; no auth, data persistence, or API contract changes. Risk is mainly regressions in diff rendering or file tree sync after refresh.

Overview
Workspace refreshes no longer wipe collapsed diff files or rebuild the entire file tree from scratch. The diff panel now tracks each file with a stable identity key (previous + current paths) separate from a per-file content version, so unchanged files keep collapse state and only edited files get a new render version in AnnotatableCodeView.

DiffPanel also exposes loadDiffFiles through a stable ref-backed callback so CodeView options do not churn when the git loader is recreated on refresh.

The file browser applies incremental path add/remove batches via buildFileTreePathUpdates instead of resetPaths on every entry refresh; the first successful load still resets the tree. It skips reconciliation until entries have loaded (entriesQuery.data !== null).

Reviewed by Cursor Bugbot for commit 6ead33d. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Preserve diff panel and file tree state across workspace refreshes

  • DiffPanel now identifies diff files by previous/current path via buildFileDiffIdentityKey instead of the cache key, and computes a per-file content version with buildFileDiffContentVersion so only changed files re-render.
  • AnnotatableCodeView prepends fileVersion into its item version hash, limiting reconciliation to files whose diff content actually changed.
  • FileBrowserPanel replaces full tree resets with incremental batched updates: new buildFileTreePathUpdates computes a minimal set of add/remove operations, collapsing deleted subtrees into a single recursive remove.
  • Risk: previousTreePathsRef in FileBrowserPanel.tsx now starts as null; first population calls model.resetPaths while subsequent updates rely on buildFileTreePathUpdates correctness — any path-order mismatch could produce stale tree nodes.

Macroscope summarized 6ead33d.

Summary by CodeRabbit

  • Bug Fixes

    • Improved diff rendering so file identity remains stable while content updates refresh correctly.
    • Preserved code annotations and view state more reliably when file contents change.
    • Improved file browser synchronization by applying only incremental path changes.
    • Correctly handles deleted folders and unchanged file trees.
  • Tests

    • Added coverage for diff versioning and file tree path reconciliation.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 31, 2026
Comment threadapps/web/src/lib/diffRendering.ts
@coderabbitai

coderabbitaiBot commented Aug 31, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Team

Run ID: f012d321-79f9-4510-947c-39c0108b6084

📥 Commits

Reviewing files that changed from the base of the PR and between 41adccc and cbb0b3d.

📒 Files selected for processing (7)
  • apps/web/src/components/DiffPanel.tsx
  • apps/web/src/components/diffs/AnnotatableCodeView.tsx
  • apps/web/src/components/files/FileBrowserPanel.tsx
  • apps/web/src/components/files/fileTreePathReconciliation.test.ts
  • apps/web/src/components/files/fileTreePathReconciliation.ts
  • apps/web/src/lib/diffRendering.test.ts
  • apps/web/src/lib/diffRendering.ts

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


📝 Walkthrough

Walkthrough

The diff view now separates file identity from content versioning and stabilizes file loading callbacks. The file browser now reconciles tree paths incrementally, including recursive subtree removal.

Changes

Diff reconciliation

Layer / File(s)Summary
Diff identity and content versioning
apps/web/src/lib/diffRendering.ts, apps/web/src/lib/diffRendering.test.ts, apps/web/src/components/DiffPanel.tsx, apps/web/src/components/diffs/AnnotatableCodeView.tsx
The diff view uses stable identity keys and deterministic content versions. Content versions now affect annotatable code view item versions. Tests cover unchanged and changed files across diff versions.
Diff content loader stability
apps/web/src/components/DiffPanel.tsx
The current file-content loader is tracked separately from a stable callback. The callback delegates through a ref and throws when no loader is available.

File tree reconciliation

Layer / File(s)Summary
Incremental file tree synchronization
apps/web/src/components/files/FileBrowserPanel.tsx, apps/web/src/components/files/fileTreePathReconciliation.ts, apps/web/src/components/files/fileTreePathReconciliation.test.ts
The file browser resets paths only on the first populated run. Later changes use batched additions and removals. Deleted directory subtrees use recursive removal, with tests for changed, deleted, and identical paths.

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

Merge Risk:⚪ Minimal · up to cbb0b

This change preserves diff collapse state and incrementally updates the file tree during workspace refreshes; no actionable merge-blocking risk remains after normal checks and review.

Suggested reviewers:juliusmarminge, stienswout

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 18.18% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 11 functions across 7 files.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
Title check✅ PassedThe title clearly and concisely describes the primary change: preserving panel state across workspace refreshes.
Description check✅ PassedThe description explains what changed, why it changed, verification performed, and UI evidence. It omits the template headings and checklist, but it provides the required information and is substantia…
Full details: Description check

Explanation

The description explains what changed, why it changed, verification performed, and UI evidence. It omits the template headings and checklist, but it provides the required information and is substantially complete.

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@macroscopeapp

macroscopeappBot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 6ead33d

Macroscope's review found this PR approvable — This is a focused web bug fix that preserves existing file-tree and diff-panel state during refreshes using localized reconciliation and per-file rendering versions. The changes are self-contained, tested, and introduce no schema, security, billing, deployment, or static-analysis configuration impact.

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

macroscopeapp[bot]
macroscopeappBot previously approved these changes Aug 31, 2026
@maria-rcks
maria-rcksforce-pushed the t3code/preserve-diff-collapse-state branch from cbb0b3d to ad8549aCompareSeptember 1, 2026 16:55

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit ad8549a. Configure here.

Comment threadapps/web/src/components/DiffPanel.tsx
@maria-rcks
maria-rcksforce-pushed the t3code/preserve-diff-collapse-state branch from ad8549a to 6ead33dCompareSeptember 1, 2026 17:09
@macroscopeapp
macroscopeappBot dismissed their stale reviewSeptember 1, 2026 17:09

Dismissing prior approval to re-evaluate 6ead33d

@maria-rcks
maria-rcks merged commit f2a914b into pingdotgg:mainSep 2, 2026
26 of 27 checks passed
dascapytal1559 added a commit to dascapytal1559/t3code that referenced this pull request Sep 2, 2026
Conflict resolutions:
- Claude $skill: adopt upstream's last-block dispatch (pingdotgg#9128). Drop the
fork's in-place $→/ rewrite on the Claude send path so the dispatcher
still sees $ tokens. Ultrathink wrapping a leading $skill is now safe
(prefix in the leading text block, command block still starts with
/name). Keep the Grok $→/ rewrite.
- Mobile composer menus: keep cwd-scoped composerSkills; apply upstream's
user-invocable filter and dedupe on that list. Path search now imports
from state/queries (upstream deleted the dedicated hook).
- Files surface: keep lazy explorer listDirectory/readDirectoryChildren;
adopt upstream's expandHomePathWith. Legacy (non-lazy) tree uses
incremental path updates (pingdotgg#8968) plus the fork's symlink badges and
ignored git status.
- Tilde paths: skip ~/ inline-code candidates in the shared
markdownLinks helper upstream extracted from web.
Pre-sync fork: backup/upstream-test-drive-pre-sync-20260902 (d4f79f8).
github-actionsBot added a commit to omarcresp/t3code-flake that referenced this pull request Sep 2, 2026
## What's Changed
* perf(client-runtime): keep turn and checkpoint refs stable while streaming by @t3dotgg in pingdotgg/t3code#9145
* perf(clients): lease sidebar status by visibility by @StiensWout in pingdotgg/t3code#9052
* fix(desktop): show newest changes in nightly previews by @t3dotgg in pingdotgg/t3code#9138
* fix(settings): sync auto-settle and other shared preferences across environments by @t3dotgg in pingdotgg/t3code#9147
* fix(server): prevent accidental service downgrades by @t3dotgg in pingdotgg/t3code#5302
* fix(server): keep attachments until the command commits by @t3dotgg in pingdotgg/t3code#7941
* fix(claude): preview images read from the workspace by @t3dotgg in pingdotgg/t3code#9119
* fix(web): keep generated muted foreground dimmer than entered text by @flamboh in pingdotgg/t3code#9113
* fix(clients): stop repeating expanded commands by @t3dotgg in pingdotgg/t3code#9120
* fix(grok): health check, model selection, and stop all work against the real CLI by @t3dotgg in pingdotgg/t3code#9154
* perf(web): halve the cold-start bundle by splitting Clerk and cold routes by @StiensWout in pingdotgg/t3code#9058
* feat(desktop): update the desktop app on remote Macs from the Update button by @t3dotgg in pingdotgg/t3code#6554
* test(server): measure shell, second client, and reconnect transfer by @t3dotgg in pingdotgg/t3code#9157
* fix(web): project default model works on the hosted app by @juliusmarminge in pingdotgg/t3code#9142
* fix(web): darken neutral control surfaces by @maria-rcks in pingdotgg/t3code#9064
* fix(web): preserve panel state across workspace refreshes by @maria-rcks in pingdotgg/t3code#8968
* feat(files): open markdown, HTML, and PDF files outside the workspace by @juliusmarminge in pingdotgg/t3code#9140
* feat(web): render HTML and PDF files in the file viewer by @juliusmarminge in pingdotgg/t3code#9143
* fix(web): compact project settings actions by @maria-rcks in pingdotgg/t3code#9160
* fix(web): browse folders from file breadcrumbs by @404khai in pingdotgg/t3code#8910
## New Contributors
* @404khai made their first contribution in pingdotgg/t3code#8910
**Full Changelog**: pingdotgg/t3code@v0.0.39-nightly.20260902.1252...v0.0.39-nightly.20260902.1253
Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.39-nightly.20260902.1253
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@maria-rcks
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
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

fix(web): preserve panel state across workspace refreshes#8968
maria-rcks merged 1 commit into
pingdotgg:mainfrom
maria-rcks:t3code/preserve-diff-collapse-state

Conversation

@maria-rcks

@maria-rcksmaria-rcks commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

Workspace refreshes no longer reset collapsed diff files or rebuild the file tree. The diff now separates stable file identity from per-file content versions, while the file browser applies incremental path changes so unchanged elements stay mounted.

Verified with 12 focused tests, targeted lint and formatting, web typecheck, and the matched UI evidence below.

Evidence

Base: state lost after refreshBranch: state preserved after refresh
Base after refresh expands both filesBranch after refresh keeps five files collapsed

Watch the real-app agent edit test

Real app flow: the branch diff stays open while GPT-5.6-Sol edits the expanded file; the other files remain collapsed through the live refresh.

Written with gpt-5.6-sol in the Codex harness.


Note

Low Risk
UI state and reconciliation logic only; no auth, data persistence, or API contract changes. Risk is mainly regressions in diff rendering or file tree sync after refresh.

Overview
Workspace refreshes no longer wipe collapsed diff files or rebuild the entire file tree from scratch. The diff panel now tracks each file with a stable identity key (previous + current paths) separate from a per-file content version, so unchanged files keep collapse state and only edited files get a new render version in AnnotatableCodeView.

DiffPanel also exposes loadDiffFiles through a stable ref-backed callback so CodeView options do not churn when the git loader is recreated on refresh.

The file browser applies incremental path add/remove batches via buildFileTreePathUpdates instead of resetPaths on every entry refresh; the first successful load still resets the tree. It skips reconciliation until entries have loaded (entriesQuery.data !== null).

Reviewed by Cursor Bugbot for commit 6ead33d. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Preserve diff panel and file tree state across workspace refreshes

  • DiffPanel now identifies diff files by previous/current path via buildFileDiffIdentityKey instead of the cache key, and computes a per-file content version with buildFileDiffContentVersion so only changed files re-render.
  • AnnotatableCodeView prepends fileVersion into its item version hash, limiting reconciliation to files whose diff content actually changed.
  • FileBrowserPanel replaces full tree resets with incremental batched updates: new buildFileTreePathUpdates computes a minimal set of add/remove operations, collapsing deleted subtrees into a single recursive remove.
  • Risk: previousTreePathsRef in FileBrowserPanel.tsx now starts as null; first population calls model.resetPaths while subsequent updates rely on buildFileTreePathUpdates correctness — any path-order mismatch could produce stale tree nodes.

Macroscope summarized 6ead33d.

Summary by CodeRabbit

  • Bug Fixes

    • Improved diff rendering so file identity remains stable while content updates refresh correctly.
    • Preserved code annotations and view state more reliably when file contents change.
    • Improved file browser synchronization by applying only incremental path changes.
    • Correctly handles deleted folders and unchanged file trees.
  • Tests

    • Added coverage for diff versioning and file tree path reconciliation.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 31, 2026
Comment threadapps/web/src/lib/diffRendering.ts
@coderabbitai

coderabbitaiBot commented Aug 31, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Team

Run ID: f012d321-79f9-4510-947c-39c0108b6084

📥 Commits

Reviewing files that changed from the base of the PR and between 41adccc and cbb0b3d.

📒 Files selected for processing (7)
  • apps/web/src/components/DiffPanel.tsx
  • apps/web/src/components/diffs/AnnotatableCodeView.tsx
  • apps/web/src/components/files/FileBrowserPanel.tsx
  • apps/web/src/components/files/fileTreePathReconciliation.test.ts
  • apps/web/src/components/files/fileTreePathReconciliation.ts
  • apps/web/src/lib/diffRendering.test.ts
  • apps/web/src/lib/diffRendering.ts

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


📝 Walkthrough

Walkthrough

The diff view now separates file identity from content versioning and stabilizes file loading callbacks. The file browser now reconciles tree paths incrementally, including recursive subtree removal.

Changes

Diff reconciliation

Layer / File(s)Summary
Diff identity and content versioning
apps/web/src/lib/diffRendering.ts, apps/web/src/lib/diffRendering.test.ts, apps/web/src/components/DiffPanel.tsx, apps/web/src/components/diffs/AnnotatableCodeView.tsx
The diff view uses stable identity keys and deterministic content versions. Content versions now affect annotatable code view item versions. Tests cover unchanged and changed files across diff versions.
Diff content loader stability
apps/web/src/components/DiffPanel.tsx
The current file-content loader is tracked separately from a stable callback. The callback delegates through a ref and throws when no loader is available.

File tree reconciliation

Layer / File(s)Summary
Incremental file tree synchronization
apps/web/src/components/files/FileBrowserPanel.tsx, apps/web/src/components/files/fileTreePathReconciliation.ts, apps/web/src/components/files/fileTreePathReconciliation.test.ts
The file browser resets paths only on the first populated run. Later changes use batched additions and removals. Deleted directory subtrees use recursive removal, with tests for changed, deleted, and identical paths.

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

Merge Risk:⚪ Minimal · up to cbb0b

This change preserves diff collapse state and incrementally updates the file tree during workspace refreshes; no actionable merge-blocking risk remains after normal checks and review.

Suggested reviewers:juliusmarminge, stienswout

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 18.18% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 11 functions across 7 files.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
Title check✅ PassedThe title clearly and concisely describes the primary change: preserving panel state across workspace refreshes.
Description check✅ PassedThe description explains what changed, why it changed, verification performed, and UI evidence. It omits the template headings and checklist, but it provides the required information and is substantia…
Full details: Description check

Explanation

The description explains what changed, why it changed, verification performed, and UI evidence. It omits the template headings and checklist, but it provides the required information and is substantially complete.

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@macroscopeapp

macroscopeappBot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 6ead33d

Macroscope's review found this PR approvable — This is a focused web bug fix that preserves existing file-tree and diff-panel state during refreshes using localized reconciliation and per-file rendering versions. The changes are self-contained, tested, and introduce no schema, security, billing, deployment, or static-analysis configuration impact.

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

macroscopeapp[bot]
macroscopeappBot previously approved these changes Aug 31, 2026
@maria-rcks
maria-rcksforce-pushed the t3code/preserve-diff-collapse-state branch from cbb0b3d to ad8549aCompareSeptember 1, 2026 16:55

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit ad8549a. Configure here.

Comment threadapps/web/src/components/DiffPanel.tsx
@maria-rcks
maria-rcksforce-pushed the t3code/preserve-diff-collapse-state branch from ad8549a to 6ead33dCompareSeptember 1, 2026 17:09
@macroscopeapp
macroscopeappBot dismissed their stale reviewSeptember 1, 2026 17:09

Dismissing prior approval to re-evaluate 6ead33d

@maria-rcks
maria-rcks merged commit f2a914b into pingdotgg:mainSep 2, 2026
26 of 27 checks passed
dascapytal1559 added a commit to dascapytal1559/t3code that referenced this pull request Sep 2, 2026
Conflict resolutions:
- Claude $skill: adopt upstream's last-block dispatch (pingdotgg#9128). Drop the
fork's in-place $→/ rewrite on the Claude send path so the dispatcher
still sees $ tokens. Ultrathink wrapping a leading $skill is now safe
(prefix in the leading text block, command block still starts with
/name). Keep the Grok $→/ rewrite.
- Mobile composer menus: keep cwd-scoped composerSkills; apply upstream's
user-invocable filter and dedupe on that list. Path search now imports
from state/queries (upstream deleted the dedicated hook).
- Files surface: keep lazy explorer listDirectory/readDirectoryChildren;
adopt upstream's expandHomePathWith. Legacy (non-lazy) tree uses
incremental path updates (pingdotgg#8968) plus the fork's symlink badges and
ignored git status.
- Tilde paths: skip ~/ inline-code candidates in the shared
markdownLinks helper upstream extracted from web.
Pre-sync fork: backup/upstream-test-drive-pre-sync-20260902 (d4f79f8).
github-actionsBot added a commit to omarcresp/t3code-flake that referenced this pull request Sep 2, 2026
## What's Changed
* perf(client-runtime): keep turn and checkpoint refs stable while streaming by @t3dotgg in pingdotgg/t3code#9145
* perf(clients): lease sidebar status by visibility by @StiensWout in pingdotgg/t3code#9052
* fix(desktop): show newest changes in nightly previews by @t3dotgg in pingdotgg/t3code#9138
* fix(settings): sync auto-settle and other shared preferences across environments by @t3dotgg in pingdotgg/t3code#9147
* fix(server): prevent accidental service downgrades by @t3dotgg in pingdotgg/t3code#5302
* fix(server): keep attachments until the command commits by @t3dotgg in pingdotgg/t3code#7941
* fix(claude): preview images read from the workspace by @t3dotgg in pingdotgg/t3code#9119
* fix(web): keep generated muted foreground dimmer than entered text by @flamboh in pingdotgg/t3code#9113
* fix(clients): stop repeating expanded commands by @t3dotgg in pingdotgg/t3code#9120
* fix(grok): health check, model selection, and stop all work against the real CLI by @t3dotgg in pingdotgg/t3code#9154
* perf(web): halve the cold-start bundle by splitting Clerk and cold routes by @StiensWout in pingdotgg/t3code#9058
* feat(desktop): update the desktop app on remote Macs from the Update button by @t3dotgg in pingdotgg/t3code#6554
* test(server): measure shell, second client, and reconnect transfer by @t3dotgg in pingdotgg/t3code#9157
* fix(web): project default model works on the hosted app by @juliusmarminge in pingdotgg/t3code#9142
* fix(web): darken neutral control surfaces by @maria-rcks in pingdotgg/t3code#9064
* fix(web): preserve panel state across workspace refreshes by @maria-rcks in pingdotgg/t3code#8968
* feat(files): open markdown, HTML, and PDF files outside the workspace by @juliusmarminge in pingdotgg/t3code#9140
* feat(web): render HTML and PDF files in the file viewer by @juliusmarminge in pingdotgg/t3code#9143
* fix(web): compact project settings actions by @maria-rcks in pingdotgg/t3code#9160
* fix(web): browse folders from file breadcrumbs by @404khai in pingdotgg/t3code#8910
## New Contributors
* @404khai made their first contribution in pingdotgg/t3code#8910
**Full Changelog**: pingdotgg/t3code@v0.0.39-nightly.20260902.1252...v0.0.39-nightly.20260902.1253
Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.39-nightly.20260902.1253
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@maria-rcks
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
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

fix(web): preserve panel state across workspace refreshes#8968
maria-rcks merged 1 commit into
pingdotgg:mainfrom
maria-rcks:t3code/preserve-diff-collapse-state

Conversation

@maria-rcks

@maria-rcksmaria-rcks commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

Workspace refreshes no longer reset collapsed diff files or rebuild the file tree. The diff now separates stable file identity from per-file content versions, while the file browser applies incremental path changes so unchanged elements stay mounted.

Verified with 12 focused tests, targeted lint and formatting, web typecheck, and the matched UI evidence below.

Evidence

Base: state lost after refreshBranch: state preserved after refresh
Base after refresh expands both filesBranch after refresh keeps five files collapsed

Watch the real-app agent edit test

Real app flow: the branch diff stays open while GPT-5.6-Sol edits the expanded file; the other files remain collapsed through the live refresh.

Written with gpt-5.6-sol in the Codex harness.


Note

Low Risk
UI state and reconciliation logic only; no auth, data persistence, or API contract changes. Risk is mainly regressions in diff rendering or file tree sync after refresh.

Overview
Workspace refreshes no longer wipe collapsed diff files or rebuild the entire file tree from scratch. The diff panel now tracks each file with a stable identity key (previous + current paths) separate from a per-file content version, so unchanged files keep collapse state and only edited files get a new render version in AnnotatableCodeView.

DiffPanel also exposes loadDiffFiles through a stable ref-backed callback so CodeView options do not churn when the git loader is recreated on refresh.

The file browser applies incremental path add/remove batches via buildFileTreePathUpdates instead of resetPaths on every entry refresh; the first successful load still resets the tree. It skips reconciliation until entries have loaded (entriesQuery.data !== null).

Reviewed by Cursor Bugbot for commit 6ead33d. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Preserve diff panel and file tree state across workspace refreshes

  • DiffPanel now identifies diff files by previous/current path via buildFileDiffIdentityKey instead of the cache key, and computes a per-file content version with buildFileDiffContentVersion so only changed files re-render.
  • AnnotatableCodeView prepends fileVersion into its item version hash, limiting reconciliation to files whose diff content actually changed.
  • FileBrowserPanel replaces full tree resets with incremental batched updates: new buildFileTreePathUpdates computes a minimal set of add/remove operations, collapsing deleted subtrees into a single recursive remove.
  • Risk: previousTreePathsRef in FileBrowserPanel.tsx now starts as null; first population calls model.resetPaths while subsequent updates rely on buildFileTreePathUpdates correctness — any path-order mismatch could produce stale tree nodes.

Macroscope summarized 6ead33d.

Summary by CodeRabbit

  • Bug Fixes

    • Improved diff rendering so file identity remains stable while content updates refresh correctly.
    • Preserved code annotations and view state more reliably when file contents change.
    • Improved file browser synchronization by applying only incremental path changes.
    • Correctly handles deleted folders and unchanged file trees.
  • Tests

    • Added coverage for diff versioning and file tree path reconciliation.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 31, 2026
Comment threadapps/web/src/lib/diffRendering.ts
@coderabbitai

coderabbitaiBot commented Aug 31, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Team

Run ID: f012d321-79f9-4510-947c-39c0108b6084

📥 Commits

Reviewing files that changed from the base of the PR and between 41adccc and cbb0b3d.

📒 Files selected for processing (7)
  • apps/web/src/components/DiffPanel.tsx
  • apps/web/src/components/diffs/AnnotatableCodeView.tsx
  • apps/web/src/components/files/FileBrowserPanel.tsx
  • apps/web/src/components/files/fileTreePathReconciliation.test.ts
  • apps/web/src/components/files/fileTreePathReconciliation.ts
  • apps/web/src/lib/diffRendering.test.ts
  • apps/web/src/lib/diffRendering.ts

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


📝 Walkthrough

Walkthrough

The diff view now separates file identity from content versioning and stabilizes file loading callbacks. The file browser now reconciles tree paths incrementally, including recursive subtree removal.

Changes

Diff reconciliation

Layer / File(s)Summary
Diff identity and content versioning
apps/web/src/lib/diffRendering.ts, apps/web/src/lib/diffRendering.test.ts, apps/web/src/components/DiffPanel.tsx, apps/web/src/components/diffs/AnnotatableCodeView.tsx
The diff view uses stable identity keys and deterministic content versions. Content versions now affect annotatable code view item versions. Tests cover unchanged and changed files across diff versions.
Diff content loader stability
apps/web/src/components/DiffPanel.tsx
The current file-content loader is tracked separately from a stable callback. The callback delegates through a ref and throws when no loader is available.

File tree reconciliation

Layer / File(s)Summary
Incremental file tree synchronization
apps/web/src/components/files/FileBrowserPanel.tsx, apps/web/src/components/files/fileTreePathReconciliation.ts, apps/web/src/components/files/fileTreePathReconciliation.test.ts
The file browser resets paths only on the first populated run. Later changes use batched additions and removals. Deleted directory subtrees use recursive removal, with tests for changed, deleted, and identical paths.

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

Merge Risk:⚪ Minimal · up to cbb0b

This change preserves diff collapse state and incrementally updates the file tree during workspace refreshes; no actionable merge-blocking risk remains after normal checks and review.

Suggested reviewers:juliusmarminge, stienswout

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 18.18% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 11 functions across 7 files.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
Title check✅ PassedThe title clearly and concisely describes the primary change: preserving panel state across workspace refreshes.
Description check✅ PassedThe description explains what changed, why it changed, verification performed, and UI evidence. It omits the template headings and checklist, but it provides the required information and is substantia…
Full details: Description check

Explanation

The description explains what changed, why it changed, verification performed, and UI evidence. It omits the template headings and checklist, but it provides the required information and is substantially complete.

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@macroscopeapp

macroscopeappBot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 6ead33d

Macroscope's review found this PR approvable — This is a focused web bug fix that preserves existing file-tree and diff-panel state during refreshes using localized reconciliation and per-file rendering versions. The changes are self-contained, tested, and introduce no schema, security, billing, deployment, or static-analysis configuration impact.

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

macroscopeapp[bot]
macroscopeappBot previously approved these changes Aug 31, 2026
@maria-rcks
maria-rcksforce-pushed the t3code/preserve-diff-collapse-state branch from cbb0b3d to ad8549aCompareSeptember 1, 2026 16:55

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit ad8549a. Configure here.

Comment threadapps/web/src/components/DiffPanel.tsx
@maria-rcks
maria-rcksforce-pushed the t3code/preserve-diff-collapse-state branch from ad8549a to 6ead33dCompareSeptember 1, 2026 17:09
@macroscopeapp
macroscopeappBot dismissed their stale reviewSeptember 1, 2026 17:09

Dismissing prior approval to re-evaluate 6ead33d

@maria-rcks
maria-rcks merged commit f2a914b into pingdotgg:mainSep 2, 2026
26 of 27 checks passed
dascapytal1559 added a commit to dascapytal1559/t3code that referenced this pull request Sep 2, 2026
Conflict resolutions:
- Claude $skill: adopt upstream's last-block dispatch (pingdotgg#9128). Drop the
fork's in-place $→/ rewrite on the Claude send path so the dispatcher
still sees $ tokens. Ultrathink wrapping a leading $skill is now safe
(prefix in the leading text block, command block still starts with
/name). Keep the Grok $→/ rewrite.
- Mobile composer menus: keep cwd-scoped composerSkills; apply upstream's
user-invocable filter and dedupe on that list. Path search now imports
from state/queries (upstream deleted the dedicated hook).
- Files surface: keep lazy explorer listDirectory/readDirectoryChildren;
adopt upstream's expandHomePathWith. Legacy (non-lazy) tree uses
incremental path updates (pingdotgg#8968) plus the fork's symlink badges and
ignored git status.
- Tilde paths: skip ~/ inline-code candidates in the shared
markdownLinks helper upstream extracted from web.
Pre-sync fork: backup/upstream-test-drive-pre-sync-20260902 (d4f79f8).
github-actionsBot added a commit to omarcresp/t3code-flake that referenced this pull request Sep 2, 2026
## What's Changed
* perf(client-runtime): keep turn and checkpoint refs stable while streaming by @t3dotgg in pingdotgg/t3code#9145
* perf(clients): lease sidebar status by visibility by @StiensWout in pingdotgg/t3code#9052
* fix(desktop): show newest changes in nightly previews by @t3dotgg in pingdotgg/t3code#9138
* fix(settings): sync auto-settle and other shared preferences across environments by @t3dotgg in pingdotgg/t3code#9147
* fix(server): prevent accidental service downgrades by @t3dotgg in pingdotgg/t3code#5302
* fix(server): keep attachments until the command commits by @t3dotgg in pingdotgg/t3code#7941
* fix(claude): preview images read from the workspace by @t3dotgg in pingdotgg/t3code#9119
* fix(web): keep generated muted foreground dimmer than entered text by @flamboh in pingdotgg/t3code#9113
* fix(clients): stop repeating expanded commands by @t3dotgg in pingdotgg/t3code#9120
* fix(grok): health check, model selection, and stop all work against the real CLI by @t3dotgg in pingdotgg/t3code#9154
* perf(web): halve the cold-start bundle by splitting Clerk and cold routes by @StiensWout in pingdotgg/t3code#9058
* feat(desktop): update the desktop app on remote Macs from the Update button by @t3dotgg in pingdotgg/t3code#6554
* test(server): measure shell, second client, and reconnect transfer by @t3dotgg in pingdotgg/t3code#9157
* fix(web): project default model works on the hosted app by @juliusmarminge in pingdotgg/t3code#9142
* fix(web): darken neutral control surfaces by @maria-rcks in pingdotgg/t3code#9064
* fix(web): preserve panel state across workspace refreshes by @maria-rcks in pingdotgg/t3code#8968
* feat(files): open markdown, HTML, and PDF files outside the workspace by @juliusmarminge in pingdotgg/t3code#9140
* feat(web): render HTML and PDF files in the file viewer by @juliusmarminge in pingdotgg/t3code#9143
* fix(web): compact project settings actions by @maria-rcks in pingdotgg/t3code#9160
* fix(web): browse folders from file breadcrumbs by @404khai in pingdotgg/t3code#8910
## New Contributors
* @404khai made their first contribution in pingdotgg/t3code#8910
**Full Changelog**: pingdotgg/t3code@v0.0.39-nightly.20260902.1252...v0.0.39-nightly.20260902.1253
Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.39-nightly.20260902.1253
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@maria-rcks
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
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

fix(web): preserve panel state across workspace refreshes#8968
maria-rcks merged 1 commit into
pingdotgg:mainfrom
maria-rcks:t3code/preserve-diff-collapse-state

Conversation

@maria-rcks

@maria-rcksmaria-rcks commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

Workspace refreshes no longer reset collapsed diff files or rebuild the file tree. The diff now separates stable file identity from per-file content versions, while the file browser applies incremental path changes so unchanged elements stay mounted.

Verified with 12 focused tests, targeted lint and formatting, web typecheck, and the matched UI evidence below.

Evidence

Base: state lost after refreshBranch: state preserved after refresh
Base after refresh expands both filesBranch after refresh keeps five files collapsed

Watch the real-app agent edit test

Real app flow: the branch diff stays open while GPT-5.6-Sol edits the expanded file; the other files remain collapsed through the live refresh.

Written with gpt-5.6-sol in the Codex harness.


Note

Low Risk
UI state and reconciliation logic only; no auth, data persistence, or API contract changes. Risk is mainly regressions in diff rendering or file tree sync after refresh.

Overview
Workspace refreshes no longer wipe collapsed diff files or rebuild the entire file tree from scratch. The diff panel now tracks each file with a stable identity key (previous + current paths) separate from a per-file content version, so unchanged files keep collapse state and only edited files get a new render version in AnnotatableCodeView.

DiffPanel also exposes loadDiffFiles through a stable ref-backed callback so CodeView options do not churn when the git loader is recreated on refresh.

The file browser applies incremental path add/remove batches via buildFileTreePathUpdates instead of resetPaths on every entry refresh; the first successful load still resets the tree. It skips reconciliation until entries have loaded (entriesQuery.data !== null).

Reviewed by Cursor Bugbot for commit 6ead33d. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Preserve diff panel and file tree state across workspace refreshes

  • DiffPanel now identifies diff files by previous/current path via buildFileDiffIdentityKey instead of the cache key, and computes a per-file content version with buildFileDiffContentVersion so only changed files re-render.
  • AnnotatableCodeView prepends fileVersion into its item version hash, limiting reconciliation to files whose diff content actually changed.
  • FileBrowserPanel replaces full tree resets with incremental batched updates: new buildFileTreePathUpdates computes a minimal set of add/remove operations, collapsing deleted subtrees into a single recursive remove.
  • Risk: previousTreePathsRef in FileBrowserPanel.tsx now starts as null; first population calls model.resetPaths while subsequent updates rely on buildFileTreePathUpdates correctness — any path-order mismatch could produce stale tree nodes.

Macroscope summarized 6ead33d.

Summary by CodeRabbit

  • Bug Fixes

    • Improved diff rendering so file identity remains stable while content updates refresh correctly.
    • Preserved code annotations and view state more reliably when file contents change.
    • Improved file browser synchronization by applying only incremental path changes.
    • Correctly handles deleted folders and unchanged file trees.
  • Tests

    • Added coverage for diff versioning and file tree path reconciliation.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 31, 2026
Comment threadapps/web/src/lib/diffRendering.ts
@coderabbitai

coderabbitaiBot commented Aug 31, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Team

Run ID: f012d321-79f9-4510-947c-39c0108b6084

📥 Commits

Reviewing files that changed from the base of the PR and between 41adccc and cbb0b3d.

📒 Files selected for processing (7)
  • apps/web/src/components/DiffPanel.tsx
  • apps/web/src/components/diffs/AnnotatableCodeView.tsx
  • apps/web/src/components/files/FileBrowserPanel.tsx
  • apps/web/src/components/files/fileTreePathReconciliation.test.ts
  • apps/web/src/components/files/fileTreePathReconciliation.ts
  • apps/web/src/lib/diffRendering.test.ts
  • apps/web/src/lib/diffRendering.ts

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


📝 Walkthrough

Walkthrough

The diff view now separates file identity from content versioning and stabilizes file loading callbacks. The file browser now reconciles tree paths incrementally, including recursive subtree removal.

Changes

Diff reconciliation

Layer / File(s)Summary
Diff identity and content versioning
apps/web/src/lib/diffRendering.ts, apps/web/src/lib/diffRendering.test.ts, apps/web/src/components/DiffPanel.tsx, apps/web/src/components/diffs/AnnotatableCodeView.tsx
The diff view uses stable identity keys and deterministic content versions. Content versions now affect annotatable code view item versions. Tests cover unchanged and changed files across diff versions.
Diff content loader stability
apps/web/src/components/DiffPanel.tsx
The current file-content loader is tracked separately from a stable callback. The callback delegates through a ref and throws when no loader is available.

File tree reconciliation

Layer / File(s)Summary
Incremental file tree synchronization
apps/web/src/components/files/FileBrowserPanel.tsx, apps/web/src/components/files/fileTreePathReconciliation.ts, apps/web/src/components/files/fileTreePathReconciliation.test.ts
The file browser resets paths only on the first populated run. Later changes use batched additions and removals. Deleted directory subtrees use recursive removal, with tests for changed, deleted, and identical paths.

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

Merge Risk:⚪ Minimal · up to cbb0b

This change preserves diff collapse state and incrementally updates the file tree during workspace refreshes; no actionable merge-blocking risk remains after normal checks and review.

Suggested reviewers:juliusmarminge, stienswout

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 18.18% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 11 functions across 7 files.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
Title check✅ PassedThe title clearly and concisely describes the primary change: preserving panel state across workspace refreshes.
Description check✅ PassedThe description explains what changed, why it changed, verification performed, and UI evidence. It omits the template headings and checklist, but it provides the required information and is substantia…
Full details: Description check

Explanation

The description explains what changed, why it changed, verification performed, and UI evidence. It omits the template headings and checklist, but it provides the required information and is substantially complete.

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@macroscopeapp

macroscopeappBot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 6ead33d

Macroscope's review found this PR approvable — This is a focused web bug fix that preserves existing file-tree and diff-panel state during refreshes using localized reconciliation and per-file rendering versions. The changes are self-contained, tested, and introduce no schema, security, billing, deployment, or static-analysis configuration impact.

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

macroscopeapp[bot]
macroscopeappBot previously approved these changes Aug 31, 2026
@maria-rcks
maria-rcksforce-pushed the t3code/preserve-diff-collapse-state branch from cbb0b3d to ad8549aCompareSeptember 1, 2026 16:55

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit ad8549a. Configure here.

Comment threadapps/web/src/components/DiffPanel.tsx
@maria-rcks
maria-rcksforce-pushed the t3code/preserve-diff-collapse-state branch from ad8549a to 6ead33dCompareSeptember 1, 2026 17:09
@macroscopeapp
macroscopeappBot dismissed their stale reviewSeptember 1, 2026 17:09

Dismissing prior approval to re-evaluate 6ead33d

@maria-rcks
maria-rcks merged commit f2a914b into pingdotgg:mainSep 2, 2026
26 of 27 checks passed
dascapytal1559 added a commit to dascapytal1559/t3code that referenced this pull request Sep 2, 2026
Conflict resolutions:
- Claude $skill: adopt upstream's last-block dispatch (pingdotgg#9128). Drop the
fork's in-place $→/ rewrite on the Claude send path so the dispatcher
still sees $ tokens. Ultrathink wrapping a leading $skill is now safe
(prefix in the leading text block, command block still starts with
/name). Keep the Grok $→/ rewrite.
- Mobile composer menus: keep cwd-scoped composerSkills; apply upstream's
user-invocable filter and dedupe on that list. Path search now imports
from state/queries (upstream deleted the dedicated hook).
- Files surface: keep lazy explorer listDirectory/readDirectoryChildren;
adopt upstream's expandHomePathWith. Legacy (non-lazy) tree uses
incremental path updates (pingdotgg#8968) plus the fork's symlink badges and
ignored git status.
- Tilde paths: skip ~/ inline-code candidates in the shared
markdownLinks helper upstream extracted from web.
Pre-sync fork: backup/upstream-test-drive-pre-sync-20260902 (d4f79f8).
github-actionsBot added a commit to omarcresp/t3code-flake that referenced this pull request Sep 2, 2026
## What's Changed
* perf(client-runtime): keep turn and checkpoint refs stable while streaming by @t3dotgg in pingdotgg/t3code#9145
* perf(clients): lease sidebar status by visibility by @StiensWout in pingdotgg/t3code#9052
* fix(desktop): show newest changes in nightly previews by @t3dotgg in pingdotgg/t3code#9138
* fix(settings): sync auto-settle and other shared preferences across environments by @t3dotgg in pingdotgg/t3code#9147
* fix(server): prevent accidental service downgrades by @t3dotgg in pingdotgg/t3code#5302
* fix(server): keep attachments until the command commits by @t3dotgg in pingdotgg/t3code#7941
* fix(claude): preview images read from the workspace by @t3dotgg in pingdotgg/t3code#9119
* fix(web): keep generated muted foreground dimmer than entered text by @flamboh in pingdotgg/t3code#9113
* fix(clients): stop repeating expanded commands by @t3dotgg in pingdotgg/t3code#9120
* fix(grok): health check, model selection, and stop all work against the real CLI by @t3dotgg in pingdotgg/t3code#9154
* perf(web): halve the cold-start bundle by splitting Clerk and cold routes by @StiensWout in pingdotgg/t3code#9058
* feat(desktop): update the desktop app on remote Macs from the Update button by @t3dotgg in pingdotgg/t3code#6554
* test(server): measure shell, second client, and reconnect transfer by @t3dotgg in pingdotgg/t3code#9157
* fix(web): project default model works on the hosted app by @juliusmarminge in pingdotgg/t3code#9142
* fix(web): darken neutral control surfaces by @maria-rcks in pingdotgg/t3code#9064
* fix(web): preserve panel state across workspace refreshes by @maria-rcks in pingdotgg/t3code#8968
* feat(files): open markdown, HTML, and PDF files outside the workspace by @juliusmarminge in pingdotgg/t3code#9140
* feat(web): render HTML and PDF files in the file viewer by @juliusmarminge in pingdotgg/t3code#9143
* fix(web): compact project settings actions by @maria-rcks in pingdotgg/t3code#9160
* fix(web): browse folders from file breadcrumbs by @404khai in pingdotgg/t3code#8910
## New Contributors
* @404khai made their first contribution in pingdotgg/t3code#8910
**Full Changelog**: pingdotgg/t3code@v0.0.39-nightly.20260902.1252...v0.0.39-nightly.20260902.1253
Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.39-nightly.20260902.1253
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@maria-rcks