Skip to content

Conversation

meganrogge
Copy link
Contributor

@meganrogge meganrogge commented Oct 10, 2025

Branched from #261503 because there were many merge conflicts and I was nervous to break something

Current status:

Screenshot 2025-10-10 at 4 41 12 PM

To do:

  • when the instance is disposed, ensure the parts are hidden / disposed?
  • all of the comments on here

@Copilot Copilot AI review requested due to automatic review settings October 10, 2025 21:04
@meganrogge meganrogge marked this pull request as draft October 10, 2025 21:04
@meganrogge meganrogge self-assigned this Oct 10, 2025
import type { ITerminalInstance } from '../../../../terminal/browser/terminal.js';
import { TerminalInstance, TerminalInstanceColorProvider } from '../../../../terminal/browser/terminalInstance.js';
import { XtermTerminal } from '../../../../terminal/browser/xterm/xtermTerminal.js';
// TODO@meganrogge fix
Copy link
Contributor Author

@meganrogge meganrogge Oct 10, 2025

Choose a reason for hiding this comment

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

To do: fix somehow, this was also in initial PR

Copy link
Contributor

@Copilot 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 implements terminal inline chat functionality by adding the ability to track terminal execution strategies and display terminal output inline within chat responses. The implementation allows chat responses to show live terminal output by creating dedicated terminal instances that mirror the execution happening in the background.

Key changes:

  • Enhanced terminal execute strategies with marker tracking and update events
  • Added terminal output display capabilities to chat terminal tool progress parts
  • Implemented terminal instance tracking and content synchronization

Reviewed Changes

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

Show a summary per file
File Description
runInTerminalTool.ts Adds execution tracking with UUID generation and strategy association
strategyHelpers.ts Modifies marker disposal to prevent cleanup for persistent UI access
richExecuteStrategy.ts Extends Disposable and adds marker/update event properties
noneExecuteStrategy.ts Extends Disposable and adds marker/update event properties
executeStrategy.ts Defines new interface properties for markers and update events
basicExecuteStrategy.ts Extends Disposable and adds marker/update event properties
xtermTerminal.ts Adds VT sequence serialization method for terminal content extraction
terminalInstance.ts Updates color provider constructor to support flexible location types
terminal.ts Adds interface method for VT range serialization
chatToolInvocationPart.ts Reorders import statements
chatTerminalToolProgressPart.ts Major enhancement adding terminal instance tracking and live output display

// TODO@meganrogge !!! does this cause disposables to be leaked?
// Don't clear the start marker on disposal - we want it to persist
// so terminal UI parts can still access it
console.log('strategy disposed but keeping start marker');
Copy link

Copilot AI Oct 10, 2025

Choose a reason for hiding this comment

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

Replace console.log with proper logging using the ITerminalLogService that's available in the execute strategy classes.

Suggested change
console.log('strategy disposed but keeping start marker');
log?.('strategy disposed but keeping start marker');

