allow configuring shell (#157)

This commit is contained in:
Ed Zynda 2025-05-15 16:53:47 +03:00 • committed by GitHub
parent 36faca4b4d
commit e8b4bb0edd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 61 additions and 3 deletions

View file

@ -96,6 +96,24 @@ You can configure OpenCode using environment variables:
| `AZURE_OPENAI_ENDPOINT` | For Azure OpenAI models | | `AZURE_OPENAI_ENDPOINT` | For Azure OpenAI models |
| `AZURE_OPENAI_API_KEY` | For Azure OpenAI models (optional when using Entra ID) | | `AZURE_OPENAI_API_KEY` | For Azure OpenAI models (optional when using Entra ID) |
| `AZURE_OPENAI_API_VERSION` | For Azure OpenAI models | | `AZURE_OPENAI_API_VERSION` | For Azure OpenAI models |
| `SHELL` | Default shell to use (if not specified in config) |
### Shell Configuration
OpenCode allows you to configure the shell used by the bash tool. By default, it uses the shell specified in the `SHELL` environment variable, or falls back to `/bin/bash` if not set.
You can override this in your configuration file:
```json
{
"shell": {
"path": "/bin/zsh",
"args": ["-l"]
}
}
```
This is useful if you want to use a different shell than your default system shell, or if you need to pass specific arguments to the shell.
### Configuration File Structure ### Configuration File Structure
@ -136,6 +154,10 @@ You can configure OpenCode using environment variables:
"maxTokens": 80 "maxTokens": 80
} }
}, },
"shell": {
"path": "/bin/bash",
"args": ["-l"]
},
"mcpServers": { "mcpServers": {
"example": { "example": {
"type": "stdio", "type": "stdio",

View file

@ -73,6 +73,12 @@ type TUIConfig struct {
Theme string `json:"theme,omitempty"` Theme string `json:"theme,omitempty"`
} }
// ShellConfig defines the configuration for the shell used by the bash tool.
type ShellConfig struct {
Path string `json:"path,omitempty"`
Args []string `json:"args,omitempty"`
}
// Config is the main configuration structure for the application. // Config is the main configuration structure for the application.
type Config struct { type Config struct {
Data Data `json:"data"` Data Data `json:"data"`
@ -85,6 +91,7 @@ type Config struct {
DebugLSP bool `json:"debugLSP,omitempty"` DebugLSP bool `json:"debugLSP,omitempty"`
ContextPaths []string `json:"contextPaths,omitempty"` ContextPaths []string `json:"contextPaths,omitempty"`
TUI TUIConfig `json:"tui"` TUI TUIConfig `json:"tui"`
Shell ShellConfig `json:"shell,omitempty"`
AutoCompact bool `json:"autoCompact,omitempty"` AutoCompact bool `json:"autoCompact,omitempty"`
} }
@ -217,6 +224,14 @@ func setDefaults(debug bool) {
viper.SetDefault("tui.theme", "opencode") viper.SetDefault("tui.theme", "opencode")
viper.SetDefault("autoCompact", true) viper.SetDefault("autoCompact", true)
// Set default shell from environment or fallback to /bin/bash
shellPath := os.Getenv("SHELL")
if shellPath == "" {
shellPath = "/bin/bash"
}
viper.SetDefault("shell.path", shellPath)
viper.SetDefault("shell.args", []string{"-l"})
if debug { if debug {
viper.SetDefault("debug", true) viper.SetDefault("debug", true)
viper.Set("log.level", "debug") viper.Set("log.level", "debug")

View file

@ -11,6 +11,8 @@ import (
"sync" "sync"
"syscall" "syscall"
"time" "time"
"github.com/opencode-ai/opencode/internal/config"
) )
type PersistentShell struct { type PersistentShell struct {
@ -57,12 +59,31 @@ func GetPersistentShell(workingDir string) *PersistentShell {
} }
func newPersistentShell(cwd string) *PersistentShell { func newPersistentShell(cwd string) *PersistentShell {
shellPath := os.Getenv("SHELL") // Get shell configuration from config
cfg := config.Get()
// Default to environment variable if config is not set or nil
var shellPath string
var shellArgs []string
if cfg != nil {
shellPath = cfg.Shell.Path
shellArgs = cfg.Shell.Args
}
if shellPath == "" {
shellPath = os.Getenv("SHELL")
if shellPath == "" { if shellPath == "" {
shellPath = "/bin/bash" shellPath = "/bin/bash"
} }
}
cmd := exec.Command(shellPath, "-l") // Default shell args
if len(shellArgs) == 0 {
shellArgs = []string{"-l"}
}
cmd := exec.Command(shellPath, shellArgs...)
cmd.Dir = cwd cmd.Dir = cwd
stdinPipe, err := cmd.StdinPipe() stdinPipe, err := cmd.StdinPipe()