[PR #9724] feat(opencode): add configurable shell resolution with plugin support #13212

Open
opened 2026-02-16 18:18:04 -05:00 by yindo · 0 comments
Owner

Original Pull Request: https://github.com/anomalyco/opencode/pull/9724

State: open
Merged: No


Summary

Adds a first-class way to control which shell OpenCode uses when executing commands. Users (and plugin authors) can now override shell resolution explicitly instead of relying on $SHELL and platform defaults.

Fixes #4702

Problem

Today, the bash tool’s shell selection is implicit: OpenCode primarily relies on $SHELL and then falls back to OS defaults. That’s fine for simple local setups, but it breaks down whenever “my login shell” is not the same as “the shell OpenCode should execute commands with.” $SHELL is global, can point at non-POSIX shells, and is often misleading in containerized/remote/dev environments (#8396), forcing users into brittle workarounds (wrapper scripts, aliases, or forks) just to control command execution.

This shows up in several common scenarios:

  • Sandboxed execution / safer “allow” mode: Teams want to route commands through a controlled entrypoint (e.g., a wrapper that runs docker run with a read-only filesystem) so they can set "bash": "allow" without approving every command while still reducing risk. #4702
  • Non-POSIX login shells: Developers using Fish/Nushell as their default shell still need OpenCode to run Bash/Zsh for agent-generated scripts and tooling compatibility. #8716
  • Per-project consistency: Repos may require a specific shell (e.g., /bin/bash for CI parity or /bin/zsh for team conventions) independent of the user’s interactive environment.
  • Remote & ephemeral environments: In nix-shell, devcontainers, SSH sessions, or remote IDEs, $SHELL can reflect the host/login context rather than the environment where commands should run leading to surprising behavior and “works on my machine” inconsistencies.
  • Enterprise policy & compliance: Orgs often need to standardize execution through an approved shell entrypoint (auditing, environment bootstrapping, restricted PATH), which must be configurable without asking every developer to change their global shell.

Solution

Shell resolution is now explicit and extensible, while preserving existing behavior by default. OpenCode resolves the shell using the following priority order:

  1. Config override set "shell": "/bin/zsh" (or a wrapper) in opencode.json
  2. Plugin hook shell.resolve can dynamically choose a shell per workspace/environment
  3. Environment $SHELL (existing behavior)
  4. Fallback system default (existing behavior)

This keeps backward compatibility for current users, but unlocks predictable, per-project and policy-driven shell behavior for advanced setups.

**Original Pull Request:** https://github.com/anomalyco/opencode/pull/9724 **State:** open **Merged:** No --- ## Summary Adds a first-class way to control which shell OpenCode uses when executing commands. Users (and plugin authors) can now override shell resolution explicitly instead of relying on `$SHELL` and platform defaults. Fixes #4702 ### Problem Today, the bash tool’s shell selection is implicit: OpenCode primarily relies on `$SHELL` and then falls back to OS defaults. That’s fine for simple local setups, but it breaks down whenever *“my login shell”* is not the same as *“the shell OpenCode should execute commands with.”* `$SHELL` is global, can point at non-POSIX shells, and is often misleading in containerized/remote/dev environments (#8396), forcing users into brittle workarounds (wrapper scripts, aliases, or forks) just to control command execution. This shows up in several common scenarios: - **Sandboxed execution / safer “allow” mode:** Teams want to route commands through a controlled entrypoint (e.g., a wrapper that runs `docker run` with a read-only filesystem) so they can set `"bash": "allow"` without approving every command while still reducing risk. #4702 - **Non-POSIX login shells:** Developers using Fish/Nushell as their default shell still need OpenCode to run Bash/Zsh for agent-generated scripts and tooling compatibility. #8716 - **Per-project consistency:** Repos may require a specific shell (e.g., `/bin/bash` for CI parity or `/bin/zsh` for team conventions) independent of the user’s interactive environment. - **Remote & ephemeral environments:** In nix-shell, devcontainers, SSH sessions, or remote IDEs, `$SHELL` can reflect the host/login context rather than the environment where commands should run leading to surprising behavior and “works on my machine” inconsistencies. - **Enterprise policy & compliance:** Orgs often need to standardize execution through an approved shell entrypoint (auditing, environment bootstrapping, restricted PATH), which must be configurable without asking every developer to change their global shell. ### Solution Shell resolution is now explicit and extensible, while preserving existing behavior by default. OpenCode resolves the shell using the following priority order: 1. **Config override** set `"shell": "/bin/zsh"` (or a wrapper) in `opencode.json` 2. **Plugin hook** `shell.resolve` can dynamically choose a shell per workspace/environment 3. **Environment** `$SHELL` (existing behavior) 4. **Fallback** system default (existing behavior) This keeps backward compatibility for current users, but unlocks predictable, per-project and policy-driven shell behavior for advanced setups.
yindo added the pull-request label 2026-02-16 18:18:04 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#13212