Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 0 additions & 3 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -877,7 +877,6 @@ export default tseslint.config(
'src/vs/workbench/contrib/tasks/common/taskConfiguration.ts',
'src/vs/workbench/contrib/tasks/common/taskSystem.ts',
'src/vs/workbench/contrib/tasks/common/tasks.ts',
'src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts',
'src/vs/workbench/contrib/terminal/browser/terminalConfigurationService.ts',
'src/vs/workbench/contrib/terminal/browser/terminalExtensions.ts',
'src/vs/workbench/contrib/terminal/browser/terminalProcessExtHostProxy.ts',
Expand All @@ -886,7 +885,6 @@ export default tseslint.config(
'src/vs/workbench/contrib/terminal/browser/terminalProfileService.ts',
'src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts',
'src/vs/workbench/contrib/terminal/common/basePty.ts',
'src/vs/workbench/contrib/terminal/common/remote/remoteTerminalChannel.ts',
'src/vs/workbench/contrib/terminal/common/terminal.ts',
'src/vs/workbench/contrib/terminalContrib/links/browser/links.ts',
'src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts',
Expand Down Expand Up @@ -989,7 +987,6 @@ export default tseslint.config(
'src/vs/server/node/remoteAgentEnvironmentImpl.ts',
'src/vs/server/node/remoteExtensionHostAgentServer.ts',
'src/vs/server/node/remoteExtensionsScanner.ts',
'src/vs/server/node/remoteTerminalChannel.ts',
// Tests
'**/*.test.ts',
'**/*.integrationTest.ts'
Expand Down
43 changes: 22 additions & 21 deletions src/vs/server/node/remoteTerminalChannel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,12 @@ export class RemoteTerminalChannel extends Disposable implements IServerChannel<

private _lastReqId = 0;
private readonly _pendingCommands = new Map<number, {
resolve: (data: any) => void;
reject: (err: any) => void;
resolve: (value: unknown) => void;
reject: (err?: unknown) => void;
uriTransformer: IURITransformer;
}>();

private readonly _onExecuteCommand = this._register(new Emitter<{ reqId: number; persistentProcessId: number; commandId: string; commandArgs: any[] }>());
private readonly _onExecuteCommand = this._register(new Emitter<{ reqId: number; persistentProcessId: number; commandId: string; commandArgs: unknown[] }>());
readonly onExecuteCommand = this._onExecuteCommand.event;

constructor(
Expand All @@ -109,6 +109,7 @@ export class RemoteTerminalChannel extends Disposable implements IServerChannel<
super();
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
async call(ctx: RemoteAgentConnectionContext, command: RemoteTerminalChannelRequest, args?: any): Promise<any> {
switch (command) {
case RemoteTerminalChannelRequest.RestartPtyHost: return this._ptyHostService.restartPtyHost.apply(this._ptyHostService, args);
Expand Down Expand Up @@ -167,21 +168,21 @@ export class RemoteTerminalChannel extends Disposable implements IServerChannel<
throw new Error(`IPC Command ${command} not found`);
}

listen(_: any, event: RemoteTerminalChannelEvent, arg: any): Event<any> {
listen<T extends unknown>(_: unknown, event: RemoteTerminalChannelEvent, _arg: unknown): Event<T> {
Copy link

Copilot AI Nov 8, 2025

Choose a reason for hiding this comment

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

The generic constraint T extends unknown is redundant since all types extend unknown by definition. This can be simplified to just <T>.

Suggested change
listen<T extends unknown>(_: unknown, event: RemoteTerminalChannelEvent, _arg: unknown): Event<T> {
listen<T>(_: unknown, event: RemoteTerminalChannelEvent, _arg: unknown): Event<T> {

Copilot uses AI. Check for mistakes.
switch (event) {
case RemoteTerminalChannelEvent.OnPtyHostExitEvent: return this._ptyHostService.onPtyHostExit || Event.None;
case RemoteTerminalChannelEvent.OnPtyHostStartEvent: return this._ptyHostService.onPtyHostStart || Event.None;
case RemoteTerminalChannelEvent.OnPtyHostUnresponsiveEvent: return this._ptyHostService.onPtyHostUnresponsive || Event.None;
case RemoteTerminalChannelEvent.OnPtyHostResponsiveEvent: return this._ptyHostService.onPtyHostResponsive || Event.None;
case RemoteTerminalChannelEvent.OnPtyHostRequestResolveVariablesEvent: return this._ptyHostService.onPtyHostRequestResolveVariables || Event.None;
case RemoteTerminalChannelEvent.OnProcessDataEvent: return this._ptyHostService.onProcessData;
case RemoteTerminalChannelEvent.OnProcessReadyEvent: return this._ptyHostService.onProcessReady;
case RemoteTerminalChannelEvent.OnProcessExitEvent: return this._ptyHostService.onProcessExit;
case RemoteTerminalChannelEvent.OnProcessReplayEvent: return this._ptyHostService.onProcessReplay;
case RemoteTerminalChannelEvent.OnProcessOrphanQuestion: return this._ptyHostService.onProcessOrphanQuestion;
case RemoteTerminalChannelEvent.OnExecuteCommand: return this.onExecuteCommand;
case RemoteTerminalChannelEvent.OnDidRequestDetach: return this._ptyHostService.onDidRequestDetach || Event.None;
case RemoteTerminalChannelEvent.OnDidChangeProperty: return this._ptyHostService.onDidChangeProperty;
case RemoteTerminalChannelEvent.OnPtyHostExitEvent: return (this._ptyHostService.onPtyHostExit || Event.None) as Event<T>;
case RemoteTerminalChannelEvent.OnPtyHostStartEvent: return (this._ptyHostService.onPtyHostStart || Event.None) as Event<T>;
case RemoteTerminalChannelEvent.OnPtyHostUnresponsiveEvent: return (this._ptyHostService.onPtyHostUnresponsive || Event.None) as Event<T>;
case RemoteTerminalChannelEvent.OnPtyHostResponsiveEvent: return (this._ptyHostService.onPtyHostResponsive || Event.None) as Event<T>;
case RemoteTerminalChannelEvent.OnPtyHostRequestResolveVariablesEvent: return (this._ptyHostService.onPtyHostRequestResolveVariables || Event.None) as Event<T>;
case RemoteTerminalChannelEvent.OnProcessDataEvent: return (this._ptyHostService.onProcessData) as Event<T>;
Copy link

Copilot AI Nov 8, 2025

Choose a reason for hiding this comment

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

Unnecessary parentheses in the type cast. Since there's no || Event.None fallback here, the parentheses can be removed: this._ptyHostService.onProcessData as Event<T>

Suggested change
case RemoteTerminalChannelEvent.OnProcessDataEvent: return (this._ptyHostService.onProcessData) as Event<T>;
case RemoteTerminalChannelEvent.OnProcessDataEvent: return this._ptyHostService.onProcessData as Event<T>;

Copilot uses AI. Check for mistakes.
case RemoteTerminalChannelEvent.OnProcessReadyEvent: return (this._ptyHostService.onProcessReady) as Event<T>;
Copy link

Copilot AI Nov 8, 2025

Choose a reason for hiding this comment

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

Unnecessary parentheses in the type cast. Since there's no || Event.None fallback here, the parentheses can be removed: this._ptyHostService.onProcessReady as Event<T>

Suggested change
case RemoteTerminalChannelEvent.OnProcessReadyEvent: return (this._ptyHostService.onProcessReady) as Event<T>;
case RemoteTerminalChannelEvent.OnProcessReadyEvent: return this._ptyHostService.onProcessReady as Event<T>;

Copilot uses AI. Check for mistakes.
case RemoteTerminalChannelEvent.OnProcessExitEvent: return (this._ptyHostService.onProcessExit) as Event<T>;
Copy link

Copilot AI Nov 8, 2025

Choose a reason for hiding this comment

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

Unnecessary parentheses in the type cast. Since there's no || Event.None fallback here, the parentheses can be removed: this._ptyHostService.onProcessExit as Event<T>

Suggested change
case RemoteTerminalChannelEvent.OnProcessExitEvent: return (this._ptyHostService.onProcessExit) as Event<T>;
case RemoteTerminalChannelEvent.OnProcessExitEvent: return this._ptyHostService.onProcessExit as Event<T>;

Copilot uses AI. Check for mistakes.
case RemoteTerminalChannelEvent.OnProcessReplayEvent: return (this._ptyHostService.onProcessReplay) as Event<T>;
Copy link

Copilot AI Nov 8, 2025

Choose a reason for hiding this comment

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

Unnecessary parentheses in the type cast. Since there's no || Event.None fallback here, the parentheses can be removed: this._ptyHostService.onProcessReplay as Event<T>

Suggested change
case RemoteTerminalChannelEvent.OnProcessReplayEvent: return (this._ptyHostService.onProcessReplay) as Event<T>;
case RemoteTerminalChannelEvent.OnProcessReplayEvent: return this._ptyHostService.onProcessReplay as Event<T>;

Copilot uses AI. Check for mistakes.
case RemoteTerminalChannelEvent.OnProcessOrphanQuestion: return (this._ptyHostService.onProcessOrphanQuestion) as Event<T>;
Copy link

Copilot AI Nov 8, 2025

Choose a reason for hiding this comment

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

Unnecessary parentheses in the type cast. Since there's no || Event.None fallback here, the parentheses can be removed: this._ptyHostService.onProcessOrphanQuestion as Event<T>

Suggested change
case RemoteTerminalChannelEvent.OnProcessOrphanQuestion: return (this._ptyHostService.onProcessOrphanQuestion) as Event<T>;
case RemoteTerminalChannelEvent.OnProcessOrphanQuestion: return this._ptyHostService.onProcessOrphanQuestion as Event<T>;

Copilot uses AI. Check for mistakes.
case RemoteTerminalChannelEvent.OnExecuteCommand: return (this.onExecuteCommand) as Event<T>;
Copy link

Copilot AI Nov 8, 2025

Choose a reason for hiding this comment

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

Unnecessary parentheses in the type cast. Since there's no || Event.None fallback here, the parentheses can be removed: this.onExecuteCommand as Event<T>

Suggested change
case RemoteTerminalChannelEvent.OnExecuteCommand: return (this.onExecuteCommand) as Event<T>;
case RemoteTerminalChannelEvent.OnExecuteCommand: return this.onExecuteCommand as Event<T>;

Copilot uses AI. Check for mistakes.
case RemoteTerminalChannelEvent.OnDidRequestDetach: return (this._ptyHostService.onDidRequestDetach || Event.None) as Event<T>;
case RemoteTerminalChannelEvent.OnDidChangeProperty: return (this._ptyHostService.onDidChangeProperty) as Event<T>;
Copy link

Copilot AI Nov 8, 2025

Choose a reason for hiding this comment

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

Unnecessary parentheses in the type cast. Since there's no || Event.None fallback here, the parentheses can be removed: this._ptyHostService.onDidChangeProperty as Event<T>

Suggested change
case RemoteTerminalChannelEvent.OnDidChangeProperty: return (this._ptyHostService.onDidChangeProperty) as Event<T>;
case RemoteTerminalChannelEvent.OnDidChangeProperty: return this._ptyHostService.onDidChangeProperty as Event<T>;

Copilot uses AI. Check for mistakes.
}

// @ts-expect-error Assert event is the `never` type to ensure all messages are handled
Expand Down Expand Up @@ -263,7 +264,7 @@ export class RemoteTerminalChannel extends Disposable implements IServerChannel<

const persistentProcessId = await this._ptyHostService.createProcess(shellLaunchConfig, initialCwd, args.cols, args.rows, args.unicodeVersion, env, baseEnv, args.options, args.shouldPersistTerminal, args.workspaceId, args.workspaceName);
const commandsExecuter: ICommandsExecuter = {
executeCommand: <T>(id: string, ...args: any[]): Promise<T> => this._executeCommand(persistentProcessId, id, args, uriTransformer)
executeCommand: <T>(id: string, ...args: unknown[]): Promise<T> => this._executeCommand(persistentProcessId, id, args, uriTransformer)
};
const cliServer = new CLIServerBase(commandsExecuter, this._logService, ipcHandlePath);
this._ptyHostService.onProcessExit(e => e.id === persistentProcessId && cliServer.dispose());
Expand All @@ -274,11 +275,11 @@ export class RemoteTerminalChannel extends Disposable implements IServerChannel<
};
}

private _executeCommand<T>(persistentProcessId: number, commandId: string, commandArgs: any[], uriTransformer: IURITransformer): Promise<T> {
private _executeCommand<T>(persistentProcessId: number, commandId: string, commandArgs: unknown[], uriTransformer: IURITransformer): Promise<T> {
const { resolve, reject, promise } = promiseWithResolvers<T>();

const reqId = ++this._lastReqId;
this._pendingCommands.set(reqId, { resolve, reject, uriTransformer });
this._pendingCommands.set(reqId, { resolve: resolve as (value: unknown) => void, reject, uriTransformer });

const serializedCommandArgs = cloneAndChange(commandArgs, (obj) => {
if (obj && obj.$mid === 1) {
Expand All @@ -300,7 +301,7 @@ export class RemoteTerminalChannel extends Disposable implements IServerChannel<
return promise;
}

private _sendCommandResult(reqId: number, isError: boolean, serializedPayload: any): void {
private _sendCommandResult(reqId: number, isError: boolean, serializedPayload: unknown): void {
const data = this._pendingCommands.get(reqId);
if (!data) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { Registry } from '../../../../platform/registry/common/platform.js';
import { IRemoteAuthorityResolverService } from '../../../../platform/remote/common/remoteAuthorityResolver.js';
import { IStorageService, StorageScope, StorageTarget } from '../../../../platform/storage/common/storage.js';
import { ISerializedTerminalCommand } from '../../../../platform/terminal/common/capabilities/capabilities.js';
import { IPtyHostLatencyMeasurement, IShellLaunchConfig, IShellLaunchConfigDto, ITerminalBackend, ITerminalBackendRegistry, ITerminalChildProcess, ITerminalEnvironment, ITerminalLogService, ITerminalProcessOptions, ITerminalProfile, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, ProcessPropertyType, TerminalExtensions, TerminalIcon, TerminalSettingId, TitleEventSource } from '../../../../platform/terminal/common/terminal.js';
import { IPtyHostLatencyMeasurement, IShellLaunchConfig, IShellLaunchConfigDto, ITerminalBackend, ITerminalBackendRegistry, ITerminalChildProcess, ITerminalEnvironment, ITerminalLogService, ITerminalProcessOptions, ITerminalProfile, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, ProcessPropertyType, TerminalExtensions, TerminalIcon, TerminalSettingId, TitleEventSource, type IProcessPropertyMap } from '../../../../platform/terminal/common/terminal.js';
import { IProcessDetails } from '../../../../platform/terminal/common/terminalProcess.js';
import { IWorkspaceContextService } from '../../../../platform/workspace/common/workspace.js';
import { IWorkbenchContribution } from '../../../common/contributions.js';
Expand Down Expand Up @@ -257,7 +257,7 @@ class RemoteTerminalBackend extends BaseTerminalBackend implements ITerminalBack
];
}

async updateProperty<T extends ProcessPropertyType>(id: number, property: T, value: any): Promise<void> {
async updateProperty<T extends ProcessPropertyType>(id: number, property: T, value: IProcessPropertyMap[T]): Promise<void> {
await this._remoteTerminalChannel.updateProperty(id, property, value);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,14 @@ export class RemoteTerminalChannelClient implements IPtyHostController {
get onProcessOrphanQuestion(): Event<{ id: number }> {
return this._channel.listen<{ id: number }>(RemoteTerminalChannelEvent.OnProcessOrphanQuestion);
}
get onExecuteCommand(): Event<{ reqId: number; persistentProcessId: number; commandId: string; commandArgs: any[] }> {
return this._channel.listen<{ reqId: number; persistentProcessId: number; commandId: string; commandArgs: any[] }>(RemoteTerminalChannelEvent.OnExecuteCommand);
get onExecuteCommand(): Event<{ reqId: number; persistentProcessId: number; commandId: string; commandArgs: unknown[] }> {
return this._channel.listen<{ reqId: number; persistentProcessId: number; commandId: string; commandArgs: unknown[] }>(RemoteTerminalChannelEvent.OnExecuteCommand);
}
get onDidRequestDetach(): Event<{ requestId: number; workspaceId: string; instanceId: number }> {
return this._channel.listen<{ requestId: number; workspaceId: string; instanceId: number }>(RemoteTerminalChannelEvent.OnDidRequestDetach);
}
get onDidChangeProperty(): Event<{ id: number; property: IProcessProperty<any> }> {
return this._channel.listen<{ id: number; property: IProcessProperty<any> }>(RemoteTerminalChannelEvent.OnDidChangeProperty);
get onDidChangeProperty(): Event<{ id: number; property: IProcessProperty }> {
return this._channel.listen<{ id: number; property: IProcessProperty }>(RemoteTerminalChannelEvent.OnDidChangeProperty);
}

constructor(
Expand Down Expand Up @@ -246,7 +246,7 @@ export class RemoteTerminalChannelClient implements IPtyHostController {
orphanQuestionReply(id: number): Promise<void> {
return this._channel.call(RemoteTerminalChannelRequest.OrphanQuestionReply, [id]);
}
sendCommandResult(reqId: number, isError: boolean, payload: any): Promise<void> {
sendCommandResult(reqId: number, isError: boolean, payload: unknown): Promise<void> {
return this._channel.call(RemoteTerminalChannelRequest.SendCommandResult, [reqId, isError, payload]);
}
freePortKillProcess(port: string): Promise<{ port: string; processId: string }> {
Expand Down
Loading