Repository navigation
fix(vscode): stop clipping the working status label during a status swap - #14156
Merged
Merged
Conversation
Contributor
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Files Reviewed (4 files)
Incremental review of
The production files were unchanged in this increment and were already verified at Previous Review Summary (commit 1b62b5e)Current summary above is authoritative. Previous snapshots are kept for context only. Previous review (commit 1b62b5e)Status: No Issues Found | Recommendation: Merge Files Reviewed (3 files)
Verified the swap logic against the surrounding CSS and the existing
Reviewed by deepseek-v4.1-flash · Input: 45.7K · Output: 8.6K · Cached: 441.3K Review guidance: REVIEW.md from base branch |
marius-kilocode
enabled auto-merge
September 15, 2026 09:42
iscekic
approved these changes
Sep 15, 2026
This was referenced Sep 16, 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
When the working indicator swapped a longer status label for a shorter one, the incoming label was rendered with a hard cut and a faded tail. With "Thinking" this read as a cut-off "g" next to a faint fragment, and it stayed that way for the length of the transition.
Why This Change Was Made
StatusTextanimates a width lock: the box is pinned to the outgoing label's width, released to the incoming one, and the outgoing label stays mounted at zero opacity until that glide lands. Two things were wrong with that.The truncation mask was driven by
scrollWidth > clientWidthon the box. On a shrink the outgoing copy is wider than the box for the entire glide, so the mask switched on and faded the right edge of a label that already fit. It also stayed on for the whole 520ms lock, because releasing the lock does not change the box width once the glide has landed, so theResizeObservernever rechecked.The second issue is that the mounted copy kept painting. Its exit animation ends at zero opacity but the
bothfill held nothing that removed it from the paint, so its tail was still drawn past the shrunken box.The mask now compares the live label's own width against the box, so a copy that only exists to hold the lock can never trigger it. That check also runs immediately after a swap is measured, since the box is locked at that moment and the observer would not fire. The exit keyframe now ends in
visibility: hidden, held by thebothfill, so the copy stops painting while it waits for the lock to release. When the indicator has no layout (the dock isdisplay: nonebetween turns) the swap is applied without the width lock or the exit copy, instead of pinning the box to0px.User Impact
A status change to a shorter label glides smoothly with the full text visible and no faded fragment beside it. A label that is genuinely wider than the row still fades at the cut while the box opens up for it.
Evidence
Frame-by-frame capture of a shrink swap ("Making edits" to "Thinking…") through the dock story that the visual regression suite already drives, sampled once per animation frame:
data-clipduring the 520ms lockThe dock story runs unchanged:
bun run test:visual -- tests/session-dock-stability.spec.tspasses all 16 tests, including three new ones. Two of the new tests fail on the parent commit and pass here, so they guard the regression rather than restating the implementation. The grow path still enables the fade, and the reduced-motion path still cuts instead of animating.The extension bundle was rebuilt and loaded in an isolated VS Code instance: the sidebar chat mounts the dock and the status label with no clip attribute and no new console errors.
Limitations
The swap was not reproduced against a live backend turn, because that needs a model request. The frame-level capture and the new tests drive the same component and stylesheets in a browser, and the isolated extension run confirms the built webview mounts them; the remaining gap is a real turn's label sequencing.