vibecheck-ai 2.0.1 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (456) hide show
  1. package/bin/.generated +25 -0
  2. package/bin/_deprecations.js +463 -0
  3. package/bin/_router.js +46 -0
  4. package/bin/cli-hygiene.js +241 -0
  5. package/bin/dev/run-v2-torture.js +30 -0
  6. package/bin/registry.js +656 -0
  7. package/bin/runners/CLI_REFACTOR_SUMMARY.md +229 -0
  8. package/bin/runners/ENHANCEMENT_GUIDE.md +121 -0
  9. package/bin/runners/REPORT_AUDIT.md +64 -0
  10. package/bin/runners/cli-utils.js +1070 -0
  11. package/bin/runners/context/ai-task-decomposer.js +337 -0
  12. package/bin/runners/context/analyzer.js +513 -0
  13. package/bin/runners/context/api-contracts.js +427 -0
  14. package/bin/runners/context/context-diff.js +342 -0
  15. package/bin/runners/context/context-pruner.js +291 -0
  16. package/bin/runners/context/dependency-graph.js +414 -0
  17. package/bin/runners/context/generators/claude.js +107 -0
  18. package/bin/runners/context/generators/codex.js +108 -0
  19. package/bin/runners/context/generators/copilot.js +119 -0
  20. package/bin/runners/context/generators/cursor-enhanced.js +2525 -0
  21. package/bin/runners/context/generators/cursor.js +514 -0
  22. package/bin/runners/context/generators/mcp.js +169 -0
  23. package/bin/runners/context/generators/windsurf.js +180 -0
  24. package/bin/runners/context/git-context.js +304 -0
  25. package/bin/runners/context/index.js +1110 -0
  26. package/bin/runners/context/insights.js +173 -0
  27. package/bin/runners/context/mcp-server/generate-rules.js +337 -0
  28. package/bin/runners/context/mcp-server/index.js +1176 -0
  29. package/bin/runners/context/mcp-server/package.json +24 -0
  30. package/bin/runners/context/memory.js +200 -0
  31. package/bin/runners/context/monorepo.js +215 -0
  32. package/bin/runners/context/multi-repo-federation.js +404 -0
  33. package/bin/runners/context/patterns.js +253 -0
  34. package/bin/runners/context/proof-context.js +1264 -0
  35. package/bin/runners/context/security-scanner.js +541 -0
  36. package/bin/runners/context/semantic-search.js +350 -0
  37. package/bin/runners/context/shared.js +264 -0
  38. package/bin/runners/context/team-conventions.js +336 -0
  39. package/bin/runners/lib/__tests__/entitlements-v2.test.js +295 -0
  40. package/bin/runners/lib/agent-firewall/ai/false-positive-analyzer.js +474 -0
  41. package/bin/runners/lib/agent-firewall/change-packet/builder.js +488 -0
  42. package/bin/runners/lib/agent-firewall/change-packet/schema.json +228 -0
  43. package/bin/runners/lib/agent-firewall/change-packet/store.js +200 -0
  44. package/bin/runners/lib/agent-firewall/claims/claim-types.js +21 -0
  45. package/bin/runners/lib/agent-firewall/claims/extractor.js +303 -0
  46. package/bin/runners/lib/agent-firewall/claims/patterns.js +24 -0
  47. package/bin/runners/lib/agent-firewall/critic/index.js +151 -0
  48. package/bin/runners/lib/agent-firewall/critic/judge.js +432 -0
  49. package/bin/runners/lib/agent-firewall/critic/prompts.js +305 -0
  50. package/bin/runners/lib/agent-firewall/enforcement/gateway.js +1059 -0
  51. package/bin/runners/lib/agent-firewall/enforcement/index.js +98 -0
  52. package/bin/runners/lib/agent-firewall/enforcement/mode.js +318 -0
  53. package/bin/runners/lib/agent-firewall/enforcement/orchestrator.js +484 -0
  54. package/bin/runners/lib/agent-firewall/enforcement/proof-artifact.js +418 -0
  55. package/bin/runners/lib/agent-firewall/enforcement/schemas/change-event.schema.json +173 -0
  56. package/bin/runners/lib/agent-firewall/enforcement/schemas/intent.schema.json +181 -0
  57. package/bin/runners/lib/agent-firewall/enforcement/schemas/verdict.schema.json +222 -0
  58. package/bin/runners/lib/agent-firewall/enforcement/verdict-v2.js +333 -0
  59. package/bin/runners/lib/agent-firewall/evidence/auth-evidence.js +88 -0
  60. package/bin/runners/lib/agent-firewall/evidence/contract-evidence.js +75 -0
  61. package/bin/runners/lib/agent-firewall/evidence/env-evidence.js +127 -0
  62. package/bin/runners/lib/agent-firewall/evidence/resolver.js +102 -0
  63. package/bin/runners/lib/agent-firewall/evidence/route-evidence.js +213 -0
  64. package/bin/runners/lib/agent-firewall/evidence/side-effect-evidence.js +145 -0
  65. package/bin/runners/lib/agent-firewall/fs-hook/daemon.js +19 -0
  66. package/bin/runners/lib/agent-firewall/fs-hook/installer.js +87 -0
  67. package/bin/runners/lib/agent-firewall/fs-hook/watcher.js +184 -0
  68. package/bin/runners/lib/agent-firewall/git-hook/pre-commit.js +163 -0
  69. package/bin/runners/lib/agent-firewall/ide-extension/cursor.js +107 -0
  70. package/bin/runners/lib/agent-firewall/ide-extension/vscode.js +68 -0
  71. package/bin/runners/lib/agent-firewall/ide-extension/windsurf.js +66 -0
  72. package/bin/runners/lib/agent-firewall/index.js +200 -0
  73. package/bin/runners/lib/agent-firewall/integration/index.js +20 -0
  74. package/bin/runners/lib/agent-firewall/integration/ship-gate.js +437 -0
  75. package/bin/runners/lib/agent-firewall/intent/alignment-engine.js +634 -0
  76. package/bin/runners/lib/agent-firewall/intent/auto-detect.js +426 -0
  77. package/bin/runners/lib/agent-firewall/intent/index.js +102 -0
  78. package/bin/runners/lib/agent-firewall/intent/schema.js +352 -0
  79. package/bin/runners/lib/agent-firewall/intent/store.js +283 -0
  80. package/bin/runners/lib/agent-firewall/interception/fs-interceptor.js +502 -0
  81. package/bin/runners/lib/agent-firewall/interception/index.js +23 -0
  82. package/bin/runners/lib/agent-firewall/interceptor/base.js +308 -0
  83. package/bin/runners/lib/agent-firewall/interceptor/cursor.js +35 -0
  84. package/bin/runners/lib/agent-firewall/interceptor/vscode.js +35 -0
  85. package/bin/runners/lib/agent-firewall/interceptor/windsurf.js +34 -0
  86. package/bin/runners/lib/agent-firewall/lawbook/distributor.js +465 -0
  87. package/bin/runners/lib/agent-firewall/lawbook/evaluator.js +604 -0
  88. package/bin/runners/lib/agent-firewall/lawbook/index.js +304 -0
  89. package/bin/runners/lib/agent-firewall/lawbook/registry.js +514 -0
  90. package/bin/runners/lib/agent-firewall/lawbook/schema.js +420 -0
  91. package/bin/runners/lib/agent-firewall/logger.js +141 -0
  92. package/bin/runners/lib/agent-firewall/policy/default-policy.json +90 -0
  93. package/bin/runners/lib/agent-firewall/policy/engine.js +103 -0
  94. package/bin/runners/lib/agent-firewall/policy/loader.js +451 -0
  95. package/bin/runners/lib/agent-firewall/policy/rules/auth-drift.js +50 -0
  96. package/bin/runners/lib/agent-firewall/policy/rules/contract-drift.js +50 -0
  97. package/bin/runners/lib/agent-firewall/policy/rules/fake-success.js +79 -0
  98. package/bin/runners/lib/agent-firewall/policy/rules/ghost-env.js +227 -0
  99. package/bin/runners/lib/agent-firewall/policy/rules/ghost-route.js +191 -0
  100. package/bin/runners/lib/agent-firewall/policy/rules/scope.js +93 -0
  101. package/bin/runners/lib/agent-firewall/policy/rules/unsafe-side-effect.js +57 -0
  102. package/bin/runners/lib/agent-firewall/policy/schema.json +183 -0
  103. package/bin/runners/lib/agent-firewall/policy/verdict.js +54 -0
  104. package/bin/runners/lib/agent-firewall/proposal/extractor.js +394 -0
  105. package/bin/runners/lib/agent-firewall/proposal/index.js +212 -0
  106. package/bin/runners/lib/agent-firewall/proposal/schema.js +251 -0
  107. package/bin/runners/lib/agent-firewall/proposal/validator.js +386 -0
  108. package/bin/runners/lib/agent-firewall/reality/index.js +332 -0
  109. package/bin/runners/lib/agent-firewall/reality/state.js +625 -0
  110. package/bin/runners/lib/agent-firewall/reality/watcher.js +322 -0
  111. package/bin/runners/lib/agent-firewall/risk/index.js +173 -0
  112. package/bin/runners/lib/agent-firewall/risk/scorer.js +328 -0
  113. package/bin/runners/lib/agent-firewall/risk/thresholds.js +322 -0
  114. package/bin/runners/lib/agent-firewall/risk/vectors.js +421 -0
  115. package/bin/runners/lib/agent-firewall/session/collector.js +451 -0
  116. package/bin/runners/lib/agent-firewall/session/index.js +26 -0
  117. package/bin/runners/lib/agent-firewall/simulator/diff-simulator.js +472 -0
  118. package/bin/runners/lib/agent-firewall/simulator/import-resolver.js +346 -0
  119. package/bin/runners/lib/agent-firewall/simulator/index.js +181 -0
  120. package/bin/runners/lib/agent-firewall/simulator/route-validator.js +380 -0
  121. package/bin/runners/lib/agent-firewall/time-machine/incident-correlator.js +661 -0
  122. package/bin/runners/lib/agent-firewall/time-machine/index.js +267 -0
  123. package/bin/runners/lib/agent-firewall/time-machine/replay-engine.js +436 -0
  124. package/bin/runners/lib/agent-firewall/time-machine/state-reconstructor.js +490 -0
  125. package/bin/runners/lib/agent-firewall/time-machine/timeline-builder.js +530 -0
  126. package/bin/runners/lib/agent-firewall/truthpack/index.js +67 -0
  127. package/bin/runners/lib/agent-firewall/truthpack/loader.js +137 -0
  128. package/bin/runners/lib/agent-firewall/unblock/planner.js +337 -0
  129. package/bin/runners/lib/agent-firewall/utils/ignore-checker.js +118 -0
  130. package/bin/runners/lib/ai-bridge.js +416 -0
  131. package/bin/runners/lib/analysis-core.js +309 -0
  132. package/bin/runners/lib/analyzers.js +2500 -0
  133. package/bin/runners/lib/api-client.js +269 -0
  134. package/bin/runners/lib/approve-output.js +235 -0
  135. package/bin/runners/lib/artifact-envelope.js +540 -0
  136. package/bin/runners/lib/assets/vibecheck-logo.png +0 -0
  137. package/bin/runners/lib/audit-bridge.js +391 -0
  138. package/bin/runners/lib/auth-shared.js +977 -0
  139. package/bin/runners/lib/auth-truth.js +193 -0
  140. package/bin/runners/lib/auth.js +215 -0
  141. package/bin/runners/lib/authority-badge.js +425 -0
  142. package/bin/runners/lib/backup.js +62 -0
  143. package/bin/runners/lib/billing.js +107 -0
  144. package/bin/runners/lib/checkpoint.js +941 -0
  145. package/bin/runners/lib/claims.js +118 -0
  146. package/bin/runners/lib/classify-output.js +204 -0
  147. package/bin/runners/lib/cleanup/engine.js +571 -0
  148. package/bin/runners/lib/cleanup/index.js +53 -0
  149. package/bin/runners/lib/cleanup/output.js +375 -0
  150. package/bin/runners/lib/cleanup/rules.js +1060 -0
  151. package/bin/runners/lib/cli-output.js +400 -0
  152. package/bin/runners/lib/cli-ui.js +540 -0
  153. package/bin/runners/lib/compliance-bridge-new.js +0 -0
  154. package/bin/runners/lib/compliance-bridge.js +165 -0
  155. package/bin/runners/lib/contracts/auth-contract.js +202 -0
  156. package/bin/runners/lib/contracts/env-contract.js +181 -0
  157. package/bin/runners/lib/contracts/external-contract.js +206 -0
  158. package/bin/runners/lib/contracts/guard.js +168 -0
  159. package/bin/runners/lib/contracts/index.js +89 -0
  160. package/bin/runners/lib/contracts/plan-validator.js +311 -0
  161. package/bin/runners/lib/contracts/route-contract.js +199 -0
  162. package/bin/runners/lib/contracts.js +804 -0
  163. package/bin/runners/lib/default-config.js +127 -0
  164. package/bin/runners/lib/detect.js +89 -0
  165. package/bin/runners/lib/detectors-v2.js +622 -0
  166. package/bin/runners/lib/doctor/autofix.js +254 -0
  167. package/bin/runners/lib/doctor/diagnosis-receipt.js +454 -0
  168. package/bin/runners/lib/doctor/failure-signatures.js +526 -0
  169. package/bin/runners/lib/doctor/fix-script.js +336 -0
  170. package/bin/runners/lib/doctor/index.js +37 -0
  171. package/bin/runners/lib/doctor/modules/build-tools.js +453 -0
  172. package/bin/runners/lib/doctor/modules/dependencies.js +325 -0
  173. package/bin/runners/lib/doctor/modules/index.js +105 -0
  174. package/bin/runners/lib/doctor/modules/network.js +250 -0
  175. package/bin/runners/lib/doctor/modules/os-quirks.js +706 -0
  176. package/bin/runners/lib/doctor/modules/project.js +312 -0
  177. package/bin/runners/lib/doctor/modules/repo-integrity.js +485 -0
  178. package/bin/runners/lib/doctor/modules/runtime.js +224 -0
  179. package/bin/runners/lib/doctor/modules/security.js +350 -0
  180. package/bin/runners/lib/doctor/modules/system.js +213 -0
  181. package/bin/runners/lib/doctor/modules/vibecheck.js +394 -0
  182. package/bin/runners/lib/doctor/reporter.js +262 -0
  183. package/bin/runners/lib/doctor/safe-repair.js +384 -0
  184. package/bin/runners/lib/doctor/service.js +262 -0
  185. package/bin/runners/lib/doctor/types.js +113 -0
  186. package/bin/runners/lib/doctor/ui.js +263 -0
  187. package/bin/runners/lib/doctor-enhanced.js +233 -0
  188. package/bin/runners/lib/doctor-output.js +226 -0
  189. package/bin/runners/lib/doctor-v2.js +608 -0
  190. package/bin/runners/lib/drift.js +425 -0
  191. package/bin/runners/lib/enforcement.js +72 -0
  192. package/bin/runners/lib/engine/ast-cache.js +210 -0
  193. package/bin/runners/lib/engine/auth-extractor.js +211 -0
  194. package/bin/runners/lib/engine/billing-extractor.js +112 -0
  195. package/bin/runners/lib/engine/enforcement-extractor.js +100 -0
  196. package/bin/runners/lib/engine/env-extractor.js +207 -0
  197. package/bin/runners/lib/engine/express-extractor.js +208 -0
  198. package/bin/runners/lib/engine/extractors.js +849 -0
  199. package/bin/runners/lib/engine/index.js +207 -0
  200. package/bin/runners/lib/engine/repo-index.js +514 -0
  201. package/bin/runners/lib/engine/types.js +124 -0
  202. package/bin/runners/lib/engines/accessibility-engine.js +190 -0
  203. package/bin/runners/lib/engines/api-consistency-engine.js +162 -0
  204. package/bin/runners/lib/engines/ast-cache.js +99 -0
  205. package/bin/runners/lib/engines/attack-detector.js +1192 -0
  206. package/bin/runners/lib/engines/code-quality-engine.js +255 -0
  207. package/bin/runners/lib/engines/console-logs-engine.js +115 -0
  208. package/bin/runners/lib/engines/cross-file-analysis-engine.js +268 -0
  209. package/bin/runners/lib/engines/dead-code-engine.js +198 -0
  210. package/bin/runners/lib/engines/deprecated-api-engine.js +226 -0
  211. package/bin/runners/lib/engines/empty-catch-engine.js +150 -0
  212. package/bin/runners/lib/engines/file-filter.js +131 -0
  213. package/bin/runners/lib/engines/hardcoded-secrets-engine.js +251 -0
  214. package/bin/runners/lib/engines/mock-data-engine.js +272 -0
  215. package/bin/runners/lib/engines/parallel-processor.js +71 -0
  216. package/bin/runners/lib/engines/performance-issues-engine.js +265 -0
  217. package/bin/runners/lib/engines/security-vulnerabilities-engine.js +243 -0
  218. package/bin/runners/lib/engines/todo-fixme-engine.js +115 -0
  219. package/bin/runners/lib/engines/type-aware-engine.js +152 -0
  220. package/bin/runners/lib/engines/unsafe-regex-engine.js +225 -0
  221. package/bin/runners/lib/engines/vibecheck-engines/README.md +53 -0
  222. package/bin/runners/lib/engines/vibecheck-engines/index.js +15 -0
  223. package/bin/runners/lib/engines/vibecheck-engines/lib/ast-cache.js +164 -0
  224. package/bin/runners/lib/engines/vibecheck-engines/lib/code-quality-engine.js +291 -0
  225. package/bin/runners/lib/engines/vibecheck-engines/lib/console-logs-engine.js +83 -0
  226. package/bin/runners/lib/engines/vibecheck-engines/lib/dead-code-engine.js +198 -0
  227. package/bin/runners/lib/engines/vibecheck-engines/lib/deprecated-api-engine.js +275 -0
  228. package/bin/runners/lib/engines/vibecheck-engines/lib/empty-catch-engine.js +167 -0
  229. package/bin/runners/lib/engines/vibecheck-engines/lib/file-filter.js +217 -0
  230. package/bin/runners/lib/engines/vibecheck-engines/lib/hardcoded-secrets-engine.js +139 -0
  231. package/bin/runners/lib/engines/vibecheck-engines/lib/mock-data-engine.js +140 -0
  232. package/bin/runners/lib/engines/vibecheck-engines/lib/parallel-processor.js +164 -0
  233. package/bin/runners/lib/engines/vibecheck-engines/lib/performance-issues-engine.js +234 -0
  234. package/bin/runners/lib/engines/vibecheck-engines/lib/type-aware-engine.js +217 -0
  235. package/bin/runners/lib/engines/vibecheck-engines/lib/unsafe-regex-engine.js +78 -0
  236. package/bin/runners/lib/engines/vibecheck-engines/package.json +13 -0
  237. package/bin/runners/lib/enterprise-detect.js +603 -0
  238. package/bin/runners/lib/enterprise-init.js +942 -0
  239. package/bin/runners/lib/entitlements-v2.js +265 -0
  240. package/bin/runners/lib/entitlements.generated.js +0 -0
  241. package/bin/runners/lib/entitlements.js +340 -0
  242. package/bin/runners/lib/env-resolver.js +417 -0
  243. package/bin/runners/lib/env-template.js +66 -0
  244. package/bin/runners/lib/env.js +189 -0
  245. package/bin/runners/lib/error-handler.js +368 -0
  246. package/bin/runners/lib/error-messages.js +289 -0
  247. package/bin/runners/lib/evidence-pack.js +684 -0
  248. package/bin/runners/lib/exit-codes.js +275 -0
  249. package/bin/runners/lib/extractors/client-calls.js +990 -0
  250. package/bin/runners/lib/extractors/fastify-route-dump.js +573 -0
  251. package/bin/runners/lib/extractors/fastify-routes.js +426 -0
  252. package/bin/runners/lib/extractors/index.js +363 -0
  253. package/bin/runners/lib/extractors/next-routes.js +524 -0
  254. package/bin/runners/lib/extractors/proof-graph.js +431 -0
  255. package/bin/runners/lib/extractors/route-matcher.js +451 -0
  256. package/bin/runners/lib/extractors/truthpack-v2.js +377 -0
  257. package/bin/runners/lib/extractors/ui-bindings.js +547 -0
  258. package/bin/runners/lib/finding-id.js +69 -0
  259. package/bin/runners/lib/finding-sorter.js +89 -0
  260. package/bin/runners/lib/findings-schema.js +281 -0
  261. package/bin/runners/lib/fingerprint.js +377 -0
  262. package/bin/runners/lib/firewall-prompt.js +50 -0
  263. package/bin/runners/lib/fix-output.js +228 -0
  264. package/bin/runners/lib/global-flags.js +250 -0
  265. package/bin/runners/lib/graph/graph-builder.js +265 -0
  266. package/bin/runners/lib/graph/html-renderer.js +413 -0
  267. package/bin/runners/lib/graph/index.js +32 -0
  268. package/bin/runners/lib/graph/runtime-collector.js +215 -0
  269. package/bin/runners/lib/graph/static-extractor.js +518 -0
  270. package/bin/runners/lib/help-formatter.js +413 -0
  271. package/bin/runners/lib/html-proof-report.js +913 -0
  272. package/bin/runners/lib/html-report.js +650 -0
  273. package/bin/runners/lib/init-wizard.js +601 -0
  274. package/bin/runners/lib/interactive-menu.js +1496 -0
  275. package/bin/runners/lib/json-output.js +76 -0
  276. package/bin/runners/lib/llm.js +75 -0
  277. package/bin/runners/lib/logger.js +38 -0
  278. package/bin/runners/lib/meter.js +61 -0
  279. package/bin/runners/lib/missions/briefing.js +427 -0
  280. package/bin/runners/lib/missions/checkpoint.js +753 -0
  281. package/bin/runners/lib/missions/evidence.js +126 -0
  282. package/bin/runners/lib/missions/hardening.js +851 -0
  283. package/bin/runners/lib/missions/plan.js +648 -0
  284. package/bin/runners/lib/missions/safety-gates.js +645 -0
  285. package/bin/runners/lib/missions/schema.js +478 -0
  286. package/bin/runners/lib/missions/templates.js +317 -0
  287. package/bin/runners/lib/next-action.js +560 -0
  288. package/bin/runners/lib/packs/bundle.js +675 -0
  289. package/bin/runners/lib/packs/evidence-pack.js +671 -0
  290. package/bin/runners/lib/packs/pack-factory.js +837 -0
  291. package/bin/runners/lib/packs/permissions-pack.js +686 -0
  292. package/bin/runners/lib/packs/proof-graph-pack.js +779 -0
  293. package/bin/runners/lib/patch.js +40 -0
  294. package/bin/runners/lib/permissions/auth-model.js +213 -0
  295. package/bin/runners/lib/permissions/idor-prover.js +205 -0
  296. package/bin/runners/lib/permissions/index.js +45 -0
  297. package/bin/runners/lib/permissions/matrix-builder.js +198 -0
  298. package/bin/runners/lib/pkgjson.js +28 -0
  299. package/bin/runners/lib/policy.js +295 -0
  300. package/bin/runners/lib/polish/accessibility.js +62 -0
  301. package/bin/runners/lib/polish/analyzer.js +93 -0
  302. package/bin/runners/lib/polish/backend.js +87 -0
  303. package/bin/runners/lib/polish/configuration.js +83 -0
  304. package/bin/runners/lib/polish/documentation.js +83 -0
  305. package/bin/runners/lib/polish/frontend.js +817 -0
  306. package/bin/runners/lib/polish/index.js +27 -0
  307. package/bin/runners/lib/polish/infrastructure.js +80 -0
  308. package/bin/runners/lib/polish/internationalization.js +85 -0
  309. package/bin/runners/lib/polish/libraries.js +180 -0
  310. package/bin/runners/lib/polish/observability.js +75 -0
  311. package/bin/runners/lib/polish/performance.js +64 -0
  312. package/bin/runners/lib/polish/privacy.js +110 -0
  313. package/bin/runners/lib/polish/resilience.js +92 -0
  314. package/bin/runners/lib/polish/security.js +78 -0
  315. package/bin/runners/lib/polish/seo.js +71 -0
  316. package/bin/runners/lib/polish/styles.js +62 -0
  317. package/bin/runners/lib/polish/utils.js +104 -0
  318. package/bin/runners/lib/preflight.js +142 -0
  319. package/bin/runners/lib/prerequisites.js +149 -0
  320. package/bin/runners/lib/prove-output.js +220 -0
  321. package/bin/runners/lib/reality/correlation-detectors.js +359 -0
  322. package/bin/runners/lib/reality/index.js +318 -0
  323. package/bin/runners/lib/reality/request-hashing.js +416 -0
  324. package/bin/runners/lib/reality/request-mapper.js +453 -0
  325. package/bin/runners/lib/reality/safety-rails.js +463 -0
  326. package/bin/runners/lib/reality/semantic-snapshot.js +408 -0
  327. package/bin/runners/lib/reality/toast-detector.js +393 -0
  328. package/bin/runners/lib/reality-findings.js +84 -0
  329. package/bin/runners/lib/reality-output.js +231 -0
  330. package/bin/runners/lib/receipts.js +179 -0
  331. package/bin/runners/lib/redact.js +29 -0
  332. package/bin/runners/lib/replay/capsule-manager.js +154 -0
  333. package/bin/runners/lib/replay/index.js +263 -0
  334. package/bin/runners/lib/replay/player.js +348 -0
  335. package/bin/runners/lib/replay/recorder.js +331 -0
  336. package/bin/runners/lib/report-engine.js +626 -0
  337. package/bin/runners/lib/report-html.js +1233 -0
  338. package/bin/runners/lib/report-output.js +366 -0
  339. package/bin/runners/lib/report-templates.js +967 -0
  340. package/bin/runners/lib/report.js +135 -0
  341. package/bin/runners/lib/route-detection.js +1209 -0
  342. package/bin/runners/lib/route-truth.js +1322 -0
  343. package/bin/runners/lib/safelist/index.js +96 -0
  344. package/bin/runners/lib/safelist/integration.js +334 -0
  345. package/bin/runners/lib/safelist/matcher.js +696 -0
  346. package/bin/runners/lib/safelist/schema.js +948 -0
  347. package/bin/runners/lib/safelist/store.js +438 -0
  348. package/bin/runners/lib/sandbox/index.js +59 -0
  349. package/bin/runners/lib/sandbox/proof-chain.js +399 -0
  350. package/bin/runners/lib/sandbox/sandbox-runner.js +205 -0
  351. package/bin/runners/lib/sandbox/worktree.js +174 -0
  352. package/bin/runners/lib/scan-cache.js +330 -0
  353. package/bin/runners/lib/scan-output-schema.js +344 -0
  354. package/bin/runners/lib/scan-output.js +631 -0
  355. package/bin/runners/lib/scan-runner.js +135 -0
  356. package/bin/runners/lib/schema-validator.js +350 -0
  357. package/bin/runners/lib/schemas/ajv-validator.js +464 -0
  358. package/bin/runners/lib/schemas/contracts.schema.json +160 -0
  359. package/bin/runners/lib/schemas/error-envelope.schema.json +105 -0
  360. package/bin/runners/lib/schemas/finding-v3.schema.json +151 -0
  361. package/bin/runners/lib/schemas/finding.schema.json +100 -0
  362. package/bin/runners/lib/schemas/mission-pack.schema.json +206 -0
  363. package/bin/runners/lib/schemas/proof-graph.schema.json +176 -0
  364. package/bin/runners/lib/schemas/reality-report.schema.json +162 -0
  365. package/bin/runners/lib/schemas/report-artifact.schema.json +120 -0
  366. package/bin/runners/lib/schemas/run-request.schema.json +108 -0
  367. package/bin/runners/lib/schemas/share-pack.schema.json +180 -0
  368. package/bin/runners/lib/schemas/ship-manifest.schema.json +251 -0
  369. package/bin/runners/lib/schemas/ship-report.schema.json +117 -0
  370. package/bin/runners/lib/schemas/truthpack-v2.schema.json +303 -0
  371. package/bin/runners/lib/schemas/validator.js +465 -0
  372. package/bin/runners/lib/schemas/verdict.schema.json +140 -0
  373. package/bin/runners/lib/score-history.js +282 -0
  374. package/bin/runners/lib/security-bridge.js +249 -0
  375. package/bin/runners/lib/server-usage.js +513 -0
  376. package/bin/runners/lib/share-pack.js +239 -0
  377. package/bin/runners/lib/ship-gate.js +832 -0
  378. package/bin/runners/lib/ship-manifest.js +1153 -0
  379. package/bin/runners/lib/ship-output-enterprise.js +239 -0
  380. package/bin/runners/lib/ship-output.js +1128 -0
  381. package/bin/runners/lib/snippets.js +67 -0
  382. package/bin/runners/lib/status-output.js +340 -0
  383. package/bin/runners/lib/terminal-ui.js +356 -0
  384. package/bin/runners/lib/truth.js +1691 -0
  385. package/bin/runners/lib/ui.js +562 -0
  386. package/bin/runners/lib/unified-cli-output.js +947 -0
  387. package/bin/runners/lib/unified-output.js +197 -0
  388. package/bin/runners/lib/upsell.js +410 -0
  389. package/bin/runners/lib/usage.js +153 -0
  390. package/bin/runners/lib/validate-patch.js +156 -0
  391. package/bin/runners/lib/verdict-engine.js +628 -0
  392. package/bin/runners/lib/verification.js +345 -0
  393. package/bin/runners/lib/why-tree.js +650 -0
  394. package/bin/runners/reality/engine.js +917 -0
  395. package/bin/runners/reality/flows.js +122 -0
  396. package/bin/runners/reality/report.js +378 -0
  397. package/bin/runners/reality/session.js +193 -0
  398. package/bin/runners/runAIAgent.js +229 -0
  399. package/bin/runners/runAgent.d.ts +5 -0
  400. package/bin/runners/runAgent.js +161 -0
  401. package/bin/runners/runAllowlist.js +418 -0
  402. package/bin/runners/runApprove.js +320 -0
  403. package/bin/runners/runAudit.js +692 -0
  404. package/bin/runners/runAuth.js +731 -0
  405. package/bin/runners/runCI.js +353 -0
  406. package/bin/runners/runCheckpoint.js +530 -0
  407. package/bin/runners/runClassify.js +928 -0
  408. package/bin/runners/runCleanup.js +343 -0
  409. package/bin/runners/runContext.d.ts +4 -0
  410. package/bin/runners/runContext.js +175 -0
  411. package/bin/runners/runDoctor.js +877 -0
  412. package/bin/runners/runEvidencePack.js +362 -0
  413. package/bin/runners/runFirewall.d.ts +5 -0
  414. package/bin/runners/runFirewall.js +134 -0
  415. package/bin/runners/runFirewallHook.d.ts +5 -0
  416. package/bin/runners/runFirewallHook.js +56 -0
  417. package/bin/runners/runFix.js +1355 -0
  418. package/bin/runners/runForge.js +451 -0
  419. package/bin/runners/runGuard.js +262 -0
  420. package/bin/runners/runInit.js +1927 -0
  421. package/bin/runners/runIntent.js +906 -0
  422. package/bin/runners/runKickoff.js +878 -0
  423. package/bin/runners/runLabs.js +424 -0
  424. package/bin/runners/runLaunch.js +2000 -0
  425. package/bin/runners/runLink.js +785 -0
  426. package/bin/runners/runMcp.js +1875 -0
  427. package/bin/runners/runPacks.js +2089 -0
  428. package/bin/runners/runPolish.d.ts +4 -0
  429. package/bin/runners/runPolish.js +390 -0
  430. package/bin/runners/runPromptFirewall.js +211 -0
  431. package/bin/runners/runProve.js +1411 -0
  432. package/bin/runners/runQuickstart.js +531 -0
  433. package/bin/runners/runReality.js +2260 -0
  434. package/bin/runners/runReport.js +726 -0
  435. package/bin/runners/runRuntime.js +110 -0
  436. package/bin/runners/runSafelist.js +1190 -0
  437. package/bin/runners/runScan.js +688 -0
  438. package/bin/runners/runShield.js +1282 -0
  439. package/bin/runners/runShip.js +1660 -0
  440. package/bin/runners/runTruth.d.ts +5 -0
  441. package/bin/runners/runTruth.js +101 -0
  442. package/bin/runners/runValidate.js +179 -0
  443. package/bin/runners/runWatch.js +478 -0
  444. package/bin/runners/utils.js +360 -0
  445. package/bin/scan.js +617 -0
  446. package/bin/vibecheck.js +1617 -0
  447. package/dist/guardrail/index.d.ts +2405 -0
  448. package/dist/guardrail/index.js +9747 -0
  449. package/dist/guardrail/index.js.map +1 -0
  450. package/dist/scanner/index.d.ts +282 -0
  451. package/dist/scanner/index.js +3395 -0
  452. package/dist/scanner/index.js.map +1 -0
  453. package/package.json +123 -104
  454. package/README.md +0 -491
  455. package/dist/index.js +0 -99711
  456. package/dist/index.js.map +0 -1
