Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 18 additions & 6 deletions crates/goose/src/agents/platform_extensions/developer/shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,13 @@ fn unix_shell_command_args(command_line: &str) -> [&str; 2] {
["-c", command_line]
}

/// Resolve the preferred Unix shell for command execution, respecting GOOSE_SHELL.
///
/// Auto-detected shells are returned as basenames (e.g. `"bash"`) so that
/// `Command::new` resolves them on `PATH` at spawn time — this also keeps
/// Flatpak happy, where absolute paths from inside the sandbox don't match
/// the host filesystem. `GOOSE_SHELL` is passed through as-is.
/// Resolve the shell used to run Developer extension commands on Windows,
/// respecting `GOOSE_SHELL`.
///
/// Defaults to `cmd` when `GOOSE_SHELL` is unset. The invocation flags are
/// chosen automatically from the executable name in `build_shell_command`,
/// so callers only ever provide a bare executable path or name — see that
/// function for the flag mapping.
#[cfg(windows)]
fn windows_shell() -> String {
std::env::var("GOOSE_SHELL").unwrap_or_else(|_| "cmd".to_string())
Expand Down Expand Up @@ -624,6 +624,18 @@ async fn run_command(
})
}

/// Build the `Command` that executes a single command line via the configured shell.
///
/// The invocation flags are selected automatically from the shell executable
/// name, so setting `GOOSE_SHELL` to a bare executable is enough — users never
/// need to supply command-style flags themselves:
///
/// - PowerShell (`pwsh`, `powershell`) → `-NoProfile -NonInteractive -Command`
/// - cmd (`cmd`) → `/C`
/// - POSIX shells (bash, zsh, … via Cygwin/MSYS2) → `-c`
///
/// On Unix the default shell (`bash`, falling back to `sh`) is likewise invoked
/// as `<shell> -c <line>`.
fn build_shell_command(
command_line: &str,
working_dir: Option<&std::path::Path>,
Expand Down
9 changes: 9 additions & 0 deletions documentation/docs/guides/environment-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,15 @@ REM Windows: use a POSIX-like shell instead of cmd.exe
set GOOSE_SHELL=C:\cygwin64\bin\bash.exe
```

:::note
You only ever set `GOOSE_SHELL` to a shell executable path or name. goose injects the command-line flags automatically based on the shell, so there is no need to add them yourself:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Saying there is no need to add them yourself seems odd when we document how to do so multiple times in this doc seems a bit odd to me...

We should take a stance on whether we document how to use this env var or keep it internal to goose and remove all mentions in docs.

Thoughts?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fair point — the note is awkwardly worded. It's telling users not to do something the examples never suggested, so I'll rephrase it to state the behavior factually instead.

On the broader question: I'd keep GOOSE_SHELL documented. It's a real config knob (force zsh, Cygwin bash on Windows, custom pwsh), and hiding it would hurt discoverability. The flag-mapping detail is better served by the build_shell_command rustdoc this PR already adds, so I'll trim the user-facing note to a one-liner and avoid duplicating the verbose list in both places.


- **PowerShell** (`pwsh`, `powershell`) → `-NoProfile -NonInteractive -Command`

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 Qualify the PowerShell flag mapping as Windows-only

When a Unix user sets GOOSE_SHELL=pwsh, the #[cfg(not(windows))] branch does not perform this PowerShell-specific mapping: unix_shell_command_args supplies only -c, leaving profiles enabled and omitting -NonInteractive. This note therefore gives cross-platform PowerShell users an incorrect account of the launched process; scope these three mappings to Windows and clarify that all Unix overrides receive -c (and make the same correction in the new Rustdoc).

Useful? React with 👍 / 👎.

- **cmd** → `/C`
- **POSIX shells** (bash, zsh, … on Windows via Cygwin/MSYS2) → `-c`
- On Unix the default shell (`bash`, falling back to `sh`) is invoked as `<shell> -c`
:::

## Security and Privacy

These variables control security features, credential storage, and anonymous usage data collection.
Expand Down