@vibecheckai/cli 3.4.0 → 3.5.1

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 (228) hide show
  1. package/bin/registry.js +154 -338
  2. package/bin/runners/context/generators/mcp.js +13 -15
  3. package/bin/runners/context/proof-context.js +1 -248
  4. package/bin/runners/lib/analysis-core.js +180 -198
  5. package/bin/runners/lib/analyzers.js +223 -1669
  6. package/bin/runners/lib/cli-output.js +210 -242
  7. package/bin/runners/lib/detectors-v2.js +785 -547
  8. package/bin/runners/lib/entitlements-v2.js +458 -96
  9. package/bin/runners/lib/error-handler.js +9 -16
  10. package/bin/runners/lib/global-flags.js +0 -37
  11. package/bin/runners/lib/route-truth.js +322 -1167
  12. package/bin/runners/lib/scan-output.js +469 -448
  13. package/bin/runners/lib/ship-output.js +27 -280
  14. package/bin/runners/lib/terminal-ui.js +733 -231
  15. package/bin/runners/lib/truth.js +321 -1004
  16. package/bin/runners/lib/unified-output.js +158 -162
  17. package/bin/runners/lib/upsell.js +204 -104
  18. package/bin/runners/runAllowlist.js +324 -0
  19. package/bin/runners/runAuth.js +95 -324
  20. package/bin/runners/runCheckpoint.js +21 -39
  21. package/bin/runners/runContext.js +24 -136
  22. package/bin/runners/runDoctor.js +67 -115
  23. package/bin/runners/runEvidencePack.js +219 -0
  24. package/bin/runners/runFix.js +5 -6
  25. package/bin/runners/runGuard.js +118 -212
  26. package/bin/runners/runInit.js +2 -14
  27. package/bin/runners/runInstall.js +281 -0
  28. package/bin/runners/runLabs.js +341 -0
  29. package/bin/runners/runMcp.js +52 -130
  30. package/bin/runners/runPolish.js +20 -43
  31. package/bin/runners/runProve.js +3 -13
  32. package/bin/runners/runReality.js +0 -14
  33. package/bin/runners/runReport.js +2 -3
  34. package/bin/runners/runScan.js +44 -511
  35. package/bin/runners/runShip.js +14 -28
  36. package/bin/runners/runValidate.js +2 -19
  37. package/bin/runners/runWatch.js +54 -118
  38. package/bin/vibecheck.js +41 -148
  39. package/mcp-server/ARCHITECTURE.md +339 -0
  40. package/mcp-server/__tests__/cache.test.ts +313 -0
  41. package/mcp-server/__tests__/executor.test.ts +239 -0
  42. package/mcp-server/__tests__/fixtures/exclusion-test/.cache/webpack/cache.pack +1 -0
  43. package/mcp-server/__tests__/fixtures/exclusion-test/.next/server/chunk.js +3 -0
  44. package/mcp-server/__tests__/fixtures/exclusion-test/.turbo/cache.json +3 -0
  45. package/mcp-server/__tests__/fixtures/exclusion-test/.venv/lib/env.py +3 -0
  46. package/mcp-server/__tests__/fixtures/exclusion-test/dist/bundle.js +3 -0
  47. package/mcp-server/__tests__/fixtures/exclusion-test/package.json +5 -0
  48. package/mcp-server/__tests__/fixtures/exclusion-test/src/app.ts +5 -0
  49. package/mcp-server/__tests__/fixtures/exclusion-test/venv/lib/config.py +4 -0
  50. package/mcp-server/__tests__/ids.test.ts +345 -0
  51. package/mcp-server/__tests__/integration/tools.test.ts +410 -0
  52. package/mcp-server/__tests__/registry.test.ts +365 -0
  53. package/mcp-server/__tests__/sandbox.test.ts +323 -0
  54. package/mcp-server/__tests__/schemas.test.ts +372 -0
  55. package/mcp-server/benchmarks/run-benchmarks.ts +304 -0
  56. package/mcp-server/examples/doctor.request.json +14 -0
  57. package/mcp-server/examples/doctor.response.json +53 -0
  58. package/mcp-server/examples/error.response.json +15 -0
  59. package/mcp-server/examples/scan.request.json +14 -0
  60. package/mcp-server/examples/scan.response.json +108 -0
  61. package/mcp-server/handlers/tool-handler.ts +671 -0
  62. package/mcp-server/index-v3.ts +293 -0
  63. package/mcp-server/index.js +1072 -1573
  64. package/mcp-server/index.old.js +4137 -0
  65. package/mcp-server/lib/cache.ts +341 -0
  66. package/mcp-server/lib/errors.ts +346 -0
  67. package/mcp-server/lib/executor.ts +792 -0
  68. package/mcp-server/lib/ids.ts +238 -0
  69. package/mcp-server/lib/logger.ts +368 -0
  70. package/mcp-server/lib/metrics.ts +365 -0
  71. package/mcp-server/lib/sandbox.ts +337 -0
  72. package/mcp-server/lib/validator.ts +229 -0
  73. package/mcp-server/package-lock.json +165 -0
  74. package/mcp-server/package.json +32 -7
  75. package/mcp-server/premium-tools.js +2 -2
  76. package/mcp-server/registry/tools.json +476 -0
  77. package/mcp-server/schemas/error-envelope.schema.json +125 -0
  78. package/mcp-server/schemas/finding.schema.json +167 -0
  79. package/mcp-server/schemas/report-artifact.schema.json +88 -0
  80. package/mcp-server/schemas/run-request.schema.json +75 -0
  81. package/mcp-server/schemas/verdict.schema.json +168 -0
  82. package/mcp-server/tier-auth.d.ts +71 -0
  83. package/mcp-server/tier-auth.js +371 -183
  84. package/mcp-server/truth-context.js +90 -131
  85. package/mcp-server/truth-firewall-tools.js +1000 -1611
  86. package/mcp-server/tsconfig.json +34 -0
  87. package/mcp-server/vibecheck-tools.js +2 -2
  88. package/mcp-server/vitest.config.ts +16 -0
  89. package/package.json +3 -4
  90. package/bin/runners/lib/agent-firewall/ai/false-positive-analyzer.js +0 -474
  91. package/bin/runners/lib/agent-firewall/change-packet/builder.js +0 -488
  92. package/bin/runners/lib/agent-firewall/change-packet/schema.json +0 -228
  93. package/bin/runners/lib/agent-firewall/change-packet/store.js +0 -200
  94. package/bin/runners/lib/agent-firewall/claims/claim-types.js +0 -21
  95. package/bin/runners/lib/agent-firewall/claims/extractor.js +0 -303
  96. package/bin/runners/lib/agent-firewall/claims/patterns.js +0 -24
  97. package/bin/runners/lib/agent-firewall/critic/index.js +0 -151
  98. package/bin/runners/lib/agent-firewall/critic/judge.js +0 -432
  99. package/bin/runners/lib/agent-firewall/critic/prompts.js +0 -305
  100. package/bin/runners/lib/agent-firewall/evidence/auth-evidence.js +0 -88
  101. package/bin/runners/lib/agent-firewall/evidence/contract-evidence.js +0 -75
  102. package/bin/runners/lib/agent-firewall/evidence/env-evidence.js +0 -127
  103. package/bin/runners/lib/agent-firewall/evidence/resolver.js +0 -102
  104. package/bin/runners/lib/agent-firewall/evidence/route-evidence.js +0 -213
  105. package/bin/runners/lib/agent-firewall/evidence/side-effect-evidence.js +0 -145
  106. package/bin/runners/lib/agent-firewall/fs-hook/daemon.js +0 -19
  107. package/bin/runners/lib/agent-firewall/fs-hook/installer.js +0 -87
  108. package/bin/runners/lib/agent-firewall/fs-hook/watcher.js +0 -184
  109. package/bin/runners/lib/agent-firewall/git-hook/pre-commit.js +0 -163
  110. package/bin/runners/lib/agent-firewall/ide-extension/cursor.js +0 -107
  111. package/bin/runners/lib/agent-firewall/ide-extension/vscode.js +0 -68
  112. package/bin/runners/lib/agent-firewall/ide-extension/windsurf.js +0 -66
  113. package/bin/runners/lib/agent-firewall/interceptor/base.js +0 -304
  114. package/bin/runners/lib/agent-firewall/interceptor/cursor.js +0 -35
  115. package/bin/runners/lib/agent-firewall/interceptor/vscode.js +0 -35
  116. package/bin/runners/lib/agent-firewall/interceptor/windsurf.js +0 -34
  117. package/bin/runners/lib/agent-firewall/lawbook/distributor.js +0 -465
  118. package/bin/runners/lib/agent-firewall/lawbook/evaluator.js +0 -604
  119. package/bin/runners/lib/agent-firewall/lawbook/index.js +0 -304
  120. package/bin/runners/lib/agent-firewall/lawbook/registry.js +0 -514
  121. package/bin/runners/lib/agent-firewall/lawbook/schema.js +0 -420
  122. package/bin/runners/lib/agent-firewall/logger.js +0 -141
  123. package/bin/runners/lib/agent-firewall/policy/default-policy.json +0 -90
  124. package/bin/runners/lib/agent-firewall/policy/engine.js +0 -103
  125. package/bin/runners/lib/agent-firewall/policy/loader.js +0 -451
  126. package/bin/runners/lib/agent-firewall/policy/rules/auth-drift.js +0 -50
  127. package/bin/runners/lib/agent-firewall/policy/rules/contract-drift.js +0 -50
  128. package/bin/runners/lib/agent-firewall/policy/rules/fake-success.js +0 -86
  129. package/bin/runners/lib/agent-firewall/policy/rules/ghost-env.js +0 -162
  130. package/bin/runners/lib/agent-firewall/policy/rules/ghost-route.js +0 -189
  131. package/bin/runners/lib/agent-firewall/policy/rules/scope.js +0 -93
  132. package/bin/runners/lib/agent-firewall/policy/rules/unsafe-side-effect.js +0 -57
  133. package/bin/runners/lib/agent-firewall/policy/schema.json +0 -183
  134. package/bin/runners/lib/agent-firewall/policy/verdict.js +0 -54
  135. package/bin/runners/lib/agent-firewall/proposal/extractor.js +0 -394
  136. package/bin/runners/lib/agent-firewall/proposal/index.js +0 -212
  137. package/bin/runners/lib/agent-firewall/proposal/schema.js +0 -251
  138. package/bin/runners/lib/agent-firewall/proposal/validator.js +0 -386
  139. package/bin/runners/lib/agent-firewall/reality/index.js +0 -332
  140. package/bin/runners/lib/agent-firewall/reality/state.js +0 -625
  141. package/bin/runners/lib/agent-firewall/reality/watcher.js +0 -322
  142. package/bin/runners/lib/agent-firewall/risk/index.js +0 -173
  143. package/bin/runners/lib/agent-firewall/risk/scorer.js +0 -328
  144. package/bin/runners/lib/agent-firewall/risk/thresholds.js +0 -321
  145. package/bin/runners/lib/agent-firewall/risk/vectors.js +0 -421
  146. package/bin/runners/lib/agent-firewall/simulator/diff-simulator.js +0 -472
  147. package/bin/runners/lib/agent-firewall/simulator/import-resolver.js +0 -346
  148. package/bin/runners/lib/agent-firewall/simulator/index.js +0 -181
  149. package/bin/runners/lib/agent-firewall/simulator/route-validator.js +0 -380
  150. package/bin/runners/lib/agent-firewall/time-machine/incident-correlator.js +0 -661
  151. package/bin/runners/lib/agent-firewall/time-machine/index.js +0 -267
  152. package/bin/runners/lib/agent-firewall/time-machine/replay-engine.js +0 -436
  153. package/bin/runners/lib/agent-firewall/time-machine/state-reconstructor.js +0 -490
  154. package/bin/runners/lib/agent-firewall/time-machine/timeline-builder.js +0 -530
  155. package/bin/runners/lib/agent-firewall/truthpack/index.js +0 -67
  156. package/bin/runners/lib/agent-firewall/truthpack/loader.js +0 -137
  157. package/bin/runners/lib/agent-firewall/unblock/planner.js +0 -337
  158. package/bin/runners/lib/agent-firewall/utils/ignore-checker.js +0 -118
  159. package/bin/runners/lib/api-client.js +0 -269
  160. package/bin/runners/lib/authority-badge.js +0 -425
  161. package/bin/runners/lib/engines/accessibility-engine.js +0 -190
  162. package/bin/runners/lib/engines/api-consistency-engine.js +0 -162
  163. package/bin/runners/lib/engines/ast-cache.js +0 -99
  164. package/bin/runners/lib/engines/code-quality-engine.js +0 -255
  165. package/bin/runners/lib/engines/console-logs-engine.js +0 -115
  166. package/bin/runners/lib/engines/cross-file-analysis-engine.js +0 -268
  167. package/bin/runners/lib/engines/dead-code-engine.js +0 -198
  168. package/bin/runners/lib/engines/deprecated-api-engine.js +0 -226
  169. package/bin/runners/lib/engines/empty-catch-engine.js +0 -150
  170. package/bin/runners/lib/engines/file-filter.js +0 -131
  171. package/bin/runners/lib/engines/hardcoded-secrets-engine.js +0 -251
  172. package/bin/runners/lib/engines/mock-data-engine.js +0 -272
  173. package/bin/runners/lib/engines/parallel-processor.js +0 -71
  174. package/bin/runners/lib/engines/performance-issues-engine.js +0 -265
  175. package/bin/runners/lib/engines/security-vulnerabilities-engine.js +0 -243
  176. package/bin/runners/lib/engines/todo-fixme-engine.js +0 -115
  177. package/bin/runners/lib/engines/type-aware-engine.js +0 -152
  178. package/bin/runners/lib/engines/unsafe-regex-engine.js +0 -225
  179. package/bin/runners/lib/engines/vibecheck-engines/README.md +0 -53
  180. package/bin/runners/lib/engines/vibecheck-engines/index.js +0 -15
  181. package/bin/runners/lib/engines/vibecheck-engines/lib/ast-cache.js +0 -164
  182. package/bin/runners/lib/engines/vibecheck-engines/lib/code-quality-engine.js +0 -291
  183. package/bin/runners/lib/engines/vibecheck-engines/lib/console-logs-engine.js +0 -83
  184. package/bin/runners/lib/engines/vibecheck-engines/lib/dead-code-engine.js +0 -198
  185. package/bin/runners/lib/engines/vibecheck-engines/lib/deprecated-api-engine.js +0 -275
  186. package/bin/runners/lib/engines/vibecheck-engines/lib/empty-catch-engine.js +0 -167
  187. package/bin/runners/lib/engines/vibecheck-engines/lib/file-filter.js +0 -217
  188. package/bin/runners/lib/engines/vibecheck-engines/lib/hardcoded-secrets-engine.js +0 -139
  189. package/bin/runners/lib/engines/vibecheck-engines/lib/mock-data-engine.js +0 -140
  190. package/bin/runners/lib/engines/vibecheck-engines/lib/parallel-processor.js +0 -164
  191. package/bin/runners/lib/engines/vibecheck-engines/lib/performance-issues-engine.js +0 -234
  192. package/bin/runners/lib/engines/vibecheck-engines/lib/type-aware-engine.js +0 -217
  193. package/bin/runners/lib/engines/vibecheck-engines/lib/unsafe-regex-engine.js +0 -78
  194. package/bin/runners/lib/engines/vibecheck-engines/package.json +0 -13
  195. package/bin/runners/lib/exit-codes.js +0 -275
  196. package/bin/runners/lib/fingerprint.js +0 -377
  197. package/bin/runners/lib/help-formatter.js +0 -413
  198. package/bin/runners/lib/logger.js +0 -38
  199. package/bin/runners/lib/ship-output-enterprise.js +0 -239
  200. package/bin/runners/lib/unified-cli-output.js +0 -604
  201. package/bin/runners/runAgent.d.ts +0 -5
  202. package/bin/runners/runAgent.js +0 -161
  203. package/bin/runners/runApprove.js +0 -1200
  204. package/bin/runners/runClassify.js +0 -859
  205. package/bin/runners/runContext.d.ts +0 -4
  206. package/bin/runners/runFirewall.d.ts +0 -5
  207. package/bin/runners/runFirewall.js +0 -134
  208. package/bin/runners/runFirewallHook.d.ts +0 -5
  209. package/bin/runners/runFirewallHook.js +0 -56
  210. package/bin/runners/runPolish.d.ts +0 -4
  211. package/bin/runners/runProof.zip +0 -0
  212. package/bin/runners/runTruth.d.ts +0 -5
  213. package/bin/runners/runTruth.js +0 -101
  214. package/mcp-server/HARDENING_SUMMARY.md +0 -299
  215. package/mcp-server/agent-firewall-interceptor.js +0 -500
  216. package/mcp-server/authority-tools.js +0 -569
  217. package/mcp-server/conductor/conflict-resolver.js +0 -588
  218. package/mcp-server/conductor/execution-planner.js +0 -544
  219. package/mcp-server/conductor/index.js +0 -377
  220. package/mcp-server/conductor/lock-manager.js +0 -615
  221. package/mcp-server/conductor/request-queue.js +0 -550
  222. package/mcp-server/conductor/session-manager.js +0 -500
  223. package/mcp-server/conductor/tools.js +0 -510
  224. package/mcp-server/lib/api-client.cjs +0 -13
  225. package/mcp-server/lib/logger.cjs +0 -30
  226. package/mcp-server/logger.js +0 -173
  227. package/mcp-server/tools-v3.js +0 -706
  228. package/mcp-server/vibecheck-mcp-server-3.2.0.tgz +0 -0
