cc-safe-setup 2.3.0 → 2.4.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 +23 -0
- package/action.yml +34 -0
- package/examples/session-checkpoint.sh +54 -0
- package/index.mjs +52 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -138,6 +138,29 @@ npx cc-safe-setup --audit
|
|
|
138
138
|
|
|
139
139
|
Analyzes 9 safety dimensions and gives you a score (0-100) with one-command fixes for each risk.
|
|
140
140
|
|
|
141
|
+
### CI Integration (GitHub Action)
|
|
142
|
+
|
|
143
|
+
```yaml
|
|
144
|
+
# .github/workflows/safety.yml
|
|
145
|
+
- uses: yurukusa/cc-safe-setup@main
|
|
146
|
+
with:
|
|
147
|
+
threshold: 70 # CI fails if score drops below this
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Project Scanner
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
npx cc-safe-setup --scan # detect tech stack, recommend hooks
|
|
154
|
+
npx cc-safe-setup --scan --apply # auto-create CLAUDE.md with project rules
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Self-Learning Safety
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
npx cc-safe-setup --learn # analyze your block history for patterns
|
|
161
|
+
npx cc-safe-setup --learn --apply # auto-generate custom hooks from patterns
|
|
162
|
+
```
|
|
163
|
+
|
|
141
164
|
## Examples
|
|
142
165
|
|
|
143
166
|
Need custom hooks beyond the 8 built-in ones? Install any example with one command:
|
package/action.yml
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
name: 'Claude Code Safety Audit'
|
|
2
|
+
description: 'Check your Claude Code safety setup and fail CI if score is below threshold'
|
|
3
|
+
branding:
|
|
4
|
+
icon: 'shield'
|
|
5
|
+
color: 'green'
|
|
6
|
+
|
|
7
|
+
inputs:
|
|
8
|
+
threshold:
|
|
9
|
+
description: 'Minimum safety score (0-100). CI fails if below this.'
|
|
10
|
+
required: false
|
|
11
|
+
default: '70'
|
|
12
|
+
|
|
13
|
+
runs:
|
|
14
|
+
using: 'composite'
|
|
15
|
+
steps:
|
|
16
|
+
- name: Run safety audit
|
|
17
|
+
shell: bash
|
|
18
|
+
run: |
|
|
19
|
+
echo "::group::Claude Code Safety Audit"
|
|
20
|
+
npx cc-safe-setup@latest --audit 2>&1 | tee /tmp/audit-output.txt
|
|
21
|
+
echo "::endgroup::"
|
|
22
|
+
|
|
23
|
+
# Extract score
|
|
24
|
+
SCORE=$(grep -oP 'Safety Score: \K\d+' /tmp/audit-output.txt || echo "0")
|
|
25
|
+
THRESHOLD="${{ inputs.threshold }}"
|
|
26
|
+
|
|
27
|
+
echo "Safety Score: $SCORE / 100 (threshold: $THRESHOLD)"
|
|
28
|
+
|
|
29
|
+
if [ "$SCORE" -lt "$THRESHOLD" ]; then
|
|
30
|
+
echo "::error::Safety score $SCORE is below threshold $THRESHOLD. Run 'npx cc-safe-setup --audit --fix' to improve."
|
|
31
|
+
exit 1
|
|
32
|
+
else
|
|
33
|
+
echo "::notice::Safety score $SCORE meets threshold $THRESHOLD ✓"
|
|
34
|
+
fi
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# session-checkpoint.sh — Auto-save session state on every stop
|
|
3
|
+
#
|
|
4
|
+
# Solves: Session crashes/disconnects causing expensive re-analysis
|
|
5
|
+
# of the entire codebase on next start (#37866)
|
|
6
|
+
#
|
|
7
|
+
# Saves: git state, recent commits, modified files, working directory.
|
|
8
|
+
# Next session reads the checkpoint instead of re-analyzing everything.
|
|
9
|
+
#
|
|
10
|
+
# Usage: Add to settings.json as a Stop hook
|
|
11
|
+
#
|
|
12
|
+
# {
|
|
13
|
+
# "hooks": {
|
|
14
|
+
# "Stop": [{
|
|
15
|
+
# "hooks": [{ "type": "command", "command": "~/.claude/hooks/session-checkpoint.sh" }]
|
|
16
|
+
# }]
|
|
17
|
+
# }
|
|
18
|
+
# }
|
|
19
|
+
#
|
|
20
|
+
# Recovery: Add to CLAUDE.md:
|
|
21
|
+
# "If ~/.claude/checkpoints/ has a file for this project, read it first."
|
|
22
|
+
|
|
23
|
+
INPUT=$(cat)
|
|
24
|
+
REASON=$(echo "$INPUT" | jq -r '.stop_reason // empty' 2>/dev/null)
|
|
25
|
+
|
|
26
|
+
CHECKPOINT_DIR="$HOME/.claude/checkpoints"
|
|
27
|
+
mkdir -p "$CHECKPOINT_DIR"
|
|
28
|
+
|
|
29
|
+
PROJECT_NAME=$(basename "$(pwd)")
|
|
30
|
+
CHECKPOINT="$CHECKPOINT_DIR/${PROJECT_NAME}-latest.md"
|
|
31
|
+
|
|
32
|
+
{
|
|
33
|
+
echo "# Session Checkpoint"
|
|
34
|
+
echo "Saved: $(date -Iseconds)"
|
|
35
|
+
echo "Directory: $(pwd)"
|
|
36
|
+
echo "Stop reason: ${REASON:-unknown}"
|
|
37
|
+
echo ""
|
|
38
|
+
echo "## Recent Commits"
|
|
39
|
+
git log --oneline -10 2>/dev/null || echo "(not a git repo)"
|
|
40
|
+
echo ""
|
|
41
|
+
echo "## Uncommitted Changes"
|
|
42
|
+
git diff --stat 2>/dev/null || echo "(none)"
|
|
43
|
+
echo ""
|
|
44
|
+
echo "## Staged Files"
|
|
45
|
+
git diff --cached --name-only 2>/dev/null || echo "(none)"
|
|
46
|
+
echo ""
|
|
47
|
+
echo "## Current Branch"
|
|
48
|
+
git branch --show-current 2>/dev/null || echo "(unknown)"
|
|
49
|
+
} > "$CHECKPOINT" 2>/dev/null
|
|
50
|
+
|
|
51
|
+
# Cleanup: keep only last 10 checkpoints
|
|
52
|
+
ls -t "$CHECKPOINT_DIR"/*.md 2>/dev/null | tail -n +11 | xargs rm -f 2>/dev/null
|
|
53
|
+
|
|
54
|
+
exit 0
|
package/index.mjs
CHANGED
|
@@ -71,6 +71,7 @@ const INSTALL_EXAMPLE = INSTALL_EXAMPLE_IDX !== -1 ? process.argv[INSTALL_EXAMPL
|
|
|
71
71
|
const AUDIT = process.argv.includes('--audit');
|
|
72
72
|
const LEARN = process.argv.includes('--learn');
|
|
73
73
|
const SCAN = process.argv.includes('--scan');
|
|
74
|
+
const FULL = process.argv.includes('--full');
|
|
74
75
|
|
|
75
76
|
if (HELP) {
|
|
76
77
|
console.log(`
|
|
@@ -568,6 +569,18 @@ async function audit() {
|
|
|
568
569
|
console.log();
|
|
569
570
|
console.log(c.dim + ' Run with --fix to auto-apply: npx cc-safe-setup --audit --fix' + c.reset);
|
|
570
571
|
}
|
|
572
|
+
|
|
573
|
+
// Badge output
|
|
574
|
+
if (process.argv.includes('--badge')) {
|
|
575
|
+
const color = score >= 80 ? 'brightgreen' : score >= 50 ? 'yellow' : 'red';
|
|
576
|
+
const badge = ``;
|
|
577
|
+
console.log();
|
|
578
|
+
console.log(c.bold + ' README Badge:' + c.reset);
|
|
579
|
+
console.log(' ' + badge);
|
|
580
|
+
console.log();
|
|
581
|
+
console.log(c.dim + ' Paste this into your README.md' + c.reset);
|
|
582
|
+
}
|
|
583
|
+
|
|
571
584
|
console.log();
|
|
572
585
|
}
|
|
573
586
|
|
|
@@ -683,6 +696,44 @@ exit 0`;
|
|
|
683
696
|
console.log();
|
|
684
697
|
}
|
|
685
698
|
|
|
699
|
+
async function fullSetup() {
|
|
700
|
+
console.log();
|
|
701
|
+
console.log(c.bold + c.green + ' cc-safe-setup --full' + c.reset);
|
|
702
|
+
console.log(c.dim + ' Complete safety setup in one command' + c.reset);
|
|
703
|
+
console.log();
|
|
704
|
+
|
|
705
|
+
const { execSync } = await import('child_process');
|
|
706
|
+
const self = process.argv[1];
|
|
707
|
+
|
|
708
|
+
// Step 1: Install 8 built-in hooks
|
|
709
|
+
console.log(c.bold + ' Step 1: Installing 8 built-in safety hooks...' + c.reset);
|
|
710
|
+
try {
|
|
711
|
+
execSync('node ' + self + ' --yes', { stdio: 'inherit' });
|
|
712
|
+
} catch(e) {
|
|
713
|
+
// --yes doesn't exist, run normal install
|
|
714
|
+
execSync('node ' + self, { stdio: 'inherit', input: 'y\n' });
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
// Step 2: Scan project and create CLAUDE.md
|
|
718
|
+
console.log();
|
|
719
|
+
console.log(c.bold + ' Step 2: Scanning project and creating CLAUDE.md...' + c.reset);
|
|
720
|
+
scan();
|
|
721
|
+
|
|
722
|
+
// Step 3: Audit and show results
|
|
723
|
+
console.log();
|
|
724
|
+
console.log(c.bold + ' Step 3: Running safety audit...' + c.reset);
|
|
725
|
+
// Inject --badge into argv temporarily
|
|
726
|
+
process.argv.push('--badge');
|
|
727
|
+
await audit();
|
|
728
|
+
|
|
729
|
+
console.log(c.bold + c.green + ' ✓ Full setup complete!' + c.reset);
|
|
730
|
+
console.log(c.dim + ' Your project now has:' + c.reset);
|
|
731
|
+
console.log(c.dim + ' • 8 built-in safety hooks' + c.reset);
|
|
732
|
+
console.log(c.dim + ' • Project-specific hook recommendations' + c.reset);
|
|
733
|
+
console.log(c.dim + ' • Safety score and README badge' + c.reset);
|
|
734
|
+
console.log();
|
|
735
|
+
}
|
|
736
|
+
|
|
686
737
|
function scan() {
|
|
687
738
|
console.log();
|
|
688
739
|
console.log(c.bold + ' cc-safe-setup --scan' + c.reset);
|
|
@@ -832,6 +883,7 @@ async function main() {
|
|
|
832
883
|
if (AUDIT) return audit();
|
|
833
884
|
if (LEARN) return learn();
|
|
834
885
|
if (SCAN) return scan();
|
|
886
|
+
if (FULL) return fullSetup();
|
|
835
887
|
|
|
836
888
|
console.log();
|
|
837
889
|
console.log(c.bold + ' cc-safe-setup' + c.reset);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cc-safe-setup",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
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": {
|