Copilot CLI with Agent Host should respect user shell from terminal profile when running shell commands #313679
Conversation
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <copilot@github.com>
|
Base:
|
Co-authored-by: Copilot <copilot@github.com>
There was a problem hiding this comment.
Pull request overview
This PR adds an agent-host–specific terminal profile setting and plumbing so that Copilot CLI shell tools running via the Agent Host use the user’s preferred terminal profile (instead of hardcoded shells), with fallback to the existing integrated terminal default profile.
Changes:
- Introduces
terminal.integrated.agentHostProfile.<os>settings and corresponding resolver support (allowAgentHostShell) to prefer that profile when resolving the default. - Bridges the resolved default shell from the workbench into the agent host root config (
defaultShell) and consumes it in the agent-host terminal manager. - Updates Copilot shell tools to use the terminal manager’s resolved default shell and adds/updates unit tests around shell resolution/classification.
Show a summary per file
| File | Description |
|---|---|
| src/vs/workbench/contrib/terminal/common/terminal.ts | Adds allowAgentHostShell resolve option to support agent-host-specific profile preference. |
| src/vs/workbench/contrib/terminal/browser/terminalProfileResolverService.ts | Prefers agent host profile (when allowed) during default profile resolution. |
| src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostTerminalContribution.ts | Resolves the agent-host shell profile and pushes the executable path to agent host root config. |
| src/vs/platform/terminal/common/terminalPlatformConfiguration.ts | Registers new terminal.integrated.agentHostProfile.<os> settings with schema and descriptions. |
| src/vs/platform/terminal/common/terminal.ts | Adds TerminalSettingId.AgentHostProfile* constants. |
| src/vs/platform/agentHost/common/agentHostCustomizationConfig.ts | Adds AgentHostConfigKey.DefaultShell to agent host root-config schema. |
| src/vs/platform/agentHost/node/agentService.ts | Plumbs configuration service into AgentHostTerminalManager construction. |
| src/vs/platform/agentHost/node/agentHostTerminalManager.ts | Implements getDefaultShell() honoring root-config defaultShell with fallback to system shell. |
| src/vs/platform/agentHost/node/copilot/copilotShellTools.ts | Resolves shell executable from terminal manager, makes tool factory async, and adds shell classification helpers + redirect tool. |
| src/vs/platform/agentHost/node/copilot/copilotAgent.ts | Adjusts session config building to await async shell tool creation. |
| src/vs/platform/agentHost/test/node/copilotShellTools.test.ts | Expands tests to cover terminal-manager-resolved executable and shell classification helpers. |
| src/vs/platform/agentHost/test/node/copilotAgent.test.ts | Updates terminal manager test stub to implement getDefaultShell(). |
Copilot's findings
Comments suppressed due to low confidence (1)
src/vs/platform/agentHost/node/agentHostTerminalManager.ts:205
- Even after receiving
AgentHostConfigKey.DefaultShell,createTerminalcan only use the executable path; any profile-specific arguments are not representable (beyond the hard-coded macOS--loginbehavior). If we want agent host terminals to truly respect terminal profiles, consider supporting configured default shell arguments (and potentially env) in the root config and using them here when spawning the PTY.
const shell = options?.shell ?? await this.getDefaultShell();
const name = platform.isWindows ? 'cmd' : 'xterm-256color';
this._logService.info(`[TerminalManager] Creating terminal ${uri}: shell=${shell}, cwd=${cwd}, cols=${cols}, rows=${rows}`);
- Files reviewed: 12/12 changed files
- Comments generated: 3
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <copilot@github.com>
| return; | ||
| } | ||
|
|
||
| this._agentHostService.dispatch({ |
There was a problem hiding this comment.
We should make sure the agent host has a AgentHostConfigKey.DefaultShell in its rootState.config.schema prior to pushing down the config. You may need to wait until onDidChange for the root state to get hydrated.
We'd also need to dispatch to the connections in IRemoteAgentHostService, this is only the local service that you're listning to right now
There was a problem hiding this comment.
Thanks! this makes sense.
Remote one is tricky - I think I'd need to figure out how to get remote profile resolver, since we can't just use remoteAuthority
The schema-gating piece has been addressed per feedback in 40ba2c1:
_pushDefaultShellnow no-ops until the local host root config schema advertisesAgentHostConfigKey.DefaultShell, retries whenrootStatehydrates/changes.- has tests covering the hydrated/missing-schema cases.
I also clarified the setting wording in cf72e32 so it does not imply full profile fidelity or remote support.
- It now says this currently applies to the local agent host, and notes that remote agent hosts need remote-side shell configuration because local resolved paths may be invalid on the remote.
I split the remaining pieces into follow-ups so this PR can stay focused:
- (current PR) Copilot CLI with Agent Host should respect user shell from terminal profile when running shell commands #313679: local agent-host executable/profile-path selection for Copilot CLI shell tools.
- Pipe terminal-profile
args(and decide onenv) to the agent host #313790: profileargs, and deciding whether/how to supportenv. - Support shell-profile config for remote agent hosts (
IRemoteAgentHostServiceconnections) #313809: remote agent-host shell config /IRemoteAgentHostService.- This is split out because this PR resolves the profile in the local workbench context (
remoteAuthority: undefined) and pushes that executable path to the local agent host. That is safe for local PTYs, but unsafe for remote agent hosts: a locally resolved path likeC:\Program Files\Git\bin\bash.exemay be invalid on the remote machine that owns the PTY. VS Code’s normal terminal flow handles this by resolving profiles/default shells against the terminal backend/remote authority. Agent-host remotes do not have that resolver path yet, so remote support needs a remote-side config/resolution story rather than simply fanning out the local path.
- This is split out because this PR resolves the profile in the local workbench context (
- Replace
AgentHostConfigKey.DefaultShellmagic key with a typed client→host channel #313812: replacing theAgentHostConfigKey.DefaultShellmagic key with a typed client→host channel.
@connor4312 Does that split match what you had in mind?
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <copilot@github.com>
|
@anthonykim1 @connor4312 Thank you both enormously for this! It's a small change, but it'll make a huge difference to us as we don't have modern Powershell running on our locked-down corporate build, so having the Agents UI respect the terminal choice from the IDE means (hopefully) that the Agents UI is actually usable. I'm super pleased about this. Thanks again. |
Resolves: #313160
Existing behavior we already have with Copilot CLI in chat:
Achievement with the PR:
New terminal agent host terminal that will be first priority:

If above is not set, we use user's default terminal profile:

Allow Agent Host (local) to respect profile (more like path executable since args and env are ignored atm) :
