claudex-setup 1.10.2 → 1.11.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/CHANGELOG.md +36 -0
- package/README.md +83 -5
- package/bin/cli.js +146 -23
- package/content/case-study-template.md +91 -0
- package/content/claims-governance.md +37 -0
- package/content/claude-code/audit-repo/SKILL.md +20 -0
- package/content/claude-native-integration.md +64 -0
- package/content/devto-article.json +9 -0
- package/content/launch-posts.md +160 -0
- package/content/pilot-rollout-kit.md +30 -0
- package/content/release-checklist.md +31 -0
- package/package.json +3 -2
- package/src/activity.js +242 -1
- package/src/analyze.js +18 -3
- package/src/audit.js +157 -10
- package/src/claudex-sync.json +2 -6
- package/src/governance.js +69 -0
- package/src/insights.js +3 -2
- package/src/techniques.js +16 -13
package/src/audit.js
CHANGED
|
@@ -30,10 +30,60 @@ function progressBar(score, max = 100, width = 20) {
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
const IMPACT_ORDER = { critical: 3, high: 2, medium: 1, low: 0 };
|
|
33
|
+
const CATEGORY_MODULES = {
|
|
34
|
+
memory: 'CLAUDE.md',
|
|
35
|
+
quality: 'verification',
|
|
36
|
+
git: 'safety',
|
|
37
|
+
workflow: 'commands-agents-skills',
|
|
38
|
+
security: 'permissions',
|
|
39
|
+
automation: 'hooks',
|
|
40
|
+
design: 'design-rules',
|
|
41
|
+
devops: 'ci-devops',
|
|
42
|
+
hygiene: 'project-hygiene',
|
|
43
|
+
performance: 'context-management',
|
|
44
|
+
tools: 'mcp-tools',
|
|
45
|
+
prompting: 'prompt-structure',
|
|
46
|
+
features: 'modern-claude-features',
|
|
47
|
+
'quality-deep': 'quality-deep',
|
|
48
|
+
};
|
|
49
|
+
const ACTION_RATIONALES = {
|
|
50
|
+
noBypassPermissions: 'bypassPermissions skips the main safety layer. Explicit allow and deny rules create safer autonomy.',
|
|
51
|
+
secretsProtection: 'Without secret protection, Claude can accidentally inspect sensitive files and leak them into outputs.',
|
|
52
|
+
permissionDeny: 'Deny rules are the strongest way to prevent dangerous reads and destructive operations.',
|
|
53
|
+
settingsPermissions: 'Explicit permission settings make the workflow safer, more governable, and easier to review.',
|
|
54
|
+
testCommand: 'Without a test command, Claude cannot verify that its changes actually work before handoff.',
|
|
55
|
+
lintCommand: 'Without a lint command, Claude will miss formatting and style regressions that teams expect to catch automatically.',
|
|
56
|
+
buildCommand: 'Without a build command, compile and packaging failures stay invisible until later in the workflow.',
|
|
57
|
+
ciPipeline: 'CI is what turns a local setup improvement into a repeatable team-wide standard.',
|
|
58
|
+
securityReview: 'If you do not wire in security review guidance, high-risk changes are easier to ship without the right scrutiny.',
|
|
59
|
+
skills: 'Skills package reusable expertise so Claude does not need the same context re-explained every session.',
|
|
60
|
+
multipleAgents: 'Specialized agents unlock role-based work such as security review, implementation, and QA in parallel.',
|
|
61
|
+
multipleMcpServers: 'A richer MCP surface gives Claude access to live tools and documentation instead of stale assumptions.',
|
|
62
|
+
roleDefinition: 'A clear role definition calibrates how Claude thinks, explains, and validates work in this repo.',
|
|
63
|
+
importSyntax: 'Imported modules keep CLAUDE.md maintainable as the workflow grows more sophisticated.',
|
|
64
|
+
claudeMd: 'CLAUDE.md is the foundation of project-specific context. Without it, Claude starts every task half-blind.',
|
|
65
|
+
hooks: 'Hooks enforce the rules programmatically, which is much more reliable than relying on instructions alone.',
|
|
66
|
+
pathRules: 'Path-specific rules help Claude behave differently in different parts of the repo without global noise.',
|
|
67
|
+
context7Mcp: 'Live documentation reduces version drift and cuts down on confident but outdated answers.',
|
|
68
|
+
};
|
|
33
69
|
|
|
34
|
-
function
|
|
70
|
+
function riskFromImpact(impact) {
|
|
71
|
+
if (impact === 'critical') return 'high';
|
|
72
|
+
if (impact === 'high') return 'medium';
|
|
73
|
+
return 'low';
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function confidenceFromImpact(impact) {
|
|
77
|
+
return impact === 'critical' || impact === 'high' ? 'high' : 'medium';
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function getPrioritizedFailed(failed) {
|
|
35
81
|
const prioritized = failed.filter(r => !(r.category === 'hygiene' && r.impact === 'low'));
|
|
36
|
-
|
|
82
|
+
return prioritized.length > 0 ? prioritized : failed;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function getQuickWins(failed) {
|
|
86
|
+
const pool = getPrioritizedFailed(failed);
|
|
37
87
|
|
|
38
88
|
return [...pool]
|
|
39
89
|
.sort((a, b) => {
|
|
@@ -45,6 +95,87 @@ function getQuickWins(failed) {
|
|
|
45
95
|
.slice(0, 3);
|
|
46
96
|
}
|
|
47
97
|
|
|
98
|
+
function buildTopNextActions(failed, limit = 5) {
|
|
99
|
+
const pool = getPrioritizedFailed(failed);
|
|
100
|
+
|
|
101
|
+
return [...pool]
|
|
102
|
+
.sort((a, b) => {
|
|
103
|
+
const impactA = IMPACT_ORDER[a.impact] ?? 0;
|
|
104
|
+
const impactB = IMPACT_ORDER[b.impact] ?? 0;
|
|
105
|
+
if (impactA !== impactB) return impactB - impactA;
|
|
106
|
+
return (a.fix || '').length - (b.fix || '').length;
|
|
107
|
+
})
|
|
108
|
+
.slice(0, limit)
|
|
109
|
+
.map(({ key, name, impact, fix, category }) => ({
|
|
110
|
+
key,
|
|
111
|
+
name,
|
|
112
|
+
impact,
|
|
113
|
+
category,
|
|
114
|
+
module: CATEGORY_MODULES[category] || category,
|
|
115
|
+
fix,
|
|
116
|
+
why: ACTION_RATIONALES[key] || fix,
|
|
117
|
+
risk: riskFromImpact(impact),
|
|
118
|
+
confidence: confidenceFromImpact(impact),
|
|
119
|
+
signals: [
|
|
120
|
+
`failed-check:${key}`,
|
|
121
|
+
`impact:${impact}`,
|
|
122
|
+
`category:${category}`,
|
|
123
|
+
],
|
|
124
|
+
}));
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function inferSuggestedNextCommand(result) {
|
|
128
|
+
const actionKeys = new Set((result.topNextActions || []).map(item => item.key));
|
|
129
|
+
|
|
130
|
+
if (result.failed === 0) {
|
|
131
|
+
return 'npx claudex-setup augment';
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (
|
|
135
|
+
result.score < 50 ||
|
|
136
|
+
actionKeys.has('claudeMd') ||
|
|
137
|
+
actionKeys.has('hooks') ||
|
|
138
|
+
actionKeys.has('settingsPermissions') ||
|
|
139
|
+
actionKeys.has('permissionDeny')
|
|
140
|
+
) {
|
|
141
|
+
return 'npx claudex-setup setup';
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (result.score < 80) {
|
|
145
|
+
return 'npx claudex-setup suggest-only';
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return 'npx claudex-setup augment';
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function printLiteAudit(result, dir) {
|
|
152
|
+
console.log('');
|
|
153
|
+
console.log(colorize(' claudex-setup quick scan', 'bold'));
|
|
154
|
+
console.log(colorize(' ═══════════════════════════════════════', 'dim'));
|
|
155
|
+
console.log(colorize(` Scanning: ${dir}`, 'dim'));
|
|
156
|
+
console.log('');
|
|
157
|
+
console.log(` Score: ${colorize(`${result.score}/100`, 'bold')}`);
|
|
158
|
+
console.log('');
|
|
159
|
+
|
|
160
|
+
if (result.failed === 0) {
|
|
161
|
+
console.log(colorize(' Your Claude setup looks solid.', 'green'));
|
|
162
|
+
console.log(` Next: ${colorize(result.suggestedNextCommand, 'bold')}`);
|
|
163
|
+
console.log('');
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
console.log(colorize(' Top 3 things to fix right now:', 'magenta'));
|
|
168
|
+
console.log('');
|
|
169
|
+
result.liteSummary.topNextActions.forEach((item, index) => {
|
|
170
|
+
console.log(` ${index + 1}. ${colorize(item.name, 'bold')}`);
|
|
171
|
+
console.log(colorize(` Why: ${item.why}`, 'dim'));
|
|
172
|
+
console.log(colorize(` Fix: ${item.fix}`, 'dim'));
|
|
173
|
+
});
|
|
174
|
+
console.log('');
|
|
175
|
+
console.log(` Ready? Run: ${colorize(result.suggestedNextCommand, 'bold')}`);
|
|
176
|
+
console.log('');
|
|
177
|
+
}
|
|
178
|
+
|
|
48
179
|
async function audit(options) {
|
|
49
180
|
const silent = options.silent || false;
|
|
50
181
|
const ctx = new ProjectContext(options.dir);
|
|
@@ -91,6 +222,7 @@ async function audit(options) {
|
|
|
91
222
|
const organicEarned = organicPassed.reduce((sum, r) => sum + (weights[r.impact] || 5), 0);
|
|
92
223
|
const organicScore = maxScore > 0 ? Math.round((organicEarned / maxScore) * 100) : 0;
|
|
93
224
|
const quickWins = getQuickWins(failed);
|
|
225
|
+
const topNextActions = buildTopNextActions(failed, 5);
|
|
94
226
|
const result = {
|
|
95
227
|
score,
|
|
96
228
|
organicScore,
|
|
@@ -102,6 +234,12 @@ async function audit(options) {
|
|
|
102
234
|
stacks,
|
|
103
235
|
results,
|
|
104
236
|
quickWins: quickWins.map(({ key, name, impact, fix, category }) => ({ key, name, impact, category, fix })),
|
|
237
|
+
topNextActions,
|
|
238
|
+
};
|
|
239
|
+
result.suggestedNextCommand = inferSuggestedNextCommand(result);
|
|
240
|
+
result.liteSummary = {
|
|
241
|
+
topNextActions: topNextActions.slice(0, 3),
|
|
242
|
+
nextCommand: result.suggestedNextCommand,
|
|
105
243
|
};
|
|
106
244
|
|
|
107
245
|
// Silent mode: skip all output, just return result
|
|
@@ -119,6 +257,12 @@ async function audit(options) {
|
|
|
119
257
|
return result;
|
|
120
258
|
}
|
|
121
259
|
|
|
260
|
+
if (options.lite) {
|
|
261
|
+
printLiteAudit(result, options.dir);
|
|
262
|
+
sendInsights(result);
|
|
263
|
+
return result;
|
|
264
|
+
}
|
|
265
|
+
|
|
122
266
|
// Display results
|
|
123
267
|
console.log('');
|
|
124
268
|
console.log(colorize(' claudex-setup audit', 'bold'));
|
|
@@ -178,13 +322,16 @@ async function audit(options) {
|
|
|
178
322
|
console.log('');
|
|
179
323
|
}
|
|
180
324
|
|
|
181
|
-
//
|
|
182
|
-
if (
|
|
183
|
-
console.log(colorize(' ⚡
|
|
184
|
-
for (let i = 0; i <
|
|
185
|
-
const
|
|
186
|
-
console.log(` ${i + 1}. ${colorize(
|
|
187
|
-
console.log(colorize(`
|
|
325
|
+
// Top next actions
|
|
326
|
+
if (topNextActions.length > 0) {
|
|
327
|
+
console.log(colorize(' ⚡ Top 5 Next Actions', 'magenta'));
|
|
328
|
+
for (let i = 0; i < topNextActions.length; i++) {
|
|
329
|
+
const item = topNextActions[i];
|
|
330
|
+
console.log(` ${i + 1}. ${colorize(item.name, 'bold')}`);
|
|
331
|
+
console.log(colorize(` Why: ${item.why}`, 'dim'));
|
|
332
|
+
console.log(colorize(` Trace: ${item.signals.join(' | ')}`, 'dim'));
|
|
333
|
+
console.log(colorize(` Risk: ${item.risk} | Confidence: ${item.confidence}`, 'dim'));
|
|
334
|
+
console.log(colorize(` Fix: ${item.fix}`, 'dim'));
|
|
188
335
|
}
|
|
189
336
|
console.log('');
|
|
190
337
|
}
|
|
@@ -194,7 +341,7 @@ async function audit(options) {
|
|
|
194
341
|
console.log(` ${colorize(`${passed.length}/${applicable.length}`, 'bold')} checks passing${skipped.length > 0 ? colorize(` (${skipped.length} not applicable)`, 'dim') : ''}`);
|
|
195
342
|
|
|
196
343
|
if (failed.length > 0) {
|
|
197
|
-
console.log(`
|
|
344
|
+
console.log(` Next command: ${colorize(result.suggestedNextCommand, 'bold')}`);
|
|
198
345
|
}
|
|
199
346
|
|
|
200
347
|
console.log('');
|
package/src/claudex-sync.json
CHANGED
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"synced_from": "claudex",
|
|
3
|
-
"synced_at": "2026-
|
|
3
|
+
"synced_at": "2026-04-02T15:12:04Z",
|
|
4
4
|
"total_items": 1107,
|
|
5
5
|
"tested": 948,
|
|
6
|
-
"last_id": 1157
|
|
7
|
-
"domain_packs": 16,
|
|
8
|
-
"mcp_packs": 26,
|
|
9
|
-
"anti_patterns": 53,
|
|
10
|
-
"contract_version": "1.0.0"
|
|
6
|
+
"last_id": 1157
|
|
11
7
|
}
|
package/src/governance.js
CHANGED
|
@@ -386,6 +386,74 @@ function printGovernanceSummary(summary, options = {}) {
|
|
|
386
386
|
console.log('');
|
|
387
387
|
}
|
|
388
388
|
|
|
389
|
+
function renderGovernanceMarkdown(summary) {
|
|
390
|
+
const lines = [
|
|
391
|
+
'# Claudex Setup Governance Report',
|
|
392
|
+
'',
|
|
393
|
+
'This report summarizes the shipped governance surface for Claude Code rollout, review, and pilot approval.',
|
|
394
|
+
'',
|
|
395
|
+
'## Permission Profiles',
|
|
396
|
+
];
|
|
397
|
+
|
|
398
|
+
for (const profile of summary.permissionProfiles) {
|
|
399
|
+
lines.push(`- **${profile.label}** \`${profile.key}\` | risk: \`${profile.risk}\` | defaultMode: \`${profile.defaultMode}\``);
|
|
400
|
+
lines.push(` - Use when: ${profile.useWhen}`);
|
|
401
|
+
lines.push(` - Behavior: ${profile.behavior}`);
|
|
402
|
+
if (Array.isArray(profile.deny) && profile.deny.length > 0) {
|
|
403
|
+
lines.push(` - Deny rules: ${profile.deny.join(', ')}`);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
lines.push('', '## Hook Registry');
|
|
408
|
+
for (const hook of summary.hookRegistry) {
|
|
409
|
+
lines.push(`- **${hook.key}** \`${hook.triggerPoint}${hook.matcher ? ` ${hook.matcher}` : ''}\` | risk: \`${hook.risk}\``);
|
|
410
|
+
lines.push(` - File: ${hook.file}`);
|
|
411
|
+
lines.push(` - Purpose: ${hook.purpose}`);
|
|
412
|
+
lines.push(` - Dry run: ${hook.dryRunExample}`);
|
|
413
|
+
lines.push(` - Rollback: ${hook.rollbackPath}`);
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
lines.push('', '## Policy Packs');
|
|
417
|
+
for (const pack of summary.policyPacks) {
|
|
418
|
+
lines.push(`- **${pack.label}**`);
|
|
419
|
+
lines.push(` - Use when: ${pack.useWhen}`);
|
|
420
|
+
lines.push(` - Modules: ${pack.modules.join(', ')}`);
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
lines.push('', `## Domain Packs (${summary.domainPacks.length})`);
|
|
424
|
+
for (const pack of summary.domainPacks) {
|
|
425
|
+
lines.push(`- **${pack.label}**: ${pack.useWhen}`);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
lines.push('', `## MCP Packs (${summary.mcpPacks.length})`);
|
|
429
|
+
for (const pack of summary.mcpPacks) {
|
|
430
|
+
lines.push(`- **${pack.label}**: ${Object.keys(pack.servers).join(', ')}`);
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
lines.push('', '## Pilot Rollout Kit', '### Recommended Scope');
|
|
434
|
+
for (const item of summary.pilotRolloutKit.recommendedScope) {
|
|
435
|
+
lines.push(`- ${item}`);
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
lines.push('', '### Approvals');
|
|
439
|
+
for (const item of summary.pilotRolloutKit.approvals) {
|
|
440
|
+
lines.push(`- ${item}`);
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
lines.push('', '### Success Metrics');
|
|
444
|
+
for (const item of summary.pilotRolloutKit.successMetrics) {
|
|
445
|
+
lines.push(`- ${item}`);
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
lines.push('', '### Rollback Expectations');
|
|
449
|
+
for (const item of summary.pilotRolloutKit.rollbackExpectations) {
|
|
450
|
+
lines.push(`- ${item}`);
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
lines.push('');
|
|
454
|
+
return lines.join('\n');
|
|
455
|
+
}
|
|
456
|
+
|
|
389
457
|
module.exports = {
|
|
390
458
|
PERMISSION_PROFILES,
|
|
391
459
|
getPermissionProfile,
|
|
@@ -394,4 +462,5 @@ module.exports = {
|
|
|
394
462
|
buildSettingsForProfile,
|
|
395
463
|
getGovernanceSummary,
|
|
396
464
|
printGovernanceSummary,
|
|
465
|
+
renderGovernanceMarkdown,
|
|
397
466
|
};
|
package/src/insights.js
CHANGED
|
@@ -87,7 +87,8 @@ function sendInsights(auditResult) {
|
|
|
87
87
|
*/
|
|
88
88
|
function getLocalInsights(auditResult) {
|
|
89
89
|
const { results } = auditResult;
|
|
90
|
-
const
|
|
90
|
+
const applicable = results.filter(r => r.passed !== null);
|
|
91
|
+
const failed = applicable.filter(r => r.passed === false);
|
|
91
92
|
|
|
92
93
|
// Top 3 most impactful fixes
|
|
93
94
|
const impactOrder = { critical: 3, high: 2, medium: 1 };
|
|
@@ -98,7 +99,7 @@ function getLocalInsights(auditResult) {
|
|
|
98
99
|
|
|
99
100
|
// Score breakdown by category
|
|
100
101
|
const categories = {};
|
|
101
|
-
for (const r of
|
|
102
|
+
for (const r of applicable) {
|
|
102
103
|
const cat = r.category || 'other';
|
|
103
104
|
if (!categories[cat]) categories[cat] = { passed: 0, total: 0 };
|
|
104
105
|
categories[cat].total++;
|
package/src/techniques.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* CLAUDEX Technique Database
|
|
3
|
-
* Curated from
|
|
3
|
+
* Curated from 1107 verified techniques, filtered to actionable setup recommendations.
|
|
4
4
|
* Each technique includes: what to check, how to fix, impact level.
|
|
5
5
|
*/
|
|
6
6
|
|
|
@@ -425,9 +425,11 @@ const TECHNIQUES = {
|
|
|
425
425
|
id: 8801,
|
|
426
426
|
name: 'Hooks configured in settings',
|
|
427
427
|
check: (ctx) => {
|
|
428
|
-
const
|
|
429
|
-
|
|
430
|
-
|
|
428
|
+
const shared = ctx.jsonFile('.claude/settings.json');
|
|
429
|
+
const local = ctx.jsonFile('.claude/settings.local.json');
|
|
430
|
+
const hasSharedHooks = shared && shared.hooks && Object.keys(shared.hooks).length > 0;
|
|
431
|
+
const hasLocalHooks = local && local.hooks && Object.keys(local.hooks).length > 0;
|
|
432
|
+
return hasSharedHooks || hasLocalHooks;
|
|
431
433
|
},
|
|
432
434
|
impact: 'high',
|
|
433
435
|
rating: 4,
|
|
@@ -440,9 +442,9 @@ const TECHNIQUES = {
|
|
|
440
442
|
id: 8802,
|
|
441
443
|
name: 'PreToolUse hook configured',
|
|
442
444
|
check: (ctx) => {
|
|
443
|
-
const
|
|
444
|
-
|
|
445
|
-
return !!
|
|
445
|
+
const shared = ctx.jsonFile('.claude/settings.json');
|
|
446
|
+
const local = ctx.jsonFile('.claude/settings.local.json');
|
|
447
|
+
return !!(shared?.hooks?.PreToolUse || local?.hooks?.PreToolUse);
|
|
446
448
|
},
|
|
447
449
|
impact: 'high',
|
|
448
450
|
rating: 4,
|
|
@@ -455,9 +457,9 @@ const TECHNIQUES = {
|
|
|
455
457
|
id: 8803,
|
|
456
458
|
name: 'PostToolUse hook configured',
|
|
457
459
|
check: (ctx) => {
|
|
458
|
-
const
|
|
459
|
-
|
|
460
|
-
return !!
|
|
460
|
+
const shared = ctx.jsonFile('.claude/settings.json');
|
|
461
|
+
const local = ctx.jsonFile('.claude/settings.local.json');
|
|
462
|
+
return !!(shared?.hooks?.PostToolUse || local?.hooks?.PostToolUse);
|
|
461
463
|
},
|
|
462
464
|
impact: 'high',
|
|
463
465
|
rating: 4,
|
|
@@ -470,9 +472,10 @@ const TECHNIQUES = {
|
|
|
470
472
|
id: 8804,
|
|
471
473
|
name: 'SessionStart hook configured',
|
|
472
474
|
check: (ctx) => {
|
|
473
|
-
const
|
|
474
|
-
|
|
475
|
-
return
|
|
475
|
+
const shared = ctx.jsonFile('.claude/settings.json');
|
|
476
|
+
const local = ctx.jsonFile('.claude/settings.local.json');
|
|
477
|
+
if (!(shared?.hooks || local?.hooks)) return false;
|
|
478
|
+
return !!(shared?.hooks?.SessionStart || local?.hooks?.SessionStart);
|
|
476
479
|
},
|
|
477
480
|
impact: 'medium',
|
|
478
481
|
rating: 4,
|