claude-cli-advanced-starter-pack 1.0.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.
Files changed (67) hide show
  1. package/LICENSE +21 -0
  2. package/OVERVIEW.md +597 -0
  3. package/README.md +439 -0
  4. package/bin/gtask.js +282 -0
  5. package/bin/postinstall.js +53 -0
  6. package/package.json +69 -0
  7. package/src/agents/phase-dev-templates.js +1011 -0
  8. package/src/agents/templates.js +668 -0
  9. package/src/analysis/checklist-parser.js +414 -0
  10. package/src/analysis/codebase.js +481 -0
  11. package/src/cli/menu.js +958 -0
  12. package/src/commands/claude-audit.js +1482 -0
  13. package/src/commands/claude-settings.js +2243 -0
  14. package/src/commands/create-agent.js +681 -0
  15. package/src/commands/create-command.js +337 -0
  16. package/src/commands/create-hook.js +262 -0
  17. package/src/commands/create-phase-dev/codebase-analyzer.js +813 -0
  18. package/src/commands/create-phase-dev/documentation-generator.js +352 -0
  19. package/src/commands/create-phase-dev/post-completion.js +404 -0
  20. package/src/commands/create-phase-dev/scale-calculator.js +344 -0
  21. package/src/commands/create-phase-dev/wizard.js +492 -0
  22. package/src/commands/create-phase-dev.js +481 -0
  23. package/src/commands/create-skill.js +313 -0
  24. package/src/commands/create.js +446 -0
  25. package/src/commands/decompose.js +392 -0
  26. package/src/commands/detect-tech-stack.js +768 -0
  27. package/src/commands/explore-mcp/claude-md-updater.js +252 -0
  28. package/src/commands/explore-mcp/mcp-installer.js +346 -0
  29. package/src/commands/explore-mcp/mcp-registry.js +438 -0
  30. package/src/commands/explore-mcp.js +638 -0
  31. package/src/commands/gtask-init.js +641 -0
  32. package/src/commands/help.js +128 -0
  33. package/src/commands/init.js +1890 -0
  34. package/src/commands/install.js +250 -0
  35. package/src/commands/list.js +116 -0
  36. package/src/commands/roadmap.js +750 -0
  37. package/src/commands/setup-wizard.js +482 -0
  38. package/src/commands/setup.js +351 -0
  39. package/src/commands/sync.js +534 -0
  40. package/src/commands/test-run.js +456 -0
  41. package/src/commands/test-setup.js +456 -0
  42. package/src/commands/validate.js +67 -0
  43. package/src/config/tech-stack.defaults.json +182 -0
  44. package/src/config/tech-stack.schema.json +502 -0
  45. package/src/github/client.js +359 -0
  46. package/src/index.js +84 -0
  47. package/src/templates/claude-command.js +244 -0
  48. package/src/templates/issue-body.js +284 -0
  49. package/src/testing/config.js +411 -0
  50. package/src/utils/template-engine.js +398 -0
  51. package/src/utils/validate-templates.js +223 -0
  52. package/src/utils.js +396 -0
  53. package/templates/commands/ccasp-setup.template.md +113 -0
  54. package/templates/commands/context-audit.template.md +97 -0
  55. package/templates/commands/create-task-list.template.md +382 -0
  56. package/templates/commands/deploy-full.template.md +261 -0
  57. package/templates/commands/github-task-start.template.md +99 -0
  58. package/templates/commands/github-update.template.md +69 -0
  59. package/templates/commands/happy-start.template.md +117 -0
  60. package/templates/commands/phase-track.template.md +142 -0
  61. package/templates/commands/tunnel-start.template.md +127 -0
  62. package/templates/commands/tunnel-stop.template.md +106 -0
  63. package/templates/hooks/context-guardian.template.js +173 -0
  64. package/templates/hooks/deployment-orchestrator.template.js +219 -0
  65. package/templates/hooks/github-progress-hook.template.js +197 -0
  66. package/templates/hooks/happy-checkpoint-manager.template.js +222 -0
  67. package/templates/hooks/phase-dev-enforcer.template.js +183 -0
