fix(app): trust server session diff for Files Changed panel - #720

Merged
jeonghun-jj-lee merged 1 commit into
mainfrom
fix-files-changed-tracking
Sep 2, 2026
Merged

fix(app): trust server session diff for Files Changed panel#720
jeonghun-jj-lee merged 1 commit into
mainfrom
fix-files-changed-tracking

Conversation

@jeonghun-jj-lee

Copy link
Copy Markdown
Contributor

Problem

The "Files Changed" panel showed every file the agent touched during a session, even when those files were reverted to their session-start state. Editing a file and then undoing that edit still left it in the panel.

Root cause

The reviewDiffs memo in session.tsx checked if (serverDiffs.length > 0) to decide whether to use the server's authoritative session-scoped diff. When the server correctly returned [] (all agent edits were reverted — no net changes), the condition was false and the code fell through to accumulateDiffs(), which counts tool operations rather than net filesystem state. Two edits to the same file (one forward, one back) always produced entries.

The same fallthrough happened during the placeholder phase of the TanStack Query, so the server path was effectively dead — the client always used the operation-based accumulator.

Fix

Extract resolveReviewDiffs — a pure, tested function that uses sessionDiffQuery.isPlaceholderData to distinguish "server responded with empty" from "query still loading":

  • serverReady = true, diffs empty → return [] (the fix — trust the server)
  • serverReady = true, diffs present → return normalized server diffs
  • serverReady = false → fall back to accumulateDiffs so the panel shows immediate results during initial load

The server's Session.diff() (already in the pinned binary since v1.18.10-amicode.18) computes the net diff by comparing the first step-start git tree snapshot to the current working tree, filtered to agent-touched files. Files with zero net change are absent from its result.

Testing

  • 8 new tests for resolveReviewDiffs covering: server-empty-means-empty, server diffs used when present, fallback while loading, path normalization, filtering
  • All 2113 existing extension tests pass
  • Full build succeeds

Files changed

FileChange
resolve-review-diffs.tsNew pure function
resolve-review-diffs.test.ts8 tests
session.tsxWire resolveReviewDiffs into the reviewDiffs memo

The reviewDiffs memo always fell through to the client-side
accumulateDiffs fallback because it checked serverDiffs.length > 0,
which was false both when the server returned empty (all edits reverted)
and during the placeholder phase of the query. This meant files that
were edited then reverted to their session-start state still appeared
in the Files Changed panel.
Extract resolveReviewDiffs — a pure, tested function that uses
isPlaceholderData to distinguish 'server responded with empty' from
'query still loading'. When the server has settled, its result is
authoritative (even if empty). The accumulateDiffs fallback now only
runs while the query is in flight so the panel is not blank during
initial load.
@jeonghun-jj-lee
jeonghun-jj-lee merged commit d871d60 into mainSep 2, 2026
7 of 8 checks passed
@jeonghun-jj-lee
jeonghun-jj-lee deleted the fix-files-changed-tracking branch September 2, 2026 19:54
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@jeonghun-jj-lee
, '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(app): trust server session diff for Files Changed panel - #720

Merged
jeonghun-jj-lee merged 1 commit into
mainfrom
fix-files-changed-tracking
Sep 2, 2026
Merged

fix(app): trust server session diff for Files Changed panel#720
jeonghun-jj-lee merged 1 commit into
mainfrom
fix-files-changed-tracking

Conversation

@jeonghun-jj-lee

Copy link
Copy Markdown
Contributor

Problem

The "Files Changed" panel showed every file the agent touched during a session, even when those files were reverted to their session-start state. Editing a file and then undoing that edit still left it in the panel.

Root cause

The reviewDiffs memo in session.tsx checked if (serverDiffs.length > 0) to decide whether to use the server's authoritative session-scoped diff. When the server correctly returned [] (all agent edits were reverted — no net changes), the condition was false and the code fell through to accumulateDiffs(), which counts tool operations rather than net filesystem state. Two edits to the same file (one forward, one back) always produced entries.

