Enhance Claude Code CLI with auto-approve hooks and modern shell support
npm install claude-code-plus


Enhancements for Claude Code CLI that fix common pain points and add quality-of-life improvements.
``bash`
npx claude-code-plus -y
Or run interactively to customize what gets installed:
`bash`
npx claude-code-plus
The problem: Claude Code's permission system uses prefix matching. If you allow Bash(ls:) and Bash(grep:), running ls | grep foo still prompts for permission because the full string doesn't match any single prefix.
The solution: A PreToolUse hook that parses piped commands using shfmt, checks each component individually against your allowed permissions, and auto-approves if all parts match.
> Related: anthropics/claude-code#13340
The problem: Claude Code ignores the $SHELL environment variable and always uses the system default shell (/bin/zsh on macOS). This means you lose access to your PATH, aliases, and shell-specific configuration.
The solution: A shell alias that wraps the claude command to set SHELL correctly, plus env.SHELL configuration in settings.json.
> Related: anthropics/claude-code#7490
Pre-configured auto-approval for common read-only commands:
- File & text: ls, cat, head, tail, grep, rg, fd, jq, yqgit status
- Git: , git diff, git log, git branch, git show (read-only)gh pr list
- GitHub CLI: , gh issue view, gh repo view (read-only)npm
- Package managers: , yarn, pnpm, pip, cargo, gem, brew (info commands)aws
- Cloud CLIs: , az, gcloud (list/describe/show)docker
- DevOps: , kubectl, helm, terraform (read-only)
See src/permissions.ts for the complete list.
| Platform | Status |
|----------|--------|
| macOS | Fully supported |
| Linux | Fully supported |
| Windows | Use WSL2 |
- Node.js 18+ (for npx)
The installer will automatically detect and offer to install missing dependencies:
- bash 4.4+ (macOS ships with 3.2)
- jq (JSON processor)
- shfmt (shell parser)
Manual installation
macOS:
`bash`
brew install bash jq shfmt
Linux (Debian/Ubuntu):
`bash`
apt install bash jq shfmt
Linux (Fedora/RHEL):
`bash`
dnf install bash jq shfmt
Linux (Arch):
`bash`
pacman -S bash jq shfmt
`bash`
npx claude-code-plus
Choose between:
1. Recommended - Installs everything with sensible defaults
2. Custom - Pick which features to install
`bash`
npx claude-code-plus -y
In Custom mode, you can specify a different shell:
- A shell name (e.g., zsh) - resolved via which/opt/homebrew/bin/zsh
- A full path (e.g., )
> Note: Claude Code currently works reliably with bash and zsh only. Other shells may have limited compatibility.
| File | Purpose |
|------|---------|
| ~/.claude/settings.json | Shell config, hook config, and permissions |~/.claude/hooks/auto-approve-allowed-commands.sh
| | Hook for piped command auto-approval |.bashrc
| Shell configs (, .zshrc, etc.) | Shell alias (workaround for shell bug) |
The installer automatically detects if chezmoi manages your ~/.claude directory:
- Writes to chezmoi's source directory
- Uses executable_ prefix for hook fileschezmoi apply
- Prompts to run at the end
No configuration needed.
1. Claude Code invokes a Bash command
2. The PreToolUse hook intercepts it
3. shfmt parses the command into components
4. Each component is checked against allowed permissions
5. If ALL match, the command is auto-approved
6. Otherwise, normal permission prompting applies
- Pipes: cmd1 | cmd2 | cmd3cmd1 && cmd2 || cmd3
- And/Or: cmd1; cmd2
- Semicolons: (cmd1; cmd2) | cmd3
- Subshells: echo $(cmd1 | cmd2)
- Command substitution: bash -c
- / sh -c: recursively expanded
- Loops: extracts inner commands
The following are not included in default permissions because they can execute arbitrary code:
- xargs - runs commands from inputpython -c
- , node -e, ruby -e - inline code executioneval
- , source - execute arbitrary strings/filesfind -exec
- - runs commands on matched files
`bashRemove the hook
rm ~/.claude/hooks/auto-approve-allowed-commands.sh
Issues and PRs welcome!