cc-safe-setup 1.5.1 → 1.5.3
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 +21 -3
- package/examples/auto-approve-build.sh +43 -0
- package/examples/edit-guard.sh +48 -0
- package/index.mjs +4 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -82,6 +82,8 @@ Safe to run multiple times. Existing settings are preserved. A backup is created
|
|
|
82
82
|
|
|
83
83
|
**Note:** Hooks are skipped when Claude Code runs with `--bare` or `--dangerously-skip-permissions`. These modes bypass all safety hooks by design.
|
|
84
84
|
|
|
85
|
+
**Known limitation:** In headless mode (`-p` / `--print`), hook exit code 2 may not block tool execution ([#36071](https://github.com/anthropics/claude-code/issues/36071)). For CI pipelines, use interactive mode with hooks rather than `-p` mode.
|
|
86
|
+
|
|
85
87
|
## Before / After
|
|
86
88
|
|
|
87
89
|
Run `npx cc-health-check` to see the difference:
|
|
@@ -116,7 +118,7 @@ npx cc-health-check
|
|
|
116
118
|
|
|
117
119
|
## Full Kit
|
|
118
120
|
|
|
119
|
-
cc-safe-setup gives you
|
|
121
|
+
cc-safe-setup gives you 8 essential hooks. For the complete autonomous operation toolkit:
|
|
120
122
|
|
|
121
123
|
**[Claude Code Ops Kit](https://yurukusa.github.io/cc-ops-kit-landing/?utm_source=github&utm_medium=readme&utm_campaign=safe-setup)** — 16 hooks + 5 templates + 3 exclusive tools + install.sh. Production-ready in 15 minutes.
|
|
122
124
|
|
|
@@ -124,20 +126,36 @@ Or start with the free hooks: [claude-code-hooks](https://github.com/yurukusa/cl
|
|
|
124
126
|
|
|
125
127
|
## Examples
|
|
126
128
|
|
|
127
|
-
Need custom hooks beyond the
|
|
129
|
+
Need custom hooks beyond the 8 built-in ones? See [`examples/`](examples/) for ready-to-use recipes:
|
|
128
130
|
|
|
129
131
|
- **auto-approve-git-read.sh** — Auto-approve `git status`, `git log`, even with `-C` flags
|
|
130
132
|
- **auto-approve-ssh.sh** — Auto-approve safe SSH commands (`uptime`, `whoami`, etc.)
|
|
131
133
|
- **enforce-tests.sh** — Warn when source files change without corresponding test files
|
|
132
134
|
- **notify-waiting.sh** — Desktop notification when Claude Code waits for input (macOS/Linux/WSL2)
|
|
135
|
+
- **edit-guard.sh** — Block Edit/Write to protected files (defense-in-depth for [#37210](https://github.com/anthropics/claude-code/issues/37210))
|
|
136
|
+
- **auto-approve-build.sh** — Auto-approve npm/yarn/cargo/go/python build, test, and lint commands
|
|
133
137
|
|
|
134
138
|
## Learn More
|
|
135
139
|
|
|
136
140
|
- [Official Hooks Reference](https://code.claude.com/docs/en/hooks) — Claude Code hooks documentation
|
|
137
|
-
- [Hooks Cookbook](https://github.com/yurukusa/claude-code-hooks/blob/main/COOKBOOK.md) —
|
|
141
|
+
- [Hooks Cookbook](https://github.com/yurukusa/claude-code-hooks/blob/main/COOKBOOK.md) — 9 ready-to-use recipes from real GitHub Issues
|
|
138
142
|
- [Japanese guide (Qiita)](https://qiita.com/yurukusa/items/a9714b33f5d974e8f1e8) — この記事の日本語解説
|
|
139
143
|
- [The incident that inspired this tool](https://github.com/anthropics/claude-code/issues/36339) — NTFS junction rm -rf
|
|
140
144
|
|
|
145
|
+
## FAQ
|
|
146
|
+
|
|
147
|
+
**Q: I installed hooks but Claude says "Unknown skill: claude-code-hooks:setup"**
|
|
148
|
+
|
|
149
|
+
cc-safe-setup installs **hooks**, not skills or plugins. Hooks run automatically in the background — you don't invoke them manually. After install + restart, try running a dangerous command; the hook will block it silently.
|
|
150
|
+
|
|
151
|
+
**Q: `cc-health-check` says to run `cc-safe-setup` but I already did**
|
|
152
|
+
|
|
153
|
+
cc-safe-setup covers Safety Guards (75-100%) and Monitoring (context-monitor). The other health check dimensions (Code Quality, Recovery, Coordination) require additional CLAUDE.md configuration or manual hook installation from [claude-code-hooks](https://github.com/yurukusa/claude-code-hooks).
|
|
154
|
+
|
|
155
|
+
**Q: Will hooks slow down Claude Code?**
|
|
156
|
+
|
|
157
|
+
No. Each hook runs in ~10ms. They only fire on specific events (before tool use, after edits, on stop). No polling, no background processes.
|
|
158
|
+
|
|
141
159
|
## Contributing
|
|
142
160
|
|
|
143
161
|
Found a false positive? Open an [issue](https://github.com/yurukusa/cc-safe-setup/issues/new?template=false_positive.md). Want a new hook? Open a [feature request](https://github.com/yurukusa/cc-safe-setup/issues/new?template=bug_report.md).
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# auto-approve-build.sh — Auto-approve build and test commands
|
|
3
|
+
#
|
|
4
|
+
# Solves: Permission prompts for npm/yarn/pnpm build/test/lint commands
|
|
5
|
+
# that slow down autonomous workflows
|
|
6
|
+
#
|
|
7
|
+
# Usage: Add to settings.json as a PreToolUse hook
|
|
8
|
+
#
|
|
9
|
+
# {
|
|
10
|
+
# "hooks": {
|
|
11
|
+
# "PreToolUse": [{
|
|
12
|
+
# "matcher": "Bash",
|
|
13
|
+
# "hooks": [{ "type": "command", "command": "~/.claude/hooks/auto-approve-build.sh" }]
|
|
14
|
+
# }]
|
|
15
|
+
# }
|
|
16
|
+
# }
|
|
17
|
+
|
|
18
|
+
INPUT=$(cat)
|
|
19
|
+
TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
|
|
20
|
+
[ "$TOOL" != "Bash" ] && exit 0
|
|
21
|
+
|
|
22
|
+
CMD=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
23
|
+
[ -z "$CMD" ] && exit 0
|
|
24
|
+
|
|
25
|
+
# Auto-approve safe build/test/lint commands
|
|
26
|
+
if echo "$CMD" | grep -qE '^\s*(npm|yarn|pnpm|bun|npx)\s+(run\s+)?(build|test|lint|check|typecheck|format|dev|start|ci)'; then
|
|
27
|
+
echo '{"decision":"approve"}'
|
|
28
|
+
exit 0
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
# Auto-approve cargo/go/make build commands
|
|
32
|
+
if echo "$CMD" | grep -qE '^\s*(cargo\s+(build|test|check|clippy|fmt)|go\s+(build|test|vet|fmt)|make\s+(build|test|check|lint))'; then
|
|
33
|
+
echo '{"decision":"approve"}'
|
|
34
|
+
exit 0
|
|
35
|
+
fi
|
|
36
|
+
|
|
37
|
+
# Auto-approve python test/lint
|
|
38
|
+
if echo "$CMD" | grep -qE '^\s*(python|python3)\s+(-m\s+)?(pytest|unittest|mypy|ruff|black|isort|flake8)'; then
|
|
39
|
+
echo '{"decision":"approve"}'
|
|
40
|
+
exit 0
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
exit 0
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# edit-guard.sh — Block Edit/Write to protected files
|
|
3
|
+
#
|
|
4
|
+
# Solves: PreToolUse deny being ignored for Edit/Write tools (#37210)
|
|
5
|
+
# Uses chmod as defense-in-depth — makes file read-only before deny
|
|
6
|
+
#
|
|
7
|
+
# GitHub Issue: #37210
|
|
8
|
+
#
|
|
9
|
+
# Usage: Add to settings.json as a PreToolUse hook
|
|
10
|
+
#
|
|
11
|
+
# {
|
|
12
|
+
# "hooks": {
|
|
13
|
+
# "PreToolUse": [{
|
|
14
|
+
# "matcher": "",
|
|
15
|
+
# "hooks": [{ "type": "command", "command": "~/.claude/hooks/edit-guard.sh" }]
|
|
16
|
+
# }]
|
|
17
|
+
# }
|
|
18
|
+
# }
|
|
19
|
+
|
|
20
|
+
INPUT=$(cat)
|
|
21
|
+
TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
|
|
22
|
+
FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
|
|
23
|
+
|
|
24
|
+
# Only check Edit and Write tools
|
|
25
|
+
if [[ "$TOOL" != "Edit" && "$TOOL" != "Write" ]]; then
|
|
26
|
+
exit 0
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
# Define protected patterns (customize these)
|
|
30
|
+
PROTECTED_PATTERNS=(
|
|
31
|
+
"*.env*"
|
|
32
|
+
"*credentials*"
|
|
33
|
+
"*secrets*"
|
|
34
|
+
"*.pem"
|
|
35
|
+
"*.key"
|
|
36
|
+
"*/.claude/settings.json"
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
for pattern in "${PROTECTED_PATTERNS[@]}"; do
|
|
40
|
+
if [[ "$FILE" == $pattern ]]; then
|
|
41
|
+
# Defense-in-depth: make file read-only
|
|
42
|
+
chmod 444 "$FILE" 2>/dev/null
|
|
43
|
+
echo "BLOCKED: Edit/Write denied for protected file: $FILE" >&2
|
|
44
|
+
exit 2
|
|
45
|
+
fi
|
|
46
|
+
done
|
|
47
|
+
|
|
48
|
+
exit 0
|
package/index.mjs
CHANGED
|
@@ -203,6 +203,10 @@ async function verify() {
|
|
|
203
203
|
{ hook: 'secret-guard', input: '{"tool_input":{"command":"git add .env"}}', expect: 2, desc: 'blocks git add .env' },
|
|
204
204
|
{ hook: 'secret-guard', input: '{"tool_input":{"command":"git add src/app.js"}}', expect: 0, desc: 'allows git add safe files' },
|
|
205
205
|
{ hook: 'api-error-alert', input: '{"stop_reason":"user"}', expect: 0, desc: 'ignores normal stops' },
|
|
206
|
+
{ hook: 'destructive-guard', input: '{"tool_input":{"command":"cd /tmp && rm -rf /"}}', expect: 2, desc: 'blocks compound rm -rf' },
|
|
207
|
+
{ hook: 'branch-guard', input: '{"tool_input":{"command":"git push --force origin feature"}}', expect: 2, desc: 'blocks force-push' },
|
|
208
|
+
{ hook: 'destructive-guard', input: '{"tool_input":{"command":"git reset --hard HEAD~5"}}', expect: 2, desc: 'blocks git reset --hard' },
|
|
209
|
+
{ hook: 'destructive-guard', input: '{"tool_input":{"command":"sudo rm -rf /var"}}', expect: 2, desc: 'blocks sudo + destructive' },
|
|
206
210
|
];
|
|
207
211
|
|
|
208
212
|
let pass = 0, fail = 0;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cc-safe-setup",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.3",
|
|
4
4
|
"description": "One command to make Claude Code safe for autonomous operation. 8 hooks: destructive blocker, branch guard, force-push protection, secret leak prevention, syntax checks, and more.",
|
|
5
5
|
"main": "index.mjs",
|
|
6
6
|
"bin": {
|