@@ -0,0 +1,541 @@
1
+ /**
2
+ * Security Scanner Module
3
+ * Scans context for secrets, vulnerabilities, and sensitive data
4
+ * Enhanced with entropy checking and better false positive prevention
5
+ */
6
+
7
+ const fs = require("fs");
8
+ const path = require("path");
9
+ const crypto = require("crypto");
10
+
11
+ /**
12
+ * Calculate Shannon entropy of a string
13
+ * Higher entropy = more random = more likely to be a real secret
14
+ */
15
+ function calculateEntropy(str) {
16
+ if (!str || str.length === 0) return 0;
17
+
18
+ const freq = {};
19
+ for (const char of str) {
20
+ freq[char] = (freq[char] || 0) + 1;
21
+ }
22
+
23
+ let entropy = 0;
24
+ const len = str.length;
25
+ for (const count of Object.values(freq)) {
26
+ const p = count / len;
27
+ entropy -= p * Math.log2(p);
28
+ }
29
+
30
+ return entropy;
31
+ }
32
+
33
+ /**
34
+ * Check if a value is a known false positive
35
+ */
36
+ function isFalsePositive(value, line, filePath) {
37
+ const lowerValue = value.toLowerCase();
38
+ const lowerLine = line.toLowerCase();
39
+ const lowerPath = filePath.toLowerCase();
40
+
41
+ // Common placeholder/test values
42
+ const falsePositiveValues = [
43
+ 'example', 'test', 'sample', 'demo', 'placeholder', 'mock', 'fake', 'dummy',
44
+ 'your_key', 'your_secret', 'your_token', 'changeme', 'replace_me', 'xxx',
45
+ 'password', 'password123', 'secret', 'admin', '12345', 'qwerty'
46
+ ];
47
+
48
+ for (const fp of falsePositiveValues) {
49
+ if (lowerValue.includes(fp)) return true;
50
+ }
51
+
52
+ // Repeating characters (low entropy)
53
+ if (/^(.)\1{5,}$/.test(value)) return true;
54
+
55
+ // Sequential characters
56
+ if (/^(012|123|234|345|456|567|678|789|abc|bcd|cde)/i.test(value)) return true;
57
+
58
+ // Test/example context
59
+ if (lowerLine.includes('example') || lowerLine.includes('// test')) return true;
60
+ if (lowerPath.includes('.test.') || lowerPath.includes('.spec.')) return true;
61
+ if (lowerPath.includes('__tests__') || lowerPath.includes('__mocks__')) return true;
62
+ if (lowerPath.includes('/fixtures/') || lowerPath.includes('/examples/')) return true;
63
+
64
+ // Documentation context
65
+ if (lowerPath.endsWith('.md') || lowerPath.includes('/docs/')) return true;
66
+
67
+ // Env template files
68
+ if (lowerPath.includes('.env.example') || lowerPath.includes('.env.template')) return true;
69
+ if (lowerPath.includes('.env.sample')) return true;
70
+
71
+ // Type definitions
72
+ if (lowerLine.includes('type ') || lowerLine.includes('interface ')) return true;
73
+
74
+ // Import statements
75
+ if (lowerLine.startsWith('import ') || lowerLine.includes('require(')) return true;
76
+
77
+ return false;
78
+ }
79
+
80
+ /**
81
+ * Secret patterns to detect
82
+ * Each pattern now includes minEntropy for generic patterns
83
+ */
84
+ const SECRET_PATTERNS = [
85
+ // API Keys - specific formats (high confidence, no entropy check needed)
86
+ { pattern: /AIza[0-9A-Za-z_-]{35}/, type: "Google API Key", minEntropy: 3.5 },
87
+ { pattern: /AKIA[0-9A-Z]{16}/, type: "AWS Access Key", minEntropy: 3.5 },
88
+ { pattern: /xoxb-[0-9]{10,13}-[0-9]{10,13}-[a-zA-Z0-9]{24}/, type: "Slack Bot Token", minEntropy: 0 },
89
+ { pattern: /ghp_[a-zA-Z0-9]{36}/, type: "GitHub Personal Token", minEntropy: 3.5 },
90
+ { pattern: /gho_[a-zA-Z0-9]{36}/, type: "GitHub OAuth Token", minEntropy: 3.5 },
91
+ { pattern: /sk_live_[0-9a-zA-Z]{24,}/, type: "Stripe Live Key", minEntropy: 3.5 },
92
+ { pattern: /pk_live_[0-9a-zA-Z]{24,}/, type: "Stripe Publishable Key", minEntropy: 0 },
93
+
94
+ // Generic patterns - require higher entropy to avoid false positives
95
+ { pattern: /['"]?api[_-]?key['"]?\s*[:=]\s*['"]([^'"]{16,})['"]/, type: "API Key", minEntropy: 4.0, valueGroup: 1 },
96
+ { pattern: /['"]?secret[_-]?key['"]?\s*[:=]\s*['"]([^'"]{16,})['"]/, type: "Secret Key", minEntropy: 4.0, valueGroup: 1 },
97
+ { pattern: /['"]?password['"]?\s*[:=]\s*['"]([^'"]{8,})['"]/, type: "Password", minEntropy: 3.0, valueGroup: 1 },
98
+ { pattern: /['"]?auth[_-]?token['"]?\s*[:=]\s*['"]([^'"]{16,})['"]/, type: "Auth Token", minEntropy: 4.0, valueGroup: 1 },
99
+ { pattern: /['"]?private[_-]?key['"]?\s*[:=]\s*['"]([^'"]{20,})['"]/, type: "Private Key", minEntropy: 4.0, valueGroup: 1 },
100
+
101
+ // Database URLs (credentials embedded)
102
+ { pattern: /mongodb(?:\+srv)?:\/\/([^:]+):([^@]+)@/, type: "MongoDB URL", minEntropy: 0 },
103
+ { pattern: /postgres(?:ql)?:\/\/([^:]+):([^@]+)@/, type: "PostgreSQL URL", minEntropy: 0 },
104
+ { pattern: /mysql:\/\/([^:]+):([^@]+)@/, type: "MySQL URL", minEntropy: 0 },
105
+ { pattern: /redis:\/\/([^:]+):([^@]+)@/, type: "Redis URL", minEntropy: 0 },
106
+
107
+ // JWT tokens - validate structure
108
+ { pattern: /eyJ[A-Za-z0-9_-]{10,}\.eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}/, type: "JWT Token", minEntropy: 4.0 },
109
+ ];
110
+
111
+ /**
112
+ * Vulnerability patterns - refined to reduce false positives
113
+ * Each pattern now includes contextual requirements
114
+ */
115
+ const VULNERABILITY_PATTERNS = [
116
+ // SQL Injection - require concatenation with user input indicators
117
+ {
118
+ pattern: /(?:query|execute|raw)\s*\(\s*['"`](?:SELECT|INSERT|UPDATE|DELETE|DROP)\s*[^'"]*\+\s*(?:req\.|user|input|param)/i,
119
+ type: "SQL Injection",
120
+ severity: "critical",
121
+ contextExclusions: ['parameterized', 'prepared', 'placeholder']
122
+ },
123
+
124
+ // XSS - dangerouslySetInnerHTML only when value comes from user/external
125
+ {
126
+ pattern: /dangerouslySetInnerHTML\s*=\s*{{\s*__html:\s*(?:props|data|user|input|param)/,
127
+ type: "XSS Risk",
128
+ severity: "high",
129
+ contextExclusions: ['sanitize', 'DOMPurify', 'escape']
130
+ },
131
+ // innerHTML with dynamic content
132
+ {
133
+ pattern: /\.innerHTML\s*=\s*(?:[^'";\n]*\+|`[^`]*\$\{)/,
134
+ type: "XSS Risk",
135
+ severity: "high",
136
+ contextExclusions: ['sanitize', 'escape', 'encode']
137
+ },
138
+ // document.write with variables
139
+ {
140
+ pattern: /document\.write\s*\([^)]*(?:\+|\$\{)/,
141
+ type: "XSS Risk",
142
+ severity: "high"
143
+ },
144
+
145
+ // Path Traversal - only flag when path comes from user input
146
+ {
147
+ pattern: /(?:readFile|readdir|open|access)\s*\([^)]*(?:req\.|user|input|param)[^)]*\)/,
148
+ type: "Path Traversal",
149
+ severity: "high",
150
+ contextExclusions: ['path.join', 'path.resolve', 'normalize', 'sanitize']
151
+ },
152
+
153
+ // Insecure Crypto - only for password/credential hashing, not checksums
154
+ {
155
+ pattern: /(?:createHash|crypto)\s*\(\s*['"](?:md5|sha1)['"]\s*\)[^;]*(?:password|credential|secret)/i,
156
+ type: "Weak Password Hash",
157
+ severity: "high",
158
+ contextExclusions: ['checksum', 'fingerprint', 'etag', 'cache']
159
+ },
160
+
161
+ // Hardcoded credentials - more specific patterns
162
+ {
163
+ pattern: /(?:password|passwd|pwd)\s*[:=]\s*['"][^'"]{4,}['"]\s*(?:,|;|$)/,
164
+ type: "Hardcoded Credentials",
165
+ severity: "high",
166
+ contextExclusions: ['process.env', 'config.', 'example', 'test', 'placeholder']
167
+ },
168
+
169
+ // Sensitive data in logs - only when logging actual variables
170
+ {
171
+ pattern: /console\.(?:log|info|debug)\s*\([^)]*(?:password|secret|token|apiKey|auth)[^)]*\)/,
172
+ type: "Sensitive Data in Log",
173
+ severity: "high",
174
+ contextExclusions: ['masked', 'redacted', '***', '[REDACTED]']
175
+ },
176
+
177
+ // Eval with dynamic content
178
+ {
179
+ pattern: /\beval\s*\([^)]*(?:\+|`\$\{|concat)/,
180
+ type: "Code Injection",
181
+ severity: "critical"
182
+ },
183
+
184
+ // Insecure random for security purposes
185
+ {
186
+ pattern: /Math\.random\s*\(\s*\)[^;]*(?:token|secret|key|password|salt|nonce)/i,
187
+ type: "Insecure Random",
188
+ severity: "high"
189
+ },
190
+ ];
191
+
192
+ /**
193
+ * Find files recursively
194
+ */
195
+ function findFiles(dir, extensions, maxDepth = 5, currentDepth = 0) {
196
+ if (currentDepth >= maxDepth || !fs.existsSync(dir)) return [];
197
+
198
+ const files = [];
199
+ try {
200
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
201
+ for (const entry of entries) {
202
+ const fullPath = path.join(dir, entry.name);
203
+ if (entry.isDirectory() && !entry.name.startsWith(".") && entry.name !== "node_modules") {
204
+ files.push(...findFiles(fullPath, extensions, maxDepth, currentDepth + 1));
205
+ } else if (entry.isFile() && extensions.some(ext => entry.name.endsWith(ext))) {
206
+ files.push(fullPath);
207
+ }
208
+ }
209
+ } catch {}
210
+ return files;
211
+ }
212
+
213
+ /**
214
+ * Scan file for secrets with entropy checking and false positive filtering
215
+ */
216
+ function scanForSecrets(content, filePath) {
217
+ const secrets = [];
218
+ const lines = content.split("\n");
219
+ const relativePath = path.relative(process.cwd(), filePath).replace(/\\/g, "/");
220
+
221
+ // Skip known safe file types
222
+ if (/\.(md|txt|svg|png|jpg|gif|ico|woff|woff2|ttf|eot|map)$/i.test(filePath)) {
223
+ return secrets;
224
+ }
225
+
226
+ for (const patternDef of SECRET_PATTERNS) {
227
+ const regex = new RegExp(patternDef.pattern.source, 'gi');
228
+ let match;
229
+
230
+ while ((match = regex.exec(content)) !== null) {
231
+ const lineNum = content.substring(0, match.index).split("\n").length;
232
+ const line = lines[lineNum - 1] || '';
233
+
234
+ // Extract the actual secret value (use valueGroup if specified)
235
+ const secretValue = patternDef.valueGroup !== undefined
236
+ ? (match[patternDef.valueGroup] || match[0])
237
+ : match[0];
238
+
239
+ // Check for false positives first
240
+ if (isFalsePositive(secretValue, line, filePath)) {
241
+ continue;
242
+ }
243
+
244
+ // Check entropy if required
245
+ if (patternDef.minEntropy && patternDef.minEntropy > 0) {
246
+ const entropy = calculateEntropy(secretValue);
247
+ if (entropy < patternDef.minEntropy) {
248
+ continue; // Too low entropy, likely not a real secret
249
+ }
250
+ }
251
+
252
+ // Additional validation for specific types
253
+ if (patternDef.type === "JWT Token") {
254
+ // Validate JWT structure
255
+ const parts = secretValue.split('.');
256
+ if (parts.length !== 3) continue;
257
+ // Check if header looks valid (should be base64 JSON starting with eyJ)
258
+ try {
259
+ const header = Buffer.from(parts[0], 'base64url').toString();
260
+ if (!header.includes('{') || !header.includes('alg')) continue;
261
+ } catch {
262
+ continue;
263
+ }
264
+ }
265
+
266
+ secrets.push({
267
+ type: patternDef.type,
268
+ file: relativePath,
269
+ line: lineNum,
270
+ content: maskSensitiveLine(line.trim()),
271
+ severity: getSeverity(patternDef.type),
272
+ entropy: calculateEntropy(secretValue).toFixed(2),
273
+ });
274
+ }
275
+ }
276
+
277
+ return secrets;
278
+ }
279
+
280
+ /**
281
+ * Mask sensitive values in the line for safe display
282
+ */
283
+ function maskSensitiveLine(line) {
284
+ // Mask potential secret values (keep first 4 and last 4 chars if long enough)
285
+ return line.replace(/(['"])[A-Za-z0-9_\-/+=]{12,}(['"])/g, (match, q1, q2) => {
286
+ const inner = match.slice(1, -1);
287
+ if (inner.length > 12) {
288
+ return `${q1}${inner.slice(0, 4)}****${inner.slice(-4)}${q2}`;
289
+ }
290
+ return `${q1}****${q2}`;
291
+ });
292
+ }
293
+
294
+ /**
295
+ * Get severity based on secret type
296
+ */
297
+ function getSeverity(type) {
298
+ const criticalTypes = [
299
+ "AWS Access Key", "Stripe Live Key", "GitHub Personal Token",
300
+ "GitHub OAuth Token", "Private Key", "Secret Key"
301
+ ];
302
+ const highTypes = [
303
+ "Google API Key", "Slack Bot Token", "MongoDB URL",
304
+ "PostgreSQL URL", "MySQL URL", "Redis URL", "Password", "Auth Token"
305
+ ];
306
+
307
+ if (criticalTypes.includes(type)) return "critical";
308
+ if (highTypes.includes(type)) return "high";
309
+ return "medium";
310
+ }
311
+
312
+ /**
313
+ * Scan file for vulnerabilities with context-aware filtering
314
+ */
315
+ function scanForVulnerabilities(content, filePath) {
316
+ const vulnerabilities = [];
317
+ const lines = content.split("\n");
318
+ const relativePath = path.relative(process.cwd(), filePath).replace(/\\/g, "/");
319
+ const lowerPath = relativePath.toLowerCase();
320
+
321
+ // Skip test files for vulnerability scanning (tests often contain intentional "bad" patterns)
322
+ if (lowerPath.includes('.test.') || lowerPath.includes('.spec.') ||
323
+ lowerPath.includes('__tests__') || lowerPath.includes('__mocks__')) {
324
+ return vulnerabilities;
325
+ }
326
+
327
+ // Skip documentation and examples
328
+ if (lowerPath.endsWith('.md') || lowerPath.includes('/docs/') ||
329
+ lowerPath.includes('/examples/')) {
330
+ return vulnerabilities;
331
+ }
332
+
333
+ for (const patternDef of VULNERABILITY_PATTERNS) {
334
+ const regex = new RegExp(patternDef.pattern.source, 'gi');
335
+ let match;
336
+
337
+ while ((match = regex.exec(content)) !== null) {
338
+ const lineNum = content.substring(0, match.index).split("\n").length;
339
+ const line = lines[lineNum - 1] || '';
340
+ const lowerLine = line.toLowerCase();
341
+
342
+ // Check context exclusions - skip if any exclusion pattern is present
343
+ if (patternDef.contextExclusions) {
344
+ const excluded = patternDef.contextExclusions.some(exclusion =>
345
+ lowerLine.includes(exclusion.toLowerCase())
346
+ );
347
+ if (excluded) continue;
348
+ }
349
+
350
+ // Skip if the line is a comment
351
+ const trimmedLine = line.trim();
352
+ if (trimmedLine.startsWith('//') || trimmedLine.startsWith('/*') ||
353
+ trimmedLine.startsWith('*') || trimmedLine.startsWith('#')) {
354
+ continue;
355
+ }
356
+
357
+ // Skip if in a multi-line comment context
358
+ const beforeMatch = content.substring(0, match.index);
359
+ const lastCommentStart = beforeMatch.lastIndexOf('/*');
360
+ const lastCommentEnd = beforeMatch.lastIndexOf('*/');
361
+ if (lastCommentStart > lastCommentEnd) {
362
+ continue; // We're inside a multi-line comment
363
+ }
364
+
365
+ vulnerabilities.push({
366
+ type: patternDef.type,
367
+ file: relativePath,
368
+ line: lineNum,
369
+ content: trimmedLine.substring(0, 100), // Limit line length
370
+ severity: patternDef.severity || "medium",
371
+ recommendation: getRecommendation(patternDef.type),
372
+ });
373
+ }
374
+ }
375
+
376
+ return vulnerabilities;
377
+ }
378
+
379
+ /**
380
+ * Get recommendation for vulnerability type
381
+ */
382
+ function getRecommendation(type) {
383
+ const recommendations = {
384
+ "SQL Injection": "Use parameterized queries or prepared statements. Never concatenate user input into SQL.",
385
+ "XSS Risk": "Sanitize user input with DOMPurify or similar. Use textContent instead of innerHTML when possible.",
386
+ "Path Traversal": "Validate and sanitize file paths. Use path.join() and verify paths don't escape the base directory.",
387
+ "Weak Password Hash": "Use bcrypt, Argon2, or scrypt for password hashing. MD5/SHA1 are cryptographically broken.",
388
+ "Hardcoded Credentials": "Use environment variables or a secrets manager. Never commit credentials to version control.",
389
+ "Sensitive Data in Log": "Remove or mask sensitive data before logging. Use structured logging with redaction.",
390
+ "Code Injection": "Never use eval() with user input. Consider safer alternatives like JSON.parse() or a sandboxed environment.",
391
+ "Insecure Random": "Use crypto.randomBytes() or crypto.randomUUID() for security-sensitive random values.",
392
+ };
393
+
394
+ return recommendations[type] || "Review and fix the security issue";
395
+ }
396
+
397
+ /**
398
+ * Scan project for security issues
399
+ */
400
+ function scanProject(projectPath) {
401
+ const files = findFiles(projectPath, [".ts", ".tsx", ".js", ".jsx", ".json", ".env*", ".yml", ".yaml"], 5);
402
+
403
+ const results = {
404
+ secrets: [],
405
+ vulnerabilities: [],
406
+ stats: {
407
+ totalFiles: files.length,
408
+ filesWithSecrets: 0,
409
+ filesWithVulnerabilities: 0,
410
+ criticalIssues: 0,
411
+ highIssues: 0,
412
+ mediumIssues: 0,
413
+ },
414
+ scanned: new Date().toISOString(),
415
+ };
416
+
417
+ for (const file of files) {
418
+ try {
419
+ const content = fs.readFileSync(file, "utf-8");
420
+ const relativePath = path.relative(projectPath, file).replace(/\\/g, "/");
421
+
422
+ // Skip certain files
423
+ if (relativePath.includes("node_modules") ||
424
+ relativePath.includes(".git") ||
425
+ relativePath.includes("dist/") ||
426
+ relativePath.includes("build/")) {
427
+ continue;
428
+ }
429
+
430
+ const secrets = scanForSecrets(content, file);
431
+ const vulnerabilities = scanForVulnerabilities(content, file);
432
+
433
+ if (secrets.length > 0) {
434
+ results.secrets.push(...secrets);
435
+ results.stats.filesWithSecrets++;
436
+ }
437
+
438
+ if (vulnerabilities.length > 0) {
439
+ results.vulnerabilities.push(...vulnerabilities);
440
+ results.stats.filesWithVulnerabilities++;
441
+ }
442
+
443
+ // Count severity
444
+ for (const issue of [...secrets, ...vulnerabilities]) {
445
+ switch (issue.severity) {
446
+ case "critical":
447
+ results.stats.criticalIssues++;
448
+ break;
449
+ case "high":
450
+ results.stats.highIssues++;
451
+ break;
452
+ case "medium":
453
+ results.stats.mediumIssues++;
454
+ break;
455
+ }
456
+ }
457
+ } catch {}
458
+ }
459
+
460
+ return results;
461
+ }
462
+
463
+ /**
464
+ * Generate security report
465
+ */
466
+ function generateSecurityReport(results) {
467
+ let report = `# Security Scan Report\n\n`;
468
+ report += `Scanned: ${new Date(results.scanned).toLocaleString()}\n`;
469
+ report += `Total Files: ${results.stats.totalFiles}\n\n`;
470
+
471
+ // Summary
472
+ report += `## Summary\n\n`;
473
+ report += `- Files with Secrets: ${results.stats.filesWithSecrets}\n`;
474
+ report += `- Files with Vulnerabilities: ${results.stats.filesWithVulnerabilities}\n`;
475
+ report += `- Critical Issues: ${results.stats.criticalIssues}\n`;
476
+ report += `- High Issues: ${results.stats.highIssues}\n`;
477
+ report += `- Medium Issues: ${results.stats.mediumIssues}\n\n`;
478
+
479
+ // Secrets
480
+ if (results.secrets.length > 0) {
481
+ report += `## 🔑 Secrets Found (${results.secrets.length})\n\n`;
482
+ for (const secret of results.secrets) {
483
+ report += `### ${secret.type} - ${secret.file}:${secret.line}\n`;
484
+ report += `\`\`\`\n${secret.content}\n\`\`\`\n\n`;
485
+ }
486
+ }
487
+
488
+ // Vulnerabilities
489
+ if (results.vulnerabilities.length > 0) {
490
+ report += `## 🚨 Vulnerabilities Found (${results.vulnerabilities.length})\n\n`;
491
+ for (const vuln of results.vulnerabilities) {
492
+ const icon = vuln.severity === "critical" ? "🔴" :
493
+ vuln.severity === "high" ? "🟠" : "🟡";
494
+ report += `### ${icon} ${vuln.type} - ${vuln.file}:${vuln.line}\n`;
495
+ report += `**Severity:** ${vuln.severity}\n`;
496
+ report += `**Recommendation:** ${vuln.recommendation}\n\n`;
497
+ report += `\`\`\`\n${vuln.content}\n\`\`\`\n\n`;
498
+ }
499
+ }
500
+
501
+ if (results.secrets.length === 0 && results.vulnerabilities.length === 0) {
502
+ report += `## ✅ No Security Issues Found\n\n`;
503
+ report += `Great job! No secrets or obvious vulnerabilities were detected.\n`;
504
+ }
505
+
506
+ return report;
507
+ }
508
+
509
+ /**
510
+ * Filter content for safe AI consumption
511
+ */
512
+ function filterForAI(content) {
513
+ let filtered = content;
514
+
515
+ // Remove detected secrets
516
+ for (const pattern of SECRET_PATTERNS) {
517
+ filtered = filtered.replace(pattern.pattern, "[REDACTED_SECRET]");
518
+ }
519
+
520
+ // Remove sensitive lines
521
+ const lines = filtered.split("\n");
522
+ const safeLines = lines.filter(line => {
523
+ const lower = line.toLowerCase();
524
+ return !lower.includes("password") &&
525
+ !lower.includes("secret") &&
526
+ !lower.includes("private_key") &&
527
+ !lower.includes("api_key") &&
528
+ !line.includes("console.log") &&
529
+ !line.includes("debugger");
530
+ });
531
+
532
+ return safeLines.join("\n");
533
+ }
534
+
535
+ module.exports = {
536
+ scanProject,
537
+ generateSecurityReport,
538
+ filterForAI,
539
+ SECRET_PATTERNS,
540
+ VULNERABILITY_PATTERNS,
541
+ };