fix(vscode): release tool animations on unmount to stop transcript leak - #14280
Merged
Merged
Conversation
Tool card fade animations kept unmounted transcript rows alive, so Agent Manager switching slowed down the longer a window stayed open. A stopped Motion animation never finishes, so Motion kept a reference cycle to the removed element through its visual element store. Settle interrupted animations with complete() instead of stop(), skip animating nodes outside the document, and read the BasicTool trigger getter once instead of building and discarding a detached subtree.
Contributor
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Incremental review since Files Reviewed (5 files)
Previous Review Summary (commit 815a81b)Current summary above is authoritative. Previous snapshots are kept for context only. Previous review (commit 815a81b)Status: No Issues Found | Recommendation: Merge Files Reviewed (5 files)
Reviewed by deepseek-v4.1-flash · Input: 0 · Output: 0 · Cached: 0 Review guidance: REVIEW.md from base branch |
marius-kilocode
enabled auto-merge
September 18, 2026 09:19
WebReflection
approved these changes
Sep 18, 2026
marius-kilocode
deleted the
investigate-session-switching-performance
branch
September 18, 2026 11:19
This was referenced Sep 19, 2026
This was referenced Sep 21, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What Problem This Solves
Agent Manager session switching gets slower the longer a VS Code window stays open. A long-lived window accumulates unmounted tool cards and transcript rows, so every switch pays for more garbage collection and render work. A fresh window with the same sessions switches fast, which is why the regression only appears after hours of use.
Why This Change Was Made
The tool card fade path kept unmounted rows alive through two mechanisms.
BasicTool(shared upstream file) read thetriggerJSX getter twice. The copy built only for theMatchcondition was never inserted into the DOM, but itsonMountstill ran, souseToolFadestarted a Motion animation on a detached node. Blink does not advance animations whose target is outside the document, soonfinishnever fired and the document timeline kept theAnimationalive.anim.stop(). Motion only clearsMotionValue.animationwhen the animation finishes, which a cancelled animation never does. The stale reference cycles through the WAAPI Animation, its target element and Motion's per-element visual element store. That cycle crosses the V8 and Blink heaps and is not collected, and the element then pinned the whole transcript row through Solid prop closures.Changes:
packages/ui/src/components/basic-tool.tsx: read the trigger getter once withcreateMemo, andcomplete()the collapsible height animation on cleanup.packages/kilo-ui/src/components/motion.tsx: add asettle()helper that callscomplete()instead ofstop()when an element goes away.packages/kilo-ui/src/components/tool-utils.ts:useToolFadeskips detached nodes and settles on cleanup;useRowWipesettles a started animation that it previously left running;useCollapsibleanduseGrowInsettle on cleanup.packages/kilo-ui/src/components/grow-box.tsx: settle on cleanup.User Impact
Agent Manager session switching stays fast in long-lived windows. Tool card fade, wipe and collapse animations are unchanged visually.
Evidence
Measured in an isolated VS Code instance with the real Agent Manager state (31 sessions across 26 worktrees) imported.
<div>after ~100 switchesAnimationobjectsHeap snapshot dominator chains showed every retained transcript row dominated by
DocumentTimeline > Animation > AsyncMotionValueAnimation > promise reactions > ShellText props > detached row.Manual Test
Detached. There should be novscode-session-turnrows and only a fewAnimationobjects.