cc-safe-setup 8.3.0 → 8.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 +112 -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 + 92 examples = **100 hooks**.
|
|
9
|
+
8 built-in + 92 examples = **100 hooks**. 31 CLI commands. 433 tests. [Web Tool](https://yurukusa.github.io/cc-safe-setup/) · [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) · [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
|
@@ -92,6 +92,7 @@ const REPORT = process.argv.includes('--report');
|
|
|
92
92
|
const QUICKFIX = process.argv.includes('--quickfix');
|
|
93
93
|
const SHIELD = process.argv.includes('--shield');
|
|
94
94
|
const ANALYZE = process.argv.includes('--analyze');
|
|
95
|
+
const TEAM = process.argv.includes('--team');
|
|
95
96
|
const PROFILE_IDX = process.argv.findIndex(a => a === '--profile');
|
|
96
97
|
const PROFILE = PROFILE_IDX !== -1 ? process.argv[PROFILE_IDX + 1] : null;
|
|
97
98
|
const COMPARE_IDX = process.argv.findIndex(a => a === '--compare');
|
|
@@ -129,6 +130,7 @@ if (HELP) {
|
|
|
129
130
|
npx cc-safe-setup --doctor Diagnose why hooks aren't working
|
|
130
131
|
npx cc-safe-setup --watch Live dashboard of blocked commands
|
|
131
132
|
npx cc-safe-setup --create "<desc>" Generate a custom hook from description
|
|
133
|
+
npx cc-safe-setup --team Set up project-level hooks (commit to repo for team)
|
|
132
134
|
npx cc-safe-setup --profile <level> Switch safety profile (strict/standard/minimal)
|
|
133
135
|
npx cc-safe-setup --analyze Analyze what Claude did in your last session
|
|
134
136
|
npx cc-safe-setup --shield Maximum safety in one command (fix + scan + install + CLAUDE.md)
|
|
@@ -838,6 +840,115 @@ async function fullSetup() {
|
|
|
838
840
|
console.log();
|
|
839
841
|
}
|
|
840
842
|
|
|
843
|
+
async function team() {
|
|
844
|
+
console.log();
|
|
845
|
+
console.log(c.bold + ' cc-safe-setup --team' + c.reset);
|
|
846
|
+
console.log(c.dim + ' Set up project-level hooks (commit to repo for team sharing)' + c.reset);
|
|
847
|
+
console.log();
|
|
848
|
+
|
|
849
|
+
const cwd = process.cwd();
|
|
850
|
+
const projectHooksDir = join(cwd, '.claude', 'hooks');
|
|
851
|
+
const projectSettings = join(cwd, '.claude', 'settings.local.json');
|
|
852
|
+
|
|
853
|
+
// Create .claude/hooks/ in project
|
|
854
|
+
mkdirSync(projectHooksDir, { recursive: true });
|
|
855
|
+
|
|
856
|
+
// Copy core safety hooks to project
|
|
857
|
+
const coreHooks = ['destructive-guard', 'branch-guard', 'secret-guard', 'syntax-check',
|
|
858
|
+
'context-monitor', 'comment-strip', 'cd-git-allow', 'api-error-alert'];
|
|
859
|
+
|
|
860
|
+
let installed = 0;
|
|
861
|
+
for (const hookId of coreHooks) {
|
|
862
|
+
const destPath = join(projectHooksDir, `${hookId}.sh`);
|
|
863
|
+
if (existsSync(destPath)) {
|
|
864
|
+
console.log(c.dim + ' ✓' + c.reset + ` ${hookId}`);
|
|
865
|
+
continue;
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
if (SCRIPTS[hookId]) {
|
|
869
|
+
writeFileSync(destPath, SCRIPTS[hookId]);
|
|
870
|
+
chmodSync(destPath, 0o755);
|
|
871
|
+
installed++;
|
|
872
|
+
console.log(c.green + ' +' + c.reset + ` ${hookId}`);
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
// Detect stack and add relevant hooks
|
|
877
|
+
const extras = [];
|
|
878
|
+
if (existsSync(join(cwd, 'package.json'))) extras.push('auto-approve-build');
|
|
879
|
+
if (existsSync(join(cwd, 'requirements.txt')) || existsSync(join(cwd, 'pyproject.toml'))) extras.push('auto-approve-python');
|
|
880
|
+
if (existsSync(join(cwd, 'go.mod'))) extras.push('auto-approve-go');
|
|
881
|
+
if (existsSync(join(cwd, 'Cargo.toml'))) extras.push('auto-approve-cargo');
|
|
882
|
+
if (existsSync(join(cwd, 'Dockerfile'))) extras.push('auto-approve-docker');
|
|
883
|
+
|
|
884
|
+
for (const ex of extras) {
|
|
885
|
+
const destPath = join(projectHooksDir, `${ex}.sh`);
|
|
886
|
+
const srcPath = join(__dirname, 'examples', `${ex}.sh`);
|
|
887
|
+
if (existsSync(destPath)) continue;
|
|
888
|
+
if (existsSync(srcPath)) {
|
|
889
|
+
copyFileSync(srcPath, destPath);
|
|
890
|
+
chmodSync(destPath, 0o755);
|
|
891
|
+
installed++;
|
|
892
|
+
console.log(c.green + ' +' + c.reset + ` ${ex} (project-specific)`);
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
// Generate settings.local.json
|
|
897
|
+
const allHooks = [...coreHooks, ...extras].filter(h => existsSync(join(projectHooksDir, `${h}.sh`)));
|
|
898
|
+
|
|
899
|
+
const bashHooks = allHooks.map(h => ({
|
|
900
|
+
type: 'command',
|
|
901
|
+
command: `bash .claude/hooks/${h}.sh`
|
|
902
|
+
}));
|
|
903
|
+
|
|
904
|
+
const settings = {
|
|
905
|
+
hooks: {
|
|
906
|
+
PreToolUse: [
|
|
907
|
+
{ matcher: 'Bash', hooks: bashHooks.filter((_, i) => {
|
|
908
|
+
const name = allHooks[i];
|
|
909
|
+
return !['syntax-check', 'context-monitor', 'api-error-alert'].includes(name);
|
|
910
|
+
})},
|
|
911
|
+
{ matcher: 'Edit|Write', hooks: [
|
|
912
|
+
{ type: 'command', command: 'bash .claude/hooks/syntax-check.sh' }
|
|
913
|
+
]}
|
|
914
|
+
],
|
|
915
|
+
PostToolUse: [
|
|
916
|
+
{ matcher: '', hooks: [
|
|
917
|
+
{ type: 'command', command: 'bash .claude/hooks/context-monitor.sh' }
|
|
918
|
+
]}
|
|
919
|
+
],
|
|
920
|
+
Stop: [
|
|
921
|
+
{ matcher: '', hooks: [
|
|
922
|
+
{ type: 'command', command: 'bash .claude/hooks/api-error-alert.sh' }
|
|
923
|
+
]}
|
|
924
|
+
]
|
|
925
|
+
}
|
|
926
|
+
};
|
|
927
|
+
|
|
928
|
+
writeFileSync(projectSettings, JSON.stringify(settings, null, 2));
|
|
929
|
+
console.log();
|
|
930
|
+
console.log(c.green + ' ✓' + c.reset + ' Created .claude/settings.local.json');
|
|
931
|
+
|
|
932
|
+
// Add .claude/hooks to .gitignore if not there
|
|
933
|
+
const gitignorePath = join(cwd, '.gitignore');
|
|
934
|
+
if (existsSync(gitignorePath)) {
|
|
935
|
+
const gi = readFileSync(gitignorePath, 'utf-8');
|
|
936
|
+
if (!gi.includes('.claude/')) {
|
|
937
|
+
// Don't add — hooks should be committed for team sharing
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
console.log();
|
|
942
|
+
console.log(c.bold + ' Next steps:' + c.reset);
|
|
943
|
+
console.log(c.dim + ' 1. git add .claude/' + c.reset);
|
|
944
|
+
console.log(c.dim + ' 2. git commit -m "chore: add Claude Code safety hooks"' + c.reset);
|
|
945
|
+
console.log(c.dim + ' 3. Team members get hooks automatically on git pull' + c.reset);
|
|
946
|
+
console.log();
|
|
947
|
+
console.log(c.dim + ` ${installed} hooks installed, ${allHooks.length} total configured.` + c.reset);
|
|
948
|
+
console.log(c.dim + ' Hooks use relative paths (.claude/hooks/) — portable across machines.' + c.reset);
|
|
949
|
+
console.log();
|
|
950
|
+
}
|
|
951
|
+
|
|
841
952
|
async function profile(level) {
|
|
842
953
|
const { readdirSync } = await import('fs');
|
|
843
954
|
console.log();
|
|
@@ -3270,6 +3381,7 @@ async function main() {
|
|
|
3270
3381
|
if (FULL) return fullSetup();
|
|
3271
3382
|
if (DOCTOR) return doctor();
|
|
3272
3383
|
if (WATCH) return watch();
|
|
3384
|
+
if (TEAM) return team();
|
|
3273
3385
|
if (PROFILE_IDX !== -1) return profile(PROFILE);
|
|
3274
3386
|
if (ANALYZE) return analyze();
|
|
3275
3387
|
if (SHIELD) return shield();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cc-safe-setup",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.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": {
|