Stop clicking "Allow" for every cat, ls, and git status. Use hooks to auto-approve safe commands while keeping dangerous operations gated.
667 hooks 9,200+ tests
Claude Code prompts for every tool call by default. For read-only commands like cat, ls, grep, and git status, this is unnecessary friction. But you don't want to use --dangerously-skip-permissions and lose ALL safety checks.
Hooks let you auto-approve the safe commands while keeping prompts for dangerous ones.
npx cc-safe-setup --install-example auto-approve-readonly
This installs a PreToolUse hook on Bash that auto-approves: cat, ls, grep, find, git status, git log, git diff, npm list, pip list, and 40+ more read-only commands.
| Hook | What it auto-approves | Install |
|---|---|---|
| auto-approve-readonly | cat, ls, grep, find, git read commands | --install-example auto-approve-readonly |
| auto-approve-readonly-tools | Read, Glob, Grep tools (PermissionRequest) | --install-example auto-approve-readonly-tools |
| auto-approve-build | npm run, make, cargo build | --install-example auto-approve-build |
| auto-approve-test | npm test, pytest, cargo test, go test | --install-example auto-approve-test |
| auto-approve-python | python, pip list, pip show | --install-example auto-approve-python |
| auto-approve-docker | docker ps, docker logs, docker inspect | --install-example auto-approve-docker |
| auto-approve-go | go build, go test, go vet | --install-example auto-approve-go |
| auto-approve-cargo | cargo build, cargo test, cargo clippy | --install-example auto-approve-cargo |
| auto-approve-git-read | git log, git blame, git show | --install-example auto-approve-git-read |
| auto-approve-compound-git | cd && git log, cd && git status (PermissionRequest) | --install-example auto-approve-compound-git |
| auto-approve-ssh | ssh-keygen -l, ssh-add -l | --install-example auto-approve-ssh |
Claude Code has built-in checks for protected directories (.claude/, .git/hooks/). PreToolUse hooks can't bypass these — they run before the built-in checks. Use PermissionRequest hooks instead:
{
"hooks": {
"PermissionRequest": [
{
"matcher": "",
"hooks": [{
"type": "command",
"command": "echo '{\"hookSpecificOutput\":{\"hookEventName\":\"PermissionRequest\",\"permissionDecision\":\"allow\",\"permissionDecisionReason\":\"auto-approved\"}}'"
}]
}
]
}
}
npx cc-safe-setup --install-example allow-git-hooks-dir
npx cc-safe-setup --install-example allow-claude-settings
Understanding why PermissionRequest exists:
| Step | Hook Type | Purpose |
|---|---|---|
| 1 | PreToolUse | Block dangerous actions (exit 2 = block) |
| 2 | Built-in checks | Protected directory prompts (not hookable) |
| 3 | PermissionRequest | Auto-approve prompts from step 2 |
Rule of thumb: PreToolUse = block dangerous. PermissionRequest = allow trusted.
Installs 8 safety hooks + project-specific recommendations. 655 example hooks available. 9,200+ tests.