cc-hook-registry 3.1.0 → 4.0.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 +91 -0
- package/package.json +2 -2
- package/test.sh +34 -0
package/index.mjs
CHANGED
|
@@ -113,6 +113,8 @@ if (!command || command === '--help' || command === '-h') {
|
|
|
113
113
|
install <id> Install a hook
|
|
114
114
|
info <id> Show hook details
|
|
115
115
|
recommend Recommend hooks for current project
|
|
116
|
+
update [id] Update one or all installed hooks
|
|
117
|
+
uninstall <id> Remove an installed hook
|
|
116
118
|
outdated Check installed hooks for updates
|
|
117
119
|
stats Registry statistics
|
|
118
120
|
|
|
@@ -368,6 +370,95 @@ else if (command === 'recommend') {
|
|
|
368
370
|
console.log();
|
|
369
371
|
}
|
|
370
372
|
|
|
373
|
+
else if (command === 'update') {
|
|
374
|
+
const targetId = args[1]; // Optional: update specific hook or all
|
|
375
|
+
console.log();
|
|
376
|
+
console.log(c.bold + ' Updating hooks...' + c.reset);
|
|
377
|
+
console.log();
|
|
378
|
+
|
|
379
|
+
if (!existsSync(HOOKS_DIR)) {
|
|
380
|
+
console.log(c.dim + ' No hooks installed.' + c.reset);
|
|
381
|
+
process.exit(0);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
const { readdirSync } = await import('fs');
|
|
385
|
+
const installed = readdirSync(HOOKS_DIR).filter(f => f.endsWith('.sh'));
|
|
386
|
+
let updated = 0;
|
|
387
|
+
let skipped = 0;
|
|
388
|
+
|
|
389
|
+
for (const file of installed) {
|
|
390
|
+
const name = file.replace('.sh', '');
|
|
391
|
+
if (targetId && name !== targetId) continue;
|
|
392
|
+
|
|
393
|
+
const hook = REGISTRY.find(h => h.id === name);
|
|
394
|
+
if (!hook || !hook.install.includes('--install-example')) {
|
|
395
|
+
skipped++;
|
|
396
|
+
continue;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
const rawUrl = `https://raw.githubusercontent.com/yurukusa/cc-safe-setup/main/examples/${name}.sh`;
|
|
400
|
+
try {
|
|
401
|
+
const remote = execSync(`curl -sL "${rawUrl}" 2>/dev/null`, { encoding: 'utf-8', timeout: 5000 });
|
|
402
|
+
const local = readFileSync(join(HOOKS_DIR, file), 'utf-8');
|
|
403
|
+
|
|
404
|
+
if (remote.trim() !== local.trim() && remote.startsWith('#!/bin/bash')) {
|
|
405
|
+
writeFileSync(join(HOOKS_DIR, file), remote);
|
|
406
|
+
chmodSync(join(HOOKS_DIR, file), 0o755);
|
|
407
|
+
console.log(' ' + c.green + '↑' + c.reset + ' Updated: ' + name);
|
|
408
|
+
updated++;
|
|
409
|
+
} else {
|
|
410
|
+
skipped++;
|
|
411
|
+
}
|
|
412
|
+
} catch {
|
|
413
|
+
skipped++;
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
if (updated === 0) {
|
|
418
|
+
console.log(c.green + ' All hooks are up to date.' + c.reset);
|
|
419
|
+
} else {
|
|
420
|
+
console.log();
|
|
421
|
+
console.log(c.green + ' Updated ' + updated + ' hook(s).' + c.reset + ' Restart Claude Code.');
|
|
422
|
+
}
|
|
423
|
+
console.log();
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
else if (command === 'uninstall') {
|
|
427
|
+
const id = args[1];
|
|
428
|
+
if (!id) { console.log(c.red + ' Usage: cc-hook-registry uninstall <id>' + c.reset); process.exit(1); }
|
|
429
|
+
|
|
430
|
+
const hookPath = join(HOOKS_DIR, id + '.sh');
|
|
431
|
+
console.log();
|
|
432
|
+
|
|
433
|
+
if (!existsSync(hookPath)) {
|
|
434
|
+
console.log(c.red + ' Hook not installed: ' + id + c.reset);
|
|
435
|
+
process.exit(1);
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
// Remove script
|
|
439
|
+
const { unlinkSync } = await import('fs');
|
|
440
|
+
unlinkSync(hookPath);
|
|
441
|
+
console.log(c.green + ' ✓ Removed: ' + hookPath + c.reset);
|
|
442
|
+
|
|
443
|
+
// Remove from settings.json
|
|
444
|
+
if (existsSync(SETTINGS_PATH)) {
|
|
445
|
+
try {
|
|
446
|
+
const settings = JSON.parse(readFileSync(SETTINGS_PATH, 'utf-8'));
|
|
447
|
+
for (const trigger of Object.keys(settings.hooks || {})) {
|
|
448
|
+
settings.hooks[trigger] = settings.hooks[trigger].filter(entry =>
|
|
449
|
+
!(entry.hooks || []).some(h => (h.command || '').includes(id))
|
|
450
|
+
);
|
|
451
|
+
if (settings.hooks[trigger].length === 0) delete settings.hooks[trigger];
|
|
452
|
+
}
|
|
453
|
+
writeFileSync(SETTINGS_PATH, JSON.stringify(settings, null, 2));
|
|
454
|
+
console.log(c.green + ' ✓ Removed from settings.json' + c.reset);
|
|
455
|
+
} catch {}
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
console.log(c.dim + ' Restart Claude Code to take effect.' + c.reset);
|
|
459
|
+
console.log();
|
|
460
|
+
}
|
|
461
|
+
|
|
371
462
|
else if (command === 'outdated') {
|
|
372
463
|
console.log();
|
|
373
464
|
console.log(c.bold + ' Checking installed hooks for updates...' + c.reset);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cc-hook-registry",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "Search, browse, and install Claude Code hooks from the community. GitHub-based registry, no server needed.",
|
|
5
5
|
"main": "index.mjs",
|
|
6
6
|
"bin": {
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"cli"
|
|
16
16
|
],
|
|
17
17
|
"scripts": {
|
|
18
|
-
"test": "
|
|
18
|
+
"test": "bash test.sh"
|
|
19
19
|
},
|
|
20
20
|
"author": "yurukusa",
|
|
21
21
|
"license": "MIT",
|
package/test.sh
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# cc-hook-registry tests
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
PASS=0; FAIL=0
|
|
5
|
+
CLI="$(dirname "$0")/index.mjs"
|
|
6
|
+
|
|
7
|
+
test_cmd() {
|
|
8
|
+
local desc="$1" cmd="$2" expect="$3"
|
|
9
|
+
local out
|
|
10
|
+
out=$(eval "$cmd" 2>&1) || true
|
|
11
|
+
if echo "$out" | grep -q "$expect"; then
|
|
12
|
+
echo " PASS: $desc"; PASS=$((PASS+1))
|
|
13
|
+
else
|
|
14
|
+
echo " FAIL: $desc (expected '$expect')"; FAIL=$((FAIL+1))
|
|
15
|
+
fi
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
echo "--- cc-hook-registry tests ---"
|
|
19
|
+
|
|
20
|
+
test_cmd "--help" "node $CLI --help" "Commands"
|
|
21
|
+
test_cmd "search database" "node $CLI search database" "block-database-wipe"
|
|
22
|
+
test_cmd "search git" "node $CLI search git" "result"
|
|
23
|
+
test_cmd "search nonexistent" "node $CLI search zzzznotfound" "No hooks"
|
|
24
|
+
test_cmd "browse" "node $CLI browse" "hooks"
|
|
25
|
+
test_cmd "browse safety" "node $CLI browse safety" "Safety"
|
|
26
|
+
test_cmd "info destructive-guard" "node $CLI info destructive-guard" "Destructive"
|
|
27
|
+
test_cmd "info nonexistent" "node $CLI info notreal" "not found"
|
|
28
|
+
test_cmd "stats" "node $CLI stats" "Total hooks"
|
|
29
|
+
test_cmd "stats count" "node $CLI stats" "48"
|
|
30
|
+
|
|
31
|
+
echo ""
|
|
32
|
+
echo "Results: $PASS/$((PASS+FAIL)) passed"
|
|
33
|
+
[ "$FAIL" -gt 0 ] && exit 1
|
|
34
|
+
echo "All tests passed!"
|