cc-safe-setup 2.0.0 → 2.0.2
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 -0
- package/examples/README.md +46 -33
- package/examples/commit-message-check.sh +53 -0
- package/examples/env-var-check.sh +38 -0
- package/index.mjs +8 -5
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -155,6 +155,7 @@ Or browse all available examples in [`examples/`](examples/):
|
|
|
155
155
|
- **network-guard.sh** — Warn on suspicious network commands sending file contents ([#37420](https://github.com/anthropics/claude-code/issues/37420))
|
|
156
156
|
- **test-before-push.sh** — Block `git push` when tests haven't been run ([#36970](https://github.com/anthropics/claude-code/issues/36970))
|
|
157
157
|
- **large-file-guard.sh** — Warn when Write tool creates files over 500KB
|
|
158
|
+
- **commit-message-check.sh** — Warn on non-conventional commit messages (feat:, fix:, docs:, etc.)
|
|
158
159
|
|
|
159
160
|
## Learn More
|
|
160
161
|
|
package/examples/README.md
CHANGED
|
@@ -1,46 +1,59 @@
|
|
|
1
1
|
# Example Hooks
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
| Hook | Purpose | Related Issue |
|
|
6
|
-
|------|---------|---------------|
|
|
7
|
-
| **allowlist.sh** | Block everything not explicitly approved (inverse model) | [#37471](https://github.com/anthropics/claude-code/issues/37471) |
|
|
8
|
-
| **auto-checkpoint.sh** | Auto-commit after edits for rollback protection | [#34674](https://github.com/anthropics/claude-code/issues/34674) |
|
|
9
|
-
| **auto-approve-build.sh** | Auto-approve npm/yarn/cargo/go build, test, lint | |
|
|
10
|
-
| **auto-approve-docker.sh** | Auto-approve docker build, compose, ps, logs | |
|
|
11
|
-
| **auto-approve-git-read.sh** | Auto-approve `git status/log/diff` even with `-C` flags | [#36900](https://github.com/anthropics/claude-code/issues/36900) |
|
|
12
|
-
| **auto-approve-python.sh** | Auto-approve pytest, mypy, ruff, black, isort | |
|
|
13
|
-
| **auto-approve-ssh.sh** | Auto-approve safe SSH commands (uptime, whoami) | |
|
|
14
|
-
| **auto-snapshot.sh** | Save file snapshots before edits (rollback protection) | [#37386](https://github.com/anthropics/claude-code/issues/37386) |
|
|
15
|
-
| **block-database-wipe.sh** | Block destructive DB commands (Laravel, Django, Rails) | [#37405](https://github.com/anthropics/claude-code/issues/37405) |
|
|
16
|
-
| **deploy-guard.sh** | Block deploy when uncommitted changes exist | [#37314](https://github.com/anthropics/claude-code/issues/37314) |
|
|
17
|
-
| **edit-guard.sh** | Block Edit/Write to protected files | [#37210](https://github.com/anthropics/claude-code/issues/37210) |
|
|
18
|
-
| **enforce-tests.sh** | Warn when source changes without test changes | |
|
|
19
|
-
| **git-config-guard.sh** | Block git config --global modifications | [#37201](https://github.com/anthropics/claude-code/issues/37201) |
|
|
20
|
-
| **large-file-guard.sh** | Warn when Write creates oversized files (>500KB) | |
|
|
21
|
-
| **network-guard.sh** | Warn on suspicious network commands (data exfiltration) | [#37420](https://github.com/anthropics/claude-code/issues/37420) |
|
|
22
|
-
| **notify-waiting.sh** | Desktop notification when Claude waits for input | |
|
|
23
|
-
| **protect-dotfiles.sh** | Block modifications to ~/.bashrc, ~/.aws/, ~/.ssh/ | [#37478](https://github.com/anthropics/claude-code/issues/37478) |
|
|
24
|
-
| **scope-guard.sh** | Block file operations outside project directory | [#36233](https://github.com/anthropics/claude-code/issues/36233) |
|
|
25
|
-
| **test-before-push.sh** | Block git push when tests haven't passed | [#36970](https://github.com/anthropics/claude-code/issues/36970) |
|
|
3
|
+
19 hooks beyond the 8 built-in ones, organized by category.
|
|
26
4
|
|
|
27
5
|
## Quick Start
|
|
28
6
|
|
|
29
7
|
```bash
|
|
30
8
|
# One command — copies hook, updates settings.json, makes executable
|
|
31
9
|
npx cc-safe-setup --install-example block-database-wipe
|
|
10
|
+
|
|
11
|
+
# Browse all examples with categories
|
|
12
|
+
npx cc-safe-setup --examples
|
|
32
13
|
```
|
|
33
14
|
|
|
34
|
-
|
|
15
|
+
## Safety Guards
|
|
16
|
+
|
|
17
|
+
| Hook | Purpose | Issue |
|
|
18
|
+
|------|---------|-------|
|
|
19
|
+
| **allowlist.sh** | Block everything not explicitly approved | [#37471](https://github.com/anthropics/claude-code/issues/37471) |
|
|
20
|
+
| **block-database-wipe.sh** | Block migrate:fresh, DROP DATABASE, Prisma reset | [#37405](https://github.com/anthropics/claude-code/issues/37405) |
|
|
21
|
+
| **deploy-guard.sh** | Block deploy with uncommitted changes | [#37314](https://github.com/anthropics/claude-code/issues/37314) |
|
|
22
|
+
| **env-var-check.sh** | Block hardcoded API keys in export commands | |
|
|
23
|
+
| **git-config-guard.sh** | Block git config --global | [#37201](https://github.com/anthropics/claude-code/issues/37201) |
|
|
24
|
+
| **network-guard.sh** | Warn on suspicious network commands | [#37420](https://github.com/anthropics/claude-code/issues/37420) |
|
|
25
|
+
| **protect-dotfiles.sh** | Block changes to ~/.bashrc, ~/.aws/, ~/.ssh/ | [#37478](https://github.com/anthropics/claude-code/issues/37478) |
|
|
26
|
+
| **scope-guard.sh** | Block operations outside project directory | [#36233](https://github.com/anthropics/claude-code/issues/36233) |
|
|
27
|
+
| **test-before-push.sh** | Block git push without tests | [#36970](https://github.com/anthropics/claude-code/issues/36970) |
|
|
28
|
+
|
|
29
|
+
## Auto-Approve
|
|
30
|
+
|
|
31
|
+
| Hook | Purpose | Issue |
|
|
32
|
+
|------|---------|-------|
|
|
33
|
+
| **auto-approve-build.sh** | npm/yarn/cargo/go build, test, lint | |
|
|
34
|
+
| **auto-approve-docker.sh** | docker build, compose, ps, logs | |
|
|
35
|
+
| **auto-approve-git-read.sh** | git status/log/diff with -C flags | [#36900](https://github.com/anthropics/claude-code/issues/36900) |
|
|
36
|
+
| **auto-approve-python.sh** | pytest, mypy, ruff, black, isort | |
|
|
37
|
+
| **auto-approve-ssh.sh** | Safe SSH commands (uptime, whoami) | |
|
|
38
|
+
|
|
39
|
+
## Quality
|
|
40
|
+
|
|
41
|
+
| Hook | Purpose | Issue |
|
|
42
|
+
|------|---------|-------|
|
|
43
|
+
| **commit-message-check.sh** | Warn on non-conventional commit messages | |
|
|
44
|
+
| **edit-guard.sh** | Block Edit/Write to protected files | [#37210](https://github.com/anthropics/claude-code/issues/37210) |
|
|
45
|
+
| **enforce-tests.sh** | Warn when source changes without tests | |
|
|
46
|
+
| **large-file-guard.sh** | Warn when Write creates files >500KB | |
|
|
35
47
|
|
|
36
|
-
|
|
37
|
-
cp examples/block-database-wipe.sh ~/.claude/hooks/
|
|
38
|
-
chmod +x ~/.claude/hooks/block-database-wipe.sh
|
|
39
|
-
# Add to settings.json — see each file's header for the JSON config
|
|
40
|
-
```
|
|
48
|
+
## Recovery
|
|
41
49
|
|
|
42
|
-
|
|
50
|
+
| Hook | Purpose | Issue |
|
|
51
|
+
|------|---------|-------|
|
|
52
|
+
| **auto-checkpoint.sh** | Auto-commit after edits (compaction protection) | [#34674](https://github.com/anthropics/claude-code/issues/34674) |
|
|
53
|
+
| **auto-snapshot.sh** | Save file copies before edits | [#37386](https://github.com/anthropics/claude-code/issues/37386) |
|
|
43
54
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
55
|
+
## UX
|
|
56
|
+
|
|
57
|
+
| Hook | Purpose | Issue |
|
|
58
|
+
|------|---------|-------|
|
|
59
|
+
| **notify-waiting.sh** | Desktop notification when Claude waits | |
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# commit-message-check.sh — Warn when commit messages don't follow conventions
|
|
3
|
+
#
|
|
4
|
+
# Checks for conventional commits format (feat:, fix:, docs:, etc.)
|
|
5
|
+
# and minimum message length.
|
|
6
|
+
#
|
|
7
|
+
# This is a PostToolUse hook — it checks AFTER git commit runs
|
|
8
|
+
# and warns if the message doesn't follow conventions.
|
|
9
|
+
#
|
|
10
|
+
# Usage: Add to settings.json as a PostToolUse hook
|
|
11
|
+
#
|
|
12
|
+
# {
|
|
13
|
+
# "hooks": {
|
|
14
|
+
# "PostToolUse": [{
|
|
15
|
+
# "matcher": "Bash",
|
|
16
|
+
# "hooks": [{ "type": "command", "command": "~/.claude/hooks/commit-message-check.sh" }]
|
|
17
|
+
# }]
|
|
18
|
+
# }
|
|
19
|
+
# }
|
|
20
|
+
|
|
21
|
+
INPUT=$(cat)
|
|
22
|
+
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
23
|
+
|
|
24
|
+
[[ -z "$COMMAND" ]] && exit 0
|
|
25
|
+
|
|
26
|
+
# Only check after git commit
|
|
27
|
+
if ! echo "$COMMAND" | grep -qE '^\s*git\s+commit\b'; then
|
|
28
|
+
exit 0
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
# Must be in a git repo
|
|
32
|
+
git rev-parse --git-dir &>/dev/null || exit 0
|
|
33
|
+
|
|
34
|
+
# Get the last commit message
|
|
35
|
+
MSG=$(git log -1 --pretty=%s 2>/dev/null)
|
|
36
|
+
[[ -z "$MSG" ]] && exit 0
|
|
37
|
+
|
|
38
|
+
# Check conventional commit format
|
|
39
|
+
if ! echo "$MSG" | grep -qE '^(feat|fix|docs|style|refactor|test|chore|perf|ci|build|revert)(\(.+\))?(!)?:'; then
|
|
40
|
+
echo "" >&2
|
|
41
|
+
echo "NOTE: Commit message doesn't follow conventional commits format." >&2
|
|
42
|
+
echo "Expected: feat|fix|docs|chore|...: description" >&2
|
|
43
|
+
echo "Got: $MSG" >&2
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
# Check minimum length
|
|
47
|
+
if (( ${#MSG} < 10 )); then
|
|
48
|
+
echo "" >&2
|
|
49
|
+
echo "NOTE: Commit message is very short (${#MSG} chars)." >&2
|
|
50
|
+
echo "Consider adding more context." >&2
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
exit 0
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# env-var-check.sh — Warn when setting environment variables with secrets
|
|
3
|
+
#
|
|
4
|
+
# Solves: Claude hardcoding API keys or passwords into export commands
|
|
5
|
+
# that end up in shell history and process environment.
|
|
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/env-var-check.sh" }]
|
|
14
|
+
# }]
|
|
15
|
+
# }
|
|
16
|
+
# }
|
|
17
|
+
|
|
18
|
+
INPUT=$(cat)
|
|
19
|
+
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
20
|
+
|
|
21
|
+
[[ -z "$COMMAND" ]] && exit 0
|
|
22
|
+
|
|
23
|
+
# Check for export/set with sensitive-looking values
|
|
24
|
+
if echo "$COMMAND" | grep -qiE 'export\s+(API_KEY|SECRET|TOKEN|PASSWORD|CREDENTIALS|AUTH)='; then
|
|
25
|
+
echo "" >&2
|
|
26
|
+
echo "⚠ SECURITY: Setting sensitive environment variable in shell" >&2
|
|
27
|
+
echo "This will appear in shell history. Use .env files or secret managers instead." >&2
|
|
28
|
+
echo "Command: $COMMAND" >&2
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
# Check for hardcoded key patterns (sk-, pk-, ghp_, etc.)
|
|
32
|
+
if echo "$COMMAND" | grep -qE 'export\s+\w+=.*(sk-[a-zA-Z0-9]{20,}|ghp_[a-zA-Z0-9]{36}|gho_[a-zA-Z0-9]{36}|glpat-[a-zA-Z0-9]{20,})'; then
|
|
33
|
+
echo "BLOCKED: Hardcoded API key detected in export command" >&2
|
|
34
|
+
echo "Use: export VAR=\$(cat ~/.credentials/key)" >&2
|
|
35
|
+
exit 2
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
exit 0
|
package/index.mjs
CHANGED
|
@@ -79,8 +79,8 @@ 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
|
|
83
|
-
npx cc-safe-setup --install-example <name> Install a specific example
|
|
82
|
+
npx cc-safe-setup --examples List 19 example hooks (5 categories)
|
|
83
|
+
npx cc-safe-setup --install-example <name> Install a specific example
|
|
84
84
|
npx cc-safe-setup --help Show this help
|
|
85
85
|
|
|
86
86
|
Hooks installed:
|
|
@@ -183,9 +183,10 @@ function status() {
|
|
|
183
183
|
const exampleFiles = [
|
|
184
184
|
'allowlist.sh', 'auto-approve-build.sh', 'auto-approve-docker.sh',
|
|
185
185
|
'auto-approve-git-read.sh', 'auto-approve-python.sh', 'auto-approve-ssh.sh',
|
|
186
|
-
'auto-checkpoint.sh', 'auto-snapshot.sh', 'block-database-wipe.sh',
|
|
186
|
+
'auto-checkpoint.sh', 'auto-snapshot.sh', 'block-database-wipe.sh', 'commit-message-check.sh',
|
|
187
187
|
'deploy-guard.sh', 'edit-guard.sh', 'enforce-tests.sh', 'git-config-guard.sh',
|
|
188
|
-
'
|
|
188
|
+
'large-file-guard.sh', 'network-guard.sh', 'notify-waiting.sh',
|
|
189
|
+
'protect-dotfiles.sh', 'scope-guard.sh', 'test-before-push.sh',
|
|
189
190
|
];
|
|
190
191
|
const installedExamples = exampleFiles.filter(f => existsSync(join(HOOKS_DIR, f)));
|
|
191
192
|
if (installedExamples.length > 0) {
|
|
@@ -280,6 +281,7 @@ function examples() {
|
|
|
280
281
|
'allowlist.sh': 'Block everything not in allowlist (inverse permission model)',
|
|
281
282
|
'block-database-wipe.sh': 'Block destructive DB commands (migrate:fresh, DROP DATABASE, Prisma)',
|
|
282
283
|
'deploy-guard.sh': 'Block deploy when uncommitted changes exist',
|
|
284
|
+
'env-var-check.sh': 'Block hardcoded API keys in export commands',
|
|
283
285
|
'network-guard.sh': 'Warn on suspicious network commands (data exfiltration)',
|
|
284
286
|
'protect-dotfiles.sh': 'Block modifications to ~/.bashrc, ~/.aws/, ~/.ssh/',
|
|
285
287
|
'scope-guard.sh': 'Block file operations outside project directory',
|
|
@@ -294,6 +296,7 @@ function examples() {
|
|
|
294
296
|
'auto-approve-ssh.sh': 'Auto-approve safe SSH commands (uptime, whoami)',
|
|
295
297
|
},
|
|
296
298
|
'Quality': {
|
|
299
|
+
'commit-message-check.sh': 'Warn on non-conventional commit messages',
|
|
297
300
|
'edit-guard.sh': 'Block Edit/Write to protected files (.env, credentials)',
|
|
298
301
|
'enforce-tests.sh': 'Warn when source files change without test files',
|
|
299
302
|
'large-file-guard.sh': 'Warn when Write creates files over 500KB',
|
|
@@ -309,7 +312,7 @@ function examples() {
|
|
|
309
312
|
|
|
310
313
|
console.log();
|
|
311
314
|
console.log(c.bold + ' cc-safe-setup --examples' + c.reset);
|
|
312
|
-
console.log(c.dim + '
|
|
315
|
+
console.log(c.dim + ' 21 hooks beyond the 8 built-in ones' + c.reset);
|
|
313
316
|
console.log();
|
|
314
317
|
|
|
315
318
|
for (const [cat, hooks] of Object.entries(CATEGORIES)) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cc-safe-setup",
|
|
3
|
-
"version": "2.0.
|
|
4
|
-
"description": "One command to make Claude Code safe for autonomous operation. 8 built-in hooks +
|
|
3
|
+
"version": "2.0.2",
|
|
4
|
+
"description": "One command to make Claude Code safe for autonomous operation. 8 built-in hooks + 21 installable examples. Destructive blocker, branch guard, database wipe protection, dotfile guard, and more.",
|
|
5
5
|
"main": "index.mjs",
|
|
6
6
|
"bin": {
|
|
7
7
|
"cc-safe-setup": "index.mjs"
|