fix(coding-agent): resolve shell config from session settings
Stop shell resolution from consulting ambient process.cwd() during bash execution and use the active session's shellPath setting instead. closes #3452
This commit is contained in:
@@ -1,10 +1,12 @@
|
||||
import { existsSync } from "node:fs";
|
||||
import { delimiter } from "node:path";
|
||||
import { spawn, spawnSync } from "child_process";
|
||||
import { getBinDir, getSettingsPath } from "../config.js";
|
||||
import { SettingsManager } from "../core/settings-manager.js";
|
||||
import { getBinDir } from "../config.js";
|
||||
|
||||
let cachedShellConfig: { shell: string; args: string[] } | null = null;
|
||||
export interface ShellConfig {
|
||||
shell: string;
|
||||
args: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Find bash executable on PATH (cross-platform)
|
||||
@@ -42,29 +44,19 @@ function findBashOnPath(): string | null {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get shell configuration based on platform.
|
||||
* Resolve shell configuration based on platform and an optional explicit shell path.
|
||||
* Resolution order:
|
||||
* 1. User-specified shellPath in settings.json
|
||||
* 1. User-specified shellPath
|
||||
* 2. On Windows: Git Bash in known locations, then bash on PATH
|
||||
* 3. On Unix: /bin/bash, then bash on PATH, then fallback to sh
|
||||
*/
|
||||
export function getShellConfig(): { shell: string; args: string[] } {
|
||||
if (cachedShellConfig) {
|
||||
return cachedShellConfig;
|
||||
}
|
||||
|
||||
const settings = SettingsManager.create(process.cwd());
|
||||
const customShellPath = settings.getShellPath();
|
||||
|
||||
export function getShellConfig(customShellPath?: string): ShellConfig {
|
||||
// 1. Check user-specified shell path
|
||||
if (customShellPath) {
|
||||
if (existsSync(customShellPath)) {
|
||||
cachedShellConfig = { shell: customShellPath, args: ["-c"] };
|
||||
return cachedShellConfig;
|
||||
return { shell: customShellPath, args: ["-c"] };
|
||||
}
|
||||
throw new Error(
|
||||
`Custom shell path not found: ${customShellPath}\nPlease update shellPath in ${getSettingsPath()}`,
|
||||
);
|
||||
throw new Error(`Custom shell path not found: ${customShellPath}`);
|
||||
}
|
||||
|
||||
if (process.platform === "win32") {
|
||||
@@ -81,41 +73,36 @@ export function getShellConfig(): { shell: string; args: string[] } {
|
||||
|
||||
for (const path of paths) {
|
||||
if (existsSync(path)) {
|
||||
cachedShellConfig = { shell: path, args: ["-c"] };
|
||||
return cachedShellConfig;
|
||||
return { shell: path, args: ["-c"] };
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Fallback: search bash.exe on PATH (Cygwin, MSYS2, WSL, etc.)
|
||||
const bashOnPath = findBashOnPath();
|
||||
if (bashOnPath) {
|
||||
cachedShellConfig = { shell: bashOnPath, args: ["-c"] };
|
||||
return cachedShellConfig;
|
||||
return { shell: bashOnPath, args: ["-c"] };
|
||||
}
|
||||
|
||||
throw new Error(
|
||||
`No bash shell found. Options:\n` +
|
||||
` 1. Install Git for Windows: https://git-scm.com/download/win\n` +
|
||||
` 2. Add your bash to PATH (Cygwin, MSYS2, etc.)\n` +
|
||||
` 3. Set shellPath in ${getSettingsPath()}\n\n` +
|
||||
" 3. Set shellPath in settings.json\n\n" +
|
||||
`Searched Git Bash in:\n${paths.map((p) => ` ${p}`).join("\n")}`,
|
||||
);
|
||||
}
|
||||
|
||||
// Unix: try /bin/bash, then bash on PATH, then fallback to sh
|
||||
if (existsSync("/bin/bash")) {
|
||||
cachedShellConfig = { shell: "/bin/bash", args: ["-c"] };
|
||||
return cachedShellConfig;
|
||||
return { shell: "/bin/bash", args: ["-c"] };
|
||||
}
|
||||
|
||||
const bashOnPath = findBashOnPath();
|
||||
if (bashOnPath) {
|
||||
cachedShellConfig = { shell: bashOnPath, args: ["-c"] };
|
||||
return cachedShellConfig;
|
||||
return { shell: bashOnPath, args: ["-c"] };
|
||||
}
|
||||
|
||||
cachedShellConfig = { shell: "sh", args: ["-c"] };
|
||||
return cachedShellConfig;
|
||||
return { shell: "sh", args: ["-c"] };
|
||||
}
|
||||
|
||||
export function getShellEnv(): NodeJS.ProcessEnv {
|
||||
|
||||
Reference in New Issue
Block a user