The same fallthrough happened during the placeholder phase of the TanStack Query, so the server path was effectively dead — the client always used the operation-based accumulator.

Fix

Extract resolveReviewDiffs — a pure, tested function that uses sessionDiffQuery.isPlaceholderData to distinguish "server responded with empty" from "query still loading":

  • serverReady = true, diffs empty → return [] (the fix — trust the server)
  • serverReady = true, diffs present → return normalized server diffs
  • serverReady = false → fall back to accumulateDiffs so the panel shows immediate results during initial load

The server's Session.diff() (already in the pinned binary since v1.18.10-amicode.18) computes the net diff by comparing the first step-start git tree snapshot to the current working tree, filtered to agent-touched files. Files with zero net change are absent from its result.

Testing

  • 8 new tests for resolveReviewDiffs covering: server-empty-means-empty, server diffs used when present, fallback while loading, path normalization, filtering
  • All 2113 existing extension tests pass
  • Full build succeeds

Files changed

FileChange
resolve-review-diffs.tsNew pure function
resolve-review-diffs.test.ts8 tests
session.tsxWire resolveReviewDiffs into the reviewDiffs memo

The reviewDiffs memo always fell through to the client-side
accumulateDiffs fallback because it checked serverDiffs.length > 0,
which was false both when the server returned empty (all edits reverted)
and during the placeholder phase of the query. This meant files that
were edited then reverted to their session-start state still appeared
in the Files Changed panel.
Extract resolveReviewDiffs — a pure, tested function that uses
isPlaceholderData to distinguish 'server responded with empty' from
'query still loading'. When the server has settled, its result is
authoritative (even if empty). The accumulateDiffs fallback now only
runs while the query is in flight so the panel is not blank during
initial load.
@jeonghun-jj-lee
jeonghun-jj-lee merged commit d871d60 into mainSep 2, 2026
7 of 8 checks passed
@jeonghun-jj-lee
jeonghun-jj-lee deleted the fix-files-changed-tracking branch September 2, 2026 19:54
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@jeonghun-jj-lee
, '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(app): trust server session diff for Files Changed panel - #720

Merged
jeonghun-jj-lee merged 1 commit into
mainfrom
fix-files-changed-tracking
Sep 2, 2026
Merged

fix(app): trust server session diff for Files Changed panel#720
jeonghun-jj-lee merged 1 commit into
mainfrom
fix-files-changed-tracking

Conversation

@jeonghun-jj-lee

Copy link
Copy Markdown
Contributor

Problem

The "Files Changed" panel showed every file the agent touched during a session, even when those files were reverted to their session-start state. Editing a file and then undoing that edit still left it in the panel.

Root cause

The reviewDiffs memo in session.tsx checked if (serverDiffs.length > 0) to decide whether to use the server's authoritative session-scoped diff. When the server correctly returned [] (all agent edits were reverted — no net changes), the condition was false and the code fell through to accumulateDiffs(), which counts tool operations rather than net filesystem state. Two edits to the same file (one forward, one back) always produced entries.

The same fallthrough happened during the placeholder phase of the TanStack Query, so the server path was effectively dead — the client always used the operation-based accumulator.

Fix

Extract resolveReviewDiffs — a pure, tested function that uses sessionDiffQuery.isPlaceholderData to distinguish "server responded with empty" from "query still loading":

  • serverReady = true, diffs empty → return [] (the fix — trust the server)
  • serverReady = true, diffs present → return normalized server diffs
  • serverReady = false → fall back to accumulateDiffs so the panel shows immediate results during initial load

The server's Session.diff() (already in the pinned binary since v1.18.10-amicode.18) computes the net diff by comparing the first step-start git tree snapshot to the current working tree, filtered to agent-touched files. Files with zero net change are absent from its result.

Testing

  • 8 new tests for resolveReviewDiffs covering: server-empty-means-empty, server diffs used when present, fallback while loading, path normalization, filtering
  • All 2113 existing extension tests pass
  • Full build succeeds

Files changed

