Explorar o código

fix(core): spawn shell non-interactively without sourcing rc files

ShellSelect.args() ran zsh/bash with -l and explicitly sourced .zshrc/.bashrc,
loading user functions and aliases that can shadow builtins and return non-zero
exit codes, breaking && chains. Match the old tool behavior: plain non-login
non-interactive shell -c command with cwd passed via spawn options.
Dax Raad hai 1 mes
pai
achega
01edae4a7f

+ 1 - 1
packages/core/src/shell.ts

@@ -159,7 +159,7 @@ export const layer = Layer.effect(
       const cwd = input.cwd ?? location.directory
       const configShell = Config.latest(yield* config.entries(), "shell")
       const shell = ShellSelect.preferred(configShell)
-      const args = ShellSelect.args(shell, input.command, cwd)
+      const args = ShellSelect.args(shell, input.command)
       const file = path.join(outputDir, `${id}.out`)
       const env = {
         ...process.env,

+ 2 - 29
packages/core/src/shell/select.ts

@@ -163,37 +163,10 @@ function info(file: string): Item {
   }
 }
 
-export function args(file: string, command: string, cwd: string) {
+export function args(file: string, command: string) {
   const n = name(file)
   if (n === "nu" || n === "fish") return ["-c", command]
-  if (n === "zsh") {
-    return [
-      "-l",
-      "-c",
-      `
-        [[ -f ~/.zshenv ]] && source ~/.zshenv >/dev/null 2>&1 || true
-        [[ -f "\${ZDOTDIR:-$HOME}/.zshrc" ]] && source "\${ZDOTDIR:-$HOME}/.zshrc" >/dev/null 2>&1 || true
-        cd -- "$1"
-        eval ${JSON.stringify(command)}
-      `,
-      "opencode",
-      cwd,
-    ]
-  }
-  if (n === "bash") {
-    return [
-      "-l",
-      "-c",
-      `
-        shopt -s expand_aliases
-        [[ -f ~/.bashrc ]] && source ~/.bashrc >/dev/null 2>&1 || true
-        cd -- "$1"
-        eval ${JSON.stringify(command)}
-      `,
-      "opencode",
-      cwd,
-    ]
-  }
+  if (n === "zsh" || n === "bash") return ["-c", command]
   if (n === "cmd") return ["/c", command]
   if (ps(file)) return ["-NoProfile", "-Command", command]
   return ["-c", command]

+ 4 - 6
packages/core/test/shell.test.ts

@@ -55,12 +55,10 @@ describe("shell", () => {
   })
 
   test("builds command args per shell family", () => {
-    expect(ShellSelect.args("/bin/sh", "echo hi", "/tmp")).toEqual(["-c", "echo hi"])
-    expect(ShellSelect.args("/usr/bin/fish", "echo hi", "/tmp")).toEqual(["-c", "echo hi"])
-    const zsh = ShellSelect.args("/bin/zsh", "echo hi", "/tmp")
-    expect(zsh[0]).toBe("-l")
-    expect(zsh[1]).toBe("-c")
-    expect(zsh.at(-1)).toBe("/tmp")
+    expect(ShellSelect.args("/bin/sh", "echo hi")).toEqual(["-c", "echo hi"])
+    expect(ShellSelect.args("/usr/bin/fish", "echo hi")).toEqual(["-c", "echo hi"])
+    expect(ShellSelect.args("/bin/zsh", "echo hi")).toEqual(["-c", "echo hi"])
+    expect(ShellSelect.args("/bin/bash", "echo hi")).toEqual(["-c", "echo hi"])
   })
 
   if (process.platform === "win32") {

+ 1 - 1
packages/opencode/src/session/prompt.ts

@@ -521,7 +521,7 @@ export const layer = Layer.effect(
 
           const cfg = yield* config.get()
           const sh = ShellSelect.preferred(cfg.shell)
-          const args = ShellSelect.args(sh, input.command, cwd)
+          const args = ShellSelect.args(sh, input.command)
           let output = ""
           let aborted = false