Agents: enhance SSH and remote agent host management#312630
Merged
roblourens merged 4 commits intomainfrom Apr 27, 2026
Merged
Conversation
- Rewrite the 'Connect via SSH' picker to mirror the remote-ssh extension UX: configured aliases at the top, dynamic 'user@host' synthetic entry, plus '+ Add New SSH Host...' and 'Configure SSH Hosts...' footer items. - Add 'Add New SSH Host...' command that ensures ~/.ssh/config exists (mode 0700/0600 on POSIX) and inserts a Host snippet with tabstops via SnippetController2. - Add 'Configure SSH Hosts...' command that lists known SSH configuration files (user + system) and opens the picked one. - Add 'Manage Remote Agent Hosts...' F1 command that shows the same actions as the workspace picker's Manage submenu, with inline X buttons to remove non-tunnel remotes. - Show inline X (remove) buttons next to non-tunnel remote entries in the workspace picker Manage submenu, by propagating onRemove from child IActions through actionList. - Extract the per-remote management options popup into a shared showRemoteHostOptions(accessor, provider) helper and consume it from both the workspace picker and the new manage command. - Centralize all action/command IDs on a RemoteAgentHostCommandIds const block. - Add listSSHConfigFiles() to ISSHRemoteAgentHostService (user config always; system config when present) and update all impls + test mocks. (Written by Copilot) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Updates the Agents (sessions) remote-agent-host UX to better match VS Code Remote-SSH, adds SSH config management commands, and introduces a unified “Manage Remote Agent Hosts…” command that reuses the same per-remote actions UI across entry points.
Changes:
- Reworked the SSH connect flow to list
~/.ssh/confighosts, add footer actions, and allow direct[user@]host[:port]connect via a synthetic entry. - Added SSH host/config management commands and a new
ISSHRemoteAgentHostService.listSSHConfigFiles()API (plus implementations/mocks). - Unified remote-host options UI via shared helpers and enabled inline “remove” (X) for non-tunnel remote entries by propagating
onRemovethroughActionListWidgetsubmenus.
Show a summary per file
| File | Description |
|---|---|
| src/vs/sessions/contrib/remoteAgentHost/browser/remoteHostOptions.ts | New shared helpers for remote status labels/hover and per-remote options quick pick. |
| src/vs/sessions/contrib/remoteAgentHost/browser/remoteAgentHostActions.ts | SSH picker rewrite + new SSH management commands + centralized command IDs. |
| src/vs/sessions/contrib/remoteAgentHost/browser/remoteAgentHost.contribution.ts | Registers the new “Manage Remote Agent Hosts…” action contribution. |
| src/vs/sessions/contrib/remoteAgentHost/browser/manageRemoteAgentHosts.ts | New unified management picker combining connected/known remotes with contributed actions. |
| src/vs/sessions/contrib/chat/browser/sessionWorkspacePicker.ts | Reuses shared remote-host options helpers and adds inline remove for non-tunnel remotes. |
| src/vs/sessions/contrib/chat/browser/scopedWorkspacePicker.ts | Constructor updated to match WorkspacePicker DI changes (instantiation service). |
| src/vs/platform/agentHost/test/electron-browser/sshRemoteAgentHostService.test.ts | Updates test mock to include new SSH config methods. |
| src/vs/platform/agentHost/test/electron-browser/sshRelayTransport.test.ts | Updates test mock to include new SSH config methods. |
| src/vs/platform/agentHost/node/sshRemoteAgentHostService.ts | Adds ensure/list SSH config file helpers in the node main service. |
| src/vs/platform/agentHost/electron-browser/sshRemoteAgentHostServiceImpl.ts | Exposes new SSH config methods via IPC proxy to the renderer service. |
| src/vs/platform/agentHost/common/sshRemoteAgentHost.ts | Extends SSH service interfaces with ensure/list SSH config file APIs. |
| src/vs/platform/agentHost/browser/nullSshRemoteAgentHostService.ts | Adds browser-null stubs for the new SSH config methods. |
| src/vs/platform/actionWidget/browser/actionList.ts | Propagates onRemove into submenu items to enable inline X buttons in submenus. |
Copilot's findings
Comments suppressed due to low confidence (1)
src/vs/sessions/contrib/remoteAgentHost/browser/manageRemoteAgentHosts.ts:165
- When invoking menu-contributed actions, this uses
commandService.executeCommand(selected.action.id)which drops anyMenuItemActionarguments/options (options.args,options.arg,shouldForwardArgs) and can change behavior compared to how the same actions run from the menu/submenu. Prefer callingselected.action.run()(or otherwise preserve the action’s configured args) so the unified picker truly matches the Manage submenu behavior.
if (selected.kind === 'remote') {
// Defer to allow the picker to fully hide before opening options
setTimeout(() => instantiationService.invokeFunction(a => showRemoteHostOptions(a, selected.provider)), 1);
} else if (selected.kind === 'menu-action') {
commandService.executeCommand(selected.action.id);
}
- Files reviewed: 13/13 changed files
- Comments generated: 2
- remoteHostOptions: add showBackButton option to showRemoteHostOptions(); now returns 'back' when the back button is pressed; picker is created with createQuickPick for full button support - remoteAgentHostActions: add showBackButton option to promptToConnectViaSSH(); the ConnectViaSSH action's run() accepts an optional onBack callback and calls it when the back button is pressed - manageRemoteAgentHosts: extract showManagePicker() inner function so it can be called recursively on back; pass showManagePicker as onBack callback to both the per-remote options picker and SSH sub-flow actions Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Configure SSH Hosts file picker now shows back button when launched from SSH picker, returning to SSH picker on click - Tunnel picker now shows back button when launched from manage picker, returning to manage picker on click - Both pickers fix leaked disposables by wrapping in DisposableStore - Remove leftover setTimeout from manage picker onDidAccept - Add comment explaining legitimate setTimeout in workspace picker Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Rename 'Connected' separator to 'Remote Agent Hosts' since items are not filtered by connection status - Rethrow errors from ensureUserSSHConfig so callers can surface real failures to the user instead of silently opening a bad path Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
rwoll
approved these changes
Apr 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Brings the Agents app's SSH/remote-host management UX in line with the vscode-remote-ssh extension, and adds an inline manage-everything command. (Written by Copilot)
SSH host picker
Rewrites "Agents: Connect to Remote Agent Host via SSH" to mirror the remote-ssh "Connect to SSH" picker:
Hostaliases from~/.ssh/config(recursively expandingInclude) listed at the top.+ Add New SSH Host...andConfigure SSH Hosts...(both also F1-able as their own commands).➤ user@hostentry appears as soon as the typed value parses as a valid SSH connection string. Press Enter and we connect directly without ever creating a config entry.The previous "Enter manually" item is gone — the synthetic entry replaces it.
New SSH commands
~/.sshexists (mode 0700), creates~/.ssh/configif missing (mode 0600), opens it, and inserts aHost alias / HostName hostname / User usersnippet viaSnippetController2with tabstops on each placeholder.ISSHRemoteAgentHostService.listSSHConfigFiles()(user config +/etc/ssh/ssh_configon POSIX or%ProgramData%\ssh\ssh_configon Windows when present), shows a quick pick (skipped when only one), and opens the chosen file. The user file is created on demand if picked and missing.Workspace picker Manage submenu — inline X buttons
Non-tunnel remote entries now render an inline X (remove) button in the Manage submenu, same as recently-opened folders at the top level. Implemented by propagating
onRemovefrom childIActions throughActionListWidgetwhen building submenu items.New "Manage Remote Agent Hosts..." command (F1)
A unified picker that shows the same set of items as the workspace picker's Manage submenu — connected remotes (with X buttons) plus the contributed Add/Manage actions. Picking a connected remote opens the per-remote actions popup (Reconnect / Remove / Copy address / Open Settings / Show Output). The actions popup logic was extracted into
showRemoteHostOptions(accessor, provider)so it's shared between the workspace picker and the new command.Internal cleanup
RemoteAgentHostCommandIds.listSSHConfigFiles()toISSHRemoteAgentHostService+ impls (node, electron-browser, browser-null) and test mocks.QuickPickand event subscriptions in aDisposableStorethat disposes ononDidHideto avoid a leaked-disposable warning.Verification
Verified live in the Agents window via the launch skill: SSH picker shows aliases + synthetic entry + footer items; Add New SSH Host opens
~/.ssh/configwith active snippet tabstops; Configure SSH Hosts shows the file picker and opens the chosen file; Manage Remote Agent Hosts opens the unified picker.