Copilot uses AI. Check for mistakes.

}
} else if (!this.xterm) {
// Missing required services, can't create terminal yet
console.log(`Can't create terminal for ${this.externalInstanceId} yet - missing required services`);
Copy link

Copilot AI Oct 10, 2025

Choose a reason for hiding this comment

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

Replace console.log statements with proper logging. Consider using ILogService or another appropriate logging mechanism available through dependency injection.

Copilot uses AI. Check for mistakes.

Comment on lines 146 to 144
console.log(`Start marker already exists for ${this.externalInstanceId} - using for initial data`);
await this.updateTerminalContent(instance, executeStrategy, executeStrategy.startMarker);
} catch (e) {
console.error(`Error getting initial terminal data for ${this.externalInstanceId}:`, e);
}
} else {
console.log(`No start marker available yet for ${this.externalInstanceId} - waiting for marker creation event. Has strategy: ${!!executeStrategy}`);
Copy link

Copilot AI Oct 10, 2025

Choose a reason for hiding this comment

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

Replace all console.log/console.error statements with proper logging using an injected logging service. This will provide better debugging capabilities and follow VS Code's logging patterns.

Copilot uses AI. Check for mistakes.

): Promise<void> {
const latestPartId = ChatTerminalToolProgressPart.latestPartPerInstance.get(this.instanceType!);
if (latestPartId !== this.externalInstanceId) {
console.log(`Skipping update for ${this.externalInstanceId} as ${latestPartId} is the latest`);
Copy link

Copilot AI Oct 10, 2025

Choose a reason for hiding this comment

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

Replace all console.log/console.error statements with proper logging using an injected logging service. This will provide better debugging capabilities and follow VS Code's logging patterns.

Copilot uses AI. Check for mistakes.

// Try persistent marker first
if (this.persistentStartMarker) {
startMarker = this.persistentStartMarker;
console.log(`Using persistent start marker for ${this.externalInstanceId}`);
Copy link

Copilot AI Oct 10, 2025

Choose a reason for hiding this comment

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

Replace all console.log/console.error statements with proper logging using an injected logging service. This will provide better debugging capabilities and follow VS Code's logging patterns.

Copilot uses AI. Check for mistakes.

Comment on lines +23 to +24
// eslint-disable-next-line local/code-import-patterns
import type { ITerminalExecuteStrategy } from '../../../../terminalContrib/chatAgentTools/browser/executeStrategy/executeStrategy.js';
Copy link

Copilot AI Oct 10, 2025

Choose a reason for hiding this comment

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

The eslint-disable comment indicates an import pattern violation that should be addressed. Consider restructuring the imports to follow the established patterns or moving the shared types to a more appropriate location.

Suggested change
// eslint-disable-next-line local/code-import-patterns
import type { ITerminalExecuteStrategy } from '../../../../terminalContrib/chatAgentTools/browser/executeStrategy/executeStrategy.js';
import type { ITerminalExecuteStrategy } from '../../../../terminalContrib/chatAgentTools/common/executeStrategyTypes.js';

Copilot uses AI. Check for mistakes.

Comment on lines +305 to +300
// const icon = !toolInvocation.isConfirmed ?
// Codicon.error :
// toolInvocation.isComplete ?
// Codicon.check : ThemeIcon.modify(Codicon.loading, 'spin');
Copy link

Copilot AI Oct 10, 2025

Choose a reason for hiding this comment

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

Remove commented-out code. If this icon logic is needed for future implementation, consider adding a proper TODO comment or implement it immediately.

Suggested change
// const icon = !toolInvocation.isConfirmed ?
// Codicon.error :
// toolInvocation.isComplete ?
// Codicon.check : ThemeIcon.modify(Codicon.loading, 'spin');
// TODO: Implement icon logic for toolInvocation status if needed (see previous commented-out code).

Copilot uses AI. Check for mistakes.

Comment on lines +41 to +47
// TODO@meganrogge !!! does this cause disposables to be leaked?
// Don't clear the start marker on disposal - we want it to persist
// so terminal UI parts can still access it
console.log('strategy disposed but keeping start marker');
// Don't fire undefined marker event - keep the last valid marker
}));
store.add(startMarker);
// We don't register startMarker with the store to prevent it from being auto-disposed
Copy link
Contributor Author

Choose a reason for hiding this comment

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

todo: fix somehow, with this clearing code, it doesn't work.

But the peristentMarker thing should make this ok 🤔 . maybe timing issue

Comment on lines +48 to +52
// Map from real terminal instance IDs to chat terminal parts
private static readonly instanceToPartMap = new Map<string, Set<ChatTerminalToolProgressPart>>();

// Track the latest part for each terminal instance type (command, output display, etc)
private static readonly latestPartPerInstance = new Map<string, string>();
Copy link
Member

Choose a reason for hiding this comment

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

This thing was really hacky just to get something working, we need to come up with a proper way of transferring the terminal over to the tool. Since we don't necessarily know the instance to be used before this object is constructed it makes things more complicated.

Perhaps a new ITerminalChatService who's job it is initially purely to track these things and make sure they're serialized correctly (so things don't break on reload). Might be worth chatting about this in a sync together.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed, and this file is getting way too big, needs separation.

Here are some notes I made:

// Chat Session
//  ├── Chat Request → Xterm → Instance (start marker → end marker)
//  ├── Chat Request → Xterm → Instance (start marker → end marker)
//  └── Chat Request → Xterm → Instance (start marker → end marker)
// ...

// Notes:
// - Each Instance should be headless, hidden, and per Chat Request?
// - Should allow opening terminals from the chat-embedded one?

interface ChatEmbeddedTerminalService {
 map: Map<ChatSessionId, Xterm[]>;

 createTerminal(): Xterm;
 serialize(): string;
 deserialize(data: string): void;

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.

2 participants