Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
113 commits
Select commit Hold shift + click to select a range
30c3b10
fixes #259261
meganrogge Oct 20, 2025
7c335a2
Merge branch 'main' into merogge/terminal-last
meganrogge Oct 20, 2025
b5e7b3e
include output
meganrogge Oct 23, 2025
27a3917
do not encode commandLine and outpu t in uri
meganrogge Oct 23, 2025
919b8f7
Merge branch 'main' into merogge/terminal-last
meganrogge Oct 23, 2025
44580cf
re-add something
meganrogge Oct 23, 2025
01a9423
format
meganrogge Oct 23, 2025
82dca7c
revert a bunch of changes
meganrogge Oct 23, 2025
cc4ad9a
revert more changes
meganrogge Oct 23, 2025
e5a1fc6
revert more changes
meganrogge Oct 23, 2025
e7894c6
get it mostly working
meganrogge Oct 23, 2025
581dab5
handle disposal properly
meganrogge Oct 23, 2025
45fea3d
add exit code
meganrogge Oct 23, 2025
d0f7d31
slight tweaks
meganrogge Oct 23, 2025
fe1e01e
add terminalService openResource
meganrogge Oct 24, 2025
0652e4f
pass in URI to xtermTerminal instead of instanceId
meganrogge Oct 24, 2025
28d4442
get hover and click working, add custom widget
meganrogge Oct 24, 2025
cc79afd
get it to work!
meganrogge Oct 24, 2025
7aa7432
rm resource check from input part
meganrogge Oct 24, 2025
d95cd6a
part of #271388
meganrogge Oct 24, 2025
3c7521c
Update src/vs/workbench/contrib/chat/browser/actions/chatContext.ts
meganrogge Oct 24, 2025
44fcff8
use html
meganrogge Oct 24, 2025
1756c51
Merge branch 'main' into merogge/inline-output
meganrogge Oct 24, 2025
026842a
scroll down by default
meganrogge Oct 24, 2025
e35e8fb
Merge branch 'main' into merogge/inline-output
meganrogge Oct 24, 2025
9e040ad
rename to align
meganrogge Oct 24, 2025
4d24d8a
rename
meganrogge Oct 24, 2025
e2e8410
fix issue with context menu action not showing up
meganrogge Oct 24, 2025
3ccc52f
fix issue with context menu action not showing up
meganrogge Oct 24, 2025
c085718
followups
meganrogge Oct 24, 2025
d3ebafd
Merge branch 'merogge/cleanup' into merogge/inline-output
meganrogge Oct 24, 2025
3990af9
add stuff
meganrogge Oct 24, 2025
ec55245
fix bug
meganrogge Oct 24, 2025
c892ad4
Merge branch 'main' into merogge/inline-output
meganrogge Oct 24, 2025
d5c0cf5
don't fallback
meganrogge Oct 24, 2025
fdad452
go back to text
meganrogge Oct 24, 2025
b4673ba
keep last max lines
meganrogge Oct 24, 2025
104b442
Merge branch 'main' into merogge/inline-output
meganrogge Oct 27, 2025
64be1c5
rm `chatSessionId` form `ITerminalCommand`, add `terminalCommandUri` …
meganrogge Oct 27, 2025
2066294
chars, not lines
meganrogge Oct 27, 2025
90984d6
rm space between elements, style
meganrogge Oct 27, 2025
1c9cdcc
try to get scrollbar working
meganrogge Oct 27, 2025
b0f1afd
fix layout issues
meganrogge Oct 27, 2025
cf9fce6
set scrollbars to auto
meganrogge Oct 27, 2025
f4e6d01
@xterm/[email protected]
meganrogge Oct 28, 2025
ec7aca0
get it mostly working
meganrogge Oct 28, 2025
bafb618
get it to work on reload
meganrogge Oct 28, 2025
49de5ce
fix start/end
meganrogge Oct 28, 2025
4060a42
get reload working for real
meganrogge Oct 28, 2025
36388f0
Update src/vs/workbench/contrib/chat/browser/chatContentParts/toolInv…
meganrogge Oct 28, 2025
d402df0
Update src/vs/workbench/contrib/chat/browser/chatContentParts/toolInv…
meganrogge Oct 28, 2025
702e8d0
cleanup
meganrogge Oct 28, 2025
ffc125a
fix issue
meganrogge Oct 28, 2025
211e912
add action on command finished
meganrogge Oct 28, 2025
21336f5
fix action order
meganrogge Oct 28, 2025
5f72467
polish style of title
meganrogge Oct 29, 2025
a086976
get rid of height 100%
meganrogge Oct 29, 2025
a2aa259
rm inline width
meganrogge Oct 29, 2025
0df968f
add getHtmlForCommand, extract ToggleChatTerminalOutputAction
meganrogge Oct 29, 2025
c1dc885
use URI
meganrogge Oct 29, 2025
40005ea
use URI
meganrogge Oct 29, 2025
8b14e57
rm overkill function
meganrogge Oct 29, 2025
a7feba3
trim empty lines
meganrogge Oct 29, 2025
215d10a
revert a commit
meganrogge Oct 29, 2025
9c6c85c
don't set command uri too early
meganrogge Oct 29, 2025
86f2d33
Register actions as disposable
meganrogge Oct 29, 2025
c0174d1
rm width
meganrogge Oct 29, 2025
16738cb
wip, not working well
meganrogge Oct 29, 2025
b5ec5b0
Apply suggestion from @meganrogge
meganrogge Oct 29, 2025
8fa79c9
Apply suggestion from @meganrogge
meganrogge Oct 29, 2025
7860bc5
Apply suggestion from @meganrogge
meganrogge Oct 29, 2025
47e5709
cleanup
meganrogge Oct 29, 2025
ee28e69
clean up
meganrogge Oct 29, 2025
866dab6
fix double border
meganrogge Oct 29, 2025
354dca5
Update src/vs/workbench/contrib/chat/browser/chatContentParts/toolInv…
meganrogge Oct 30, 2025
9b2e7b4
Update src/vs/workbench/contrib/chat/browser/chatContentParts/toolInv…
meganrogge Oct 30, 2025
d404e7c
revert changes
meganrogge Oct 30, 2025
ca3c6ae
Merge branch 'main' into merogge/inline-output
meganrogge Oct 30, 2025
b60f110
add todo
meganrogge Oct 30, 2025
158c137
fix bug
meganrogge Oct 30, 2025
f2d7c98
rename function
meganrogge Oct 30, 2025
dd4924f
don't override startCol
meganrogge Oct 30, 2025
c81d9b1
rm lines
meganrogge Oct 30, 2025
f557a9d
use const enums
meganrogge Oct 30, 2025
fa99301
get output to show on reload
meganrogge Oct 30, 2025
07f235c
fix issue
meganrogge Oct 30, 2025
194dc79
rename
meganrogge Oct 30, 2025
21fa01d
cleanup
meganrogge Oct 30, 2025
4d54439
still have focus terminal action even if no command
meganrogge Oct 30, 2025
754d216
Merge branch 'main' into merogge/inline-output
meganrogge Oct 30, 2025
5767f4f
enable modifying for now
meganrogge Oct 30, 2025
341bad3
Merge branch 'main' into merogge/inline-output
meganrogge Oct 30, 2025
47bafa8
fix error, use UriComponents
meganrogge Oct 30, 2025
daf34d7
Initial plan
Copilot Oct 30, 2025
6e75209
Add command ID support for terminal commands to link across renderer …
Copilot Oct 30, 2025
fc7410c
Improve command ID handling with setNextCommandId method
Copilot Oct 30, 2025
7013a8c
Merge branch 'main' into copilot/link-command-id-in-terminal
meganrogge Oct 31, 2025
d880136
Simplify _updateTerminalCommandMetadata using command ID lookup
Copilot Oct 31, 2025
02be8c6
Add missing terminalCommandUri to IChatTerminalToolInvocationData
Copilot Oct 31, 2025
db4013c
Remove unnecessary _updateTerminalCommandMetadata method
Copilot Oct 31, 2025
dc9f36e
Move command ID management to terminalChatService
Copilot Oct 31, 2025
b770d1f
set next command id
meganrogge Oct 31, 2025
d2eccf7
get command to persist
meganrogge Oct 31, 2025
5a80b6e
rm output
meganrogge Oct 31, 2025
92736e9
Merge branch 'main' into merogge/persist-command
meganrogge Oct 31, 2025
5af5703
tweak
meganrogge Oct 31, 2025
f68c200
Update src/vs/workbench/contrib/terminalContrib/chatAgentTools/browse…
meganrogge Oct 31, 2025
5683fbe
Update src/vs/platform/terminal/common/capabilities/commandDetectionC…
meganrogge Oct 31, 2025
67ab4da
Merge branch 'main' into merogge/persist-command
meganrogge Oct 31, 2025
368c070
Fix bug
meganrogge Oct 31, 2025
064acdc
Merge branch 'main' into merogge/persist-command
meganrogge Oct 31, 2025
2196dea
clean up
meganrogge Oct 31, 2025
880cd7c
Rm persisting command IDs in terminal chat service
meganrogge Oct 31, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion src/vs/platform/terminal/common/capabilities/capabilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,12 @@ export interface ICommandDetectionCapability {
* always be present when running the _builtin_ SI scripts.
*/
setCommandLine(commandLine: string, isTrusted: boolean): void;
/**
* Sets the command ID to use for the next command that starts.
* This allows pre-assigning an ID before the shell sends the command start sequence,
* which is useful for linking commands across renderer and ptyHost.
*/
setNextCommandId(command: string, commandId: string): void;
serialize(): ISerializedCommandDetectionCapability;
deserialize(serialized: ISerializedCommandDetectionCapability): void;
}
Expand All @@ -270,6 +276,12 @@ export interface IHandleCommandOptions {
* Properties for the mark
*/
markProperties?: IMarkProperties;

/**
* An optional predefined command ID. When provided, this ID will be used instead of
* generating a new one, allowing commands to be linked across renderer and ptyHost.
*/
commandId?: string;
}