FileChange
resolve-review-diffs.tsNew pure function
resolve-review-diffs.test.ts8 tests
session.tsxWire resolveReviewDiffs into the reviewDiffs memo

The reviewDiffs memo always fell through to the client-side
accumulateDiffs fallback because it checked serverDiffs.length > 0,
which was false both when the server returned empty (all edits reverted)
and during the placeholder phase of the query. This meant files that
were edited then reverted to their session-start state still appeared
in the Files Changed panel.
Extract resolveReviewDiffs — a pure, tested function that uses
isPlaceholderData to distinguish 'server responded with empty' from
'query still loading'. When the server has settled, its result is
authoritative (even if empty). The accumulateDiffs fallback now only
runs while the query is in flight so the panel is not blank during
initial load.
@jeonghun-jj-lee
jeonghun-jj-lee merged commit d871d60 into mainSep 2, 2026
7 of 8 checks passed
@jeonghun-jj-lee
jeonghun-jj-lee deleted the fix-files-changed-tracking branch September 2, 2026 19:54
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@jeonghun-jj-lee
, '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(app): trust server session diff for Files Changed panel - #720

Merged
jeonghun-jj-lee merged 1 commit into
mainfrom
fix-files-changed-tracking
Sep 2, 2026
Merged

fix(app): trust server session diff for Files Changed panel#720
jeonghun-jj-lee merged 1 commit into
mainfrom
fix-files-changed-tracking

Conversation

@jeonghun-jj-lee

Copy link
Copy Markdown
Contributor

Problem

The "Files Changed" panel showed every file the agent touched during a session, even when those files were reverted to their session-start state. Editing a file and then undoing that edit still left it in the panel.

Root cause

The reviewDiffs memo in session.tsx checked if (serverDiffs.length > 0) to decide whether to use the server's authoritative session-scoped diff. When the server correctly returned [] (all agent edits were reverted — no net changes), the condition was false and the code fell through to accumulateDiffs(), which counts tool operations rather than net filesystem state. Two edits to the same file (one forward, one back) always produced entries.

The same fallthrough happened during the placeholder phase of the TanStack Query, so the server path was effectively dead — the client always used the operation-based accumulator.

Fix

Extract resolveReviewDiffs — a pure, tested function that uses sessionDiffQuery.isPlaceholderData to distinguish "server responded with empty" from "query still loading":

  • serverReady = true, diffs empty → return [] (the fix — trust the server)
  • serverReady = true, diffs present → return normalized server diffs
  • serverReady = false → fall back to accumulateDiffs so the panel shows immediate results during initial load

The server's Session.diff() (already in the pinned binary since v1.18.10-amicode.18) computes the net diff by comparing the first step-start git tree snapshot to the current working tree, filtered to agent-touched files. Files with zero net change are absent from its result.

Testing

  • 8 new tests for resolveReviewDiffs covering: server-empty-means-empty, server diffs used when present, fallback while loading, path normalization, filtering
  • All 2113 existing extension tests pass
  • Full build succeeds

Files changed

FileChange
resolve-review-diffs.tsNew pure function
resolve-review-diffs.test.ts8 tests
session.tsxWire resolveReviewDiffs into the reviewDiffs memo

The reviewDiffs memo always fell through to the client-side
accumulateDiffs fallback because it checked serverDiffs.length > 0,
which was false both when the server returned empty (all edits reverted)
and during the placeholder phase of the query. This meant files that
were edited then reverted to their session-start state still appeared
in the Files Changed panel.
Extract resolveReviewDiffs — a pure, tested function that uses
isPlaceholderData to distinguish 'server responded with empty' from
'query still loading'. When the server has settled, its result is
authoritative (even if empty). The accumulateDiffs fallback now only
runs while the query is in flight so the panel is not blank during
initial load.
@jeonghun-jj-lee
jeonghun-jj-lee merged commit d871d60 into mainSep 2, 2026
7 of 8 checks passed
@jeonghun-jj-lee
jeonghun-jj-lee deleted the fix-files-changed-tracking branch September 2, 2026 19:54
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@jeonghun-jj-lee
, '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(app): trust server session diff for Files Changed panel - #720

