@chemx/starter-kit 26.9.9-786 → 26.9.11-481

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 (45) hide show
  1. package/cli/audit/ast-visitors.js +243 -0
  2. package/cli/audit/discussion-store.js +39 -0
  3. package/cli/audit/history.d.ts +69 -0
  4. package/cli/audit/history.js +397 -0
  5. package/cli/audit/metrics.js +179 -0
  6. package/cli/audit/prompts.js +174 -0
  7. package/cli/audit/reporter-ascii.d.ts +4 -0
  8. package/cli/audit/reporter-ascii.js +99 -0
  9. package/cli/audit/reporter-grades.js +275 -0
  10. package/cli/audit/reporter-markdown.js +137 -0
  11. package/cli/audit/reporter-utils.js +125 -0
  12. package/cli/audit/reporter.js +497 -0
  13. package/cli/audit/rules-helpers.js +109 -0
  14. package/cli/audit/rules-registry.js +97 -0
  15. package/cli/audit/rules.js +123 -0
  16. package/cli/audit/social-constants.js +4 -0
  17. package/cli/audit/social-gh.js +126 -0
  18. package/cli/audit/social-git.js +214 -0
  19. package/cli/audit/social-http.js +222 -0
  20. package/cli/audit/social-publisher.js +193 -0
  21. package/cli/audit/social.d.ts +69 -0
  22. package/cli/audit/social.js +303 -0
  23. package/cli/audit/types.d.ts +140 -0
  24. package/cli/audit.d.ts +3 -24
  25. package/cli/audit.js +207 -210
  26. package/cli/help.d.ts +1 -0
  27. package/cli/help.js +136 -0
  28. package/cli/index.js +128 -566
  29. package/cli/installer-templates.js +91 -0
  30. package/cli/installer.d.ts +21 -0
  31. package/cli/installer.js +104 -0
  32. package/cli/license.js +320 -0
  33. package/cli/navigator-actions.js +274 -0
  34. package/cli/navigator-banner.js +98 -0
  35. package/cli/navigator-conversion.js +100 -0
  36. package/cli/navigator-grades.js +87 -0
  37. package/cli/navigator-menu.js +127 -0
  38. package/cli/navigator-paged.js +86 -0
  39. package/cli/navigator-share.js +129 -0
  40. package/cli/navigator.d.ts +43 -0
  41. package/cli/navigator.js +126 -0
  42. package/cli/scaffold.js +148 -0
  43. package/cli/terminal.js +126 -0
  44. package/docs/CHANGELOG.md +101 -0
  45. package/package.json +11 -10
