Skip to content

Instantly share code, notes, and snippets.

@rayjohnson
Last active June 15, 2026 05:48
Show Gist options
  • Select an option

  • Save rayjohnson/7b9cef2cb69b76d80eb72ad5103ca58f to your computer and use it in GitHub Desktop.

Select an option

Save rayjohnson/7b9cef2cb69b76d80eb72ad5103ca58f to your computer and use it in GitHub Desktop.
Claude Code: Reduce approval prompts with a global CLAUDE.md

Claude Code: Reduce Approval Prompts with a Global CLAUDE.md

If you use Claude Code regularly you have probably seen a lot of this:

This command requires approval. Do you want to proceed?

Most of it is avoidable. Claude Code has native file editing tools (Edit, Write) that require zero Bash execution and zero approval prompts. But by default, Claude tends to reach for Python scripts or sed out of habit — even for simple file edits — which routes everything through Bash and triggers the approval flow.

This CLAUDE.md fixes that by giving Claude explicit guidance on the right tool for the job, and pre-approving a set of safe, well-scoped tools in settings.json so the ones that do use Bash do not interrupt your flow.

The core insight

Approach Goes through Bash? Approval prompt?
Claude Code Edit tool No Never
Claude Code Write tool No Never
sd, rg, jq, yq, yamllint (pre-approved) Yes No
sed, Python scripts Yes Yes, every time

The Edit tool works on the full file buffer — newlines are just characters, multiline matches just work. sed and sd process line by line by default, so multiline patterns silently fail and Claude falls back to Python. Telling Claude to Read the file first, then Edit, eliminates most of that entirely.

The shell scaffolding trap

Even with pre-approved tools, you can still get approval prompts if Claude wraps them in diagnostic shell expressions:

# This triggers an approval prompt — pattern match fails
fastmod 'old' 'new' src/ 2>&1
echo "exit: $?"

# This does not — matches the pre-approved pattern cleanly
fastmod 'old' 'new' src/

The reason: Claude Code's permission matching is prefix-based. The moment a command becomes a compound shell expression, it no longer matches the allow pattern for that tool.

The good news: Claude Code's Bash tool already returns stdout, stderr, and the exit code automatically as part of every tool result. Claude does not need to echo $? or redirect stderr — it already has all of that. The CLAUDE.md in this Gist tells Claude to run commands directly and trust the tool result rather than adding defensive scaffolding.

Setup

1. Install the preferred tools

brew install sd fastmod ripgrep jq yq yamllint

2. Add the global CLAUDE.md

mkdir -p ~/.claude
curl -o ~/.claude/CLAUDE.md \
  https://gist.githubusercontent.com/rayjohnson/7b9cef2cb69b76d80eb72ad5103ca58f/raw/CLAUDE.md

Or copy the contents of CLAUDE.md from this Gist manually.

3. Pre-approve safe tools in settings.json

Add the following to ~/.claude/settings.json (create it if it does not exist):

{
  "permissions": {
    "allow": [
      "Bash(sd *)",
      "Bash(rg *)",
      "Bash(jq *)",
      "Bash(yq *)",
      "Bash(yamllint *)",
      "Bash(shellcheck *)",
      "Bash(fastmod *)",
      "Bash(which *)",
      "Bash(brew install *)"
    ]
  }
}

If you already have a settings.json, just merge the allow entries in.

4. Verify

Start a new Claude Code session. Ask it to edit any file. It should reach for the Edit tool directly rather than writing a Python script or sed command.

Why these tools are safe to pre-approve

  • rg — read-only, cannot modify files
  • jq — read-only unless explicitly redirected
  • yamllint — read-only linter, cannot modify files
  • shellcheck — read-only linter, cannot modify files
  • sd — text replacement only, no execution mode, no -e flag escape hatch
  • fastmod — purpose-built codemod tool, no shell execution capability
  • which — read-only system lookup
  • brew install — will still prompt interactively in your terminal