Merged
jeonghun-jj-lee merged 1 commit into
mainfrom
fix-files-changed-tracking
Sep 2, 2026
Merged

fix(app): trust server session diff for Files Changed panel#720
jeonghun-jj-lee merged 1 commit into
mainfrom
fix-files-changed-tracking

Conversation

@jeonghun-jj-lee

Copy link
Copy Markdown
Contributor

Problem

The "Files Changed" panel showed every file the agent touched during a session, even when those files were reverted to their session-start state. Editing a file and then undoing that edit still left it in the panel.

Root cause

The reviewDiffs memo in session.tsx checked if (serverDiffs.length > 0) to decide whether to use the server's authoritative session-scoped diff. When the server correctly returned [] (all agent edits were reverted — no net changes), the condition was false and the code fell through to accumulateDiffs(), which counts tool operations rather than net filesystem state. Two edits to the same file (one forward, one back) always produced entries.

The same fallthrough happened during the placeholder phase of the TanStack Query, so the server path was effectively dead — the client always used the operation-based accumulator.

Fix

Extract resolveReviewDiffs — a pure, tested function that uses sessionDiffQuery.isPlaceholderData to distinguish "server responded with empty" from "query still loading":

  • serverReady = true, diffs empty → return [] (the fix — trust the server)
  • serverReady = true, diffs present → return normalized server diffs
  • serverReady = false → fall back to accumulateDiffs so the panel shows immediate results during initial load

The server's Session.diff() (already in the pinned binary since v1.18.10-amicode.18) computes the net diff by comparing the first step-start git tree snapshot to the current working tree, filtered to agent-touched files. Files with zero net change are absent from its result.

Testing

  • 8 new tests for resolveReviewDiffs covering: server-empty-means-empty, server diffs used when present, fallback while loading, path normalization, filtering
  • All 2113 existing extension tests pass
  • Full build succeeds

Files changed

FileChange
resolve-review-diffs.tsNew pure function
resolve-review-diffs.test.ts8 tests
session.tsxWire resolveReviewDiffs into the reviewDiffs memo

The reviewDiffs memo always fell through to the client-side
accumulateDiffs fallback because it checked serverDiffs.length > 0,
which was false both when the server returned empty (all edits reverted)
and during the placeholder phase of the query. This meant files that
were edited then reverted to their session-start state still appeared
in the Files Changed panel.
Extract resolveReviewDiffs — a pure, tested function that uses
isPlaceholderData to distinguish 'server responded with empty' from
'query still loading'. When the server has settled, its result is
authoritative (even if empty). The accumulateDiffs fallback now only
runs while the query is in flight so the panel is not blank during
initial load.
@jeonghun-jj-lee
jeonghun-jj-lee merged commit d871d60 into mainSep 2, 2026
7 of 8 checks passed
@jeonghun-jj-lee
jeonghun-jj-lee deleted the fix-files-changed-tracking branch September 2, 2026 19:54
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@jeonghun-jj-lee
, '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(app): trust server session diff for Files Changed panel - #720

Merged
jeonghun-jj-lee merged 1 commit into
mainfrom
fix-files-changed-tracking
Sep 2, 2026
Merged

fix(app): trust server session diff for Files Changed panel#720
jeonghun-jj-lee merged 1 commit into
mainfrom
fix-files-changed-tracking

Conversation

@jeonghun-jj-lee

Copy link
Copy Markdown
Contributor

Problem

The "Files Changed" panel showed every file the agent touched during a session, even when those files were reverted to their session-start state. Editing a file and then undoing that edit still left it in the panel.

Root cause

The reviewDiffs memo in session.tsx checked if (serverDiffs.length > 0) to decide whether to use the server's authoritative session-scoped diff. When the server correctly returned [] (all agent edits were reverted — no net changes), the condition was false and the code fell through to accumulateDiffs(), which counts tool operations rather than net filesystem state. Two edits to the same file (one forward, one back) always produced entries.

The same fallthrough happened during the placeholder phase of the TanStack Query, so the server path was effectively dead — the client always used the operation-based accumulator.

Fix

Extract resolveReviewDiffs — a pure, tested function that uses sessionDiffQuery.isPlaceholderData to distinguish "server responded with empty" from "query still loading":

  • serverReady = true, diffs empty → return [] (the fix — trust the server)
  • serverReady = true, diffs present → return normalized server diffs
  • serverReady = false → fall back to accumulateDiffs so the panel shows immediate results during initial load

The server's Session.diff() (already in the pinned binary since v1.18.10-amicode.18) computes the net diff by comparing the first step-start git tree snapshot to the current working tree, filtered to agent-touched files. Files with zero net change are absent from its result.

Testing

  • 8 new tests for resolveReviewDiffs covering: server-empty-means-empty, server diffs used when present, fallback while loading, path normalization, filtering
  • All 2113 existing extension tests pass
  • Full build succeeds

Files changed

FileChange
resolve-review-diffs.tsNew pure function
resolve-review-diffs.test.ts8 tests
session.tsxWire resolveReviewDiffs into the reviewDiffs memo

The reviewDiffs memo always fell through to the client-side
accumulateDiffs fallback because it checked serverDiffs.length > 0,
which was false both when the server returned empty (all edits reverted)
and during the placeholder phase of the query. This meant files that
were edited then reverted to their session-start state still appeared
in the Files Changed panel.
Extract resolveReviewDiffs — a pure, tested function that uses
isPlaceholderData to distinguish 'server responded with empty' from
'query still loading'. When the server has settled, its result is
authoritative (even if empty). The accumulateDiffs fallback now only
runs while the query is in flight so the panel is not blank during
initial load.
@jeonghun-jj-lee
jeonghun-jj-lee merged commit d871d60 into mainSep 2, 2026
7 of 8 checks passed
@jeonghun-jj-lee
jeonghun-jj-lee deleted the fix-files-changed-tracking branch September 2, 2026 19:54
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@jeonghun-jj-lee
, '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(app): trust server session diff for Files Changed panel - #720

Merged
jeonghun-jj-lee merged 1 commit into
mainfrom
fix-files-changed-tracking
Sep 2, 2026
Merged

fix(app): trust server session diff for Files Changed panel#720
jeonghun-jj-lee merged 1 commit into
mainfrom
fix-files-changed-tracking

Conversation

@jeonghun-jj-lee

Copy link
Copy Markdown
Contributor

Problem

The "Files Changed" panel showed every file the agent touched during a session, even when those files were reverted to their session-start state. Editing a file and then undoing that edit still left it in the panel.

Root cause

The reviewDiffs memo in session.tsx checked if (serverDiffs.length > 0) to decide whether to use the server's authoritative session-scoped diff. When the server correctly returned [] (all agent edits were reverted — no net changes), the condition was false and the code fell through to accumulateDiffs(), which counts tool operations rather than net filesystem state. Two edits to the same file (one forward, one back) always produced entries.

The same fallthrough happened during the placeholder phase of the TanStack Query, so the server path was effectively dead — the client always used the operation-based accumulator.

Fix

Extract resolveReviewDiffs — a pure, tested function that uses sessionDiffQuery.isPlaceholderData to distinguish "server responded with empty" from "query still loading":

  • serverReady = true, diffs empty → return [] (the fix — trust the server)
  • serverReady = true, diffs present → return normalized server diffs
  • serverReady = false → fall back to accumulateDiffs so the panel shows immediate results during initial load

The server's Session.diff() (already in the pinned binary since v1.18.10-amicode.18) computes the net diff by comparing the first step-start git tree snapshot to the current working tree, filtered to agent-touched files. Files with zero net change are absent from its result.

Testing

  • 8 new tests for resolveReviewDiffs covering: server-empty-means-empty, server diffs used when present, fallback while loading, path normalization, filtering
  • All 2113 existing extension tests pass
  • Full build succeeds

Files changed