@@ -0,0 +1,497 @@
1
+ import { PILLARS } from './rules.js';
2
+ import {
3
+ buildMasterPrompt,
4
+ formatPromptBox
5
+ } from './prompts.js';
6
+ import {
7
+ CYAN,
8
+ GREEN,
9
+ YELLOW,
10
+ RED,
11
+ ORANGE,
12
+ DIM,
13
+ BOLD,
14
+ RESET,
15
+ groupViolationsBySeverity,
16
+ getStatusBadge,
17
+ resolveGradeColor,
18
+ resolveHealthHearts,
19
+ resolveRiskColor,
20
+ resolveHotspotBadge
21
+ } from './reporter-utils.js';
22
+
23
+ export {
24
+ groupViolationsBySeverity,
25
+ getSeverityBadge,
26
+ getStatusBadge,
27
+ resolveGradeColor,
28
+ resolveHealthHearts,
29
+ resolveRiskColor,
30
+ resolveHotspotBadge,
31
+ resolveMarkdownStatusIcon,
32
+ resolveMarkdownMonolithText,
33
+ PILLAR_EMOJIS,
34
+ NUMBER_EMOJIS,
35
+ resolvePriorityBadge,
36
+ CYAN,
37
+ GREEN,
38
+ YELLOW,
39
+ RED,
40
+ ORANGE,
41
+ DIM,
42
+ BOLD,
43
+ RESET
44
+ } from './reporter-utils.js';
45
+
46
+ export { generateMarkdownReport } from './reporter-markdown.js';
47
+
48
+ export {
49
+ formatGradeFSection,
50
+ formatGradeDSection,
51
+ formatGradeCSection,
52
+ formatGradeBSection,
53
+ formatGradeASection
54
+ } from './reporter-grades.js';
55
+
56
+ export {
57
+ getAsciiGradeLines,
58
+ formatAsciiGrade,
59
+ getReportCardAsciiLines,
60
+ REPORT_CARD_ASCII
61
+ } from './reporter-ascii.js';
62
+
63
+ import { getAsciiGradeLines, getReportCardAsciiLines } from './reporter-ascii.js';
64
+
65
+ export const resolveTopSectionColor = (report) => {
66
+ const hasNoViolations = (report?.violations?.length ?? 0) === 0;
67
+ const hasNoHotspots = (report?.hotspots?.length ?? 0) === 0;
68
+ const areAllPillarsPassed = Object.values(report?.pillars ?? {}).every((p) => p.status === 'PASSED');
69
+ const isAllPassed = hasNoViolations && hasNoHotspots && areAllPillarsPassed;
70
+ return isAllPassed ? GREEN : CYAN;
71
+ };
72
+
73
+ export const formatScorecardSection = (report, themeColor = null) => {
74
+ const { metrics, health } = report;
75
+ const sectionColor = themeColor || resolveTopSectionColor(report);
76
+ const gradeColor = resolveGradeColor(health?.score ?? health?.grade ?? 'A');
77
+ const lines = [];
78
+
79
+ lines.push('');
80
+ for (const rcLine of getReportCardAsciiLines(sectionColor)) {
81
+ lines.push(` ${rcLine}`);
82
+ }
83
+ lines.push(`${sectionColor}======================================================================${RESET}`);
84
+ lines.push(`${BOLD}${sectionColor} MOLECULAR HEALTH INDEX & CODEBASE OVERVIEW${RESET}`);
85
+ lines.push(`${sectionColor}======================================================================${RESET}`);
86
+
87
+ const asciiGradeLines = getAsciiGradeLines(health?.grade || 'A', gradeColor);
88
+ if (asciiGradeLines.length > 0) {
89
+ lines.push('');
90
+ for (const asciiLine of asciiGradeLines) {
91
+ lines.push(` ${asciiLine}`);
92
+ }
93
+ lines.push('');
94
+ lines.push(`${sectionColor}----------------------------------------------------------------------${RESET}`);
95
+ }
96
+
97
+ const hearts = resolveHealthHearts(health?.grade, health?.score);
98
+ lines.push(` Life / Health Meter: ${hearts} ${gradeColor}${BOLD}${health.score} / 100${RESET} (Grade: ${gradeColor}${BOLD}${health.grade}${RESET} - ${health.label})`);
99
+ lines.push(` Files Scanned: ${BOLD}${metrics.scannedFiles}${RESET} source files`);
100
+ lines.push(` Total Lines of Code: ${BOLD}${metrics.totalLoc}${RESET} lines of code (avg: ${metrics.avgLoc} lines/file)`);
101
+ lines.push(` Largest File: ${BOLD}${metrics.largestFile.filePath || 'None'}${RESET} (${metrics.largestFile.lineCount} lines)`);
102
+ lines.push(` Molecule Capsules: ${metrics.moleculeCount} found (${metrics.moleculeCompliantPct}% compliant < 100 lines of code)`);
103
+ lines.push(` Custom Hooks: ${metrics.hookCount} detected`);
104
+ lines.push(`${sectionColor}======================================================================${RESET}\n`);
105
+
106
+ return lines.join('\n');
107
+ };
108
+
109
+ export const formatCriticalSection = (report) => {
110
+ const { violations } = report;
111
+ const { critical } = groupViolationsBySeverity(violations);
112
+ const lines = [];
113
+
114
+ lines.push('');
115
+ lines.push(`${RED}======================================================================${RESET}`);
116
+ lines.push(`${BOLD}${RED} CRITICAL HAZARDS (${critical.length} TOTAL) : IMMEDIATE ACTION REQUIRED${RESET}`);
117
+ lines.push(`${DIM} Violations that break Molecular line budgets or introduce severe AST bugs${RESET}`);
118
+ lines.push(`${RED}======================================================================${RESET}`);
119
+
120
+ if (critical.length === 0) {
121
+ lines.push(` ${GREEN}✔ Zero critical hazards detected. No monoliths or breaking AST patterns.${RESET}`);
122
+ } else {
123
+ critical.forEach((v, idx) => {
124
+ lines.push(` ${RED}[#${idx + 1} CRITICAL]${RESET} [${v.rule}] ${YELLOW}${v.filePath}:${v.line}:${v.column}${RESET}`);
125
+ lines.push(` Hazard: ${v.hazard}`);
126
+ lines.push(` Directive: ${CYAN}${v.directive}${RESET}\n`);
127
+ });
128
+ }
129
+ lines.push(`${RED}======================================================================${RESET}\n`);
130
+
131
+ return lines.join('\n');
132
+ };
133
+
134
+ export const formatHighMediumSection = (report) => {
135
+ const { violations } = report;
136
+ const { high, medium } = groupViolationsBySeverity(violations);
137
+ const totalCount = high.length + medium.length;
138
+ const lines = [];
139
+
140
+ lines.push('');
141
+ lines.push(`${ORANGE}======================================================================${RESET}`);
142
+ lines.push(`${BOLD}${ORANGE} HIGH & MEDIUM HAZARDS (${totalCount} TOTAL) : ARCHITECTURE DEBTS${RESET}`);
143
+ lines.push(`${DIM} Saturation, complex control flow booleans, and raw inline styles${RESET}`);
144
+ lines.push(`${ORANGE}======================================================================${RESET}`);
145
+
146
+ if (totalCount === 0) {
147
+ lines.push(` ${GREEN}✔ Zero high or medium architecture hazards detected.${RESET}`);
148
+ } else {
149
+ if (high.length > 0) {
150
+ lines.push(`\n ${BOLD}--- High Severity (${high.length} items) ---${RESET}`);
151
+ high.forEach((v, idx) => {
152
+ lines.push(` ${ORANGE}[#${idx + 1} HIGH]${RESET} [${v.rule}] ${YELLOW}${v.filePath}:${v.line}:${v.column}${RESET}`);
153
+ lines.push(` Hazard: ${v.hazard}`);
154
+ lines.push(` Directive: ${CYAN}${v.directive}${RESET}\n`);
155
+ });
156
+ }
157
+
158
+ if (medium.length > 0) {
159
+ lines.push(`\n ${BOLD}--- Medium Severity (${medium.length} items) ---${RESET}`);
160
+ medium.forEach((v, idx) => {
161
+ lines.push(` ${ORANGE}[#${idx + 1} MED]${RESET} [${v.rule}] ${YELLOW}${v.filePath}:${v.line}:${v.column}${RESET}`);
162
+ lines.push(` Hazard: ${v.hazard}`);
163
+ lines.push(` Directive: ${CYAN}${v.directive}${RESET}\n`);
164
+ });
165
+ }
166
+ }
167
+ lines.push(`${ORANGE}======================================================================${RESET}\n`);
168
+
169
+ return lines.join('\n');
170
+ };
171
+
172
+ export const formatLowSection = (report) => {
173
+ const { violations } = report;
174
+ const { low } = groupViolationsBySeverity(violations);
175
+ const lines = [];
176
+
177
+ lines.push('');
178
+ lines.push(`${YELLOW}======================================================================${RESET}`);
179
+ lines.push(`${BOLD}${YELLOW} LOW & HYGIENE ISSUES (${low.length} TOTAL) : TYPOGRAPHY & LOGGING${RESET}`);
180
+ lines.push(`${DIM} Em dash typography violations and unguarded console statements${RESET}`);
181
+ lines.push(`${YELLOW}======================================================================${RESET}`);
182
+
183
+ if (low.length === 0) {
184
+ lines.push(` ${GREEN}✔ Zero typography or logging hygiene issues detected.${RESET}`);
185
+ } else {
186
+ low.forEach((v, idx) => {
187
+ lines.push(` ${YELLOW}[#${idx + 1} LOW]${RESET} [${v.rule}] ${YELLOW}${v.filePath}:${v.line}:${v.column}${RESET}`);
188
+ lines.push(` Hazard: ${v.hazard}`);
189
+ lines.push(` Directive: ${CYAN}${v.directive}${RESET}\n`);
190
+ });
191
+ }
192
+ lines.push(`${YELLOW}======================================================================${RESET}\n`);
193
+
194
+ return lines.join('\n');
195
+ };
196
+
197
+ export const formatPillarsSection = (report, themeColor = null) => {
198
+ const { pillars } = report;
199
+ const sectionColor = themeColor || resolveTopSectionColor(report);
200
+ const lines = [];
201
+
202
+ lines.push('');
203
+ lines.push(`${sectionColor}======================================================================${RESET}`);
204
+ lines.push(`${BOLD}${sectionColor} 7-PILLAR ARCHITECTURAL COMPLIANCE MATRIX${RESET}`);
205
+ lines.push(`${sectionColor}======================================================================${RESET}`);
206
+ lines.push(` ${DIM}Pillar Name Status Violations${RESET}`);
207
+ lines.push(` ${DIM}------------------------------------------------------------------${RESET}`);
208
+ for (const [pillarName, data] of Object.entries(pillars)) {
209
+ const padName = pillarName.padEnd(45, ' ');
210
+ const badge = getStatusBadge(data.status).padEnd(16, ' ');
211
+ const countStr = data.violations === 0 ? `${GREEN}0${RESET}` : `${RED}${data.violations}${RESET}`;
212
+ lines.push(` ${padName} ${badge} ${countStr}`);
213
+ }
214
+ lines.push(`${sectionColor}======================================================================${RESET}\n`);
215
+
216
+ return lines.join('\n');
217
+ };
218
+
219
+ export const formatHotspotsSection = (report, themeColor = null) => {
220
+ const { hotspots } = report;
221
+ const sectionColor = themeColor || resolveTopSectionColor(report);
222
+ const lines = [];
223
+
224
+ lines.push('');
225
+ lines.push(`${sectionColor}======================================================================${RESET}`);
226
+ lines.push(`${BOLD}${sectionColor} TOP REFACTORING HOTSPOTS (PRIORITY RANKING)${RESET}`);
227
+ lines.push(`${sectionColor}======================================================================${RESET}`);
228
+
229
+ if (hotspots.length === 0) {
230
+ lines.push(` ${GREEN}✔ Zero hotspot files. All files stay within architectural budgets.${RESET}`);
231
+ } else {
232
+ hotspots.forEach((h, idx) => {
233
+ const monolithBadge = resolveHotspotBadge(h.lineCount);
234
+ lines.push(` [#${idx + 1}] ${YELLOW}${h.filePath}${RESET} (${h.lineCount} lines, ${h.violationCount} hazards)${monolithBadge}`);
235
+ });
236
+ }
237
+ lines.push(`${sectionColor}======================================================================${RESET}\n`);
238
+
239
+ return lines.join('\n');
240
+ };
241
+
242
+ export const formatContextAnalysisSection = (report, themeColor = null) => {
243
+ const { contextAnalysis } = report;
244
+ const sectionColor = themeColor || resolveTopSectionColor(report);
245
+ const riskColor = resolveRiskColor(contextAnalysis.riskLevel);
246
+ const lines = [];
247
+
248
+ lines.push('');
249
+ lines.push(`${sectionColor}======================================================================${RESET}`);
250
+ lines.push(`${BOLD}${sectionColor} CONTEXT ROT & TOKEN BURN ANALYTICS${RESET}`);
251
+ lines.push(`${sectionColor}======================================================================${RESET}`);
252
+ lines.push(` Estimated Codebase Tokens: ~${contextAnalysis.estimatedTokens.toLocaleString()} tokens`);
253
+ lines.push(` Estimated Monolith Bloat: ~${contextAnalysis.estimatedExcessTokens.toLocaleString()} tokens`);
254
+ lines.push(` Target Architecture Cut: ${BOLD}${contextAnalysis.potentialSavingsPct}%${RESET} token reduction potential`);
255
+ lines.push(` Agent Hallucination Risk: ${riskColor}${BOLD}${contextAnalysis.riskLevel}${RESET}`);
256
+ if (contextAnalysis.excessCostPerPass !== undefined) {
257
+ const costPass = contextAnalysis.excessCostPerPass.toFixed(3);
258
+ const costMonth = contextAnalysis.monthlyWastePerDev.toFixed(2);
259
+ const costWeek = contextAnalysis.weeklyWastePerDev.toFixed(2);
260
+ lines.push(` Pricing Model Baseline: ${contextAnalysis.pricingModel}`);
261
+ lines.push(` Monolith Bloat per AI Turn: \x1b[38;5;208;1m$${costPass}\x1b[0m / prompt turn`);
262
+ lines.push(` Projected Dev Context Tax: \x1b[31;1m$${costMonth}/mo\x1b[0m per engineer ($${costWeek}/wk)`);
263
+ }
264
+ lines.push(`${sectionColor}======================================================================${RESET}\n`);
265
+
266
+ return lines.join('\n');
267
+ };
268
+
269
+ export const getChemicalXAsciiBanner = (gradeOrReport = null) => {
270
+ const grade = typeof gradeOrReport === 'object' && gradeOrReport !== null
271
+ ? gradeOrReport.health?.grade
272
+ : gradeOrReport;
273
+
274
+ const art = [
275
+ ' ██████╗██╗ ██╗███████╗███╗ ███╗██╗ ██████╗ █████╗ ██╗ ██╗ ██╗',
276
+ '██╔════╝██║ ██║██╔════╝████╗ ████║██║██╔════╝██╔══██╗██║ ╚██╗██╔╝',
277
+ '██║ ███████║█████╗ ██╔████╔██║██║██║ ███████║██║ ╚███╔╝ ',
278
+ '██║ ██╔══██║██╔══╝ ██║╚██╔╝██║██║██║ ██╔══██║██║ ██╔██╗ ',
279
+ '╚██████╗██║ ██║███████╗██║ ╚═╝ ██║██║╚██████╗██║ ██║███████╗ ██╔╝ ██╗',
280
+ ' ╚═════╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝╚═╝ ╚═════╝╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═╝'
281
+ ];
282
+
283
+ const maxLen = 74;
284
+ const lines = [];
285
+
286
+ lines.push(' \x1b[1m\x1b[37mThe Secret Sauce to \x1b[38;2;98;201;255mVibe Coding\x1b[0m');
287
+
288
+ const gColor = grade ? resolveGradeColor(grade) : '';
289
+ const gradeLines = grade ? getAsciiGradeLines(grade, gColor, true) : [];
290
+ const termWidth = process.stdout.columns || 0;
291
+ const isSideBySide = Boolean(!termWidth || termWidth >= 105);
292
+
293
+ for (let lineIdx = 0; lineIdx < art.length; lineIdx++) {
294
+ const line = art[lineIdx];
295
+ let out = '';
296
+ for (let i = 0; i < line.length; i++) {
297
+ const ch = line[i];
298
+ if (ch === ' ') {
299
+ out += ' ';
300
+ continue;
301
+ }
302
+ const t = i / (maxLen - 1);
303
+ let r, g, b;
304
+ if (t < 0.5) {
305
+ const factor = t * 2;
306
+ r = Math.round(244 * (1 - factor) + 192 * factor);
307
+ g = Math.round(114 * (1 - factor) + 132 * factor);
308
+ b = Math.round(182 * (1 - factor) + 252 * factor);
309
+ } else {
310
+ const factor = (t - 0.5) * 2;
311
+ r = Math.round(192 * (1 - factor) + 129 * factor);
312
+ g = Math.round(132 * (1 - factor) + 140 * factor);
313
+ b = Math.round(252 * (1 - factor) + 248 * factor);
314
+ }
315
+ out += `\x1b[38;2;${r};${g};${b}m\x1b[1m${ch}\x1b[0m`;
316
+ }
317
+
318
+ if (isSideBySide && gradeLines.length > lineIdx) {
319
+ out += ` ${gradeLines[lineIdx]}`;
320
+ }
321
+
322
+ lines.push(out);
323
+ }
324
+
325
+ const subtitle = 'Architectural guardrails to eliminate token burn and AI hallucinations.';
326
+ const pad = ' '.repeat(Math.max(0, Math.floor((maxLen - subtitle.length) / 2)));
327
+ lines.push(`${pad}\x1b[2m${subtitle}\x1b[0m\n`);
328
+
329
+ if (!isSideBySide && gradeLines.length > 0) {
330
+ for (const gl of gradeLines) {
331
+ lines.push(` ${gl}`);
332
+ }
333
+ lines.push('');
334
+ }
335
+
336
+ return lines.join('\n');
337
+ };
338
+
339
+ export const formatTerminalReport = (report) => {
340
+ const lines = [];
341
+ const topColor = resolveTopSectionColor(report);
342
+
343
+ lines.push('');
344
+ lines.push(getChemicalXAsciiBanner(report?.health?.grade));
345
+ lines.push(`${topColor}======================================================================${RESET}`);
346
+ lines.push(`${BOLD}${topColor} CHEMICAL X PROTOCOL : FULL CODEBASE ARCHITECTURAL AUDIT REPORT${RESET}`);
347
+ lines.push(`${DIM} Molecular Architecture Standards & Context Hazard Verification${RESET}`);
348
+ lines.push(`${topColor}======================================================================${RESET}`);
349
+
350
+ lines.push(formatScorecardSection(report, topColor));
351
+ lines.push(formatContextAnalysisSection(report, topColor));
352
+ lines.push(formatPillarsSection(report, topColor));
353
+ lines.push(formatHotspotsSection(report, topColor));
354
+ lines.push(formatCriticalSection(report));
355
+ lines.push(formatHighMediumSection(report));
356
+ lines.push(formatLowSection(report));
357
+
358
+ const masterPrompt = buildMasterPrompt(report);
359
+ if (masterPrompt) {
360
+ lines.push(formatPromptBox('🤖 MASTER AI AGENT REFACTORING PROMPT', masterPrompt));
361
+ }
362
+
363
+ return lines.join('\n');
364
+ };
365
+
366
+ export const formatFailuresSection = (report) => {
367
+ const { violations, pillars, hotspots } = report;
368
+ const { critical, high, medium, low } = groupViolationsBySeverity(violations);
369
+ const lines = [];
370
+
371
+ lines.push('');
372
+ lines.push(`${RED}======================================================================${RESET}`);
373
+ lines.push(`${BOLD}${RED} FAILED & DEGRADED CHECKS : HAZARDS, DEBTS & HOTSPOTS${RESET}`);
374
+ lines.push(`${DIM} Consolidated breakdown of all failed architectural checks${RESET}`);
375
+ lines.push(`${RED}======================================================================${RESET}`);
376
+
377
+ if (violations.length === 0 && hotspots.length === 0) {
378
+ lines.push(`\n ${GREEN}${BOLD}✔ ZERO FAILURES DETECTED!${RESET}`);
379
+ lines.push(' All 7 Chemical X Molecular Architecture Pillars are 100% Compliant.\n');
380
+ lines.push(`${RED}======================================================================${RESET}\n`);
381
+ return lines.join('\n');
382
+ }
383
+
384
+ lines.push(` Total Hazards Flagged: ${BOLD}${RED}${violations.length}${RESET}`);
385
+ const critDesc = critical.length > 0 ? `${RED}${BOLD}${critical.length} (Immediate Action Required)${RESET}` : `${GREEN}0${RESET}`;
386
+ lines.push(` Critical Hazards: ${critDesc}`);
387
+ const debtsTotal = high.length + medium.length;
388
+ const debtsDesc = debtsTotal > 0 ? `${ORANGE}${BOLD}${debtsTotal}${RESET}` : `${GREEN}0${RESET}`;
389
+ lines.push(` High/Med Debts: ${debtsDesc}`);
390
+ const lowDesc = low.length > 0 ? `${YELLOW}${low.length}${RESET}` : `${GREEN}0${RESET}`;
391
+ lines.push(` Low Hygiene Issues: ${lowDesc}`);
392
+ const hotspotsDesc = hotspots.length > 0 ? `${YELLOW}${hotspots.length}${RESET}` : `${GREEN}0${RESET}`;
393
+ lines.push(` Hotspot Files: ${hotspotsDesc}`);
394
+ lines.push(`${RED}----------------------------------------------------------------------${RESET}`);
395
+
396
+ if (critical.length > 0) {
397
+ lines.push(`\n ${BOLD}${RED}🚨 CRITICAL HAZARDS (${critical.length}) : IMMEDIATE ACTION REQUIRED${RESET}`);
398
+ critical.forEach((v, idx) => {
399
+ lines.push(` ${RED}[#${idx + 1} CRITICAL]${RESET} [${v.rule}] ${YELLOW}${v.filePath}:${v.line}:${v.column}${RESET}`);
400
+ lines.push(` Hazard: ${v.hazard}`);
401
+ lines.push(` Directive: ${CYAN}${v.directive}${RESET}\n`);
402
+ });
403
+ }
404
+
405
+ if (debtsTotal > 0) {
406
+ lines.push(` ${BOLD}${ORANGE}⚠️ HIGH & MEDIUM HAZARDS (${debtsTotal}) : ARCHITECTURE DEBTS${RESET}`);
407
+ [...high, ...medium].forEach((v, idx) => {
408
+ const isHigh = v.severity === 'HIGH';
409
+ const badge = isHigh ? `${ORANGE}[#${idx + 1} HIGH]${RESET}` : `${ORANGE}[#${idx + 1} MED]${RESET}`;
410
+ lines.push(` ${badge} [${v.rule}] ${YELLOW}${v.filePath}:${v.line}:${v.column}${RESET}`);
411
+ lines.push(` Hazard: ${v.hazard}`);
412
+ lines.push(` Directive: ${CYAN}${v.directive}${RESET}\n`);
413
+ });
414
+ }
415
+
416
+ if (low.length > 0) {
417
+ lines.push(` ${BOLD}${YELLOW}🧹 LOW & HYGIENE ISSUES (${low.length})${RESET}`);
418
+ low.forEach((v, idx) => {
419
+ lines.push(` ${YELLOW}[#${idx + 1} LOW]${RESET} [${v.rule}] ${YELLOW}${v.filePath}:${v.line}:${v.column}${RESET}`);
420
+ lines.push(` Hazard: ${v.hazard}`);
421
+ lines.push(` Directive: ${CYAN}${v.directive}${RESET}\n`);
422
+ });
423
+ }
424
+
425
+ const failedPillars = Object.entries(pillars).filter(([_, p]) => p.status !== 'PASSED');
426
+ if (failedPillars.length > 0) {
427
+ lines.push(` ${BOLD}${RED}🏛️ FAILED / DEGRADED PILLARS (${failedPillars.length})${RESET}`);
428
+ for (const [name, p] of failedPillars) {
429
+ lines.push(` ✕ ${YELLOW}${name}${RESET}: ${p.violations} violations (${p.critical} Critical, ${p.high} High, ${p.medium} Med)`);
430
+ }
431
+ lines.push('');
432
+ }
433
+
434
+ if (hotspots.length > 0) {
435
+ lines.push(` ${BOLD}${YELLOW}🔥 REFACTORING HOTSPOTS (${hotspots.length})${RESET}`);
436
+ hotspots.forEach((h, idx) => {
437
+ const monolithBadge = resolveHotspotBadge(h.lineCount);
438
+ lines.push(` [#${idx + 1}] ${YELLOW}${h.filePath}${RESET} (${h.lineCount} lines, ${h.violationCount} hazards)${monolithBadge}`);
439
+ });
440
+ lines.push('');
441
+ }
442
+
443
+ const prompt = buildMasterPrompt(report);
444
+ if (prompt) {
445
+ lines.push(formatPromptBox('🤖 AI AGENT REFACTORING PROMPT (ALL FAILED CHECKS)', prompt));
446
+ }
447
+
448
+ lines.push(`${RED}======================================================================${RESET}\n`);
449
+ return lines.join('\n');
450
+ };
451
+
452
+ export const formatPassesSection = (report) => {
453
+ const { metrics, health, pillars, hotspots, contextAnalysis } = report;
454
+ const passedPillars = Object.entries(pillars).filter(([_, p]) => p.status === 'PASSED');
455
+ const lines = [];
456
+
457
+ lines.push('');
458
+ lines.push(`${GREEN}======================================================================${RESET}`);
459
+ lines.push(`${BOLD}${GREEN} PASSED & COMPLIANT CHECKS : CLEAN ARCHITECTURE STANDARDS${RESET}`);
460
+ lines.push(`${DIM} Consolidated breakdown of verified compliant areas${RESET}`);
461
+ lines.push(`${GREEN}======================================================================${RESET}`);
462
+
463
+ lines.push(` Molecular Health Score: ${BOLD}${GREEN}${health.score}/100${RESET} [Grade: ${BOLD}${GREEN}${health.grade}${RESET}]`);
464
+ lines.push(` Passing Pillars: ${BOLD}${GREEN}${passedPillars.length} / 7 Pillars PASSED${RESET}`);
465
+ lines.push(` Capsule Compliance: ${BOLD}${GREEN}${metrics.moleculeCompliantPct}%${RESET} molecules compliant (< 100 lines of code)`);
466
+ lines.push(` Total Files Scanned: ${metrics.scannedFiles} source files (${metrics.totalLoc} total lines of code)`);
467
+ lines.push(`${GREEN}----------------------------------------------------------------------${RESET}`);
468
+
469
+ lines.push(`\n ${BOLD}${GREEN}✔ COMPLIANT ARCHITECTURAL PILLARS:${RESET}`);
470
+ if (passedPillars.length === 0) {
471
+ lines.push(` ${YELLOW}No pillars are completely hazard-free.${RESET}\n`);
472
+ } else {
473
+ for (const [name] of passedPillars) {
474
+ lines.push(` ${GREEN}✔${RESET} ${name} ${DIM}(0 violations)${RESET}`);
475
+ }
476
+ lines.push('');
477
+ }
478
+
479
+ lines.push(` ${BOLD}${CYAN}STANDARDS MET & CLEAN AREAS:${RESET}`);
480
+ if (metrics.moleculeCompliantPct === 100) {
481
+ lines.push(` ${GREEN}✔${RESET} 100% Molecule Capsule Limit (< 100 lines per molecule)`);
482
+ }
483
+ const hasExtremeMonolith = hotspots.some((h) => h.lineCount >= 2000);
484
+ if (!hasExtremeMonolith) {
485
+ lines.push(` ${GREEN}✔${RESET} Zero Extreme Monoliths (0 files >= 2,000 lines of code)`);
486
+ }
487
+ const hasSevereMonolith = hotspots.some((h) => h.lineCount >= 1000);
488
+ if (!hasSevereMonolith) {
489
+ lines.push(` ${GREEN}✔${RESET} Zero Severe Monoliths (0 files >= 1,000 lines of code)`);
490
+ }
491
+ if (contextAnalysis.riskLevel === 'LOW') {
492
+ lines.push(` ${GREEN}✔${RESET} Low Context Hazard & Token Burn Risk`);
493
+ }
494
+
495
+ lines.push(`\n${GREEN}======================================================================${RESET}\n`);
496
+ return lines.join('\n');
497
+ };
@@ -0,0 +1,109 @@
1
+ import * as t from '@babel/types';
2
+ import { RULE_REGISTRY } from './rules-registry.js';
3
+
4
+ export const countLogicalOperators = (node) => {
5
+ let count = 0;
6
+ if (t.isLogicalExpression(node)) {
7
+ count += 1;
8
+ count += countLogicalOperators(node.left);
9
+ count += countLogicalOperators(node.right);
10
+ } else if (t.isUnaryExpression(node) && node.operator === '!') {
11
+ count += 1;
12
+ count += countLogicalOperators(node.argument);
13
+ }
14
+ return count;
15
+ };
16
+
17
+ export const extractParseableCode = (content, ext) => {
18
+ if (ext === '.vue') {
19
+ const scriptMatch = content.match(/<script\b[^>]*>([\s\S]*?)<\/script>/i);
20
+ return scriptMatch ? scriptMatch[1] : '';
21
+ }
22
+ return content;
23
+ };
24
+
25
+ export const checkTypographyEmDash = (content, lines, relativePath, violations) => {
26
+ if (!content.includes('\u2014')) return;
27
+ lines.forEach((lineText, idx) => {
28
+ if (lineText.includes('\u2014')) {
29
+ const ruleMeta = RULE_REGISTRY.TYPOGRAPHY_EM_DASH;
30
+ violations.push({
31
+ filePath: relativePath,
32
+ line: idx + 1,
33
+ column: lineText.indexOf('\u2014') + 1,
34
+ hazard: 'Em dash detected in source code or copy',
35
+ rule: 'TYPOGRAPHY_EM_DASH',
36
+ severity: ruleMeta.severity,
37
+ pillar: ruleMeta.pillar,
38
+ directive: ruleMeta.directive
39
+ });
40
+ }
41
+ });
42
+ };
43
+
44
+ export const checkMockDataPatterns = (content, lines, relativePath, violations) => {
45
+ const mockEmailRegex = /['"][a-zA-Z0-9._%+-]+@(example\.com|test\.com|gmail\.com|foo\.bar)['"]/g;
46
+ const mockPhoneRegex = /['"]555-\d{3,4}['"]/g;
47
+
48
+ lines.forEach((lineText, idx) => {
49
+ const hasMockEmail = mockEmailRegex.test(lineText);
50
+ const hasMockPhone = mockPhoneRegex.test(lineText);
51
+ if (hasMockEmail || hasMockPhone) {
52
+ const ruleMeta = RULE_REGISTRY.SYNTHETIC_MOCK_DATA;
53
+ violations.push({
54
+ filePath: relativePath,
55
+ line: idx + 1,
56
+ column: 1,
57
+ hazard: 'Hardcoded synthetic mock data pattern detected',
58
+ rule: 'SYNTHETIC_MOCK_DATA',
59
+ severity: ruleMeta.severity,
60
+ pillar: ruleMeta.pillar,
61
+ directive: ruleMeta.directive
62
+ });
63
+ }
64
+ });
65
+ };
66
+
67
+ export const resolveMonolithTier = (lineCount) => {
68
+ if (lineCount >= 2000) {
69
+ return {
70
+ severity: 'CRITICAL',
71
+ hazard: `Extreme monolith hazard (${lineCount} >= 2,000 lines)`,
72
+ directive: 'Immediate decomposition required: extreme monolith induces severe agent context degradation'
73
+ };
74
+ }
75
+ if (lineCount >= 1000) {
76
+ return {
77
+ severity: 'HIGH',
78
+ hazard: `Severe monolith hazard (${lineCount} >= 1,000 lines)`,
79
+ directive: 'Decompose file into domain capsules and molecules to prevent context degradation'
80
+ };
81
+ }
82
+ return {
83
+ severity: 'MEDIUM',
84
+ hazard: `Monolith line budget warning (${lineCount} > 500 lines)`,
85
+ directive: 'Plan decomposition into focused modules before file grows further'
86
+ };
87
+ };
88
+
89
+ export const resolveMoleculeTier = (lineCount) => {
90
+ if (lineCount >= 500) {
91
+ return {
92
+ severity: 'CRITICAL',
93
+ hazard: `Extreme molecule monolith (${lineCount} >= 500 lines)`,
94
+ directive: 'Decompose molecule capsule into smaller sub-molecules or extract state to hooks'
95
+ };
96
+ }
97
+ if (lineCount >= 250) {
98
+ return {
99
+ severity: 'HIGH',
100
+ hazard: `Oversized molecule capsule (${lineCount} >= 250 lines)`,
101
+ directive: 'Decompose molecule capsule into smaller sub-molecules or extract state to hooks'
102
+ };
103
+ }
104
+ return {
105
+ severity: 'MEDIUM',
106
+ hazard: `Molecule capsule budget warning (${lineCount} > 100 lines)`,
107
+ directive: 'Split molecule into focused sub-molecules or extract state to hook'
108
+ };
109
+ };