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 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 = `![Claude Code Safety](https://img.shields.io/badge/Claude_Code_Safety-${score}%2F100-${color})`;
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.0",
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": {