cc-safe-setup 28.7.0 → 28.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/examples/auto-approve-compound-git.sh +53 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -87,7 +87,7 @@ Each hook exists because a real incident happened without it.
|
|
|
87
87
|
| `--scan [--apply]` | Tech stack detection |
|
|
88
88
|
| `--export / --import` | Team config sharing |
|
|
89
89
|
| `--verify` | Test each hook |
|
|
90
|
-
| `--install-example <name>` | Install from
|
|
90
|
+
| `--install-example <name>` | Install from 336 examples |
|
|
91
91
|
| `--examples [filter]` | Browse examples by keyword |
|
|
92
92
|
| `--full` | All-in-one setup |
|
|
93
93
|
| `--status` | Check installed hooks |
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# auto-approve-compound-git.sh — PermissionRequest hook
|
|
3
|
+
# Trigger: PermissionRequest
|
|
4
|
+
# Matcher: Bash
|
|
5
|
+
#
|
|
6
|
+
# Auto-approves compound git commands that the built-in permission
|
|
7
|
+
# system fails to match. The wildcard pattern Bash(git:*) only matches
|
|
8
|
+
# simple commands like "git status" but not "cd src && git log" or
|
|
9
|
+
# "git add file.txt && git commit -m 'fix'".
|
|
10
|
+
#
|
|
11
|
+
# This hook runs AFTER the built-in permission check fails (because
|
|
12
|
+
# compound commands don't match Bash(git:*)), and approves if ALL
|
|
13
|
+
# individual commands in the chain are safe git operations.
|
|
14
|
+
#
|
|
15
|
+
# See: https://github.com/anthropics/claude-code/issues/30519
|
|
16
|
+
# See: https://github.com/anthropics/claude-code/issues/16561
|
|
17
|
+
|
|
18
|
+
INPUT=$(cat)
|
|
19
|
+
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
20
|
+
[ -z "$COMMAND" ] && exit 0
|
|
21
|
+
|
|
22
|
+
# Split on && ; || and check each part
|
|
23
|
+
# Only approve if EVERY component is a safe git command or cd
|
|
24
|
+
SAFE=true
|
|
25
|
+
while IFS= read -r part; do
|
|
26
|
+
# Trim whitespace
|
|
27
|
+
part=$(echo "$part" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
|
|
28
|
+
[ -z "$part" ] && continue
|
|
29
|
+
|
|
30
|
+
# Allow: cd, git (read ops), git add, git commit, git stash, git branch
|
|
31
|
+
if echo "$part" | grep -qE '^(cd |git (status|log|diff|show|branch|tag|stash|add|commit|fetch|pull|checkout|switch|restore|rebase|merge|cherry-pick|remote|config) )'; then
|
|
32
|
+
continue
|
|
33
|
+
fi
|
|
34
|
+
# Allow simple git commands without args
|
|
35
|
+
if echo "$part" | grep -qE '^git (status|log|diff|show|branch|tag|stash|fetch|pull)$'; then
|
|
36
|
+
continue
|
|
37
|
+
fi
|
|
38
|
+
# Any non-git command = not safe
|
|
39
|
+
SAFE=false
|
|
40
|
+
break
|
|
41
|
+
done < <(echo "$COMMAND" | tr '&' '\n' | tr ';' '\n' | tr '|' '\n')
|
|
42
|
+
|
|
43
|
+
if [ "$SAFE" = "true" ]; then
|
|
44
|
+
jq -n '{
|
|
45
|
+
hookSpecificOutput: {
|
|
46
|
+
hookEventName: "PermissionRequest",
|
|
47
|
+
permissionDecision: "allow",
|
|
48
|
+
permissionDecisionReason: "Allowed: compound git command (all parts are safe git ops)"
|
|
49
|
+
}
|
|
50
|
+
}'
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
exit 0
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cc-safe-setup",
|
|
3
|
-
"version": "28.
|
|
4
|
-
"description": "One command to make Claude Code safe.
|
|
3
|
+
"version": "28.8.0",
|
|
4
|
+
"description": "One command to make Claude Code safe. 344 hooks (8 built-in + 336 examples). 49 CLI commands. 1018 tests. 5 languages.",
|
|
5
5
|
"main": "index.mjs",
|
|
6
6
|
"bin": {
|
|
7
7
|
"cc-safe-setup": "index.mjs"
|