Set SHELL correctly in background shells.

This commit is contained in:
Dominic Cooney
2026-05-18 08:23:13 -07:00
committed by Max Paulus 🥪
parent c20096b1a8
commit 8bfef89972
2 changed files with 21 additions and 2 deletions
@@ -99,6 +99,10 @@ export class StandaloneTerminalProcess extends EventEmitter<TerminalProcessEvent
stdio: ["ignore", "pipe", "pipe"], // Disable STDIN to prevent interactivity
env: {
...process.env,
// Set SHELL to match the shell we're actually spawning, not
// whatever the parent process inherited. This ensures child
// processes and scripts that inspect $SHELL see the correct value.
SHELL: shell,
TERM: "xterm-256color",
PAGER: "cat", // Prevent less from being used, reducing interactivity
EDITOR: process.env.EDITOR || "cat", // Set EDITOR if not already set
+17 -2
View File
@@ -19,6 +19,7 @@ import { createTool, type Tool, type ToolContext } from "@clinebot/shared"
import { StateManager } from "@/core/storage/StateManager"
import type { ITerminalManager } from "@/integrations/terminal/types"
import { Logger } from "@/shared/services/Logger"
import { getShellForProfile } from "@/utils/shell"
// ---------------------------------------------------------------------------
// Types
@@ -51,11 +52,16 @@ export interface VscodeRunCommandsToolOptions {
function createBackgroundExecutor(opts: {
timeoutMs: number
maxOutputBytes: number
shell: string
}): (command: string, cwd: string, context: ToolContext) => Promise<string> {
const executors = createDefaultExecutors({
bash: {
timeoutMs: opts.timeoutMs,
maxOutputBytes: opts.maxOutputBytes,
shell: opts.shell,
// Set SHELL env to match the shell we're spawning so child
// processes see the correct value instead of the inherited parent's.
env: { SHELL: opts.shell },
},
})
return executors.bash!
@@ -208,8 +214,9 @@ async function executeBackground(
export function createVscodeRunCommandsTool(options: VscodeRunCommandsToolOptions): Tool {
const { cwd, getTerminalManager, backgroundTimeoutMs = 300_000, backgroundMaxOutputBytes = 1_000_000 } = options
// Lazy-init background executor
// Lazy-init background executor — recreated when the user's shell profile changes.
let bgExecutor: ((command: string, cwd: string, context: ToolContext) => Promise<string>) | undefined
let bgExecutorShell: string | undefined
// Lazy-init terminal manager reference
let terminalManager: ITerminalManager | undefined
@@ -247,11 +254,19 @@ export function createVscodeRunCommandsTool(options: VscodeRunCommandsToolOption
if (mode === "backgroundExec") {
// Background path — use SDK's createBashExecutor
if (!bgExecutor) {
// Resolve shell from the user's terminal profile setting
const profileId = (StateManager.get().getGlobalSettingsKey("defaultTerminalProfile") as string) || "default"
const shell = getShellForProfile(profileId)
// Recreate the executor if the shell has changed
if (!bgExecutor || bgExecutorShell !== shell) {
bgExecutorShell = shell
bgExecutor = createBackgroundExecutor({
timeoutMs: backgroundTimeoutMs,
maxOutputBytes: backgroundMaxOutputBytes,
shell,
})
Logger.log(`[VscodeRunCommands] Background executor using shell: ${shell}`)
}
const results = await Promise.all(commands.map((cmd) => executeBackground(cmd, cwd, bgExecutor!, context)))
return results