diff --git a/packages/desktop/src/main/shell-env.test.ts b/packages/desktop/src/main/shell-env.test.ts index cfe88277ea..e71708ad04 100644 --- a/packages/desktop/src/main/shell-env.test.ts +++ b/packages/desktop/src/main/shell-env.test.ts @@ -1,6 +1,6 @@ import { describe, expect, test } from "bun:test" -import { isNushell, mergeShellEnv, parseShellEnv } from "./shell-env" +import { isNushell, mergeShellEnv, parseShellEnv, resolveUserShell } from "./shell-env" describe("shell env", () => { test("parseShellEnv supports null-delimited pairs", () => { @@ -34,6 +34,13 @@ describe("shell env", () => { expect(env.OPENCODE_CLIENT).toBe("desktop") }) + test("resolveUserShell falls back to the login shell before /bin/sh", () => { + expect(resolveUserShell("/custom/env-shell", "/bin/zsh")).toBe("/custom/env-shell") + expect(resolveUserShell(undefined, "/bin/zsh")).toBe("/bin/zsh") + expect(resolveUserShell(undefined, "unknown")).toBe("/bin/sh") + expect(resolveUserShell(undefined, undefined)).toBe("/bin/sh") + }) + test("isNushell handles path and binary name", () => { expect(isNushell("nu")).toBe(true) expect(isNushell("/opt/homebrew/bin/nu")).toBe(true) diff --git a/packages/desktop/src/main/shell-env.ts b/packages/desktop/src/main/shell-env.ts index 4a65fbf0f7..deb43033ae 100644 --- a/packages/desktop/src/main/shell-env.ts +++ b/packages/desktop/src/main/shell-env.ts @@ -1,4 +1,5 @@ import { spawnSync } from "node:child_process" +import { userInfo } from "node:os" import { basename } from "node:path" import { getLogger } from "./logging" @@ -6,8 +7,17 @@ const TIMEOUT = 5_000 type Probe = { type: "Loaded"; value: Record } | { type: "Timeout" } | { type: "Unavailable" } +export function resolveUserShell(envShell: string | undefined, loginShell: string | null | undefined) { + const resolvedLoginShell = loginShell && loginShell !== "unknown" ? loginShell : undefined + return envShell || resolvedLoginShell || "/bin/sh" +} + export function getUserShell() { - return process.env.SHELL || "/bin/sh" + try { + return resolveUserShell(process.env.SHELL, userInfo().shell) + } catch { + return resolveUserShell(process.env.SHELL, undefined) + } } export function parseShellEnv(out: Buffer) {