claudex-setup 0.2.0 → 0.3.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 CHANGED
@@ -206,7 +206,7 @@ npx claudex-setup --help # Show help
206
206
 
207
207
  ## Backed by Research
208
208
 
209
- Every check and template is derived from the [CLAUDEX](https://github.com/DnaFin/claudex) research catalog — a systematic audit of 1,107 verified Claude Code techniques across 13 research categories. This includes findings from all 73 official Claude Code documentation pages, community reports, and hands-on experiments.
209
+ Every check and template is derived from the [CLAUDEX](https://github.com/DnaFin/claudex-setup) research catalog — a systematic audit of 1,107 verified Claude Code techniques across 13 research categories. This includes findings from all 73 official Claude Code documentation pages, community reports, and hands-on experiments.
210
210
 
211
211
  The knowledge base is continuously updated. Run `npx claudex-setup` periodically to pick up new checks and improved templates.
212
212
 
package/bin/cli.js CHANGED
@@ -14,14 +14,17 @@ const HELP = `
14
14
  Powered by 1,107 verified techniques.
15
15
 
16
16
  Usage:
17
- npx claudex-setup Run audit on current directory
18
- npx claudex-setup audit Same as above
19
- npx claudex-setup setup Apply recommended configuration
20
- npx claudex-setup setup --auto Apply all recommendations without prompts
17
+ npx claudex-setup Run audit on current directory
18
+ npx claudex-setup audit Same as above
19
+ npx claudex-setup setup Apply recommended configuration
20
+ npx claudex-setup setup --auto Apply all without prompts
21
+ npx claudex-setup interactive Step-by-step guided wizard
22
+ npx claudex-setup watch Monitor changes and re-audit live
23
+ npx claudex-setup badge Generate shields.io badge markdown
21
24
 
22
25
  Options:
23
- --verbose Show detailed analysis
24
- --json Output as JSON
26
+ --verbose Show all recommendations (not just critical/high)
27
+ --json Output as JSON (for CI pipelines)
25
28
  --help Show this help
26
29
  --version Show version
27
30
  `;
@@ -45,7 +48,20 @@ async function main() {
45
48
  };
46
49
 
47
50
  try {
48
- if (command === 'setup') {
51
+ if (command === 'badge') {
52
+ const { getBadgeMarkdown } = require('../src/badge');
53
+ const result = await audit({ ...options, silent: true });
54
+ console.log(getBadgeMarkdown(result.score));
55
+ console.log('');
56
+ console.log('Add this to your README.md');
57
+ process.exit(0);
58
+ } else if (command === 'interactive' || command === 'wizard') {
59
+ const { interactive } = require('../src/interactive');
60
+ await interactive(options);
61
+ } else if (command === 'watch') {
62
+ const { watch } = require('../src/watch');
63
+ await watch(options);
64
+ } else if (command === 'setup') {
49
65
  await setup(options);
50
66
  } else {
51
67
  await audit(options);
package/package.json CHANGED
@@ -1,11 +1,17 @@
1
1
  {
2
2
  "name": "claudex-setup",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Audit and optimize any project for Claude Code. Powered by 1107 verified techniques.",
5
5
  "main": "src/index.js",
6
6
  "bin": {
7
7
  "claudex-setup": "bin/cli.js"
8
8
  },
9
+ "files": [
10
+ "bin",
11
+ "src",
12
+ "README.md",
13
+ "CHANGELOG.md"
14
+ ],
9
15
  "scripts": {
10
16
  "start": "node bin/cli.js",
11
17
  "test": "node test/run.js"
@@ -25,7 +31,7 @@
25
31
  "license": "MIT",
26
32
  "repository": {
27
33
  "type": "git",
28
- "url": "https://github.com/DnaFin/claudex"
34
+ "url": "git+https://github.com/DnaFin/claudex-setup.git"
29
35
  },
30
36
  "engines": {
31
37
  "node": ">=18.0.0"
package/src/audit.js CHANGED
@@ -4,6 +4,7 @@
4
4
 
5
5
  const { TECHNIQUES, STACKS } = require('./techniques');
6
6
  const { ProjectContext } = require('./context');
7
+ const { getBadgeMarkdown } = require('./badge');
7
8
 
8
9
  const COLORS = {
9
10
  reset: '\x1b[0m',
@@ -27,7 +28,24 @@ function progressBar(score, max = 100, width = 20) {
27
28
  return colorize('█'.repeat(filled), color) + colorize('░'.repeat(empty), 'dim');
28
29
  }
29
30
 
31
+ const EFFORT_ORDER = { critical: 0, high: 1, medium: 2 };
32
+
33
+ function getQuickWins(failed) {
34
+ // Quick wins = medium impact items first (easiest), then high, sorted by name length (shorter = simpler)
35
+ return [...failed]
36
+ .sort((a, b) => {
37
+ const effortA = EFFORT_ORDER[a.impact] ?? 3;
38
+ const effortB = EFFORT_ORDER[b.impact] ?? 3;
39
+ // Prefer medium (easiest to fix), then high, then critical
40
+ if (effortA !== effortB) return effortB - effortA;
41
+ // Tie-break by fix length (shorter fix description = likely simpler)
42
+ return (a.fix || '').length - (b.fix || '').length;
43
+ })
44
+ .slice(0, 3);
45
+ }
46
+
30
47
  async function audit(options) {
48
+ const silent = options.silent || false;
31
49
  const ctx = new ProjectContext(options.dir);
32
50
  const stacks = ctx.detectStacks(STACKS);
33
51
  const results = [];
@@ -54,9 +72,14 @@ async function audit(options) {
54
72
  const earnedScore = passed.reduce((sum, r) => sum + (weights[r.impact] || 5), 0);
55
73
  const score = Math.round((earnedScore / maxScore) * 100);
56
74
 
75
+ // Silent mode: skip all output, just return result
76
+ if (silent) {
77
+ return { score, passed: passed.length, failed: failed.length, stacks, results };
78
+ }
79
+
57
80
  if (options.json) {
58
81
  console.log(JSON.stringify({ score, stacks, passed: passed.length, failed: failed.length, results }, null, 2));
59
- return;
82
+ return { score, passed: passed.length, failed: failed.length, stacks, results };
60
83
  }
61
84
 
62
85
  // Display results
@@ -115,6 +138,18 @@ async function audit(options) {
115
138
  console.log('');
116
139
  }
117
140
 
141
+ // Quick wins
142
+ if (failed.length > 0) {
143
+ const quickWins = getQuickWins(failed);
144
+ console.log(colorize(' ⚡ Quick wins (easiest fixes first)', 'magenta'));
145
+ for (let i = 0; i < quickWins.length; i++) {
146
+ const r = quickWins[i];
147
+ console.log(` ${i + 1}. ${colorize(r.name, 'bold')}`);
148
+ console.log(colorize(` → ${r.fix}`, 'dim'));
149
+ }
150
+ console.log('');
151
+ }
152
+
118
153
  // Summary
119
154
  console.log(colorize(' ─────────────────────────────────────', 'dim'));
120
155
  console.log(` ${colorize(`${passed.length}/${results.length}`, 'bold')} checks passing`);
@@ -123,12 +158,14 @@ async function audit(options) {
123
158
  console.log(` Run ${colorize('npx claudex-setup setup', 'bold')} to fix automatically`);
124
159
  }
125
160
 
161
+ console.log('');
162
+ console.log(` Add to README: ${getBadgeMarkdown(score)}`);
126
163
  console.log('');
127
164
  console.log(colorize(' Powered by CLAUDEX - 1,107 verified Claude Code techniques', 'dim'));
128
- console.log(colorize(' https://github.com/naorp/claudex-setup', 'dim'));
165
+ console.log(colorize(' https://github.com/DnaFin/claudex-setup', 'dim'));
129
166
  console.log('');
130
167
 
131
- return { score, passed: passed.length, failed: failed.length, stacks };
168
+ return { score, passed: passed.length, failed: failed.length, stacks, results };
132
169
  }
133
170
 
134
171
  module.exports = { audit };
package/src/badge.js ADDED
@@ -0,0 +1,13 @@
1
+ function getBadgeUrl(score) {
2
+ const color = score >= 80 ? 'brightgreen' : score >= 60 ? 'yellow' : score >= 40 ? 'orange' : 'red';
3
+ const label = encodeURIComponent('Claude Code Ready');
4
+ const message = encodeURIComponent(`${score}/100`);
5
+ return `https://img.shields.io/badge/${label}-${message}-${color}`;
6
+ }
7
+
8
+ function getBadgeMarkdown(score) {
9
+ const url = getBadgeUrl(score);
10
+ return `[![Claude Code Ready](${url})](https://github.com/DnaFin/claudex-setup)`;
11
+ }
12
+
13
+ module.exports = { getBadgeUrl, getBadgeMarkdown };
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Interactive mode - guides users step-by-step through Claude Code setup.
3
+ * Uses Node.js readline (zero dependencies).
4
+ */
5
+
6
+ const readline = require('readline');
7
+ const { TECHNIQUES, STACKS } = require('./techniques');
8
+ const { ProjectContext } = require('./context');
9
+ const { setup } = require('./setup');
10
+
11
+ const COLORS = {
12
+ reset: '\x1b[0m', bold: '\x1b[1m', dim: '\x1b[2m',
13
+ red: '\x1b[31m', green: '\x1b[32m', yellow: '\x1b[33m',
14
+ blue: '\x1b[36m', magenta: '\x1b[35m',
15
+ };
16
+ const c = (text, color) => `${COLORS[color] || ''}${text}${COLORS.reset}`;
17
+
18
+ function ask(rl, question) {
19
+ return new Promise(resolve => rl.question(question, resolve));
20
+ }
21
+
22
+ async function interactive(options) {
23
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
24
+ const ctx = new ProjectContext(options.dir);
25
+ const stacks = ctx.detectStacks(STACKS);
26
+
27
+ console.log('');
28
+ console.log(c(' ╔═══════════════════════════════════════╗', 'magenta'));
29
+ console.log(c(' ║ claudex-setup interactive wizard ║', 'magenta'));
30
+ console.log(c(' ╚═══════════════════════════════════════╝', 'magenta'));
31
+ console.log('');
32
+
33
+ if (stacks.length > 0) {
34
+ console.log(c(` Detected stack: ${stacks.map(s => s.label).join(', ')}`, 'blue'));
35
+ }
36
+ console.log(c(` Working directory: ${options.dir}`, 'dim'));
37
+ console.log('');
38
+
39
+ // Run audit silently
40
+ const results = [];
41
+ for (const [key, technique] of Object.entries(TECHNIQUES)) {
42
+ results.push({ key, ...technique, passed: technique.check(ctx) });
43
+ }
44
+ const failed = results.filter(r => !r.passed);
45
+ const passed = results.filter(r => r.passed);
46
+
47
+ console.log(` ${c(`${passed.length}/${results.length}`, 'bold')} checks already passing.`);
48
+ console.log(` ${c(String(failed.length), 'yellow')} improvements available.`);
49
+ console.log('');
50
+
51
+ if (failed.length === 0) {
52
+ console.log(c(' Your project is fully optimized for Claude Code!', 'green'));
53
+ rl.close();
54
+ return;
55
+ }
56
+
57
+ // Group by priority
58
+ const critical = failed.filter(r => r.impact === 'critical');
59
+ const high = failed.filter(r => r.impact === 'high');
60
+ const medium = failed.filter(r => r.impact === 'medium');
61
+ const groups = [
62
+ { label: 'Critical', color: 'red', items: critical },
63
+ { label: 'High Impact', color: 'yellow', items: high },
64
+ { label: 'Recommended', color: 'blue', items: medium },
65
+ ].filter(g => g.items.length > 0);
66
+
67
+ const toFix = [];
68
+
69
+ for (const group of groups) {
70
+ console.log(c(` ── ${group.label} (${group.items.length}) ──`, group.color));
71
+ console.log('');
72
+
73
+ for (const item of group.items) {
74
+ console.log(` ${c(item.name, 'bold')}`);
75
+ console.log(c(` ${item.fix}`, 'dim'));
76
+ const answer = await ask(rl, c(' Fix this? (y/n/q) ', 'magenta'));
77
+
78
+ if (answer.toLowerCase() === 'q') {
79
+ console.log('');
80
+ console.log(c(' Stopping wizard.', 'dim'));
81
+ break;
82
+ }
83
+ if (answer.toLowerCase() === 'y' || answer.toLowerCase() === '') {
84
+ toFix.push(item.key);
85
+ console.log(c(' → Will fix', 'green'));
86
+ } else {
87
+ console.log(c(' → Skipped', 'dim'));
88
+ }
89
+ console.log('');
90
+ }
91
+ }
92
+
93
+ rl.close();
94
+
95
+ if (toFix.length === 0) {
96
+ console.log(c(' No changes selected.', 'dim'));
97
+ return;
98
+ }
99
+
100
+ console.log('');
101
+ console.log(c(` Applying ${toFix.length} fixes...`, 'bold'));
102
+ console.log('');
103
+
104
+ // Run setup in auto mode
105
+ await setup({ ...options, auto: true });
106
+
107
+ console.log('');
108
+ console.log(c(' Done! Run `npx claudex-setup` to see your new score.', 'green'));
109
+ }
110
+
111
+ module.exports = { interactive };