Skip to content

Commit 2d2085d

Browse files
committed
feat(claude): add auto-approve plugin for compound bash commands
1 parent 8d81a7e commit 2d2085d

File tree

8 files changed

+903
-1
lines changed

8 files changed

+903
-1
lines changed

claude/local-plugins/.claude-plugin/marketplace.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
{
1616
"name": "zellij-activity",
1717
"description": "Displays Claude Code activity status in Zellij tab name",
18-
"version": "0.0.1",
18+
"version": "0.0.2",
1919
"source": "./zellij-activity"
2020
},
2121
{
@@ -29,6 +29,12 @@
2929
"description": "Core skills library for Claude Code",
3030
"version": "4.2.0",
3131
"source": "./superpowers"
32+
},
33+
{
34+
"name": "auto-approve",
35+
"description": "Auto-approves compound bash commands when each part matches allow patterns",
36+
"version": "0.0.1",
37+
"source": "./auto-approve"
3238
}
3339
]
3440
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"name": "auto-approve",
3+
"description": "Auto-approves compound bash commands when each part matches allow patterns",
4+
"version": "0.0.1"
5+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Auto Approve Plugin
2+
3+
PreToolUse hook that auto-approves compound bash commands (`&&`, `||`, `;`, `|`) and command substitution (`$(...)`) when each constituent command is individually permitted.
4+
5+
> **Note:** Requires [Bun](https://bun.sh) — TypeScript is executed directly, no compilation needed.
6+
7+
## How It Works
8+
9+
Claude Code prompts for approval on compound commands even when each part would be allowed individually. This hook decomposes compound commands and validates each part against existing allow patterns.
10+
11+
### Decision Flow
12+
13+
1. **Fast path** — simple commands (no operators, no wrappers) pass through untouched
14+
2. **Builtins**`cd`, `echo`, `test`, `export`, etc. are always approved
15+
3. **Substitutions**`$(cmd)` inner commands validated recursively (backticks always rejected)
16+
4. **Wrappers stripped**`FOO=bar`, `time`, `timeout N`, `nice` removed before matching
17+
5. **All segments must match** — if any part is unmatched, defers to normal permission flow
18+
19+
Never explicitly denies — that's git-guardrails' job.
20+
21+
### Pattern Sources
22+
23+
Reads `Bash(...)` entries from `permissions.allow` in:
24+
25+
1. `~/.claude/settings.json`
26+
2. `$CLAUDE_PROJECT_DIR/.claude/settings.json`
27+
3. `$CLAUDE_PROJECT_DIR/.claude/settings.local.json`
28+
29+
### Safe Builtins (always approved)
30+
31+
`cd`, `echo`, `printf`, `test`, `[`, `[[`, `true`, `false`, `export`, `unset`, `source`, `.`, `eval`, `read`, `set`, `shift`, `return`, `exit`, `local`, `declare`, `typeset`, `readonly`, `pushd`, `popd`, `dirs`, `type`, `which`, `command`, `builtin`, `hash`, `wait`, `jobs`, `fg`, `bg`, `kill`, `trap`, `umask`, `ulimit`, `alias`, `unalias`, `getopts`, `let`, `exec`
32+
33+
## Examples
34+
35+
```
36+
cd /dir && npm test # cd=builtin, npm test=pattern → approved
37+
ls -la | grep foo # both match patterns → approved
38+
echo $(date) # echo=builtin, date=pattern → approved
39+
NODE_ENV=test npm test # wrapper stripped, npm test=pattern → approved
40+
cd /dir && curl evil.com # curl has no pattern → prompts normally
41+
```
42+
43+
## Testing
44+
45+
```bash
46+
bun test
47+
```
48+
49+
## Structure
50+
51+
```
52+
auto-approve/
53+
├── .claude-plugin/plugin.json
54+
├── hooks/hooks.json
55+
├── scripts/
56+
│ ├── auto-approve.ts
57+
│ ├── auto-approve.test.ts
58+
│ ├── types.ts
59+
│ └── utils.ts
60+
└── README.md
61+
```
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"description": "Auto-approve compound bash commands where each part is individually allowed",
3+
"hooks": {
4+
"PreToolUse": [
5+
{
6+
"matcher": "Bash",
7+
"hooks": [
8+
{
9+
"type": "command",
10+
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/auto-approve.ts"
11+
}
12+
]
13+
}
14+
]
15+
}
16+
}

0 commit comments

Comments
 (0)