cc-safe-setup 12.7.0 → 13.1.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 + 124 examples = **135 hooks**. 42 CLI commands. 561 tests. 5 languages. [**Hub**](https://yurukusa.github.io/cc-safe-setup/hub.html) · [Wizard](https://yurukusa.github.io/cc-safe-setup/wizard.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)
9
+ 8 built-in + 124 examples = **137 hooks**. 43 CLI commands. 561 tests. 5 languages. [**Hub**](https://yurukusa.github.io/cc-safe-setup/hub.html) · [Wizard](https://yurukusa.github.io/cc-safe-setup/wizard.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
@@ -0,0 +1,18 @@
1
+ #!/bin/bash
2
+ # dotenv-validate.sh — Validate .env syntax after edits
3
+ # TRIGGER: PostToolUse MATCHER: "Edit|Write"
4
+ FILE=$(cat | jq -r '.tool_input.file_path // empty' 2>/dev/null)
5
+ [ -z "$FILE" ] && exit 0
6
+ case "$FILE" in *.env|*.env.*) ;; *) exit 0 ;; esac
7
+ [ ! -f "$FILE" ] && exit 0
8
+ # Check for common .env syntax errors
9
+ ERRORS=0
10
+ while IFS= read -r line; do
11
+ [ -z "$line" ] || [[ "$line" =~ ^# ]] && continue
12
+ if ! echo "$line" | grep -qE '^[A-Z_][A-Z0-9_]*='; then
13
+ echo "WARNING: Invalid .env line: $line" >&2
14
+ ERRORS=$((ERRORS+1))
15
+ fi
16
+ done < "$FILE"
17
+ [ "$ERRORS" -gt 0 ] && echo "$ERRORS syntax error(s) in $FILE" >&2
18
+ exit 0
@@ -0,0 +1,14 @@
1
+ #!/bin/bash
2
+ # readme-update-reminder.sh — Remind to update README when APIs change
3
+ # TRIGGER: PreToolUse MATCHER: "Bash"
4
+ COMMAND=$(cat | jq -r '.tool_input.command // empty' 2>/dev/null)
5
+ [ -z "$COMMAND" ] && exit 0
6
+ echo "$COMMAND" | grep -qE '^\s*git\s+commit' || exit 0
7
+ # Check if API-related files changed but README didn't
8
+ API_FILES=$(git diff --cached --name-only 2>/dev/null | grep -cE '(routes|api|endpoint|handler|controller)' || echo 0)
9
+ README_CHANGED=$(git diff --cached --name-only 2>/dev/null | grep -c 'README' || echo 0)
10
+ if [ "$API_FILES" -gt 0 ] && [ "$README_CHANGED" -eq 0 ]; then
11
+ echo "NOTE: API files changed but README was not updated." >&2
12
+ echo "Consider updating API documentation." >&2
13
+ fi
14
+ exit 0
package/index.mjs CHANGED
@@ -111,6 +111,7 @@ const SAVE_PROFILE = SAVE_PROFILE_IDX !== -1 ? process.argv[SAVE_PROFILE_IDX + 1
111
111
  const CREATE_IDX = process.argv.findIndex(a => a === '--create');
112
112
  const CREATE_DESC = CREATE_IDX !== -1 ? process.argv.slice(CREATE_IDX + 1).join(' ') : null;
113
113
  const SUGGEST = process.argv.includes('--suggest');
114
+ const INIT_PROJECT = process.argv.includes('--init-project');
114
115
  const TEST_HOOK_IDX = process.argv.findIndex(a => a === '--test-hook');
115
116
  const TEST_HOOK = TEST_HOOK_IDX !== -1 ? process.argv[TEST_HOOK_IDX + 1] : null;
116
117
  const WHY_IDX = process.argv.findIndex(a => a === '--why');
@@ -148,6 +149,7 @@ if (HELP) {
148
149
  npx cc-safe-setup --create "<desc>" Generate a custom hook from description
149
150
  npx cc-safe-setup --test-hook <name> Test a specific hook with sample inputs
150
151
  npx cc-safe-setup --save-profile <name> Save current hooks as a named profile
152
+ npx cc-safe-setup --init-project Complete project setup (CLAUDE.md + hooks + CI + .gitignore)
151
153
  npx cc-safe-setup --suggest Analyze project and predict risks → suggest hooks
152
154
  npx cc-safe-setup --why <hook> Why this hook exists (real incident + issue link)
153
155
  npx cc-safe-setup --replay Replay blocked commands timeline (demo/review)
@@ -1070,6 +1072,68 @@ async function saveProfile(name) {
1070
1072
  console.log();
1071
1073
  }
1072
1074
 
1075
+ async function initProject() {
1076
+ console.log();
1077
+ console.log(c.bold + ' cc-safe-setup --init-project' + c.reset);
1078
+ console.log(c.dim + ' Complete Claude Code setup for this project' + c.reset);
1079
+ console.log();
1080
+
1081
+ const cwd = process.cwd();
1082
+ let steps = 0;
1083
+
1084
+ // Step 1: Shield (hooks + stack detection + settings)
1085
+ console.log(c.bold + ' Step 1: Safety hooks' + c.reset);
1086
+ await shield();
1087
+ steps++;
1088
+
1089
+ // Step 2: .gitignore — add .claude/settings.local.json
1090
+ console.log(c.bold + ' Step 2: .gitignore' + c.reset);
1091
+ const gitignorePath = join(cwd, '.gitignore');
1092
+ if (existsSync(gitignorePath)) {
1093
+ const gi = readFileSync(gitignorePath, 'utf-8');
1094
+ const additions = [];
1095
+ if (!gi.includes('.claude/settings.local.json')) additions.push('.claude/settings.local.json');
1096
+ if (!gi.includes('.env')) additions.push('.env');
1097
+ if (!gi.includes('.env.local')) additions.push('.env.local');
1098
+ if (additions.length > 0) {
1099
+ writeFileSync(gitignorePath, gi.trimEnd() + '\n\n# Claude Code\n' + additions.join('\n') + '\n');
1100
+ console.log(c.green + ` +` + c.reset + ` Added ${additions.length} entries to .gitignore`);
1101
+ } else {
1102
+ console.log(c.dim + ' ✓ .gitignore already configured' + c.reset);
1103
+ }
1104
+ } else {
1105
+ writeFileSync(gitignorePath, '# Claude Code\n.claude/settings.local.json\n.env\n.env.local\nnode_modules/\n');
1106
+ console.log(c.green + ' +' + c.reset + ' Created .gitignore');
1107
+ }
1108
+ steps++;
1109
+ console.log();
1110
+
1111
+ // Step 3: Generate CI workflow
1112
+ console.log(c.bold + ' Step 3: CI workflow' + c.reset);
1113
+ const ciPath = join(cwd, '.github', 'workflows', 'claude-code-safety.yml');
1114
+ if (!existsSync(ciPath)) {
1115
+ generateCI();
1116
+ } else {
1117
+ console.log(c.dim + ' ✓ CI workflow already exists' + c.reset);
1118
+ }
1119
+ steps++;
1120
+ console.log();
1121
+
1122
+ // Step 4: Risk analysis
1123
+ console.log(c.bold + ' Step 4: Risk analysis' + c.reset);
1124
+ await suggest();
1125
+ steps++;
1126
+
1127
+ // Summary
1128
+ console.log();
1129
+ console.log(c.bold + c.green + ' ✓ Project initialized!' + c.reset);
1130
+ console.log(c.dim + ` ${steps} steps completed.` + c.reset);
1131
+ console.log();
1132
+ console.log(c.dim + ' Next: git add .claude/ CLAUDE.md .github/ .gitignore' + c.reset);
1133
+ console.log(c.dim + ' Then: git commit -m "chore: initialize Claude Code safety"' + c.reset);
1134
+ console.log();
1135
+ }
1136
+
1073
1137
  async function suggest() {
1074
1138
  const { execSync } = await import('child_process');
1075
1139
  const { readdirSync } = await import('fs');
@@ -4434,6 +4498,7 @@ async function main() {
4434
4498
  if (WATCH) return watch();
4435
4499
  if (TEST_HOOK_IDX !== -1) return testHook(TEST_HOOK);
4436
4500
  if (SAVE_PROFILE_IDX !== -1) return saveProfile(SAVE_PROFILE);
4501
+ if (INIT_PROJECT) return initProject();
4437
4502
  if (SUGGEST) return suggest();
4438
4503
  if (WHY_IDX !== -1) return why(WHY_HOOK);
4439
4504
  if (REPLAY) return replay();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cc-safe-setup",
3
- "version": "12.7.0",
3
+ "version": "13.1.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": {