cc-safe-setup 13.2.0 → 13.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 +1 -1
- package/index.mjs +63 -2
- package/package.json +1 -1
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 = **138 hooks**.
|
|
9
|
+
8 built-in + 124 examples = **138 hooks**. 44 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
|
package/index.mjs
CHANGED
|
@@ -112,6 +112,7 @@ 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
114
|
const INIT_PROJECT = process.argv.includes('--init-project');
|
|
115
|
+
const SCORE_ONLY = process.argv.includes('--score');
|
|
115
116
|
const TEST_HOOK_IDX = process.argv.findIndex(a => a === '--test-hook');
|
|
116
117
|
const TEST_HOOK = TEST_HOOK_IDX !== -1 ? process.argv[TEST_HOOK_IDX + 1] : null;
|
|
117
118
|
const WHY_IDX = process.argv.findIndex(a => a === '--why');
|
|
@@ -149,6 +150,7 @@ if (HELP) {
|
|
|
149
150
|
npx cc-safe-setup --create "<desc>" Generate a custom hook from description
|
|
150
151
|
npx cc-safe-setup --test-hook <name> Test a specific hook with sample inputs
|
|
151
152
|
npx cc-safe-setup --save-profile <name> Save current hooks as a named profile
|
|
153
|
+
npx cc-safe-setup --score Print safety score (0-100) and exit
|
|
152
154
|
npx cc-safe-setup --init-project Complete project setup (CLAUDE.md + hooks + CI + .gitignore)
|
|
153
155
|
npx cc-safe-setup --suggest Analyze project and predict risks → suggest hooks
|
|
154
156
|
npx cc-safe-setup --why <hook> Why this hook exists (real incident + issue link)
|
|
@@ -537,8 +539,28 @@ function examples() {
|
|
|
537
539
|
console.log();
|
|
538
540
|
}
|
|
539
541
|
|
|
540
|
-
|
|
541
|
-
|
|
542
|
+
// Show batch install command if filtered
|
|
543
|
+
const allFiltered = [];
|
|
544
|
+
for (const [cat, hooks] of Object.entries(CATEGORIES)) {
|
|
545
|
+
const fh = filter
|
|
546
|
+
? Object.entries(hooks).filter(([file, desc]) =>
|
|
547
|
+
cat.toLowerCase().includes(filter) ||
|
|
548
|
+
file.toLowerCase().includes(filter) ||
|
|
549
|
+
desc.toLowerCase().includes(filter))
|
|
550
|
+
: Object.entries(hooks);
|
|
551
|
+
for (const [file] of fh) allFiltered.push(file.replace('.sh', ''));
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
if (filter && allFiltered.length > 0 && allFiltered.length <= 20) {
|
|
555
|
+
console.log(c.dim + ' Install all filtered hooks:' + c.reset);
|
|
556
|
+
for (const h of allFiltered) {
|
|
557
|
+
console.log(c.dim + ` npx cc-safe-setup --install-example ${h}` + c.reset);
|
|
558
|
+
}
|
|
559
|
+
console.log();
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
console.log(c.dim + ' Or install any single hook:' + c.reset);
|
|
563
|
+
console.log(c.dim + ' npx cc-safe-setup --install-example <name>' + c.reset);
|
|
542
564
|
console.log(c.dim + ' Source: ' + c.blue + 'https://github.com/yurukusa/cc-safe-setup/tree/main/examples' + c.reset);
|
|
543
565
|
console.log();
|
|
544
566
|
}
|
|
@@ -1072,6 +1094,44 @@ async function saveProfile(name) {
|
|
|
1072
1094
|
console.log();
|
|
1073
1095
|
}
|
|
1074
1096
|
|
|
1097
|
+
async function scoreOnly() {
|
|
1098
|
+
const { readdirSync } = await import('fs');
|
|
1099
|
+
let score = 0;
|
|
1100
|
+
|
|
1101
|
+
// Hooks installed (max 50 points)
|
|
1102
|
+
const hookDir = join(HOME, '.claude', 'hooks');
|
|
1103
|
+
const hookCount = existsSync(hookDir) ? readdirSync(hookDir).filter(f => f.endsWith('.sh') || f.endsWith('.py')).length : 0;
|
|
1104
|
+
score += Math.min(hookCount * 3, 50);
|
|
1105
|
+
|
|
1106
|
+
// Critical hooks (max 20 points)
|
|
1107
|
+
const critical = ['destructive-guard', 'branch-guard', 'secret-guard'];
|
|
1108
|
+
if (existsSync(SETTINGS_PATH)) {
|
|
1109
|
+
try {
|
|
1110
|
+
const s = JSON.parse(readFileSync(SETTINGS_PATH, 'utf-8'));
|
|
1111
|
+
const cmds = JSON.stringify(s.hooks || {});
|
|
1112
|
+
for (const h of critical) {
|
|
1113
|
+
if (cmds.includes(h)) score += 7;
|
|
1114
|
+
}
|
|
1115
|
+
} catch {}
|
|
1116
|
+
}
|
|
1117
|
+
|
|
1118
|
+
// CLAUDE.md exists (10 points)
|
|
1119
|
+
if (existsSync(join(process.cwd(), 'CLAUDE.md'))) score += 10;
|
|
1120
|
+
|
|
1121
|
+
// .gitignore has .env (10 points)
|
|
1122
|
+
const gi = existsSync(join(process.cwd(), '.gitignore')) ? readFileSync(join(process.cwd(), '.gitignore'), 'utf-8') : '';
|
|
1123
|
+
if (gi.includes('.env')) score += 10;
|
|
1124
|
+
|
|
1125
|
+
// CI workflow (10 points)
|
|
1126
|
+
if (existsSync(join(process.cwd(), '.github', 'workflows', 'claude-code-safety.yml'))) score += 10;
|
|
1127
|
+
|
|
1128
|
+
score = Math.min(score, 100);
|
|
1129
|
+
|
|
1130
|
+
// Output just the score for piping
|
|
1131
|
+
console.log(score);
|
|
1132
|
+
process.exit(score >= 70 ? 0 : 1);
|
|
1133
|
+
}
|
|
1134
|
+
|
|
1075
1135
|
async function initProject() {
|
|
1076
1136
|
console.log();
|
|
1077
1137
|
console.log(c.bold + ' cc-safe-setup --init-project' + c.reset);
|
|
@@ -4498,6 +4558,7 @@ async function main() {
|
|
|
4498
4558
|
if (WATCH) return watch();
|
|
4499
4559
|
if (TEST_HOOK_IDX !== -1) return testHook(TEST_HOOK);
|
|
4500
4560
|
if (SAVE_PROFILE_IDX !== -1) return saveProfile(SAVE_PROFILE);
|
|
4561
|
+
if (SCORE_ONLY) return scoreOnly();
|
|
4501
4562
|
if (INIT_PROJECT) return initProject();
|
|
4502
4563
|
if (SUGGEST) return suggest();
|
|
4503
4564
|
if (WHY_IDX !== -1) return why(WHY_HOOK);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cc-safe-setup",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.4.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": {
|