feat: add GOOSE_SHELL env var to configure preferred shell#7909
feat: add GOOSE_SHELL env var to configure preferred shell#7909DOsinga merged 1 commit intoblock:mainfrom
Conversation
87b17dc to
bf7258a
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 87b17dc9a5
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 67e155f7e4
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| let shell_name = Path::new(shell) | ||
| .file_stem() | ||
| .and_then(|s| s.to_str()) | ||
| .unwrap_or(shell); |
There was a problem hiding this comment.
Normalize preferred shell name before argument matching
The shell-type dispatch is currently case-sensitive, so on Windows a valid GOOSE_SHELL like C:\Windows\System32\WindowsPowerShell\v1.0\PowerShell.EXE (or CMD.EXE) produces a stem of PowerShell/CMD, misses these lowercase match arms, and falls through to the POSIX -c path; those shells do not accept -c, so shell execution fails even though the executable path is valid. Converting the extracted stem to lowercase before the match would make this robust to normal Windows path casing.
Useful? React with 👍 / 👎.
Apply the GOOSE_SHELL feature to the current developer extension location (crates/goose/src/agents/platform_extensions/developer/shell.rs). - build_shell_command checks GOOSE_SHELL before $SHELL / /bin/bash - resolve_login_shell_path also respects GOOSE_SHELL - On Windows, lower-case the shell stem before matching so PowerShell.EXE and CMD.EXE are recognised correctly (fixes case-sensitive match bug) - POSIX-like shells on Windows (Cygwin/MSYS2 bash) use -c instead of /C Signed-off-by: Douwe Osinga <[email protected]>
DOsinga
left a comment
There was a problem hiding this comment.
Good feature, real pain point. The P1 (Windows PATH probing for POSIX shells) was already fixed by the author. I pushed a one-liner fix for the unaddressed P2 — case-insensitive shell name matching so PowerShell.EXE / PWSH.EXE resolve to the right args on Windows.
049262c to
9af6ef6
Compare
DOsinga
left a comment
There was a problem hiding this comment.
Rebased onto current main and applied the GOOSE_SHELL feature to the new developer extension location (crates/goose/src/agents/platform_extensions/developer/shell.rs) — the original target (crates/goose-mcp/src/developer/) was moved since the PR was opened. Also fixed the case-sensitive shell name matching on Windows (Codex P2: PowerShell.EXE → stem lowercased before matching so pwsh/powershell/cmd arms fire correctly). The PR's redundant doc comments were not ported.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9af6ef6357
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| let mut command = { | ||
| let mut command = tokio::process::Command::new("cmd"); | ||
| command.arg("/C").raw_arg(command_line); | ||
| let shell = std::env::var("GOOSE_SHELL").unwrap_or_else(|_| "cmd".to_string()); |
There was a problem hiding this comment.
Treat empty GOOSE_SHELL as unset
If GOOSE_SHELL is present but empty (for example GOOSE_SHELL=), std::env::var returns Ok(""), so this code constructs Command::new("") and shell execution fails with a spawn error. Before this change, the code fell back to a working default shell (cmd on Windows, /bin/bash/$SHELL on Unix), so an empty override now causes a full regression in command execution. Filtering out empty values before using the override would preserve the intended fallback behavior.
Useful? React with 👍 / 👎.
Signed-off-by: Douwe Osinga <[email protected]> Co-authored-by: Douwe Osinga <[email protected]> Signed-off-by: esnyder <[email protected]>
Signed-off-by: Douwe Osinga <[email protected]> Co-authored-by: Douwe Osinga <[email protected]> Signed-off-by: esnyder <[email protected]>
Signed-off-by: Douwe Osinga <[email protected]> Co-authored-by: Douwe Osinga <[email protected]> Signed-off-by: esnyder <[email protected]>
* origin/main: (62 commits) Tweak the release process: no more merge to main (#7994) fix: gemini models via databricks (#8042) feat(apps): Pass toolInfo to MCP Apps via hostContext (#7506) fix: remove configured marker when deleting oauth provider configuration (#7887) docs: add vmware-aiops MCP extension documentation (#8055) Show setup instructions for ACP providers in settings modal (#8065) deps: replace sigstore-verification with sigstore-verify to kill vulns (#8064) feat(acp): add session/set_config and stabilize list, delete and close (#7984) docs: Correct `gosoe` typo to `goose` (#8062) fix: use default provider and model when provider in session no longer exists (#8035) feat: add GOOSE_SHELL env var to configure preferred shell (#7909) fix(desktop): fullscreen header bar + always-visible close controls (#8033) docs: add Claude Code approve mode permission routing documentation (#7949) chatgpt_codex: Support reasoning and gpt-5.4 (#7941) refactor(anthropic): fix N+1 thinking message storage issue (#7958) fix: handle mid-stream error events in OpenAI SSE streaming (#8031) Fix apps extension: coerce string arguments from inner LLM responses (#8030) feat: ability to expand sidebar to see chats names (#7816) Fix config for GOOSE_MAX_BACKGROUND_TASKS (#7940) set MACOSX_DEPLOYMENT_TARGET=12.0 (#7947) ...
…pstream * wpfleger/socket-support: (62 commits) Tweak the release process: no more merge to main (#7994) fix: gemini models via databricks (#8042) feat(apps): Pass toolInfo to MCP Apps via hostContext (#7506) fix: remove configured marker when deleting oauth provider configuration (#7887) docs: add vmware-aiops MCP extension documentation (#8055) Show setup instructions for ACP providers in settings modal (#8065) deps: replace sigstore-verification with sigstore-verify to kill vulns (#8064) feat(acp): add session/set_config and stabilize list, delete and close (#7984) docs: Correct `gosoe` typo to `goose` (#8062) fix: use default provider and model when provider in session no longer exists (#8035) feat: add GOOSE_SHELL env var to configure preferred shell (#7909) fix(desktop): fullscreen header bar + always-visible close controls (#8033) docs: add Claude Code approve mode permission routing documentation (#7949) chatgpt_codex: Support reasoning and gpt-5.4 (#7941) refactor(anthropic): fix N+1 thinking message storage issue (#7958) fix: handle mid-stream error events in OpenAI SSE streaming (#8031) Fix apps extension: coerce string arguments from inner LLM responses (#8030) feat: ability to expand sidebar to see chats names (#7816) Fix config for GOOSE_MAX_BACKGROUND_TASKS (#7940) set MACOSX_DEPLOYMENT_TARGET=12.0 (#7947) ...
* main: (37 commits) fix: handle reasoning content blocks in OpenAI-compat streaming parser (#8078) chore(acp): build native packages on latest mac (#8075) Display delegate sub agents logs in UI (#7519) Update tar version to avoid CVE-2026-33056 (#8073) refactor: consolidate duplicated dependencies into workspace (#8041) tui: set up for publishing via github actions (#8020) feat: feature-gate local inference dependencies (#7976) feat: ability to manage sub recipes in desktop ui (#6360) Tweak the release process: no more merge to main (#7994) fix: gemini models via databricks (#8042) feat(apps): Pass toolInfo to MCP Apps via hostContext (#7506) fix: remove configured marker when deleting oauth provider configuration (#7887) docs: add vmware-aiops MCP extension documentation (#8055) Show setup instructions for ACP providers in settings modal (#8065) deps: replace sigstore-verification with sigstore-verify to kill vulns (#8064) feat(acp): add session/set_config and stabilize list, delete and close (#7984) docs: Correct `gosoe` typo to `goose` (#8062) fix: use default provider and model when provider in session no longer exists (#8035) feat: add GOOSE_SHELL env var to configure preferred shell (#7909) fix(desktop): fullscreen header bar + always-visible close controls (#8033) ...
Summary
GOOSE_SHELLenvironment variable to let users override the default shell used for command execution-cfor POSIX shells,-Commandfor PowerShell,/cfor cmd) based on executable nameget_shell_path_dirs) also respectsGOOSE_SHELLCloses #7837
Motivation
Two key pain points addressed:
$SHELLisdash/ashget bash-specific commands from the model that failcmd.exeis extremely limited; Cygwin/MSYS2 users want to usebash.exedirectlyUsage
Without
GOOSE_SHELLset, behavior is unchanged (reads$SHELLon Unix, auto-detects PowerShell/cmd on Windows).Test plan
cargo buildsucceedscargo test -p goose-mcp— all 182 tests passcargo test -p goose-server— all 11 tests passGOOSE_SHELL=/bin/zshand verify shell commands execute with zshGOOSE_SHELLand verify existing default behavior unchanged🤖 Generated with Claude Code