cc-safe-setup 2.0.6 → 2.0.8
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 +2 -1
- package/examples/README.md +2 -1
- package/examples/block-database-wipe.sh +8 -1
- package/examples/verify-before-commit.sh +60 -0
- package/index.mjs +3 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -160,11 +160,12 @@ Or browse all available examples in [`examples/`](examples/):
|
|
|
160
160
|
- **timeout-guard.sh** — Warn before long-running commands (npm start, rails s, docker-compose up)
|
|
161
161
|
- **branch-name-check.sh** — Warn on non-conventional branch names (feature/, fix/, etc.)
|
|
162
162
|
- **todo-check.sh** — Warn when committing files with TODO/FIXME/HACK markers
|
|
163
|
+
- **path-traversal-guard.sh** — Block Edit/Write with `../../` path traversal and system directories
|
|
163
164
|
|
|
164
165
|
## Learn More
|
|
165
166
|
|
|
166
167
|
- [Official Hooks Reference](https://code.claude.com/docs/en/hooks) — Claude Code hooks documentation
|
|
167
|
-
- [Hooks Cookbook](https://github.com/yurukusa/claude-code-hooks/blob/main/COOKBOOK.md) —
|
|
168
|
+
- [Hooks Cookbook](https://github.com/yurukusa/claude-code-hooks/blob/main/COOKBOOK.md) — 18 ready-to-use recipes from real GitHub Issues
|
|
168
169
|
- [Japanese guide (Qiita)](https://qiita.com/yurukusa/items/a9714b33f5d974e8f1e8) — この記事の日本語解説
|
|
169
170
|
- [The incident that inspired this tool](https://github.com/anthropics/claude-code/issues/36339) — NTFS junction rm -rf
|
|
170
171
|
|
package/examples/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Example Hooks
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
25 hooks beyond the 8 built-in ones, organized by category.
|
|
4
4
|
|
|
5
5
|
## Quick Start
|
|
6
6
|
|
|
@@ -48,6 +48,7 @@ npx cc-safe-setup --examples
|
|
|
48
48
|
| **enforce-tests.sh** | Warn when source changes without tests | |
|
|
49
49
|
| **large-file-guard.sh** | Warn when Write creates files >500KB | |
|
|
50
50
|
| **todo-check.sh** | Warn when committing files with TODO/FIXME | |
|
|
51
|
+
| **verify-before-commit.sh** | Block commit unless tests passed recently | [#37818](https://github.com/anthropics/claude-code/issues/37818) |
|
|
51
52
|
|
|
52
53
|
## Recovery
|
|
53
54
|
|
|
@@ -6,10 +6,11 @@
|
|
|
6
6
|
# - Django: flush, sqlflush
|
|
7
7
|
# - Rails: db:drop, db:reset
|
|
8
8
|
# - Raw SQL: DROP DATABASE, TRUNCATE
|
|
9
|
+
# - Symfony/Doctrine: fixtures:load (without --append), schema:drop, database:drop
|
|
9
10
|
# - Prisma: migrate reset, db push --force-reset
|
|
10
11
|
# - PostgreSQL: dropdb
|
|
11
12
|
#
|
|
12
|
-
# Born from GitHub Issues #37405, #37439, #34729
|
|
13
|
+
# Born from GitHub Issues #37405, #37439, #34729, #37574
|
|
13
14
|
#
|
|
14
15
|
# Usage: Add to settings.json as a PreToolUse hook
|
|
15
16
|
#
|
|
@@ -61,6 +62,12 @@ if echo "$COMMAND" | grep -qiE 'DROP\s+(DATABASE|TABLE|SCHEMA)|TRUNCATE\s+TABLE|
|
|
|
61
62
|
exit 2
|
|
62
63
|
fi
|
|
63
64
|
|
|
65
|
+
# Symfony/Doctrine destructive commands
|
|
66
|
+
if echo "$COMMAND" | grep -qiE 'doctrine:(fixtures:load|schema:drop|database:drop)' && ! echo "$COMMAND" | grep -qE '\-\-append'; then
|
|
67
|
+
echo "BLOCKED: Destructive Doctrine command (use --append for fixtures:load)" >&2
|
|
68
|
+
exit 2
|
|
69
|
+
fi
|
|
70
|
+
|
|
64
71
|
# Prisma destructive commands
|
|
65
72
|
if echo "$COMMAND" | grep -qiE 'prisma\s+migrate\s+reset|prisma\s+db\s+push\s+--force-reset'; then
|
|
66
73
|
echo "BLOCKED: Destructive Prisma database command" >&2
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# verify-before-commit.sh — Block git commit unless tests passed recently
|
|
3
|
+
#
|
|
4
|
+
# Solves: Claude saying "fixed" and committing without actually
|
|
5
|
+
# verifying the fix works (#37818, #36970)
|
|
6
|
+
#
|
|
7
|
+
# How it works:
|
|
8
|
+
# 1. Your test runner creates a marker file on success
|
|
9
|
+
# 2. This hook checks for the marker before allowing commit
|
|
10
|
+
# 3. Marker expires after 10 minutes (stale test results don't count)
|
|
11
|
+
#
|
|
12
|
+
# Marker creation (add to your test script or PostToolUse hook):
|
|
13
|
+
# touch "/tmp/cc-tests-passed-$(pwd | md5sum | cut -c1-8)"
|
|
14
|
+
#
|
|
15
|
+
# Usage: Add to settings.json as a PreToolUse hook
|
|
16
|
+
#
|
|
17
|
+
# {
|
|
18
|
+
# "hooks": {
|
|
19
|
+
# "PreToolUse": [{
|
|
20
|
+
# "matcher": "Bash",
|
|
21
|
+
# "hooks": [{ "type": "command", "command": "~/.claude/hooks/verify-before-commit.sh" }]
|
|
22
|
+
# }]
|
|
23
|
+
# }
|
|
24
|
+
# }
|
|
25
|
+
|
|
26
|
+
INPUT=$(cat)
|
|
27
|
+
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
28
|
+
|
|
29
|
+
[[ -z "$COMMAND" ]] && exit 0
|
|
30
|
+
|
|
31
|
+
# Only check git commit commands
|
|
32
|
+
if ! echo "$COMMAND" | grep -qE '^\s*git\s+commit\b'; then
|
|
33
|
+
exit 0
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
# Must be in a git repo
|
|
37
|
+
git rev-parse --git-dir &>/dev/null || exit 0
|
|
38
|
+
|
|
39
|
+
# Check for test marker (created by test runner)
|
|
40
|
+
PROJECT_HASH=$(pwd | md5sum | cut -c1-8)
|
|
41
|
+
MARKER="/tmp/cc-tests-passed-${PROJECT_HASH}"
|
|
42
|
+
MAX_AGE=600 # 10 minutes
|
|
43
|
+
|
|
44
|
+
if [ ! -f "$MARKER" ]; then
|
|
45
|
+
echo "BLOCKED: No test evidence found. Run tests before committing." >&2
|
|
46
|
+
echo "" >&2
|
|
47
|
+
echo "Your test runner should create: $MARKER" >&2
|
|
48
|
+
echo "Example: pytest && touch $MARKER" >&2
|
|
49
|
+
exit 2
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
# Check marker age
|
|
53
|
+
MARKER_AGE=$(( $(date +%s) - $(stat -c %Y "$MARKER" 2>/dev/null || echo 0) ))
|
|
54
|
+
if (( MARKER_AGE > MAX_AGE )); then
|
|
55
|
+
echo "BLOCKED: Test results are stale (${MARKER_AGE}s old, max ${MAX_AGE}s)." >&2
|
|
56
|
+
echo "Run tests again before committing." >&2
|
|
57
|
+
exit 2
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
exit 0
|
package/index.mjs
CHANGED
|
@@ -79,7 +79,7 @@ if (HELP) {
|
|
|
79
79
|
npx cc-safe-setup --verify Test each hook with sample inputs
|
|
80
80
|
npx cc-safe-setup --dry-run Preview without installing
|
|
81
81
|
npx cc-safe-setup --uninstall Remove all installed hooks
|
|
82
|
-
npx cc-safe-setup --examples List
|
|
82
|
+
npx cc-safe-setup --examples List 25 example hooks (5 categories)
|
|
83
83
|
npx cc-safe-setup --install-example <name> Install a specific example
|
|
84
84
|
npx cc-safe-setup --help Show this help
|
|
85
85
|
|
|
@@ -185,7 +185,7 @@ function status() {
|
|
|
185
185
|
'auto-approve-git-read.sh', 'auto-approve-python.sh', 'auto-approve-ssh.sh',
|
|
186
186
|
'auto-checkpoint.sh', 'auto-snapshot.sh', 'block-database-wipe.sh', 'branch-name-check.sh', 'commit-message-check.sh', 'env-var-check.sh',
|
|
187
187
|
'deploy-guard.sh', 'edit-guard.sh', 'enforce-tests.sh', 'git-config-guard.sh',
|
|
188
|
-
'large-file-guard.sh', 'network-guard.sh', 'notify-waiting.sh',
|
|
188
|
+
'large-file-guard.sh', 'network-guard.sh', 'notify-waiting.sh', 'path-traversal-guard.sh',
|
|
189
189
|
'protect-dotfiles.sh', 'scope-guard.sh', 'test-before-push.sh', 'timeout-guard.sh', 'todo-check.sh',
|
|
190
190
|
];
|
|
191
191
|
const installedExamples = exampleFiles.filter(f => existsSync(join(HOOKS_DIR, f)));
|
|
@@ -304,6 +304,7 @@ function examples() {
|
|
|
304
304
|
'enforce-tests.sh': 'Warn when source files change without test files',
|
|
305
305
|
'large-file-guard.sh': 'Warn when Write creates files over 500KB',
|
|
306
306
|
'todo-check.sh': 'Warn when committing files with TODO/FIXME markers',
|
|
307
|
+
'verify-before-commit.sh': 'Block commit unless tests passed recently',
|
|
307
308
|
},
|
|
308
309
|
'Recovery': {
|
|
309
310
|
'auto-checkpoint.sh': 'Auto-commit after edits for rollback protection',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cc-safe-setup",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.8",
|
|
4
4
|
"description": "One command to make Claude Code safe for autonomous operation. 8 built-in hooks + 25 installable examples. Destructive blocker, branch guard, database wipe protection, dotfile guard, and more.",
|
|
5
5
|
"main": "index.mjs",
|
|
6
6
|
"bin": {
|