@vibecheckai/cli 3.5.0 → 3.5.2

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 (224) hide show
  1. package/bin/registry.js +214 -237
  2. package/bin/runners/cli-utils.js +33 -2
  3. package/bin/runners/context/analyzer.js +52 -1
  4. package/bin/runners/context/generators/cursor.js +2 -49
  5. package/bin/runners/context/git-context.js +3 -1
  6. package/bin/runners/context/team-conventions.js +33 -7
  7. package/bin/runners/lib/analysis-core.js +25 -5
  8. package/bin/runners/lib/analyzers.js +431 -481
  9. package/bin/runners/lib/default-config.js +127 -0
  10. package/bin/runners/lib/doctor/modules/security.js +3 -1
  11. package/bin/runners/lib/engine/ast-cache.js +210 -0
  12. package/bin/runners/lib/engine/auth-extractor.js +211 -0
  13. package/bin/runners/lib/engine/billing-extractor.js +112 -0
  14. package/bin/runners/lib/engine/enforcement-extractor.js +100 -0
  15. package/bin/runners/lib/engine/env-extractor.js +207 -0
  16. package/bin/runners/lib/engine/express-extractor.js +208 -0
  17. package/bin/runners/lib/engine/extractors.js +849 -0
  18. package/bin/runners/lib/engine/index.js +207 -0
  19. package/bin/runners/lib/engine/repo-index.js +514 -0
  20. package/bin/runners/lib/engine/types.js +124 -0
  21. package/bin/runners/lib/engines/accessibility-engine.js +18 -218
  22. package/bin/runners/lib/engines/api-consistency-engine.js +30 -335
  23. package/bin/runners/lib/engines/cross-file-analysis-engine.js +27 -292
  24. package/bin/runners/lib/engines/empty-catch-engine.js +17 -127
  25. package/bin/runners/lib/engines/mock-data-engine.js +10 -53
  26. package/bin/runners/lib/engines/performance-issues-engine.js +36 -176
  27. package/bin/runners/lib/engines/security-vulnerabilities-engine.js +54 -382
  28. package/bin/runners/lib/engines/type-aware-engine.js +39 -263
  29. package/bin/runners/lib/engines/vibecheck-engines/index.js +13 -122
  30. package/bin/runners/lib/engines/vibecheck-engines/lib/ast-cache.js +164 -0
  31. package/bin/runners/lib/engines/vibecheck-engines/lib/code-quality-engine.js +291 -0
  32. package/bin/runners/lib/engines/vibecheck-engines/lib/console-logs-engine.js +83 -0
  33. package/bin/runners/lib/engines/vibecheck-engines/lib/dead-code-engine.js +198 -0
  34. package/bin/runners/lib/engines/vibecheck-engines/lib/deprecated-api-engine.js +275 -0
  35. package/bin/runners/lib/engines/vibecheck-engines/lib/empty-catch-engine.js +167 -0
  36. package/bin/runners/lib/engines/vibecheck-engines/lib/file-filter.js +217 -0
  37. package/bin/runners/lib/engines/vibecheck-engines/lib/hardcoded-secrets-engine.js +73 -373
  38. package/bin/runners/lib/engines/vibecheck-engines/lib/mock-data-engine.js +140 -0
  39. package/bin/runners/lib/engines/vibecheck-engines/lib/parallel-processor.js +164 -0
  40. package/bin/runners/lib/engines/vibecheck-engines/lib/performance-issues-engine.js +234 -0
  41. package/bin/runners/lib/engines/vibecheck-engines/lib/type-aware-engine.js +217 -0
  42. package/bin/runners/lib/engines/vibecheck-engines/lib/unsafe-regex-engine.js +78 -0
  43. package/bin/runners/lib/entitlements-v2.js +73 -97
  44. package/bin/runners/lib/error-handler.js +44 -3
  45. package/bin/runners/lib/error-messages.js +289 -0
  46. package/bin/runners/lib/evidence-pack.js +7 -1
  47. package/bin/runners/lib/finding-id.js +69 -0
  48. package/bin/runners/lib/finding-sorter.js +89 -0
  49. package/bin/runners/lib/html-proof-report.js +700 -350
  50. package/bin/runners/lib/missions/plan.js +6 -46
  51. package/bin/runners/lib/missions/templates.js +0 -232
  52. package/bin/runners/lib/next-action.js +560 -0
  53. package/bin/runners/lib/prerequisites.js +149 -0
  54. package/bin/runners/lib/route-detection.js +137 -68
  55. package/bin/runners/lib/scan-output.js +91 -76
  56. package/bin/runners/lib/scan-runner.js +135 -0
  57. package/bin/runners/lib/schemas/ajv-validator.js +464 -0
  58. package/bin/runners/lib/schemas/error-envelope.schema.json +105 -0
  59. package/bin/runners/lib/schemas/finding-v3.schema.json +151 -0
  60. package/bin/runners/lib/schemas/report-artifact.schema.json +120 -0
  61. package/bin/runners/lib/schemas/run-request.schema.json +108 -0
  62. package/bin/runners/lib/schemas/validator.js +27 -0
  63. package/bin/runners/lib/schemas/verdict.schema.json +140 -0
  64. package/bin/runners/lib/ship-output-enterprise.js +23 -23
  65. package/bin/runners/lib/ship-output.js +75 -31
  66. package/bin/runners/lib/terminal-ui.js +6 -113
  67. package/bin/runners/lib/truth.js +351 -10
  68. package/bin/runners/lib/unified-cli-output.js +430 -603
  69. package/bin/runners/lib/unified-output.js +13 -9
  70. package/bin/runners/runAIAgent.js +10 -5
  71. package/bin/runners/runAgent.js +0 -3
  72. package/bin/runners/runAllowlist.js +389 -0
  73. package/bin/runners/runApprove.js +0 -33
  74. package/bin/runners/runAuth.js +73 -45
  75. package/bin/runners/runCheckpoint.js +51 -11
  76. package/bin/runners/runClassify.js +85 -21
  77. package/bin/runners/runContext.js +0 -3
  78. package/bin/runners/runDoctor.js +41 -28
  79. package/bin/runners/runEvidencePack.js +362 -0
  80. package/bin/runners/runFirewall.js +0 -3
  81. package/bin/runners/runFirewallHook.js +0 -3
  82. package/bin/runners/runFix.js +66 -76
  83. package/bin/runners/runGuard.js +18 -411
  84. package/bin/runners/runInit.js +113 -30
  85. package/bin/runners/runLabs.js +424 -0
  86. package/bin/runners/runMcp.js +19 -25
  87. package/bin/runners/runPolish.js +64 -240
  88. package/bin/runners/runPromptFirewall.js +12 -5
  89. package/bin/runners/runProve.js +57 -22
  90. package/bin/runners/runQuickstart.js +531 -0
  91. package/bin/runners/runReality.js +59 -68
  92. package/bin/runners/runReport.js +38 -33
  93. package/bin/runners/runRuntime.js +8 -5
  94. package/bin/runners/runScan.js +1413 -190
  95. package/bin/runners/runShip.js +113 -719
  96. package/bin/runners/runTruth.js +0 -3
  97. package/bin/runners/runValidate.js +13 -9
  98. package/bin/runners/runWatch.js +23 -14
  99. package/bin/scan.js +6 -1
  100. package/bin/vibecheck.js +204 -185
  101. package/mcp-server/deprecation-middleware.js +282 -0
  102. package/mcp-server/handlers/index.ts +15 -0
  103. package/mcp-server/handlers/tool-handler.ts +554 -0
  104. package/mcp-server/index-v1.js +698 -0
  105. package/mcp-server/index.js +210 -238
  106. package/mcp-server/lib/cache-wrapper.cjs +383 -0
  107. package/mcp-server/lib/error-envelope.js +138 -0
  108. package/mcp-server/lib/executor.ts +499 -0
  109. package/mcp-server/lib/index.ts +19 -0
  110. package/mcp-server/lib/rate-limiter.js +166 -0
  111. package/mcp-server/lib/sandbox.test.ts +519 -0
  112. package/mcp-server/lib/sandbox.ts +395 -0
  113. package/mcp-server/lib/types.ts +267 -0
  114. package/mcp-server/package.json +12 -3
  115. package/mcp-server/registry/tool-registry.js +794 -0
  116. package/mcp-server/registry/tools.json +605 -0
  117. package/mcp-server/registry.test.ts +334 -0
  118. package/mcp-server/tests/tier-gating.test.js +297 -0
  119. package/mcp-server/tier-auth.js +378 -45
  120. package/mcp-server/tools-v3.js +353 -442
  121. package/mcp-server/tsconfig.json +37 -0
  122. package/mcp-server/vibecheck-2.0-tools.js +14 -1
  123. package/package.json +1 -1
  124. package/bin/runners/lib/agent-firewall/learning/learning-engine.js +0 -849
  125. package/bin/runners/lib/audit-logger.js +0 -532
  126. package/bin/runners/lib/authority/authorities/architecture.js +0 -364
  127. package/bin/runners/lib/authority/authorities/compliance.js +0 -341
  128. package/bin/runners/lib/authority/authorities/human.js +0 -343
  129. package/bin/runners/lib/authority/authorities/quality.js +0 -420
  130. package/bin/runners/lib/authority/authorities/security.js +0 -228
  131. package/bin/runners/lib/authority/index.js +0 -293
  132. package/bin/runners/lib/bundle/bundle-intelligence.js +0 -846
  133. package/bin/runners/lib/cli-charts.js +0 -368
  134. package/bin/runners/lib/cli-config-display.js +0 -405
  135. package/bin/runners/lib/cli-demo.js +0 -275
  136. package/bin/runners/lib/cli-errors.js +0 -438
  137. package/bin/runners/lib/cli-help-formatter.js +0 -439
  138. package/bin/runners/lib/cli-interactive-menu.js +0 -509
  139. package/bin/runners/lib/cli-prompts.js +0 -441
  140. package/bin/runners/lib/cli-scan-cards.js +0 -362
  141. package/bin/runners/lib/compliance-reporter.js +0 -710
  142. package/bin/runners/lib/conductor/index.js +0 -671
  143. package/bin/runners/lib/easy/README.md +0 -123
  144. package/bin/runners/lib/easy/index.js +0 -140
  145. package/bin/runners/lib/easy/interactive-wizard.js +0 -788
  146. package/bin/runners/lib/easy/one-click-firewall.js +0 -564
  147. package/bin/runners/lib/easy/zero-config-reality.js +0 -714
  148. package/bin/runners/lib/engines/async-patterns-engine.js +0 -444
  149. package/bin/runners/lib/engines/bundle-size-engine.js +0 -433
  150. package/bin/runners/lib/engines/confidence-scoring.js +0 -276
  151. package/bin/runners/lib/engines/context-detection.js +0 -264
  152. package/bin/runners/lib/engines/database-patterns-engine.js +0 -429
  153. package/bin/runners/lib/engines/duplicate-code-engine.js +0 -354
  154. package/bin/runners/lib/engines/env-variables-engine.js +0 -458
  155. package/bin/runners/lib/engines/error-handling-engine.js +0 -437
  156. package/bin/runners/lib/engines/false-positive-prevention.js +0 -630
  157. package/bin/runners/lib/engines/framework-adapters/index.js +0 -607
  158. package/bin/runners/lib/engines/framework-detection.js +0 -508
  159. package/bin/runners/lib/engines/import-order-engine.js +0 -429
  160. package/bin/runners/lib/engines/naming-conventions-engine.js +0 -544
  161. package/bin/runners/lib/engines/noise-reduction-engine.js +0 -452
  162. package/bin/runners/lib/engines/orchestrator.js +0 -334
  163. package/bin/runners/lib/engines/react-patterns-engine.js +0 -457
  164. package/bin/runners/lib/engines/vibecheck-engines/lib/ai-hallucination-engine.js +0 -806
  165. package/bin/runners/lib/engines/vibecheck-engines/lib/smart-fix-engine.js +0 -577
  166. package/bin/runners/lib/engines/vibecheck-engines/lib/vibe-score-engine.js +0 -543
  167. package/bin/runners/lib/engines/vibecheck-engines.js +0 -514
  168. package/bin/runners/lib/enhanced-features/index.js +0 -305
  169. package/bin/runners/lib/enhanced-output.js +0 -631
  170. package/bin/runners/lib/enterprise.js +0 -300
  171. package/bin/runners/lib/firewall/command-validator.js +0 -351
  172. package/bin/runners/lib/firewall/config.js +0 -341
  173. package/bin/runners/lib/firewall/content-validator.js +0 -519
  174. package/bin/runners/lib/firewall/index.js +0 -101
  175. package/bin/runners/lib/firewall/path-validator.js +0 -256
  176. package/bin/runners/lib/intelligence/cross-repo-intelligence.js +0 -817
  177. package/bin/runners/lib/mcp-utils.js +0 -425
  178. package/bin/runners/lib/output/index.js +0 -1022
  179. package/bin/runners/lib/policy-engine.js +0 -652
  180. package/bin/runners/lib/polish/autofix/accessibility-fixes.js +0 -333
  181. package/bin/runners/lib/polish/autofix/async-handlers.js +0 -273
  182. package/bin/runners/lib/polish/autofix/dead-code.js +0 -280
  183. package/bin/runners/lib/polish/autofix/imports-optimizer.js +0 -344
  184. package/bin/runners/lib/polish/autofix/index.js +0 -200
  185. package/bin/runners/lib/polish/autofix/remove-consoles.js +0 -209
  186. package/bin/runners/lib/polish/autofix/strengthen-types.js +0 -245
  187. package/bin/runners/lib/polish/backend-checks.js +0 -148
  188. package/bin/runners/lib/polish/documentation-checks.js +0 -111
  189. package/bin/runners/lib/polish/frontend-checks.js +0 -168
  190. package/bin/runners/lib/polish/index.js +0 -71
  191. package/bin/runners/lib/polish/infrastructure-checks.js +0 -131
  192. package/bin/runners/lib/polish/library-detection.js +0 -175
  193. package/bin/runners/lib/polish/performance-checks.js +0 -100
  194. package/bin/runners/lib/polish/security-checks.js +0 -148
  195. package/bin/runners/lib/polish/utils.js +0 -203
  196. package/bin/runners/lib/prompt-builder.js +0 -540
  197. package/bin/runners/lib/proof-certificate.js +0 -634
  198. package/bin/runners/lib/reality/accessibility-audit.js +0 -946
  199. package/bin/runners/lib/reality/api-contract-validator.js +0 -1012
  200. package/bin/runners/lib/reality/chaos-engineering.js +0 -1084
  201. package/bin/runners/lib/reality/performance-tracker.js +0 -1077
  202. package/bin/runners/lib/reality/scenario-generator.js +0 -1404
  203. package/bin/runners/lib/reality/visual-regression.js +0 -852
  204. package/bin/runners/lib/reality-profiler.js +0 -717
  205. package/bin/runners/lib/replay/flight-recorder-viewer.js +0 -1160
  206. package/bin/runners/lib/review/ai-code-review.js +0 -832
  207. package/bin/runners/lib/rules/custom-rule-engine.js +0 -985
  208. package/bin/runners/lib/sbom-generator.js +0 -641
  209. package/bin/runners/lib/scan-output-enhanced.js +0 -512
  210. package/bin/runners/lib/security/owasp-scanner.js +0 -939
  211. package/bin/runners/lib/validators/contract-validator.js +0 -283
  212. package/bin/runners/lib/validators/dead-export-detector.js +0 -279
  213. package/bin/runners/lib/validators/dep-audit.js +0 -245
  214. package/bin/runners/lib/validators/env-validator.js +0 -319
  215. package/bin/runners/lib/validators/index.js +0 -120
  216. package/bin/runners/lib/validators/license-checker.js +0 -252
  217. package/bin/runners/lib/validators/route-validator.js +0 -290
  218. package/bin/runners/runAuthority.js +0 -528
  219. package/bin/runners/runConductor.js +0 -772
  220. package/bin/runners/runContainer.js +0 -366
  221. package/bin/runners/runEasy.js +0 -410
  222. package/bin/runners/runIaC.js +0 -372
  223. package/bin/runners/runVibe.js +0 -791
  224. package/mcp-server/tools.js +0 -495
