Skip to content

Conversation

@meganrogge
Copy link
Contributor

@meganrogge meganrogge commented Oct 24, 2025

fixes #271387
fixes #271388

Also updates xterm

demo.mov

Copilot AI review requested due to automatic review settings October 24, 2025 19:25
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 PR adds terminal output dropdown functionality and implements command reveal on focus. It integrates terminal commands as attachments in chat, allowing users to attach terminal command output to chat conversations and navigate directly to commands in the terminal.

Key Changes:

  • Added support for terminal command attachments in chat with associated UI widgets and hover previews
  • Implemented command reveal functionality that scrolls to and highlights commands when terminal instances are focused
  • Extended terminal URI handling to support command IDs for direct navigation to specific commands

Reviewed Changes

Copilot reviewed 27 out of 27 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
terminalCommand.ts Added unique ID and session tracking to terminal commands
capabilities.ts Extended command interfaces with ID and chat session fields
decorationAddon.ts Added "Attach To Chat" action for terminal commands
xtermTerminal.ts Updated constructor to accept resource parameter for URI-based navigation
terminalUri.ts Extended URI generation to include command IDs
terminalService.ts Implemented openResource method to reveal commands in terminals
chatVariableEntries.ts Added ITerminalVariableEntry type for terminal command attachments
chatAttachmentWidgets.ts Implemented TerminalCommandAttachmentWidget for displaying terminal commands
chatContext.ts Added TerminalContext class for terminal command context integration
chatTerminalToolProgressPart.ts Added collapsible output preview with show/hide functionality
Test files Updated test instantiations to match new constructor signatures

@meganrogge meganrogge requested a review from Tyriar October 24, 2025 19:26
@meganrogge meganrogge self-assigned this Oct 24, 2025
@meganrogge meganrogge added this to the October 2025 milestone Oct 24, 2025
Tyriar
Tyriar previously requested changes Oct 24, 2025
Copy link
Member

Choose a reason for hiding this comment

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

Comment on lines +404 to +406
if (!terminalInstance) {
return { text: '', truncated: false };
}
Copy link
Member

Choose a reason for hiding this comment

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

_collectOutput is only called when terminalInstance is truthy I believe

Comment on lines +329 to +331
const output = await this._collectOutput(this._terminalInstance);
const content = this._renderOutput(output);
const theme = this._terminalInstance?.xterm?.getXtermTheme();
Copy link
Member

Choose a reason for hiding this comment

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

xterm is used in collect output and in this function. There should be a single xtermReadyPromise call and a single check whether it's truthy.

const content = this._renderOutput(output);
const theme = this._terminalInstance?.xterm?.getXtermTheme();
if (theme) {
const inlineTerminal = content.querySelector('div');
Copy link
Member

Choose a reason for hiding this comment

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

Should use the h helper, and keep track of elements we care about. We should very rarely query sub-elements like this. Doing this should also make the if (inlineTerminal) on the following line unnecessary.

Comment on lines +415 to +420
const text = await xterm.getCommandOutputAsHtml(command, CHAT_TERMINAL_OUTPUT_MAX_PREVIEW_LINES);
if (!text) {
return { text: '', truncated: false };
}

return { text, truncated: false };
Copy link
Member

Choose a reason for hiding this comment

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

This if (!text) seems redundant as getCommandOutputAsHtml returns a string and when it's '' the behavior would be the same if it fell through.

Comment on lines +555 to 561
this._terminalService.setActiveInstance(this._instance);
if (this._instance.target === TerminalLocation.Editor) {
this._terminalEditorService.openEditor(this._instance);
} else {
this._terminalGroupService.showPanel(true);
await this._terminalGroupService.showPanel(true);
}
this._terminalService.setActiveInstance(this._instance);
Copy link
Member

Choose a reason for hiding this comment

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

setActiveInstance is now run twice? This shouldn't be needed. What case were you trying to fix here, as this code is relatively fragile and caused a new insiders to go out when changed before.

Comment on lines +391 to +413
// Trim empty lines from the end
let emptyLinesFromEnd = 0;
for (let i = endLine; i >= startLine; i--) {
const line = this.raw.buffer.active.getLine(i);
if (line && line.translateToString(true).trim() === '') {
emptyLinesFromEnd++;
} else {
break;
}
}
endLine = endLine - emptyLinesFromEnd;

// Trim empty lines from the start
let emptyLinesFromStart = 0;
for (let i = startLine; i <= endLine; i++) {
const line = this.raw.buffer.active.getLine(i);
if (line && line.translateToString(true).trim() === '') {
emptyLinesFromStart++;
} else {
break;
}
}
startLine = startLine + emptyLinesFromStart;
Copy link
Member

Choose a reason for hiding this comment

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

Lots of code repetition

Comment on lines +420 to +423
const bufferLine = this.raw.buffer.active.getLine(startLine);
if (bufferLine) {
startCol = Math.min(startCol, bufferLine.length);
}
Copy link
Member

Choose a reason for hiding this comment

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

It's not clear to me if this does anything

Comment on lines +425 to +427
const range = { startLine, endLine, startCol };
const result = this._serializeAddon.serializeAsHTML({ range });
return result;
Copy link
Member

Choose a reason for hiding this comment

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

nit: Easier to read when it's all on the same line imo

return this._serializeAddon.serializeAsHTML({ startLine, endLine, startCol });

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.

Showing completed terminal tool output in chat view Pop out button should show the terminal command via addressable URI

4 participants