microsoft/vscode PR #320782 — Fix terminal pill rendering race — PR #320782
microsoft/vscode · pull request #320782 ·
Transcript
PlainEnglish
Let's walk through PR 320782 — a focused fix for the VS Code chat UI that resolves a visual glitch when terminal tools are invoked. We'll see how a small guard condition eliminates broken empty terminal pills.
PlainEnglish
This PR pursues one main goal — make sure the terminal pill only appears once we actually have a command to show. Along the way, it adds documentation explaining the rendering lifecycle and a test to prevent regression. And critically, it preserves the happy path where terminal pills render normally once command input is available.
PlainEnglish
The race condition lived between two async events. When the SDK invokes a bash tool, VS Code immediately knows the tool kind is terminal — but the actual command text streams in afterward. The old logic tried to render the terminal pill as soon as it saw the kind, resulting in a broken empty widget. This PR waits for both signals before committing to the terminal UI.
Architecture
Two files changed. The main logic lives in the state-to-progress adapter, which is responsible for rendering chat tool invocations. The test file mirrors that structure, adding coverage for the edge case.
Architecture
First, the documentation update. The JSDoc now explicitly states that terminal rendering waits for the getTerminalInput helper to return a value — meaning both the tool status is no longer streaming and the command text has arrived. This clarifies the lifecycle for future maintainers.
Architecture
And here's the fix itself. The second branch of the conditional — which handles SDK bash tools — now requires that getTerminalInput returns a defined value. That helper already checks both the status and the toolInput field, so this one-line addition ensures the terminal pill never renders with an empty command. When the guard fails, the chat UI falls back to showing the generic invocation message widget instead.
Architecture
The new test validates the edge case. It creates a terminal tool with status Running but no toolInput — simulating the moment after the tool opens but before the command text arrives. The assertion confirms that toolSpecificData is undefined, meaning the terminal pill is not rendered, and the fallback invocation message is used instead. This test locks in the fix and prevents future regressions.
CodeQuality
The analysis examined all five callsites that invoke isTerminalToolCall and confirmed they all now use the same gating logic. The getTerminalInput helper already includes robust status and input checking with JSON error handling, so the guard is safe. And critically, all existing tests continue to pass — the constraint is satisfied. Terminal pills still render perfectly when command input is available.
PlainEnglish
After this PR lands, the chat UI will no longer show broken terminal pills with empty command lines. When an SDK bash tool opens, the UI shows the generic invocation message until the command text arrives. Once getTerminalInput returns a value, the terminal pill renders properly. The behavior is consistent across all lifecycle states — Running, Completed, and history replay — because every callsite uses the same predicate.
PlainEnglish
And that's the story of PR 320782. A focused fix that closes a visual glitch with a single guard condition — terminal pills now wait for command input to arrive before rendering. The logic is consistent, the tests are in place, and the chat UI stays clean at every stage of the tool lifecycle.
How this was made
Lenzon read microsoft/vscode at pull request #320782 and generated this walkthrough automatically. The narration above is the transcript of what it says.
Explain a pull request from your own repo
Point Lenzon at a repo or a pull request and get a narrated walkthrough like this one.
Try it