Skip to content

Conversation

@JohnDeved
Copy link

@JohnDeved JohnDeved commented Jan 20, 2026

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. [FEATURE]: Add config to change shell for bash tool #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. Opencode Desktop error with nushell as default shell #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.

- Add 'shell' config option to opencode.json for explicit shell override
- Add 'shell.resolve' plugin hook for dynamic shell resolution
- Convert Shell.preferred() and Shell.acceptable() to async
- Update call sites in bash tool, pty, and prompt to await shell
- Add comprehensive tests for config, plugin, and fallback scenarios
- Regenerate SDK types to include new shell config property
Copilot AI review requested due to automatic review settings January 20, 2026 23:38
@github-actions
Copy link
Contributor

Thanks for your contribution!

This PR doesn't have a linked issue. All PRs must reference an existing issue.

Please:

  1. Open an issue describing the bug/feature (if one doesn't exist)
  2. Add Fixes #<number> or Closes #<number> to this PR description

See CONTRIBUTING.md for details.

@github-actions
Copy link
Contributor

The following comment was made by an LLM, it may be inaccurate:

No duplicate PRs found

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds configurable shell resolution with plugin support to OpenCode, allowing users to override shell detection through configuration or plugins instead of relying solely on environment variables.

Changes:

  • Added shell configuration field to allow explicit shell path override
  • Implemented plugin hook shell.resolve for dynamic shell resolution
  • Converted Shell.preferred() and Shell.acceptable() from synchronous to async functions
  • Updated all call sites to use await with the newly async shell functions

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
packages/opencode/src/config/config.ts Added optional shell field to config schema
packages/sdk/openapi.json Regenerated SDK with new shell config field
packages/sdk/js/src/v2/gen/types.gen.ts Regenerated TypeScript types with shell config
packages/plugin/src/index.ts Added shell.resolve hook for plugin-based shell resolution
packages/opencode/src/shell/shell.ts Converted to async, added config/plugin resolution with priority chain
packages/opencode/src/tool/bash.ts Added await to Shell.acceptable() call
packages/opencode/src/pty/index.ts Added await to Shell.preferred() call
packages/opencode/src/session/prompt.ts Added await to Shell.preferred() call
packages/opencode/test/shell/shell.test.ts Added 4 tests for config, plugin, and fallback behavior

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Remove unused imports (Config, path)
- Add return statement to mock function
- Add test for Shell.acceptable() with plugin
- Add test for Shell.acceptable() fallback on blacklisted shell
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Improve shell config description with priority info and examples
- Add JSDoc documentation for shell.resolve plugin hook
- Add test: config takes priority over plugin
- Add test: config can override blacklist for Shell.acceptable
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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.

[FEATURE]: Add config to change shell for bash tool

1 participant