FileChange
resolve-review-diffs.tsNew pure function
resolve-review-diffs.test.ts8 tests
session.tsxWire resolveReviewDiffs into the reviewDiffs memo

The reviewDiffs memo always fell through to the client-side
accumulateDiffs fallback because it checked serverDiffs.length > 0,
which was false both when the server returned empty (all edits reverted)
and during the placeholder phase of the query. This meant files that
were edited then reverted to their session-start state still appeared
in the Files Changed panel.
Extract resolveReviewDiffs — a pure, tested function that uses
isPlaceholderData to distinguish 'server responded with empty' from
'query still loading'. When the server has settled, its result is
authoritative (even if empty). The accumulateDiffs fallback now only
runs while the query is in flight so the panel is not blank during
initial load.
@jeonghun-jj-lee
jeonghun-jj-lee merged commit d871d60 into mainSep 2, 2026
7 of 8 checks passed
@jeonghun-jj-lee
jeonghun-jj-lee deleted the fix-files-changed-tracking branch September 2, 2026 19:54
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@jeonghun-jj-lee
, '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(app): trust server session diff for Files Changed panel - #720

Merged
jeonghun-jj-lee merged 1 commit into
mainfrom
fix-files-changed-tracking
Sep 2, 2026
Merged

fix(app): trust server session diff for Files Changed panel#720
jeonghun-jj-lee merged 1 commit into
mainfrom
fix-files-changed-tracking

Conversation

@jeonghun-jj-lee

Copy link
Copy Markdown
Contributor

Problem

The "Files Changed" panel showed every file the agent touched during a session, even when those files were reverted to their session-start state. Editing a file and then undoing that edit still left it in the panel.

Root cause

The reviewDiffs memo in session.tsx checked if (serverDiffs.length > 0) to decide whether to use the server's authoritative session-scoped diff. When the server correctly returned [] (all agent edits were reverted — no net changes), the condition was false and the code fell through to accumulateDiffs(), which counts tool operations rather than net filesystem state. Two edits to the same file (one forward, one back) always produced entries.

The same fallthrough happened during the placeholder phase of the TanStack Query, so the server path was effectively dead — the client always used the operation-based accumulator.

Fix

Extract resolveReviewDiffs — a pure, tested function that uses sessionDiffQuery.isPlaceholderData to distinguish "server responded with empty" from "query still loading":

  • serverReady = true, diffs empty → return [] (the fix — trust the server)
  • serverReady = true, diffs present → return normalized server diffs
  • serverReady = false → fall back to accumulateDiffs so the panel shows immediate results during initial load

The server's Session.diff() (already in the pinned binary since v1.18.10-amicode.18) computes the net diff by comparing the first step-start git tree snapshot to the current working tree, filtered to agent-touched files. Files with zero net change are absent from its result.

Testing

  • 8 new tests for resolveReviewDiffs covering: server-empty-means-empty, server diffs used when present, fallback while loading, path normalization, filtering
  • All 2113 existing extension tests pass
  • Full build succeeds

Files changed

FileChange
resolve-review-diffs.tsNew pure function
resolve-review-diffs.test.ts8 tests
session.tsxWire resolveReviewDiffs into the reviewDiffs memo

The reviewDiffs memo always fell through to the client-side
accumulateDiffs fallback because it checked serverDiffs.length > 0,
which was false both when the server returned empty (all edits reverted)
and during the placeholder phase of the query. This meant files that
were edited then reverted to their session-start state still appeared
in the Files Changed panel.
Extract resolveReviewDiffs — a pure, tested function that uses
isPlaceholderData to distinguish 'server responded with empty' from
'query still loading'. When the server has settled, its result is
authoritative (even if empty). The accumulateDiffs fallback now only
runs while the query is in flight so the panel is not blank during
initial load.
@jeonghun-jj-lee
jeonghun-jj-lee merged commit d871d60 into mainSep 2, 2026
7 of 8 checks passed
@jeonghun-jj-lee
jeonghun-jj-lee deleted the fix-files-changed-tracking branch September 2, 2026 19:54
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@jeonghun-jj-lee