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.
@@ -0,0 +1,64 @@
1
+ # Using claudex-setup from inside Claude Code
2
+
3
+ ## Skill: Audit Repo
4
+
5
+ Add this to `.claude/skills/audit-repo.md` in any project:
6
+
7
+ ```markdown
8
+ ---
9
+ name: audit-repo
10
+ description: Run claudex-setup audit on the current project and show score + top gaps
11
+ ---
12
+
13
+ Run `npx claudex-setup --json` on the current project directory.
14
+ Parse the JSON output and present:
15
+ 1. Score X/100
16
+ 2. Top 3 critical/high gaps with fix descriptions
17
+ 3. Suggest next command based on score
18
+
19
+ $ARGUMENTS — optional: --lite for quick scan
20
+ ```
21
+
22
+ ## Hook: Auto-audit on SessionStart
23
+
24
+ Add to `.claude/settings.json`:
25
+
26
+ ```json
27
+ {
28
+ "hooks": {
29
+ "SessionStart": [
30
+ {
31
+ "hooks": [
32
+ {
33
+ "type": "command",
34
+ "command": "node -e \"try{const r=require('child_process').execSync('npx claudex-setup --json 2>/dev/null',{timeout:15000}).toString();const d=JSON.parse(r);if(d.score<50)console.log(JSON.stringify({systemMessage:'⚠️ Claude Code setup score: '+d.score+'/100. Consider running: npx claudex-setup --lite'}))}catch(e){console.log('{}')}\"",
35
+ "timeout": 20,
36
+ "statusMessage": "Checking Claude Code setup..."
37
+ }
38
+ ]
39
+ }
40
+ ]
41
+ }
42
+ }
43
+ ```
44
+
45
+ ## Agent: Setup Advisor
46
+
47
+ Add to `.claude/agents/setup-advisor.md`:
48
+
49
+ ```markdown
50
+ ---
51
+ name: setup-advisor
52
+ description: Analyzes Claude Code setup and recommends improvements
53
+ tools: [Bash, Read, Glob, Grep]
54
+ model: haiku
55
+ maxTurns: 10
56
+ ---
57
+
58
+ You are a Claude Code setup advisor.
59
+
60
+ 1. Run `npx claudex-setup augment --json` on the current project
61
+ 2. Analyze gaps and strengths
62
+ 3. Recommend top 5 improvements with rationale
63
+ 4. If user approves, guide them through applying changes
64
+ ```
@@ -0,0 +1,9 @@
1
+ {
2
+ "article": {
3
+ "title": "Your Claude Code project scores 10/100. Here's how to fix it in 60 seconds.",
4
+ "published": false,
5
+ "tags": ["claude", "ai", "productivity", "devtools"],
6
+ "series": "Claude Code Optimization",
7
+ "body_markdown": "After cataloging **1,107 Claude Code entries** and verifying **948 with real evidence**, I found that most projects use barely 10% of what's available.\n\nI built a CLI that scores your project:\n\n```bash\nnpx claudex-setup\n```\n\nMost projects score **10-20 out of 100**. After running setup, they jump to **70+**.\n\n## The Top 10 Things You're Missing\n\n### 1. CLAUDE.md (Critical)\n\nClaude reads this file at the start of every session. Without it, Claude doesn't know your build commands, code style, or project rules.\n\nOur tool generates a smart CLAUDE.md that detects your framework, TypeScript config, and creates a Mermaid architecture diagram automatically.\n\n### 2. Mermaid Architecture Diagrams (73% Token Savings)\n\nA Mermaid diagram in CLAUDE.md gives Claude your project structure in a fraction of the tokens that prose requires.\n\n### 3. Hooks > CLAUDE.md Rules (100% vs 80%)\n\nCLAUDE.md instructions are advisory (~80% compliance). Hooks are deterministic (100%). Auto-lint after every edit. Every time.\n\n### 4. Custom Commands\n\nStop typing the same prompts. Create `/test`, `/deploy`, `/review` in `.claude/commands/`.\n\n### 5. Verification Loops (The #1 Best Practice)\n\n> *This is the single highest-leverage thing you can do.* — Anthropic Best Practices\n\nClaude performs dramatically better when it can verify its own work.\n\n### 6. XML Tags (30% Quality Boost)\n\nUse `<constraints>`, `<validation>` in CLAUDE.md for unambiguous instructions.\n\n### 7. Secrets Protection\n\nClaude Code loads `.env` automatically. Add deny rules to prevent reading sensitive files.\n\n### 8. /security-review\n\nBuilt-in OWASP Top 10 scanning. Most people don't know this command exists.\n\n### 9. Custom Agents\n\nSpecialized subagents: security-reviewer, test-writer in `.claude/agents/`.\n\n### 10. Skills (On-Demand Knowledge)\n\nReusable skills package expertise that Claude can load on demand.\n\n## Try It Now\n\n```bash\nnpx claudex-setup --lite # Quick scan\nnpx claudex-setup # Full audit\nnpx claudex-setup --snapshot # Save evidence artifact\nnpx claudex-setup governance --out governance.md\n```\n\nFree, open source, zero dependencies.\n\n**GitHub:** [github.com/DnaFin/claudex-setup](https://github.com/DnaFin/claudex-setup)\n**npm:** [npmjs.com/package/claudex-setup](https://www.npmjs.com/package/claudex-setup)\n\n---\n\n*Built from a research catalog of 1,107 Claude Code entries, 948 verified with evidence.*"
8
+ }
9
+ }
@@ -0,0 +1,160 @@
1
+ # Launch Posts — Ready to Publish
2
+
3
+ ## Post 1: Reddit r/ClaudeAI
4
+
5
+ **Title:** I built a tool that audits your project for Claude Code optimization — scores you 0-100
6
+
7
+ **Body:**
8
+ After cataloging 1,107 Claude Code entries and verifying 948 of them with evidence, I built a CLI that checks if your project is actually set up to get the most out of Claude Code.
9
+
10
+ Most projects score around 10-20/100. After running setup, they jump to 70+.
11
+
12
+ ```
13
+ npx claudex-setup
14
+ ```
15
+
16
+ It checks for: CLAUDE.md, hooks, custom commands, skills, agents, Mermaid diagrams, XML tags, path rules, MCP config, permissions, and more.
17
+
18
+ Then `npx claudex-setup setup` auto-creates everything that's missing, tailored to your stack (React, Python, TypeScript, etc).
19
+
20
+ Zero dependencies. No API keys. Runs entirely local.
21
+
22
+ GitHub: https://github.com/DnaFin/claudex-setup
23
+
24
+ Would love feedback!
25
+
26
+ ---
27
+
28
+ ## Post 2: Reddit r/ChatGPTCoding
29
+
30
+ **Title:** Your Claude Code project is probably running at 10% efficiency. Here's how to check.
31
+
32
+ **Body:**
33
+ I spent weeks cataloging every Claude Code feature, technique, and best practice — 1,107 total, 948 verified with real evidence.
34
+
35
+ Turns out most projects are missing basic stuff that makes a huge difference:
36
+ - No CLAUDE.md (Claude doesn't know your project conventions)
37
+ - No hooks (no auto-lint, no auto-test)
38
+ - No custom commands (repeating the same prompts manually)
39
+ - No Mermaid diagrams (wasting 73% more tokens on prose descriptions)
40
+
41
+ Built a quick checker:
42
+ ```
43
+ npx claudex-setup
44
+ ```
45
+
46
+ Scores your project 0-100, tells you exactly what to fix, and can auto-apply everything.
47
+
48
+ Free, open source, zero dependencies: https://github.com/DnaFin/claudex-setup
49
+
50
+ ---
51
+
52
+ ## Post 3: Dev.to Article
53
+
54
+ **Title:** 1,107 Claude Code Entries: What I Learned Building the Most Comprehensive Catalog
55
+
56
+ **Body (excerpt):**
57
+ I set out to catalog every single Claude Code capability, technique, and best practice. After repeated research cycles, I have 1,107 entries — 948 verified with real evidence.
58
+
59
+ Here are the top 10 things most developers are missing:
60
+
61
+ 1. **CLAUDE.md** — Claude reads this at the start of every session. Without it, Claude doesn't know your build commands, code style, or project rules.
62
+
63
+ 2. **Mermaid diagrams** — A Mermaid architecture diagram saves 73% tokens compared to describing your project in prose.
64
+
65
+ 3. **Hooks** — Auto-lint after every edit. Auto-test before every commit. Hooks fire 100% of the time, CLAUDE.md rules fire ~80%.
66
+
67
+ 4. **Custom commands** — `/test`, `/deploy`, `/review` — package your repeated workflows.
68
+
69
+ 5. **Verification loops** — Tell Claude how to verify its own work. Include test commands in CLAUDE.md.
70
+
71
+ 6. **Path-specific rules** — Different conventions for frontend vs backend files.
72
+
73
+ 7. **XML tags** — `<constraints>`, `<validation>` in CLAUDE.md = unambiguous instructions.
74
+
75
+ 8. **Custom agents** — Security reviewer, test writer — specialized subagents for focused tasks.
76
+
77
+ 9. **Skills** — Domain-specific workflows that load on demand, not every session.
78
+
79
+ 10. **MCP servers** — Connect Claude to your database, ticket system, Slack.
80
+
81
+ I packaged this into a CLI that checks your project:
82
+ ```
83
+ npx claudex-setup
84
+ ```
85
+
86
+ Full catalog: https://github.com/DnaFin/claudex-setup
87
+
88
+ ---
89
+
90
+ ## Post 4: Twitter/X Thread
91
+
92
+ **Tweet 1:**
93
+ I cataloged 1,107 Claude Code entries and verified 948 of them with evidence.
94
+
95
+ Most projects use less than 5% of what Claude Code can do.
96
+
97
+ Here's a free tool that checks your project and tells you exactly what's missing:
98
+
99
+ npx claudex-setup
100
+
101
+ Thread 🧵👇
102
+
103
+ **Tweet 2:**
104
+ The #1 thing you're probably missing: CLAUDE.md
105
+
106
+ It's a file Claude reads at the start of every session. Without it, Claude doesn't know your:
107
+ - Build commands
108
+ - Code style
109
+ - Testing framework
110
+ - Project architecture
111
+
112
+ Takes 2 minutes to create. Impact: massive.
113
+
114
+ **Tweet 3:**
115
+ #2: Mermaid diagrams in CLAUDE.md
116
+
117
+ A few hundred tokens of Mermaid syntax conveys what takes thousands of tokens in prose.
118
+
119
+ 73% token savings = faster responses, lower cost, better context.
120
+
121
+ **Tweet 4:**
122
+ #3: Hooks > CLAUDE.md rules
123
+
124
+ CLAUDE.md instructions = ~80% compliance
125
+ Hooks = 100% enforcement
126
+
127
+ Auto-lint after edits. Block commits without tests. Prevent force-push.
128
+
129
+ Hooks are deterministic. Instructions are advisory.
130
+
131
+ **Tweet 5:**
132
+ Want to check your project in 10 seconds?
133
+
134
+ npx claudex-setup
135
+
136
+ Scores 0-100. Shows what's missing. Auto-fixes with `setup`.
137
+
138
+ Free. Open source. Zero dependencies.
139
+
140
+ https://github.com/DnaFin/claudex-setup
141
+
142
+ ---
143
+
144
+ ## Post 5: Hacker News (Show HN)
145
+
146
+ **Title:** Show HN: claudex-setup – Audit any project for Claude Code optimization (1,107 entries)
147
+
148
+ **Body:**
149
+ I built a CLI tool that scores your project against Claude Code best practices.
150
+
151
+ After researching 1,107 entries (948 verified with evidence), most projects score 10-20 out of 100 because they're missing basic optimizations like CLAUDE.md files, hooks, custom commands, and architecture diagrams.
152
+
153
+ npx claudex-setup → audit (0-100 score)
154
+ npx claudex-setup setup → auto-fix
155
+
156
+ Detects your stack (React, Python, TS, Rust, Go, etc) and tailors recommendations.
157
+
158
+ Zero dependencies, no API keys, runs locally.
159
+
160
+ https://github.com/DnaFin/claudex-setup
@@ -0,0 +1,30 @@
1
+ # Pilot Rollout Kit
2
+
3
+ ## Suggested pilot shape
4
+
5
+ 1. Choose 1-2 repos with active owners and low blast radius.
6
+ 2. Run `discover`, `suggest-only`, and `governance` before any write flow.
7
+ 3. Pick one permission profile and document why it fits the pilot.
8
+ 4. Run `benchmark` to capture a baseline and expected value.
9
+ 5. Use `plan` and selective `apply` for the first write batch.
10
+
11
+ ## Approval checklist
12
+
13
+ - Engineering owner approves scope.
14
+ - Security owner approves permission profile and hooks.
15
+ - Pilot owner records success metrics.
16
+ - Rollback expectations are documented before apply.
17
+
18
+ ## Success metrics
19
+
20
+ - readiness score delta
21
+ - organic score delta
22
+ - number of proposal bundles accepted
23
+ - rollback-free apply rate
24
+ - time to first useful Claude workflow
25
+
26
+ ## Rollback expectations
27
+
28
+ - every apply run must produce a rollback artifact
29
+ - rejected starter artifacts are deleted using the rollback manifest
30
+ - rollback decisions are logged in the activity trail
@@ -0,0 +1,31 @@
1
+ # claudex-setup Release Checklist
2
+
3
+ Use this before tagging or publishing a release.
4
+
5
+ ## Code And Packaging
6
+
7
+ - bump `package.json` version intentionally
8
+ - update `CHANGELOG.md` with the shipped changes
9
+ - run `npm test`
10
+ - run `npm pack --dry-run`
11
+
12
+ ## Product Surface Consistency
13
+
14
+ - verify `README.md` reflects the current CLI surface
15
+ - verify `docs/index.html` reflects the current CLI surface
16
+ - verify new flags and commands appear in `--help`
17
+ - verify proof numbers and public claims match the current state
18
+
19
+ ## Trust And Governance
20
+
21
+ - run `npx claudex-setup --snapshot` on the repo itself
22
+ - run `npx claudex-setup governance --out governance.md`
23
+ - verify MCP package names and env preflight behavior for changed packs
24
+ - verify no recommendation regressions on known scenarios
25
+
26
+ ## Release Readiness
27
+
28
+ - confirm npm publish target and account are correct
29
+ - confirm git branch / commit matches the intended release
30
+ - confirm any new templates or content files are included in the package
31
+ - capture one final note about what changed and what still remains intentionally deferred
package/package.json CHANGED
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "claudex-setup",
3
- "version": "1.10.2",
4
- "description": "Audit and improve Claude Code readiness with discover, plan, apply, governance, and benchmark workflows.",
3
+ "version": "1.11.0",
4
+ "description": "Score your repo's Claude Code setup against 62 checks. See gaps, apply fixes selectively with rollback, govern hooks and permissions, and benchmark impact — without breaking existing config.",
5
5
  "main": "src/index.js",
6
6
  "bin": {
7
7
  "claudex-setup": "bin/cli.js"
8
8
  },
9
9
  "files": [
10
10
  "bin",
11
+ "content",
11
12
  "src",
12
13
  "README.md",
13
14
  "CHANGELOG.md"
package/src/activity.js CHANGED
@@ -1,5 +1,6 @@
1
1
  const fs = require('fs');
2
2
  const path = require('path');
3
+ const { version } = require('../package.json');
3
4
 
4
5
  function timestampId() {
5
6
  return new Date().toISOString().replace(/[:.]/g, '-');
@@ -9,9 +10,11 @@ function ensureArtifactDirs(dir) {
9
10
  const root = path.join(dir, '.claude', 'claudex-setup');
10
11
  const activityDir = path.join(root, 'activity');
11
12
  const rollbackDir = path.join(root, 'rollbacks');
13
+ const snapshotDir = path.join(root, 'snapshots');
12
14
  fs.mkdirSync(activityDir, { recursive: true });
13
15
  fs.mkdirSync(rollbackDir, { recursive: true });
14
- return { root, activityDir, rollbackDir };
16
+ fs.mkdirSync(snapshotDir, { recursive: true });
17
+ return { root, activityDir, rollbackDir, snapshotDir };
15
18
  }
16
19
 
17
20
  function writeJson(filePath, payload) {
@@ -53,8 +56,246 @@ function writeRollbackArtifact(dir, payload) {
53
56
  };
54
57
  }
55
58
 
59
+ function summarizeSnapshot(snapshotKind, payload) {
60
+ if (snapshotKind === 'audit') {
61
+ return {
62
+ score: payload.score,
63
+ organicScore: payload.organicScore,
64
+ passed: payload.passed,
65
+ failed: payload.failed,
66
+ checkCount: payload.checkCount,
67
+ suggestedNextCommand: payload.suggestedNextCommand,
68
+ topActionKeys: Array.isArray(payload.topNextActions)
69
+ ? payload.topNextActions.slice(0, 3).map(item => item.key)
70
+ : [],
71
+ };
72
+ }
73
+
74
+ if (snapshotKind === 'augment' || snapshotKind === 'suggest-only') {
75
+ return {
76
+ score: payload.projectSummary?.score,
77
+ organicScore: payload.projectSummary?.organicScore,
78
+ maturity: payload.projectSummary?.maturity,
79
+ domains: payload.projectSummary?.domains || [],
80
+ topActionKeys: Array.isArray(payload.topNextActions)
81
+ ? payload.topNextActions.slice(0, 3).map(item => item.key)
82
+ : [],
83
+ };
84
+ }
85
+
86
+ if (snapshotKind === 'benchmark') {
87
+ return {
88
+ beforeScore: payload.before?.score,
89
+ afterScore: payload.after?.score,
90
+ scoreDelta: payload.delta?.score,
91
+ organicDelta: payload.delta?.organicScore,
92
+ decisionGuidance: payload.executiveSummary?.decisionGuidance || null,
93
+ };
94
+ }
95
+
96
+ if (snapshotKind === 'governance') {
97
+ return {
98
+ permissionProfiles: Array.isArray(payload.permissionProfiles) ? payload.permissionProfiles.length : 0,
99
+ hooks: Array.isArray(payload.hookRegistry) ? payload.hookRegistry.length : 0,
100
+ policyPacks: Array.isArray(payload.policyPacks) ? payload.policyPacks.length : 0,
101
+ domainPacks: Array.isArray(payload.domainPacks) ? payload.domainPacks.length : 0,
102
+ mcpPacks: Array.isArray(payload.mcpPacks) ? payload.mcpPacks.length : 0,
103
+ };
104
+ }
105
+
106
+ return {};
107
+ }
108
+
109
+ function updateSnapshotIndex(snapshotDir, record) {
110
+ const indexPath = path.join(snapshotDir, 'index.json');
111
+ let entries = [];
112
+
113
+ if (fs.existsSync(indexPath)) {
114
+ try {
115
+ entries = JSON.parse(fs.readFileSync(indexPath, 'utf8'));
116
+ if (!Array.isArray(entries)) {
117
+ entries = [];
118
+ }
119
+ } catch {
120
+ entries = [];
121
+ }
122
+ }
123
+
124
+ entries.push(record);
125
+ fs.writeFileSync(indexPath, JSON.stringify(entries, null, 2), 'utf8');
126
+ }
127
+
128
+ function writeSnapshotArtifact(dir, snapshotKind, payload, meta = {}) {
129
+ const id = timestampId();
130
+ const { snapshotDir } = ensureArtifactDirs(dir);
131
+ const filePath = path.join(snapshotDir, `${id}-${snapshotKind}.json`);
132
+ const summary = summarizeSnapshot(snapshotKind, payload);
133
+ const envelope = {
134
+ schemaVersion: 1,
135
+ artifactType: 'snapshot',
136
+ snapshotKind,
137
+ id,
138
+ createdAt: new Date().toISOString(),
139
+ generatedBy: `claudex-setup@${version}`,
140
+ directory: dir,
141
+ summary,
142
+ ...meta,
143
+ payload,
144
+ };
145
+
146
+ writeJson(filePath, envelope);
147
+
148
+ const record = {
149
+ id,
150
+ snapshotKind,
151
+ createdAt: envelope.createdAt,
152
+ relativePath: path.relative(dir, filePath),
153
+ summary,
154
+ };
155
+ updateSnapshotIndex(snapshotDir, record);
156
+
157
+ return {
158
+ id,
159
+ filePath,
160
+ relativePath: path.relative(dir, filePath),
161
+ indexPath: path.relative(dir, path.join(snapshotDir, 'index.json')),
162
+ summary,
163
+ };
164
+ }
165
+
166
+ function readSnapshotIndex(dir) {
167
+ const indexPath = path.join(dir, '.claude', 'claudex-setup', 'snapshots', 'index.json');
168
+ if (!fs.existsSync(indexPath)) return [];
169
+ try {
170
+ const entries = JSON.parse(fs.readFileSync(indexPath, 'utf8'));
171
+ return Array.isArray(entries) ? entries : [];
172
+ } catch {
173
+ return [];
174
+ }
175
+ }
176
+
177
+ function getHistory(dir, limit = 20) {
178
+ const entries = readSnapshotIndex(dir);
179
+ return entries
180
+ .filter(e => e.snapshotKind === 'audit')
181
+ .sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt))
182
+ .slice(0, limit);
183
+ }
184
+
185
+ function compareLatest(dir) {
186
+ const audits = getHistory(dir, 2);
187
+ if (audits.length < 2) return null;
188
+
189
+ const current = audits[0];
190
+ const previous = audits[1];
191
+
192
+ const delta = {
193
+ score: (current.summary?.score || 0) - (previous.summary?.score || 0),
194
+ organic: (current.summary?.organicScore || 0) - (previous.summary?.organicScore || 0),
195
+ passed: (current.summary?.passed || 0) - (previous.summary?.passed || 0),
196
+ };
197
+
198
+ const regressions = [];
199
+ const improvements = [];
200
+
201
+ const prevKeys = new Set(previous.summary?.topActionKeys || []);
202
+ const currKeys = new Set(current.summary?.topActionKeys || []);
203
+
204
+ for (const key of currKeys) {
205
+ if (!prevKeys.has(key)) regressions.push(key);
206
+ }
207
+ for (const key of prevKeys) {
208
+ if (!currKeys.has(key)) improvements.push(key);
209
+ }
210
+
211
+ return {
212
+ current: { date: current.createdAt, score: current.summary?.score, passed: current.summary?.passed },
213
+ previous: { date: previous.createdAt, score: previous.summary?.score, passed: previous.summary?.passed },
214
+ delta,
215
+ regressions,
216
+ improvements,
217
+ trend: delta.score > 0 ? 'improving' : delta.score < 0 ? 'regressing' : 'stable',
218
+ };
219
+ }
220
+
221
+ function formatHistory(dir) {
222
+ const history = getHistory(dir, 10);
223
+ if (history.length === 0) return 'No snapshots found. Run `npx claudex-setup --snapshot` to save one.';
224
+
225
+ const lines = ['Score history (most recent first):', ''];
226
+ for (const entry of history) {
227
+ const date = entry.createdAt?.split('T')[0] || 'unknown';
228
+ const score = entry.summary?.score ?? '?';
229
+ const passed = entry.summary?.passed ?? '?';
230
+ const total = entry.summary?.checkCount ?? '?';
231
+ lines.push(` ${date} ${score}/100 (${passed}/${total} passing)`);
232
+ }
233
+
234
+ const comparison = compareLatest(dir);
235
+ if (comparison) {
236
+ lines.push('');
237
+ const sign = comparison.delta.score >= 0 ? '+' : '';
238
+ lines.push(` Trend: ${comparison.trend} (${sign}${comparison.delta.score} since previous)`);
239
+ if (comparison.improvements.length > 0) {
240
+ lines.push(` Fixed: ${comparison.improvements.join(', ')}`);
241
+ }
242
+ if (comparison.regressions.length > 0) {
243
+ lines.push(` New gaps: ${comparison.regressions.join(', ')}`);
244
+ }
245
+ }
246
+
247
+ return lines.join('\n');
248
+ }
249
+
250
+ function exportTrendReport(dir) {
251
+ const history = getHistory(dir, 50);
252
+ if (history.length === 0) return null;
253
+
254
+ const comparison = compareLatest(dir);
255
+ const lines = [
256
+ '# Claude Code Setup Trend Report',
257
+ '',
258
+ `**Project:** ${path.basename(dir)}`,
259
+ `**Generated:** ${new Date().toISOString().split('T')[0]}`,
260
+ `**Snapshots:** ${history.length}`,
261
+ '',
262
+ '## Score History',
263
+ '',
264
+ '| Date | Score | Passed | Checks |',
265
+ '|------|-------|--------|--------|',
266
+ ];
267
+
268
+ for (const entry of history) {
269
+ const date = entry.createdAt?.split('T')[0] || '?';
270
+ lines.push(`| ${date} | ${entry.summary?.score ?? '?'}/100 | ${entry.summary?.passed ?? '?'} | ${entry.summary?.checkCount ?? '?'} |`);
271
+ }
272
+
273
+ if (comparison) {
274
+ lines.push('');
275
+ lines.push('## Latest Comparison');
276
+ lines.push('');
277
+ lines.push(`- **Previous:** ${comparison.previous.score}/100 (${comparison.previous.date?.split('T')[0]})`);
278
+ lines.push(`- **Current:** ${comparison.current.score}/100 (${comparison.current.date?.split('T')[0]})`);
279
+ lines.push(`- **Delta:** ${comparison.delta.score >= 0 ? '+' : ''}${comparison.delta.score} points`);
280
+ lines.push(`- **Trend:** ${comparison.trend}`);
281
+ if (comparison.improvements.length > 0) lines.push(`- **Fixed:** ${comparison.improvements.join(', ')}`);
282
+ if (comparison.regressions.length > 0) lines.push(`- **New gaps:** ${comparison.regressions.join(', ')}`);
283
+ }
284
+
285
+ lines.push('');
286
+ lines.push(`---`);
287
+ lines.push(`*Generated by claudex-setup v${version}*`);
288
+ return lines.join('\n');
289
+ }
290
+
56
291
  module.exports = {
57
292
  ensureArtifactDirs,
58
293
  writeActivityArtifact,
59
294
  writeRollbackArtifact,
295
+ writeSnapshotArtifact,
296
+ readSnapshotIndex,
297
+ getHistory,
298
+ compareLatest,
299
+ formatHistory,
300
+ exportTrendReport,
60
301
  };
package/src/analyze.js CHANGED
@@ -351,7 +351,7 @@ async function analyzeProject(options) {
351
351
  },
352
352
  strengthsPreserved: toStrengths(auditResult.results),
353
353
  gapsIdentified: toGaps(auditResult.results),
354
- topNextActions: auditResult.quickWins,
354
+ topNextActions: auditResult.topNextActions || auditResult.quickWins,
355
355
  recommendedImprovements: toRecommendations(auditResult),
356
356
  recommendedDomainPacks,
357
357
  recommendedMcpPacks,
@@ -417,7 +417,14 @@ function printAnalysis(report, options = {}) {
417
417
  console.log(c(' Top 5 Next Actions', 'magenta'));
418
418
  report.topNextActions.slice(0, 5).forEach((item, index) => {
419
419
  console.log(` ${index + 1}. ${item.name}`);
420
- console.log(c(` ${item.fix}`, 'dim'));
420
+ console.log(c(` Why: ${item.why || item.fix}`, 'dim'));
421
+ if (Array.isArray(item.signals) && item.signals.length > 0) {
422
+ console.log(c(` Trace: ${item.signals.join(' | ')}`, 'dim'));
423
+ }
424
+ if (item.risk || item.confidence) {
425
+ console.log(c(` Risk: ${item.risk || 'low'} | Confidence: ${item.confidence || 'medium'}`, 'dim'));
426
+ }
427
+ console.log(c(` Fix: ${item.fix}`, 'dim'));
421
428
  });
422
429
  console.log('');
423
430
  }
@@ -500,7 +507,15 @@ function exportMarkdown(report) {
500
507
  lines.push('## Top Next Actions');
501
508
  lines.push('');
502
509
  report.topNextActions.slice(0, 5).forEach((item, index) => {
503
- lines.push(`${index + 1}. **${item.name}** — ${item.fix}`);
510
+ lines.push(`${index + 1}. **${item.name}**`);
511
+ lines.push(` - Why: ${item.why || item.fix}`);
512
+ if (Array.isArray(item.signals) && item.signals.length > 0) {
513
+ lines.push(` - Trace: ${item.signals.join(' | ')}`);
514
+ }
515
+ if (item.risk || item.confidence) {
516
+ lines.push(` - Risk / Confidence: ${item.risk || 'low'} / ${item.confidence || 'medium'}`);
517
+ }
518
+ lines.push(` - Fix: ${item.fix}`);
504
519
  });
505
520
  lines.push('');
506
521
  }