cc-safe-setup 1.2.1 → 1.3.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/index.mjs +59 -0
- package/package.json +2 -2
package/index.mjs
CHANGED
|
@@ -59,6 +59,7 @@ const HOOKS = {
|
|
|
59
59
|
|
|
60
60
|
const HELP = process.argv.includes('--help') || process.argv.includes('-h');
|
|
61
61
|
const STATUS = process.argv.includes('--status') || process.argv.includes('-s');
|
|
62
|
+
const VERIFY = process.argv.includes('--verify') || process.argv.includes('-v');
|
|
62
63
|
|
|
63
64
|
if (HELP) {
|
|
64
65
|
console.log(`
|
|
@@ -67,6 +68,7 @@ if (HELP) {
|
|
|
67
68
|
Usage:
|
|
68
69
|
npx cc-safe-setup Install 7 safety hooks
|
|
69
70
|
npx cc-safe-setup --status Check installed hooks
|
|
71
|
+
npx cc-safe-setup --verify Test each hook with sample inputs
|
|
70
72
|
npx cc-safe-setup --dry-run Preview without installing
|
|
71
73
|
npx cc-safe-setup --uninstall Remove all installed hooks
|
|
72
74
|
npx cc-safe-setup --help Show this help
|
|
@@ -174,10 +176,67 @@ function status() {
|
|
|
174
176
|
console.log(' ' + c.dim + 'Run: npx cc-safe-setup' + c.reset);
|
|
175
177
|
}
|
|
176
178
|
console.log();
|
|
179
|
+
|
|
180
|
+
// Exit code for CI: 0 = all installed, 1 = missing hooks
|
|
181
|
+
if (missing > 0) process.exit(1);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
async function verify() {
|
|
185
|
+
const { execSync } = await import('child_process');
|
|
186
|
+
console.log();
|
|
187
|
+
console.log(c.bold + ' cc-safe-setup --verify' + c.reset);
|
|
188
|
+
console.log(c.dim + ' Testing each hook with sample inputs...' + c.reset);
|
|
189
|
+
console.log();
|
|
190
|
+
|
|
191
|
+
const tests = [
|
|
192
|
+
{ hook: 'destructive-guard', input: '{"tool_input":{"command":"rm -rf /"}}', expect: 2, desc: 'blocks rm -rf /' },
|
|
193
|
+
{ hook: 'destructive-guard', input: '{"tool_input":{"command":"ls -la"}}', expect: 0, desc: 'allows safe commands' },
|
|
194
|
+
{ hook: 'branch-guard', input: '{"tool_input":{"command":"git push origin main"}}', expect: 2, desc: 'blocks push to main' },
|
|
195
|
+
{ hook: 'branch-guard', input: '{"tool_input":{"command":"git push origin feature"}}', expect: 0, desc: 'allows push to feature' },
|
|
196
|
+
{ hook: 'secret-guard', input: '{"tool_input":{"command":"git add .env"}}', expect: 2, desc: 'blocks git add .env' },
|
|
197
|
+
{ hook: 'secret-guard', input: '{"tool_input":{"command":"git add src/app.js"}}', expect: 0, desc: 'allows git add safe files' },
|
|
198
|
+
];
|
|
199
|
+
|
|
200
|
+
let pass = 0, fail = 0;
|
|
201
|
+
for (const t of tests) {
|
|
202
|
+
const hookPath = join(HOOKS_DIR, t.hook + '.sh');
|
|
203
|
+
if (!existsSync(hookPath)) {
|
|
204
|
+
console.log(' ' + c.red + '✗' + c.reset + ' ' + t.hook + ': ' + t.desc + c.dim + ' (not installed)' + c.reset);
|
|
205
|
+
fail++;
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
try {
|
|
209
|
+
execSync(`echo '${t.input}' | bash "${hookPath}"`, { stdio: 'pipe' });
|
|
210
|
+
if (t.expect === 0) {
|
|
211
|
+
console.log(' ' + c.green + '✓' + c.reset + ' ' + t.hook + ': ' + t.desc);
|
|
212
|
+
pass++;
|
|
213
|
+
} else {
|
|
214
|
+
console.log(' ' + c.red + '✗' + c.reset + ' ' + t.hook + ': ' + t.desc + ' (should have blocked)');
|
|
215
|
+
fail++;
|
|
216
|
+
}
|
|
217
|
+
} catch(e) {
|
|
218
|
+
if (e.status === t.expect) {
|
|
219
|
+
console.log(' ' + c.green + '✓' + c.reset + ' ' + t.hook + ': ' + t.desc);
|
|
220
|
+
pass++;
|
|
221
|
+
} else {
|
|
222
|
+
console.log(' ' + c.red + '✗' + c.reset + ' ' + t.hook + ': ' + t.desc + ' (exit ' + e.status + ', expected ' + t.expect + ')');
|
|
223
|
+
fail++;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
console.log();
|
|
229
|
+
console.log(c.bold + ' ' + pass + '/' + (pass + fail) + ' tests passed.' + c.reset);
|
|
230
|
+
if (fail > 0) {
|
|
231
|
+
console.log(' ' + c.red + fail + ' failures.' + c.reset + ' Run ' + c.blue + 'npx cc-safe-setup' + c.reset + ' to reinstall.');
|
|
232
|
+
process.exit(1);
|
|
233
|
+
}
|
|
234
|
+
console.log();
|
|
177
235
|
}
|
|
178
236
|
|
|
179
237
|
async function main() {
|
|
180
238
|
if (UNINSTALL) return uninstall();
|
|
239
|
+
if (VERIFY) return verify();
|
|
181
240
|
if (STATUS) return status();
|
|
182
241
|
|
|
183
242
|
console.log();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cc-safe-setup",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "One command to make Claude Code safe for autonomous operation. 7 hooks: destructive blocker, branch guard, force-push protection, secret leak prevention, syntax checks, and more.",
|
|
5
5
|
"main": "index.mjs",
|
|
6
6
|
"bin": {
|
|
@@ -34,4 +34,4 @@
|
|
|
34
34
|
"url": "https://github.com/yurukusa/cc-safe-setup"
|
|
35
35
|
},
|
|
36
36
|
"homepage": "https://github.com/yurukusa/cc-safe-setup"
|
|
37
|
-
}
|
|
37
|
+
}
|