Skip to content

feat: add GOOSE_SHELL env var to configure preferred shell#7909

Merged
DOsinga merged 1 commit intoblock:mainfrom
vincenzopalazzo:claude/musing-banach
Mar 20, 2026
Merged

feat: add GOOSE_SHELL env var to configure preferred shell#7909
DOsinga merged 1 commit intoblock:mainfrom
vincenzopalazzo:claude/musing-banach

Conversation

@vincenzopalazzo
Copy link
Copy Markdown
Contributor

Summary

  • Adds GOOSE_SHELL environment variable to let users override the default shell used for command execution
  • Auto-detects shell argument style (-c for POSIX shells, -Command for PowerShell, /c for cmd) based on executable name
  • Updates the model's system prompt to reflect which shell is active, so it generates compatible commands
  • PATH resolution (get_shell_path_dirs) also respects GOOSE_SHELL

Closes #7837

Motivation

Two key pain points addressed:

  • Unix: Users whose $SHELL is dash/ash get bash-specific commands from the model that fail
  • Windows: cmd.exe is extremely limited; Cygwin/MSYS2 users want to use bash.exe directly

Usage

# Use zsh instead of default shell
export GOOSE_SHELL=/bin/zsh

# Windows: use Cygwin bash
set GOOSE_SHELL=C:\cygwin64\bin\bash.exe

Without GOOSE_SHELL set, behavior is unchanged (reads $SHELL on Unix, auto-detects PowerShell/cmd on Windows).

Test plan

  • cargo build succeeds
  • cargo test -p goose-mcp — all 182 tests pass
  • cargo test -p goose-server — all 11 tests pass
  • Manual: set GOOSE_SHELL=/bin/zsh and verify shell commands execute with zsh
  • Manual: unset GOOSE_SHELL and verify existing default behavior unchanged

🤖 Generated with Claude Code

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment on lines +46 to +49
let shell_name = Path::new(shell)
.file_stem()
.and_then(|s| s.to_str())
.unwrap_or(shell);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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]>
Copy link
Copy Markdown
Collaborator

@DOsinga DOsinga left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@DOsinga DOsinga force-pushed the claude/musing-banach branch from 049262c to 9af6ef6 Compare March 20, 2026 15:03
Copy link
Copy Markdown
Collaborator

@DOsinga DOsinga left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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());
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

@DOsinga DOsinga added this pull request to the merge queue Mar 20, 2026
Merged via the queue into block:main with commit 1f7f234 Mar 20, 2026
21 checks passed
@vincenzopalazzo vincenzopalazzo deleted the claude/musing-banach branch March 20, 2026 20:58
elijahsgh pushed a commit to elijahsgh/goose that referenced this pull request Mar 21, 2026
Signed-off-by: Douwe Osinga <[email protected]>
Co-authored-by: Douwe Osinga <[email protected]>
Signed-off-by: esnyder <[email protected]>
elijahsgh pushed a commit to elijahsgh/goose that referenced this pull request Mar 21, 2026
Signed-off-by: Douwe Osinga <[email protected]>
Co-authored-by: Douwe Osinga <[email protected]>
Signed-off-by: esnyder <[email protected]>
elijahsgh pushed a commit to elijahsgh/goose that referenced this pull request Mar 21, 2026
Signed-off-by: Douwe Osinga <[email protected]>
Co-authored-by: Douwe Osinga <[email protected]>
Signed-off-by: esnyder <[email protected]>
wpfleger96 added a commit that referenced this pull request Mar 23, 2026
* 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)
  ...
wpfleger96 added a commit that referenced this pull request Mar 23, 2026
…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)
  ...
lifeizhou-ap added a commit that referenced this pull request Mar 24, 2026
* 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)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make it possible to select an alternative shell to use.

2 participants