cc-safe-setup 11.6.0 → 11.8.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 +15 -1
- package/index.mjs +29 -0
- package/package.json +1 -1
- package/.claude/session-snapshot.md +0 -25
- package/cc-safe-setup-export.json +0 -321
- package/docs/README.ja.md +0 -64
- package/docs/ROADMAP.md +0 -83
- package/docs/builder.html +0 -283
- package/docs/by-example.html +0 -234
- package/docs/cheatsheet.html +0 -187
- package/docs/ecosystem.html +0 -223
- package/docs/faq.html +0 -244
- package/docs/hooks-cheatsheet.html +0 -319
- package/docs/hub.html +0 -155
- package/docs/index-legacy.html +0 -685
- package/docs/index.html +0 -271
- package/docs/matrix.html +0 -139
- package/docs/migration-guide.html +0 -198
- package/docs/settings-reference.html +0 -317
- package/docs/troubleshooting.html +0 -189
- package/examples/go/destructive_guard.go +0 -69
- package/examples/python/__pycache__/destructive_guard.cpython-312.pyc +0 -0
- package/examples/python/__pycache__/secret_guard.cpython-312.pyc +0 -0
- package/examples/rust/destructive_guard.rs +0 -72
- package/examples/typescript/destructive-guard.ts +0 -64
package/docs/index.html
DELETED
|
@@ -1,271 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<title>cc-safe-setup — Claude Code Safety Suite</title>
|
|
7
|
-
<meta name="description" content="Audit, build, browse, and learn Claude Code hooks. All in one page, 100% client-side.">
|
|
8
|
-
<style>
|
|
9
|
-
*{box-sizing:border-box;margin:0;padding:0}
|
|
10
|
-
body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;background:#0d1117;color:#c9d1d9;min-height:100vh}
|
|
11
|
-
.nav{display:flex;background:#161b22;border-bottom:1px solid #30363d;overflow-x:auto}
|
|
12
|
-
.nav a{padding:.75rem 1.2rem;color:#8b949e;text-decoration:none;font-size:.85rem;white-space:nowrap;border-bottom:2px solid transparent;cursor:pointer}
|
|
13
|
-
.nav a.active{color:#f0f6fc;border-bottom-color:#f78166}
|
|
14
|
-
.nav a:hover{color:#c9d1d9}
|
|
15
|
-
.page{display:none;max-width:800px;margin:0 auto;padding:1.5rem}
|
|
16
|
-
.page.active{display:block}
|
|
17
|
-
h1{font-size:1.3rem;color:#f0f6fc;margin-bottom:.5rem}
|
|
18
|
-
h2{font-size:1.1rem;color:#f0f6fc;margin:1.5rem 0 .5rem}
|
|
19
|
-
h3{font-size:.95rem;color:#c9d1d9;margin:1rem 0 .3rem}
|
|
20
|
-
p,.sub{color:#8b949e;font-size:.85rem;margin-bottom:.75rem}
|
|
21
|
-
a{color:#58a6ff;text-decoration:none}
|
|
22
|
-
textarea,input,select{width:100%;padding:.5rem;background:#161b22;border:1px solid #30363d;border-radius:4px;color:#c9d1d9;font-family:monospace;font-size:.8rem;margin:.25rem 0}
|
|
23
|
-
textarea{height:150px;resize:vertical}
|
|
24
|
-
button,.btn{background:#238636;color:#fff;border:none;padding:.5rem 1rem;border-radius:4px;cursor:pointer;font-size:.85rem;margin:.25rem .25rem .25rem 0}
|
|
25
|
-
button:hover,.btn:hover{background:#2ea043}
|
|
26
|
-
.btn-sm{padding:.25rem .5rem;font-size:.75rem}
|
|
27
|
-
.btn-secondary{background:#30363d}
|
|
28
|
-
pre{background:#161b22;border:1px solid #30363d;border-radius:4px;padding:.6rem;font-size:.75rem;overflow-x:auto;position:relative;margin:.3rem 0}
|
|
29
|
-
.copy{position:absolute;top:.3rem;right:.3rem;background:#30363d;color:#c9d1d9;border:none;padding:.15rem .4rem;border-radius:3px;font-size:.65rem;cursor:pointer}
|
|
30
|
-
.score{font-size:1.8rem;font-weight:bold;margin:.5rem 0}
|
|
31
|
-
.score.good{color:#3fb950} .score.mid{color:#d29922} .score.bad{color:#f85149}
|
|
32
|
-
.risk{background:#161b22;border:1px solid #30363d;border-radius:4px;padding:.75rem;margin:.3rem 0;font-size:.8rem}
|
|
33
|
-
.good-item{color:#3fb950;margin:.2rem 0;font-size:.8rem}
|
|
34
|
-
table{width:100%;border-collapse:collapse;font-size:.8rem;margin:.5rem 0}
|
|
35
|
-
th,td{text-align:left;padding:.35rem .5rem;border-bottom:1px solid #21262d}
|
|
36
|
-
th{font-weight:600;color:#f0f6fc}
|
|
37
|
-
.recipe{background:#161b22;border:1px solid #30363d;border-radius:4px;margin:.3rem 0;overflow:hidden}
|
|
38
|
-
.recipe summary{padding:.5rem .75rem;cursor:pointer;font-weight:600;color:#f0f6fc;font-size:.85rem}
|
|
39
|
-
.recipe-body{padding:0 .75rem .5rem}
|
|
40
|
-
.filter{padding:.2rem .5rem;border-radius:3px;border:1px solid #30363d;background:transparent;color:#8b949e;cursor:pointer;font-size:.7rem;margin:.15rem}
|
|
41
|
-
.filter.active{background:#238636;border-color:#238636;color:#fff}
|
|
42
|
-
.badge{display:inline-block;padding:.1rem .3rem;border-radius:3px;font-size:.65rem;font-weight:bold}
|
|
43
|
-
.badge-bash{background:#1f6feb22;color:#58a6ff;border:1px solid #1f6feb44}
|
|
44
|
-
.badge-js{background:#f0e68c22;color:#f0e68c;border:1px solid #f0e68c44}
|
|
45
|
-
.badge-py{background:#3fb95022;color:#3fb950;border:1px solid #3fb95044}
|
|
46
|
-
.badge-ts{background:#388bfd22;color:#388bfd;border:1px solid #388bfd44}
|
|
47
|
-
.check{color:#3fb950} .cross{color:#484f58}
|
|
48
|
-
.footer{text-align:center;color:#484f58;font-size:.7rem;padding:2rem 1rem}
|
|
49
|
-
@media print{.nav{display:none} .page{display:block!important}}
|
|
50
|
-
</style>
|
|
51
|
-
</head>
|
|
52
|
-
<body>
|
|
53
|
-
|
|
54
|
-
<nav class="nav">
|
|
55
|
-
<a onclick="go('audit')" id="nav-audit" class="active">Audit</a>
|
|
56
|
-
<a onclick="go('builder')" id="nav-builder">Hook Builder</a>
|
|
57
|
-
<a onclick="go('cookbook')" id="nav-cookbook">Cookbook</a>
|
|
58
|
-
<a onclick="go('ecosystem')" id="nav-ecosystem">Ecosystem</a>
|
|
59
|
-
<a onclick="go('cheatsheet')" id="nav-cheatsheet">Cheat Sheet</a>
|
|
60
|
-
</nav>
|
|
61
|
-
|
|
62
|
-
<!-- PAGE: AUDIT -->
|
|
63
|
-
<div class="page active" id="page-audit">
|
|
64
|
-
<h1>Safety Audit</h1>
|
|
65
|
-
<p>Paste your <code>~/.claude/settings.json</code>. Nothing leaves your browser.</p>
|
|
66
|
-
<textarea id="settings" placeholder='{"permissions":{"allow":["Bash(git:*)"]},"hooks":{"PreToolUse":[...]}}'></textarea>
|
|
67
|
-
<button onclick="runAudit()">Run Audit</button>
|
|
68
|
-
<button class="btn-secondary" onclick="generateFresh()">Generate Fresh Setup</button>
|
|
69
|
-
<div id="audit-results"></div>
|
|
70
|
-
</div>
|
|
71
|
-
|
|
72
|
-
<!-- PAGE: HOOK BUILDER -->
|
|
73
|
-
<div class="page" id="page-builder">
|
|
74
|
-
<h1>Hook Builder</h1>
|
|
75
|
-
<p>Build a custom hook without writing code.</p>
|
|
76
|
-
<div style="display:flex;gap:.75rem;flex-wrap:wrap">
|
|
77
|
-
<div style="flex:1;min-width:180px">
|
|
78
|
-
<label style="font-size:.75rem;color:#8b949e">Action</label>
|
|
79
|
-
<select id="hb-action"><option value="block">Block</option><option value="warn">Warn</option><option value="approve">Auto-approve</option></select>
|
|
80
|
-
</div>
|
|
81
|
-
<div style="flex:2;min-width:250px">
|
|
82
|
-
<label style="font-size:.75rem;color:#8b949e">Pattern (regex)</label>
|
|
83
|
-
<input id="hb-pattern" placeholder="e.g. rm\s+-rf, git push --force">
|
|
84
|
-
</div>
|
|
85
|
-
</div>
|
|
86
|
-
<label style="font-size:.75rem;color:#8b949e">Message</label>
|
|
87
|
-
<input id="hb-message" placeholder="e.g. Run tests before pushing">
|
|
88
|
-
<button onclick="buildHook()">Generate</button>
|
|
89
|
-
<div id="hb-result"></div>
|
|
90
|
-
</div>
|
|
91
|
-
|
|
92
|
-
<!-- PAGE: COOKBOOK -->
|
|
93
|
-
<div class="page" id="page-cookbook">
|
|
94
|
-
<h1>Hooks Cookbook</h1>
|
|
95
|
-
<p>Copy-paste recipes from real GitHub Issues.</p>
|
|
96
|
-
<input id="cb-search" placeholder="Search... (database, git, deploy)" oninput="filterRecipes()">
|
|
97
|
-
<div style="margin:.3rem 0" id="cb-filters"></div>
|
|
98
|
-
<div id="cb-count" style="color:#8b949e;font-size:.8rem"></div>
|
|
99
|
-
<div id="cb-list"></div>
|
|
100
|
-
</div>
|
|
101
|
-
|
|
102
|
-
<!-- PAGE: ECOSYSTEM -->
|
|
103
|
-
<div class="page" id="page-ecosystem">
|
|
104
|
-
<h1>Ecosystem Comparison</h1>
|
|
105
|
-
<p>All major Claude Code hook projects compared.</p>
|
|
106
|
-
<table>
|
|
107
|
-
<tr><th>Project</th><th>Lang</th><th>Hooks</th><th>Install</th></tr>
|
|
108
|
-
<tr><td><a href="https://github.com/kenryu42/claude-code-safety-net">safety-net</a></td><td><span class="badge badge-ts">TS</span></td><td>5</td><td>npx</td></tr>
|
|
109
|
-
<tr><td><a href="https://github.com/yurukusa/cc-safe-setup">cc-safe-setup</a></td><td><span class="badge badge-bash">Bash</span></td><td>8+39</td><td>npx</td></tr>
|
|
110
|
-
<tr><td><a href="https://github.com/karanb192/claude-code-hooks">karanb192</a></td><td><span class="badge badge-js">JS</span></td><td>5+</td><td>copy</td></tr>
|
|
111
|
-
<tr><td><a href="https://github.com/disler/claude-code-hooks-mastery">mastery</a></td><td><span class="badge badge-py">Python</span></td><td>12</td><td>copy</td></tr>
|
|
112
|
-
<tr><td><a href="https://github.com/lasso-security/claude-hooks">lasso</a></td><td><span class="badge badge-py">Python</span></td><td>1</td><td>install.sh</td></tr>
|
|
113
|
-
</table>
|
|
114
|
-
<h2>Feature Matrix</h2>
|
|
115
|
-
<table>
|
|
116
|
-
<tr><th>Feature</th><th>safety-net</th><th>cc-safe-setup</th><th>karanb192</th><th>mastery</th></tr>
|
|
117
|
-
<tr><td>rm -rf blocker</td><td class="check">✓</td><td class="check">✓</td><td class="check">✓</td><td class="check">✓</td></tr>
|
|
118
|
-
<tr><td>Branch guard</td><td class="check">✓</td><td class="check">✓</td><td class="cross">-</td><td class="cross">-</td></tr>
|
|
119
|
-
<tr><td>Secret guard</td><td class="cross">-</td><td class="check">✓</td><td class="check">✓</td><td class="cross">-</td></tr>
|
|
120
|
-
<tr><td>Syntax check</td><td class="cross">-</td><td class="check">✓</td><td class="cross">-</td><td class="cross">-</td></tr>
|
|
121
|
-
<tr><td>Context monitor</td><td class="cross">-</td><td class="check">✓</td><td class="cross">-</td><td class="cross">-</td></tr>
|
|
122
|
-
<tr><td>Hook generator</td><td class="cross">-</td><td class="check">✓</td><td class="cross">-</td><td class="cross">-</td></tr>
|
|
123
|
-
<tr><td>Dashboard</td><td class="cross">-</td><td class="check">✓</td><td class="cross">-</td><td class="cross">-</td></tr>
|
|
124
|
-
<tr><td>GitHub Action</td><td class="cross">-</td><td class="check">✓</td><td class="cross">-</td><td class="cross">-</td></tr>
|
|
125
|
-
</table>
|
|
126
|
-
</div>
|
|
127
|
-
|
|
128
|
-
<!-- PAGE: CHEAT SHEET -->
|
|
129
|
-
<div class="page" id="page-cheatsheet">
|
|
130
|
-
<h1>Hooks Cheat Sheet</h1>
|
|
131
|
-
<p>Print this page (Ctrl+P) for a quick reference.</p>
|
|
132
|
-
|
|
133
|
-
<h3>Lifecycle</h3>
|
|
134
|
-
<pre>Prompt → PreToolUse → Tool → PostToolUse → Stop</pre>
|
|
135
|
-
|
|
136
|
-
<h3>Exit Codes</h3>
|
|
137
|
-
<table><tr><th>Code</th><th>Meaning</th></tr>
|
|
138
|
-
<tr><td><code>0</code></td><td>Allow</td></tr>
|
|
139
|
-
<tr><td><code>2</code></td><td><strong>Block</strong></td></tr></table>
|
|
140
|
-
|
|
141
|
-
<h3>Minimal Block Hook</h3>
|
|
142
|
-
<pre>#!/bin/bash
|
|
143
|
-
CMD=$(cat | jq -r '.tool_input.command // empty')
|
|
144
|
-
[ -z "$CMD" ] && exit 0
|
|
145
|
-
echo "$CMD" | grep -qE 'PATTERN' && echo "BLOCKED" >&2 && exit 2
|
|
146
|
-
exit 0</pre>
|
|
147
|
-
|
|
148
|
-
<h3>Auto-Approve Hook</h3>
|
|
149
|
-
<pre>#!/bin/bash
|
|
150
|
-
CMD=$(cat | jq -r '.tool_input.command // empty')
|
|
151
|
-
[ -z "$CMD" ] && exit 0
|
|
152
|
-
echo "$CMD" | grep -qE '^git\s+(status|log|diff)' && \
|
|
153
|
-
jq -n '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"allow"}}'
|
|
154
|
-
exit 0</pre>
|
|
155
|
-
|
|
156
|
-
<h3>Quick Commands</h3>
|
|
157
|
-
<table>
|
|
158
|
-
<tr><td><code>npx cc-safe-setup</code></td><td>Install 8 hooks</td></tr>
|
|
159
|
-
<tr><td><code>--create "desc"</code></td><td>Generate hook</td></tr>
|
|
160
|
-
<tr><td><code>--audit</code></td><td>Score 0-100</td></tr>
|
|
161
|
-
<tr><td><code>--dashboard</code></td><td>Live status</td></tr>
|
|
162
|
-
<tr><td><code>--doctor</code></td><td>Diagnose</td></tr>
|
|
163
|
-
<tr><td><code>--benchmark</code></td><td>Speed test</td></tr>
|
|
164
|
-
</table>
|
|
165
|
-
</div>
|
|
166
|
-
|
|
167
|
-
<div class="footer">
|
|
168
|
-
cc-safe-setup · 100% client-side · <a href="https://github.com/yurukusa/cc-safe-setup">GitHub</a> · <a href="https://www.npmjs.com/package/cc-safe-setup">npm</a>
|
|
169
|
-
</div>
|
|
170
|
-
|
|
171
|
-
<script>
|
|
172
|
-
// Navigation
|
|
173
|
-
function go(page) {
|
|
174
|
-
document.querySelectorAll('.page').forEach(p => p.classList.remove('active'));
|
|
175
|
-
document.querySelectorAll('.nav a').forEach(a => a.classList.remove('active'));
|
|
176
|
-
document.getElementById('page-' + page).classList.add('active');
|
|
177
|
-
document.getElementById('nav-' + page).classList.add('active');
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
// AUDIT
|
|
181
|
-
function runAudit() {
|
|
182
|
-
const raw = document.getElementById('settings').value.trim();
|
|
183
|
-
const el = document.getElementById('audit-results');
|
|
184
|
-
if (!raw) { generateFresh(); return; }
|
|
185
|
-
let s; try { s = JSON.parse(raw); } catch { el.innerHTML='<p style="color:#f85149">Invalid JSON</p>'; return; }
|
|
186
|
-
const {risks,good,score} = analyze(s);
|
|
187
|
-
renderAudit(risks, good, score, el);
|
|
188
|
-
}
|
|
189
|
-
function generateFresh() {
|
|
190
|
-
const {risks,good,score} = analyze({});
|
|
191
|
-
renderAudit(risks, good, score, document.getElementById('audit-results'));
|
|
192
|
-
}
|
|
193
|
-
function analyze(s) {
|
|
194
|
-
const risks=[], good=[];
|
|
195
|
-
const pre=s.hooks?.PreToolUse||[], post=s.hooks?.PostToolUse||[];
|
|
196
|
-
const all=JSON.stringify(pre).toLowerCase();
|
|
197
|
-
if(!pre.length) risks.push({s:'CRITICAL',i:'No PreToolUse hooks',f:'npx cc-safe-setup'});
|
|
198
|
-
else { good.push('PreToolUse ('+pre.length+')');
|
|
199
|
-
if(!all.match(/destructive|guard|rm.*rf/)) risks.push({s:'HIGH',i:'No destructive guard',f:'npx cc-safe-setup'});
|
|
200
|
-
else good.push('Destructive protection');
|
|
201
|
-
if(!all.match(/branch|push|main/)) risks.push({s:'HIGH',i:'No branch guard',f:'npx cc-safe-setup'});
|
|
202
|
-
else good.push('Branch protection');
|
|
203
|
-
if(!all.match(/secret|env|credential/)) risks.push({s:'HIGH',i:'No secret guard',f:'npx cc-safe-setup'});
|
|
204
|
-
else good.push('Secret protection');
|
|
205
|
-
}
|
|
206
|
-
if(!post.length) risks.push({s:'MEDIUM',i:'No PostToolUse hooks',f:'npx cc-safe-setup'});
|
|
207
|
-
else good.push('PostToolUse ('+post.length+')');
|
|
208
|
-
const score=Math.max(0,100-risks.reduce((n,r)=>n+(r.s==='CRITICAL'?30:r.s==='HIGH'?20:10),0));
|
|
209
|
-
return {risks,good,score};
|
|
210
|
-
}
|
|
211
|
-
function renderAudit(risks,good,score,el) {
|
|
212
|
-
const cls=score>=80?'good':score>=50?'mid':'bad';
|
|
213
|
-
let h='<div class="score '+cls+'">'+score+'/100</div>';
|
|
214
|
-
if(good.length) { h+='<h3 style="color:#3fb950">Working</h3>'; good.forEach(g=>h+='<div class="good-item">✓ '+g+'</div>'); }
|
|
215
|
-
if(risks.length) { h+='<h3>Risks ('+risks.length+')</h3>'; risks.forEach(r=>h+='<div class="risk"><strong>['+r.s+']</strong> '+r.i+'<br><code>'+r.f+'</code></div>'); }
|
|
216
|
-
if(!risks.length) h+='<p style="color:#3fb950">No risks detected.</p>';
|
|
217
|
-
el.innerHTML=h;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
// HOOK BUILDER
|
|
221
|
-
function buildHook() {
|
|
222
|
-
const action=document.getElementById('hb-action').value;
|
|
223
|
-
const pattern=document.getElementById('hb-pattern').value.trim();
|
|
224
|
-
const message=document.getElementById('hb-message').value.trim()||'Blocked';
|
|
225
|
-
const el=document.getElementById('hb-result');
|
|
226
|
-
if(!pattern){el.innerHTML='<p style="color:#f85149">Enter a pattern</p>';return;}
|
|
227
|
-
let s='#!/bin/bash\nCMD=$(cat | jq -r \'.tool_input.command // empty\' 2>/dev/null)\n[ -z "$CMD" ] && exit 0\n';
|
|
228
|
-
if(action==='block') s+='echo "$CMD" | grep -qE \''+pattern+'\' && echo "BLOCKED: '+message+'" >&2 && exit 2\n';
|
|
229
|
-
else if(action==='warn') s+='echo "$CMD" | grep -qE \''+pattern+'\' && echo "WARNING: '+message+'" >&2\n';
|
|
230
|
-
else s+='echo "$CMD" | grep -qE \''+pattern+'\' && jq -n \'{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"allow"}}\'\n';
|
|
231
|
-
s+='exit 0';
|
|
232
|
-
el.innerHTML='<h3>Script</h3><pre>'+esc(s)+'</pre><p style="font-size:.75rem;color:#8b949e">Save as ~/.claude/hooks/custom.sh, chmod +x, add to settings.json</p>';
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
// COOKBOOK
|
|
236
|
-
const RECIPES=[
|
|
237
|
-
{cat:'block',t:'Block rm -rf',d:'Destructive commands (#36339)',code:'CMD=$(cat|jq -r \'.tool_input.command // empty\')\n[ -z "$CMD" ] && exit 0\necho "$CMD"|grep -qE \'rm\\s+(-[rf]+\\s+)*/\' && echo "BLOCKED" >&2 && exit 2\nexit 0',trigger:'PreToolUse'},
|
|
238
|
-
{cat:'block',t:'Block force push',d:'Branch protection',code:'CMD=$(cat|jq -r \'.tool_input.command // empty\')\n[ -z "$CMD" ] && exit 0\necho "$CMD"|grep -qE \'git\\s+push.*--force\' && echo "BLOCKED" >&2 && exit 2\nexit 0',trigger:'PreToolUse'},
|
|
239
|
-
{cat:'block',t:'Block .env staging',d:'Secret leak prevention (#6527)',code:'CMD=$(cat|jq -r \'.tool_input.command // empty\')\n[ -z "$CMD" ] && exit 0\necho "$CMD"|grep -qiE \'git\\s+add.*\\.env\' && echo "BLOCKED" >&2 && exit 2\nexit 0',trigger:'PreToolUse'},
|
|
240
|
-
{cat:'block',t:'Block database wipe',d:'migrate:fresh, DROP DATABASE (#37405)',code:'CMD=$(cat|jq -r \'.tool_input.command // empty\')\n[ -z "$CMD" ] && exit 0\necho "$CMD"|grep -qiE \'migrate:fresh|DROP\\s+DATABASE|prisma\\s+migrate\\s+reset\' && echo "BLOCKED" >&2 && exit 2\nexit 0',trigger:'PreToolUse'},
|
|
241
|
-
{cat:'approve',t:'Auto-approve git read',d:'git status/log/diff with -C flag (#36900)',code:'CMD=$(cat|jq -r \'.tool_input.command // empty\')\n[ -z "$CMD" ] && exit 0\necho "$CMD"|grep -qE \'^\\s*git\\s+(-C\\s+\\S+\\s+)?(status|log|diff|branch|show)\' && jq -n \'{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"allow"}}\'\nexit 0',trigger:'PreToolUse'},
|
|
242
|
-
{cat:'approve',t:'Compound commands',d:'cd && git log auto-approve (#30519)',code:'# Full: npx cc-safe-setup --install-example compound-command-approver',trigger:'PreToolUse'},
|
|
243
|
-
{cat:'detect',t:'Loop detector',d:'Break command repetition (5+ times)',code:'CMD=$(cat|jq -r \'.tool_input.command // empty\')\n[ -z "$CMD" ] && exit 0\nSTATE=/tmp/cc-loop\necho "$CMD">>$STATE\ntail -n 10 $STATE>${STATE}.tmp&&mv ${STATE}.tmp $STATE\nCOUNT=$(grep -cF "$CMD" $STATE||echo 0)\n[ "$COUNT" -ge 5 ]&&echo "BLOCKED: repeated $COUNT times" >&2&&exit 2\nexit 0',trigger:'PreToolUse'},
|
|
244
|
-
{cat:'utility',t:'Session handoff',d:'Save state for next session',code:'# npx cc-safe-setup --install-example session-handoff',trigger:'Stop'},
|
|
245
|
-
{cat:'utility',t:'Cost tracker',d:'Estimate session token cost',code:'# npx cc-safe-setup --install-example cost-tracker',trigger:'PostToolUse'},
|
|
246
|
-
{cat:'utility',t:'tmp cleanup',d:'/tmp/claude-*-cwd files (#8856)',code:'find /tmp -maxdepth 1 -name \'claude-*-cwd\' -type f -mmin +60 -delete 2>/dev/null\nexit 0',trigger:'Stop'},
|
|
247
|
-
];
|
|
248
|
-
|
|
249
|
-
function initCookbook() {
|
|
250
|
-
const cats=['all','block','approve','detect','utility'];
|
|
251
|
-
document.getElementById('cb-filters').innerHTML=cats.map(c=>'<button class="filter'+(c==='all'?' active':'')+'" onclick="setCbFilter(\''+c+'\')">'+c+'</button>').join('');
|
|
252
|
-
filterRecipes();
|
|
253
|
-
}
|
|
254
|
-
let cbFilter='all';
|
|
255
|
-
function setCbFilter(f){cbFilter=f;document.querySelectorAll('#cb-filters .filter').forEach(b=>b.classList.toggle('active',b.textContent===f));filterRecipes();}
|
|
256
|
-
function filterRecipes(){
|
|
257
|
-
const q=(document.getElementById('cb-search')?.value||'').toLowerCase();
|
|
258
|
-
const filtered=RECIPES.filter(r=>(cbFilter==='all'||r.cat===cbFilter)&&(!q||r.t.toLowerCase().includes(q)||r.d.toLowerCase().includes(q)||(r.code||'').toLowerCase().includes(q)));
|
|
259
|
-
document.getElementById('cb-count').textContent=filtered.length+' recipe(s)';
|
|
260
|
-
document.getElementById('cb-list').innerHTML=filtered.map(r=>'<details class="recipe"><summary>'+esc(r.t)+' <span style="color:#484f58;font-size:.7rem">['+r.trigger+']</span></summary><div class="recipe-body"><p style="color:#8b949e;font-size:.8rem">'+esc(r.d)+'</p>'+(r.code?'<pre>'+esc(r.code)+'</pre>':'')+'</div></details>').join('');
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
function esc(s){return(s||'').replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');}
|
|
264
|
-
|
|
265
|
-
// URL param
|
|
266
|
-
(function(){const p=new URLSearchParams(location.search);const c=p.get('config');if(c){try{document.getElementById('settings').value=atob(c);runAudit();}catch{}}})();
|
|
267
|
-
|
|
268
|
-
initCookbook();
|
|
269
|
-
</script>
|
|
270
|
-
</body>
|
|
271
|
-
</html>
|
package/docs/matrix.html
DELETED
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<title>Claude Code Hooks Matrix — 112 Hooks at a Glance</title>
|
|
7
|
-
<meta name="description" content="Interactive matrix of all 112 Claude Code hooks. Filter by trigger, category, and action type.">
|
|
8
|
-
<style>
|
|
9
|
-
*{box-sizing:border-box;margin:0;padding:0}
|
|
10
|
-
body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;background:#0d1117;color:#c9d1d9;padding:1rem;font-size:.82rem}
|
|
11
|
-
.c{max-width:1100px;margin:0 auto}
|
|
12
|
-
h1{color:#f0f6fc;font-size:1.3rem;margin-bottom:.2rem}
|
|
13
|
-
.sub{color:#8b949e;font-size:.8rem;margin-bottom:.8rem}
|
|
14
|
-
a{color:#58a6ff;text-decoration:none}
|
|
15
|
-
input{width:100%;padding:.5rem;background:#161b22;border:1px solid #30363d;border-radius:6px;color:#c9d1d9;font-size:.85rem;margin-bottom:.5rem}
|
|
16
|
-
input::placeholder{color:#484f58}
|
|
17
|
-
.filters{display:flex;gap:.3rem;flex-wrap:wrap;margin-bottom:.5rem}
|
|
18
|
-
.f{padding:.2rem .5rem;border-radius:3px;border:1px solid #30363d;background:transparent;color:#8b949e;cursor:pointer;font-size:.7rem}
|
|
19
|
-
.f.on{background:#238636;border-color:#238636;color:#fff}
|
|
20
|
-
table{width:100%;border-collapse:collapse}
|
|
21
|
-
th,td{padding:.3rem .4rem;border:1px solid #21262d;text-align:left;font-size:.75rem}
|
|
22
|
-
th{background:#161b22;color:#f0f6fc;position:sticky;top:0;cursor:pointer}
|
|
23
|
-
th:hover{background:#21262d}
|
|
24
|
-
tr:hover td{background:#161b2288}
|
|
25
|
-
.act-block{color:#f85149;font-weight:bold}
|
|
26
|
-
.act-warn{color:#d29922}
|
|
27
|
-
.act-approve{color:#3fb950}
|
|
28
|
-
.act-monitor{color:#58a6ff}
|
|
29
|
-
.count{color:#8b949e;font-size:.78rem;margin:.3rem 0}
|
|
30
|
-
.footer{text-align:center;color:#484f58;font-size:.65rem;margin-top:1rem}
|
|
31
|
-
td code{background:#21262d;padding:.1rem .2rem;border-radius:2px;font-size:.7rem;cursor:pointer}
|
|
32
|
-
td code:hover{color:#58a6ff}
|
|
33
|
-
</style>
|
|
34
|
-
</head>
|
|
35
|
-
<body>
|
|
36
|
-
<div class="c">
|
|
37
|
-
<h1>Hook Matrix</h1>
|
|
38
|
-
<p class="sub">112 hooks. Click column headers to sort. Search to filter.</p>
|
|
39
|
-
|
|
40
|
-
<input id="q" placeholder="Filter hooks..." oninput="render()">
|
|
41
|
-
<div class="filters" id="filters"></div>
|
|
42
|
-
<div class="count" id="count"></div>
|
|
43
|
-
<div style="overflow-x:auto"><table id="tbl"><thead><tr>
|
|
44
|
-
<th onclick="sortBy('name')">Hook</th>
|
|
45
|
-
<th onclick="sortBy('cat')">Category</th>
|
|
46
|
-
<th onclick="sortBy('trigger')">Trigger</th>
|
|
47
|
-
<th onclick="sortBy('action')">Action</th>
|
|
48
|
-
<th>Description</th>
|
|
49
|
-
<th>Install</th>
|
|
50
|
-
</tr></thead><tbody id="tbody"></tbody></table></div>
|
|
51
|
-
|
|
52
|
-
<div class="footer">
|
|
53
|
-
<a href="hooks-cheatsheet.html">Cheat Sheet</a> ·
|
|
54
|
-
<a href="builder.html">Builder</a> ·
|
|
55
|
-
<a href="troubleshooting.html">Troubleshoot</a> ·
|
|
56
|
-
<a href="https://github.com/yurukusa/cc-safe-setup">GitHub</a>
|
|
57
|
-
</div>
|
|
58
|
-
</div>
|
|
59
|
-
|
|
60
|
-
<script>
|
|
61
|
-
const H=[
|
|
62
|
-
{n:'destructive-guard',c:'safety',t:'Pre',a:'block',d:'rm -rf, git reset --hard, git clean',i:'npx cc-safe-setup'},
|
|
63
|
-
{n:'branch-guard',c:'safety',t:'Pre',a:'block',d:'Push to main/master, force-push',i:'npx cc-safe-setup'},
|
|
64
|
-
{n:'secret-guard',c:'safety',t:'Pre',a:'block',d:'git add .env, credential files',i:'npx cc-safe-setup'},
|
|
65
|
-
{n:'syntax-check',c:'quality',t:'Post',a:'warn',d:'Python/Shell/JSON/JS syntax after edits',i:'npx cc-safe-setup'},
|
|
66
|
-
{n:'context-monitor',c:'monitor',t:'Post',a:'warn',d:'Context warnings at 40/25/20/15%',i:'npx cc-safe-setup'},
|
|
67
|
-
{n:'comment-strip',c:'utility',t:'Pre',a:'warn',d:'Fix bash comments breaking permissions',i:'npx cc-safe-setup'},
|
|
68
|
-
{n:'cd-git-allow',c:'approve',t:'Pre',a:'approve',d:'Auto-approve cd && git compounds',i:'npx cc-safe-setup'},
|
|
69
|
-
{n:'api-error-alert',c:'monitor',t:'Stop',a:'monitor',d:'Notify on session API errors',i:'npx cc-safe-setup'},
|
|
70
|
-
{n:'scope-guard',c:'safety',t:'Pre',a:'block',d:'Block operations outside project',i:'--install-example scope-guard'},
|
|
71
|
-
{n:'no-sudo-guard',c:'safety',t:'Pre',a:'block',d:'Block all sudo commands',i:'--install-example no-sudo-guard'},
|
|
72
|
-
{n:'protect-claudemd',c:'safety',t:'Pre',a:'block',d:'Block edits to CLAUDE.md/settings',i:'--install-example protect-claudemd'},
|
|
73
|
-
{n:'protect-dotfiles',c:'safety',t:'Pre',a:'block',d:'Block .bashrc, .aws/, .ssh/ changes',i:'--install-example protect-dotfiles'},
|
|
74
|
-
{n:'block-database-wipe',c:'safety',t:'Pre',a:'block',d:'DROP DATABASE, migrate:fresh, prisma reset',i:'--install-example block-database-wipe'},
|
|
75
|
-
{n:'deploy-guard',c:'deploy',t:'Pre',a:'warn',d:'Warn deploy with uncommitted changes',i:'--install-example deploy-guard'},
|
|
76
|
-
{n:'no-deploy-friday',c:'deploy',t:'Pre',a:'block',d:'Block deploys on Fridays',i:'--install-example no-deploy-friday'},
|
|
77
|
-
{n:'work-hours-guard',c:'deploy',t:'Pre',a:'warn',d:'Restrict risky ops outside hours',i:'--install-example work-hours-guard'},
|
|
78
|
-
{n:'uncommitted-work-guard',c:'safety',t:'Pre',a:'block',d:'Block destructive git when dirty',i:'--install-example uncommitted-work-guard'},
|
|
79
|
-
{n:'test-deletion-guard',c:'quality',t:'Pre',a:'warn',d:'Warn when removing test assertions',i:'--install-example test-deletion-guard'},
|
|
80
|
-
{n:'overwrite-guard',c:'safety',t:'Pre',a:'warn',d:'Warn before overwriting files',i:'--install-example overwrite-guard'},
|
|
81
|
-
{n:'memory-write-guard',c:'safety',t:'Pre',a:'warn',d:'Log writes to ~/.claude/',i:'--install-example memory-write-guard'},
|
|
82
|
-
{n:'fact-check-gate',c:'quality',t:'Post',a:'warn',d:'Docs reference unread source files',i:'--install-example fact-check-gate'},
|
|
83
|
-
{n:'token-budget-guard',c:'monitor',t:'Post',a:'block',d:'Block when cost exceeds budget',i:'--install-example token-budget-guard'},
|
|
84
|
-
{n:'conflict-marker-guard',c:'quality',t:'Pre',a:'block',d:'Block commits with conflict markers',i:'--install-example conflict-marker-guard'},
|
|
85
|
-
{n:'error-memory-guard',c:'safety',t:'Post',a:'block',d:'Block retries of failed commands',i:'--install-example error-memory-guard'},
|
|
86
|
-
{n:'strict-allowlist',c:'safety',t:'Pre',a:'block',d:'Only allow permitted commands',i:'--install-example strict-allowlist'},
|
|
87
|
-
{n:'hardcoded-secret-detector',c:'security',t:'Post',a:'warn',d:'Detect AWS keys, passwords, JWT',i:'--install-example hardcoded-secret-detector'},
|
|
88
|
-
{n:'auto-approve-build',c:'approve',t:'Pre',a:'approve',d:'npm test, cargo build, go test',i:'--install-example auto-approve-build'},
|
|
89
|
-
{n:'auto-approve-python',c:'approve',t:'Pre',a:'approve',d:'pytest, mypy, ruff, black',i:'--install-example auto-approve-python'},
|
|
90
|
-
{n:'auto-approve-docker',c:'approve',t:'Pre',a:'approve',d:'docker build, compose, ps',i:'--install-example auto-approve-docker'},
|
|
91
|
-
{n:'auto-approve-go',c:'approve',t:'Pre',a:'approve',d:'go build/test/vet/fmt',i:'--install-example auto-approve-go'},
|
|
92
|
-
{n:'auto-approve-cargo',c:'approve',t:'Pre',a:'approve',d:'cargo build/test/clippy',i:'--install-example auto-approve-cargo'},
|
|
93
|
-
{n:'auto-approve-make',c:'approve',t:'Pre',a:'approve',d:'make build/test/lint',i:'--install-example auto-approve-make'},
|
|
94
|
-
{n:'auto-approve-gradle',c:'approve',t:'Pre',a:'approve',d:'gradle build/test',i:'--install-example auto-approve-gradle'},
|
|
95
|
-
{n:'auto-approve-maven',c:'approve',t:'Pre',a:'approve',d:'mvn compile/test/verify',i:'--install-example auto-approve-maven'},
|
|
96
|
-
{n:'loop-detector',c:'safety',t:'Pre',a:'block',d:'Break command repetition loops',i:'--install-example loop-detector'},
|
|
97
|
-
{n:'cost-tracker',c:'monitor',t:'Post',a:'monitor',d:'Estimate session token cost',i:'--install-example cost-tracker'},
|
|
98
|
-
{n:'session-handoff',c:'utility',t:'Stop',a:'monitor',d:'Save state for next session',i:'--install-example session-handoff'},
|
|
99
|
-
{n:'revert-helper',c:'utility',t:'Stop',a:'monitor',d:'Show undo on session end',i:'--install-example revert-helper'},
|
|
100
|
-
{n:'compact-reminder',c:'utility',t:'Stop',a:'warn',d:'Suggest /compact after N calls',i:'--install-example compact-reminder'},
|
|
101
|
-
{n:'env-drift-guard',c:'quality',t:'Post',a:'warn',d:'.env vs .env.example mismatch',i:'--install-example env-drift-guard'},
|
|
102
|
-
{n:'package-script-guard',c:'quality',t:'Pre',a:'warn',d:'Warn on package.json script changes',i:'--install-example package-script-guard'},
|
|
103
|
-
{n:'git-blame-context',c:'quality',t:'Pre',a:'monitor',d:'Show file ownership before edits',i:'--install-example git-blame-context'},
|
|
104
|
-
{n:'import-cycle-warn',c:'quality',t:'Post',a:'warn',d:'Detect circular imports',i:'--install-example import-cycle-warn'},
|
|
105
|
-
{n:'lockfile-guard',c:'quality',t:'Pre',a:'warn',d:'Warn when lockfiles modified',i:'--install-example lockfile-guard'},
|
|
106
|
-
{n:'context-snapshot',c:'utility',t:'Stop',a:'monitor',d:'Save branch/files/TODOs state',i:'--install-example context-snapshot'},
|
|
107
|
-
{n:'prompt-injection-guard',c:'security',t:'Post',a:'warn',d:'Detect injection in output',i:'--install-example prompt-injection-guard'},
|
|
108
|
-
{n:'no-eval',c:'security',t:'Post',a:'warn',d:'Warn on eval() usage',i:'--install-example no-eval'},
|
|
109
|
-
{n:'no-console-log',c:'quality',t:'Post',a:'warn',d:'Warn on console.log in prod',i:'--install-example no-console-log'},
|
|
110
|
-
{n:'no-wildcard-import',c:'quality',t:'Post',a:'warn',d:'Warn on import * patterns',i:'--install-example no-wildcard-import'},
|
|
111
|
-
];
|
|
112
|
-
|
|
113
|
-
const cats=[...new Set(H.map(h=>h.c))].sort();
|
|
114
|
-
const actClass={block:'act-block',warn:'act-warn',approve:'act-approve',monitor:'act-monitor'};
|
|
115
|
-
let filter='all',sortKey='name',sortDir=1;
|
|
116
|
-
|
|
117
|
-
document.getElementById('filters').innerHTML=['all',...cats].map(c=>`<button class="f${c==='all'?' on':''}" onclick="setF('${c}')">${c}</button>`).join('');
|
|
118
|
-
|
|
119
|
-
function setF(f){filter=f;document.querySelectorAll('.f').forEach(b=>b.classList.toggle('on',b.textContent===f));render();}
|
|
120
|
-
function sortBy(k){if(sortKey===k)sortDir*=-1;else{sortKey=k;sortDir=1;}render();}
|
|
121
|
-
|
|
122
|
-
function render(){
|
|
123
|
-
const q=document.getElementById('q').value.toLowerCase();
|
|
124
|
-
let list=H.filter(h=>(filter==='all'||h.c===filter)&&(!q||h.n.includes(q)||h.d.toLowerCase().includes(q)||h.c.includes(q)));
|
|
125
|
-
list.sort((a,b)=>{const av=a[sortKey]||'',bv=b[sortKey]||'';return av<bv?-sortDir:av>bv?sortDir:0;});
|
|
126
|
-
document.getElementById('count').textContent=list.length+'/'+H.length+' hooks';
|
|
127
|
-
document.getElementById('tbody').innerHTML=list.map(h=>`<tr>
|
|
128
|
-
<td><strong>${h.n}</strong></td>
|
|
129
|
-
<td>${h.c}</td>
|
|
130
|
-
<td>${h.t}</td>
|
|
131
|
-
<td class="${actClass[h.a]||''}">${h.a}</td>
|
|
132
|
-
<td>${h.d}</td>
|
|
133
|
-
<td><code onclick="navigator.clipboard.writeText('npx cc-safe-setup ${h.i}');this.textContent='✓'">${h.i.substring(0,25)}</code></td>
|
|
134
|
-
</tr>`).join('');
|
|
135
|
-
}
|
|
136
|
-
render();
|
|
137
|
-
</script>
|
|
138
|
-
</body>
|
|
139
|
-
</html>
|
|
@@ -1,198 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<title>Claude Code Hooks — Migration Guide from Other AI Tools</title>
|
|
7
|
-
<meta name="description" content="Moving from Cursor, Windsurf, Aider, or Copilot to Claude Code? Here's how to set up equivalent safety using hooks.">
|
|
8
|
-
<style>
|
|
9
|
-
*{box-sizing:border-box;margin:0;padding:0}
|
|
10
|
-
body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;background:#0d1117;color:#c9d1d9;padding:1.5rem;line-height:1.6}
|
|
11
|
-
.c{max-width:800px;margin:0 auto}
|
|
12
|
-
h1{color:#f0f6fc;font-size:1.5rem;margin-bottom:.3rem}
|
|
13
|
-
h2{color:#f0f6fc;font-size:1.1rem;margin:1.5rem 0 .5rem;padding-bottom:.3rem;border-bottom:1px solid #21262d}
|
|
14
|
-
h3{color:#c9d1d9;font-size:.9rem;margin:.8rem 0 .3rem}
|
|
15
|
-
.sub{color:#8b949e;font-size:.85rem;margin-bottom:1.5rem}
|
|
16
|
-
a{color:#58a6ff;text-decoration:none}
|
|
17
|
-
code{background:#161b22;padding:.15rem .3rem;border-radius:3px;font-size:.85rem}
|
|
18
|
-
pre{background:#161b22;border:1px solid #30363d;border-radius:6px;padding:.7rem;font-size:.8rem;color:#e6edf3;overflow-x:auto;margin:.4rem 0}
|
|
19
|
-
table{width:100%;border-collapse:collapse;margin:.5rem 0;font-size:.82rem}
|
|
20
|
-
th,td{padding:.4rem .6rem;border:1px solid #21262d;text-align:left}
|
|
21
|
-
th{background:#161b22;color:#f0f6fc}
|
|
22
|
-
.note{background:#161b22;border-left:3px solid #58a6ff;padding:.5rem .8rem;margin:.5rem 0;font-size:.82rem;color:#8b949e}
|
|
23
|
-
.tool{background:#161b22;border:1px solid #30363d;border-radius:6px;padding:.8rem;margin:.6rem 0}
|
|
24
|
-
.tool-name{font-weight:600;color:#f0f6fc;font-size:.95rem}
|
|
25
|
-
.tool-desc{color:#8b949e;font-size:.82rem;margin:.3rem 0}
|
|
26
|
-
.footer{text-align:center;color:#484f58;font-size:.7rem;margin-top:2rem;padding-top:1rem;border-top:1px solid #21262d}
|
|
27
|
-
.quick{background:#238636;color:#fff;padding:.5rem 1rem;border-radius:6px;font-family:monospace;font-size:.85rem;border:none;display:block;width:100%;text-align:center;margin:.5rem 0;cursor:pointer}
|
|
28
|
-
</style>
|
|
29
|
-
</head>
|
|
30
|
-
<body>
|
|
31
|
-
<div class="c">
|
|
32
|
-
|
|
33
|
-
<h1>Migrating to Claude Code</h1>
|
|
34
|
-
<p class="sub">Safety setup guide for developers coming from Cursor, Windsurf, Aider, or Copilot</p>
|
|
35
|
-
|
|
36
|
-
<button class="quick" onclick="navigator.clipboard.writeText('npx cc-safe-setup --shield');this.textContent='Copied!';setTimeout(()=>this.textContent='npx cc-safe-setup --shield — one command to set up everything',1500)">npx cc-safe-setup --shield — one command to set up everything</button>
|
|
37
|
-
|
|
38
|
-
<h2>Why Claude Code is Different</h2>
|
|
39
|
-
|
|
40
|
-
<p>Unlike Cursor or Copilot, Claude Code has <strong>full terminal access</strong>. It can run any command, edit any file, push to any branch. This is powerful but requires safety hooks.</p>
|
|
41
|
-
|
|
42
|
-
<table>
|
|
43
|
-
<tr><th>Feature</th><th>Cursor/Copilot</th><th>Claude Code</th></tr>
|
|
44
|
-
<tr><td>Terminal access</td><td>Limited/sandboxed</td><td><strong>Full access</strong></td></tr>
|
|
45
|
-
<tr><td>File editing</td><td>IDE-controlled</td><td><strong>Direct filesystem</strong></td></tr>
|
|
46
|
-
<tr><td>Git operations</td><td>Via IDE UI</td><td><strong>Direct git commands</strong></td></tr>
|
|
47
|
-
<tr><td>Safety model</td><td>IDE sandbox</td><td><strong>Hooks (you configure)</strong></td></tr>
|
|
48
|
-
<tr><td>Autonomous mode</td><td>No</td><td><strong>Yes (headless)</strong></td></tr>
|
|
49
|
-
</table>
|
|
50
|
-
|
|
51
|
-
<div class="note">
|
|
52
|
-
<strong>Key difference:</strong> Cursor/Copilot run inside an IDE sandbox. Claude Code runs in your actual terminal. Hooks replace the sandbox.
|
|
53
|
-
</div>
|
|
54
|
-
|
|
55
|
-
<h2>From Cursor</h2>
|
|
56
|
-
|
|
57
|
-
<div class="tool">
|
|
58
|
-
<div class="tool-name">Cursor → Claude Code</div>
|
|
59
|
-
<div class="tool-desc">Cursor Rules (.cursorrules) → CLAUDE.md + hooks</div>
|
|
60
|
-
</div>
|
|
61
|
-
|
|
62
|
-
<h3>What you had in Cursor</h3>
|
|
63
|
-
<ul>
|
|
64
|
-
<li><code>.cursorrules</code> — project-specific instructions</li>
|
|
65
|
-
<li>IDE-level file protection</li>
|
|
66
|
-
<li>Built-in git safety (can't force-push from UI)</li>
|
|
67
|
-
</ul>
|
|
68
|
-
|
|
69
|
-
<h3>What you need in Claude Code</h3>
|
|
70
|
-
<pre><code># 1. Convert .cursorrules to CLAUDE.md
|
|
71
|
-
cp .cursorrules CLAUDE.md # Then edit to Claude Code format
|
|
72
|
-
|
|
73
|
-
# 2. Install safety hooks
|
|
74
|
-
npx cc-safe-setup --shield
|
|
75
|
-
|
|
76
|
-
# 3. Add auto-approve for your workflow
|
|
77
|
-
npx cc-safe-setup --install-example auto-approve-build
|
|
78
|
-
</code></pre>
|
|
79
|
-
|
|
80
|
-
<h3>Key hooks for Cursor migrants</h3>
|
|
81
|
-
<table>
|
|
82
|
-
<tr><th>Cursor feature</th><th>Hook equivalent</th></tr>
|
|
83
|
-
<tr><td>Can't delete system files</td><td><code>destructive-guard</code> + <code>scope-guard</code></td></tr>
|
|
84
|
-
<tr><td>IDE confirms before push</td><td><code>branch-guard</code></td></tr>
|
|
85
|
-
<tr><td>Lint on save</td><td><code>syntax-check</code></td></tr>
|
|
86
|
-
<tr><td>.env excluded from commits</td><td><code>secret-guard</code></td></tr>
|
|
87
|
-
</table>
|
|
88
|
-
|
|
89
|
-
<h2>From Windsurf</h2>
|
|
90
|
-
|
|
91
|
-
<div class="tool">
|
|
92
|
-
<div class="tool-name">Windsurf → Claude Code</div>
|
|
93
|
-
<div class="tool-desc">Windsurf Rules → CLAUDE.md + hooks</div>
|
|
94
|
-
</div>
|
|
95
|
-
|
|
96
|
-
<pre><code># Convert Windsurf cascade rules
|
|
97
|
-
# Windsurf's "Flows" → Claude Code's autonomous mode + hooks
|
|
98
|
-
|
|
99
|
-
npx cc-safe-setup --shield
|
|
100
|
-
npx cc-safe-setup --install-example context-snapshot # Preserve state across sessions
|
|
101
|
-
npx cc-safe-setup --install-example session-handoff # Hand off between sessions
|
|
102
|
-
</code></pre>
|
|
103
|
-
|
|
104
|
-
<h2>From Aider</h2>
|
|
105
|
-
|
|
106
|
-
<div class="tool">
|
|
107
|
-
<div class="tool-name">Aider → Claude Code</div>
|
|
108
|
-
<div class="tool-desc">.aider.conf → CLAUDE.md, /lint → syntax-check hook</div>
|
|
109
|
-
</div>
|
|
110
|
-
|
|
111
|
-
<pre><code># Aider auto-commits → Claude Code needs explicit control
|
|
112
|
-
npx cc-safe-setup --shield
|
|
113
|
-
npx cc-safe-setup --install-example auto-checkpoint # Similar to Aider's auto-commit
|
|
114
|
-
npx cc-safe-setup --install-example verify-before-done # Ensure tests pass before commit
|
|
115
|
-
|
|
116
|
-
# Aider's /lint → already covered by syntax-check hook
|
|
117
|
-
# Aider's /test → use auto-approve-build to skip prompts
|
|
118
|
-
</code></pre>
|
|
119
|
-
|
|
120
|
-
<h2>From GitHub Copilot Workspace</h2>
|
|
121
|
-
|
|
122
|
-
<div class="tool">
|
|
123
|
-
<div class="tool-name">Copilot Workspace → Claude Code</div>
|
|
124
|
-
<div class="tool-desc">Copilot's plan-execute → Claude Code's plan mode + hooks</div>
|
|
125
|
-
</div>
|
|
126
|
-
|
|
127
|
-
<pre><code># Copilot Workspace creates PRs automatically
|
|
128
|
-
# Claude Code needs branch protection
|
|
129
|
-
npx cc-safe-setup --shield
|
|
130
|
-
npx cc-safe-setup --install-example deploy-guard # Prevent accidental deploys
|
|
131
|
-
npx cc-safe-setup --install-example diff-size-guard # Warn on large changes
|
|
132
|
-
npx cc-safe-setup --install-example pr-description-check # Ensure PR quality
|
|
133
|
-
</code></pre>
|
|
134
|
-
|
|
135
|
-
<h2>Universal Setup (Any Tool)</h2>
|
|
136
|
-
|
|
137
|
-
<pre><code># Step 1: Maximum safety
|
|
138
|
-
npx cc-safe-setup --shield
|
|
139
|
-
|
|
140
|
-
# Step 2: Check what's installed
|
|
141
|
-
npx cc-safe-setup --status
|
|
142
|
-
|
|
143
|
-
# Step 3: Verify everything works
|
|
144
|
-
npx cc-safe-setup --verify
|
|
145
|
-
|
|
146
|
-
# Step 4: View your safety score
|
|
147
|
-
npx cc-safe-setup --audit
|
|
148
|
-
</code></pre>
|
|
149
|
-
|
|
150
|
-
<h2>CLAUDE.md Template</h2>
|
|
151
|
-
|
|
152
|
-
<p>Create a <code>CLAUDE.md</code> in your project root:</p>
|
|
153
|
-
|
|
154
|
-
<pre><code># Project Rules
|
|
155
|
-
|
|
156
|
-
## Safety
|
|
157
|
-
- Do not push to main/master directly
|
|
158
|
-
- Do not force-push
|
|
159
|
-
- Do not delete files outside this project
|
|
160
|
-
- Do not commit .env or credential files
|
|
161
|
-
- Run tests before committing
|
|
162
|
-
|
|
163
|
-
## Code Style
|
|
164
|
-
- Follow existing conventions in this codebase
|
|
165
|
-
- Keep functions small and focused
|
|
166
|
-
|
|
167
|
-
## Git
|
|
168
|
-
- Use descriptive commit messages
|
|
169
|
-
- One logical change per commit
|
|
170
|
-
- Create feature branches for new work
|
|
171
|
-
</code></pre>
|
|
172
|
-
|
|
173
|
-
<div class="note">
|
|
174
|
-
<strong>CLAUDE.md vs .cursorrules:</strong> Same concept, but CLAUDE.md is also read by Claude in the API (not just the CLI). Hooks add enforcement — CLAUDE.md is advisory, hooks are mandatory.
|
|
175
|
-
</div>
|
|
176
|
-
|
|
177
|
-
<h2>Safety Profile Comparison</h2>
|
|
178
|
-
|
|
179
|
-
<table>
|
|
180
|
-
<tr><th>Profile</th><th>Hooks</th><th>Best for</th></tr>
|
|
181
|
-
<tr><td><code>minimal</code></td><td>8</td><td>Experienced users, quick tasks</td></tr>
|
|
182
|
-
<tr><td><code>standard</code></td><td>20</td><td>Daily development, balanced safety</td></tr>
|
|
183
|
-
<tr><td><code>strict</code></td><td>33</td><td>Autonomous sessions, production repos</td></tr>
|
|
184
|
-
</table>
|
|
185
|
-
|
|
186
|
-
<pre><code>npx cc-safe-setup --profile strict # For autonomous/production use
|
|
187
|
-
</code></pre>
|
|
188
|
-
|
|
189
|
-
<div class="footer">
|
|
190
|
-
<a href="hooks-cheatsheet.html">Cheat Sheet</a> ·
|
|
191
|
-
<a href="builder.html">Hook Builder</a> ·
|
|
192
|
-
<a href="faq.html">FAQ</a> ·
|
|
193
|
-
<a href="https://yurukusa.github.io/cc-hook-registry/playground.html">Playground</a> ·
|
|
194
|
-
<a href="https://github.com/yurukusa/cc-safe-setup">GitHub</a>
|
|
195
|
-
</div>
|
|
196
|
-
</div>
|
|
197
|
-
</body>
|
|
198
|
-
</html>
|