cc-safe-setup 10.8.0 → 10.9.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 +68 -0
- 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 + 104 examples = **118 hooks**.
|
|
9
|
+
8 built-in + 104 examples = **118 hooks**. 39 CLI commands. 531 tests. 5 languages. [**Hub**](https://yurukusa.github.io/cc-safe-setup/hub.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
|
@@ -108,6 +108,8 @@ const COMPARE = COMPARE_IDX !== -1 ? { a: process.argv[COMPARE_IDX + 1], b: proc
|
|
|
108
108
|
const REPLAY = process.argv.includes('--replay');
|
|
109
109
|
const CREATE_IDX = process.argv.findIndex(a => a === '--create');
|
|
110
110
|
const CREATE_DESC = CREATE_IDX !== -1 ? process.argv.slice(CREATE_IDX + 1).join(' ') : null;
|
|
111
|
+
const WHY_IDX = process.argv.findIndex(a => a === '--why');
|
|
112
|
+
const WHY_HOOK = WHY_IDX !== -1 ? process.argv[WHY_IDX + 1] : null;
|
|
111
113
|
|
|
112
114
|
if (HELP) {
|
|
113
115
|
console.log(`
|
|
@@ -139,6 +141,7 @@ if (HELP) {
|
|
|
139
141
|
npx cc-safe-setup --doctor Diagnose why hooks aren't working
|
|
140
142
|
npx cc-safe-setup --watch Live dashboard of blocked commands
|
|
141
143
|
npx cc-safe-setup --create "<desc>" Generate a custom hook from description
|
|
144
|
+
npx cc-safe-setup --why <hook> Why this hook exists (real incident + issue link)
|
|
142
145
|
npx cc-safe-setup --replay Replay blocked commands timeline (demo/review)
|
|
143
146
|
npx cc-safe-setup --guard "<rule>" Instantly enforce a rule (generate + install + activate)
|
|
144
147
|
npx cc-safe-setup --diff-hooks <path> Compare hooks between two settings files
|
|
@@ -922,6 +925,70 @@ async function fullSetup() {
|
|
|
922
925
|
console.log();
|
|
923
926
|
}
|
|
924
927
|
|
|
928
|
+
async function why(hookName) {
|
|
929
|
+
const WHY_DATA = {
|
|
930
|
+
'destructive-guard': { issue: '#36339', incident: 'User lost entire C:\\Users directory — rm -rf followed NTFS junctions', url: 'https://github.com/anthropics/claude-code/issues/36339' },
|
|
931
|
+
'branch-guard': { issue: '#36640', incident: 'Autonomous Claude pushed untested code to main at 3am', url: 'https://github.com/anthropics/claude-code/issues/36640' },
|
|
932
|
+
'secret-guard': { issue: '#16561', incident: 'API keys committed to public repo via git add .', url: 'https://github.com/anthropics/claude-code/issues/16561' },
|
|
933
|
+
'block-database-wipe': { issue: '#37405', incident: 'Production database wiped by migrate:fresh', url: 'https://github.com/anthropics/claude-code/issues/37405' },
|
|
934
|
+
'uncommitted-work-guard': { issue: '#37888', incident: 'Claude destroyed uncommitted work twice in same session', url: 'https://github.com/anthropics/claude-code/issues/37888' },
|
|
935
|
+
'test-deletion-guard': { issue: '#38050', incident: 'Claude deleted failing tests instead of fixing code', url: 'https://github.com/anthropics/claude-code/issues/38050' },
|
|
936
|
+
'fact-check-gate': { issue: '#38057', incident: 'Claude wrote false claims in technical docs without reading source', url: 'https://github.com/anthropics/claude-code/issues/38057' },
|
|
937
|
+
'token-budget-guard': { issue: '#38029', incident: 'Session consumed $342 in tokens without user knowing', url: 'https://github.com/anthropics/claude-code/issues/38029' },
|
|
938
|
+
'protect-dotfiles': { issue: '#37478', incident: '.bashrc and environment files overwritten', url: 'https://github.com/anthropics/claude-code/issues/37478' },
|
|
939
|
+
'scope-guard': { issue: '#36233', incident: 'Entire Mac filesystem deleted by out-of-scope operation', url: 'https://github.com/anthropics/claude-code/issues/36233' },
|
|
940
|
+
'case-sensitive-guard': { issue: '#37875', incident: 'exFAT case collision caused data loss via rm -rf', url: 'https://github.com/anthropics/claude-code/issues/37875' },
|
|
941
|
+
'prompt-injection-guard': { issue: '#38046', incident: 'Prompt injection found in /insights output', url: 'https://github.com/anthropics/claude-code/issues/38046' },
|
|
942
|
+
'overwrite-guard': { issue: '#37595', incident: '/export overwrites existing files without warning', url: 'https://github.com/anthropics/claude-code/issues/37595' },
|
|
943
|
+
'memory-write-guard': { issue: '#38040', incident: 'No way to see what Claude writes to ~/.claude/', url: 'https://github.com/anthropics/claude-code/issues/38040' },
|
|
944
|
+
'context-monitor': { issue: '#6527', incident: 'Sessions silently lost all state after 150+ tool calls', url: 'https://github.com/anthropics/claude-code/issues/6527' },
|
|
945
|
+
'comment-strip': { issue: '#29582', incident: 'Bash comments in hook commands broke permission matching', url: 'https://github.com/anthropics/claude-code/issues/29582' },
|
|
946
|
+
'cd-git-allow': { issue: '#32985', incident: 'cd+git compounds spammed permission prompts endlessly', url: 'https://github.com/anthropics/claude-code/issues/32985' },
|
|
947
|
+
'strict-allowlist': { issue: '#37471', incident: 'Denylist model creates arms race — Claude finds bypasses', url: 'https://github.com/anthropics/claude-code/issues/37471' },
|
|
948
|
+
'error-memory-guard': { issue: 'common', incident: 'Claude retries the same failing command 10+ times' },
|
|
949
|
+
'typosquat-guard': { issue: 'supply-chain', incident: 'Misspelled package names can install malware' },
|
|
950
|
+
};
|
|
951
|
+
|
|
952
|
+
console.log();
|
|
953
|
+
if (!hookName) {
|
|
954
|
+
console.log(c.bold + ' cc-safe-setup --why <hook-name>' + c.reset);
|
|
955
|
+
console.log(c.dim + ' Show why a hook exists — the real incident that inspired it.' + c.reset);
|
|
956
|
+
console.log();
|
|
957
|
+
console.log(' Examples:');
|
|
958
|
+
console.log(c.dim + ' npx cc-safe-setup --why destructive-guard' + c.reset);
|
|
959
|
+
console.log(c.dim + ' npx cc-safe-setup --why token-budget-guard' + c.reset);
|
|
960
|
+
console.log();
|
|
961
|
+
console.log(` ${Object.keys(WHY_DATA).length} hooks have documented incidents.`);
|
|
962
|
+
return;
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
const name = hookName.replace('.sh', '');
|
|
966
|
+
const data = WHY_DATA[name];
|
|
967
|
+
if (!data) {
|
|
968
|
+
console.log(c.yellow + ` No incident documented for "${name}".` + c.reset);
|
|
969
|
+
console.log(c.dim + ' This hook may have been created proactively.' + c.reset);
|
|
970
|
+
console.log();
|
|
971
|
+
console.log(c.dim + ` Hooks with documented incidents: ${Object.keys(WHY_DATA).join(', ')}` + c.reset);
|
|
972
|
+
return;
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
console.log(c.bold + ` Why "${name}" exists` + c.reset);
|
|
976
|
+
console.log();
|
|
977
|
+
console.log(c.red + ' Incident:' + c.reset);
|
|
978
|
+
console.log(' ' + data.incident);
|
|
979
|
+
console.log();
|
|
980
|
+
if (data.url) {
|
|
981
|
+
console.log(c.blue + ' Source:' + c.reset);
|
|
982
|
+
console.log(' ' + data.url);
|
|
983
|
+
}
|
|
984
|
+
if (data.issue && data.issue !== 'common' && data.issue !== 'supply-chain') {
|
|
985
|
+
console.log(c.dim + ` GitHub Issue: ${data.issue}` + c.reset);
|
|
986
|
+
}
|
|
987
|
+
console.log();
|
|
988
|
+
console.log(c.dim + ' Install: npx cc-safe-setup --install-example ' + name + c.reset);
|
|
989
|
+
console.log();
|
|
990
|
+
}
|
|
991
|
+
|
|
925
992
|
async function replay() {
|
|
926
993
|
console.log();
|
|
927
994
|
console.log(c.bold + ' cc-safe-setup --replay' + c.reset);
|
|
@@ -4051,6 +4118,7 @@ async function main() {
|
|
|
4051
4118
|
if (FULL) return fullSetup();
|
|
4052
4119
|
if (DOCTOR) return doctor();
|
|
4053
4120
|
if (WATCH) return watch();
|
|
4121
|
+
if (WHY_IDX !== -1) return why(WHY_HOOK);
|
|
4054
4122
|
if (REPLAY) return replay();
|
|
4055
4123
|
if (GUARD_IDX !== -1) return guard(GUARD_DESC);
|
|
4056
4124
|
if (DIFF_HOOKS_IDX !== -1) return diffHooks(DIFF_HOOKS);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cc-safe-setup",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "10.9.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": {
|