fix(non-interactive-env): detect shell type for csh/tcsh env var syntax (fixes #2089)
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import type { PluginInput } from "@opencode-ai/plugin"
|
import type { PluginInput } from "@opencode-ai/plugin"
|
||||||
import { HOOK_NAME, NON_INTERACTIVE_ENV, SHELL_COMMAND_PATTERNS } from "./constants"
|
import { HOOK_NAME, NON_INTERACTIVE_ENV, SHELL_COMMAND_PATTERNS } from "./constants"
|
||||||
import { log, buildEnvPrefix } from "../../shared"
|
import { log, buildEnvPrefix, detectShellType } from "../../shared"
|
||||||
|
|
||||||
export * from "./constants"
|
export * from "./constants"
|
||||||
export * from "./detector"
|
export * from "./detector"
|
||||||
@@ -52,9 +52,9 @@ export function createNonInteractiveEnvHook(_ctx: PluginInput) {
|
|||||||
// The env vars (GIT_EDITOR=:, EDITOR=:, etc.) must ALWAYS be injected
|
// The env vars (GIT_EDITOR=:, EDITOR=:, etc.) must ALWAYS be injected
|
||||||
// for git commands to prevent interactive prompts.
|
// for git commands to prevent interactive prompts.
|
||||||
|
|
||||||
// The bash tool always runs in a Unix-like shell (bash/sh), even on Windows
|
// Detect the current shell type for proper env var syntax (export for bash/zsh, setenv for csh/tcsh, etc.)
|
||||||
// (via Git Bash, WSL, etc.), so always use unix export syntax.
|
const shellType = detectShellType()
|
||||||
const envPrefix = buildEnvPrefix(NON_INTERACTIVE_ENV, "unix")
|
const envPrefix = buildEnvPrefix(NON_INTERACTIVE_ENV, shellType)
|
||||||
|
|
||||||
// Check if the command already starts with the prefix to avoid stacking.
|
// Check if the command already starts with the prefix to avoid stacking.
|
||||||
// This maintains the non-interactive behavior and makes the operation idempotent.
|
// This maintains the non-interactive behavior and makes the operation idempotent.
|
||||||
|
|||||||
+13
-1
@@ -1,4 +1,4 @@
|
|||||||
export type ShellType = "unix" | "powershell" | "cmd"
|
export type ShellType = "unix" | "powershell" | "cmd" | "csh"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Detect the current shell type based on environment variables.
|
* Detect the current shell type based on environment variables.
|
||||||
@@ -14,6 +14,10 @@ export function detectShellType(): ShellType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (process.env.SHELL) {
|
if (process.env.SHELL) {
|
||||||
|
const shell = process.env.SHELL
|
||||||
|
if (shell.includes("csh") || shell.includes("tcsh")) {
|
||||||
|
return "csh"
|
||||||
|
}
|
||||||
return "unix"
|
return "unix"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,6 +38,7 @@ export function shellEscape(value: string, shellType: ShellType): string {
|
|||||||
|
|
||||||
switch (shellType) {
|
switch (shellType) {
|
||||||
case "unix":
|
case "unix":
|
||||||
|
case "csh":
|
||||||
if (/[^a-zA-Z0-9_\-.:\/]/.test(value)) {
|
if (/[^a-zA-Z0-9_\-.:\/]/.test(value)) {
|
||||||
return `'${value.replace(/'/g, "'\\''")}'`
|
return `'${value.replace(/'/g, "'\\''")}'`
|
||||||
}
|
}
|
||||||
@@ -91,6 +96,13 @@ export function buildEnvPrefix(
|
|||||||
return `export ${assignments};`
|
return `export ${assignments};`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case "csh": {
|
||||||
|
const assignments = entries
|
||||||
|
.map(([key, value]) => `setenv ${key} ${shellEscape(value, shellType)}`)
|
||||||
|
.join("; ")
|
||||||
|
return `${assignments};`
|
||||||
|
}
|
||||||
|
|
||||||
case "powershell": {
|
case "powershell": {
|
||||||
const assignments = entries
|
const assignments = entries
|
||||||
.map(([key, value]) => `$env:${key}=${shellEscape(value, shellType)}`)
|
.map(([key, value]) => `$env:${key}=${shellEscape(value, shellType)}`)
|
||||||
|
|||||||
Reference in New Issue
Block a user