Desktop app ignores `respondToBashCommands: false` (bundled 2.1.234); terminal CLI honors it
Summary
"respondToBashCommands": false in ~/.claude/settings.json is honored by the terminal CLI but ignored by the Claude Desktop app's bundled Claude Code build. In the desktop, every ! bash command still triggers a full model turn responding to the output.
There is no UI toggle for this in the desktop app, so there is currently no way to get the context-only behavior there.
Environment
- macOS 14.4 (darwin, arm64)
- Terminal CLI: 2.1.227 (Homebrew cask,
/opt/homebrew/bin/claude) - Desktop app: Claude.app, which runs its own bundled copy at
~/Library/Application Support/Claude/claude-code/2.1.234/claude.app/Contents/MacOS/claude — 2.1.234
- Setting present in user settings (
~/.claude/settings.json), unchanged for ~2 weeks:
{
"respondToBashCommands": false
}
- Not overridden anywhere else: absent from
~/.claude/settings.local.json, the project's.claude/settings.json, the project's.claude/settings.local.json,~/.claude.json, and there is no/Library/Application Support/ClaudeCode/managed-settings.json.
Repro
- Put
"respondToBashCommands": falsein~/.claude/settings.json. - In a terminal
claudesession, run!git status. → output is added to context, no model turn. Correct. - In the Claude Desktop app, open a Claude Code session in the same directory and run
!git status. → Claude produces a full response to the output.
Evidence from session transcripts
Same machine, same settings file, same project directory. Comparing the message immediately following a <bash-input> entry in ~/.claude/projects/<project>/*.jsonl:
| Date | version in transcript | Surface | Entry after <bash-input> |
|---|---|---|---|
| 2026-08-17 | 2.1.224 | terminal CLI | user — no assistant turn (correct) |
| 2026-08-19 | 2.1.221 | terminal CLI | user — no assistant turn (correct) |
| 2026-08-20 | 2.1.234 | desktop app | attachment, then assistant (thinking + tool_use) — incorrect |
Investigation notes
Some things I checked that may narrow it down:
- The desktop launches its bundled CLI with, among others:
--setting-sources=user,project,local --settings '{"fastMode":false}' --input-format stream-json --output-format stream-json --permission-prompt-tool stdio
So user is in the setting sources, and the --settings flag payload does not contain respondToBashCommands.
CLAUDE_CONFIG_DIRis not set in the desktop-spawned process environment, so it should be resolving the same~/.claude/settings.json.- The 2.1.234 bundle does contain the read:
processBashCommanddoes
let respond = getMergedSettings().respondToBashCommands ?? true and returns shouldQuery: respond && !interrupted && !backgroundTaskId && !aborted.
So the code path exists in the desktop build — it just isn't producing false.
- The desktop's Electron bundle (
app.asar) contains the settings schema entry forrespondToBashCommandsbut no UI control for it, and no independent!handling of its own (its only<bash-input>reference is a regex used for session-title extraction), so the bash-mode path really is the bundled CLI's. - A headless repro attempt using the same binary and flags did not work, because
!is not parsed as bash mode over--input-format stream-jsonwhen the message is a plain text user message — the model just sees the literal text. So whatever signals bash mode from the desktop host is the interesting part of this path, and is probably where the setting is getting lost.
Expected
With "respondToBashCommands": false, a ! command in the desktop app adds <bash-stdout>/<bash-stderr> to context without triggering a model response — matching the terminal CLI and the documented behavior from the 2.1.186 changelog entry.
Actual
The setting has no effect in the desktop app; every ! command costs a full turn.
Notes
- Related but distinct: #74095 (a shell mode that never touches context at all) and #80529 (an opt-in
!!variant). This issue is specifically that the existing documented opt-out is not applied on the desktop surface. - No fix for this appears in the changelog through 2.1.235.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