cc-safe-setup 13.0.0 → 13.2.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/examples/relative-path-guard.sh +12 -0
- package/index.mjs +65 -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 + 124 examples = **
|
|
9
|
+
8 built-in + 124 examples = **138 hooks**. 43 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
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# relative-path-guard.sh — Warn on relative file paths in Edit/Write
|
|
3
|
+
# TRIGGER: PreToolUse MATCHER: "Edit|Write"
|
|
4
|
+
# Born from: https://github.com/anthropics/claude-code/issues/38270
|
|
5
|
+
FILE=$(cat | jq -r '.tool_input.file_path // empty' 2>/dev/null)
|
|
6
|
+
[ -z "$FILE" ] && exit 0
|
|
7
|
+
if [[ ! "$FILE" = /* ]]; then
|
|
8
|
+
ABS=$(realpath -m "$FILE" 2>/dev/null || echo "$PWD/$FILE")
|
|
9
|
+
echo "WARNING: Relative path: $FILE → $ABS" >&2
|
|
10
|
+
echo "Claude may be targeting the wrong file." >&2
|
|
11
|
+
fi
|
|
12
|
+
exit 0
|
package/index.mjs
CHANGED
|
@@ -111,6 +111,7 @@ const SAVE_PROFILE = SAVE_PROFILE_IDX !== -1 ? process.argv[SAVE_PROFILE_IDX + 1
|
|
|
111
111
|
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
|
+
const INIT_PROJECT = process.argv.includes('--init-project');
|
|
114
115
|
const TEST_HOOK_IDX = process.argv.findIndex(a => a === '--test-hook');
|
|
115
116
|
const TEST_HOOK = TEST_HOOK_IDX !== -1 ? process.argv[TEST_HOOK_IDX + 1] : null;
|
|
116
117
|
const WHY_IDX = process.argv.findIndex(a => a === '--why');
|
|
@@ -148,6 +149,7 @@ if (HELP) {
|
|
|
148
149
|
npx cc-safe-setup --create "<desc>" Generate a custom hook from description
|
|
149
150
|
npx cc-safe-setup --test-hook <name> Test a specific hook with sample inputs
|
|
150
151
|
npx cc-safe-setup --save-profile <name> Save current hooks as a named profile
|
|
152
|
+
npx cc-safe-setup --init-project Complete project setup (CLAUDE.md + hooks + CI + .gitignore)
|
|
151
153
|
npx cc-safe-setup --suggest Analyze project and predict risks → suggest hooks
|
|
152
154
|
npx cc-safe-setup --why <hook> Why this hook exists (real incident + issue link)
|
|
153
155
|
npx cc-safe-setup --replay Replay blocked commands timeline (demo/review)
|
|
@@ -1070,6 +1072,68 @@ async function saveProfile(name) {
|
|
|
1070
1072
|
console.log();
|
|
1071
1073
|
}
|
|
1072
1074
|
|
|
1075
|
+
async function initProject() {
|
|
1076
|
+
console.log();
|
|
1077
|
+
console.log(c.bold + ' cc-safe-setup --init-project' + c.reset);
|
|
1078
|
+
console.log(c.dim + ' Complete Claude Code setup for this project' + c.reset);
|
|
1079
|
+
console.log();
|
|
1080
|
+
|
|
1081
|
+
const cwd = process.cwd();
|
|
1082
|
+
let steps = 0;
|
|
1083
|
+
|
|
1084
|
+
// Step 1: Shield (hooks + stack detection + settings)
|
|
1085
|
+
console.log(c.bold + ' Step 1: Safety hooks' + c.reset);
|
|
1086
|
+
await shield();
|
|
1087
|
+
steps++;
|
|
1088
|
+
|
|
1089
|
+
// Step 2: .gitignore — add .claude/settings.local.json
|
|
1090
|
+
console.log(c.bold + ' Step 2: .gitignore' + c.reset);
|
|
1091
|
+
const gitignorePath = join(cwd, '.gitignore');
|
|
1092
|
+
if (existsSync(gitignorePath)) {
|
|
1093
|
+
const gi = readFileSync(gitignorePath, 'utf-8');
|
|
1094
|
+
const additions = [];
|
|
1095
|
+
if (!gi.includes('.claude/settings.local.json')) additions.push('.claude/settings.local.json');
|
|
1096
|
+
if (!gi.includes('.env')) additions.push('.env');
|
|
1097
|
+
if (!gi.includes('.env.local')) additions.push('.env.local');
|
|
1098
|
+
if (additions.length > 0) {
|
|
1099
|
+
writeFileSync(gitignorePath, gi.trimEnd() + '\n\n# Claude Code\n' + additions.join('\n') + '\n');
|
|
1100
|
+
console.log(c.green + ` +` + c.reset + ` Added ${additions.length} entries to .gitignore`);
|
|
1101
|
+
} else {
|
|
1102
|
+
console.log(c.dim + ' ✓ .gitignore already configured' + c.reset);
|
|
1103
|
+
}
|
|
1104
|
+
} else {
|
|
1105
|
+
writeFileSync(gitignorePath, '# Claude Code\n.claude/settings.local.json\n.env\n.env.local\nnode_modules/\n');
|
|
1106
|
+
console.log(c.green + ' +' + c.reset + ' Created .gitignore');
|
|
1107
|
+
}
|
|
1108
|
+
steps++;
|
|
1109
|
+
console.log();
|
|
1110
|
+
|
|
1111
|
+
// Step 3: Generate CI workflow
|
|
1112
|
+
console.log(c.bold + ' Step 3: CI workflow' + c.reset);
|
|
1113
|
+
const ciPath = join(cwd, '.github', 'workflows', 'claude-code-safety.yml');
|
|
1114
|
+
if (!existsSync(ciPath)) {
|
|
1115
|
+
generateCI();
|
|
1116
|
+
} else {
|
|
1117
|
+
console.log(c.dim + ' ✓ CI workflow already exists' + c.reset);
|
|
1118
|
+
}
|
|
1119
|
+
steps++;
|
|
1120
|
+
console.log();
|
|
1121
|
+
|
|
1122
|
+
// Step 4: Risk analysis
|
|
1123
|
+
console.log(c.bold + ' Step 4: Risk analysis' + c.reset);
|
|
1124
|
+
await suggest();
|
|
1125
|
+
steps++;
|
|
1126
|
+
|
|
1127
|
+
// Summary
|
|
1128
|
+
console.log();
|
|
1129
|
+
console.log(c.bold + c.green + ' ✓ Project initialized!' + c.reset);
|
|
1130
|
+
console.log(c.dim + ` ${steps} steps completed.` + c.reset);
|
|
1131
|
+
console.log();
|
|
1132
|
+
console.log(c.dim + ' Next: git add .claude/ CLAUDE.md .github/ .gitignore' + c.reset);
|
|
1133
|
+
console.log(c.dim + ' Then: git commit -m "chore: initialize Claude Code safety"' + c.reset);
|
|
1134
|
+
console.log();
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1073
1137
|
async function suggest() {
|
|
1074
1138
|
const { execSync } = await import('child_process');
|
|
1075
1139
|
const { readdirSync } = await import('fs');
|
|
@@ -4434,6 +4498,7 @@ async function main() {
|
|
|
4434
4498
|
if (WATCH) return watch();
|
|
4435
4499
|
if (TEST_HOOK_IDX !== -1) return testHook(TEST_HOOK);
|
|
4436
4500
|
if (SAVE_PROFILE_IDX !== -1) return saveProfile(SAVE_PROFILE);
|
|
4501
|
+
if (INIT_PROJECT) return initProject();
|
|
4437
4502
|
if (SUGGEST) return suggest();
|
|
4438
4503
|
if (WHY_IDX !== -1) return why(WHY_HOOK);
|
|
4439
4504
|
if (REPLAY) return replay();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cc-safe-setup",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.2.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": {
|