@@ -1,251 +0,0 @@
1
- /**
2
- * Hardcoded Secrets Detection Engine
3
- * Uses AST analysis + entropy to detect hardcoded secrets
4
- */
5
-
6
- const { getAST, parseCode } = require("./ast-cache");
7
- const traverse = require("@babel/traverse").default;
8
- const t = require("@babel/types");
9
- const crypto = require("crypto");
10
- const { shouldExcludeFile } = require("./file-filter");
11
-
12
- /**
13
- * Calculate Shannon entropy for a string
14
- */
15
- function getShannonEntropy(str) {
16
- if (!str || str.length === 0) return 0;
17
- const len = str.length;
18
- const frequencies = {};
19
- for (let i = 0; i < len; i++) {
20
- const char = str[i];
21
- frequencies[char] = (frequencies[char] || 0) + 1;
22
- }
23
-
24
- let entropy = 0;
25
- for (const char in frequencies) {
26
- const p = frequencies[char] / len;
27
- entropy -= p * Math.log2(p);
28
- }
29
- return entropy;
30
- }
31
-
32
- /**
33
- * Specific secret patterns (high confidence, no entropy needed)
34
- */
35
- const SPECIFIC_PATTERNS = [
36
- {
37
- pattern: /^sk_live_[a-zA-Z0-9]{20,}$/,
38
- label: "Stripe live secret key",
39
- severity: "BLOCK",
40
- },
41
- {
42
- pattern: /^sk_test_[a-zA-Z0-9]{20,}$/,
43
- label: "Stripe test secret key",
44
- severity: "WARN",
45
- },
46
- {
47
- pattern: /^pk_live_[a-zA-Z0-9]{20,}$/,
48
- label: "Stripe live publishable key",
49
- severity: "BLOCK",
50
- },
51
- {
52
- pattern: /^AKIA[0-9A-Z]{16}$/,
53
- label: "AWS Access Key ID",
54
- severity: "BLOCK",
55
- },
56
- {
57
- pattern: /^ghp_[a-zA-Z0-9]{36}$/,
58
- label: "GitHub Personal Access Token",
59
- severity: "BLOCK",
60
- },
61
- {
62
- pattern: /^gho_[a-zA-Z0-9]{36}$/,
63
- label: "GitHub OAuth Token",
64
- severity: "BLOCK",
65
- },
66
- {
67
- pattern: /^xox[baprs]-[0-9]{10,13}-[0-9]{10,13}-[a-zA-Z0-9]{24}$/,
68
- label: "Slack Token",
69
- severity: "BLOCK",
70
- },
71
- {
72
- pattern: /^eyJ[a-zA-Z0-9_-]{100,}\.[a-zA-Z0-9_-]{100,}\.[a-zA-Z0-9_-]{43,}$/,
73
- label: "JWT Token (hardcoded)",
74
- severity: "WARN",
75
- },
76
- ];
77
-
78
- /**
79
- * Check if string matches a specific secret pattern
80
- */
81
- function matchesSpecificPattern(value) {
82
- for (const { pattern, label, severity } of SPECIFIC_PATTERNS) {
83
- if (pattern.test(value)) {
84
- return { label, severity, confidence: "high" };
85
- }
86
- }
87
- return null;
88
- }
89
-
90
- /**
91
- * Check if string looks like a secret based on context and entropy
92
- */
93
- function looksLikeSecret(value, context = {}) {
94
- // Skip common false positives
95
- if (/^(undefined|null|true|false|localhost|example|placeholder|test|demo|development|production)$/i.test(value)) {
96
- return null;
97
- }
98
-
99
- // Skip hex-only strings (likely Git SHAs, image IDs, hashes)
100
- if (/^[a-f0-9]{32,}$/i.test(value)) {
101
- return null;
102
- }
103
-
104
- // Skip UUIDs (they have high entropy but are not secrets)
105
- if (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value)) {
106
- return null;
107
- }
108
-
109
- // Skip common test/example values
110
- if (/^(test|example|sample|demo|placeholder|foo|bar|baz|qux)/i.test(value)) {
111
- return null;
112
- }
113
-
114
- // Check entropy
115
- const entropy = getShannonEntropy(value);
116
-
117
- // Context-based checks - require explicit secret context
118
- const hasSecretContext =
119
- context.variableName && /(password|secret|key|token|credential|api[_-]?key|private[_-]?key|access[_-]?token)/i.test(context.variableName);
120
-
121
- // Only flag if we have explicit secret context AND high entropy
122
- if (hasSecretContext && value.length >= 12 && entropy >= 4.0) {
123
- return {
124
- label: `Hardcoded ${context.variableName.match(/(password|secret|key|token|credential|api[_-]?key|private[_-]?key|access[_-]?token)/i)?.[0] || "secret"}`,
125
- severity: "WARN",
126
- confidence: "med",
127
- entropy,
128
- };
129
- }
130
-
131
- // Generic high entropy check - be more conservative (require longer strings and higher entropy)
132
- if (entropy >= 5.0 && value.length >= 32) {
133
- return {
134
- label: "Possible hardcoded secret (high entropy)",
135
- severity: "WARN",
136
- confidence: "low",
137
- entropy,
138
- };
139
- }
140
-
141
- return null;
142
- }
143
-
144
- /**
145
- * Analyze a file for hardcoded secrets
146
- */
147
- function analyzeHardcodedSecrets(code, filePath) {
148
- const findings = [];
149
-
150
- // Skip excluded files (includes .env files)
151
- if (shouldExcludeFile(filePath)) return findings;
152
-
153
- const ast = getAST(code, filePath);
154
- if (!ast) return findings;
155
-
156
- const lines = code.split("\n");
157
-
158
- traverse(ast, {
159
- // Check string literals
160
- StringLiteral(path) {
161
- const value = path.node.value;
162
- if (!value || value.length < 8) return;
163
-
164
- // Check specific patterns first
165
- const specificMatch = matchesSpecificPattern(value);
166
- if (specificMatch) {
167
- const line = path.node.loc.start.line;
168
- findings.push({
169
- type: "specific_secret",
170
- severity: specificMatch.severity,
171
- category: "HardcodedSecret",
172
- file: filePath,
173
- line,
174
- column: path.node.loc.start.column,
175
- title: `${specificMatch.label} detected`,
176
- message: `${specificMatch.label} found in code`,
177
- codeSnippet: lines[line - 1]?.trim(),
178
- confidence: specificMatch.confidence,
179
- });
180
- return;
181
- }
182
-
183
- // Check generic patterns with context
184
- const parent = path.parent;
185
- let variableName = null;
186
-
187
- if (t.isVariableDeclarator(parent)) {
188
- variableName = parent.id.name;
189
- } else if (t.isObjectProperty(parent)) {
190
- variableName = t.isIdentifier(parent.key) ? parent.key.name : null;
191
- } else if (t.isAssignmentExpression(parent)) {
192
- if (t.isIdentifier(parent.left)) {
193
- variableName = parent.left.name;
194
- }
195
- }
196
-
197
- const secretMatch = looksLikeSecret(value, { variableName });
198
- if (secretMatch) {
199
- const line = path.node.loc.start.line;
200
- findings.push({
201
- type: "generic_secret",
202
- severity: secretMatch.severity,
203
- category: "HardcodedSecret",
204
- file: filePath,
205
- line,
206
- column: path.node.loc.start.column,
207
- title: secretMatch.label,
208
- message: `High entropy string (${secretMatch.entropy.toFixed(2)}) detected${variableName ? ` in variable "${variableName}"` : ""}`,
209
- codeSnippet: lines[line - 1]?.trim(),
210
- confidence: secretMatch.confidence,
211
- });
212
- }
213
- },
214
-
215
- // Check template literals
216
- TemplateLiteral(path) {
217
- const quasis = path.node.quasis;
218
- for (const quasi of quasis) {
219
- if (quasi.value && quasi.value.raw) {
220
- const value = quasi.value.raw;
221
- if (value.length >= 8) {
222
- const specificMatch = matchesSpecificPattern(value);
223
- if (specificMatch) {
224
- const line = path.node.loc.start.line;
225
- findings.push({
226
- type: "specific_secret",
227
- severity: specificMatch.severity,
228
- category: "HardcodedSecret",
229
- file: filePath,
230
- line,
231
- column: path.node.loc.start.column,
232
- title: `${specificMatch.label} detected`,
233
- message: `${specificMatch.label} found in template literal`,
234
- codeSnippet: lines[line - 1]?.trim(),
235
- confidence: specificMatch.confidence,
236
- });
237
- }
238
- }
239
- }
240
- }
241
- },
242
- });
243
-
244
- return findings;
245
- }
246
-
247
- module.exports = {
248
- analyzeHardcodedSecrets,
249
- parseCode,
250
- getShannonEntropy,
251
- };
@@ -1,272 +0,0 @@
1
- /**
2
- * Mock Data Detection Engine
3
- * Uses AST analysis to detect mock/test data patterns in production code
4
- */
5
-
6
- const { getAST, parseCode } = require("./ast-cache");
7
- const traverse = require("@babel/traverse").default;
8
- const t = require("@babel/types");
9
- const { shouldExcludeFile } = require("./file-filter");
10
-
11
- /**
12
- * Check if a string literal looks like mock/test data
13
- */
14
- function isMockString(value) {
15
- if (typeof value !== "string") return false;
16
-
17
- const lower = value.toLowerCase();
18
-
19
- // Mock data patterns
20
- const mockPatterns = [
21
- /^(fake|mock|dummy|test|sample|placeholder)[_-]?/i,
22
- /@(test|example|fake|demo)\.com$/i,
23
- /^(password|admin|test|secret)123$/i,
24
- /^test@/i,
25
- /^(MOCK|FAKE|DUMMY)_API/i,
26
- ];
27
-
28
- return mockPatterns.some(pattern => pattern.test(value));
29
- }
30
-
31
- /**
32
- * Check if a variable name suggests mock data
33
- * Be more conservative - only flag explicit mock/test data variables
34
- */
35
- function isMockVariableName(name) {
36
- if (!name || typeof name !== "string") return false;
37
-
38
- const lower = name.toLowerCase();
39
-
40
- // Only flag explicit mock/test data variable names (exact matches or explicit prefixes)
41
- const mockNamePatterns = [
42
- /^(fake|mock|dummy)[_-]?(data|user|api|response|value|input)$/i, // Explicit mock prefixes
43
- /^mockData$/i,
44
- /^fakeData$/i,
45
- ];
46
-
47
- // Exclude common legitimate patterns
48
- const legitimatePatterns = [
49
- /sample/i, // "sample" is often legitimate
50
- /example/i, // "example" is often legitimate
51
- /demo/i, // "demo" is often legitimate
52
- /test/i, // "test" alone is often legitimate
53
- ];
54
-
55
- // Don't flag if it matches legitimate patterns
56
- if (legitimatePatterns.some(pattern => pattern.test(name))) {
57
- return false;
58
- }
59
-
60
- return mockNamePatterns.some(pattern => pattern.test(name));
61
- }
62
-
63
- /**
64
- * Check if a call expression is generating random/mock data
65
- */
66
- function isRandomDataGeneration(node) {
67
- if (!t.isCallExpression(node)) return false;
68
-
69
- const callee = node.callee;
70
-
71
- // Math.random() with multiplication
72
- if (t.isMemberExpression(callee) &&
73
- t.isIdentifier(callee.object) && callee.object.name === "Math" &&
74
- t.isIdentifier(callee.property) && callee.property.name === "random") {
75
-
76
- // Check parent for multiplication or comparison
77
- const parent = node.parent;
78
- if (t.isBinaryExpression(parent) &&
79
- (parent.operator === "*" || parent.operator === "<" || parent.operator === ">")) {
80
- return true;
81
- }
82
- }
83
-
84
- return false;
85
- }
86
-
87
- /**
88
- * Check if setTimeout has suspiciously long delays (simulated delays)
89
- */
90
- function isSuspiciousSetTimeout(node) {
91
- if (!t.isCallExpression(node)) return false;
92
-
93
- const callee = node.callee;
94
- if (!t.isIdentifier(callee) || callee.name !== "setTimeout") return false;
95
-
96
- const args = node.arguments;
97
- if (args.length < 2) return false;
98
-
99
- // Check delay argument
100
- const delay = args[1];
101
- if (t.isNumericLiteral(delay)) {
102
- // Suspicious if > 5000ms (5 seconds)
103
- return delay.value > 5000;
104
- }
105
-
106
- return false;
107
- }
108
-
109
- /**
110
- * Analyze a file for mock data patterns
111
- */
112
- function analyzeMockData(code, filePath) {
113
- const findings = [];
114
-
115
- // Skip excluded files (test files, examples, etc.)
116
- if (shouldExcludeFile(filePath)) return findings;
117
-
118
- const ast = getAST(code, filePath);
119
- if (!ast) return findings;
120
-
121
- const lines = code.split("\n");
122
-
123
- traverse(ast, {
124
- // Check variable declarations
125
- VariableDeclarator(path) {
126
- const id = path.node.id;
127
- const init = path.node.init;
128
-
129
- // Check variable name
130
- if (t.isIdentifier(id) && isMockVariableName(id.name)) {
131
- const line = getLineNumber(path.node, code);
132
- findings.push({
133
- type: "mock_variable",
134
- severity: "WARN",
135
- category: "MockData",
136
- file: filePath,
137
- line,
138
- column: path.node.loc.start.column,
139
- title: `Mock data variable: ${id.name}`,
140
- message: `Variable name suggests mock/test data: ${id.name}`,
141
- codeSnippet: lines[line - 1]?.trim(),
142
- confidence: "high",
143
- });
144
- }
145
-
146
- // Check initializer value
147
- if (init && t.isStringLiteral(init) && isMockString(init.value)) {
148
- const line = getLineNumber(path.node, code);
149
- findings.push({
150
- type: "mock_string_literal",
151
- severity: "WARN",
152
- category: "MockData",
153
- file: filePath,
154
- line,
155
- column: path.node.loc.start.column,
156
- title: "Mock/test string literal detected",
157
- message: `String value appears to be mock data: "${init.value.substring(0, 50)}"`,
158
- codeSnippet: lines[line - 1]?.trim(),
159
- confidence: "med",
160
- });
161
- }
162
- },
163
-
164
- // Check object properties
165
- ObjectProperty(path) {
166
- const key = path.node.key;
167
- const value = path.node.value;
168
-
169
- if (t.isIdentifier(key) && isMockVariableName(key.name)) {
170
- const line = getLineNumber(path.node, code);
171
- findings.push({
172
- type: "mock_object_property",
173
- severity: "WARN",
174
- category: "MockData",
175
- file: filePath,
176
- line,
177
- column: path.node.loc.start.column,
178
- title: `Mock data property: ${key.name}`,
179
- message: `Object property name suggests mock data: ${key.name}`,
180
- codeSnippet: lines[line - 1]?.trim(),
181
- confidence: "med",
182
- });
183
- }
184
-
185
- if (t.isStringLiteral(value) && isMockString(value.value)) {
186
- const line = getLineNumber(path.node, code);
187
- findings.push({
188
- type: "mock_property_value",
189
- severity: "WARN",
190
- category: "MockData",
191
- file: filePath,
192
- line,
193
- column: path.node.loc.start.column,
194
- title: "Mock string in object property",
195
- message: `Property value appears to be mock data: "${value.value.substring(0, 50)}"`,
196
- codeSnippet: lines[line - 1]?.trim(),
197
- confidence: "med",
198
- });
199
- }
200
- },
201
-
202
- // Check call expressions for random data generation
203
- CallExpression(path) {
204
- if (isRandomDataGeneration(path.node)) {
205
- const line = getLineNumber(path.node, code);
206
- findings.push({
207
- type: "random_data_generation",
208
- severity: "WARN",
209
- category: "MockData",
210
- file: filePath,
211
- line,
212
- column: path.node.loc.start.column,
213
- title: "Random data generation detected",
214
- message: "Math.random() used for data generation (may be mock data)",
215
- codeSnippet: lines[line - 1]?.trim(),
216
- confidence: "low",
217
- });
218
- }
219
-
220
- if (isSuspiciousSetTimeout(path.node)) {
221
- const line = getLineNumber(path.node, code);
222
- findings.push({
223
- type: "suspicious_settimeout",
224
- severity: "WARN",
225
- category: "MockData",
226
- file: filePath,
227
- line,
228
- column: path.node.loc.start.column,
229
- title: "Long setTimeout delay (possible simulated delay)",
230
- message: "setTimeout with delay > 5000ms may indicate simulated/mock behavior",
231
- codeSnippet: lines[line - 1]?.trim(),
232
- confidence: "low",
233
- });
234
- }
235
- },
236
-
237
- // Check template literals
238
- TemplateLiteral(path) {
239
- const quasis = path.node.quasis;
240
- for (const quasi of quasis) {
241
- if (quasi.value && isMockString(quasi.value.raw)) {
242
- const line = getLineNumber(path.node, code);
243
- findings.push({
244
- type: "mock_template_literal",
245
- severity: "WARN",
246
- category: "MockData",
247
- file: filePath,
248
- line,
249
- column: path.node.loc.start.column,
250
- title: "Mock data in template literal",
251
- message: `Template literal contains mock/test data pattern`,
252
- codeSnippet: lines[line - 1]?.trim(),
253
- confidence: "med",
254
- });
255
- break;
256
- }
257
- }
258
- },
259
- });
260
-
261
- return findings;
262
- }
263
-
264
- function getLineNumber(node, code) {
265
- if (!node || !node.loc) return 1;
266
- return node.loc.start.line;
267
- }
268
-
269
- module.exports = {
270
- analyzeMockData,
271
- parseCode,
272
- };
@@ -1,71 +0,0 @@
1
- /**
2
- * Parallel File Processor
3
- * Processes files in parallel with configurable concurrency
4
- */
5
-
6
- const os = require("os");
7
-
8
- /**
9
- * Process files in parallel batches
10
- */
11
- async function processFilesInParallel(files, processor, options = {}) {
12
- const {
13
- concurrency = Math.min(os.cpus().length, 8), // Default to CPU count, max 8
14
- onProgress = null,
15
- } = options;
16
-
17
- const results = [];
18
- const errors = [];
19
-
20
- // Process in batches
21
- for (let i = 0; i < files.length; i += concurrency) {
22
- const batch = files.slice(i, i + concurrency);
23
-
24
- const batchPromises = batch.map(async (file, index) => {
25
- try {
26
- const result = await processor(file);
27
- if (onProgress) {
28
- onProgress(i + index + 1, files.length);
29
- }
30
- return { file, result, error: null };
31
- } catch (error) {
32
- errors.push({ file, error });
33
- return { file, result: null, error };
34
- }
35
- });
36
-
37
- const batchResults = await Promise.all(batchPromises);
38
- results.push(...batchResults);
39
- }
40
-
41
- return { results, errors };
42
- }
43
-
44
- /**
45
- * Process files sequentially (fallback)
46
- */
47
- async function processFilesSequentially(files, processor, onProgress = null) {
48
- const results = [];
49
- const errors = [];
50
-
51
- for (let i = 0; i < files.length; i++) {
52
- const file = files[i];
53
- try {
54
- const result = await processor(file);
55
- if (onProgress) {
56
- onProgress(i + 1, files.length);
57
- }
58
- results.push({ file, result, error: null });
59
- } catch (error) {
60
- errors.push({ file, error });
61
- results.push({ file, result: null, error });
62
- }
63
- }
64
-
65
- return { results, errors };
66
- }
67
-
68
- module.exports = {
69
- processFilesInParallel,
70
- processFilesSequentially,
71
- };