@@ -0,0 +1,1482 @@
1
+ /**
2
+ * Claude Audit Command
3
+ *
4
+ * Audits CLAUDE.md files and .claude/ folder structure against
5
+ * Anthropic's Claude Code CLI best practices.
6
+ *
7
+ * Reference: https://code.claude.com/docs/en/best-practices
8
+ */
9
+
10
+ import chalk from 'chalk';
11
+ import ora from 'ora';
12
+ import inquirer from 'inquirer';
13
+ import { existsSync, readFileSync, writeFileSync, readdirSync, statSync, mkdirSync } from 'fs';
14
+ import { join, basename, extname } from 'path';
15
+ import { showHeader } from '../cli/menu.js';
16
+ import { detectTechStack } from './detect-tech-stack.js';
17
+
18
+ /**
19
+ * Audit rules based on Anthropic documentation
20
+ */
21
+ const AUDIT_RULES = {
22
+ claudeMd: {
23
+ maxLines: 300,
24
+ recommendedLines: 60,
25
+ warningLines: 150,
26
+ requiredSections: [],
27
+ antiPatterns: [
28
+ { pattern: /```[\s\S]{500,}```/g, message: 'Long code blocks (>500 chars) bloat context - link to docs instead' },
29
+ { pattern: /\b(obvious|obviously|of course|everyone knows)\b/gi, message: 'Self-evident statements waste tokens' },
30
+ { pattern: /^\s*-\s*Write clean code/mi, message: 'Generic advice like "write clean code" adds no value' },
31
+ { pattern: /^\s*-\s*Follow best practices/mi, message: 'Vague instructions get ignored - be specific' },
32
+ { pattern: /^#{1,6}\s+.{100,}/gm, message: 'Headers over 100 chars are too long' },
33
+ ],
34
+ goodPatterns: [
35
+ { pattern: /IMPORTANT|YOU MUST|CRITICAL|NEVER|ALWAYS/i, message: 'Has emphasis keywords for critical rules' },
36
+ { pattern: /```(bash|sh|shell)/i, message: 'Includes runnable bash commands' },
37
+ { pattern: /@[\w\/\.-]+\.(md|json|txt)/g, message: 'Uses @import syntax for modularity' },
38
+ ],
39
+ },
40
+ claudeFolder: {
41
+ expectedStructure: {
42
+ 'commands/': { type: 'dir', description: 'Slash commands (.md files)' },
43
+ 'skills/': { type: 'dir', description: 'Skills with SKILL.md files' },
44
+ 'agents/': { type: 'dir', description: 'Subagent definitions' },
45
+ 'hooks/': { type: 'dir', description: 'Hook scripts and configs' },
46
+ 'settings.json': { type: 'file', description: 'Project settings (git-tracked)' },
47
+ 'settings.local.json': { type: 'file', description: 'Local settings (gitignored)' },
48
+ },
49
+ filePatterns: {
50
+ commands: { ext: '.md', frontmatter: false },
51
+ skills: { ext: '.md', frontmatter: true, requiredFrontmatter: ['name', 'description'] },
52
+ agents: { ext: '.md', frontmatter: true, requiredFrontmatter: ['name', 'description', 'tools'] },
53
+ },
54
+ },
55
+ };
56
+
57
+ /**
58
+ * Enhancement templates for generating CLAUDE.md content
59
+ */
60
+ const ENHANCEMENT_TEMPLATES = {
61
+ // Quick Start section - most important
62
+ quickStart: (techStack) => {
63
+ const lines = ['## Quick Start', ''];
64
+
65
+ // Build commands based on detected stack
66
+ if (techStack.devEnvironment?.packageManager) {
67
+ const pm = techStack.devEnvironment.packageManager;
68
+ const installCmd = pm === 'yarn' ? 'yarn' : pm === 'pnpm' ? 'pnpm install' : pm === 'bun' ? 'bun install' : 'npm install';
69
+ lines.push('```bash');
70
+ lines.push(`# Install dependencies`);
71
+ lines.push(installCmd);
72
+ lines.push('');
73
+ }
74
+
75
+ if (techStack.frontend?.framework) {
76
+ lines.push(`# Run frontend (${techStack.frontend.framework})`);
77
+ lines.push(`${techStack.devEnvironment?.packageManager || 'npm'} run dev`);
78
+ lines.push('');
79
+ }
80
+
81
+ if (techStack.backend?.framework) {
82
+ lines.push(`# Run backend (${techStack.backend.framework})`);
83
+ if (techStack.backend.language === 'python') {
84
+ lines.push('python -m uvicorn main:app --reload # or python run_api.py');
85
+ } else {
86
+ lines.push(`${techStack.devEnvironment?.packageManager || 'npm'} run server`);
87
+ }
88
+ lines.push('');
89
+ }
90
+
91
+ if (techStack.testing?.e2e?.framework) {
92
+ lines.push(`# Run E2E tests (${techStack.testing.e2e.framework})`);
93
+ if (techStack.testing.e2e.framework === 'playwright') {
94
+ lines.push('npx playwright test');
95
+ } else if (techStack.testing.e2e.framework === 'cypress') {
96
+ lines.push('npx cypress run');
97
+ }
98
+ }
99
+
100
+ lines.push('```');
101
+ lines.push('');
102
+ return lines.join('\n');
103
+ },
104
+
105
+ // Tech stack overview table
106
+ techStackTable: (techStack) => {
107
+ const lines = ['## Tech Stack', '', '| Layer | Technology |', '|-------|------------|'];
108
+
109
+ if (techStack.frontend?.framework) {
110
+ let frontend = techStack.frontend.framework;
111
+ if (techStack.frontend.buildTool) frontend += ` + ${techStack.frontend.buildTool}`;
112
+ if (techStack.frontend.stateManager) frontend += ` + ${techStack.frontend.stateManager}`;
113
+ lines.push(`| Frontend | ${frontend} |`);
114
+ }
115
+
116
+ if (techStack.backend?.framework) {
117
+ lines.push(`| Backend | ${techStack.backend.framework} (${techStack.backend.language || 'unknown'}) |`);
118
+ }
119
+
120
+ if (techStack.database?.primary) {
121
+ let db = techStack.database.primary;
122
+ if (techStack.database.orm) db += ` + ${techStack.database.orm}`;
123
+ lines.push(`| Database | ${db} |`);
124
+ }
125
+
126
+ if (techStack.testing?.e2e?.framework) {
127
+ lines.push(`| E2E Testing | ${techStack.testing.e2e.framework} |`);
128
+ }
129
+
130
+ if (techStack.testing?.unit?.framework) {
131
+ lines.push(`| Unit Testing | ${techStack.testing.unit.framework} |`);
132
+ }
133
+
134
+ lines.push('');
135
+ return lines.join('\n');
136
+ },
137
+
138
+ // Key locations section
139
+ keyLocations: (techStack) => {
140
+ const lines = ['## Key Locations', '', '| Type | Path |', '|------|------|'];
141
+
142
+ if (techStack.frontend?.framework) {
143
+ lines.push('| Frontend Entry | `src/main.tsx` or `src/index.tsx` |');
144
+ lines.push('| Components | `src/components/` |');
145
+ }
146
+
147
+ if (techStack.backend?.framework) {
148
+ if (techStack.backend.language === 'python') {
149
+ lines.push('| Backend Entry | `main.py` or `run_api.py` |');
150
+ lines.push('| API Routes | `routes/` or `routers/` |');
151
+ } else {
152
+ lines.push('| Backend Entry | `src/index.ts` or `server.js` |');
153
+ lines.push('| API Routes | `src/routes/` |');
154
+ }
155
+ }
156
+
157
+ if (techStack.testing?.e2e?.framework) {
158
+ lines.push('| E2E Tests | `tests/` or `e2e/` |');
159
+ }
160
+
161
+ lines.push('| Config | `.env`, `package.json` |');
162
+ lines.push('');
163
+ return lines.join('\n');
164
+ },
165
+
166
+ // Import patterns based on language/framework
167
+ importPatterns: (techStack) => {
168
+ const lines = ['## Import Patterns', ''];
169
+
170
+ if (techStack.frontend?.framework === 'react') {
171
+ lines.push('**React/TypeScript:**');
172
+ lines.push('```typescript');
173
+ lines.push("import { useState, useEffect } from 'react';");
174
+ lines.push("import { Button } from '@/components/ui';");
175
+ if (techStack.frontend.stateManager === 'zustand') {
176
+ lines.push("import { useStore } from '@/store';");
177
+ } else if (techStack.frontend.stateManager === 'redux') {
178
+ lines.push("import { useSelector, useDispatch } from 'react-redux';");
179
+ }
180
+ lines.push('```');
181
+ lines.push('');
182
+ }
183
+
184
+ if (techStack.backend?.language === 'python') {
185
+ lines.push('**Python (FastAPI):**');
186
+ lines.push('```python');
187
+ lines.push('from fastapi import APIRouter, Depends, HTTPException');
188
+ lines.push('from sqlalchemy.orm import Session');
189
+ lines.push('from app.database import get_db');
190
+ lines.push('```');
191
+ lines.push('');
192
+ } else if (techStack.backend?.framework === 'express') {
193
+ lines.push('**Node.js (Express):**');
194
+ lines.push('```typescript');
195
+ lines.push("import express from 'express';");
196
+ lines.push("import { Router } from 'express';");
197
+ lines.push('```');
198
+ lines.push('');
199
+ }
200
+
201
+ return lines.join('\n');
202
+ },
203
+
204
+ // Testing section
205
+ testingInstructions: (techStack) => {
206
+ const lines = ['## Testing', ''];
207
+
208
+ if (techStack.testing?.e2e?.framework === 'playwright') {
209
+ lines.push('**Playwright E2E:**');
210
+ lines.push('```bash');
211
+ lines.push('npx playwright test # Run all tests');
212
+ lines.push('npx playwright test --ui # Open UI mode');
213
+ lines.push('npx playwright test --headed # Show browser');
214
+ lines.push('npx playwright codegen # Generate tests');
215
+ lines.push('```');
216
+ lines.push('');
217
+ } else if (techStack.testing?.e2e?.framework === 'cypress') {
218
+ lines.push('**Cypress E2E:**');
219
+ lines.push('```bash');
220
+ lines.push('npx cypress run # Run headless');
221
+ lines.push('npx cypress open # Open UI');
222
+ lines.push('```');
223
+ lines.push('');
224
+ }
225
+
226
+ if (techStack.testing?.unit?.framework === 'vitest') {
227
+ lines.push('**Vitest Unit Tests:**');
228
+ lines.push('```bash');
229
+ lines.push('npm run test # Run tests');
230
+ lines.push('npm run test -- --coverage # With coverage');
231
+ lines.push('```');
232
+ lines.push('');
233
+ } else if (techStack.testing?.unit?.framework === 'jest') {
234
+ lines.push('**Jest Unit Tests:**');
235
+ lines.push('```bash');
236
+ lines.push('npm test # Run tests');
237
+ lines.push('npm test -- --coverage # With coverage');
238
+ lines.push('```');
239
+ lines.push('');
240
+ } else if (techStack.testing?.unit?.framework === 'pytest') {
241
+ lines.push('**Pytest:**');
242
+ lines.push('```bash');
243
+ lines.push('pytest # Run all tests');
244
+ lines.push('pytest -v # Verbose');
245
+ lines.push('pytest --cov=app # With coverage');
246
+ lines.push('```');
247
+ lines.push('');
248
+ }
249
+
250
+ return lines.join('\n');
251
+ },
252
+
253
+ // Deployment section
254
+ deploymentSection: (techStack) => {
255
+ const lines = ['## Deployment', ''];
256
+
257
+ if (techStack.deployment?.frontend?.platform) {
258
+ lines.push(`**Frontend (${techStack.deployment.frontend.platform}):**`);
259
+ lines.push('```bash');
260
+
261
+ if (techStack.deployment.frontend.platform === 'cloudflare') {
262
+ lines.push('npm run build');
263
+ lines.push('npx wrangler pages deploy dist --project-name=YOUR_PROJECT');
264
+ } else if (techStack.deployment.frontend.platform === 'vercel') {
265
+ lines.push('vercel --prod');
266
+ } else if (techStack.deployment.frontend.platform === 'netlify') {
267
+ lines.push('netlify deploy --prod');
268
+ }
269
+
270
+ lines.push('```');
271
+ lines.push('');
272
+ }
273
+
274
+ if (techStack.deployment?.backend?.platform) {
275
+ lines.push(`**Backend (${techStack.deployment.backend.platform}):**`);
276
+ lines.push('```bash');
277
+
278
+ if (techStack.deployment.backend.platform === 'railway') {
279
+ lines.push('# Use Railway MCP or dashboard');
280
+ lines.push('# railway up');
281
+ } else if (techStack.deployment.backend.platform === 'docker') {
282
+ lines.push('docker build -t app .');
283
+ lines.push('docker push registry/app');
284
+ }
285
+
286
+ lines.push('```');
287
+ lines.push('');
288
+ }
289
+
290
+ return lines.join('\n');
291
+ },
292
+
293
+ // Reference documentation links
294
+ referenceLinks: (techStack) => {
295
+ const lines = ['## Reference Documentation', ''];
296
+ const links = [];
297
+
298
+ // Frontend
299
+ if (techStack.frontend?.framework === 'react') {
300
+ links.push('- [React Docs](https://react.dev/)');
301
+ } else if (techStack.frontend?.framework === 'vue') {
302
+ links.push('- [Vue.js Docs](https://vuejs.org/)');
303
+ } else if (techStack.frontend?.framework === 'angular') {
304
+ links.push('- [Angular Docs](https://angular.io/docs)');
305
+ } else if (techStack.frontend?.framework === 'svelte') {
306
+ links.push('- [Svelte Docs](https://svelte.dev/docs)');
307
+ } else if (techStack.frontend?.framework === 'nextjs') {
308
+ links.push('- [Next.js Docs](https://nextjs.org/docs)');
309
+ }
310
+
311
+ // Build tools
312
+ if (techStack.frontend?.buildTool === 'vite') {
313
+ links.push('- [Vite Docs](https://vitejs.dev/)');
314
+ }
315
+
316
+ // State
317
+ if (techStack.frontend?.stateManager === 'zustand') {
318
+ links.push('- [Zustand Docs](https://github.com/pmndrs/zustand)');
319
+ } else if (techStack.frontend?.stateManager === 'redux') {
320
+ links.push('- [Redux Toolkit](https://redux-toolkit.js.org/)');
321
+ }
322
+
323
+ // Styling
324
+ if (techStack.frontend?.styling === 'tailwind') {
325
+ links.push('- [Tailwind CSS](https://tailwindcss.com/docs)');
326
+ }
327
+
328
+ // Backend
329
+ if (techStack.backend?.framework === 'fastapi') {
330
+ links.push('- [FastAPI Docs](https://fastapi.tiangolo.com/)');
331
+ } else if (techStack.backend?.framework === 'express') {
332
+ links.push('- [Express.js Docs](https://expressjs.com/)');
333
+ } else if (techStack.backend?.framework === 'nestjs') {
334
+ links.push('- [NestJS Docs](https://docs.nestjs.com/)');
335
+ }
336
+
337
+ // Database/ORM
338
+ if (techStack.database?.orm === 'prisma') {
339
+ links.push('- [Prisma Docs](https://www.prisma.io/docs)');
340
+ } else if (techStack.database?.orm === 'sqlalchemy') {
341
+ links.push('- [SQLAlchemy Docs](https://docs.sqlalchemy.org/)');
342
+ }
343
+
344
+ // Testing
345
+ if (techStack.testing?.e2e?.framework === 'playwright') {
346
+ links.push('- [Playwright Docs](https://playwright.dev/)');
347
+ } else if (techStack.testing?.e2e?.framework === 'cypress') {
348
+ links.push('- [Cypress Docs](https://docs.cypress.io/)');
349
+ }
350
+
351
+ if (links.length === 0) {
352
+ return '';
353
+ }
354
+
355
+ lines.push(...links, '');
356
+ return lines.join('\n');
357
+ },
358
+
359
+ // Architecture rules based on stack
360
+ architectureRules: (techStack) => {
361
+ const lines = ['## Architecture Rules', ''];
362
+
363
+ if (techStack.frontend?.framework === 'react') {
364
+ lines.push('**React Guidelines:**');
365
+ lines.push('- Use functional components with hooks');
366
+ lines.push('- Colocate component styles and tests');
367
+ lines.push('- Extract shared logic into custom hooks');
368
+ lines.push('');
369
+ }
370
+
371
+ if (techStack.backend?.language === 'python') {
372
+ lines.push('**Python Guidelines:**');
373
+ lines.push('- Use type hints for all function signatures');
374
+ lines.push('- Keep route handlers thin - delegate to services');
375
+ lines.push('- Use dependency injection for database sessions');
376
+ lines.push('');
377
+ }
378
+
379
+ if (techStack.database?.primary === 'postgresql') {
380
+ lines.push('**Database Guidelines:**');
381
+ lines.push('- Use migrations for schema changes');
382
+ lines.push('- Index frequently queried columns');
383
+ lines.push('- Use connection pooling in production');
384
+ lines.push('');
385
+ }
386
+
387
+ return lines.join('\n');
388
+ },
389
+
390
+ // Critical rules with emphasis
391
+ criticalRules: () => {
392
+ return `## Critical Rules
393
+
394
+ **IMPORTANT**: These rules MUST be followed:
395
+
396
+ 1. **NEVER commit secrets** - Use environment variables
397
+ 2. **Run tests before committing** - All tests must pass
398
+ 3. **Use conventional commits** - feat:, fix:, chore:, etc.
399
+
400
+ `;
401
+ },
402
+
403
+ // Full CLAUDE.md template
404
+ fullTemplate: (techStack, projectName) => {
405
+ const sections = [];
406
+
407
+ sections.push(`# ${projectName || 'Project'} - Quick Reference`);
408
+ sections.push('');
409
+ sections.push(ENHANCEMENT_TEMPLATES.quickStart(techStack));
410
+ sections.push(ENHANCEMENT_TEMPLATES.techStackTable(techStack));
411
+ sections.push(ENHANCEMENT_TEMPLATES.keyLocations(techStack));
412
+ sections.push(ENHANCEMENT_TEMPLATES.importPatterns(techStack));
413
+ sections.push(ENHANCEMENT_TEMPLATES.testingInstructions(techStack));
414
+ sections.push(ENHANCEMENT_TEMPLATES.deploymentSection(techStack));
415
+ sections.push(ENHANCEMENT_TEMPLATES.architectureRules(techStack));
416
+ sections.push(ENHANCEMENT_TEMPLATES.criticalRules());
417
+ sections.push(ENHANCEMENT_TEMPLATES.referenceLinks(techStack));
418
+
419
+ return sections.filter(s => s.trim()).join('\n');
420
+ },
421
+ };
422
+
423
+ /**
424
+ * Audit result structure
425
+ */
426
+ function createAuditResult() {
427
+ return {
428
+ passed: [],
429
+ warnings: [],
430
+ errors: [],
431
+ suggestions: [],
432
+ score: 100,
433
+ };
434
+ }
435
+
436
+ /**
437
+ * Main audit runner
438
+ */
439
+ export async function runClaudeAudit(options = {}) {
440
+ const cwd = options.cwd || process.cwd();
441
+
442
+ showHeader('Claude Code Audit');
443
+
444
+ console.log(chalk.dim('Auditing against Anthropic best practices...'));
445
+ console.log(chalk.dim('Reference: https://code.claude.com/docs/en/best-practices'));
446
+ console.log('');
447
+
448
+ const spinner = ora('Scanning project...').start();
449
+
450
+ const results = {
451
+ claudeMd: createAuditResult(),
452
+ claudeFolder: createAuditResult(),
453
+ overall: createAuditResult(),
454
+ };
455
+
456
+ // Audit CLAUDE.md files
457
+ spinner.text = 'Auditing CLAUDE.md files...';
458
+ auditClaudeMdFiles(cwd, results.claudeMd);
459
+
460
+ // Audit .claude folder
461
+ spinner.text = 'Auditing .claude/ folder structure...';
462
+ auditClaudeFolder(cwd, results.claudeFolder);
463
+
464
+ // Calculate overall score
465
+ calculateOverallScore(results);
466
+
467
+ spinner.succeed('Audit complete');
468
+ console.log('');
469
+
470
+ // Display results
471
+ displayAuditResults(results);
472
+
473
+ // Show fix suggestions
474
+ if (options.interactive !== false) {
475
+ await showFixSuggestions(results, cwd);
476
+ }
477
+
478
+ return results;
479
+ }
480
+
481
+ /**
482
+ * Audit CLAUDE.md files at various locations
483
+ */
484
+ function auditClaudeMdFiles(cwd, result) {
485
+ const locations = [
486
+ { path: join(cwd, 'CLAUDE.md'), name: 'Root CLAUDE.md', required: true },
487
+ { path: join(cwd, 'CLAUDE.local.md'), name: 'Local CLAUDE.md', required: false },
488
+ ];
489
+
490
+ // Check for CLAUDE.md in parent directories (monorepo support)
491
+ let parentDir = join(cwd, '..');
492
+ const checkedPaths = new Set([cwd]);
493
+ while (parentDir !== cwd && !checkedPaths.has(parentDir)) {
494
+ checkedPaths.add(parentDir);
495
+ const parentClaudeMd = join(parentDir, 'CLAUDE.md');
496
+ if (existsSync(parentClaudeMd)) {
497
+ locations.push({ path: parentClaudeMd, name: `Parent CLAUDE.md (${basename(parentDir)})`, required: false });
498
+ }
499
+ cwd = parentDir;
500
+ parentDir = join(cwd, '..');
501
+ }
502
+
503
+ let foundAny = false;
504
+
505
+ for (const loc of locations) {
506
+ if (existsSync(loc.path)) {
507
+ foundAny = true;
508
+ auditSingleClaudeMd(loc.path, loc.name, result);
509
+ } else if (loc.required) {
510
+ result.errors.push({
511
+ file: loc.path,
512
+ message: `Missing ${loc.name} - run /init to generate one`,
513
+ fix: 'Run `claude /init` to generate a starter CLAUDE.md',
514
+ });
515
+ }
516
+ }
517
+
518
+ if (!foundAny) {
519
+ result.errors.push({
520
+ file: 'CLAUDE.md',
521
+ message: 'No CLAUDE.md found in project',
522
+ fix: 'Create a CLAUDE.md file with project-specific instructions',
523
+ });
524
+ }
525
+ }
526
+
527
+ /**
528
+ * Audit a single CLAUDE.md file
529
+ */
530
+ function auditSingleClaudeMd(filePath, name, result) {
531
+ const content = readFileSync(filePath, 'utf8');
532
+ const lines = content.split('\n');
533
+ const lineCount = lines.length;
534
+
535
+ // Line count checks
536
+ if (lineCount > AUDIT_RULES.claudeMd.maxLines) {
537
+ result.errors.push({
538
+ file: name,
539
+ message: `${lineCount} lines exceeds max recommended ${AUDIT_RULES.claudeMd.maxLines}`,
540
+ fix: 'Prune ruthlessly - if Claude already does it correctly, remove the instruction',
541
+ });
542
+ } else if (lineCount > AUDIT_RULES.claudeMd.warningLines) {
543
+ result.warnings.push({
544
+ file: name,
545
+ message: `${lineCount} lines is getting long (recommended: <${AUDIT_RULES.claudeMd.recommendedLines})`,
546
+ fix: 'Consider moving domain-specific content to skills',
547
+ });
548
+ } else if (lineCount <= AUDIT_RULES.claudeMd.recommendedLines) {
549
+ result.passed.push({
550
+ file: name,
551
+ message: `Good length: ${lineCount} lines`,
552
+ });
553
+ }
554
+
555
+ // Check for anti-patterns
556
+ for (const anti of AUDIT_RULES.claudeMd.antiPatterns) {
557
+ const matches = content.match(anti.pattern);
558
+ if (matches) {
559
+ result.warnings.push({
560
+ file: name,
561
+ message: anti.message,
562
+ fix: `Found ${matches.length} occurrence(s)`,
563
+ });
564
+ }
565
+ }
566
+
567
+ // Check for good patterns
568
+ for (const good of AUDIT_RULES.claudeMd.goodPatterns) {
569
+ const matches = content.match(good.pattern);
570
+ if (matches) {
571
+ result.passed.push({
572
+ file: name,
573
+ message: good.message,
574
+ });
575
+ }
576
+ }
577
+
578
+ // Check for common content issues
579
+ if (content.length > 15000) {
580
+ result.errors.push({
581
+ file: name,
582
+ message: `File is ${Math.round(content.length / 1000)}KB - too large for efficient loading`,
583
+ fix: 'Split into skills or use @imports',
584
+ });
585
+ }
586
+
587
+ // Check for gitignore mention if .local.md
588
+ if (name.includes('local') && !content.includes('.gitignore')) {
589
+ result.suggestions.push({
590
+ file: name,
591
+ message: 'Local files should be gitignored',
592
+ fix: 'Add CLAUDE.local.md to .gitignore',
593
+ });
594
+ }
595
+
596
+ // Check for import usage
597
+ const imports = content.match(/@[\w\/\.-]+/g) || [];
598
+ if (imports.length > 0) {
599
+ result.passed.push({
600
+ file: name,
601
+ message: `Uses ${imports.length} @imports for modularity`,
602
+ });
603
+ }
604
+
605
+ // Check for empty or minimal content
606
+ const meaningfulContent = content.replace(/^#.*$/gm, '').replace(/\s+/g, '').length;
607
+ if (meaningfulContent < 100) {
608
+ result.warnings.push({
609
+ file: name,
610
+ message: 'Very little content - might not be useful',
611
+ fix: 'Add bash commands, code style rules, and workflow instructions',
612
+ });
613
+ }
614
+ }
615
+
616
+ /**
617
+ * Audit .claude folder structure
618
+ */
619
+ function auditClaudeFolder(cwd, result) {
620
+ const claudeDir = join(cwd, '.claude');
621
+
622
+ if (!existsSync(claudeDir)) {
623
+ result.errors.push({
624
+ file: '.claude/',
625
+ message: 'No .claude folder found',
626
+ fix: 'Create .claude/ directory for commands, skills, hooks, and settings',
627
+ });
628
+ return;
629
+ }
630
+
631
+ result.passed.push({
632
+ file: '.claude/',
633
+ message: '.claude folder exists',
634
+ });
635
+
636
+ // Check expected structure
637
+ for (const [name, spec] of Object.entries(AUDIT_RULES.claudeFolder.expectedStructure)) {
638
+ const itemPath = join(claudeDir, name);
639
+ const exists = existsSync(itemPath);
640
+
641
+ if (!exists) {
642
+ result.suggestions.push({
643
+ file: `.claude/${name}`,
644
+ message: `Missing ${spec.description}`,
645
+ fix: `Create .claude/${name}`,
646
+ });
647
+ } else {
648
+ if (spec.type === 'dir') {
649
+ const isDir = statSync(itemPath).isDirectory();
650
+ if (isDir) {
651
+ result.passed.push({
652
+ file: `.claude/${name}`,
653
+ message: `${spec.description} exists`,
654
+ });
655
+ // Audit contents
656
+ auditClaudeFolderContents(itemPath, name.replace('/', ''), result);
657
+ } else {
658
+ result.errors.push({
659
+ file: `.claude/${name}`,
660
+ message: `Expected directory, found file`,
661
+ });
662
+ }
663
+ } else {
664
+ result.passed.push({
665
+ file: `.claude/${name}`,
666
+ message: `${spec.description} exists`,
667
+ });
668
+ // Validate JSON files
669
+ if (name.endsWith('.json')) {
670
+ validateJsonFile(itemPath, `.claude/${name}`, result);
671
+ }
672
+ }
673
+ }
674
+ }
675
+
676
+ // Check for common misconfigurations
677
+ checkCommonMisconfigurations(claudeDir, result);
678
+ }
679
+
680
+ /**
681
+ * Audit contents of .claude subdirectories
682
+ */
683
+ function auditClaudeFolderContents(dirPath, type, result) {
684
+ const files = readdirSync(dirPath);
685
+ const spec = AUDIT_RULES.claudeFolder.filePatterns[type];
686
+
687
+ if (!spec) return;
688
+
689
+ for (const file of files) {
690
+ const filePath = join(dirPath, file);
691
+ const stat = statSync(filePath);
692
+
693
+ if (stat.isDirectory()) {
694
+ // Skills can have subdirectories with SKILL.md
695
+ if (type === 'skills') {
696
+ const skillMdPath = join(filePath, 'SKILL.md');
697
+ if (existsSync(skillMdPath)) {
698
+ validateSkillOrAgent(skillMdPath, `.claude/skills/${file}/SKILL.md`, 'skill', result);
699
+ } else {
700
+ result.warnings.push({
701
+ file: `.claude/skills/${file}/`,
702
+ message: 'Skill directory missing SKILL.md',
703
+ fix: 'Add SKILL.md with name, description frontmatter',
704
+ });
705
+ }
706
+ }
707
+ continue;
708
+ }
709
+
710
+ const ext = extname(file);
711
+
712
+ if (ext !== spec.ext) {
713
+ result.warnings.push({
714
+ file: `.claude/${type}/${file}`,
715
+ message: `Unexpected file extension (expected ${spec.ext})`,
716
+ });
717
+ continue;
718
+ }
719
+
720
+ if (spec.frontmatter) {
721
+ if (type === 'skills') {
722
+ validateSkillOrAgent(filePath, `.claude/${type}/${file}`, 'skill', result);
723
+ } else if (type === 'agents') {
724
+ validateSkillOrAgent(filePath, `.claude/${type}/${file}`, 'agent', result);
725
+ }
726
+ } else {
727
+ // Commands just need to be valid markdown
728
+ result.passed.push({
729
+ file: `.claude/${type}/${file}`,
730
+ message: 'Command file found',
731
+ });
732
+ }
733
+ }
734
+
735
+ if (files.length === 0) {
736
+ result.suggestions.push({
737
+ file: `.claude/${type}/`,
738
+ message: `Empty ${type} directory`,
739
+ fix: `Add ${type} to extend Claude's capabilities`,
740
+ });
741
+ }
742
+ }
743
+
744
+ /**
745
+ * Validate skill or agent markdown file
746
+ */
747
+ function validateSkillOrAgent(filePath, displayPath, type, result) {
748
+ const content = readFileSync(filePath, 'utf8');
749
+
750
+ // Check for frontmatter
751
+ const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
752
+
753
+ if (!frontmatterMatch) {
754
+ result.errors.push({
755
+ file: displayPath,
756
+ message: `Missing frontmatter (required for ${type}s)`,
757
+ fix: `Add ---\\nname: ...\\ndescription: ...\\n--- at top of file`,
758
+ });
759
+ return;
760
+ }
761
+
762
+ const frontmatter = frontmatterMatch[1];
763
+ const required = AUDIT_RULES.claudeFolder.filePatterns[type === 'skill' ? 'skills' : 'agents'].requiredFrontmatter;
764
+
765
+ for (const field of required) {
766
+ if (!frontmatter.includes(`${field}:`)) {
767
+ result.errors.push({
768
+ file: displayPath,
769
+ message: `Missing required frontmatter field: ${field}`,
770
+ fix: `Add ${field}: value to frontmatter`,
771
+ });
772
+ }
773
+ }
774
+
775
+ // Check for tools in agents
776
+ if (type === 'agent' && !frontmatter.includes('tools:')) {
777
+ result.errors.push({
778
+ file: displayPath,
779
+ message: 'Agent missing tools specification',
780
+ fix: 'Add tools: Read, Grep, Glob, Bash (or specific tools)',
781
+ });
782
+ }
783
+
784
+ // Check for model specification in agents (optional but recommended)
785
+ if (type === 'agent' && !frontmatter.includes('model:')) {
786
+ result.suggestions.push({
787
+ file: displayPath,
788
+ message: 'Agent has no model specified (will use default)',
789
+ fix: 'Add model: opus, sonnet, or haiku',
790
+ });
791
+ }
792
+
793
+ // Content length check
794
+ const body = content.replace(/^---[\s\S]*?---\n?/, '').trim();
795
+ if (body.length < 50) {
796
+ result.warnings.push({
797
+ file: displayPath,
798
+ message: `${type} has minimal instructions`,
799
+ fix: 'Add detailed instructions for the skill/agent',
800
+ });
801
+ } else {
802
+ result.passed.push({
803
+ file: displayPath,
804
+ message: `Valid ${type} with frontmatter`,
805
+ });
806
+ }
807
+ }
808
+
809
+ /**
810
+ * Validate JSON file
811
+ */
812
+ function validateJsonFile(filePath, displayPath, result) {
813
+ try {
814
+ const content = readFileSync(filePath, 'utf8');
815
+ JSON.parse(content);
816
+ result.passed.push({
817
+ file: displayPath,
818
+ message: 'Valid JSON',
819
+ });
820
+ } catch (e) {
821
+ result.errors.push({
822
+ file: displayPath,
823
+ message: `Invalid JSON: ${e.message}`,
824
+ });
825
+ }
826
+ }
827
+
828
+ /**
829
+ * Check for common misconfigurations
830
+ */
831
+ function checkCommonMisconfigurations(claudeDir, result) {
832
+ // Check if settings.local.json is gitignored
833
+ const gitignorePath = join(claudeDir, '..', '.gitignore');
834
+ if (existsSync(gitignorePath)) {
835
+ const gitignore = readFileSync(gitignorePath, 'utf8');
836
+ if (!gitignore.includes('settings.local.json') && !gitignore.includes('.claude/settings.local.json')) {
837
+ const localSettingsPath = join(claudeDir, 'settings.local.json');
838
+ if (existsSync(localSettingsPath)) {
839
+ result.warnings.push({
840
+ file: '.claude/settings.local.json',
841
+ message: 'Local settings may not be gitignored',
842
+ fix: 'Add .claude/settings.local.json to .gitignore',
843
+ });
844
+ }
845
+ }
846
+ }
847
+
848
+ // Check for MCP configuration
849
+ const mcpPath = join(claudeDir, '..', '.mcp.json');
850
+ if (existsSync(mcpPath)) {
851
+ validateJsonFile(mcpPath, '.mcp.json', result);
852
+ }
853
+
854
+ // Check for hooks configuration
855
+ const hooksDir = join(claudeDir, 'hooks');
856
+ if (existsSync(hooksDir)) {
857
+ const hookFiles = readdirSync(hooksDir).filter(f => f.endsWith('.js') || f.endsWith('.sh'));
858
+ if (hookFiles.length > 0) {
859
+ result.passed.push({
860
+ file: '.claude/hooks/',
861
+ message: `${hookFiles.length} hook script(s) configured`,
862
+ });
863
+ }
864
+ }
865
+
866
+ // Check settings.json for permissions
867
+ const settingsPath = join(claudeDir, 'settings.json');
868
+ if (existsSync(settingsPath)) {
869
+ try {
870
+ const settings = JSON.parse(readFileSync(settingsPath, 'utf8'));
871
+ if (settings.permissions?.allow?.length > 0) {
872
+ result.passed.push({
873
+ file: '.claude/settings.json',
874
+ message: `${settings.permissions.allow.length} allowed tool patterns configured`,
875
+ });
876
+ }
877
+ if (settings.permissions?.deny?.length > 0) {
878
+ result.passed.push({
879
+ file: '.claude/settings.json',
880
+ message: `${settings.permissions.deny.length} denied patterns configured`,
881
+ });
882
+ }
883
+ } catch (e) {
884
+ // Already reported in JSON validation
885
+ }
886
+ }
887
+ }
888
+
889
+ /**
890
+ * Calculate overall score
891
+ */
892
+ function calculateOverallScore(results) {
893
+ let totalPassed = 0;
894
+ let totalWarnings = 0;
895
+ let totalErrors = 0;
896
+
897
+ for (const key of ['claudeMd', 'claudeFolder']) {
898
+ totalPassed += results[key].passed.length;
899
+ totalWarnings += results[key].warnings.length;
900
+ totalErrors += results[key].errors.length;
901
+ }
902
+
903
+ // Score calculation: start at 100, -5 per warning, -15 per error
904
+ let score = 100 - (totalWarnings * 5) - (totalErrors * 15);
905
+ score = Math.max(0, Math.min(100, score));
906
+
907
+ results.overall = {
908
+ passed: totalPassed,
909
+ warnings: totalWarnings,
910
+ errors: totalErrors,
911
+ suggestions: results.claudeMd.suggestions.length + results.claudeFolder.suggestions.length,
912
+ score,
913
+ };
914
+ }
915
+
916
+ /**
917
+ * Display audit results
918
+ */
919
+ function displayAuditResults(results) {
920
+ const { overall } = results;
921
+
922
+ // Score display with color
923
+ let scoreColor = chalk.green;
924
+ let scoreEmoji = '✅';
925
+ if (overall.score < 50) {
926
+ scoreColor = chalk.red;
927
+ scoreEmoji = '❌';
928
+ } else if (overall.score < 75) {
929
+ scoreColor = chalk.yellow;
930
+ scoreEmoji = '⚠️';
931
+ }
932
+
933
+ console.log(chalk.bold('━'.repeat(60)));
934
+ console.log(`${scoreEmoji} ${chalk.bold('Audit Score:')} ${scoreColor.bold(overall.score + '/100')}`);
935
+ console.log(chalk.bold('━'.repeat(60)));
936
+ console.log('');
937
+
938
+ console.log(` ${chalk.green('✓')} Passed: ${overall.passed}`);
939
+ console.log(` ${chalk.yellow('⚠')} Warnings: ${overall.warnings}`);
940
+ console.log(` ${chalk.red('✗')} Errors: ${overall.errors}`);
941
+ console.log(` ${chalk.blue('💡')} Suggestions: ${overall.suggestions}`);
942
+ console.log('');
943
+
944
+ // Display errors first
945
+ if (results.claudeMd.errors.length > 0 || results.claudeFolder.errors.length > 0) {
946
+ console.log(chalk.red.bold('Errors (must fix):'));
947
+ for (const err of [...results.claudeMd.errors, ...results.claudeFolder.errors]) {
948
+ console.log(` ${chalk.red('✗')} ${chalk.dim(err.file)} - ${err.message}`);
949
+ if (err.fix) {
950
+ console.log(` ${chalk.dim('Fix:')} ${err.fix}`);
951
+ }
952
+ }
953
+ console.log('');
954
+ }
955
+
956
+ // Display warnings
957
+ if (results.claudeMd.warnings.length > 0 || results.claudeFolder.warnings.length > 0) {
958
+ console.log(chalk.yellow.bold('Warnings (should fix):'));
959
+ for (const warn of [...results.claudeMd.warnings, ...results.claudeFolder.warnings]) {
960
+ console.log(` ${chalk.yellow('⚠')} ${chalk.dim(warn.file)} - ${warn.message}`);
961
+ if (warn.fix) {
962
+ console.log(` ${chalk.dim('Fix:')} ${warn.fix}`);
963
+ }
964
+ }
965
+ console.log('');
966
+ }
967
+
968
+ // Display suggestions (collapsed by default)
969
+ if (overall.suggestions > 0) {
970
+ console.log(chalk.blue.bold('Suggestions (optional):'));
971
+ for (const sug of [...results.claudeMd.suggestions, ...results.claudeFolder.suggestions]) {
972
+ console.log(` ${chalk.blue('💡')} ${chalk.dim(sug.file)} - ${sug.message}`);
973
+ }
974
+ console.log('');
975
+ }
976
+
977
+ // Display passes (summarized)
978
+ if (overall.passed > 0) {
979
+ console.log(chalk.green.bold(`Passed Checks (${overall.passed}):`));
980
+ const passedItems = [...results.claudeMd.passed, ...results.claudeFolder.passed];
981
+ // Show first 5, summarize rest
982
+ const toShow = passedItems.slice(0, 5);
983
+ for (const pass of toShow) {
984
+ console.log(` ${chalk.green('✓')} ${chalk.dim(pass.file)} - ${pass.message}`);
985
+ }
986
+ if (passedItems.length > 5) {
987
+ console.log(` ${chalk.dim(`... and ${passedItems.length - 5} more`)}`);
988
+ }
989
+ console.log('');
990
+ }
991
+ }
992
+
993
+ /**
994
+ * Show fix suggestions interactively
995
+ */
996
+ async function showFixSuggestions(results, cwd) {
997
+ const { overall } = results;
998
+
999
+ if (overall.errors === 0 && overall.warnings === 0) {
1000
+ console.log(chalk.green.bold('🎉 Great job! Your Claude configuration follows best practices.'));
1001
+ console.log('');
1002
+
1003
+ // Still offer enhancement even if passing
1004
+ const { wantEnhance } = await inquirer.prompt([
1005
+ {
1006
+ type: 'confirm',
1007
+ name: 'wantEnhance',
1008
+ message: 'Would you like to enhance CLAUDE.md with additional sections based on your tech stack?',
1009
+ default: false,
1010
+ },
1011
+ ]);
1012
+
1013
+ if (wantEnhance) {
1014
+ await runEnhancement(cwd);
1015
+ }
1016
+ return;
1017
+ }
1018
+
1019
+ const { action } = await inquirer.prompt([
1020
+ {
1021
+ type: 'list',
1022
+ name: 'action',
1023
+ message: 'What would you like to do?',
1024
+ choices: [
1025
+ { name: chalk.cyan('✨ Auto-enhance CLAUDE.md (Recommended)'), value: 'enhance' },
1026
+ { name: 'Show detailed fix instructions', value: 'details' },
1027
+ { name: 'Show best practices reference', value: 'reference' },
1028
+ { name: 'Exit', value: 'exit' },
1029
+ ],
1030
+ },
1031
+ ]);
1032
+
1033
+ if (action === 'enhance') {
1034
+ await runEnhancement(cwd);
1035
+ } else if (action === 'details') {
1036
+ showDetailedFixes(results);
1037
+ } else if (action === 'reference') {
1038
+ showBestPracticesReference();
1039
+ }
1040
+ }
1041
+
1042
+ /**
1043
+ * Show detailed fix instructions
1044
+ */
1045
+ function showDetailedFixes(results) {
1046
+ console.log('');
1047
+ console.log(chalk.bold('━'.repeat(60)));
1048
+ console.log(chalk.bold('Detailed Fix Instructions'));
1049
+ console.log(chalk.bold('━'.repeat(60)));
1050
+ console.log('');
1051
+
1052
+ const allIssues = [
1053
+ ...results.claudeMd.errors.map(e => ({ ...e, type: 'error' })),
1054
+ ...results.claudeFolder.errors.map(e => ({ ...e, type: 'error' })),
1055
+ ...results.claudeMd.warnings.map(w => ({ ...w, type: 'warning' })),
1056
+ ...results.claudeFolder.warnings.map(w => ({ ...w, type: 'warning' })),
1057
+ ];
1058
+
1059
+ for (let i = 0; i < allIssues.length; i++) {
1060
+ const issue = allIssues[i];
1061
+ const icon = issue.type === 'error' ? chalk.red('✗') : chalk.yellow('⚠');
1062
+ console.log(`${i + 1}. ${icon} ${chalk.bold(issue.file)}`);
1063
+ console.log(` Issue: ${issue.message}`);
1064
+ if (issue.fix) {
1065
+ console.log(` ${chalk.green('Fix:')} ${issue.fix}`);
1066
+ }
1067
+ console.log('');
1068
+ }
1069
+ }
1070
+
1071
+ /**
1072
+ * Show best practices reference
1073
+ */
1074
+ function showBestPracticesReference() {
1075
+ console.log('');
1076
+ console.log(chalk.bold('━'.repeat(60)));
1077
+ console.log(chalk.bold('Claude Code Best Practices Reference'));
1078
+ console.log(chalk.bold('━'.repeat(60)));
1079
+ console.log('');
1080
+
1081
+ console.log(chalk.cyan.bold('CLAUDE.md Best Practices:'));
1082
+ console.log('');
1083
+ console.log(` ${chalk.green('✓')} Keep under 60-150 lines (max 300)`);
1084
+ console.log(` ${chalk.green('✓')} Include bash commands Claude can't guess`);
1085
+ console.log(` ${chalk.green('✓')} Document code style rules that differ from defaults`);
1086
+ console.log(` ${chalk.green('✓')} Add testing instructions and preferred runners`);
1087
+ console.log(` ${chalk.green('✓')} Use emphasis (IMPORTANT, YOU MUST) for critical rules`);
1088
+ console.log(` ${chalk.green('✓')} Use @imports to keep files modular`);
1089
+ console.log('');
1090
+ console.log(` ${chalk.red('✗')} Avoid long code blocks (link to docs instead)`);
1091
+ console.log(` ${chalk.red('✗')} Skip obvious/generic advice ("write clean code")`);
1092
+ console.log(` ${chalk.red('✗')} Don't include API docs (link instead)`);
1093
+ console.log(` ${chalk.red('✗')} Remove anything Claude does correctly without instruction`);
1094
+ console.log('');
1095
+
1096
+ console.log(chalk.cyan.bold('.claude/ Folder Structure:'));
1097
+ console.log('');
1098
+ console.log(' .claude/');
1099
+ console.log(' ├── commands/ # Slash commands (.md files)');
1100
+ console.log(' ├── skills/ # Skills with SKILL.md');
1101
+ console.log(' ├── agents/ # Subagent definitions');
1102
+ console.log(' ├── hooks/ # Hook scripts');
1103
+ console.log(' ├── settings.json # Shared settings (git-tracked)');
1104
+ console.log(' └── settings.local.json # Local settings (gitignored)');
1105
+ console.log('');
1106
+
1107
+ console.log(chalk.cyan.bold('Skill/Agent Frontmatter:'));
1108
+ console.log('');
1109
+ console.log(' ---');
1110
+ console.log(' name: my-skill');
1111
+ console.log(' description: What this skill does');
1112
+ console.log(' tools: Read, Grep, Glob, Bash # agents only');
1113
+ console.log(' model: opus # optional');
1114
+ console.log(' ---');
1115
+ console.log('');
1116
+
1117
+ console.log(chalk.dim('Reference: https://code.claude.com/docs/en/best-practices'));
1118
+ console.log('');
1119
+ }
1120
+
1121
+ /**
1122
+ * Run CLAUDE.md enhancement
1123
+ */
1124
+ async function runEnhancement(cwd) {
1125
+ console.log('');
1126
+ console.log(chalk.bold('━'.repeat(60)));
1127
+ console.log(chalk.bold.cyan('🚀 CLAUDE.md Enhancement Mode'));
1128
+ console.log(chalk.bold('━'.repeat(60)));
1129
+ console.log('');
1130
+
1131
+ const spinner = ora('Detecting tech stack...').start();
1132
+
1133
+ // Detect tech stack
1134
+ const techStack = await detectTechStack(cwd, { silent: true });
1135
+
1136
+ spinner.succeed('Tech stack detected');
1137
+
1138
+ // Show what was detected
1139
+ console.log('');
1140
+ console.log(chalk.cyan('Detected Technologies:'));
1141
+ const detected = techStack._detected || [];
1142
+ for (const item of detected.slice(0, 8)) {
1143
+ console.log(` ${chalk.green('✓')} ${item}`);
1144
+ }
1145
+ if (detected.length > 8) {
1146
+ console.log(chalk.dim(` ... and ${detected.length - 8} more`));
1147
+ }
1148
+ console.log('');
1149
+
1150
+ // Get project name
1151
+ const projectName = techStack.project?.name || basename(cwd);
1152
+
1153
+ // Ask what to enhance
1154
+ const { enhanceMode } = await inquirer.prompt([
1155
+ {
1156
+ type: 'list',
1157
+ name: 'enhanceMode',
1158
+ message: 'What would you like to do?',
1159
+ choices: [
1160
+ { name: 'Generate full CLAUDE.md from scratch', value: 'full' },
1161
+ { name: 'Add missing sections to existing CLAUDE.md', value: 'add' },
1162
+ { name: 'Generate specific section', value: 'section' },
1163
+ { name: 'Preview generated content', value: 'preview' },
1164
+ { name: 'Back', value: 'back' },
1165
+ ],
1166
+ },
1167
+ ]);
1168
+
1169
+ if (enhanceMode === 'back') return;
1170
+
1171
+ if (enhanceMode === 'preview') {
1172
+ console.log('');
1173
+ console.log(chalk.bold('━'.repeat(60)));
1174
+ console.log(chalk.bold('Generated CLAUDE.md Preview:'));
1175
+ console.log(chalk.bold('━'.repeat(60)));
1176
+ console.log('');
1177
+ console.log(ENHANCEMENT_TEMPLATES.fullTemplate(techStack, projectName));
1178
+ console.log(chalk.bold('━'.repeat(60)));
1179
+ console.log('');
1180
+
1181
+ const { savePreview } = await inquirer.prompt([
1182
+ {
1183
+ type: 'confirm',
1184
+ name: 'savePreview',
1185
+ message: 'Save this to CLAUDE.md?',
1186
+ default: false,
1187
+ },
1188
+ ]);
1189
+
1190
+ if (savePreview) {
1191
+ await saveClaudeMd(cwd, techStack, projectName, 'full');
1192
+ }
1193
+ return;
1194
+ }
1195
+
1196
+ if (enhanceMode === 'section') {
1197
+ const { section } = await inquirer.prompt([
1198
+ {
1199
+ type: 'list',
1200
+ name: 'section',
1201
+ message: 'Which section to generate?',
1202
+ choices: [
1203
+ { name: 'Quick Start (commands to run)', value: 'quickStart' },
1204
+ { name: 'Tech Stack Table', value: 'techStackTable' },
1205
+ { name: 'Key Locations', value: 'keyLocations' },
1206
+ { name: 'Import Patterns', value: 'importPatterns' },
1207
+ { name: 'Testing Instructions', value: 'testingInstructions' },
1208
+ { name: 'Deployment Section', value: 'deploymentSection' },
1209
+ { name: 'Architecture Rules', value: 'architectureRules' },
1210
+ { name: 'Critical Rules', value: 'criticalRules' },
1211
+ { name: 'Reference Documentation Links', value: 'referenceLinks' },
1212
+ ],
1213
+ },
1214
+ ]);
1215
+
1216
+ const content = ENHANCEMENT_TEMPLATES[section](techStack);
1217
+ console.log('');
1218
+ console.log(chalk.bold('Generated Content:'));
1219
+ console.log(chalk.bold('━'.repeat(60)));
1220
+ console.log(content);
1221
+ console.log(chalk.bold('━'.repeat(60)));
1222
+ console.log('');
1223
+
1224
+ const { appendSection } = await inquirer.prompt([
1225
+ {
1226
+ type: 'confirm',
1227
+ name: 'appendSection',
1228
+ message: 'Append this section to CLAUDE.md?',
1229
+ default: true,
1230
+ },
1231
+ ]);
1232
+
1233
+ if (appendSection) {
1234
+ await appendToClaudeMd(cwd, content);
1235
+ }
1236
+ return;
1237
+ }
1238
+
1239
+ if (enhanceMode === 'full') {
1240
+ await saveClaudeMd(cwd, techStack, projectName, 'full');
1241
+ return;
1242
+ }
1243
+
1244
+ if (enhanceMode === 'add') {
1245
+ await addMissingSections(cwd, techStack, projectName);
1246
+ return;
1247
+ }
1248
+ }
1249
+
1250
+ /**
1251
+ * Save full CLAUDE.md
1252
+ */
1253
+ async function saveClaudeMd(cwd, techStack, projectName, mode) {
1254
+ const claudeMdPath = join(cwd, 'CLAUDE.md');
1255
+ const backupPath = join(cwd, 'CLAUDE.md.backup');
1256
+
1257
+ // Check for existing file
1258
+ if (existsSync(claudeMdPath)) {
1259
+ const { overwrite } = await inquirer.prompt([
1260
+ {
1261
+ type: 'list',
1262
+ name: 'overwrite',
1263
+ message: 'CLAUDE.md already exists. What would you like to do?',
1264
+ choices: [
1265
+ { name: 'Backup existing and replace', value: 'backup' },
1266
+ { name: 'Merge with existing (add missing sections)', value: 'merge' },
1267
+ { name: 'Cancel', value: 'cancel' },
1268
+ ],
1269
+ },
1270
+ ]);
1271
+
1272
+ if (overwrite === 'cancel') {
1273
+ console.log(chalk.yellow('Cancelled.'));
1274
+ return;
1275
+ }
1276
+
1277
+ if (overwrite === 'backup') {
1278
+ const existingContent = readFileSync(claudeMdPath, 'utf8');
1279
+ writeFileSync(backupPath, existingContent, 'utf8');
1280
+ console.log(chalk.dim(`Backed up to ${backupPath}`));
1281
+ }
1282
+
1283
+ if (overwrite === 'merge') {
1284
+ await addMissingSections(cwd, techStack, projectName);
1285
+ return;
1286
+ }
1287
+ }
1288
+
1289
+ // Generate and save
1290
+ const content = ENHANCEMENT_TEMPLATES.fullTemplate(techStack, projectName);
1291
+ writeFileSync(claudeMdPath, content, 'utf8');
1292
+
1293
+ console.log(chalk.green.bold('✓ CLAUDE.md generated successfully!'));
1294
+ console.log(chalk.dim(` Path: ${claudeMdPath}`));
1295
+ console.log('');
1296
+
1297
+ // Show stats
1298
+ const lines = content.split('\n').length;
1299
+ console.log(chalk.cyan('Stats:'));
1300
+ console.log(` Lines: ${lines} (recommended: <60, max: 300)`);
1301
+ console.log(` Size: ${(content.length / 1024).toFixed(1)} KB`);
1302
+ console.log('');
1303
+ }
1304
+
1305
+ /**
1306
+ * Append content to existing CLAUDE.md
1307
+ */
1308
+ async function appendToClaudeMd(cwd, content) {
1309
+ const claudeMdPath = join(cwd, 'CLAUDE.md');
1310
+
1311
+ let existingContent = '';
1312
+ if (existsSync(claudeMdPath)) {
1313
+ existingContent = readFileSync(claudeMdPath, 'utf8');
1314
+ }
1315
+
1316
+ const newContent = existingContent.trim() + '\n\n' + content;
1317
+ writeFileSync(claudeMdPath, newContent, 'utf8');
1318
+
1319
+ console.log(chalk.green.bold('✓ Section appended to CLAUDE.md'));
1320
+ }
1321
+
1322
+ /**
1323
+ * Add missing sections to existing CLAUDE.md
1324
+ */
1325
+ async function addMissingSections(cwd, techStack, projectName) {
1326
+ const claudeMdPath = join(cwd, 'CLAUDE.md');
1327
+
1328
+ let existingContent = '';
1329
+ if (existsSync(claudeMdPath)) {
1330
+ existingContent = readFileSync(claudeMdPath, 'utf8');
1331
+ }
1332
+
1333
+ const missingSections = [];
1334
+
1335
+ // Check which sections are missing
1336
+ const sectionChecks = [
1337
+ { pattern: /##\s*quick\s*start/i, name: 'Quick Start', key: 'quickStart' },
1338
+ { pattern: /##\s*tech\s*stack/i, name: 'Tech Stack', key: 'techStackTable' },
1339
+ { pattern: /##\s*key\s*locations/i, name: 'Key Locations', key: 'keyLocations' },
1340
+ { pattern: /##\s*import\s*patterns/i, name: 'Import Patterns', key: 'importPatterns' },
1341
+ { pattern: /##\s*testing/i, name: 'Testing', key: 'testingInstructions' },
1342
+ { pattern: /##\s*deploy/i, name: 'Deployment', key: 'deploymentSection' },
1343
+ { pattern: /##\s*architecture/i, name: 'Architecture Rules', key: 'architectureRules' },
1344
+ { pattern: /##\s*critical/i, name: 'Critical Rules', key: 'criticalRules' },
1345
+ { pattern: /##\s*reference/i, name: 'Reference Links', key: 'referenceLinks' },
1346
+ ];
1347
+
1348
+ for (const check of sectionChecks) {
1349
+ if (!check.pattern.test(existingContent)) {
1350
+ missingSections.push(check);
1351
+ }
1352
+ }
1353
+
1354
+ if (missingSections.length === 0) {
1355
+ console.log(chalk.green.bold('✓ CLAUDE.md already has all recommended sections!'));
1356
+ return;
1357
+ }
1358
+
1359
+ console.log('');
1360
+ console.log(chalk.yellow(`Found ${missingSections.length} missing sections:`));
1361
+ for (const section of missingSections) {
1362
+ console.log(` ${chalk.dim('-')} ${section.name}`);
1363
+ }
1364
+ console.log('');
1365
+
1366
+ const { sectionsToAdd } = await inquirer.prompt([
1367
+ {
1368
+ type: 'checkbox',
1369
+ name: 'sectionsToAdd',
1370
+ message: 'Select sections to add:',
1371
+ choices: missingSections.map((s) => ({
1372
+ name: s.name,
1373
+ value: s.key,
1374
+ checked: true,
1375
+ })),
1376
+ },
1377
+ ]);
1378
+
1379
+ if (sectionsToAdd.length === 0) {
1380
+ console.log(chalk.yellow('No sections selected.'));
1381
+ return;
1382
+ }
1383
+
1384
+ // Generate and append selected sections
1385
+ let newContent = existingContent.trim();
1386
+
1387
+ for (const key of sectionsToAdd) {
1388
+ const sectionContent = ENHANCEMENT_TEMPLATES[key](techStack);
1389
+ if (sectionContent.trim()) {
1390
+ newContent += '\n\n' + sectionContent;
1391
+ }
1392
+ }
1393
+
1394
+ writeFileSync(claudeMdPath, newContent, 'utf8');
1395
+
1396
+ console.log(chalk.green.bold(`✓ Added ${sectionsToAdd.length} sections to CLAUDE.md`));
1397
+ }
1398
+
1399
+ /**
1400
+ * Suggest enhancements based on audit results
1401
+ */
1402
+ function generateEnhancementSuggestions(results, techStack) {
1403
+ const suggestions = [];
1404
+
1405
+ // Check if missing Quick Start
1406
+ const hasQuickStart = results.claudeMd.passed.some((p) =>
1407
+ p.message?.includes('Quick Start')
1408
+ );
1409
+ if (!hasQuickStart) {
1410
+ suggestions.push({
1411
+ type: 'section',
1412
+ name: 'Quick Start',
1413
+ priority: 'high',
1414
+ reason: 'Every CLAUDE.md should have runnable commands',
1415
+ content: ENHANCEMENT_TEMPLATES.quickStart(techStack),
1416
+ });
1417
+ }
1418
+
1419
+ // Check if file is too short
1420
+ const veryShort = results.claudeMd.warnings.some((w) =>
1421
+ w.message?.includes('Very little content')
1422
+ );
1423
+ if (veryShort) {
1424
+ suggestions.push({
1425
+ type: 'full',
1426
+ name: 'Full Enhancement',
1427
+ priority: 'high',
1428
+ reason: 'CLAUDE.md has minimal content',
1429
+ });
1430
+ }
1431
+
1432
+ // Suggest reference docs based on tech stack
1433
+ if (techStack.frontend?.framework || techStack.backend?.framework) {
1434
+ suggestions.push({
1435
+ type: 'section',
1436
+ name: 'Reference Links',
1437
+ priority: 'medium',
1438
+ reason: 'Add framework documentation links',
1439
+ content: ENHANCEMENT_TEMPLATES.referenceLinks(techStack),
1440
+ });
1441
+ }
1442
+
1443
+ return suggestions;
1444
+ }
1445
+
1446
+ /**
1447
+ * Interactive menu entry point
1448
+ */
1449
+ export async function showClaudeAuditMenu() {
1450
+ const { mode } = await inquirer.prompt([
1451
+ {
1452
+ type: 'list',
1453
+ name: 'mode',
1454
+ message: 'Claude Code Configuration Audit:',
1455
+ choices: [
1456
+ { name: 'Run Full Audit', value: 'full' },
1457
+ { name: 'Audit CLAUDE.md only', value: 'claudemd' },
1458
+ { name: 'Audit .claude/ folder only', value: 'folder' },
1459
+ { name: chalk.cyan('✨ Enhance CLAUDE.md (NEW)'), value: 'enhance' },
1460
+ { name: 'Show Best Practices Reference', value: 'reference' },
1461
+ { name: 'Back', value: 'back' },
1462
+ ],
1463
+ },
1464
+ ]);
1465
+
1466
+ if (mode === 'back') return;
1467
+
1468
+ if (mode === 'reference') {
1469
+ showBestPracticesReference();
1470
+ return;
1471
+ }
1472
+
1473
+ if (mode === 'enhance') {
1474
+ await runEnhancement(process.cwd());
1475
+ return;
1476
+ }
1477
+
1478
+ await runClaudeAudit({ mode });
1479
+ }
1480
+
1481
+ // Export enhancement templates for use by other modules
1482
+ export { ENHANCEMENT_TEMPLATES, runEnhancement };