cc-safe-setup 10.3.0 → 10.5.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
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
**One command to make Claude Code safe for autonomous operation.** [日本語](docs/README.ja.md)
|
|
8
8
|
|
|
9
|
-
8 built-in + 104 examples = **
|
|
9
|
+
8 built-in + 104 examples = **118 hooks**. 37 CLI commands. 531 tests. 5 languages. [**Hub**](https://yurukusa.github.io/cc-safe-setup/hub.html) · [Cheat Sheet](https://yurukusa.github.io/cc-safe-setup/hooks-cheatsheet.html) · [Builder](https://yurukusa.github.io/cc-safe-setup/builder.html) · [FAQ](https://yurukusa.github.io/cc-safe-setup/faq.html) · [Examples](https://yurukusa.github.io/cc-safe-setup/by-example.html) · [Matrix](https://yurukusa.github.io/cc-safe-setup/matrix.html) · [Playground](https://yurukusa.github.io/cc-hook-registry/playground.html)
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
12
|
npx cc-safe-setup
|
|
@@ -105,6 +105,8 @@ Safe to run multiple times. Existing settings are preserved. A backup is created
|
|
|
105
105
|
|
|
106
106
|
**Maximum safety:** `npx cc-safe-setup --shield` — one command: fix environment, install hooks, detect stack, configure settings, generate CLAUDE.md.
|
|
107
107
|
|
|
108
|
+
**Instant rule:** `npx cc-safe-setup --guard "never touch the database"` — generates, installs, activates a hook instantly from plain English.
|
|
109
|
+
|
|
108
110
|
**Team setup:** `npx cc-safe-setup --team` — copy hooks to `.claude/hooks/` with relative paths, commit to repo for team sharing.
|
|
109
111
|
|
|
110
112
|
**Preview first:** `npx cc-safe-setup --dry-run`
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# ================================================================
|
|
3
|
+
# git-author-guard.sh — Verify commit author is configured correctly
|
|
4
|
+
# ================================================================
|
|
5
|
+
# PURPOSE:
|
|
6
|
+
# Claude Code sometimes commits with incorrect or default
|
|
7
|
+
# git author settings. This hook checks that user.name and
|
|
8
|
+
# user.email are set before allowing commits.
|
|
9
|
+
#
|
|
10
|
+
# TRIGGER: PreToolUse MATCHER: "Bash"
|
|
11
|
+
# ================================================================
|
|
12
|
+
|
|
13
|
+
COMMAND=$(cat | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
14
|
+
[ -z "$COMMAND" ] && exit 0
|
|
15
|
+
echo "$COMMAND" | grep -qE '^\s*git\s+commit' || exit 0
|
|
16
|
+
|
|
17
|
+
NAME=$(git config user.name 2>/dev/null)
|
|
18
|
+
EMAIL=$(git config user.email 2>/dev/null)
|
|
19
|
+
|
|
20
|
+
if [ -z "$NAME" ] || [ -z "$EMAIL" ]; then
|
|
21
|
+
echo "WARNING: Git author not configured." >&2
|
|
22
|
+
[ -z "$NAME" ] && echo " Missing: git config user.name" >&2
|
|
23
|
+
[ -z "$EMAIL" ] && echo " Missing: git config user.email" >&2
|
|
24
|
+
fi
|
|
25
|
+
|
|
26
|
+
# Warn on common placeholder values
|
|
27
|
+
if echo "$EMAIL" | grep -qE '(example\.com|noreply|placeholder)' 2>/dev/null; then
|
|
28
|
+
echo "WARNING: Git email looks like a placeholder: $EMAIL" >&2
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
exit 0
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# ================================================================
|
|
3
|
+
# permission-cache.sh — Remember approved commands in session
|
|
4
|
+
# ================================================================
|
|
5
|
+
# PURPOSE:
|
|
6
|
+
# Claude asks permission for the same safe command repeatedly.
|
|
7
|
+
# This hook caches approved command patterns within a session,
|
|
8
|
+
# auto-approving on subsequent calls. Resets when the state
|
|
9
|
+
# file is deleted (new session).
|
|
10
|
+
#
|
|
11
|
+
# TRIGGER: PreToolUse MATCHER: "Bash"
|
|
12
|
+
#
|
|
13
|
+
# Only caches commands that match safe patterns (not destructive).
|
|
14
|
+
# ================================================================
|
|
15
|
+
|
|
16
|
+
COMMAND=$(cat | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
17
|
+
[ -z "$COMMAND" ] && exit 0
|
|
18
|
+
|
|
19
|
+
# Never cache destructive commands
|
|
20
|
+
echo "$COMMAND" | grep -qE '(rm\s+-rf|git\s+reset|git\s+clean|git\s+push.*--force|sudo|chmod\s+777)' && exit 0
|
|
21
|
+
|
|
22
|
+
STATE="/tmp/cc-permission-cache-$(echo "$PWD" | md5sum | cut -c1-8)"
|
|
23
|
+
|
|
24
|
+
# Normalize command (strip args that change, keep base command)
|
|
25
|
+
BASE=$(echo "$COMMAND" | awk '{print $1, $2}' | head -c 40)
|
|
26
|
+
HASH=$(echo "$BASE" | md5sum | cut -c1-12)
|
|
27
|
+
|
|
28
|
+
if grep -q "^$HASH$" "$STATE" 2>/dev/null; then
|
|
29
|
+
# Already approved in this session
|
|
30
|
+
echo "{\"decision\":\"approve\",\"reason\":\"Previously approved in this session\"}"
|
|
31
|
+
exit 0
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
# Record for future calls (will be approved by the normal flow)
|
|
35
|
+
echo "$HASH" >> "$STATE" 2>/dev/null
|
|
36
|
+
|
|
37
|
+
exit 0
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# typescript-strict-guard.sh — Warn when tsconfig.json strict mode is disabled
|
|
3
|
+
# TRIGGER: PostToolUse MATCHER: "Edit"
|
|
4
|
+
INPUT=$(cat)
|
|
5
|
+
FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
|
|
6
|
+
[ -z "$FILE" ] && exit 0
|
|
7
|
+
case "$FILE" in */tsconfig.json|tsconfig.json) ;; *) exit 0 ;; esac
|
|
8
|
+
NEW=$(echo "$INPUT" | jq -r '.tool_input.new_string // empty' 2>/dev/null)
|
|
9
|
+
[ -z "$NEW" ] && exit 0
|
|
10
|
+
if echo "$NEW" | grep -q '"strict"' && echo "$NEW" | grep -q 'false'; then
|
|
11
|
+
echo "WARNING: TypeScript strict mode being disabled in tsconfig.json." >&2
|
|
12
|
+
echo "Strict mode catches bugs at compile time. Think twice." >&2
|
|
13
|
+
fi
|
|
14
|
+
exit 0
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# ================================================================
|
|
3
|
+
# typosquat-guard.sh — Detect potential typosquatting in npm install
|
|
4
|
+
# ================================================================
|
|
5
|
+
# PURPOSE:
|
|
6
|
+
# Claude sometimes installs packages with slightly misspelled
|
|
7
|
+
# names (e.g., "loadsh" instead of "lodash"). This hook checks
|
|
8
|
+
# common typosquatting patterns in npm/pip install commands.
|
|
9
|
+
#
|
|
10
|
+
# TRIGGER: PreToolUse MATCHER: "Bash"
|
|
11
|
+
# ================================================================
|
|
12
|
+
|
|
13
|
+
COMMAND=$(cat | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
14
|
+
[ -z "$COMMAND" ] && exit 0
|
|
15
|
+
|
|
16
|
+
# Extract package name from install command
|
|
17
|
+
PKG=""
|
|
18
|
+
if echo "$COMMAND" | grep -qE '^\s*npm\s+install\s+'; then
|
|
19
|
+
PKG=$(echo "$COMMAND" | grep -oE 'npm\s+install\s+(\S+)' | awk '{print $3}' | head -1)
|
|
20
|
+
elif echo "$COMMAND" | grep -qE '^\s*pip\s+install\s+'; then
|
|
21
|
+
PKG=$(echo "$COMMAND" | grep -oE 'pip\s+install\s+(\S+)' | awk '{print $3}' | head -1)
|
|
22
|
+
fi
|
|
23
|
+
[ -z "$PKG" ] && exit 0
|
|
24
|
+
|
|
25
|
+
# Strip scope and version
|
|
26
|
+
PKG=$(echo "$PKG" | sed 's/@[^/]*\///' | sed 's/@.*//')
|
|
27
|
+
|
|
28
|
+
# Known popular packages and their common typos
|
|
29
|
+
declare -A POPULAR=(
|
|
30
|
+
["lodash"]="loadsh lodassh lodas"
|
|
31
|
+
["express"]="expresss expres exppress"
|
|
32
|
+
["react"]="recat raect reatc"
|
|
33
|
+
["axios"]="axois axio axioss"
|
|
34
|
+
["moment"]="momnet moemnt momet"
|
|
35
|
+
["webpack"]="webpak webpackk wepback"
|
|
36
|
+
["typescript"]="typscript typescrip tyepscript"
|
|
37
|
+
["eslint"]="esling eslnt elsint"
|
|
38
|
+
["prettier"]="pretier pretter prettir"
|
|
39
|
+
["mongoose"]="mongose mongooe mongooes"
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
for legit in "${!POPULAR[@]}"; do
|
|
43
|
+
for typo in ${POPULAR[$legit]}; do
|
|
44
|
+
if [ "$PKG" = "$typo" ]; then
|
|
45
|
+
echo "WARNING: '$PKG' looks like a typo of '$legit'." >&2
|
|
46
|
+
echo "Did you mean: npm install $legit" >&2
|
|
47
|
+
echo "Typosquatting packages can contain malware." >&2
|
|
48
|
+
exit 0
|
|
49
|
+
fi
|
|
50
|
+
done
|
|
51
|
+
done
|
|
52
|
+
|
|
53
|
+
# Check for suspicious single-char differences from popular packages
|
|
54
|
+
LEN=${#PKG}
|
|
55
|
+
if [ "$LEN" -gt 3 ] && [ "$LEN" -lt 20 ]; then
|
|
56
|
+
for legit in "${!POPULAR[@]}"; do
|
|
57
|
+
LEGIT_LEN=${#legit}
|
|
58
|
+
DIFF=$((LEN - LEGIT_LEN))
|
|
59
|
+
[ "$DIFF" -lt -1 ] || [ "$DIFF" -gt 1 ] && continue
|
|
60
|
+
# Simple Levenshtein approximation: count differing chars
|
|
61
|
+
MATCH=0
|
|
62
|
+
for ((i=0; i<LEN && i<LEGIT_LEN; i++)); do
|
|
63
|
+
[ "${PKG:$i:1}" = "${legit:$i:1}" ] && MATCH=$((MATCH+1))
|
|
64
|
+
done
|
|
65
|
+
SIMILARITY=$((MATCH * 100 / (LEGIT_LEN > LEN ? LEGIT_LEN : LEN)))
|
|
66
|
+
if [ "$SIMILARITY" -ge 80 ] && [ "$PKG" != "$legit" ]; then
|
|
67
|
+
echo "NOTE: '$PKG' is similar to '$legit' (${SIMILARITY}% match)." >&2
|
|
68
|
+
echo "Verify this is the correct package name." >&2
|
|
69
|
+
fi
|
|
70
|
+
done
|
|
71
|
+
fi
|
|
72
|
+
|
|
73
|
+
exit 0
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cc-safe-setup",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "10.5.0",
|
|
4
4
|
"description": "One command to make Claude Code safe. 59 hooks (8 built-in + 51 examples). 26 CLI commands: dashboard, create, audit, lint, diff, migrate, compare, generate-ci. 284 tests.",
|
|
5
5
|
"main": "index.mjs",
|
|
6
6
|
"bin": {
|