cc-safe-setup 28.6.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 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 331 examples |
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 |
@@ -232,6 +232,22 @@ echo "[$(date -Iseconds)] BLOCKED: reason | cmd: $COMMAND" >> "$LOG"
232
232
 
233
233
  Then view with: `npx cc-safe-setup --watch` or `npx cc-safe-setup --stats`
234
234
 
235
+ ## "claude -p returns empty output when Stop hook is configured"
236
+
237
+ This is a known Claude Code v2.1.83 bug ([#38651](https://github.com/anthropics/claude-code/issues/38651)), not a cc-safe-setup issue. Any Stop hook — even `true` — causes `-p` (print mode) to return empty stdout.
238
+
239
+ **Workaround:** Temporarily remove Stop hooks when using `-p` mode:
240
+
241
+ ```bash
242
+ # Quick toggle: comment out Stop hooks before -p commands
243
+ npx cc-safe-setup --status # See which hooks are active
244
+ # Manually comment out Stop hooks in ~/.claude/settings.json
245
+ # Run your -p command
246
+ # Uncomment Stop hooks after
247
+ ```
248
+
249
+ This should be fixed in a future Claude Code release.
250
+
235
251
  ## Still Stuck?
236
252
 
237
253
  1. Wrap the hook with debug wrapper: `npx cc-safe-setup --install-example hook-debug-wrapper`
@@ -0,0 +1,33 @@
1
+ #!/bin/bash
2
+ # allow-claude-settings.sh — PermissionRequest hook
3
+ # Trigger: PermissionRequest
4
+ # Matcher: Edit|Write
5
+ #
6
+ # Auto-approves writes to .claude/ configuration files.
7
+ # Use this in isolated environments (containers, VMs) where
8
+ # bypassPermissions is enabled but .claude/ writes still prompt.
9
+ #
10
+ # See: https://github.com/anthropics/claude-code/issues/36044
11
+ # See: https://github.com/anthropics/claude-code/issues/37765
12
+ #
13
+ # WARNING: Only use in environments where you trust Claude's edits
14
+ # to your configuration. In shared or production environments,
15
+ # keep the default prompts.
16
+
17
+ INPUT=$(cat)
18
+ FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
19
+ [ -z "$FILE_PATH" ] && exit 0
20
+
21
+ # Allow .claude/ writes (settings, rules, agents, skills, hooks)
22
+ if echo "$FILE_PATH" | grep -qE '\.claude/'; then
23
+ jq -n '{
24
+ hookSpecificOutput: {
25
+ hookEventName: "PermissionRequest",
26
+ permissionDecision: "allow",
27
+ permissionDecisionReason: "Allowed: .claude/ directory (isolated environment)"
28
+ }
29
+ }'
30
+ exit 0
31
+ fi
32
+
33
+ exit 0
@@ -0,0 +1,32 @@
1
+ #!/bin/bash
2
+ # allow-protected-dirs.sh — PermissionRequest hook
3
+ # Trigger: PermissionRequest
4
+ # Matcher: Edit|Write
5
+ #
6
+ # Auto-approves writes to ALL protected directories (.claude/, .git/,
7
+ # .vscode/, .idea/). Equivalent to full bypassPermissions for file edits.
8
+ #
9
+ # USE CASE: Docker containers, CI/CD, disposable VMs where you want
10
+ # zero prompts and understand the risks.
11
+ #
12
+ # WARNING: This is the most permissive PermissionRequest hook possible.
13
+ # It bypasses ALL built-in file protection. Do NOT use in shared or
14
+ # production environments. Prefer allow-git-hooks-dir.sh or
15
+ # allow-claude-settings.sh for targeted bypass.
16
+
17
+ INPUT=$(cat)
18
+ FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
19
+ [ -z "$FILE_PATH" ] && exit 0
20
+
21
+ if echo "$FILE_PATH" | grep -qE '\.(claude|git|vscode|idea)/'; then
22
+ jq -n '{
23
+ hookSpecificOutput: {
24
+ hookEventName: "PermissionRequest",
25
+ permissionDecision: "allow",
26
+ permissionDecisionReason: "Allowed: protected directory (full bypass)"
27
+ }
28
+ }'
29
+ exit 0
30
+ fi
31
+
32
+ exit 0
@@ -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.6.0",
4
- "description": "One command to make Claude Code safe. 337 hooks (8 built-in + 331 examples). 49 CLI commands. 996 tests. 5 languages.",
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"