@@ -1,514 +0,0 @@
1
- /**
2
- * Vibecheck Engines - Main Analysis Module
3
- *
4
- * Combines all analysis engines into a unified vibe score calculation.
5
- * This is the brain behind the `vibecheck vibe` command.
6
- */
7
-
8
- "use strict";
9
-
10
- const fs = require("fs");
11
- const path = require("path");
12
-
13
- // Import individual engines with graceful fallbacks
14
- let emptyCatchEngine, mockDataEngine, hardcodedSecretsEngine, consoleLogsEngine;
15
- let codeQualityEngine, securityEngine, deadCodeEngine;
16
-
17
- try {
18
- emptyCatchEngine = require("./empty-catch-engine");
19
- } catch { emptyCatchEngine = null; }
20
-
21
- try {
22
- mockDataEngine = require("./mock-data-engine");
23
- } catch { mockDataEngine = null; }
24
-
25
- try {
26
- hardcodedSecretsEngine = require("./hardcoded-secrets-engine");
27
- } catch { hardcodedSecretsEngine = null; }
28
-
29
- try {
30
- consoleLogsEngine = require("./console-logs-engine");
31
- } catch { consoleLogsEngine = null; }
32
-
33
- try {
34
- codeQualityEngine = require("./code-quality-engine");
35
- } catch { codeQualityEngine = null; }
36
-
37
- try {
38
- securityEngine = require("./security-vulnerabilities-engine");
39
- } catch { securityEngine = null; }
40
-
41
- try {
42
- deadCodeEngine = require("./dead-code-engine");
43
- } catch { deadCodeEngine = null; }
44
-
45
- // ═══════════════════════════════════════════════════════════════════════════════
46
- // AI HALLUCINATION DETECTION
47
- // ═══════════════════════════════════════════════════════════════════════════════
48
-
49
- /**
50
- * Patterns that indicate AI-generated code that may not work as expected
51
- */
52
- const AI_HALLUCINATION_PATTERNS = [
53
- // Fake success returns
54
- {
55
- pattern: /return\s+{\s*success:\s*true\s*}/g,
56
- title: "Fake Success Return",
57
- description: "Returns success without doing actual work",
58
- severity: "WARN",
59
- category: "AIHallucination",
60
- },
61
- {
62
- pattern: /return\s+{\s*ok:\s*true\s*}/g,
63
- title: "Fake OK Return",
64
- description: "Returns OK without validation",
65
- severity: "WARN",
66
- category: "AIHallucination",
67
- },
68
- // Stub implementations
69
- {
70
- pattern: /TODO|FIXME|HACK|XXX|STUB/gi,
71
- title: "Incomplete Implementation",
72
- description: "Code contains TODO/FIXME markers indicating unfinished work",
73
- severity: "INFO",
74
- category: "AIHallucination",
75
- },
76
- // Placeholder implementations
77
- {
78
- pattern: /throw\s+new\s+Error\s*\(\s*['"]not\s+implemented['"]\s*\)/gi,
79
- title: "Not Implemented",
80
- description: "Function throws 'not implemented' error",
81
- severity: "BLOCK",
82
- category: "AIHallucination",
83
- },
84
- // Fake data patterns
85
- {
86
- pattern: /['"]example\.com['"]/gi,
87
- title: "Placeholder URL",
88
- description: "Using example.com placeholder URL",
89
- severity: "WARN",
90
- category: "AIHallucination",
91
- },
92
- {
93
- pattern: /['"]test@test\.com['"]/gi,
94
- title: "Test Email",
95
- description: "Using test email in non-test code",
96
- severity: "WARN",
97
- category: "AIHallucination",
98
- },
99
- {
100
- pattern: /['"]lorem\s+ipsum['"]/gi,
101
- title: "Lorem Ipsum",
102
- description: "Placeholder text found in code",
103
- severity: "INFO",
104
- category: "AIHallucination",
105
- },
106
- // Mock implementations
107
- {
108
- pattern: /\/\/\s*mock|\/\/\s*fake|\/\/\s*stub|\/\/\s*placeholder/gi,
109
- title: "Marked as Mock",
110
- description: "Code is explicitly marked as mock/fake/stub",
111
- severity: "WARN",
112
- category: "AIHallucination",
113
- },
114
- // Optimistic error handling
115
- {
116
- pattern: /catch\s*\([^)]*\)\s*{\s*\/\/\s*ignore|catch\s*\([^)]*\)\s*{\s*}/g,
117
- title: "Swallowed Error",
118
- description: "Error is caught but ignored",
119
- severity: "WARN",
120
- category: "AIHallucination",
121
- },
122
- // Fake database queries
123
- {
124
- pattern: /return\s+\[\s*{\s*id:\s*1/g,
125
- title: "Hardcoded Data",
126
- description: "Returns hardcoded array instead of database query",
127
- severity: "WARN",
128
- category: "AIHallucination",
129
- },
130
- ];
131
-
132
- /**
133
- * Analyze code for AI hallucination patterns
134
- */
135
- function analyzeAIHallucinations(content, filePath, options = {}) {
136
- const findings = [];
137
- const lines = content.split('\n');
138
- const fileName = path.basename(filePath);
139
-
140
- // Skip test files unless explicitly included
141
- if (!options.includeTests) {
142
- if (fileName.includes('.test.') || fileName.includes('.spec.') ||
143
- fileName.includes('__tests__') || filePath.includes('/test/') ||
144
- filePath.includes('\\test\\')) {
145
- return findings;
146
- }
147
- }
148
-
149
- for (const patternDef of AI_HALLUCINATION_PATTERNS) {
150
- const matches = content.matchAll(patternDef.pattern);
151
-
152
- for (const match of matches) {
153
- const matchIndex = match.index;
154
- let lineNumber = 1;
155
- let charCount = 0;
156
-
157
- for (let i = 0; i < lines.length; i++) {
158
- charCount += lines[i].length + 1;
159
- if (charCount > matchIndex) {
160
- lineNumber = i + 1;
161
- break;
162
- }
163
- }
164
-
165
- findings.push({
166
- title: patternDef.title,
167
- message: patternDef.description,
168
- severity: patternDef.severity,
169
- category: patternDef.category,
170
- file: filePath,
171
- line: lineNumber,
172
- evidence: [{
173
- file: filePath,
174
- lines: `${lineNumber}`,
175
- snippet: match[0].substring(0, 50),
176
- }],
177
- fixHints: getFixHint(patternDef.title),
178
- });
179
- }
180
- }
181
-
182
- return findings;
183
- }
184
-
185
- function getFixHint(title) {
186
- const hints = {
187
- "Fake Success Return": ["Implement actual success validation logic"],
188
- "Fake OK Return": ["Add proper validation before returning OK"],
189
- "Incomplete Implementation": ["Complete the TODO item or remove if not needed"],
190
- "Not Implemented": ["Implement the function or remove if not used"],
191
- "Placeholder URL": ["Replace with actual production URL"],
192
- "Test Email": ["Use environment variable for email configuration"],
193
- "Lorem Ipsum": ["Replace with actual content"],
194
- "Marked as Mock": ["Replace mock implementation with real code"],
195
- "Swallowed Error": ["Handle the error appropriately or log it"],
196
- "Hardcoded Data": ["Replace with actual database query"],
197
- };
198
- return hints[title] || ["Review and fix this issue"];
199
- }
200
-
201
- // ═══════════════════════════════════════════════════════════════════════════════
202
- // ENGINE WRAPPERS
203
- // ═══════════════════════════════════════════════════════════════════════════════
204
-
205
- function analyzeEmptyCatch(content, filePath) {
206
- if (!emptyCatchEngine || !emptyCatchEngine.analyze) return [];
207
- try {
208
- return emptyCatchEngine.analyze(content, filePath);
209
- } catch {
210
- return [];
211
- }
212
- }
213
-
214
- function analyzeMockData(content, filePath) {
215
- if (!mockDataEngine || !mockDataEngine.analyze) return [];
216
- try {
217
- return mockDataEngine.analyze(content, filePath);
218
- } catch {
219
- return [];
220
- }
221
- }
222
-
223
- function analyzeHardcodedSecrets(content, filePath) {
224
- if (!hardcodedSecretsEngine || !hardcodedSecretsEngine.analyze) return [];
225
- try {
226
- return hardcodedSecretsEngine.analyze(content, filePath);
227
- } catch {
228
- return [];
229
- }
230
- }
231
-
232
- function analyzeConsoleLogs(content, filePath) {
233
- if (!consoleLogsEngine || !consoleLogsEngine.analyze) return [];
234
- try {
235
- return consoleLogsEngine.analyze(content, filePath);
236
- } catch {
237
- return [];
238
- }
239
- }
240
-
241
- // ═══════════════════════════════════════════════════════════════════════════════
242
- // VIBE SCORE CALCULATION
243
- // ═══════════════════════════════════════════════════════════════════════════════
244
-
245
- /**
246
- * Calculate comprehensive vibe score from findings
247
- */
248
- function calculateVibeScore(findings, meta = {}) {
249
- const { filesAnalyzed = 0, linesOfCode = 0 } = meta;
250
-
251
- // Count by severity
252
- const blockers = findings.filter(f => f.severity === 'BLOCK' || f.severity === 'critical').length;
253
- const warnings = findings.filter(f => f.severity === 'WARN' || f.severity === 'warning').length;
254
- const info = findings.filter(f => f.severity === 'INFO' || f.severity === 'info').length;
255
-
256
- // Count by category
257
- const byCategory = {};
258
- for (const f of findings) {
259
- const cat = f.category || 'Other';
260
- byCategory[cat] = (byCategory[cat] || 0) + 1;
261
- }
262
-
263
- // Calculate base score
264
- let score = 100;
265
- score -= blockers * 15;
266
- score -= warnings * 5;
267
- score -= info * 1;
268
- score = Math.max(0, Math.min(100, score));
269
-
270
- // Calculate component scores
271
- const components = {
272
- implementationCompleteness: calculateComponentScore(findings, ['AIHallucination', 'Incomplete']),
273
- errorHandling: calculateComponentScore(findings, ['EmptyCatch', 'SwallowedError']),
274
- apiDataIntegrity: calculateComponentScore(findings, ['MockData', 'PlaceholderURL', 'FakeData']),
275
- codeQuality: calculateComponentScore(findings, ['ConsoleLog', 'DeadCode', 'CodeQuality']),
276
- securityPosture: calculateComponentScore(findings, ['HardcodedSecret', 'Security']),
277
- };
278
-
279
- // Calculate grade
280
- let grade, label, emoji;
281
- if (score >= 90) {
282
- grade = 'A'; label = 'Ship Ready'; emoji = '🚀';
283
- } else if (score >= 80) {
284
- grade = 'B'; label = 'Almost There'; emoji = '✨';
285
- } else if (score >= 70) {
286
- grade = 'C'; label = 'Needs Polish'; emoji = '🔧';
287
- } else if (score >= 50) {
288
- grade = 'D'; label = 'Work Required'; emoji = '⚠️';
289
- } else {
290
- grade = 'F'; label = 'Not Ready'; emoji = '🚫';
291
- }
292
-
293
- // Calculate risk level
294
- let riskLevel;
295
- if (blockers === 0 && warnings <= 2) {
296
- riskLevel = 'minimal';
297
- } else if (blockers <= 1 && warnings <= 5) {
298
- riskLevel = 'low';
299
- } else if (blockers <= 3 && warnings <= 10) {
300
- riskLevel = 'medium';
301
- } else if (blockers <= 5) {
302
- riskLevel = 'high';
303
- } else {
304
- riskLevel = 'critical';
305
- }
306
-
307
- // Generate insights
308
- const insights = generateInsights(findings, byCategory, score);
309
-
310
- // Calculate risk metrics
311
- const risk = calculateRiskMetrics(findings, filesAnalyzed, linesOfCode);
312
-
313
- return {
314
- score,
315
- grade,
316
- label,
317
- emoji,
318
- riskLevel,
319
- components,
320
- insights,
321
- risk,
322
- summary: {
323
- blockers,
324
- warnings,
325
- info,
326
- total: findings.length,
327
- },
328
- findings,
329
- meta: {
330
- filesAnalyzed,
331
- linesOfCode,
332
- analyzedAt: new Date().toISOString(),
333
- },
334
- };
335
- }
336
-
337
- function calculateComponentScore(findings, categories) {
338
- const relevant = findings.filter(f => categories.some(c =>
339
- (f.category || '').toLowerCase().includes(c.toLowerCase())
340
- ));
341
-
342
- const blockers = relevant.filter(f => f.severity === 'BLOCK').length;
343
- const warnings = relevant.filter(f => f.severity === 'WARN').length;
344
-
345
- let score = 100;
346
- score -= blockers * 20;
347
- score -= warnings * 8;
348
- score = Math.max(0, Math.min(100, score));
349
-
350
- let status;
351
- if (score >= 90) status = 'excellent';
352
- else if (score >= 70) status = 'good';
353
- else if (score >= 50) status = 'needs-work';
354
- else status = 'critical';
355
-
356
- return {
357
- score,
358
- status,
359
- issueCount: relevant.length,
360
- };
361
- }
362
-
363
- function generateInsights(findings, byCategory, score) {
364
- const insights = [];
365
-
366
- // Category-based insights
367
- if (byCategory.AIHallucination > 0) {
368
- insights.push({
369
- type: 'pattern',
370
- title: 'AI Hallucination Patterns Detected',
371
- message: `Found ${byCategory.AIHallucination} potential AI-generated code issues`,
372
- action: 'Review code marked as fake/mock/stub and implement real logic',
373
- });
374
- }
375
-
376
- if (byCategory.EmptyCatch > 0) {
377
- insights.push({
378
- type: 'critical',
379
- title: 'Silent Error Handling',
380
- message: `${byCategory.EmptyCatch} errors are being silently swallowed`,
381
- action: 'Add proper error logging or handling to catch blocks',
382
- });
383
- }
384
-
385
- if (byCategory.HardcodedSecret > 0) {
386
- insights.push({
387
- type: 'critical',
388
- title: 'Security Risk: Hardcoded Secrets',
389
- message: `Found ${byCategory.HardcodedSecret} hardcoded credentials`,
390
- action: 'Move secrets to environment variables immediately',
391
- });
392
- }
393
-
394
- if (byCategory.MockData > 0) {
395
- insights.push({
396
- type: 'pattern',
397
- title: 'Mock Data in Production Code',
398
- message: `Found ${byCategory.MockData} mock data patterns`,
399
- action: 'Replace mock data with real API calls or database queries',
400
- });
401
- }
402
-
403
- if (score >= 90) {
404
- insights.push({
405
- type: 'positive',
406
- title: 'Excellent Code Quality',
407
- message: 'Your codebase shows strong production readiness',
408
- action: 'Run vibecheck ship to generate your ship badge',
409
- });
410
- }
411
-
412
- return insights;
413
- }
414
-
415
- function calculateRiskMetrics(findings, filesAnalyzed, linesOfCode) {
416
- const blockers = findings.filter(f => f.severity === 'BLOCK').length;
417
- const securityIssues = findings.filter(f =>
418
- (f.category || '').toLowerCase().includes('secret') ||
419
- (f.category || '').toLowerCase().includes('security')
420
- ).length;
421
-
422
- // Technical debt hours (rough estimate)
423
- let debtHours = 0;
424
- for (const f of findings) {
425
- if (f.severity === 'BLOCK') debtHours += 2;
426
- else if (f.severity === 'WARN') debtHours += 0.5;
427
- else debtHours += 0.1;
428
- }
429
- debtHours = Math.round(debtHours * 10) / 10;
430
-
431
- let technicalDebtLabel;
432
- if (debtHours < 4) technicalDebtLabel = 'low';
433
- else if (debtHours < 16) technicalDebtLabel = 'medium';
434
- else technicalDebtLabel = 'high';
435
-
436
- // Security risk
437
- let securityRiskLevel;
438
- if (securityIssues === 0) securityRiskLevel = 'normal';
439
- else if (securityIssues <= 2) securityRiskLevel = 'elevated';
440
- else securityRiskLevel = 'critical';
441
-
442
- // Reliability risk
443
- const errorHandlingIssues = findings.filter(f =>
444
- (f.category || '').toLowerCase().includes('catch') ||
445
- (f.category || '').toLowerCase().includes('error')
446
- ).length;
447
-
448
- let reliabilityRiskLevel;
449
- if (errorHandlingIssues === 0) reliabilityRiskLevel = 'low';
450
- else if (errorHandlingIssues <= 3) reliabilityRiskLevel = 'medium';
451
- else reliabilityRiskLevel = 'high';
452
-
453
- // Deployment risk
454
- let deploymentRisk;
455
- if (blockers === 0 && securityIssues === 0) deploymentRisk = 'acceptable';
456
- else if (blockers <= 2 && securityIssues <= 1) deploymentRisk = 'medium-risk';
457
- else deploymentRisk = 'high-risk';
458
-
459
- return {
460
- technicalDebtHours: debtHours,
461
- technicalDebtLabel,
462
- securityRiskLevel,
463
- reliabilityRiskLevel,
464
- deploymentRisk,
465
- };
466
- }
467
-
468
- // ═══════════════════════════════════════════════════════════════════════════════
469
- // JSON REPORT GENERATOR
470
- // ═══════════════════════════════════════════════════════════════════════════════
471
-
472
- function generateVibeReportJSON(vibeScore) {
473
- return {
474
- vibeScore: {
475
- score: vibeScore.score,
476
- grade: vibeScore.grade,
477
- label: vibeScore.label,
478
- riskLevel: vibeScore.riskLevel,
479
- },
480
- components: vibeScore.components,
481
- insights: vibeScore.insights,
482
- risk: vibeScore.risk,
483
- summary: vibeScore.summary,
484
- findings: vibeScore.findings.map(f => ({
485
- title: f.title,
486
- message: f.message,
487
- severity: f.severity,
488
- category: f.category,
489
- file: f.file,
490
- line: f.line,
491
- })),
492
- meta: vibeScore.meta,
493
- };
494
- }
495
-
496
- // ═══════════════════════════════════════════════════════════════════════════════
497
- // EXPORTS
498
- // ═══════════════════════════════════════════════════════════════════════════════
499
-
500
- module.exports = {
501
- // Main analysis functions
502
- analyzeAIHallucinations,
503
- analyzeEmptyCatch,
504
- analyzeMockData,
505
- analyzeHardcodedSecrets,
506
- analyzeConsoleLogs,
507
-
508
- // Score calculation
509
- calculateVibeScore,
510
- generateVibeReportJSON,
511
-
512
- // Utilities
513
- AI_HALLUCINATION_PATTERNS,
514
- };