Compare to sed -e which can be chained with shell execution, or python * which can run arbitrary code. Those stay unapproved for good reason.

Adapting for your own setup

The CLAUDE.md in this Gist is intentionally minimal — just the tool preference and approval-avoidance guidance. Add your own conventions on top: language preferences, commit message rules, project-specific patterns.

If you manage dotfiles with chezmoi, this fits naturally: chezmoi add ~/.claude/CLAUDE.md after any changes.

Global Claude Code Instructions

Preferred Tools & Auto-Install via Homebrew

Before falling back to Python scripts or sed for file manipulation, check for and prefer these tools. If a preferred tool is not installed, suggest installing it via Homebrew before proceeding with an inferior alternative.

File Editing

  • Edit tool — always first choice for single precise edits
  • fastmod — bulk pattern replacement across files
    • Check: which fastmod
    • Install: brew install fastmod
    • Run directly: fastmod 'pattern' 'replacement' dir/ — do NOT wrap in shell scaffolding (2>&1, echo exit codes, etc.) as this breaks pre-approval

Data Formats

  • jq — JSON querying and manipulation
    • Check: which jq
    • Install: brew install jq
  • yq — YAML querying and manipulation
    • Check: which yq
    • Install: brew install yq
  • yamllint — YAML validation and linting; always use instead of Python for YAML validation
    • Check: which yamllint
    • Install: brew install yamllint

Search

  • ripgrep (rg) — fast file content search, use before Edit to confirm exact match strings
    • Check: which rg
    • Install: brew install ripgrep

Text Replacement

  • sd — modern sed alternative with sane regex syntax, pre-approved in settings.json
    • Check: which sd
    • Install: brew install sd

Behavior

  • If a preferred tool is missing, say so and offer to install it via Homebrew before falling back to Python or sed
  • Never write a temporary Python script solely to edit or transform files when the above tools are available
  • Never use sed — use sd instead (it is pre-approved and will not prompt)

Bash Tool — Exit Codes and Output Capture

Claude Code's Bash tool automatically returns stdout, stderr, and the exit code as part of every tool result. Therefore:

  • Never append echo "exit: $?" — the exit code is already available
  • Never use 2>&1 to capture stderr — it is already captured separately
  • Never wrap commands in diagnostic scaffolding just to observe results
  • Run commands directly: fastmod 'a' 'b' src/ not fastmod 'a' 'b' src/ 2>&1 && echo $?
  • Wrapping pre-approved tools in shell expressions breaks pattern matching and causes unnecessary approval prompts

File Editing — Approval Avoidance

The Edit and Write tools require NO Bash execution and NO approval prompts. Bash-based tools ALL require approval unless pre-approved in settings.json.

Decision rule — follow strictly:

  1. Single location edit → use Edit tool directly. Never use Bash.
  2. Whole file rewrite → use Write tool. Never use Bash.
  3. Bulk edits across multiple files → use Edit tool in a loop across files. Still no Bash.
  4. Only use sd or fastmod when regex pattern matching is genuinely required AND the Edit tool cannot work. Both are pre-approved.

The key insight:

Even well-intentioned tools like sd and fastmod go through Bash and would normally trigger approval prompts — but sd, rg, jq, yq, yamllint, and fastmod are pre-approved in settings.json so they will not prompt. The Edit tool never prompts regardless. Always prefer Edit first.

When to use Edit tool vs sd:

  • Single line replacement → sd is fine and pre-approved
  • Multiline pattern (match spans a newline) → Edit tool only, sd will fail
  • Uncertain whether pattern is single or multiline → Edit tool to be safe

What Edit needs to work well:

  • Read the file first to get the exact string before attempting an Edit
  • Use rg to locate exact content if uncertain about surrounding text
  • Make multiple small Edit calls rather than one complex Bash command
  • Never construct a Bash command to handle uncertainty — Read first, then Edit
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment