Skip to content

Conversation

@meganrogge
Copy link
Contributor

@meganrogge meganrogge commented Nov 18, 2025

fixes #276946
fixes #271390

To do/defer:

  • occasionally the next prompt is included in the output, tried to fix that, but looks like the endMarker is just wrong in these cases
  • add setting to determine if it's expanded when streaming or if only expanded for non-zero exit code
  • calculate max width so horizontal scrollbar is hidden unless necessary

Summary:

  • Owns the rolling chat-terminal buffer (terminalCommandOutput), resetting it from stored output or when a new stream begins so the preview knows the stream state (isStreaming, needsReplay, shouldRender).
  • Adds incremental VT data via appendData, which keeps the stream active, concatenates chunks, and records them for later replay.
  • Diffs each snapshot from xterm against the last one in applySnapshot, emitting one of four mutations: no-op, append (shared prefix), truncate+append (partial overlap), or full replace when the buffer diverges.
  • Detects overlap for truncation with a bounded KMP search and overlap/ratio thresholds, protecting against quadratic scans and avoiding trims for small prompt churn.
  • Provides helpers (applyEmptyOutput, countRenderableLines, markRenderableOutput, getBufferedText, getBuffer) so the view can clear, size, or replay the preview without re-reading the terminal.

Copilot AI review requested due to automatic review settings November 18, 2025 22:19
@meganrogge meganrogge self-assigned this Nov 18, 2025
@meganrogge meganrogge added this to the November 2025 milestone Nov 18, 2025
@meganrogge meganrogge requested review from Tyriar and removed request for Copilot November 18, 2025 22:20
Copilot finished reviewing on behalf of meganrogge November 18, 2025 22:25
@meganrogge meganrogge marked this pull request as draft November 18, 2025 23:26
Copilot AI review requested due to automatic review settings November 18, 2025 23:34
Copilot finished reviewing on behalf of meganrogge November 18, 2025 23:36
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This pull request implements streaming of terminal command output to inline chat terminal views. The changes replace the previous HTML-based output rendering with a live xterm instance that displays output as it's captured in real-time. The PR removes the serialized command output collection and instead streams terminal data directly to a detached terminal instance.

Key changes:

  • Streaming terminal output is captured via onData events and written to a detached xterm instance
  • Command output collection is removed from the artifact collector - it now only collects metadata (exit code, timestamp, duration)
  • The command ID is ensured before firing onCommandExecuted to enable proper command tracking during streaming

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 8 comments.

File Description
terminalCommandArtifactCollector.ts Removes output serialization logic; now only captures command metadata
chatTerminalToolProgressPart.ts Implements streaming architecture with detached terminal instance and buffer management
chatTerminalToolProgressPart.css Adds styling for embedded xterm terminal and scroll container
commandDetectionCapability.ts Moves command ID assignment before command execution event to ensure ID is available for tracking

@meganrogge meganrogge requested a review from Copilot November 19, 2025 15:40
Copilot finished reviewing on behalf of meganrogge November 19, 2025 15:44
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.

@meganrogge meganrogge requested review from Tyriar and Copilot November 20, 2025 01:28
Copilot finished reviewing on behalf of meganrogge November 20, 2025 01:31
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 17 comments.

DonJayamanne
DonJayamanne previously approved these changes Nov 20, 2025
Copy link
Member

Choose a reason for hiding this comment

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

Testing out and it doesn't handle commands with lots of output well

Finished inline:

Image

Actual command:

Image

Copy link
Contributor Author

@meganrogge meganrogge Nov 20, 2025

Choose a reason for hiding this comment

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

I can repro

Copy link
Member

Choose a reason for hiding this comment

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

I recommending taking a step back from this and first replacing the HTML with the xterm instance in its own PR, focusing on maintainability and small modules. At 2100 lines that makes this larger than the entirety of terminalTaskSystem.ts or terminalService.ts.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

moving ChatTerminalStreamingModel to its own file helps with this, but yes, can do

export const focusMostRecentChatTerminalCommandId = 'workbench.action.chat.focusMostRecentChatTerminal';
export const focusMostRecentChatTerminalOutputCommandId = 'workbench.action.chat.focusMostRecentChatTerminalOutput';

KeybindingsRegistry.registerCommandAndKeybindingRule({
Copy link
Member

Choose a reason for hiding this comment

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

Seeing this now, we should not be registering keybindings, menus or commands outside of contribution files

Copy link
Contributor Author

Choose a reason for hiding this comment

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

separate pr

Comment on lines 561 to 564
private _streamingQueue: IStreamingSnapshotRequest[];
private readonly _streamingSnapshotRetryCounts = new WeakMap<ITerminalCommand, number>();
private _isDrainingStreamingQueue = false;
private _streamingDrainScheduled = false;
Copy link
Member

Choose a reason for hiding this comment

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

I question the queue approach in general, but these are the sort of properties that should live in one of the other classes.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I thought this is what you meant by not chaining promises together and keeping track of the requests in a Data[]. What do you think would be better?

@meganrogge
Copy link
Contributor Author

Closing in favor of smaller PRs

@meganrogge meganrogge closed this Nov 21, 2025
Sign up for free to 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.

Stream inline terminal tool output into chat view Embed xterm.js instead of text content

4 participants