export interface INaiveCwdDetectionCapability {
Expand All @@ -291,7 +303,7 @@ interface IBaseTerminalCommand {
isTrusted: boolean;
timestamp: number;
duration: number;
id: string;
id: string | undefined;

// Optional serializable
cwd: string | undefined;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@
import { IMarkProperties, ISerializedTerminalCommand, ITerminalCommand } from '../capabilities.js';
import { ITerminalOutputMatcher, ITerminalOutputMatch } from '../../terminal.js';
import type { IBuffer, IBufferLine, IMarker, Terminal } from '@xterm/headless';
import { generateUuid } from '../../../../../base/common/uuid.js';

export interface ITerminalCommandProperties {
command: string;
commandLineConfidence: 'low' | 'medium' | 'high';
isTrusted: boolean;
timestamp: number;
duration: number;
id: string;
id: string | undefined;
marker: IMarker | undefined;
cwd: string | undefined;
exitCode: number | undefined;
Expand Down Expand Up @@ -276,7 +275,7 @@ export class PartialTerminalCommand implements ICurrentPartialCommand {
cwd?: string;
command?: string;
commandLineConfidence?: 'low' | 'medium' | 'high';
id: string;
id: string | undefined;

isTrusted?: boolean;
isInvalid?: boolean;
Expand All @@ -285,8 +284,7 @@ export class PartialTerminalCommand implements ICurrentPartialCommand {
private readonly _xterm: Terminal,
id?: string
) {
//TODO: this does not restore properly due to conflicting with the one created in the. PtyHost
this.id = id ?? generateUuid();
this.id = id;
}

serialize(cwd: string | undefined): ISerializedTerminalCommand | undefined {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export class CommandDetectionCapability extends Disposable implements ICommandDe
private _handleCommandStartOptions?: IHandleCommandOptions;
private _hasRichCommandDetection: boolean = false;
get hasRichCommandDetection() { return this._hasRichCommandDetection; }
private _nextCommandId: { command: string; commandId: string | undefined } | undefined;

private _ptyHeuristicsHooks: ICommandDetectionHeuristicsHooks;
private readonly _ptyHeuristics: MandatoryMutableDisposable<IPtyHeuristics>;
Expand Down Expand Up @@ -342,6 +343,14 @@ export class CommandDetectionCapability extends Disposable implements ICommandDe
this._ptyHeuristics.value.handleCommandStart(options);
}

/**
* Sets the command ID to use for the next command that starts.
* This is useful when you want to pre-assign an ID before the shell sends the command start sequence.
*/
setNextCommandId(command: string, commandId: string): void {
this._nextCommandId = { command, commandId };
}

handleCommandExecuted(options?: IHandleCommandOptions): void {
this._ptyHeuristics.value.handleCommandExecuted(options);
this._currentCommand.markExecutedTime();
Expand All @@ -355,7 +364,20 @@ export class CommandDetectionCapability extends Disposable implements ICommandDe
if (!this._currentCommand.commandExecutedMarker) {
this.handleCommandExecuted();
}

// If a custom command ID is provided, use it for the current command
// Otherwise, check if there's a pending next command ID
if (options?.commandId) {
this._currentCommand.id = options.commandId;
this._nextCommandId = undefined; // Clear the pending ID
} else if (
this._nextCommandId &&
typeof this.currentCommand.command === 'string' &&
typeof this._nextCommandId.command === 'string' &&
this.currentCommand.command.trim() === this._nextCommandId.command.trim()
) {
this._currentCommand.id = this._nextCommandId.commandId;
this._nextCommandId = undefined; // Clear after use
}
this._currentCommand.markFinishedTime();
this._ptyHeuristics.value.preHandleCommandFinished?.();

Expand Down Expand Up @@ -392,7 +414,9 @@ export class CommandDetectionCapability extends Disposable implements ICommandDe
this._logService.debug('CommandDetectionCapability#onCommandFinished', newCommand);
this._onCommandFinished.fire(newCommand);
}
this._currentCommand = new PartialTerminalCommand(this._terminal);
// Create new command for next execution, preserving command ID if one was specified
const nextCommandId = this._handleCommandStartOptions?.commandId;
this._currentCommand = new PartialTerminalCommand(this._terminal, nextCommandId);
this._handleCommandStartOptions = undefined;
}

Expand Down
9 changes: 9 additions & 0 deletions src/vs/platform/terminal/common/terminal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ export interface IPtyService {
getInitialCwd(id: number): Promise<string>;
getCwd(id: number): Promise<string>;
acknowledgeDataEvent(id: number, charCount: number): Promise<void>;
setNextCommandId(id: number, commandLine: string, commandId: string): Promise<void>;
setUnicodeVersion(id: number, version: '6' | '11'): Promise<void>;
processBinary(id: number, data: string): Promise<void>;
/** Confirm the process is _not_ an orphan. */
Expand Down Expand Up @@ -816,6 +817,12 @@ export interface ITerminalChildProcess {
*/
acknowledgeDataEvent(charCount: number): void;

/**
* Pre-assigns the command identifier that should be associated with the next command detected by
* shell integration. This keeps the pty host and renderer command stores aligned.
*/
setNextCommandId(commandLine: string, commandId: string): Promise<void>;

/**
* Sets the unicode version for the process, this drives the size of some characters in the
* xterm-headless instance.
Expand Down Expand Up @@ -976,6 +983,8 @@ export interface IShellIntegration {
readonly onDidChangeSeenSequences: Event<ReadonlySet<string>>;

deserialize(serialized: ISerializedCommandDetectionCapability): void;

setNextCommandId(command: string, commandId: string): void;
}

export interface IDecorationAddon {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,12 @@ export class ShellIntegrationAddon extends Disposable implements IShellIntegrati
this._createOrGetBufferMarkDetection(terminal).getMark(vscodeMarkerId);
}

setNextCommandId(command: string, commandId: string): void {
if (this._terminal) {
this._createOrGetCommandDetection(this._terminal).setNextCommandId(command, commandId);
}
}

private _markSequenceSeen(sequence: string) {
if (!this._seenSequences.has(sequence)) {
this._seenSequences.add(sequence);
Expand Down
3 changes: 3 additions & 0 deletions src/vs/platform/terminal/node/ptyHostService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,9 @@ export class PtyHostService extends Disposable implements IPtyHostService {
setUnicodeVersion(id: number, version: '6' | '11'): Promise<void> {
return this._proxy.setUnicodeVersion(id, version);
}
setNextCommandId(id: number, commandLine: string, commandId: string): Promise<void> {
return this._proxy.setNextCommandId(id, commandLine, commandId);
}
getInitialCwd(id: number): Promise<string> {
return this._proxy.getInitialCwd(id);
}
Expand Down
15 changes: 15 additions & 0 deletions src/vs/platform/terminal/node/ptyService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,11 @@ export class PtyService extends Disposable implements IPtyService {
async setUnicodeVersion(id: number, version: '6' | '11'): Promise<void> {
return this._throwIfNoPty(id).setUnicodeVersion(version);
}

@traceRpc
async setNextCommandId(id: number, commandLine: string, commandId: string): Promise<void> {
return this._throwIfNoPty(id).setNextCommandId(commandLine, commandId);
}
@traceRpc
async getLatency(): Promise<IPtyHostLatencyMeasurement[]> {
return [];
Expand Down Expand Up @@ -892,6 +897,11 @@ class PersistentTerminalProcess extends Disposable {
this._serializer.setUnicodeVersion?.(version);
// TODO: Pass in unicode version in ctor
}

async setNextCommandId(commandLine: string, commandId: string): Promise<void> {
this._serializer.setNextCommandId?.(commandLine, commandId);
}

acknowledgeDataEvent(charCount: number): void {
if (this._inReplay) {
return;
Expand Down Expand Up @@ -1039,6 +1049,10 @@ class XtermSerializer implements ITerminalSerializer {
this._xterm.clear();
}

setNextCommandId(commandLine: string, commandId: string): void {
this._shellIntegrationAddon.setNextCommandId(commandLine, commandId);
}

async generateReplayEvent(normalBufferOnly?: boolean, restoreToLastReviveBuffer?: boolean): Promise<IPtyHostProcessReplayEvent> {
const serialize = new (await this._getSerializeConstructor());
this._xterm.loadAddon(serialize);
Expand Down Expand Up @@ -1126,4 +1140,5 @@ interface ITerminalSerializer {
clearBuffer(): void;
generateReplayEvent(normalBufferOnly?: boolean, restoreToLastReviveBuffer?: boolean): Promise<IPtyHostProcessReplayEvent>;
setUnicodeVersion?(version: '6' | '11'): void;
setNextCommandId?(commandLine: string, commandId: string): void;
}
4 changes: 4 additions & 0 deletions src/vs/platform/terminal/node/terminalProcess.ts
Original file line number Diff line number Diff line change
Expand Up @@ -614,6 +614,10 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess
// No-op
}

async setNextCommandId(commandLine: string, commandId: string): Promise<void> {
// No-op: command IDs are tracked on the renderer and serializer only.
}

getInitialCwd(): Promise<string> {
return Promise.resolve(this._initialCwd);
}
Expand Down
1 change: 1 addition & 0 deletions src/vs/server/node/remoteTerminalChannel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ export class RemoteTerminalChannel extends Disposable implements IServerChannel<
case RemoteTerminalChannelRequest.ReviveTerminalProcesses: return this._ptyHostService.reviveTerminalProcesses.apply(this._ptyHostService, args);
case RemoteTerminalChannelRequest.GetRevivedPtyNewId: return this._ptyHostService.getRevivedPtyNewId.apply(this._ptyHostService, args);
case RemoteTerminalChannelRequest.SetUnicodeVersion: return this._ptyHostService.setUnicodeVersion.apply(this._ptyHostService, args);
case RemoteTerminalChannelRequest.SetNextCommandId: return this._ptyHostService.setNextCommandId.apply(this._ptyHostService, args);
case RemoteTerminalChannelRequest.ReduceConnectionGraceTime: return this._reduceConnectionGraceTime();
case RemoteTerminalChannelRequest.UpdateIcon: return this._ptyHostService.updateIcon.apply(this._ptyHostService, args);
case RemoteTerminalChannelRequest.UpdateTitle: return this._ptyHostService.updateTitle.apply(this._ptyHostService, args);
Expand Down
4 changes: 4 additions & 0 deletions src/vs/workbench/api/common/extHostTerminalService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,10 @@ class ExtHostPseudoterminal implements ITerminalChildProcess {
// No-op, xterm-headless isn't used for extension owned terminals.
}

async setNextCommandId(commandLine: string, commandId: string): Promise<void> {
// No-op, command IDs are only tracked on the renderer for extension terminals.
}

getInitialCwd(): Promise<string> {
return Promise.resolve('');
}
Expand Down
Loading
Loading