← Back to PRs

#11300: feat(exec): make shell configurable via tools.exec.shell

by imjszhang open 2026-02-07 17:30 View on GitHub →
cli agents stale
## Summary - Adds `tools.exec.shell` and `tools.exec.shellArgs` configuration options to allow users to override the default shell used by the exec tool. - On Windows, the exec tool defaults to PowerShell, which is incompatible with many common Unix-style commands that AI agents generate. This change lets users configure Git Bash (or any other shell) as the exec shell. - When `shellArgs` is omitted, arguments are auto-detected based on the shell binary name (e.g. bash -> `["-c"]`, powershell -> `["-NoProfile", "-NonInteractive", "-Command"]`). ## Motivation Windows users frequently encounter command failures because the exec tool hardcodes PowerShell. Common issues include: - `rm -rf`, `grep`, `cat`, `export` and other Unix commands failing in PowerShell - AI agents generating bash-style commands that are incompatible with PowerShell syntax This change follows the existing pattern of other `tools.exec.*` config keys (like `pathPrepend`, `host`, `safeBins`) to keep the implementation consistent. ## Changes | File | Change | |------|--------| | `src/config/types.tools.ts` | Add `shell?` and `shellArgs?` to `ExecToolConfig` | | `src/config/zod-schema.agent-runtime.ts` | Add zod validation for both global and per-agent exec schemas | | `src/config/schema.ts` | Register config key labels and descriptions | | `src/agents/shell-utils.ts` | `getShellConfig()` accepts optional overrides, add `detectShellArgs()` | | `src/agents/bash-tools.exec.ts` | Thread shell config through `ExecToolDefaults` -> `runExecProcess` -> `getShellConfig` | | `src/agents/pi-tools.ts` | Pass shell/shellArgs in `resolveExecConfig()` and `createExecTool()` | | `src/cli/nodes-cli/register.invoke.ts` | Pass shell/shellArgs in `resolveExecDefaults()` | | `src/agents/shell-utils.test.ts` | Add 6 test cases covering override scenarios | ## Usage ```bash openclaw config set tools.exec.shell "d:\\Program Files\\Git\\bin\\bash.exe" ``` Or in `~/.openclaw/openclaw.json`: ```json { "tools": { "exec": { "shell": "d:\\Program Files\\Git\\bin\\bash.exe" } } } ``` ## Test plan - [x] `pnpm tsgo` - TypeScript type check passes - [x] `pnpm vitest run src/agents/shell-utils.test.ts` - All 7 tests pass (6 new) - [x] `pnpm build` - Full build succeeds - [x] Manual: configure `tools.exec.shell` to Git Bash on Windows and verify exec commands use bash - [x] Manual: verify default behavior (no config) is unchanged on both Windows and Unix <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This PR adds `tools.exec.shell` and `tools.exec.shellArgs` to the config model + zod schemas, wires those defaults through CLI/agent tool creation into the exec tool’s process spawning logic, and adds tests around shell argument auto-detection. The new behavior allows Windows users (and others) to override the shell binary and/or arguments used for `exec`, with `shellArgs` auto-detected when omitted based on the configured shell binary name. <h3>Confidence Score: 4/5</h3> - Mostly safe to merge once the shellArgs-only override behavior is fixed. - Changes are localized and covered by unit tests, but `shellArgs` is currently ignored unless `shell` is also set, which contradicts the intended config behavior and can surprise users. - src/agents/shell-utils.ts <!-- greptile_other_comments_section --> <sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub> <!-- /greptile_comment -->

Most Similar PRs