Skip to content

Commit 50b9df8

Browse files
committed
fix: use VS Code default shell for command execution instead of /bin/sh
When terminalShellIntegrationDisabled is true (the default), commands are executed via execa. Previously, execa used shell: true which defaults to /bin/sh on Linux, ignoring the user's VS Code terminal shell settings. Now execa falls back to getShell() which respects: - VS Code terminal.integrated.defaultProfile.linux - os.userInfo().shell - $SHELL environment variable - Platform-specific defaults (/bin/bash on Linux, /bin/zsh on macOS)
1 parent 47e6215 commit 50b9df8

2 files changed

Lines changed: 11 additions & 4 deletions

File tree

src/integrations/terminal/ExecaTerminalProcess.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import psTree from "ps-tree"
33
import process from "process"
44

55
import type { RooTerminal } from "./types"
6+
import { getShell } from "../../utils/shell"
67
import { BaseTerminal } from "./BaseTerminal"
78
import { BaseTerminalProcess } from "./BaseTerminalProcess"
89

@@ -40,7 +41,7 @@ export class ExecaTerminalProcess extends BaseTerminalProcess {
4041
this.isHot = true
4142

4243
this.subprocess = execa({
43-
shell: BaseTerminal.getExecaShellPath() || true,
44+
shell: BaseTerminal.getExecaShellPath() || getShell(),
4445
cwd: this.terminal.getCurrentWorkingDirectory(),
4546
all: true,
4647
// Ignore stdin to ensure non-interactive mode and prevent hanging

src/integrations/terminal/__tests__/ExecaTerminalProcess.spec.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// npx vitest run integrations/terminal/__tests__/ExecaTerminalProcess.spec.ts
22

33
const mockPid = 12345
4+
const mockGetShell = vitest.fn(() => "/bin/bash")
45

56
vitest.mock("execa", () => {
67
const mockKill = vitest.fn()
@@ -21,6 +22,10 @@ vitest.mock("ps-tree", () => ({
2122
default: vitest.fn((_: number, cb: any) => cb(null, [])),
2223
}))
2324

25+
vitest.mock("../../../utils/shell", () => ({
26+
getShell: () => mockGetShell(),
27+
}))
28+
2429
import { execa } from "execa"
2530
import { ExecaTerminalProcess } from "../ExecaTerminalProcess"
2631
import { BaseTerminal } from "../BaseTerminal"
@@ -63,7 +68,7 @@ describe("ExecaTerminalProcess", () => {
6368
const execaMock = vitest.mocked(execa)
6469
expect(execaMock).toHaveBeenCalledWith(
6570
expect.objectContaining({
66-
shell: true,
71+
shell: "/bin/bash",
6772
cwd: "/test/cwd",
6873
all: true,
6974
env: expect.objectContaining({
@@ -105,13 +110,14 @@ describe("ExecaTerminalProcess", () => {
105110
)
106111
})
107112

108-
it("should fall back to shell=true when execaShellPath is undefined", async () => {
113+
it("should fall back to getShell() when execaShellPath is undefined", async () => {
109114
BaseTerminal.setExecaShellPath(undefined)
115+
mockGetShell.mockReturnValue("/usr/bin/zsh")
110116
await terminalProcess.run("echo test")
111117
const execaMock = vitest.mocked(execa)
112118
expect(execaMock).toHaveBeenCalledWith(
113119
expect.objectContaining({
114-
shell: true,
120+
shell: "/usr/bin/zsh",
115121
}),
116122
)
117123
})

0 commit comments

Comments
 (0)