@kevinrabun/judges-cli 3.124.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 (1745) hide show
  1. package/README.md +24 -0
  2. package/agents/accessibility.judge.md +44 -0
  3. package/agents/agent-instructions.judge.md +44 -0
  4. package/agents/ai-code-safety.judge.md +55 -0
  5. package/agents/api-contract.judge.md +37 -0
  6. package/agents/api-design.judge.md +55 -0
  7. package/agents/authentication.judge.md +61 -0
  8. package/agents/backwards-compatibility.judge.md +44 -0
  9. package/agents/caching.judge.md +44 -0
  10. package/agents/ci-cd.judge.md +44 -0
  11. package/agents/cloud-readiness.judge.md +51 -0
  12. package/agents/code-structure.judge.md +48 -0
  13. package/agents/compliance.judge.md +47 -0
  14. package/agents/concurrency.judge.md +46 -0
  15. package/agents/configuration-management.judge.md +44 -0
  16. package/agents/cost-effectiveness.judge.md +40 -0
  17. package/agents/cybersecurity.judge.md +61 -0
  18. package/agents/data-security.judge.md +48 -0
  19. package/agents/data-sovereignty.judge.md +58 -0
  20. package/agents/database.judge.md +49 -0
  21. package/agents/dependency-health.judge.md +46 -0
  22. package/agents/documentation.judge.md +53 -0
  23. package/agents/error-handling.judge.md +53 -0
  24. package/agents/ethics-bias.judge.md +46 -0
  25. package/agents/false-positive-review.judge.md +85 -0
  26. package/agents/framework-safety.judge.md +47 -0
  27. package/agents/hallucination-detection.judge.md +46 -0
  28. package/agents/iac-security.judge.md +45 -0
  29. package/agents/intent-alignment.judge.md +44 -0
  30. package/agents/internationalization.judge.md +42 -0
  31. package/agents/logging-privacy.judge.md +44 -0
  32. package/agents/logic-review.judge.md +34 -0
  33. package/agents/maintainability.judge.md +44 -0
  34. package/agents/model-fingerprint.judge.md +31 -0
  35. package/agents/multi-turn-coherence.judge.md +36 -0
  36. package/agents/observability.judge.md +52 -0
  37. package/agents/over-engineering.judge.md +48 -0
  38. package/agents/performance.judge.md +44 -0
  39. package/agents/portability.judge.md +44 -0
  40. package/agents/rate-limiting.judge.md +53 -0
  41. package/agents/reliability.judge.md +55 -0
  42. package/agents/scalability.judge.md +50 -0
  43. package/agents/security.judge.md +62 -0
  44. package/agents/software-practices.judge.md +54 -0
  45. package/agents/testing.judge.md +52 -0
  46. package/agents/ux.judge.md +44 -0
  47. package/bin/judges.js +8 -0
  48. package/dist/a2a-protocol.d.ts +136 -0
  49. package/dist/a2a-protocol.js +218 -0
  50. package/dist/agent-loader.d.ts +107 -0
  51. package/dist/agent-loader.js +260 -0
  52. package/dist/api.d.ts +169 -0
  53. package/dist/api.js +195 -0
  54. package/dist/ast/cross-file-taint.d.ts +42 -0
  55. package/dist/ast/cross-file-taint.js +679 -0
  56. package/dist/ast/index.d.ts +25 -0
  57. package/dist/ast/index.js +148 -0
  58. package/dist/ast/structural-parser.d.ts +2 -0
  59. package/dist/ast/structural-parser.js +756 -0
  60. package/dist/ast/taint-tracker.d.ts +48 -0
  61. package/dist/ast/taint-tracker.js +1033 -0
  62. package/dist/ast/tree-sitter-ast.d.ts +33 -0
  63. package/dist/ast/tree-sitter-ast.js +1164 -0
  64. package/dist/ast/types.d.ts +50 -0
  65. package/dist/ast/types.js +7 -0
  66. package/dist/audit-trail.d.ts +245 -0
  67. package/dist/audit-trail.js +257 -0
  68. package/dist/auto-tune.d.ts +146 -0
  69. package/dist/auto-tune.js +373 -0
  70. package/dist/cache.d.ts +53 -0
  71. package/dist/cache.js +86 -0
  72. package/dist/calibration.d.ts +108 -0
  73. package/dist/calibration.js +219 -0
  74. package/dist/cli-dispatch.d.ts +7 -0
  75. package/dist/cli-dispatch.js +654 -0
  76. package/dist/cli-formatters.d.ts +6 -0
  77. package/dist/cli-formatters.js +186 -0
  78. package/dist/cli-helpers.d.ts +29 -0
  79. package/dist/cli-helpers.js +129 -0
  80. package/dist/cli.d.ts +30 -0
  81. package/dist/cli.js +1487 -0
  82. package/dist/commands/adoption-report.d.ts +7 -0
  83. package/dist/commands/adoption-report.js +218 -0
  84. package/dist/commands/adoption-track.d.ts +4 -0
  85. package/dist/commands/adoption-track.js +246 -0
  86. package/dist/commands/ai-gate.d.ts +7 -0
  87. package/dist/commands/ai-gate.js +212 -0
  88. package/dist/commands/ai-model-trust.d.ts +16 -0
  89. package/dist/commands/ai-model-trust.js +234 -0
  90. package/dist/commands/ai-output-compare.d.ts +8 -0
  91. package/dist/commands/ai-output-compare.js +202 -0
  92. package/dist/commands/ai-pattern-trend.d.ts +8 -0
  93. package/dist/commands/ai-pattern-trend.js +223 -0
  94. package/dist/commands/ai-prompt-audit.d.ts +22 -0
  95. package/dist/commands/ai-prompt-audit.js +254 -0
  96. package/dist/commands/ai-provenance.d.ts +4 -0
  97. package/dist/commands/ai-provenance.js +247 -0
  98. package/dist/commands/api-audit.d.ts +8 -0
  99. package/dist/commands/api-audit.js +359 -0
  100. package/dist/commands/api-misuse.d.ts +4 -0
  101. package/dist/commands/api-misuse.js +260 -0
  102. package/dist/commands/api-versioning-audit.d.ts +5 -0
  103. package/dist/commands/api-versioning-audit.js +233 -0
  104. package/dist/commands/approve-chain.d.ts +7 -0
  105. package/dist/commands/approve-chain.js +234 -0
  106. package/dist/commands/arch-audit.d.ts +8 -0
  107. package/dist/commands/arch-audit.js +283 -0
  108. package/dist/commands/assertion-density.d.ts +4 -0
  109. package/dist/commands/assertion-density.js +263 -0
  110. package/dist/commands/assign-findings.d.ts +36 -0
  111. package/dist/commands/assign-findings.js +177 -0
  112. package/dist/commands/async-safety.d.ts +4 -0
  113. package/dist/commands/async-safety.js +266 -0
  114. package/dist/commands/audit-bundle.d.ts +28 -0
  115. package/dist/commands/audit-bundle.js +234 -0
  116. package/dist/commands/audit-trail.d.ts +17 -0
  117. package/dist/commands/audit-trail.js +154 -0
  118. package/dist/commands/auto-approve.d.ts +4 -0
  119. package/dist/commands/auto-approve.js +188 -0
  120. package/dist/commands/auto-calibrate.d.ts +14 -0
  121. package/dist/commands/auto-calibrate.js +106 -0
  122. package/dist/commands/auto-detect.d.ts +61 -0
  123. package/dist/commands/auto-detect.js +328 -0
  124. package/dist/commands/auto-fix.d.ts +17 -0
  125. package/dist/commands/auto-fix.js +240 -0
  126. package/dist/commands/auto-triage.d.ts +31 -0
  127. package/dist/commands/auto-triage.js +125 -0
  128. package/dist/commands/baseline.d.ts +47 -0
  129. package/dist/commands/baseline.js +353 -0
  130. package/dist/commands/batch-review.d.ts +4 -0
  131. package/dist/commands/batch-review.js +180 -0
  132. package/dist/commands/benchmark-advanced.d.ts +14 -0
  133. package/dist/commands/benchmark-advanced.js +5057 -0
  134. package/dist/commands/benchmark-ai-agents.d.ts +8 -0
  135. package/dist/commands/benchmark-ai-agents.js +4123 -0
  136. package/dist/commands/benchmark-ai-output.d.ts +9 -0
  137. package/dist/commands/benchmark-ai-output.js +365 -0
  138. package/dist/commands/benchmark-compliance-ethics.d.ts +8 -0
  139. package/dist/commands/benchmark-compliance-ethics.js +3060 -0
  140. package/dist/commands/benchmark-expanded-2.d.ts +12 -0
  141. package/dist/commands/benchmark-expanded-2.js +5530 -0
  142. package/dist/commands/benchmark-expanded.d.ts +12 -0
  143. package/dist/commands/benchmark-expanded.js +2599 -0
  144. package/dist/commands/benchmark-infrastructure.d.ts +8 -0
  145. package/dist/commands/benchmark-infrastructure.js +2882 -0
  146. package/dist/commands/benchmark-languages.d.ts +8 -0
  147. package/dist/commands/benchmark-languages.js +1963 -0
  148. package/dist/commands/benchmark-quality-ops.d.ts +8 -0
  149. package/dist/commands/benchmark-quality-ops.js +3415 -0
  150. package/dist/commands/benchmark-security-deep.d.ts +9 -0
  151. package/dist/commands/benchmark-security-deep.js +2335 -0
  152. package/dist/commands/benchmark.d.ts +233 -0
  153. package/dist/commands/benchmark.js +3214 -0
  154. package/dist/commands/blame-review.d.ts +4 -0
  155. package/dist/commands/blame-review.js +266 -0
  156. package/dist/commands/boundary-enforce.d.ts +5 -0
  157. package/dist/commands/boundary-enforce.js +255 -0
  158. package/dist/commands/build-optimize.d.ts +6 -0
  159. package/dist/commands/build-optimize.js +256 -0
  160. package/dist/commands/burndown.d.ts +26 -0
  161. package/dist/commands/burndown.js +179 -0
  162. package/dist/commands/cache-audit.d.ts +4 -0
  163. package/dist/commands/cache-audit.js +219 -0
  164. package/dist/commands/calibration-dashboard.d.ts +1 -0
  165. package/dist/commands/calibration-dashboard.js +294 -0
  166. package/dist/commands/calibration-share.d.ts +30 -0
  167. package/dist/commands/calibration-share.js +182 -0
  168. package/dist/commands/chat-notify.d.ts +8 -0
  169. package/dist/commands/chat-notify.js +258 -0
  170. package/dist/commands/ci-template.d.ts +14 -0
  171. package/dist/commands/ci-template.js +211 -0
  172. package/dist/commands/ci-templates.d.ts +9 -0
  173. package/dist/commands/ci-templates.js +89 -0
  174. package/dist/commands/clarity-score.d.ts +8 -0
  175. package/dist/commands/clarity-score.js +260 -0
  176. package/dist/commands/clone-detect.d.ts +4 -0
  177. package/dist/commands/clone-detect.js +232 -0
  178. package/dist/commands/coach-mode.d.ts +7 -0
  179. package/dist/commands/coach-mode.js +229 -0
  180. package/dist/commands/code-health.d.ts +4 -0
  181. package/dist/commands/code-health.js +195 -0
  182. package/dist/commands/code-owner-suggest.d.ts +16 -0
  183. package/dist/commands/code-owner-suggest.js +214 -0
  184. package/dist/commands/code-similarity.d.ts +8 -0
  185. package/dist/commands/code-similarity.js +231 -0
  186. package/dist/commands/comment-drift.d.ts +4 -0
  187. package/dist/commands/comment-drift.js +228 -0
  188. package/dist/commands/commit-hygiene.d.ts +5 -0
  189. package/dist/commands/commit-hygiene.js +175 -0
  190. package/dist/commands/community-patterns.d.ts +1 -0
  191. package/dist/commands/community-patterns.js +131 -0
  192. package/dist/commands/compare-runs.d.ts +37 -0
  193. package/dist/commands/compare-runs.js +228 -0
  194. package/dist/commands/completion-audit.d.ts +4 -0
  195. package/dist/commands/completion-audit.js +296 -0
  196. package/dist/commands/completions.d.ts +1 -0
  197. package/dist/commands/completions.js +257 -0
  198. package/dist/commands/compliance-map.d.ts +8 -0
  199. package/dist/commands/compliance-map.js +374 -0
  200. package/dist/commands/compliance-report.d.ts +34 -0
  201. package/dist/commands/compliance-report.js +161 -0
  202. package/dist/commands/compliance-weight.d.ts +8 -0
  203. package/dist/commands/compliance-weight.js +272 -0
  204. package/dist/commands/config-drift.d.ts +24 -0
  205. package/dist/commands/config-drift.js +213 -0
  206. package/dist/commands/config-lint.d.ts +4 -0
  207. package/dist/commands/config-lint.js +187 -0
  208. package/dist/commands/config-migrate.d.ts +43 -0
  209. package/dist/commands/config-migrate.js +240 -0
  210. package/dist/commands/config-share.d.ts +95 -0
  211. package/dist/commands/config-share.js +406 -0
  212. package/dist/commands/context-blind.d.ts +4 -0
  213. package/dist/commands/context-blind.js +272 -0
  214. package/dist/commands/context-inject.d.ts +8 -0
  215. package/dist/commands/context-inject.js +211 -0
  216. package/dist/commands/contract-verify.d.ts +4 -0
  217. package/dist/commands/contract-verify.js +316 -0
  218. package/dist/commands/correlate.d.ts +27 -0
  219. package/dist/commands/correlate.js +241 -0
  220. package/dist/commands/cost-forecast.d.ts +18 -0
  221. package/dist/commands/cost-forecast.js +193 -0
  222. package/dist/commands/coverage-map.d.ts +22 -0
  223. package/dist/commands/coverage-map.js +222 -0
  224. package/dist/commands/coverage.d.ts +40 -0
  225. package/dist/commands/coverage.js +147 -0
  226. package/dist/commands/cross-file-consistency.d.ts +4 -0
  227. package/dist/commands/cross-file-consistency.js +254 -0
  228. package/dist/commands/cross-pr-regression.d.ts +8 -0
  229. package/dist/commands/cross-pr-regression.js +297 -0
  230. package/dist/commands/custom-rule.d.ts +4 -0
  231. package/dist/commands/custom-rule.js +210 -0
  232. package/dist/commands/dead-code-detect.d.ts +4 -0
  233. package/dist/commands/dead-code-detect.js +255 -0
  234. package/dist/commands/dedup-report.d.ts +12 -0
  235. package/dist/commands/dedup-report.js +137 -0
  236. package/dist/commands/dep-audit.d.ts +52 -0
  237. package/dist/commands/dep-audit.js +277 -0
  238. package/dist/commands/dep-correlate.d.ts +8 -0
  239. package/dist/commands/dep-correlate.js +207 -0
  240. package/dist/commands/deploy-readiness.d.ts +5 -0
  241. package/dist/commands/deploy-readiness.js +211 -0
  242. package/dist/commands/deprecated.d.ts +47 -0
  243. package/dist/commands/deprecated.js +201 -0
  244. package/dist/commands/deps.d.ts +5 -0
  245. package/dist/commands/deps.js +122 -0
  246. package/dist/commands/design-audit.d.ts +8 -0
  247. package/dist/commands/design-audit.js +301 -0
  248. package/dist/commands/dev-score.d.ts +36 -0
  249. package/dist/commands/dev-score.js +203 -0
  250. package/dist/commands/diff-explain.d.ts +4 -0
  251. package/dist/commands/diff-explain.js +142 -0
  252. package/dist/commands/diff-only.d.ts +33 -0
  253. package/dist/commands/diff-only.js +151 -0
  254. package/dist/commands/diff-review.d.ts +4 -0
  255. package/dist/commands/diff-review.js +190 -0
  256. package/dist/commands/diff.d.ts +6 -0
  257. package/dist/commands/diff.js +449 -0
  258. package/dist/commands/digest.d.ts +19 -0
  259. package/dist/commands/digest.js +221 -0
  260. package/dist/commands/doc-drift.d.ts +8 -0
  261. package/dist/commands/doc-drift.js +258 -0
  262. package/dist/commands/doc-gen.d.ts +7 -0
  263. package/dist/commands/doc-gen.js +208 -0
  264. package/dist/commands/docs.d.ts +1 -0
  265. package/dist/commands/docs.js +156 -0
  266. package/dist/commands/doctor.d.ts +55 -0
  267. package/dist/commands/doctor.js +362 -0
  268. package/dist/commands/encoding-safety.d.ts +4 -0
  269. package/dist/commands/encoding-safety.js +275 -0
  270. package/dist/commands/error-taxonomy.d.ts +5 -0
  271. package/dist/commands/error-taxonomy.js +226 -0
  272. package/dist/commands/error-ux.d.ts +4 -0
  273. package/dist/commands/error-ux.js +252 -0
  274. package/dist/commands/event-leak.d.ts +4 -0
  275. package/dist/commands/event-leak.js +262 -0
  276. package/dist/commands/evidence-chain.d.ts +4 -0
  277. package/dist/commands/evidence-chain.js +309 -0
  278. package/dist/commands/example-leak.d.ts +4 -0
  279. package/dist/commands/example-leak.js +232 -0
  280. package/dist/commands/exception-consistency.d.ts +6 -0
  281. package/dist/commands/exception-consistency.js +192 -0
  282. package/dist/commands/exec-report.d.ts +8 -0
  283. package/dist/commands/exec-report.js +271 -0
  284. package/dist/commands/explain-finding.d.ts +7 -0
  285. package/dist/commands/explain-finding.js +278 -0
  286. package/dist/commands/false-negatives.d.ts +34 -0
  287. package/dist/commands/false-negatives.js +165 -0
  288. package/dist/commands/feedback-rules.d.ts +28 -0
  289. package/dist/commands/feedback-rules.js +173 -0
  290. package/dist/commands/feedback.d.ts +182 -0
  291. package/dist/commands/feedback.js +550 -0
  292. package/dist/commands/finding-age-analysis.d.ts +4 -0
  293. package/dist/commands/finding-age-analysis.js +144 -0
  294. package/dist/commands/finding-age-report.d.ts +4 -0
  295. package/dist/commands/finding-age-report.js +154 -0
  296. package/dist/commands/finding-age-tracker.d.ts +7 -0
  297. package/dist/commands/finding-age-tracker.js +152 -0
  298. package/dist/commands/finding-age.d.ts +4 -0
  299. package/dist/commands/finding-age.js +145 -0
  300. package/dist/commands/finding-ancestry-trace.d.ts +1 -0
  301. package/dist/commands/finding-ancestry-trace.js +69 -0
  302. package/dist/commands/finding-annotation-export.d.ts +1 -0
  303. package/dist/commands/finding-annotation-export.js +97 -0
  304. package/dist/commands/finding-annotation-layer.d.ts +4 -0
  305. package/dist/commands/finding-annotation-layer.js +128 -0
  306. package/dist/commands/finding-auto-categorize.d.ts +1 -0
  307. package/dist/commands/finding-auto-categorize.js +109 -0
  308. package/dist/commands/finding-auto-fix-suggest.d.ts +1 -0
  309. package/dist/commands/finding-auto-fix-suggest.js +76 -0
  310. package/dist/commands/finding-auto-fix.d.ts +4 -0
  311. package/dist/commands/finding-auto-fix.js +188 -0
  312. package/dist/commands/finding-auto-group.d.ts +4 -0
  313. package/dist/commands/finding-auto-group.js +108 -0
  314. package/dist/commands/finding-auto-label.d.ts +4 -0
  315. package/dist/commands/finding-auto-label.js +220 -0
  316. package/dist/commands/finding-auto-priority.d.ts +1 -0
  317. package/dist/commands/finding-auto-priority.js +100 -0
  318. package/dist/commands/finding-auto-suppress.d.ts +4 -0
  319. package/dist/commands/finding-auto-suppress.js +126 -0
  320. package/dist/commands/finding-auto-tag.d.ts +4 -0
  321. package/dist/commands/finding-auto-tag.js +113 -0
  322. package/dist/commands/finding-auto-triage.d.ts +4 -0
  323. package/dist/commands/finding-auto-triage.js +108 -0
  324. package/dist/commands/finding-autofix-preview.d.ts +4 -0
  325. package/dist/commands/finding-autofix-preview.js +86 -0
  326. package/dist/commands/finding-batch-resolve.d.ts +4 -0
  327. package/dist/commands/finding-batch-resolve.js +165 -0
  328. package/dist/commands/finding-batch-suppress.d.ts +4 -0
  329. package/dist/commands/finding-batch-suppress.js +85 -0
  330. package/dist/commands/finding-batch-triage.d.ts +1 -0
  331. package/dist/commands/finding-batch-triage.js +90 -0
  332. package/dist/commands/finding-blast-radius.d.ts +4 -0
  333. package/dist/commands/finding-blast-radius.js +91 -0
  334. package/dist/commands/finding-budget.d.ts +4 -0
  335. package/dist/commands/finding-budget.js +232 -0
  336. package/dist/commands/finding-category-map.d.ts +4 -0
  337. package/dist/commands/finding-category-map.js +103 -0
  338. package/dist/commands/finding-category-stats.d.ts +4 -0
  339. package/dist/commands/finding-category-stats.js +104 -0
  340. package/dist/commands/finding-category.d.ts +4 -0
  341. package/dist/commands/finding-category.js +109 -0
  342. package/dist/commands/finding-change-impact.d.ts +4 -0
  343. package/dist/commands/finding-change-impact.js +107 -0
  344. package/dist/commands/finding-cluster-analysis.d.ts +4 -0
  345. package/dist/commands/finding-cluster-analysis.js +133 -0
  346. package/dist/commands/finding-cluster-group.d.ts +4 -0
  347. package/dist/commands/finding-cluster-group.js +105 -0
  348. package/dist/commands/finding-cluster-summary.d.ts +1 -0
  349. package/dist/commands/finding-cluster-summary.js +85 -0
  350. package/dist/commands/finding-cluster.d.ts +4 -0
  351. package/dist/commands/finding-cluster.js +157 -0
  352. package/dist/commands/finding-code-context.d.ts +4 -0
  353. package/dist/commands/finding-code-context.js +96 -0
  354. package/dist/commands/finding-code-smell.d.ts +4 -0
  355. package/dist/commands/finding-code-smell.js +113 -0
  356. package/dist/commands/finding-compare-runs.d.ts +4 -0
  357. package/dist/commands/finding-compare-runs.js +105 -0
  358. package/dist/commands/finding-compliance-tag.d.ts +1 -0
  359. package/dist/commands/finding-compliance-tag.js +106 -0
  360. package/dist/commands/finding-confidence-boost.d.ts +1 -0
  361. package/dist/commands/finding-confidence-boost.js +88 -0
  362. package/dist/commands/finding-confidence-calibrate.d.ts +4 -0
  363. package/dist/commands/finding-confidence-calibrate.js +111 -0
  364. package/dist/commands/finding-confidence-filter.d.ts +4 -0
  365. package/dist/commands/finding-confidence-filter.js +77 -0
  366. package/dist/commands/finding-contest.d.ts +7 -0
  367. package/dist/commands/finding-contest.js +192 -0
  368. package/dist/commands/finding-context-enrich.d.ts +4 -0
  369. package/dist/commands/finding-context-enrich.js +89 -0
  370. package/dist/commands/finding-context-expand.d.ts +4 -0
  371. package/dist/commands/finding-context-expand.js +102 -0
  372. package/dist/commands/finding-context-link.d.ts +1 -0
  373. package/dist/commands/finding-context-link.js +94 -0
  374. package/dist/commands/finding-context-summary.d.ts +1 -0
  375. package/dist/commands/finding-context-summary.js +85 -0
  376. package/dist/commands/finding-context-window.d.ts +4 -0
  377. package/dist/commands/finding-context-window.js +126 -0
  378. package/dist/commands/finding-context.d.ts +4 -0
  379. package/dist/commands/finding-context.js +140 -0
  380. package/dist/commands/finding-correlate.d.ts +4 -0
  381. package/dist/commands/finding-correlate.js +88 -0
  382. package/dist/commands/finding-correlation-map.d.ts +4 -0
  383. package/dist/commands/finding-correlation-map.js +101 -0
  384. package/dist/commands/finding-correlation.d.ts +4 -0
  385. package/dist/commands/finding-correlation.js +103 -0
  386. package/dist/commands/finding-cross-file-link.d.ts +1 -0
  387. package/dist/commands/finding-cross-file-link.js +101 -0
  388. package/dist/commands/finding-cross-ref.d.ts +4 -0
  389. package/dist/commands/finding-cross-ref.js +98 -0
  390. package/dist/commands/finding-cve-lookup.d.ts +4 -0
  391. package/dist/commands/finding-cve-lookup.js +97 -0
  392. package/dist/commands/finding-cwe-lookup.d.ts +4 -0
  393. package/dist/commands/finding-cwe-lookup.js +148 -0
  394. package/dist/commands/finding-cwe-map.d.ts +4 -0
  395. package/dist/commands/finding-cwe-map.js +133 -0
  396. package/dist/commands/finding-dedup-cross-file.d.ts +4 -0
  397. package/dist/commands/finding-dedup-cross-file.js +95 -0
  398. package/dist/commands/finding-dedup-cross.d.ts +4 -0
  399. package/dist/commands/finding-dedup-cross.js +90 -0
  400. package/dist/commands/finding-dedup-merge.d.ts +1 -0
  401. package/dist/commands/finding-dedup-merge.js +107 -0
  402. package/dist/commands/finding-dedup-report.d.ts +4 -0
  403. package/dist/commands/finding-dedup-report.js +101 -0
  404. package/dist/commands/finding-dedup-smart.d.ts +1 -0
  405. package/dist/commands/finding-dedup-smart.js +109 -0
  406. package/dist/commands/finding-deduplicate.d.ts +4 -0
  407. package/dist/commands/finding-deduplicate.js +141 -0
  408. package/dist/commands/finding-dependency-check.d.ts +4 -0
  409. package/dist/commands/finding-dependency-check.js +119 -0
  410. package/dist/commands/finding-dependency-impact.d.ts +1 -0
  411. package/dist/commands/finding-dependency-impact.js +97 -0
  412. package/dist/commands/finding-dependency-link.d.ts +4 -0
  413. package/dist/commands/finding-dependency-link.js +73 -0
  414. package/dist/commands/finding-dependency-risk.d.ts +4 -0
  415. package/dist/commands/finding-dependency-risk.js +117 -0
  416. package/dist/commands/finding-dependency-tree.d.ts +4 -0
  417. package/dist/commands/finding-dependency-tree.js +116 -0
  418. package/dist/commands/finding-diff-highlight.d.ts +4 -0
  419. package/dist/commands/finding-diff-highlight.js +107 -0
  420. package/dist/commands/finding-dismiss-workflow.d.ts +4 -0
  421. package/dist/commands/finding-dismiss-workflow.js +119 -0
  422. package/dist/commands/finding-duplicate-detect.d.ts +4 -0
  423. package/dist/commands/finding-duplicate-detect.js +113 -0
  424. package/dist/commands/finding-duplicate-rule.d.ts +4 -0
  425. package/dist/commands/finding-duplicate-rule.js +103 -0
  426. package/dist/commands/finding-effort-rank.d.ts +1 -0
  427. package/dist/commands/finding-effort-rank.js +93 -0
  428. package/dist/commands/finding-evidence-chain.d.ts +4 -0
  429. package/dist/commands/finding-evidence-chain.js +147 -0
  430. package/dist/commands/finding-evidence-collect.d.ts +4 -0
  431. package/dist/commands/finding-evidence-collect.js +114 -0
  432. package/dist/commands/finding-explain.d.ts +4 -0
  433. package/dist/commands/finding-explain.js +93 -0
  434. package/dist/commands/finding-export-csv.d.ts +4 -0
  435. package/dist/commands/finding-export-csv.js +78 -0
  436. package/dist/commands/finding-false-neg-check.d.ts +8 -0
  437. package/dist/commands/finding-false-neg-check.js +139 -0
  438. package/dist/commands/finding-false-positive-learn.d.ts +4 -0
  439. package/dist/commands/finding-false-positive-learn.js +85 -0
  440. package/dist/commands/finding-false-positive-log.d.ts +4 -0
  441. package/dist/commands/finding-false-positive-log.js +150 -0
  442. package/dist/commands/finding-false-positive.d.ts +4 -0
  443. package/dist/commands/finding-false-positive.js +134 -0
  444. package/dist/commands/finding-filter-view.d.ts +4 -0
  445. package/dist/commands/finding-filter-view.js +107 -0
  446. package/dist/commands/finding-fix-chain.d.ts +1 -0
  447. package/dist/commands/finding-fix-chain.js +78 -0
  448. package/dist/commands/finding-fix-estimate.d.ts +1 -0
  449. package/dist/commands/finding-fix-estimate.js +95 -0
  450. package/dist/commands/finding-fix-playbook.d.ts +1 -0
  451. package/dist/commands/finding-fix-playbook.js +110 -0
  452. package/dist/commands/finding-fix-priority.d.ts +4 -0
  453. package/dist/commands/finding-fix-priority.js +98 -0
  454. package/dist/commands/finding-fix-rate.d.ts +4 -0
  455. package/dist/commands/finding-fix-rate.js +141 -0
  456. package/dist/commands/finding-fix-suggest.d.ts +4 -0
  457. package/dist/commands/finding-fix-suggest.js +88 -0
  458. package/dist/commands/finding-fix-validation.d.ts +4 -0
  459. package/dist/commands/finding-fix-validation.js +115 -0
  460. package/dist/commands/finding-fix-verify.d.ts +4 -0
  461. package/dist/commands/finding-fix-verify.js +198 -0
  462. package/dist/commands/finding-group-by.d.ts +4 -0
  463. package/dist/commands/finding-group-by.js +86 -0
  464. package/dist/commands/finding-group.d.ts +15 -0
  465. package/dist/commands/finding-group.js +164 -0
  466. package/dist/commands/finding-groupby-file.d.ts +4 -0
  467. package/dist/commands/finding-groupby-file.js +94 -0
  468. package/dist/commands/finding-hotfix-suggest.d.ts +7 -0
  469. package/dist/commands/finding-hotfix-suggest.js +170 -0
  470. package/dist/commands/finding-hotspot-detect.d.ts +1 -0
  471. package/dist/commands/finding-hotspot-detect.js +120 -0
  472. package/dist/commands/finding-hotspot-map.d.ts +4 -0
  473. package/dist/commands/finding-hotspot-map.js +106 -0
  474. package/dist/commands/finding-hotspot.d.ts +4 -0
  475. package/dist/commands/finding-hotspot.js +115 -0
  476. package/dist/commands/finding-impact-radius.d.ts +1 -0
  477. package/dist/commands/finding-impact-radius.js +94 -0
  478. package/dist/commands/finding-impact-rank.d.ts +4 -0
  479. package/dist/commands/finding-impact-rank.js +85 -0
  480. package/dist/commands/finding-impact-score.d.ts +4 -0
  481. package/dist/commands/finding-impact-score.js +123 -0
  482. package/dist/commands/finding-impact.d.ts +4 -0
  483. package/dist/commands/finding-impact.js +135 -0
  484. package/dist/commands/finding-line-blame.d.ts +7 -0
  485. package/dist/commands/finding-line-blame.js +129 -0
  486. package/dist/commands/finding-link-graph.d.ts +4 -0
  487. package/dist/commands/finding-link-graph.js +144 -0
  488. package/dist/commands/finding-link.d.ts +4 -0
  489. package/dist/commands/finding-link.js +128 -0
  490. package/dist/commands/finding-merge-results.d.ts +4 -0
  491. package/dist/commands/finding-merge-results.js +110 -0
  492. package/dist/commands/finding-merge-strategy.d.ts +1 -0
  493. package/dist/commands/finding-merge-strategy.js +84 -0
  494. package/dist/commands/finding-metadata-enrich.d.ts +4 -0
  495. package/dist/commands/finding-metadata-enrich.js +92 -0
  496. package/dist/commands/finding-noise-filter.d.ts +7 -0
  497. package/dist/commands/finding-noise-filter.js +140 -0
  498. package/dist/commands/finding-noise-reduce.d.ts +1 -0
  499. package/dist/commands/finding-noise-reduce.js +81 -0
  500. package/dist/commands/finding-noise-score.d.ts +1 -0
  501. package/dist/commands/finding-noise-score.js +93 -0
  502. package/dist/commands/finding-owner-assign.d.ts +4 -0
  503. package/dist/commands/finding-owner-assign.js +133 -0
  504. package/dist/commands/finding-owner-notify.d.ts +1 -0
  505. package/dist/commands/finding-owner-notify.js +121 -0
  506. package/dist/commands/finding-ownership-assign.d.ts +4 -0
  507. package/dist/commands/finding-ownership-assign.js +101 -0
  508. package/dist/commands/finding-ownership-map.d.ts +4 -0
  509. package/dist/commands/finding-ownership-map.js +118 -0
  510. package/dist/commands/finding-patch-chain.d.ts +1 -0
  511. package/dist/commands/finding-patch-chain.js +90 -0
  512. package/dist/commands/finding-patch-preview.d.ts +4 -0
  513. package/dist/commands/finding-patch-preview.js +103 -0
  514. package/dist/commands/finding-pattern-detect.d.ts +4 -0
  515. package/dist/commands/finding-pattern-detect.js +127 -0
  516. package/dist/commands/finding-pattern-library.d.ts +4 -0
  517. package/dist/commands/finding-pattern-library.js +145 -0
  518. package/dist/commands/finding-pattern-match.d.ts +4 -0
  519. package/dist/commands/finding-pattern-match.js +165 -0
  520. package/dist/commands/finding-prioritize.d.ts +4 -0
  521. package/dist/commands/finding-prioritize.js +119 -0
  522. package/dist/commands/finding-priority-matrix.d.ts +4 -0
  523. package/dist/commands/finding-priority-matrix.js +102 -0
  524. package/dist/commands/finding-priority-queue.d.ts +4 -0
  525. package/dist/commands/finding-priority-queue.js +131 -0
  526. package/dist/commands/finding-priority-rank.d.ts +1 -0
  527. package/dist/commands/finding-priority-rank.js +82 -0
  528. package/dist/commands/finding-quality-gate.d.ts +4 -0
  529. package/dist/commands/finding-quality-gate.js +107 -0
  530. package/dist/commands/finding-rank.d.ts +4 -0
  531. package/dist/commands/finding-rank.js +138 -0
  532. package/dist/commands/finding-reachability-check.d.ts +4 -0
  533. package/dist/commands/finding-reachability-check.js +102 -0
  534. package/dist/commands/finding-reachability.d.ts +4 -0
  535. package/dist/commands/finding-reachability.js +131 -0
  536. package/dist/commands/finding-recurrence-check.d.ts +1 -0
  537. package/dist/commands/finding-recurrence-check.js +103 -0
  538. package/dist/commands/finding-recurrence-detect.d.ts +4 -0
  539. package/dist/commands/finding-recurrence-detect.js +77 -0
  540. package/dist/commands/finding-recurrence.d.ts +4 -0
  541. package/dist/commands/finding-recurrence.js +135 -0
  542. package/dist/commands/finding-regression-check.d.ts +4 -0
  543. package/dist/commands/finding-regression-check.js +112 -0
  544. package/dist/commands/finding-regression-detect.d.ts +1 -0
  545. package/dist/commands/finding-regression-detect.js +86 -0
  546. package/dist/commands/finding-related-rules.d.ts +4 -0
  547. package/dist/commands/finding-related-rules.js +151 -0
  548. package/dist/commands/finding-remediation-cost.d.ts +1 -0
  549. package/dist/commands/finding-remediation-cost.js +79 -0
  550. package/dist/commands/finding-remediation-plan.d.ts +4 -0
  551. package/dist/commands/finding-remediation-plan.js +107 -0
  552. package/dist/commands/finding-reopen-detect.d.ts +1 -0
  553. package/dist/commands/finding-reopen-detect.js +77 -0
  554. package/dist/commands/finding-repeat-detect.d.ts +1 -0
  555. package/dist/commands/finding-repeat-detect.js +92 -0
  556. package/dist/commands/finding-resolution-track.d.ts +4 -0
  557. package/dist/commands/finding-resolution-track.js +150 -0
  558. package/dist/commands/finding-resolution-tracker.d.ts +4 -0
  559. package/dist/commands/finding-resolution-tracker.js +163 -0
  560. package/dist/commands/finding-resolution-workflow.d.ts +1 -0
  561. package/dist/commands/finding-resolution-workflow.js +91 -0
  562. package/dist/commands/finding-resolution.d.ts +4 -0
  563. package/dist/commands/finding-resolution.js +142 -0
  564. package/dist/commands/finding-risk-label.d.ts +1 -0
  565. package/dist/commands/finding-risk-label.js +72 -0
  566. package/dist/commands/finding-risk-matrix.d.ts +4 -0
  567. package/dist/commands/finding-risk-matrix.js +126 -0
  568. package/dist/commands/finding-risk-score.d.ts +4 -0
  569. package/dist/commands/finding-risk-score.js +95 -0
  570. package/dist/commands/finding-root-cause.d.ts +4 -0
  571. package/dist/commands/finding-root-cause.js +184 -0
  572. package/dist/commands/finding-rule-explain.d.ts +4 -0
  573. package/dist/commands/finding-rule-explain.js +140 -0
  574. package/dist/commands/finding-scope-filter.d.ts +1 -0
  575. package/dist/commands/finding-scope-filter.js +77 -0
  576. package/dist/commands/finding-scope-impact.d.ts +1 -0
  577. package/dist/commands/finding-scope-impact.js +83 -0
  578. package/dist/commands/finding-search-index.d.ts +4 -0
  579. package/dist/commands/finding-search-index.js +99 -0
  580. package/dist/commands/finding-security-hotspot.d.ts +4 -0
  581. package/dist/commands/finding-security-hotspot.js +175 -0
  582. package/dist/commands/finding-severity-dist.d.ts +4 -0
  583. package/dist/commands/finding-severity-dist.js +105 -0
  584. package/dist/commands/finding-severity-drift.d.ts +4 -0
  585. package/dist/commands/finding-severity-drift.js +92 -0
  586. package/dist/commands/finding-severity-heatmap.d.ts +4 -0
  587. package/dist/commands/finding-severity-heatmap.js +108 -0
  588. package/dist/commands/finding-severity-histogram.d.ts +4 -0
  589. package/dist/commands/finding-severity-histogram.js +66 -0
  590. package/dist/commands/finding-severity-override.d.ts +4 -0
  591. package/dist/commands/finding-severity-override.js +131 -0
  592. package/dist/commands/finding-severity-rebalance.d.ts +1 -0
  593. package/dist/commands/finding-severity-rebalance.js +108 -0
  594. package/dist/commands/finding-severity-trend.d.ts +4 -0
  595. package/dist/commands/finding-severity-trend.js +127 -0
  596. package/dist/commands/finding-similar-match.d.ts +1 -0
  597. package/dist/commands/finding-similar-match.js +112 -0
  598. package/dist/commands/finding-snippet.d.ts +4 -0
  599. package/dist/commands/finding-snippet.js +102 -0
  600. package/dist/commands/finding-summary-digest.d.ts +7 -0
  601. package/dist/commands/finding-summary-digest.js +145 -0
  602. package/dist/commands/finding-suppress-pattern.d.ts +4 -0
  603. package/dist/commands/finding-suppress-pattern.js +148 -0
  604. package/dist/commands/finding-suppress.d.ts +4 -0
  605. package/dist/commands/finding-suppress.js +164 -0
  606. package/dist/commands/finding-suppression-audit.d.ts +4 -0
  607. package/dist/commands/finding-suppression-audit.js +137 -0
  608. package/dist/commands/finding-suppression-list.d.ts +4 -0
  609. package/dist/commands/finding-suppression-list.js +119 -0
  610. package/dist/commands/finding-suppression-log.d.ts +4 -0
  611. package/dist/commands/finding-suppression-log.js +174 -0
  612. package/dist/commands/finding-time-to-fix.d.ts +1 -0
  613. package/dist/commands/finding-time-to-fix.js +98 -0
  614. package/dist/commands/finding-timeline-view.d.ts +4 -0
  615. package/dist/commands/finding-timeline-view.js +98 -0
  616. package/dist/commands/finding-timeline.d.ts +4 -0
  617. package/dist/commands/finding-timeline.js +143 -0
  618. package/dist/commands/finding-top-offender.d.ts +1 -0
  619. package/dist/commands/finding-top-offender.js +75 -0
  620. package/dist/commands/finding-trace.d.ts +4 -0
  621. package/dist/commands/finding-trace.js +118 -0
  622. package/dist/commands/finding-trend-alert.d.ts +1 -0
  623. package/dist/commands/finding-trend-alert.js +126 -0
  624. package/dist/commands/finding-trend-analysis.d.ts +4 -0
  625. package/dist/commands/finding-trend-analysis.js +95 -0
  626. package/dist/commands/finding-trend-forecast.d.ts +4 -0
  627. package/dist/commands/finding-trend-forecast.js +106 -0
  628. package/dist/commands/finding-trend-report.d.ts +4 -0
  629. package/dist/commands/finding-trend-report.js +107 -0
  630. package/dist/commands/finding-trend.d.ts +4 -0
  631. package/dist/commands/finding-trend.js +118 -0
  632. package/dist/commands/fix-pr.d.ts +22 -0
  633. package/dist/commands/fix-pr.js +286 -0
  634. package/dist/commands/fix-suggest.d.ts +4 -0
  635. package/dist/commands/fix-suggest.js +171 -0
  636. package/dist/commands/fix-verify.d.ts +4 -0
  637. package/dist/commands/fix-verify.js +123 -0
  638. package/dist/commands/fix.d.ts +117 -0
  639. package/dist/commands/fix.js +445 -0
  640. package/dist/commands/focus-area.d.ts +5 -0
  641. package/dist/commands/focus-area.js +192 -0
  642. package/dist/commands/generate.d.ts +7 -0
  643. package/dist/commands/generate.js +403 -0
  644. package/dist/commands/governance.d.ts +31 -0
  645. package/dist/commands/governance.js +202 -0
  646. package/dist/commands/group-findings.d.ts +22 -0
  647. package/dist/commands/group-findings.js +154 -0
  648. package/dist/commands/guided-tour.d.ts +8 -0
  649. package/dist/commands/guided-tour.js +287 -0
  650. package/dist/commands/habit-tracker.d.ts +7 -0
  651. package/dist/commands/habit-tracker.js +194 -0
  652. package/dist/commands/hallucination-detect.d.ts +4 -0
  653. package/dist/commands/hallucination-detect.js +350 -0
  654. package/dist/commands/hallucination-score.d.ts +8 -0
  655. package/dist/commands/hallucination-score.js +316 -0
  656. package/dist/commands/help.d.ts +7 -0
  657. package/dist/commands/help.js +302 -0
  658. package/dist/commands/hook-install.d.ts +21 -0
  659. package/dist/commands/hook-install.js +142 -0
  660. package/dist/commands/hook.d.ts +8 -0
  661. package/dist/commands/hook.js +145 -0
  662. package/dist/commands/iac-lint.d.ts +7 -0
  663. package/dist/commands/iac-lint.js +312 -0
  664. package/dist/commands/idempotency-audit.d.ts +4 -0
  665. package/dist/commands/idempotency-audit.js +222 -0
  666. package/dist/commands/ignore-list.d.ts +18 -0
  667. package/dist/commands/ignore-list.js +152 -0
  668. package/dist/commands/impact-scan.d.ts +8 -0
  669. package/dist/commands/impact-scan.js +281 -0
  670. package/dist/commands/incident-response.d.ts +7 -0
  671. package/dist/commands/incident-response.js +254 -0
  672. package/dist/commands/incremental-review.d.ts +4 -0
  673. package/dist/commands/incremental-review.js +236 -0
  674. package/dist/commands/init.d.ts +10 -0
  675. package/dist/commands/init.js +265 -0
  676. package/dist/commands/input-guard.d.ts +4 -0
  677. package/dist/commands/input-guard.js +255 -0
  678. package/dist/commands/interactive-fix.d.ts +22 -0
  679. package/dist/commands/interactive-fix.js +139 -0
  680. package/dist/commands/judge-author.d.ts +7 -0
  681. package/dist/commands/judge-author.js +260 -0
  682. package/dist/commands/judge-config.d.ts +4 -0
  683. package/dist/commands/judge-config.js +151 -0
  684. package/dist/commands/judge-learn.d.ts +8 -0
  685. package/dist/commands/judge-learn.js +217 -0
  686. package/dist/commands/judge-reputation.d.ts +28 -0
  687. package/dist/commands/judge-reputation.js +198 -0
  688. package/dist/commands/kb.d.ts +40 -0
  689. package/dist/commands/kb.js +228 -0
  690. package/dist/commands/language-packs.d.ts +42 -0
  691. package/dist/commands/language-packs.js +150 -0
  692. package/dist/commands/learn.d.ts +26 -0
  693. package/dist/commands/learn.js +288 -0
  694. package/dist/commands/learning-path.d.ts +8 -0
  695. package/dist/commands/learning-path.js +325 -0
  696. package/dist/commands/license-scan.d.ts +8 -0
  697. package/dist/commands/license-scan.js +183 -0
  698. package/dist/commands/llm-benchmark-optimizer.d.ts +78 -0
  699. package/dist/commands/llm-benchmark-optimizer.js +241 -0
  700. package/dist/commands/llm-benchmark.d.ts +156 -0
  701. package/dist/commands/llm-benchmark.js +670 -0
  702. package/dist/commands/log-quality.d.ts +5 -0
  703. package/dist/commands/log-quality.js +211 -0
  704. package/dist/commands/logic-lint.d.ts +4 -0
  705. package/dist/commands/logic-lint.js +255 -0
  706. package/dist/commands/lsp.d.ts +23 -0
  707. package/dist/commands/lsp.js +285 -0
  708. package/dist/commands/merge-verdict.d.ts +4 -0
  709. package/dist/commands/merge-verdict.js +287 -0
  710. package/dist/commands/metrics-dashboard.d.ts +21 -0
  711. package/dist/commands/metrics-dashboard.js +334 -0
  712. package/dist/commands/metrics.d.ts +57 -0
  713. package/dist/commands/metrics.js +241 -0
  714. package/dist/commands/migration-safety.d.ts +5 -0
  715. package/dist/commands/migration-safety.js +256 -0
  716. package/dist/commands/model-report.d.ts +8 -0
  717. package/dist/commands/model-report.js +194 -0
  718. package/dist/commands/model-risk.d.ts +27 -0
  719. package/dist/commands/model-risk.js +220 -0
  720. package/dist/commands/monorepo.d.ts +37 -0
  721. package/dist/commands/monorepo.js +232 -0
  722. package/dist/commands/multi-lang-review.d.ts +4 -0
  723. package/dist/commands/multi-lang-review.js +230 -0
  724. package/dist/commands/noise-advisor.d.ts +29 -0
  725. package/dist/commands/noise-advisor.js +170 -0
  726. package/dist/commands/notify.d.ts +78 -0
  727. package/dist/commands/notify.js +324 -0
  728. package/dist/commands/null-safety-audit.d.ts +5 -0
  729. package/dist/commands/null-safety-audit.js +221 -0
  730. package/dist/commands/observability-gap.d.ts +5 -0
  731. package/dist/commands/observability-gap.js +211 -0
  732. package/dist/commands/onboard.d.ts +12 -0
  733. package/dist/commands/onboard.js +178 -0
  734. package/dist/commands/org-metrics.d.ts +23 -0
  735. package/dist/commands/org-metrics.js +237 -0
  736. package/dist/commands/org-policy.d.ts +7 -0
  737. package/dist/commands/org-policy.js +207 -0
  738. package/dist/commands/over-abstraction.d.ts +4 -0
  739. package/dist/commands/over-abstraction.js +307 -0
  740. package/dist/commands/override.d.ts +61 -0
  741. package/dist/commands/override.js +268 -0
  742. package/dist/commands/ownership-map.d.ts +5 -0
  743. package/dist/commands/ownership-map.js +217 -0
  744. package/dist/commands/parity.d.ts +30 -0
  745. package/dist/commands/parity.js +212 -0
  746. package/dist/commands/pattern-registry.d.ts +22 -0
  747. package/dist/commands/pattern-registry.js +226 -0
  748. package/dist/commands/perf-compare.d.ts +8 -0
  749. package/dist/commands/perf-compare.js +245 -0
  750. package/dist/commands/perf-hotspot.d.ts +7 -0
  751. package/dist/commands/perf-hotspot.js +273 -0
  752. package/dist/commands/phantom-import.d.ts +4 -0
  753. package/dist/commands/phantom-import.js +260 -0
  754. package/dist/commands/pii-scan.d.ts +7 -0
  755. package/dist/commands/pii-scan.js +299 -0
  756. package/dist/commands/plugin-search.d.ts +39 -0
  757. package/dist/commands/plugin-search.js +327 -0
  758. package/dist/commands/plugins.d.ts +12 -0
  759. package/dist/commands/plugins.js +104 -0
  760. package/dist/commands/policy-audit.d.ts +52 -0
  761. package/dist/commands/policy-audit.js +160 -0
  762. package/dist/commands/pr-quality-gate.d.ts +28 -0
  763. package/dist/commands/pr-quality-gate.js +207 -0
  764. package/dist/commands/pr-summary.d.ts +25 -0
  765. package/dist/commands/pr-summary.js +187 -0
  766. package/dist/commands/predict.d.ts +7 -0
  767. package/dist/commands/predict.js +218 -0
  768. package/dist/commands/privilege-path.d.ts +4 -0
  769. package/dist/commands/privilege-path.js +233 -0
  770. package/dist/commands/profile.d.ts +37 -0
  771. package/dist/commands/profile.js +101 -0
  772. package/dist/commands/prompt-replay.d.ts +7 -0
  773. package/dist/commands/prompt-replay.js +176 -0
  774. package/dist/commands/quality-gate.d.ts +69 -0
  775. package/dist/commands/quality-gate.js +252 -0
  776. package/dist/commands/query.d.ts +19 -0
  777. package/dist/commands/query.js +229 -0
  778. package/dist/commands/quick-check.d.ts +4 -0
  779. package/dist/commands/quick-check.js +173 -0
  780. package/dist/commands/recommend.d.ts +20 -0
  781. package/dist/commands/recommend.js +282 -0
  782. package/dist/commands/refactor-safety.d.ts +8 -0
  783. package/dist/commands/refactor-safety.js +273 -0
  784. package/dist/commands/reg-watch.d.ts +20 -0
  785. package/dist/commands/reg-watch.js +219 -0
  786. package/dist/commands/regression-alert.d.ts +31 -0
  787. package/dist/commands/regression-alert.js +215 -0
  788. package/dist/commands/remediation-lib.d.ts +8 -0
  789. package/dist/commands/remediation-lib.js +265 -0
  790. package/dist/commands/remediation.d.ts +20 -0
  791. package/dist/commands/remediation.js +256 -0
  792. package/dist/commands/report-template.d.ts +16 -0
  793. package/dist/commands/report-template.js +290 -0
  794. package/dist/commands/report.d.ts +12 -0
  795. package/dist/commands/report.js +139 -0
  796. package/dist/commands/resource-cleanup.d.ts +6 -0
  797. package/dist/commands/resource-cleanup.js +235 -0
  798. package/dist/commands/retro.d.ts +22 -0
  799. package/dist/commands/retro.js +211 -0
  800. package/dist/commands/retry-pattern-audit.d.ts +5 -0
  801. package/dist/commands/retry-pattern-audit.js +215 -0
  802. package/dist/commands/review-ab-test.d.ts +4 -0
  803. package/dist/commands/review-ab-test.js +224 -0
  804. package/dist/commands/review-access-log.d.ts +4 -0
  805. package/dist/commands/review-access-log.js +65 -0
  806. package/dist/commands/review-action-item-gen.d.ts +1 -0
  807. package/dist/commands/review-action-item-gen.js +72 -0
  808. package/dist/commands/review-adoption-metrics.d.ts +4 -0
  809. package/dist/commands/review-adoption-metrics.js +95 -0
  810. package/dist/commands/review-adoption-score.d.ts +1 -0
  811. package/dist/commands/review-adoption-score.js +181 -0
  812. package/dist/commands/review-ai-feedback-loop.d.ts +1 -0
  813. package/dist/commands/review-ai-feedback-loop.js +116 -0
  814. package/dist/commands/review-annotate.d.ts +4 -0
  815. package/dist/commands/review-annotate.js +122 -0
  816. package/dist/commands/review-annotation-export.d.ts +4 -0
  817. package/dist/commands/review-annotation-export.js +105 -0
  818. package/dist/commands/review-annotation.d.ts +4 -0
  819. package/dist/commands/review-annotation.js +133 -0
  820. package/dist/commands/review-api-export.d.ts +4 -0
  821. package/dist/commands/review-api-export.js +98 -0
  822. package/dist/commands/review-approval-criteria.d.ts +1 -0
  823. package/dist/commands/review-approval-criteria.js +99 -0
  824. package/dist/commands/review-approval-gate.d.ts +7 -0
  825. package/dist/commands/review-approval-gate.js +190 -0
  826. package/dist/commands/review-approval.d.ts +4 -0
  827. package/dist/commands/review-approval.js +133 -0
  828. package/dist/commands/review-archive-search.d.ts +4 -0
  829. package/dist/commands/review-archive-search.js +70 -0
  830. package/dist/commands/review-archive.d.ts +4 -0
  831. package/dist/commands/review-archive.js +135 -0
  832. package/dist/commands/review-audit-export.d.ts +4 -0
  833. package/dist/commands/review-audit-export.js +93 -0
  834. package/dist/commands/review-audit-log.d.ts +4 -0
  835. package/dist/commands/review-audit-log.js +140 -0
  836. package/dist/commands/review-audit-trail.d.ts +4 -0
  837. package/dist/commands/review-audit-trail.js +96 -0
  838. package/dist/commands/review-auto-merge.d.ts +4 -0
  839. package/dist/commands/review-auto-merge.js +175 -0
  840. package/dist/commands/review-badge.d.ts +4 -0
  841. package/dist/commands/review-badge.js +152 -0
  842. package/dist/commands/review-batch-files.d.ts +4 -0
  843. package/dist/commands/review-batch-files.js +82 -0
  844. package/dist/commands/review-batch-mode.d.ts +4 -0
  845. package/dist/commands/review-batch-mode.js +97 -0
  846. package/dist/commands/review-batch-run.d.ts +4 -0
  847. package/dist/commands/review-batch-run.js +149 -0
  848. package/dist/commands/review-benchmark-self.d.ts +4 -0
  849. package/dist/commands/review-benchmark-self.js +140 -0
  850. package/dist/commands/review-blame-map.d.ts +4 -0
  851. package/dist/commands/review-blame-map.js +100 -0
  852. package/dist/commands/review-branch-compare.d.ts +4 -0
  853. package/dist/commands/review-branch-compare.js +108 -0
  854. package/dist/commands/review-branch-policy.d.ts +4 -0
  855. package/dist/commands/review-branch-policy.js +102 -0
  856. package/dist/commands/review-bulk-action.d.ts +4 -0
  857. package/dist/commands/review-bulk-action.js +109 -0
  858. package/dist/commands/review-bulk-apply.d.ts +4 -0
  859. package/dist/commands/review-bulk-apply.js +102 -0
  860. package/dist/commands/review-cache-clear.d.ts +4 -0
  861. package/dist/commands/review-cache-clear.js +160 -0
  862. package/dist/commands/review-cache-warm.d.ts +4 -0
  863. package/dist/commands/review-cache-warm.js +70 -0
  864. package/dist/commands/review-cache.d.ts +22 -0
  865. package/dist/commands/review-cache.js +134 -0
  866. package/dist/commands/review-changelog-entry.d.ts +7 -0
  867. package/dist/commands/review-changelog-entry.js +109 -0
  868. package/dist/commands/review-changelog-gen.d.ts +4 -0
  869. package/dist/commands/review-changelog-gen.js +117 -0
  870. package/dist/commands/review-changelog-impact.d.ts +1 -0
  871. package/dist/commands/review-changelog-impact.js +89 -0
  872. package/dist/commands/review-checklist.d.ts +4 -0
  873. package/dist/commands/review-checklist.js +144 -0
  874. package/dist/commands/review-checkpoint.d.ts +4 -0
  875. package/dist/commands/review-checkpoint.js +163 -0
  876. package/dist/commands/review-ci-gate.d.ts +4 -0
  877. package/dist/commands/review-ci-gate.js +114 -0
  878. package/dist/commands/review-ci-insight.d.ts +1 -0
  879. package/dist/commands/review-ci-insight.js +100 -0
  880. package/dist/commands/review-ci-integration.d.ts +4 -0
  881. package/dist/commands/review-ci-integration.js +125 -0
  882. package/dist/commands/review-ci-status.d.ts +4 -0
  883. package/dist/commands/review-ci-status.js +200 -0
  884. package/dist/commands/review-cicd-integrate.d.ts +4 -0
  885. package/dist/commands/review-cicd-integrate.js +122 -0
  886. package/dist/commands/review-code-health-score.d.ts +1 -0
  887. package/dist/commands/review-code-health-score.js +100 -0
  888. package/dist/commands/review-code-owner.d.ts +7 -0
  889. package/dist/commands/review-code-owner.js +164 -0
  890. package/dist/commands/review-code-ownership.d.ts +1 -0
  891. package/dist/commands/review-code-ownership.js +88 -0
  892. package/dist/commands/review-comment.d.ts +4 -0
  893. package/dist/commands/review-comment.js +165 -0
  894. package/dist/commands/review-commit-hook.d.ts +7 -0
  895. package/dist/commands/review-commit-hook.js +134 -0
  896. package/dist/commands/review-commit-quality.d.ts +1 -0
  897. package/dist/commands/review-commit-quality.js +94 -0
  898. package/dist/commands/review-comparative.d.ts +4 -0
  899. package/dist/commands/review-comparative.js +149 -0
  900. package/dist/commands/review-compare-version.d.ts +4 -0
  901. package/dist/commands/review-compare-version.js +108 -0
  902. package/dist/commands/review-compare.d.ts +4 -0
  903. package/dist/commands/review-compare.js +200 -0
  904. package/dist/commands/review-compliance-check.d.ts +4 -0
  905. package/dist/commands/review-compliance-check.js +202 -0
  906. package/dist/commands/review-compliance-gate.d.ts +4 -0
  907. package/dist/commands/review-compliance-gate.js +151 -0
  908. package/dist/commands/review-compliance-map.d.ts +4 -0
  909. package/dist/commands/review-compliance-map.js +110 -0
  910. package/dist/commands/review-compliance-report.d.ts +4 -0
  911. package/dist/commands/review-compliance-report.js +127 -0
  912. package/dist/commands/review-confidence-explain.d.ts +1 -0
  913. package/dist/commands/review-confidence-explain.js +99 -0
  914. package/dist/commands/review-config-diff.d.ts +4 -0
  915. package/dist/commands/review-config-diff.js +108 -0
  916. package/dist/commands/review-config-export.d.ts +4 -0
  917. package/dist/commands/review-config-export.js +124 -0
  918. package/dist/commands/review-config-health.d.ts +1 -0
  919. package/dist/commands/review-config-health.js +172 -0
  920. package/dist/commands/review-config-migrate.d.ts +4 -0
  921. package/dist/commands/review-config-migrate.js +123 -0
  922. package/dist/commands/review-config-template.d.ts +4 -0
  923. package/dist/commands/review-config-template.js +112 -0
  924. package/dist/commands/review-config-validate.d.ts +4 -0
  925. package/dist/commands/review-config-validate.js +110 -0
  926. package/dist/commands/review-contract.d.ts +4 -0
  927. package/dist/commands/review-contract.js +199 -0
  928. package/dist/commands/review-coverage-gap.d.ts +4 -0
  929. package/dist/commands/review-coverage-gap.js +120 -0
  930. package/dist/commands/review-coverage-map.d.ts +4 -0
  931. package/dist/commands/review-coverage-map.js +194 -0
  932. package/dist/commands/review-custom-judge-config.d.ts +4 -0
  933. package/dist/commands/review-custom-judge-config.js +103 -0
  934. package/dist/commands/review-custom-judge.d.ts +4 -0
  935. package/dist/commands/review-custom-judge.js +182 -0
  936. package/dist/commands/review-custom-prompt.d.ts +4 -0
  937. package/dist/commands/review-custom-prompt.js +170 -0
  938. package/dist/commands/review-custom-rule.d.ts +4 -0
  939. package/dist/commands/review-custom-rule.js +169 -0
  940. package/dist/commands/review-dashboard-data.d.ts +4 -0
  941. package/dist/commands/review-dashboard-data.js +142 -0
  942. package/dist/commands/review-dashboard.d.ts +4 -0
  943. package/dist/commands/review-dashboard.js +140 -0
  944. package/dist/commands/review-data-retention.d.ts +4 -0
  945. package/dist/commands/review-data-retention.js +119 -0
  946. package/dist/commands/review-dependency-graph.d.ts +4 -0
  947. package/dist/commands/review-dependency-graph.js +94 -0
  948. package/dist/commands/review-dependency-review.d.ts +1 -0
  949. package/dist/commands/review-dependency-review.js +104 -0
  950. package/dist/commands/review-deployment-gate.d.ts +4 -0
  951. package/dist/commands/review-deployment-gate.js +94 -0
  952. package/dist/commands/review-depth.d.ts +4 -0
  953. package/dist/commands/review-depth.js +142 -0
  954. package/dist/commands/review-diff-annotate.d.ts +4 -0
  955. package/dist/commands/review-diff-annotate.js +104 -0
  956. package/dist/commands/review-diff-context.d.ts +4 -0
  957. package/dist/commands/review-diff-context.js +158 -0
  958. package/dist/commands/review-diff-highlight.d.ts +4 -0
  959. package/dist/commands/review-diff-highlight.js +179 -0
  960. package/dist/commands/review-diff-stats.d.ts +4 -0
  961. package/dist/commands/review-diff-stats.js +90 -0
  962. package/dist/commands/review-diff-summary.d.ts +4 -0
  963. package/dist/commands/review-diff-summary.js +154 -0
  964. package/dist/commands/review-digest-gen.d.ts +1 -0
  965. package/dist/commands/review-digest-gen.js +100 -0
  966. package/dist/commands/review-digest.d.ts +4 -0
  967. package/dist/commands/review-digest.js +265 -0
  968. package/dist/commands/review-dry-run.d.ts +4 -0
  969. package/dist/commands/review-dry-run.js +120 -0
  970. package/dist/commands/review-engagement-score.d.ts +1 -0
  971. package/dist/commands/review-engagement-score.js +111 -0
  972. package/dist/commands/review-env-check.d.ts +4 -0
  973. package/dist/commands/review-env-check.js +115 -0
  974. package/dist/commands/review-environment-config.d.ts +4 -0
  975. package/dist/commands/review-environment-config.js +102 -0
  976. package/dist/commands/review-escalation-path.d.ts +1 -0
  977. package/dist/commands/review-escalation-path.js +86 -0
  978. package/dist/commands/review-exclude-vendor.d.ts +4 -0
  979. package/dist/commands/review-exclude-vendor.js +158 -0
  980. package/dist/commands/review-explain.d.ts +5 -0
  981. package/dist/commands/review-explain.js +194 -0
  982. package/dist/commands/review-export-pdf.d.ts +7 -0
  983. package/dist/commands/review-export-pdf.js +131 -0
  984. package/dist/commands/review-export.d.ts +4 -0
  985. package/dist/commands/review-export.js +179 -0
  986. package/dist/commands/review-feedback-loop.d.ts +4 -0
  987. package/dist/commands/review-feedback-loop.js +113 -0
  988. package/dist/commands/review-feedback-summary.d.ts +1 -0
  989. package/dist/commands/review-feedback-summary.js +130 -0
  990. package/dist/commands/review-feedback.d.ts +4 -0
  991. package/dist/commands/review-feedback.js +145 -0
  992. package/dist/commands/review-file-complexity.d.ts +4 -0
  993. package/dist/commands/review-file-complexity.js +137 -0
  994. package/dist/commands/review-file-filter.d.ts +4 -0
  995. package/dist/commands/review-file-filter.js +121 -0
  996. package/dist/commands/review-file-stats.d.ts +4 -0
  997. package/dist/commands/review-file-stats.js +130 -0
  998. package/dist/commands/review-filter.d.ts +4 -0
  999. package/dist/commands/review-filter.js +161 -0
  1000. package/dist/commands/review-finding-link.d.ts +7 -0
  1001. package/dist/commands/review-finding-link.js +115 -0
  1002. package/dist/commands/review-focus-area.d.ts +1 -0
  1003. package/dist/commands/review-focus-area.js +96 -0
  1004. package/dist/commands/review-focus.d.ts +4 -0
  1005. package/dist/commands/review-focus.js +196 -0
  1006. package/dist/commands/review-gate-config.d.ts +4 -0
  1007. package/dist/commands/review-gate-config.js +153 -0
  1008. package/dist/commands/review-gate.d.ts +4 -0
  1009. package/dist/commands/review-gate.js +212 -0
  1010. package/dist/commands/review-goal-track.d.ts +1 -0
  1011. package/dist/commands/review-goal-track.js +123 -0
  1012. package/dist/commands/review-guardrail.d.ts +4 -0
  1013. package/dist/commands/review-guardrail.js +155 -0
  1014. package/dist/commands/review-handoff.d.ts +4 -0
  1015. package/dist/commands/review-handoff.js +208 -0
  1016. package/dist/commands/review-health-check.d.ts +4 -0
  1017. package/dist/commands/review-health-check.js +148 -0
  1018. package/dist/commands/review-health-trend.d.ts +1 -0
  1019. package/dist/commands/review-health-trend.js +107 -0
  1020. package/dist/commands/review-history-compare.d.ts +4 -0
  1021. package/dist/commands/review-history-compare.js +93 -0
  1022. package/dist/commands/review-history-search.d.ts +4 -0
  1023. package/dist/commands/review-history-search.js +214 -0
  1024. package/dist/commands/review-ide-sync.d.ts +4 -0
  1025. package/dist/commands/review-ide-sync.js +91 -0
  1026. package/dist/commands/review-ignore-path.d.ts +4 -0
  1027. package/dist/commands/review-ignore-path.js +147 -0
  1028. package/dist/commands/review-ignore-pattern.d.ts +5 -0
  1029. package/dist/commands/review-ignore-pattern.js +138 -0
  1030. package/dist/commands/review-incident-link.d.ts +4 -0
  1031. package/dist/commands/review-incident-link.js +93 -0
  1032. package/dist/commands/review-incremental.d.ts +4 -0
  1033. package/dist/commands/review-incremental.js +128 -0
  1034. package/dist/commands/review-integration-health.d.ts +4 -0
  1035. package/dist/commands/review-integration-health.js +84 -0
  1036. package/dist/commands/review-integration-test.d.ts +4 -0
  1037. package/dist/commands/review-integration-test.js +145 -0
  1038. package/dist/commands/review-integration.d.ts +4 -0
  1039. package/dist/commands/review-integration.js +236 -0
  1040. package/dist/commands/review-interactive.d.ts +4 -0
  1041. package/dist/commands/review-interactive.js +85 -0
  1042. package/dist/commands/review-knowledge-capture.d.ts +1 -0
  1043. package/dist/commands/review-knowledge-capture.js +94 -0
  1044. package/dist/commands/review-language-profile.d.ts +4 -0
  1045. package/dist/commands/review-language-profile.js +72 -0
  1046. package/dist/commands/review-language-stats.d.ts +4 -0
  1047. package/dist/commands/review-language-stats.js +152 -0
  1048. package/dist/commands/review-lock-file.d.ts +4 -0
  1049. package/dist/commands/review-lock-file.js +153 -0
  1050. package/dist/commands/review-lock.d.ts +4 -0
  1051. package/dist/commands/review-lock.js +107 -0
  1052. package/dist/commands/review-log.d.ts +22 -0
  1053. package/dist/commands/review-log.js +164 -0
  1054. package/dist/commands/review-mentor-suggest.d.ts +1 -0
  1055. package/dist/commands/review-mentor-suggest.js +112 -0
  1056. package/dist/commands/review-merge-check.d.ts +4 -0
  1057. package/dist/commands/review-merge-check.js +101 -0
  1058. package/dist/commands/review-merge-config.d.ts +4 -0
  1059. package/dist/commands/review-merge-config.js +119 -0
  1060. package/dist/commands/review-merge-readiness.d.ts +1 -0
  1061. package/dist/commands/review-merge-readiness.js +90 -0
  1062. package/dist/commands/review-merge-request.d.ts +4 -0
  1063. package/dist/commands/review-merge-request.js +95 -0
  1064. package/dist/commands/review-merge.d.ts +4 -0
  1065. package/dist/commands/review-merge.js +145 -0
  1066. package/dist/commands/review-metric-export.d.ts +4 -0
  1067. package/dist/commands/review-metric-export.js +62 -0
  1068. package/dist/commands/review-milestone.d.ts +4 -0
  1069. package/dist/commands/review-milestone.js +136 -0
  1070. package/dist/commands/review-multi-repo-sync.d.ts +4 -0
  1071. package/dist/commands/review-multi-repo-sync.js +115 -0
  1072. package/dist/commands/review-multi-repo.d.ts +4 -0
  1073. package/dist/commands/review-multi-repo.js +145 -0
  1074. package/dist/commands/review-note.d.ts +4 -0
  1075. package/dist/commands/review-note.js +104 -0
  1076. package/dist/commands/review-notification-config.d.ts +4 -0
  1077. package/dist/commands/review-notification-config.js +122 -0
  1078. package/dist/commands/review-notification-digest.d.ts +4 -0
  1079. package/dist/commands/review-notification-digest.js +64 -0
  1080. package/dist/commands/review-notification.d.ts +4 -0
  1081. package/dist/commands/review-notification.js +126 -0
  1082. package/dist/commands/review-notify.d.ts +4 -0
  1083. package/dist/commands/review-notify.js +143 -0
  1084. package/dist/commands/review-offline.d.ts +4 -0
  1085. package/dist/commands/review-offline.js +125 -0
  1086. package/dist/commands/review-onboard-checklist.d.ts +4 -0
  1087. package/dist/commands/review-onboard-checklist.js +119 -0
  1088. package/dist/commands/review-onboard-wizard.d.ts +4 -0
  1089. package/dist/commands/review-onboard-wizard.js +92 -0
  1090. package/dist/commands/review-onboard.d.ts +4 -0
  1091. package/dist/commands/review-onboard.js +154 -0
  1092. package/dist/commands/review-onboarding-check.d.ts +1 -0
  1093. package/dist/commands/review-onboarding-check.js +93 -0
  1094. package/dist/commands/review-org-dashboard.d.ts +4 -0
  1095. package/dist/commands/review-org-dashboard.js +68 -0
  1096. package/dist/commands/review-output-filter.d.ts +4 -0
  1097. package/dist/commands/review-output-filter.js +112 -0
  1098. package/dist/commands/review-output-format.d.ts +4 -0
  1099. package/dist/commands/review-output-format.js +144 -0
  1100. package/dist/commands/review-output-transform.d.ts +4 -0
  1101. package/dist/commands/review-output-transform.js +119 -0
  1102. package/dist/commands/review-owner.d.ts +4 -0
  1103. package/dist/commands/review-owner.js +129 -0
  1104. package/dist/commands/review-parallel-diff.d.ts +4 -0
  1105. package/dist/commands/review-parallel-diff.js +146 -0
  1106. package/dist/commands/review-parallel-files.d.ts +7 -0
  1107. package/dist/commands/review-parallel-files.js +134 -0
  1108. package/dist/commands/review-parallel-run.d.ts +4 -0
  1109. package/dist/commands/review-parallel-run.js +116 -0
  1110. package/dist/commands/review-parallel.d.ts +4 -0
  1111. package/dist/commands/review-parallel.js +164 -0
  1112. package/dist/commands/review-perf-profile.d.ts +4 -0
  1113. package/dist/commands/review-perf-profile.js +98 -0
  1114. package/dist/commands/review-permission-model.d.ts +4 -0
  1115. package/dist/commands/review-permission-model.js +149 -0
  1116. package/dist/commands/review-pipeline-status.d.ts +4 -0
  1117. package/dist/commands/review-pipeline-status.js +54 -0
  1118. package/dist/commands/review-plugin-config.d.ts +4 -0
  1119. package/dist/commands/review-plugin-config.js +167 -0
  1120. package/dist/commands/review-plugin-list.d.ts +4 -0
  1121. package/dist/commands/review-plugin-list.js +99 -0
  1122. package/dist/commands/review-plugin-manage.d.ts +4 -0
  1123. package/dist/commands/review-plugin-manage.js +137 -0
  1124. package/dist/commands/review-plugin-status.d.ts +4 -0
  1125. package/dist/commands/review-plugin-status.js +53 -0
  1126. package/dist/commands/review-policy-enforce.d.ts +1 -0
  1127. package/dist/commands/review-policy-enforce.js +92 -0
  1128. package/dist/commands/review-policy-engine.d.ts +4 -0
  1129. package/dist/commands/review-policy-engine.js +135 -0
  1130. package/dist/commands/review-pr-comment-gen.d.ts +4 -0
  1131. package/dist/commands/review-pr-comment-gen.js +62 -0
  1132. package/dist/commands/review-pr-comment.d.ts +4 -0
  1133. package/dist/commands/review-pr-comment.js +106 -0
  1134. package/dist/commands/review-pr-label-suggest.d.ts +1 -0
  1135. package/dist/commands/review-pr-label-suggest.js +77 -0
  1136. package/dist/commands/review-pr-size-check.d.ts +1 -0
  1137. package/dist/commands/review-pr-size-check.js +98 -0
  1138. package/dist/commands/review-pr-template.d.ts +4 -0
  1139. package/dist/commands/review-pr-template.js +104 -0
  1140. package/dist/commands/review-preset-save.d.ts +4 -0
  1141. package/dist/commands/review-preset-save.js +159 -0
  1142. package/dist/commands/review-priority.d.ts +4 -0
  1143. package/dist/commands/review-priority.js +157 -0
  1144. package/dist/commands/review-profile.d.ts +4 -0
  1145. package/dist/commands/review-profile.js +168 -0
  1146. package/dist/commands/review-progress-bar.d.ts +4 -0
  1147. package/dist/commands/review-progress-bar.js +157 -0
  1148. package/dist/commands/review-progress-report.d.ts +1 -0
  1149. package/dist/commands/review-progress-report.js +95 -0
  1150. package/dist/commands/review-progress-track.d.ts +4 -0
  1151. package/dist/commands/review-progress-track.js +94 -0
  1152. package/dist/commands/review-quality-baseline.d.ts +1 -0
  1153. package/dist/commands/review-quality-baseline.js +134 -0
  1154. package/dist/commands/review-quality-gate.d.ts +1 -0
  1155. package/dist/commands/review-quality-gate.js +86 -0
  1156. package/dist/commands/review-quality-score.d.ts +4 -0
  1157. package/dist/commands/review-quality-score.js +127 -0
  1158. package/dist/commands/review-quality-trend.d.ts +4 -0
  1159. package/dist/commands/review-quality-trend.js +57 -0
  1160. package/dist/commands/review-queue.d.ts +33 -0
  1161. package/dist/commands/review-queue.js +225 -0
  1162. package/dist/commands/review-quickstart.d.ts +4 -0
  1163. package/dist/commands/review-quickstart.js +107 -0
  1164. package/dist/commands/review-quota-check.d.ts +4 -0
  1165. package/dist/commands/review-quota-check.js +97 -0
  1166. package/dist/commands/review-quota.d.ts +4 -0
  1167. package/dist/commands/review-quota.js +126 -0
  1168. package/dist/commands/review-rate-limit.d.ts +4 -0
  1169. package/dist/commands/review-rate-limit.js +130 -0
  1170. package/dist/commands/review-readiness-check.d.ts +1 -0
  1171. package/dist/commands/review-readiness-check.js +98 -0
  1172. package/dist/commands/review-receipt.d.ts +4 -0
  1173. package/dist/commands/review-receipt.js +220 -0
  1174. package/dist/commands/review-release-gate.d.ts +1 -0
  1175. package/dist/commands/review-release-gate.js +81 -0
  1176. package/dist/commands/review-replay.d.ts +8 -0
  1177. package/dist/commands/review-replay.js +264 -0
  1178. package/dist/commands/review-repo-onboard.d.ts +4 -0
  1179. package/dist/commands/review-repo-onboard.js +114 -0
  1180. package/dist/commands/review-report-archive.d.ts +4 -0
  1181. package/dist/commands/review-report-archive.js +100 -0
  1182. package/dist/commands/review-report-merge.d.ts +4 -0
  1183. package/dist/commands/review-report-merge.js +90 -0
  1184. package/dist/commands/review-report-pdf.d.ts +4 -0
  1185. package/dist/commands/review-report-pdf.js +163 -0
  1186. package/dist/commands/review-report-schedule.d.ts +4 -0
  1187. package/dist/commands/review-report-schedule.js +96 -0
  1188. package/dist/commands/review-retrospective.d.ts +1 -0
  1189. package/dist/commands/review-retrospective.js +118 -0
  1190. package/dist/commands/review-retry.d.ts +4 -0
  1191. package/dist/commands/review-retry.js +91 -0
  1192. package/dist/commands/review-review-cadence.d.ts +1 -0
  1193. package/dist/commands/review-review-cadence.js +85 -0
  1194. package/dist/commands/review-review-comments.d.ts +4 -0
  1195. package/dist/commands/review-review-comments.js +84 -0
  1196. package/dist/commands/review-reviewer-match.d.ts +1 -0
  1197. package/dist/commands/review-reviewer-match.js +108 -0
  1198. package/dist/commands/review-risk-matrix.d.ts +1 -0
  1199. package/dist/commands/review-risk-matrix.js +96 -0
  1200. package/dist/commands/review-risk-score.d.ts +4 -0
  1201. package/dist/commands/review-risk-score.js +156 -0
  1202. package/dist/commands/review-role-assignment.d.ts +4 -0
  1203. package/dist/commands/review-role-assignment.js +98 -0
  1204. package/dist/commands/review-rollback.d.ts +4 -0
  1205. package/dist/commands/review-rollback.js +171 -0
  1206. package/dist/commands/review-rollout-plan.d.ts +4 -0
  1207. package/dist/commands/review-rollout-plan.js +123 -0
  1208. package/dist/commands/review-rule-filter.d.ts +4 -0
  1209. package/dist/commands/review-rule-filter.js +116 -0
  1210. package/dist/commands/review-rule-stats.d.ts +4 -0
  1211. package/dist/commands/review-rule-stats.js +161 -0
  1212. package/dist/commands/review-sandbox.d.ts +4 -0
  1213. package/dist/commands/review-sandbox.js +191 -0
  1214. package/dist/commands/review-schedule.d.ts +4 -0
  1215. package/dist/commands/review-schedule.js +169 -0
  1216. package/dist/commands/review-scope-limit.d.ts +4 -0
  1217. package/dist/commands/review-scope-limit.js +100 -0
  1218. package/dist/commands/review-scope-lock.d.ts +7 -0
  1219. package/dist/commands/review-scope-lock.js +138 -0
  1220. package/dist/commands/review-scope-select.d.ts +4 -0
  1221. package/dist/commands/review-scope-select.js +98 -0
  1222. package/dist/commands/review-scope-suggest.d.ts +1 -0
  1223. package/dist/commands/review-scope-suggest.js +112 -0
  1224. package/dist/commands/review-scope.d.ts +4 -0
  1225. package/dist/commands/review-scope.js +197 -0
  1226. package/dist/commands/review-score-history.d.ts +4 -0
  1227. package/dist/commands/review-score-history.js +137 -0
  1228. package/dist/commands/review-security-posture.d.ts +1 -0
  1229. package/dist/commands/review-security-posture.js +105 -0
  1230. package/dist/commands/review-session-replay.d.ts +4 -0
  1231. package/dist/commands/review-session-replay.js +81 -0
  1232. package/dist/commands/review-session-save.d.ts +4 -0
  1233. package/dist/commands/review-session-save.js +173 -0
  1234. package/dist/commands/review-session.d.ts +4 -0
  1235. package/dist/commands/review-session.js +150 -0
  1236. package/dist/commands/review-skip-list.d.ts +4 -0
  1237. package/dist/commands/review-skip-list.js +135 -0
  1238. package/dist/commands/review-skip-rule.d.ts +4 -0
  1239. package/dist/commands/review-skip-rule.js +105 -0
  1240. package/dist/commands/review-sla-config.d.ts +4 -0
  1241. package/dist/commands/review-sla-config.js +88 -0
  1242. package/dist/commands/review-slack-format.d.ts +4 -0
  1243. package/dist/commands/review-slack-format.js +113 -0
  1244. package/dist/commands/review-snapshot-diff.d.ts +4 -0
  1245. package/dist/commands/review-snapshot-diff.js +100 -0
  1246. package/dist/commands/review-sprint-plan.d.ts +1 -0
  1247. package/dist/commands/review-sprint-plan.js +79 -0
  1248. package/dist/commands/review-stakeholder-notify.d.ts +1 -0
  1249. package/dist/commands/review-stakeholder-notify.js +134 -0
  1250. package/dist/commands/review-stakeholder-report.d.ts +4 -0
  1251. package/dist/commands/review-stakeholder-report.js +75 -0
  1252. package/dist/commands/review-stale-finding-clean.d.ts +1 -0
  1253. package/dist/commands/review-stale-finding-clean.js +81 -0
  1254. package/dist/commands/review-standup.d.ts +4 -0
  1255. package/dist/commands/review-standup.js +95 -0
  1256. package/dist/commands/review-stats.d.ts +4 -0
  1257. package/dist/commands/review-stats.js +175 -0
  1258. package/dist/commands/review-status-badge.d.ts +4 -0
  1259. package/dist/commands/review-status-badge.js +120 -0
  1260. package/dist/commands/review-streak.d.ts +4 -0
  1261. package/dist/commands/review-streak.js +150 -0
  1262. package/dist/commands/review-summary-dashboard.d.ts +4 -0
  1263. package/dist/commands/review-summary-dashboard.js +96 -0
  1264. package/dist/commands/review-summary-email.d.ts +4 -0
  1265. package/dist/commands/review-summary-email.js +102 -0
  1266. package/dist/commands/review-summary.d.ts +4 -0
  1267. package/dist/commands/review-summary.js +174 -0
  1268. package/dist/commands/review-tag-manager.d.ts +4 -0
  1269. package/dist/commands/review-tag-manager.js +128 -0
  1270. package/dist/commands/review-tag.d.ts +4 -0
  1271. package/dist/commands/review-tag.js +136 -0
  1272. package/dist/commands/review-team-analytics.d.ts +1 -0
  1273. package/dist/commands/review-team-analytics.js +94 -0
  1274. package/dist/commands/review-team-assign.d.ts +7 -0
  1275. package/dist/commands/review-team-assign.js +211 -0
  1276. package/dist/commands/review-team-coverage.d.ts +1 -0
  1277. package/dist/commands/review-team-coverage.js +95 -0
  1278. package/dist/commands/review-team-dashboard.d.ts +4 -0
  1279. package/dist/commands/review-team-dashboard.js +98 -0
  1280. package/dist/commands/review-team-rotation.d.ts +1 -0
  1281. package/dist/commands/review-team-rotation.js +99 -0
  1282. package/dist/commands/review-team-skill-map.d.ts +1 -0
  1283. package/dist/commands/review-team-skill-map.js +102 -0
  1284. package/dist/commands/review-team-stats.d.ts +4 -0
  1285. package/dist/commands/review-team-stats.js +97 -0
  1286. package/dist/commands/review-team-summary.d.ts +4 -0
  1287. package/dist/commands/review-team-summary.js +155 -0
  1288. package/dist/commands/review-team-velocity.d.ts +1 -0
  1289. package/dist/commands/review-team-velocity.js +103 -0
  1290. package/dist/commands/review-template-export.d.ts +4 -0
  1291. package/dist/commands/review-template-export.js +146 -0
  1292. package/dist/commands/review-template-library.d.ts +4 -0
  1293. package/dist/commands/review-template-library.js +155 -0
  1294. package/dist/commands/review-template-suggest.d.ts +1 -0
  1295. package/dist/commands/review-template-suggest.js +119 -0
  1296. package/dist/commands/review-template.d.ts +4 -0
  1297. package/dist/commands/review-template.js +212 -0
  1298. package/dist/commands/review-tenant-config.d.ts +4 -0
  1299. package/dist/commands/review-tenant-config.js +116 -0
  1300. package/dist/commands/review-threshold-tune.d.ts +4 -0
  1301. package/dist/commands/review-threshold-tune.js +135 -0
  1302. package/dist/commands/review-timeline.d.ts +4 -0
  1303. package/dist/commands/review-timeline.js +76 -0
  1304. package/dist/commands/review-token-budget.d.ts +4 -0
  1305. package/dist/commands/review-token-budget.js +117 -0
  1306. package/dist/commands/review-velocity-track.d.ts +1 -0
  1307. package/dist/commands/review-velocity-track.js +94 -0
  1308. package/dist/commands/review-watch-mode.d.ts +7 -0
  1309. package/dist/commands/review-watch-mode.js +132 -0
  1310. package/dist/commands/review-webhook-dispatch.d.ts +4 -0
  1311. package/dist/commands/review-webhook-dispatch.js +99 -0
  1312. package/dist/commands/review-webhook-notify.d.ts +4 -0
  1313. package/dist/commands/review-webhook-notify.js +145 -0
  1314. package/dist/commands/review-webhook.d.ts +4 -0
  1315. package/dist/commands/review-webhook.js +140 -0
  1316. package/dist/commands/review-whitelist.d.ts +4 -0
  1317. package/dist/commands/review-whitelist.js +150 -0
  1318. package/dist/commands/review-workflow-suggest.d.ts +1 -0
  1319. package/dist/commands/review-workflow-suggest.js +129 -0
  1320. package/dist/commands/review-workload-balance.d.ts +1 -0
  1321. package/dist/commands/review-workload-balance.js +86 -0
  1322. package/dist/commands/review-workspace-init.d.ts +4 -0
  1323. package/dist/commands/review-workspace-init.js +104 -0
  1324. package/dist/commands/review-workspace-scan.d.ts +4 -0
  1325. package/dist/commands/review-workspace-scan.js +144 -0
  1326. package/dist/commands/review.d.ts +155 -0
  1327. package/dist/commands/review.js +1114 -0
  1328. package/dist/commands/risk-heatmap.d.ts +7 -0
  1329. package/dist/commands/risk-heatmap.js +223 -0
  1330. package/dist/commands/rollback-safety.d.ts +4 -0
  1331. package/dist/commands/rollback-safety.js +191 -0
  1332. package/dist/commands/rule-catalog.d.ts +4 -0
  1333. package/dist/commands/rule-catalog.js +128 -0
  1334. package/dist/commands/rule-metrics.d.ts +43 -0
  1335. package/dist/commands/rule-metrics.js +113 -0
  1336. package/dist/commands/rule-owner.d.ts +30 -0
  1337. package/dist/commands/rule-owner.js +181 -0
  1338. package/dist/commands/rule-share.d.ts +34 -0
  1339. package/dist/commands/rule-share.js +202 -0
  1340. package/dist/commands/rule-test.d.ts +4 -0
  1341. package/dist/commands/rule-test.js +201 -0
  1342. package/dist/commands/rule.d.ts +114 -0
  1343. package/dist/commands/rule.js +295 -0
  1344. package/dist/commands/sbom-export.d.ts +7 -0
  1345. package/dist/commands/sbom-export.js +161 -0
  1346. package/dist/commands/scaffold-plugin.d.ts +15 -0
  1347. package/dist/commands/scaffold-plugin.js +270 -0
  1348. package/dist/commands/secret-age.d.ts +5 -0
  1349. package/dist/commands/secret-age.js +214 -0
  1350. package/dist/commands/secret-scan.d.ts +7 -0
  1351. package/dist/commands/secret-scan.js +244 -0
  1352. package/dist/commands/security-maturity.d.ts +7 -0
  1353. package/dist/commands/security-maturity.js +312 -0
  1354. package/dist/commands/security-theater.d.ts +4 -0
  1355. package/dist/commands/security-theater.js +278 -0
  1356. package/dist/commands/setup-wizard.d.ts +4 -0
  1357. package/dist/commands/setup-wizard.js +174 -0
  1358. package/dist/commands/severity-tune.d.ts +4 -0
  1359. package/dist/commands/severity-tune.js +208 -0
  1360. package/dist/commands/sla-track.d.ts +56 -0
  1361. package/dist/commands/sla-track.js +268 -0
  1362. package/dist/commands/smart-output.d.ts +38 -0
  1363. package/dist/commands/smart-output.js +175 -0
  1364. package/dist/commands/smart-select.d.ts +26 -0
  1365. package/dist/commands/smart-select.js +345 -0
  1366. package/dist/commands/snapshot.d.ts +139 -0
  1367. package/dist/commands/snapshot.js +478 -0
  1368. package/dist/commands/snippet-eval.d.ts +7 -0
  1369. package/dist/commands/snippet-eval.js +223 -0
  1370. package/dist/commands/spec-conform.d.ts +4 -0
  1371. package/dist/commands/spec-conform.js +304 -0
  1372. package/dist/commands/stale-pattern.d.ts +4 -0
  1373. package/dist/commands/stale-pattern.js +293 -0
  1374. package/dist/commands/state-integrity.d.ts +4 -0
  1375. package/dist/commands/state-integrity.js +283 -0
  1376. package/dist/commands/suppress.d.ts +39 -0
  1377. package/dist/commands/suppress.js +203 -0
  1378. package/dist/commands/team-config.d.ts +4 -0
  1379. package/dist/commands/team-config.js +234 -0
  1380. package/dist/commands/team-leaderboard.d.ts +24 -0
  1381. package/dist/commands/team-leaderboard.js +227 -0
  1382. package/dist/commands/team-rules-sync.d.ts +7 -0
  1383. package/dist/commands/team-rules-sync.js +250 -0
  1384. package/dist/commands/team-trust.d.ts +7 -0
  1385. package/dist/commands/team-trust.js +174 -0
  1386. package/dist/commands/test-correlate.d.ts +7 -0
  1387. package/dist/commands/test-correlate.js +221 -0
  1388. package/dist/commands/test-isolation.d.ts +5 -0
  1389. package/dist/commands/test-isolation.js +234 -0
  1390. package/dist/commands/test-quality.d.ts +5 -0
  1391. package/dist/commands/test-quality.js +160 -0
  1392. package/dist/commands/test-suggest.d.ts +8 -0
  1393. package/dist/commands/test-suggest.js +247 -0
  1394. package/dist/commands/ticket-sync.d.ts +25 -0
  1395. package/dist/commands/ticket-sync.js +235 -0
  1396. package/dist/commands/timeout-audit.d.ts +4 -0
  1397. package/dist/commands/timeout-audit.js +210 -0
  1398. package/dist/commands/trace.d.ts +64 -0
  1399. package/dist/commands/trace.js +245 -0
  1400. package/dist/commands/trend-report.d.ts +4 -0
  1401. package/dist/commands/trend-report.js +148 -0
  1402. package/dist/commands/triage.d.ts +15 -0
  1403. package/dist/commands/triage.js +171 -0
  1404. package/dist/commands/trust-adaptive.d.ts +8 -0
  1405. package/dist/commands/trust-adaptive.js +193 -0
  1406. package/dist/commands/trust-ramp.d.ts +29 -0
  1407. package/dist/commands/trust-ramp.js +189 -0
  1408. package/dist/commands/tune.d.ts +24 -0
  1409. package/dist/commands/tune.js +380 -0
  1410. package/dist/commands/type-boundary.d.ts +4 -0
  1411. package/dist/commands/type-boundary.js +235 -0
  1412. package/dist/commands/upload.d.ts +13 -0
  1413. package/dist/commands/upload.js +172 -0
  1414. package/dist/commands/validate-config.d.ts +16 -0
  1415. package/dist/commands/validate-config.js +267 -0
  1416. package/dist/commands/vendor-lock-detect.d.ts +7 -0
  1417. package/dist/commands/vendor-lock-detect.js +288 -0
  1418. package/dist/commands/vote.d.ts +31 -0
  1419. package/dist/commands/vote.js +200 -0
  1420. package/dist/commands/warm-cache.d.ts +30 -0
  1421. package/dist/commands/warm-cache.js +165 -0
  1422. package/dist/commands/watch-judge.d.ts +7 -0
  1423. package/dist/commands/watch-judge.js +179 -0
  1424. package/dist/commands/watch.d.ts +22 -0
  1425. package/dist/commands/watch.js +147 -0
  1426. package/dist/comparison.d.ts +67 -0
  1427. package/dist/comparison.js +253 -0
  1428. package/dist/config.d.ts +108 -0
  1429. package/dist/config.js +694 -0
  1430. package/dist/context/context-snippets.d.ts +15 -0
  1431. package/dist/context/context-snippets.js +36 -0
  1432. package/dist/context/embedding-cache.d.ts +30 -0
  1433. package/dist/context/embedding-cache.js +48 -0
  1434. package/dist/data-adapter.d.ts +123 -0
  1435. package/dist/data-adapter.js +212 -0
  1436. package/dist/dedup.d.ts +105 -0
  1437. package/dist/dedup.js +606 -0
  1438. package/dist/disk-cache.d.ts +59 -0
  1439. package/dist/disk-cache.js +236 -0
  1440. package/dist/errors.d.ts +43 -0
  1441. package/dist/errors.js +63 -0
  1442. package/dist/escalation.d.ts +100 -0
  1443. package/dist/escalation.js +292 -0
  1444. package/dist/evaluation-session.d.ts +74 -0
  1445. package/dist/evaluation-session.js +152 -0
  1446. package/dist/evaluators/accessibility.d.ts +2 -0
  1447. package/dist/evaluators/accessibility.js +559 -0
  1448. package/dist/evaluators/agent-instructions.d.ts +2 -0
  1449. package/dist/evaluators/agent-instructions.js +214 -0
  1450. package/dist/evaluators/ai-code-safety.d.ts +8 -0
  1451. package/dist/evaluators/ai-code-safety.js +410 -0
  1452. package/dist/evaluators/api-contract.d.ts +9 -0
  1453. package/dist/evaluators/api-contract.js +203 -0
  1454. package/dist/evaluators/api-design.d.ts +2 -0
  1455. package/dist/evaluators/api-design.js +260 -0
  1456. package/dist/evaluators/app-builder.d.ts +33 -0
  1457. package/dist/evaluators/app-builder.js +155 -0
  1458. package/dist/evaluators/authentication.d.ts +2 -0
  1459. package/dist/evaluators/authentication.js +455 -0
  1460. package/dist/evaluators/backwards-compatibility.d.ts +2 -0
  1461. package/dist/evaluators/backwards-compatibility.js +168 -0
  1462. package/dist/evaluators/caching.d.ts +2 -0
  1463. package/dist/evaluators/caching.js +171 -0
  1464. package/dist/evaluators/ci-cd.d.ts +2 -0
  1465. package/dist/evaluators/ci-cd.js +218 -0
  1466. package/dist/evaluators/cloud-readiness.d.ts +2 -0
  1467. package/dist/evaluators/cloud-readiness.js +231 -0
  1468. package/dist/evaluators/code-structure.d.ts +21 -0
  1469. package/dist/evaluators/code-structure.js +195 -0
  1470. package/dist/evaluators/compliance.d.ts +2 -0
  1471. package/dist/evaluators/compliance.js +329 -0
  1472. package/dist/evaluators/concurrency.d.ts +2 -0
  1473. package/dist/evaluators/concurrency.js +307 -0
  1474. package/dist/evaluators/configuration-management.d.ts +2 -0
  1475. package/dist/evaluators/configuration-management.js +232 -0
  1476. package/dist/evaluators/cost-effectiveness.d.ts +2 -0
  1477. package/dist/evaluators/cost-effectiveness.js +418 -0
  1478. package/dist/evaluators/cybersecurity.d.ts +2 -0
  1479. package/dist/evaluators/cybersecurity.js +1197 -0
  1480. package/dist/evaluators/data-security.d.ts +2 -0
  1481. package/dist/evaluators/data-security.js +467 -0
  1482. package/dist/evaluators/data-sovereignty.d.ts +2 -0
  1483. package/dist/evaluators/data-sovereignty.js +495 -0
  1484. package/dist/evaluators/database.d.ts +2 -0
  1485. package/dist/evaluators/database.js +240 -0
  1486. package/dist/evaluators/dependencies.d.ts +5 -0
  1487. package/dist/evaluators/dependencies.js +228 -0
  1488. package/dist/evaluators/dependency-health.d.ts +2 -0
  1489. package/dist/evaluators/dependency-health.js +477 -0
  1490. package/dist/evaluators/documentation.d.ts +2 -0
  1491. package/dist/evaluators/documentation.js +432 -0
  1492. package/dist/evaluators/error-handling.d.ts +2 -0
  1493. package/dist/evaluators/error-handling.js +426 -0
  1494. package/dist/evaluators/ethics-bias.d.ts +2 -0
  1495. package/dist/evaluators/ethics-bias.js +263 -0
  1496. package/dist/evaluators/false-positive-review.d.ts +21 -0
  1497. package/dist/evaluators/false-positive-review.js +1246 -0
  1498. package/dist/evaluators/framework-rules.d.ts +58 -0
  1499. package/dist/evaluators/framework-rules.js +291 -0
  1500. package/dist/evaluators/framework-safety.d.ts +12 -0
  1501. package/dist/evaluators/framework-safety.js +1205 -0
  1502. package/dist/evaluators/hallucination-detection.d.ts +2 -0
  1503. package/dist/evaluators/hallucination-detection.js +1250 -0
  1504. package/dist/evaluators/iac-security.d.ts +8 -0
  1505. package/dist/evaluators/iac-security.js +701 -0
  1506. package/dist/evaluators/index.d.ts +167 -0
  1507. package/dist/evaluators/index.js +994 -0
  1508. package/dist/evaluators/intent-alignment.d.ts +18 -0
  1509. package/dist/evaluators/intent-alignment.js +405 -0
  1510. package/dist/evaluators/internationalization.d.ts +2 -0
  1511. package/dist/evaluators/internationalization.js +287 -0
  1512. package/dist/evaluators/judge-selector.d.ts +19 -0
  1513. package/dist/evaluators/judge-selector.js +141 -0
  1514. package/dist/evaluators/logging-privacy.d.ts +2 -0
  1515. package/dist/evaluators/logging-privacy.js +190 -0
  1516. package/dist/evaluators/logic-review.d.ts +2 -0
  1517. package/dist/evaluators/logic-review.js +289 -0
  1518. package/dist/evaluators/maintainability.d.ts +2 -0
  1519. package/dist/evaluators/maintainability.js +430 -0
  1520. package/dist/evaluators/model-fingerprint.d.ts +2 -0
  1521. package/dist/evaluators/model-fingerprint.js +151 -0
  1522. package/dist/evaluators/multi-turn-coherence.d.ts +13 -0
  1523. package/dist/evaluators/multi-turn-coherence.js +149 -0
  1524. package/dist/evaluators/observability.d.ts +2 -0
  1525. package/dist/evaluators/observability.js +238 -0
  1526. package/dist/evaluators/over-engineering.d.ts +2 -0
  1527. package/dist/evaluators/over-engineering.js +160 -0
  1528. package/dist/evaluators/performance.d.ts +2 -0
  1529. package/dist/evaluators/performance.js +649 -0
  1530. package/dist/evaluators/portability.d.ts +2 -0
  1531. package/dist/evaluators/portability.js +254 -0
  1532. package/dist/evaluators/project.d.ts +48 -0
  1533. package/dist/evaluators/project.js +817 -0
  1534. package/dist/evaluators/rate-limiting.d.ts +2 -0
  1535. package/dist/evaluators/rate-limiting.js +193 -0
  1536. package/dist/evaluators/recall-boost.d.ts +27 -0
  1537. package/dist/evaluators/recall-boost.js +409 -0
  1538. package/dist/evaluators/reliability.d.ts +2 -0
  1539. package/dist/evaluators/reliability.js +245 -0
  1540. package/dist/evaluators/scalability.d.ts +2 -0
  1541. package/dist/evaluators/scalability.js +230 -0
  1542. package/dist/evaluators/security.d.ts +12 -0
  1543. package/dist/evaluators/security.js +1013 -0
  1544. package/dist/evaluators/shared.d.ts +219 -0
  1545. package/dist/evaluators/shared.js +1169 -0
  1546. package/dist/evaluators/software-practices.d.ts +2 -0
  1547. package/dist/evaluators/software-practices.js +395 -0
  1548. package/dist/evaluators/suppressions.d.ts +49 -0
  1549. package/dist/evaluators/suppressions.js +185 -0
  1550. package/dist/evaluators/testing.d.ts +2 -0
  1551. package/dist/evaluators/testing.js +348 -0
  1552. package/dist/evaluators/ux.d.ts +2 -0
  1553. package/dist/evaluators/ux.js +309 -0
  1554. package/dist/evaluators/v2.d.ts +26 -0
  1555. package/dist/evaluators/v2.js +354 -0
  1556. package/dist/ext-to-lang.d.ts +16 -0
  1557. package/dist/ext-to-lang.js +60 -0
  1558. package/dist/feedback-loop.d.ts +62 -0
  1559. package/dist/feedback-loop.js +179 -0
  1560. package/dist/finding-lifecycle.d.ts +215 -0
  1561. package/dist/finding-lifecycle.js +547 -0
  1562. package/dist/fingerprint.d.ts +39 -0
  1563. package/dist/fingerprint.js +179 -0
  1564. package/dist/fix-history.d.ts +103 -0
  1565. package/dist/fix-history.js +164 -0
  1566. package/dist/formatters/badge.d.ts +16 -0
  1567. package/dist/formatters/badge.js +78 -0
  1568. package/dist/formatters/codeclimate.d.ts +24 -0
  1569. package/dist/formatters/codeclimate.js +80 -0
  1570. package/dist/formatters/csv.d.ts +16 -0
  1571. package/dist/formatters/csv.js +53 -0
  1572. package/dist/formatters/diagnostics.d.ts +81 -0
  1573. package/dist/formatters/diagnostics.js +152 -0
  1574. package/dist/formatters/github-actions.d.ts +6 -0
  1575. package/dist/formatters/github-actions.js +68 -0
  1576. package/dist/formatters/html.d.ts +12 -0
  1577. package/dist/formatters/html.js +194 -0
  1578. package/dist/formatters/junit.d.ts +6 -0
  1579. package/dist/formatters/junit.js +68 -0
  1580. package/dist/formatters/pdf.d.ts +12 -0
  1581. package/dist/formatters/pdf.js +114 -0
  1582. package/dist/formatters/sarif.d.ts +92 -0
  1583. package/dist/formatters/sarif.js +256 -0
  1584. package/dist/formatters/shared.d.ts +4 -0
  1585. package/dist/formatters/shared.js +29 -0
  1586. package/dist/git-diff.d.ts +62 -0
  1587. package/dist/git-diff.js +282 -0
  1588. package/dist/github-app.d.ts +152 -0
  1589. package/dist/github-app.js +716 -0
  1590. package/dist/import-resolver.d.ts +51 -0
  1591. package/dist/import-resolver.js +213 -0
  1592. package/dist/index.d.ts +4 -0
  1593. package/dist/index.js +38 -0
  1594. package/dist/judge-registry.d.ts +156 -0
  1595. package/dist/judge-registry.js +272 -0
  1596. package/dist/judges/accessibility.d.ts +2 -0
  1597. package/dist/judges/accessibility.js +46 -0
  1598. package/dist/judges/agent-instructions.d.ts +2 -0
  1599. package/dist/judges/agent-instructions.js +46 -0
  1600. package/dist/judges/ai-code-safety.d.ts +2 -0
  1601. package/dist/judges/ai-code-safety.js +57 -0
  1602. package/dist/judges/api-contract.d.ts +2 -0
  1603. package/dist/judges/api-contract.js +40 -0
  1604. package/dist/judges/api-design.d.ts +2 -0
  1605. package/dist/judges/api-design.js +57 -0
  1606. package/dist/judges/authentication.d.ts +2 -0
  1607. package/dist/judges/authentication.js +63 -0
  1608. package/dist/judges/backwards-compatibility.d.ts +2 -0
  1609. package/dist/judges/backwards-compatibility.js +46 -0
  1610. package/dist/judges/caching.d.ts +2 -0
  1611. package/dist/judges/caching.js +46 -0
  1612. package/dist/judges/ci-cd.d.ts +2 -0
  1613. package/dist/judges/ci-cd.js +46 -0
  1614. package/dist/judges/cloud-readiness.d.ts +2 -0
  1615. package/dist/judges/cloud-readiness.js +53 -0
  1616. package/dist/judges/code-structure.d.ts +2 -0
  1617. package/dist/judges/code-structure.js +50 -0
  1618. package/dist/judges/compliance.d.ts +2 -0
  1619. package/dist/judges/compliance.js +49 -0
  1620. package/dist/judges/concurrency.d.ts +2 -0
  1621. package/dist/judges/concurrency.js +48 -0
  1622. package/dist/judges/configuration-management.d.ts +2 -0
  1623. package/dist/judges/configuration-management.js +46 -0
  1624. package/dist/judges/cost-effectiveness.d.ts +2 -0
  1625. package/dist/judges/cost-effectiveness.js +42 -0
  1626. package/dist/judges/cybersecurity.d.ts +2 -0
  1627. package/dist/judges/cybersecurity.js +63 -0
  1628. package/dist/judges/data-security.d.ts +2 -0
  1629. package/dist/judges/data-security.js +50 -0
  1630. package/dist/judges/data-sovereignty.d.ts +2 -0
  1631. package/dist/judges/data-sovereignty.js +60 -0
  1632. package/dist/judges/database.d.ts +2 -0
  1633. package/dist/judges/database.js +51 -0
  1634. package/dist/judges/dependency-health.d.ts +2 -0
  1635. package/dist/judges/dependency-health.js +48 -0
  1636. package/dist/judges/documentation.d.ts +2 -0
  1637. package/dist/judges/documentation.js +55 -0
  1638. package/dist/judges/error-handling.d.ts +2 -0
  1639. package/dist/judges/error-handling.js +55 -0
  1640. package/dist/judges/ethics-bias.d.ts +2 -0
  1641. package/dist/judges/ethics-bias.js +48 -0
  1642. package/dist/judges/false-positive-review.d.ts +2 -0
  1643. package/dist/judges/false-positive-review.js +85 -0
  1644. package/dist/judges/framework-safety.d.ts +2 -0
  1645. package/dist/judges/framework-safety.js +49 -0
  1646. package/dist/judges/hallucination-detection.d.ts +2 -0
  1647. package/dist/judges/hallucination-detection.js +48 -0
  1648. package/dist/judges/iac-security.d.ts +2 -0
  1649. package/dist/judges/iac-security.js +47 -0
  1650. package/dist/judges/index.d.ts +88 -0
  1651. package/dist/judges/index.js +128 -0
  1652. package/dist/judges/intent-alignment.d.ts +2 -0
  1653. package/dist/judges/intent-alignment.js +46 -0
  1654. package/dist/judges/internationalization.d.ts +2 -0
  1655. package/dist/judges/internationalization.js +44 -0
  1656. package/dist/judges/logging-privacy.d.ts +2 -0
  1657. package/dist/judges/logging-privacy.js +46 -0
  1658. package/dist/judges/logic-review.d.ts +2 -0
  1659. package/dist/judges/logic-review.js +36 -0
  1660. package/dist/judges/maintainability.d.ts +2 -0
  1661. package/dist/judges/maintainability.js +46 -0
  1662. package/dist/judges/model-fingerprint.d.ts +2 -0
  1663. package/dist/judges/model-fingerprint.js +35 -0
  1664. package/dist/judges/multi-turn-coherence.d.ts +2 -0
  1665. package/dist/judges/multi-turn-coherence.js +39 -0
  1666. package/dist/judges/observability.d.ts +2 -0
  1667. package/dist/judges/observability.js +54 -0
  1668. package/dist/judges/over-engineering.d.ts +2 -0
  1669. package/dist/judges/over-engineering.js +50 -0
  1670. package/dist/judges/performance.d.ts +2 -0
  1671. package/dist/judges/performance.js +46 -0
  1672. package/dist/judges/portability.d.ts +2 -0
  1673. package/dist/judges/portability.js +46 -0
  1674. package/dist/judges/rate-limiting.d.ts +2 -0
  1675. package/dist/judges/rate-limiting.js +55 -0
  1676. package/dist/judges/reliability.d.ts +2 -0
  1677. package/dist/judges/reliability.js +57 -0
  1678. package/dist/judges/scalability.d.ts +2 -0
  1679. package/dist/judges/scalability.js +52 -0
  1680. package/dist/judges/security.d.ts +2 -0
  1681. package/dist/judges/security.js +64 -0
  1682. package/dist/judges/software-practices.d.ts +2 -0
  1683. package/dist/judges/software-practices.js +56 -0
  1684. package/dist/judges/testing.d.ts +2 -0
  1685. package/dist/judges/testing.js +54 -0
  1686. package/dist/judges/ux.d.ts +2 -0
  1687. package/dist/judges/ux.js +46 -0
  1688. package/dist/language-patterns.d.ts +653 -0
  1689. package/dist/language-patterns.js +851 -0
  1690. package/dist/parallel.d.ts +52 -0
  1691. package/dist/parallel.js +157 -0
  1692. package/dist/patches/apply.d.ts +15 -0
  1693. package/dist/patches/apply.js +37 -0
  1694. package/dist/patches/index.d.ts +9 -0
  1695. package/dist/patches/index.js +2544 -0
  1696. package/dist/plugins.d.ts +59 -0
  1697. package/dist/plugins.js +76 -0
  1698. package/dist/presets.d.ts +35 -0
  1699. package/dist/presets.js +406 -0
  1700. package/dist/probabilistic/llm-response-validator.d.ts +26 -0
  1701. package/dist/probabilistic/llm-response-validator.js +122 -0
  1702. package/dist/reports/public-repo-report.d.ts +42 -0
  1703. package/dist/reports/public-repo-report.js +579 -0
  1704. package/dist/review-conversation.d.ts +87 -0
  1705. package/dist/review-conversation.js +307 -0
  1706. package/dist/sast-integration.d.ts +112 -0
  1707. package/dist/sast-integration.js +215 -0
  1708. package/dist/scoring.d.ts +36 -0
  1709. package/dist/scoring.js +437 -0
  1710. package/dist/security-ids.d.ts +23 -0
  1711. package/dist/security-ids.js +239 -0
  1712. package/dist/skill-loader.d.ts +33 -0
  1713. package/dist/skill-loader.js +167 -0
  1714. package/dist/tools/command-safety.d.ts +13 -0
  1715. package/dist/tools/command-safety.js +95 -0
  1716. package/dist/tools/deep-review.d.ts +38 -0
  1717. package/dist/tools/deep-review.js +302 -0
  1718. package/dist/tools/prompts.d.ts +27 -0
  1719. package/dist/tools/prompts.js +122 -0
  1720. package/dist/tools/register-evaluation.d.ts +6 -0
  1721. package/dist/tools/register-evaluation.js +587 -0
  1722. package/dist/tools/register-fix.d.ts +5 -0
  1723. package/dist/tools/register-fix.js +175 -0
  1724. package/dist/tools/register-resources.d.ts +6 -0
  1725. package/dist/tools/register-resources.js +177 -0
  1726. package/dist/tools/register-review.d.ts +6 -0
  1727. package/dist/tools/register-review.js +564 -0
  1728. package/dist/tools/register-scaffold.d.ts +2 -0
  1729. package/dist/tools/register-scaffold.js +398 -0
  1730. package/dist/tools/register-workflow.d.ts +6 -0
  1731. package/dist/tools/register-workflow.js +1037 -0
  1732. package/dist/tools/register-workspace.d.ts +2 -0
  1733. package/dist/tools/register-workspace.js +214 -0
  1734. package/dist/tools/register.d.ts +6 -0
  1735. package/dist/tools/register.js +21 -0
  1736. package/dist/tools/schemas.d.ts +25 -0
  1737. package/dist/tools/schemas.js +41 -0
  1738. package/dist/tools/validation.d.ts +13 -0
  1739. package/dist/tools/validation.js +77 -0
  1740. package/dist/types.d.ts +898 -0
  1741. package/dist/types.js +1 -0
  1742. package/package.json +54 -0
  1743. package/skills/ai-code-review.skill.md +57 -0
  1744. package/skills/release-gate.skill.md +27 -0
  1745. package/skills/security-review.skill.md +32 -0
@@ -0,0 +1,2544 @@
1
+ /**
2
+ * Auto-Fix Patch Rules
3
+ *
4
+ * Extracted from the evaluators monolith. Contains the PATCH_RULES registry
5
+ * and the enrichWithPatches function that attaches deterministic, single-line
6
+ * code-fix patches to findings.
7
+ */
8
+ /**
9
+ * Auto-fix patch rules: each entry maps a finding pattern to a function that
10
+ * can produce a Patch from the source code line. Only deterministic,
11
+ * single-line replacements are emitted — no guessing.
12
+ */
13
+ const PATCH_RULES = [
14
+ // ── Deprecated APIs ──
15
+ // new Buffer() → Buffer.from()
16
+ {
17
+ match: /deprecated|DEPRECATED_API/i,
18
+ generate: (line) => {
19
+ const m = line.match(/new\s+Buffer\s*\(([^)]*)\)/);
20
+ if (!m)
21
+ return null;
22
+ return { oldText: m[0], newText: `Buffer.from(${m[1]})` };
23
+ },
24
+ },
25
+ // ── Transport Security ──
26
+ // http:// → https:// (non-localhost)
27
+ {
28
+ match: /unencrypted.*http|http.*connection/i,
29
+ generate: (line) => {
30
+ const m = line.match(/(["'])http:\/\/(?!localhost|127\.0\.0\.1|0\.0\.0\.0)([^"']+)\1/);
31
+ if (!m)
32
+ return null;
33
+ return { oldText: `${m[1]}http://${m[2]}${m[1]}`, newText: `${m[1]}https://${m[2]}${m[1]}` };
34
+ },
35
+ },
36
+ // ws:// → wss:// (insecure WebSocket)
37
+ {
38
+ match: /insecure.*websocket|ws:\/\//i,
39
+ generate: (line) => {
40
+ const m = line.match(/(["'])ws:\/\/([^"']+)\1/);
41
+ if (!m)
42
+ return null;
43
+ return { oldText: `${m[1]}ws://${m[2]}${m[1]}`, newText: `${m[1]}wss://${m[2]}${m[1]}` };
44
+ },
45
+ },
46
+ // ── Cryptography ──
47
+ // Math.random() → crypto.randomUUID()
48
+ {
49
+ match: /insecure.*random/i,
50
+ generate: (line) => {
51
+ const m = line.match(/Math\.random\s*\(\s*\)/);
52
+ if (!m)
53
+ return null;
54
+ return { oldText: m[0], newText: "crypto.randomUUID()" };
55
+ },
56
+ },
57
+ // MD5/SHA-1 → SHA-256
58
+ {
59
+ match: /weak.*hash|weak.*crypto/i,
60
+ generate: (line) => {
61
+ const m = line.match(/createHash\s*\(\s*(["'])(md5|sha1|sha-1)\1\s*\)/i);
62
+ if (!m)
63
+ return null;
64
+ return { oldText: m[0], newText: `createHash(${m[1]}sha256${m[1]})` };
65
+ },
66
+ },
67
+ // ECB encryption mode → GCM
68
+ {
69
+ match: /insecure.*ecb|encryption.*mode/i,
70
+ generate: (line) => {
71
+ const m = line.match(/(["'])(aes-\d+-)(ecb)\1/i);
72
+ if (!m)
73
+ return null;
74
+ return { oldText: `${m[1]}${m[2]}${m[3]}${m[1]}`, newText: `${m[1]}${m[2]}gcm${m[1]}` };
75
+ },
76
+ },
77
+ // ── Injection Prevention ──
78
+ // eval() → Function() or comment warning
79
+ {
80
+ match: /dangerous.*eval|eval.*usage/i,
81
+ generate: (line) => {
82
+ const m = line.match(/\beval\s*\(([^)]*)\)/);
83
+ if (!m)
84
+ return null;
85
+ return { oldText: m[0], newText: `new Function(${m[1]})() /* TODO: eliminate dynamic code execution */` };
86
+ },
87
+ },
88
+ // innerHTML → textContent (XSS prevention)
89
+ {
90
+ match: /xss.*innerhtml|innerhtml/i,
91
+ generate: (line) => {
92
+ const m = line.match(/(\.innerHTML)\s*=\s*/);
93
+ if (!m)
94
+ return null;
95
+ return { oldText: m[1], newText: ".textContent" };
96
+ },
97
+ },
98
+ // document.write → safer alternative
99
+ {
100
+ match: /document\.write/i,
101
+ generate: (line) => {
102
+ const m = line.match(/document\.write\s*\(([^)]*)\)/);
103
+ if (!m)
104
+ return null;
105
+ return { oldText: m[0], newText: `document.body.insertAdjacentHTML("beforeend", ${m[1]})` };
106
+ },
107
+ },
108
+ // exec() → execFile() (command injection)
109
+ {
110
+ match: /command.*injection|potential command/i,
111
+ generate: (line) => {
112
+ const m = line.match(/\bexec\s*\(/);
113
+ if (!m)
114
+ return null;
115
+ return { oldText: "exec(", newText: "execFile(" };
116
+ },
117
+ },
118
+ // User input in RegExp → escaped
119
+ {
120
+ match: /redos|regexp.*user/i,
121
+ generate: (line) => {
122
+ const m = line.match(/new\s+RegExp\s*\((\w+)\)/);
123
+ if (!m)
124
+ return null;
125
+ return { oldText: m[0], newText: `new RegExp(${m[1]}.replace(/[.*+?^\${}()|[\\]\\\\]/g, "\\\\$&"))` };
126
+ },
127
+ },
128
+ // ── Equality & Type Safety ──
129
+ // == → === (loose equality)
130
+ {
131
+ match: /loose.*equal|==.*strict/i,
132
+ generate: (line) => {
133
+ const m = line.match(/([^!=<>])={2}(?!=)/);
134
+ if (!m)
135
+ return null;
136
+ return { oldText: m[0], newText: `${m[1]}===` };
137
+ },
138
+ },
139
+ // != → !== (loose inequality)
140
+ {
141
+ match: /loose.*equal/i,
142
+ generate: (line) => {
143
+ const m = line.match(/!={1}(?!=)/);
144
+ if (!m)
145
+ return null;
146
+ return { oldText: m[0], newText: "!==" };
147
+ },
148
+ },
149
+ // throw "string" → throw new Error("string")
150
+ {
151
+ match: /throwing.*string|string.*literal.*instead.*error/i,
152
+ generate: (line) => {
153
+ const m = line.match(/throw\s+(["'])([^"']*)\1/);
154
+ if (!m)
155
+ return null;
156
+ return { oldText: m[0], newText: `throw new Error(${m[1]}${m[2]}${m[1]})` };
157
+ },
158
+ },
159
+ // any → unknown
160
+ {
161
+ match: /weak.*type|unsafe.*type|any.*type/i,
162
+ generate: (line) => {
163
+ const m = line.match(/:\s*any\b/);
164
+ if (!m)
165
+ return null;
166
+ return { oldText: m[0], newText: ": unknown" };
167
+ },
168
+ },
169
+ // ── Variable Declarations ──
170
+ // var → let (maintainability)
171
+ {
172
+ match: /var.*declaration|var.*keyword|var.*instead/i,
173
+ generate: (line) => {
174
+ const m = line.match(/\bvar\s+/);
175
+ if (!m)
176
+ return null;
177
+ return { oldText: m[0], newText: "let " };
178
+ },
179
+ },
180
+ // ── Logging ──
181
+ // console.log → structured logger placeholder
182
+ {
183
+ match: /console.*log.*structured|console.*instead.*structured/i,
184
+ generate: (line) => {
185
+ const m = line.match(/console\.log\s*\(([^)]*)\)/);
186
+ if (!m)
187
+ return null;
188
+ return { oldText: m[0], newText: `logger.info(${m[1]})` };
189
+ },
190
+ },
191
+ // console.error as sole error strategy
192
+ {
193
+ match: /console\.error.*sole/i,
194
+ generate: (line) => {
195
+ const m = line.match(/console\.error\s*\(([^)]*)\)/);
196
+ if (!m)
197
+ return null;
198
+ return { oldText: m[0], newText: `logger.error(${m[1]})` };
199
+ },
200
+ },
201
+ // ── Error Handling ──
202
+ // Empty catch block → catch with error handling comment
203
+ {
204
+ match: /empty.*catch|catch.*swallow/i,
205
+ generate: (line) => {
206
+ const m = line.match(/catch\s*\(\s*\)\s*\{\s*\}/);
207
+ if (!m)
208
+ return null;
209
+ return { oldText: m[0], newText: "catch (error) { /* TODO: handle error appropriately */ }" };
210
+ },
211
+ },
212
+ // catch without error parameter
213
+ {
214
+ match: /catch.*discard|catch.*error.*object/i,
215
+ generate: (line) => {
216
+ const m = line.match(/catch\s*\(\s*\)\s*\{/);
217
+ if (!m)
218
+ return null;
219
+ return { oldText: m[0], newText: "catch (error) {" };
220
+ },
221
+ },
222
+ // ── Security Headers & CORS ──
223
+ // Wildcard CORS → specific origin
224
+ {
225
+ match: /wildcard.*cors|cors.*wildcard|permissive.*cors/i,
226
+ generate: (line) => {
227
+ const m = line.match(/(origin\s*:\s*)(["'])\*\2/);
228
+ if (!m)
229
+ return null;
230
+ return { oldText: m[0], newText: `${m[1]}process.env.ALLOWED_ORIGIN || ${m[2]}*${m[2]}` };
231
+ },
232
+ },
233
+ // CSP unsafe-inline → nonce-based
234
+ {
235
+ match: /content-security-policy|csp.*unsafe/i,
236
+ generate: (line) => {
237
+ const m = line.match(/(["'])unsafe-inline\1/);
238
+ if (!m)
239
+ return null;
240
+ return { oldText: m[0], newText: `${m[1]}nonce-\${nonce}${m[1]}` };
241
+ },
242
+ },
243
+ // ── Cookie Security ──
244
+ // Cookie without secure flag
245
+ {
246
+ match: /cookie.*security|cookie.*secure|cookie.*httponly/i,
247
+ generate: (line) => {
248
+ const m = line.match(/(secure\s*:\s*)false/);
249
+ if (m)
250
+ return { oldText: m[0], newText: `${m[1]}true` };
251
+ const m2 = line.match(/(httpOnly\s*:\s*)false/i);
252
+ if (m2)
253
+ return { oldText: m2[0], newText: `${m2[1]}true` };
254
+ return null;
255
+ },
256
+ },
257
+ // ── Authentication ──
258
+ // JWT without verification
259
+ {
260
+ match: /jwt.*without.*verif|jwt.*decoded/i,
261
+ generate: (line) => {
262
+ const m = line.match(/jwt\.decode\s*\(([^)]*)\)/);
263
+ if (!m)
264
+ return null;
265
+ return { oldText: m[0], newText: `jwt.verify(${m[1]}, process.env.JWT_SECRET)` };
266
+ },
267
+ },
268
+ // TLS verification disabled
269
+ {
270
+ match: /tls.*verif|certificate.*valid.*disabled/i,
271
+ generate: (line) => {
272
+ const m = line.match(/(rejectUnauthorized\s*:\s*)false/);
273
+ if (!m)
274
+ return null;
275
+ return { oldText: m[0], newText: `${m[1]}true` };
276
+ },
277
+ },
278
+ // ── Async/Concurrency ──
279
+ // .then() without .catch()
280
+ {
281
+ match: /promise.*catch|then.*without.*catch/i,
282
+ generate: (line) => {
283
+ const m = line.match(/(\.then\s*\([^)]*\))\s*;/);
284
+ if (!m)
285
+ return null;
286
+ return { oldText: m[0], newText: `${m[1]}.catch((err) => { throw err; });` };
287
+ },
288
+ },
289
+ // Synchronous fs operations → async
290
+ {
291
+ match: /synchronous.*blocking|blocking.*i\/o|sync.*file/i,
292
+ generate: (line) => {
293
+ const m = line.match(/\b(readFileSync|writeFileSync|appendFileSync|existsSync|mkdirSync|readdirSync|statSync|unlinkSync|renameSync|copyFileSync)\b/);
294
+ if (!m)
295
+ return null;
296
+ const asyncName = m[1].replace("Sync", "");
297
+ return { oldText: m[1], newText: `await ${asyncName}` };
298
+ },
299
+ },
300
+ // ── Performance ──
301
+ // new Array() → []
302
+ {
303
+ match: /array.*constructor/i,
304
+ generate: (line) => {
305
+ const m = line.match(/new\s+Array\s*\(\s*\)/);
306
+ if (!m)
307
+ return null;
308
+ return { oldText: m[0], newText: "[]" };
309
+ },
310
+ },
311
+ // new Object() → {}
312
+ {
313
+ match: /object.*constructor/i,
314
+ generate: (line) => {
315
+ const m = line.match(/new\s+Object\s*\(\s*\)/);
316
+ if (!m)
317
+ return null;
318
+ return { oldText: m[0], newText: "{}" };
319
+ },
320
+ },
321
+ // String concatenation in loop → template literal guidance
322
+ {
323
+ match: /string.*concat.*loop/i,
324
+ generate: (line) => {
325
+ const m = line.match(/(\w+)\s*\+=\s*(["'])/);
326
+ if (!m)
327
+ return null;
328
+ return { oldText: m[0], newText: `/* TODO: use array.push() + join() instead */ ${m[0]}` };
329
+ },
330
+ },
331
+ // ── Database ──
332
+ // SELECT * → explicit columns reminder
333
+ {
334
+ match: /select\s*\*/i,
335
+ generate: (line) => {
336
+ const m = line.match(/SELECT\s+\*/i);
337
+ if (!m)
338
+ return null;
339
+ return { oldText: m[0], newText: "SELECT /* TODO: specify columns */" };
340
+ },
341
+ },
342
+ // ── Serialization ──
343
+ // JSON.parse without try/catch → safe wrapper
344
+ {
345
+ match: /unsafe.*deserialization|deserialization/i,
346
+ generate: (line) => {
347
+ const m = line.match(/JSON\.parse\s*\(([^)]*)\)/);
348
+ if (!m)
349
+ return null;
350
+ return { oldText: m[0], newText: `(() => { try { return JSON.parse(${m[1]}); } catch { return null; } })()` };
351
+ },
352
+ },
353
+ // ── Process & Lifecycle ──
354
+ // process.exit() → graceful shutdown
355
+ {
356
+ match: /abrupt.*process|process.*termination/i,
357
+ generate: (line) => {
358
+ const m = line.match(/process\.exit\s*\(([^)]*)\)/);
359
+ if (!m)
360
+ return null;
361
+ return { oldText: m[0], newText: `process.exitCode = ${m[1] || "1"}; /* allow graceful cleanup */` };
362
+ },
363
+ },
364
+ // ── Docker / Container ──
365
+ // :latest tag → pinned version
366
+ {
367
+ match: /latest.*tag|docker.*latest/i,
368
+ generate: (line) => {
369
+ const m = line.match(/(FROM\s+\S+):latest/i);
370
+ if (!m)
371
+ return null;
372
+ return { oldText: `${m[1]}:latest`, newText: `${m[1]}:lts-slim /* TODO: pin to specific version */` };
373
+ },
374
+ },
375
+ // USER root → non-root user
376
+ {
377
+ match: /docker.*root|container.*root/i,
378
+ generate: (line) => {
379
+ const m = line.match(/^USER\s+root\s*$/i);
380
+ if (!m)
381
+ return null;
382
+ return { oldText: m[0], newText: "USER node" };
383
+ },
384
+ },
385
+ // ── CI/CD ──
386
+ // npm install → npm ci
387
+ {
388
+ match: /npm install.*instead.*ci|npm ci/i,
389
+ generate: (line) => {
390
+ const m = line.match(/npm\s+install(?!\s+\S)/);
391
+ if (!m)
392
+ return null;
393
+ return { oldText: m[0], newText: "npm ci" };
394
+ },
395
+ },
396
+ // ── Network ──
397
+ // 0.0.0.0 binding → localhost
398
+ {
399
+ match: /binds.*all.*interfaces|0\.0\.0\.0/i,
400
+ generate: (line) => {
401
+ const m = line.match(/(["'])0\.0\.0\.0\1/);
402
+ if (!m)
403
+ return null;
404
+ return { oldText: m[0], newText: `${m[1]}127.0.0.1${m[1]}` };
405
+ },
406
+ },
407
+ // External calls without timeout
408
+ {
409
+ match: /without.*timeout|network.*timeout/i,
410
+ generate: (line) => {
411
+ const m = line.match(/(fetch\s*\(\s*\w+)\s*\)/);
412
+ if (!m)
413
+ return null;
414
+ return { oldText: m[0], newText: `${m[1]}, { signal: AbortSignal.timeout(30000) })` };
415
+ },
416
+ },
417
+ // ── Accessibility ──
418
+ // outline: none → visible focus style
419
+ {
420
+ match: /focus.*indicator.*removed|outline.*none/i,
421
+ generate: (line) => {
422
+ const m = line.match(/outline\s*:\s*none/);
423
+ if (!m)
424
+ return null;
425
+ return { oldText: m[0], newText: "outline: 2px solid currentColor" };
426
+ },
427
+ },
428
+ // img without alt → add alt placeholder
429
+ {
430
+ match: /image.*alt|missing.*alt/i,
431
+ generate: (line) => {
432
+ const m = line.match(/<img\s+(?!.*alt\s*=)/);
433
+ if (!m)
434
+ return null;
435
+ return { oldText: m[0], newText: `<img alt="" ` };
436
+ },
437
+ },
438
+ // ── Configuration ──
439
+ // Hardcoded connection string → env var
440
+ {
441
+ match: /hardcoded.*connection|connection.*string.*code/i,
442
+ generate: (line) => {
443
+ const m = line.match(/(["'])((?:mongodb|postgres|mysql|redis):\/\/[^"']+)\1/);
444
+ if (!m)
445
+ return null;
446
+ return { oldText: m[0], newText: `process.env.DATABASE_URL || ${m[0]}` };
447
+ },
448
+ },
449
+ // Debug mode enabled
450
+ {
451
+ match: /debug.*mode.*enabled|debug.*enabled/i,
452
+ generate: (line) => {
453
+ const m = line.match(/(debug\s*[:=]\s*)true/i);
454
+ if (!m)
455
+ return null;
456
+ return { oldText: m[0], newText: `${m[1]}process.env.NODE_ENV !== "production"` };
457
+ },
458
+ },
459
+ // ── Session Security ──
460
+ // Insecure session config
461
+ {
462
+ match: /insecure.*session/i,
463
+ generate: (line) => {
464
+ const m = line.match(/(secure\s*:\s*)false/);
465
+ if (m)
466
+ return { oldText: m[0], newText: `${m[1]}process.env.NODE_ENV === "production"` };
467
+ return null;
468
+ },
469
+ },
470
+ // ── Input Validation ──
471
+ // Request body without size limit
472
+ {
473
+ match: /body.*parser.*size|request.*body.*size/i,
474
+ generate: (line) => {
475
+ const m = line.match(/(\.json\s*\(\s*)\)/);
476
+ if (!m)
477
+ return null;
478
+ return { oldText: m[0], newText: `${m[1]}{ limit: "1mb" })` };
479
+ },
480
+ },
481
+ // ── Deprecated Patterns ──
482
+ // __dirname in ESM → import.meta
483
+ {
484
+ match: /__dirname.*esm|__filename.*esm/i,
485
+ generate: (line) => {
486
+ const m = line.match(/__dirname/);
487
+ if (!m)
488
+ return null;
489
+ return { oldText: m[0], newText: `new URL(".", import.meta.url).pathname` };
490
+ },
491
+ },
492
+ // ── XML Security ──
493
+ // XML without XXE protection
494
+ {
495
+ match: /xxe|xml.*protect/i,
496
+ generate: (line) => {
497
+ const m = line.match(/(new\s+(?:DOMParser|XMLParser)\s*\(\s*)\)/);
498
+ if (!m)
499
+ return null;
500
+ return { oldText: m[0], newText: `${m[1]}{ noent: false, dtd: false })` };
501
+ },
502
+ },
503
+ // ── Python Patches ──
504
+ // Python: hashlib.md5/sha1 → sha256
505
+ {
506
+ match: /weak.*hash|weak.*crypto|insecure.*hash/i,
507
+ generate: (line) => {
508
+ const m = line.match(/hashlib\.(md5|sha1)\s*\(/i);
509
+ if (!m)
510
+ return null;
511
+ return { oldText: m[0], newText: "hashlib.sha256(" };
512
+ },
513
+ },
514
+ // Python: random.random() → secrets.token_hex()
515
+ {
516
+ match: /insecure.*random|weak.*random/i,
517
+ generate: (line) => {
518
+ const m = line.match(/random\.(?:random|randint|choice)\s*\([^)]*\)/);
519
+ if (!m)
520
+ return null;
521
+ return { oldText: m[0], newText: "secrets.token_hex(32)" };
522
+ },
523
+ },
524
+ // Python: pickle.loads → json.loads
525
+ {
526
+ match: /unsafe.*deseri|pickle.*untrusted|insecure.*deseri/i,
527
+ generate: (line) => {
528
+ const m = line.match(/pickle\.loads?\s*\(/);
529
+ if (!m)
530
+ return null;
531
+ return { oldText: m[0], newText: "json.loads(" };
532
+ },
533
+ },
534
+ // Python: yaml.load(data) → yaml.safe_load(data)
535
+ {
536
+ match: /unsafe.*yaml|yaml.*load|insecure.*yaml/i,
537
+ generate: (line) => {
538
+ const m = line.match(/yaml\.load\s*\(/);
539
+ if (!m)
540
+ return null;
541
+ return { oldText: m[0], newText: "yaml.safe_load(" };
542
+ },
543
+ },
544
+ // Python: os.system → subprocess.run
545
+ {
546
+ match: /command.*inject|os\.system|shell.*inject/i,
547
+ generate: (line) => {
548
+ const m = line.match(/os\.system\s*\(\s*(f?["'])/);
549
+ if (!m)
550
+ return null;
551
+ return { oldText: "os.system(", newText: "subprocess.run(" };
552
+ },
553
+ },
554
+ // Python: assert for validation → raise ValueError
555
+ {
556
+ match: /assert.*valid|assert.*production|assert.*security/i,
557
+ generate: (line) => {
558
+ const m = line.match(/^(\s*)assert\s+(.*),\s*["'](.*?)["']\s*$/);
559
+ if (!m)
560
+ return null;
561
+ return { oldText: m[0], newText: `${m[1]}if not (${m[2]}): raise ValueError("${m[3]}")` };
562
+ },
563
+ },
564
+ // Python DEBUG=True → environment variable
565
+ {
566
+ match: /debug.*true|debug.*production/i,
567
+ generate: (line) => {
568
+ const m = line.match(/^(\s*)DEBUG\s*=\s*True\s*$/);
569
+ if (!m)
570
+ return null;
571
+ return { oldText: m[0], newText: `${m[1]}DEBUG = os.environ.get('DEBUG', 'False') == 'True'` };
572
+ },
573
+ },
574
+ // ── Go Patches ──
575
+ // Go: fmt.Sprintf in SQL → parameterized query marker
576
+ {
577
+ match: /sql.*inject|string.*format.*sql/i,
578
+ generate: (line) => {
579
+ const m = line.match(/fmt\.Sprintf\s*\(\s*["']([^"']*?)%[sdv]/);
580
+ if (!m)
581
+ return null;
582
+ if (!/SELECT|INSERT|UPDATE|DELETE|WHERE/i.test(m[1]))
583
+ return null;
584
+ return { oldText: "fmt.Sprintf(", newText: "/* TODO: use parameterized query ($1) */ fmt.Sprintf(" };
585
+ },
586
+ },
587
+ // Go: http.ListenAndServe → http.ListenAndServeTLS
588
+ {
589
+ match: /unencrypted.*http|http.*tls|insecure.*transport/i,
590
+ generate: (line) => {
591
+ const m = line.match(/http\.ListenAndServe\s*\(/);
592
+ if (!m)
593
+ return null;
594
+ return { oldText: m[0], newText: "http.ListenAndServeTLS(" };
595
+ },
596
+ },
597
+ // ── Java Patches ──
598
+ // Java: MessageDigest MD5/SHA-1 → SHA-256
599
+ {
600
+ match: /weak.*hash|weak.*digest|insecure.*hash/i,
601
+ generate: (line) => {
602
+ const m = line.match(/MessageDigest\.getInstance\s*\(\s*["'](MD5|SHA-1)["']\s*\)/i);
603
+ if (!m)
604
+ return null;
605
+ return { oldText: m[0], newText: `MessageDigest.getInstance("SHA-256")` };
606
+ },
607
+ },
608
+ // Java: new Random() → SecureRandom
609
+ {
610
+ match: /insecure.*random|predictable.*random/i,
611
+ generate: (line) => {
612
+ const m = line.match(/new\s+Random\s*\(\s*\)/);
613
+ if (!m)
614
+ return null;
615
+ return { oldText: m[0], newText: "new SecureRandom()" };
616
+ },
617
+ },
618
+ // Java: DES/3DES → AES (cipher)
619
+ {
620
+ match: /weak.*cipher|insecure.*cipher|des.*encrypt/i,
621
+ generate: (line) => {
622
+ const m = line.match(/Cipher\.getInstance\s*\(\s*["'](?:DES|DESede|3DES)(?:\/[^"']*)?["']\s*\)/i);
623
+ if (!m)
624
+ return null;
625
+ return { oldText: m[0], newText: `Cipher.getInstance("AES/GCM/NoPadding")` };
626
+ },
627
+ },
628
+ // Java: Runtime.exec with string → ProcessBuilder
629
+ {
630
+ match: /command.*inject|runtime.*exec|os.*command/i,
631
+ generate: (line) => {
632
+ const m = line.match(/Runtime\.getRuntime\s*\(\s*\)\.exec\s*\(/);
633
+ if (!m)
634
+ return null;
635
+ return { oldText: m[0], newText: "new ProcessBuilder(" };
636
+ },
637
+ },
638
+ // Java: XMLInputFactory without disabling DTD
639
+ {
640
+ match: /xxe|xml.*injection|xml.*entity/i,
641
+ generate: (line) => {
642
+ const m = line.match(/XMLInputFactory\.newInstance\s*\(\s*\)/);
643
+ if (!m)
644
+ return null;
645
+ return {
646
+ oldText: m[0],
647
+ newText: `XMLInputFactory.newInstance() /* TODO: factory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false) */`,
648
+ };
649
+ },
650
+ },
651
+ // ── C# Patches ──
652
+ // C#: MD5/SHA1 → SHA256
653
+ {
654
+ match: /weak.*hash|insecure.*hash|obsolete.*hash/i,
655
+ generate: (line) => {
656
+ const m = line.match(/(MD5|SHA1)\.Create\s*\(\s*\)/);
657
+ if (!m)
658
+ return null;
659
+ return { oldText: m[0], newText: "SHA256.Create()" };
660
+ },
661
+ },
662
+ // C#: new Random() → RandomNumberGenerator
663
+ {
664
+ match: /insecure.*random|predictable.*random/i,
665
+ generate: (line) => {
666
+ const m = line.match(/new\s+Random\s*\(\s*\)/);
667
+ if (!m)
668
+ return null;
669
+ return { oldText: m[0], newText: "RandomNumberGenerator.Create()" };
670
+ },
671
+ },
672
+ // C#: AllowAnyOrigin → specific origin comment
673
+ {
674
+ match: /cors.*wildcard|permissive.*cors|cors.*any/i,
675
+ generate: (line) => {
676
+ const m = line.match(/\.AllowAnyOrigin\s*\(\s*\)/);
677
+ if (!m)
678
+ return null;
679
+ return { oldText: m[0], newText: `.WithOrigins("https://your-domain.com") /* TODO: restrict origins */` };
680
+ },
681
+ },
682
+ // C#: FromSqlRaw with interpolation → FromSqlInterpolated
683
+ {
684
+ match: /sql.*inject|raw.*sql/i,
685
+ generate: (line) => {
686
+ const m = line.match(/FromSqlRaw\s*\(\s*\$/);
687
+ if (!m)
688
+ return null;
689
+ return { oldText: "FromSqlRaw($", newText: "FromSqlInterpolated($" };
690
+ },
691
+ },
692
+ // ── Rust Patches ──
693
+ // Rust: unwrap() → expect() with message
694
+ {
695
+ match: /unwrap.*panic|unwrap.*error|unhandled.*unwrap/i,
696
+ generate: (line) => {
697
+ const m = line.match(/\.unwrap\s*\(\s*\)/);
698
+ if (!m)
699
+ return null;
700
+ return { oldText: m[0], newText: `.expect("TODO: handle this error")` };
701
+ },
702
+ },
703
+ // Rust: unsafe block → comment marker
704
+ {
705
+ match: /unsafe.*block|unsafe.*usage/i,
706
+ generate: (line) => {
707
+ const m = line.match(/^(\s*)unsafe\s*\{/);
708
+ if (!m)
709
+ return null;
710
+ return { oldText: m[0], newText: `${m[1]}// SAFETY: TODO: document why unsafe is needed\n${m[1]}unsafe {` };
711
+ },
712
+ },
713
+ // Rust: panic!() in library → return Result comment
714
+ {
715
+ match: /panic.*library|panic.*production|avoid.*panic/i,
716
+ generate: (line) => {
717
+ const m = line.match(/panic!\s*\(\s*(["'][^"']*["'])\s*\)/);
718
+ if (!m)
719
+ return null;
720
+ return { oldText: m[0], newText: `return Err(anyhow::anyhow!(${m[1]})) /* TODO: replace panic with Result */` };
721
+ },
722
+ },
723
+ // Rust: .clone() hint → borrow comment
724
+ {
725
+ match: /unnecessary.*clone|avoid.*clone|excessive.*clone/i,
726
+ generate: (line) => {
727
+ const m = line.match(/(\w+)\.clone\(\)/);
728
+ if (!m)
729
+ return null;
730
+ return { oldText: m[0], newText: `${m[1]}.clone() /* TODO: consider borrowing &${m[1]} instead */` };
731
+ },
732
+ },
733
+ // ── Additional Python Patches ──
734
+ // Python: eval() → ast.literal_eval()
735
+ {
736
+ match: /dangerous.*eval|python.*eval|eval.*usage/i,
737
+ generate: (line) => {
738
+ const m = line.match(/\beval\s*\(\s*(\w+)\s*\)/);
739
+ if (!m)
740
+ return null;
741
+ // Only match if it looks like Python (no 'new Function' around it)
742
+ if (line.includes("new Function") || line.includes("Function("))
743
+ return null;
744
+ return { oldText: m[0], newText: `ast.literal_eval(${m[1]})` };
745
+ },
746
+ },
747
+ // Python: requests without verify → verify=True
748
+ {
749
+ match: /ssl.*verif.*disabled|tls.*verif.*disabled|certificate.*verif/i,
750
+ generate: (line) => {
751
+ const m = line.match(/(requests\.(?:get|post|put|delete|patch)\s*\([^)]*?)verify\s*=\s*False/);
752
+ if (!m)
753
+ return null;
754
+ return { oldText: "verify=False", newText: "verify=True" };
755
+ },
756
+ },
757
+ // Python: subprocess with shell=True → shell=False
758
+ {
759
+ match: /shell.*true|subprocess.*shell|shell.*inject/i,
760
+ generate: (line) => {
761
+ const m = line.match(/(subprocess\.(?:run|call|check_call|check_output|Popen)\s*\([^)]*?)shell\s*=\s*True/);
762
+ if (!m)
763
+ return null;
764
+ return { oldText: "shell=True", newText: "shell=False" };
765
+ },
766
+ },
767
+ // Python: open() without encoding → add encoding
768
+ {
769
+ match: /missing.*encoding|file.*encoding|open.*without.*encoding/i,
770
+ generate: (line) => {
771
+ const m = line.match(/(open\s*\(\s*\w+\s*,\s*["'][rw](?:t)?["'])\s*\)/);
772
+ if (!m)
773
+ return null;
774
+ return { oldText: m[0], newText: `${m[1]}, encoding="utf-8")` };
775
+ },
776
+ },
777
+ // ── Additional Go Patches ──
778
+ // Go: log.Fatal in HTTP handler → http.Error
779
+ {
780
+ match: /log\.fatal.*handler|fatal.*http.*handler|log.*fatal.*request/i,
781
+ generate: (line) => {
782
+ const m = line.match(/log\.Fatal(?:f|ln)?\s*\(([^)]*)\)/);
783
+ if (!m)
784
+ return null;
785
+ return { oldText: m[0], newText: `http.Error(w, ${m[1]}, http.StatusInternalServerError)` };
786
+ },
787
+ },
788
+ // Go: defer file.Close() without error check → named return
789
+ {
790
+ match: /defer.*close.*error|close.*without.*check|resource.*leak/i,
791
+ generate: (line) => {
792
+ const m = line.match(/(defer\s+\w+\.Close)\s*\(\s*\)/);
793
+ if (!m)
794
+ return null;
795
+ return { oldText: m[0], newText: `${m[1]}() // TODO: check Close() error in named return` };
796
+ },
797
+ },
798
+ // ── Additional Java Patches ──
799
+ // Java: System.out.println → Logger
800
+ {
801
+ match: /system\.out|console.*output|print.*instead.*log/i,
802
+ generate: (line) => {
803
+ const m = line.match(/System\.out\.println\s*\(([^)]*)\)/);
804
+ if (!m)
805
+ return null;
806
+ return { oldText: m[0], newText: `logger.info(${m[1]})` };
807
+ },
808
+ },
809
+ // Java: String concatenation in SQL → PreparedStatement marker
810
+ {
811
+ match: /sql.*concatenat|string.*concat.*sql|sql.*inject/i,
812
+ generate: (line) => {
813
+ const m = line.match(/(Statement\s*\w+\s*=\s*\w+\.createStatement)\s*\(\s*\)/);
814
+ if (!m)
815
+ return null;
816
+ return { oldText: m[0], newText: `/* TODO: use PreparedStatement instead */ ${m[0]}` };
817
+ },
818
+ },
819
+ // ── Additional C# Patches ──
820
+ // C#: string.Format/interpolation in SQL → parameterized
821
+ {
822
+ match: /sql.*inject|string.*interpol.*sql|sql.*concat/i,
823
+ generate: (line) => {
824
+ const m = line.match(/ExecuteSqlRaw\s*\(\s*\$/);
825
+ if (!m)
826
+ return null;
827
+ return { oldText: "ExecuteSqlRaw($", newText: "ExecuteSqlInterpolated($" };
828
+ },
829
+ },
830
+ // C#: Console.WriteLine → ILogger
831
+ {
832
+ match: /console.*writeline.*log|console.*instead.*logger/i,
833
+ generate: (line) => {
834
+ const m = line.match(/Console\.WriteLine\s*\(([^)]*)\)/);
835
+ if (!m)
836
+ return null;
837
+ return { oldText: m[0], newText: `_logger.LogInformation(${m[1]})` };
838
+ },
839
+ },
840
+ // ── Hardcoded Secrets ──
841
+ // Hardcoded password/secret → environment variable
842
+ {
843
+ match: /hardcoded.*password|password.*literal|hardcoded.*secret|hardcoded.*credential/i,
844
+ generate: (line) => {
845
+ const m = line.match(/(password|passwd|pwd|secret)\s*[:=]\s*(["'])([^"']{4,})\2/i);
846
+ if (!m)
847
+ return null;
848
+ const envVar = m[1].toUpperCase();
849
+ return { oldText: `${m[2]}${m[3]}${m[2]}`, newText: `process.env.${envVar} || ${m[2]}${m[2]}` };
850
+ },
851
+ },
852
+ // Hardcoded API key → environment variable
853
+ {
854
+ match: /hardcoded.*api.?key|api.?key.*hardcoded|hardcoded.*token|secret.*key.*literal/i,
855
+ generate: (line) => {
856
+ const m = line.match(/(api_?[Kk]ey|api_?[Tt]oken|auth_?[Tt]oken|access_?[Tt]oken)\s*[:=]\s*(["'])([^"']{8,})\2/i);
857
+ if (!m)
858
+ return null;
859
+ const normalized = m[1].toUpperCase().replace(/([a-z])([A-Z])/g, "$1_$2");
860
+ return { oldText: `${m[2]}${m[3]}${m[2]}`, newText: `process.env.${normalized} || ${m[2]}${m[2]}` };
861
+ },
862
+ },
863
+ // ── Path Traversal ──
864
+ {
865
+ match: /path.*traversal|directory.*traversal|path.*manipulation/i,
866
+ generate: (line) => {
867
+ const m = line.match(/path\.join\s*\(([^,]+),\s*(\w+)\s*\)/);
868
+ if (!m)
869
+ return null;
870
+ return {
871
+ oldText: m[0],
872
+ newText: `path.resolve(${m[1]}, path.basename(${m[2]})) /* TODO: validate no traversal */`,
873
+ };
874
+ },
875
+ },
876
+ // ── Open Redirect ──
877
+ {
878
+ match: /open.*redirect|unvalidat.*redirect|redirect.*user.*input/i,
879
+ generate: (line) => {
880
+ const m = line.match(/(res\.redirect\s*\(\s*)(req\.(?:query|params|body)\.\w+)\s*\)/);
881
+ if (!m)
882
+ return null;
883
+ return {
884
+ oldText: m[0],
885
+ newText: `${m[1]}/* TODO: validate against allowlist */ new URL(${m[2]}, \`\${req.protocol}://\${req.get("host")}\`).pathname)`,
886
+ };
887
+ },
888
+ },
889
+ // ── Timing-Safe Comparison ──
890
+ {
891
+ match: /timing.*attack|constant.*time.*compar|timing.*safe/i,
892
+ generate: (line) => {
893
+ const m = line.match(/([\w.]+)\s*===?\s*([\w.]*(?:secret|token|key|hash|digest|signature)[\w.]*)/i);
894
+ if (!m)
895
+ return null;
896
+ return {
897
+ oldText: m[0],
898
+ newText: `crypto.timingSafeEqual(Buffer.from(String(${m[1]})), Buffer.from(String(${m[2]})))`,
899
+ };
900
+ },
901
+ },
902
+ // ── Error Information Leakage ──
903
+ {
904
+ match: /error.*leak|stack.*trace.*expos|error.*information.*disclos|sensitive.*error/i,
905
+ generate: (line) => {
906
+ const m = line.match(/(res\.(?:send|json)\s*\(\s*(?:err|error))\.stack\b/);
907
+ if (!m)
908
+ return null;
909
+ return { oldText: `${m[1]}.stack`, newText: `${m[1]}.message || "Internal server error"` };
910
+ },
911
+ },
912
+ // ── Link Security ──
913
+ // target="_blank" without rel="noopener"
914
+ {
915
+ match: /noopener|reverse.*tabnab|target.*blank.*rel/i,
916
+ generate: (line) => {
917
+ const m = line.match(/(target\s*=\s*["']_blank["'])(?!.*rel\s*=)/);
918
+ if (!m)
919
+ return null;
920
+ return { oldText: m[1], newText: `${m[1]} rel="noopener noreferrer"` };
921
+ },
922
+ },
923
+ // ── Password Hashing ──
924
+ {
925
+ match: /bcrypt.*rounds|salt.*rounds|weak.*hash.*factor|low.*cost.*factor/i,
926
+ generate: (line) => {
927
+ const m = line.match(/(bcrypt\.(?:hash|genSalt)\s*\(\s*\w+\s*,\s*)(\d+)/);
928
+ if (!m)
929
+ return null;
930
+ if (parseInt(m[2]) >= 10)
931
+ return null;
932
+ return { oldText: m[0], newText: `${m[1]}12` };
933
+ },
934
+ },
935
+ // ── Log Injection ──
936
+ {
937
+ match: /log.*inject|logging.*untrusted|unsanit.*log/i,
938
+ generate: (line) => {
939
+ const m = line.match(/((?:console|logger)\.\w+\s*\(\s*)(req\.(?:body|query|params)\.\w+)\s*\)/);
940
+ if (!m)
941
+ return null;
942
+ return { oldText: m[0], newText: `${m[1]}String(${m[2]}).replace(/[\\n\\r]/g, ""))` };
943
+ },
944
+ },
945
+ // ── Python: f-string in SQL execute ──
946
+ {
947
+ match: /sql.*injection.*f.?string|f.?string.*sql|python.*sql.*inject/i,
948
+ generate: (line) => {
949
+ const m = line.match(/\.execute\s*\(\s*f(["'])/);
950
+ if (!m)
951
+ return null;
952
+ return { oldText: m[0], newText: `.execute(/* TODO: use parameterized query with %s placeholders */ f${m[1]}` };
953
+ },
954
+ },
955
+ // ── Python: Flask debug mode ──
956
+ {
957
+ match: /flask.*debug|debug.*production.*flask/i,
958
+ generate: (line) => {
959
+ const m = line.match(/(app\.run\s*\([^)]*debug\s*=\s*)True/);
960
+ if (!m)
961
+ return null;
962
+ return { oldText: m[0], newText: `${m[1]}os.environ.get("FLASK_DEBUG", "False") == "True"` };
963
+ },
964
+ },
965
+ // ── Python: bare except clause ──
966
+ {
967
+ match: /bare.*except|broad.*except|generic.*except.*clause/i,
968
+ generate: (line) => {
969
+ const m = line.match(/^(\s*)except\s*:/);
970
+ if (!m)
971
+ return null;
972
+ return { oldText: m[0], newText: `${m[1]}except Exception: # TODO: use specific exception` };
973
+ },
974
+ },
975
+ // ── Python: hardcoded Flask secret key ──
976
+ {
977
+ match: /flask.*secret.*key|hardcoded.*secret.*key/i,
978
+ generate: (line) => {
979
+ const m = line.match(/((?:app\.)?(?:config\s*\[\s*["']SECRET_KEY["']\s*\]\s*=|secret_key\s*=)\s*)(["'])([^"']+)\2/i);
980
+ if (!m)
981
+ return null;
982
+ return { oldText: m[0], newText: `${m[1]}os.environ.get("SECRET_KEY", secrets.token_hex(32))` };
983
+ },
984
+ },
985
+ // ── Python: insecure tempfile ──
986
+ {
987
+ match: /insecure.*temp|tempfile.*mktemp|predictable.*temp/i,
988
+ generate: (line) => {
989
+ const m = line.match(/tempfile\.mktemp\s*\(/);
990
+ if (!m)
991
+ return null;
992
+ return { oldText: m[0], newText: "tempfile.mkstemp(" };
993
+ },
994
+ },
995
+ // ── File Permissions ──
996
+ {
997
+ match: /insecure.*permission|chmod.*777|file.*permission.*broad|overly.*permissive/i,
998
+ generate: (line) => {
999
+ const mShell = line.match(/chmod\s+(777|666)\b/);
1000
+ if (mShell)
1001
+ return { oldText: mShell[0], newText: `chmod ${mShell[1] === "777" ? "750" : "640"}` };
1002
+ const mPy = line.match(/os\.chmod\s*\(\s*(\w+)\s*,\s*0o(777|666)\s*\)/);
1003
+ if (mPy)
1004
+ return { oldText: mPy[0], newText: `os.chmod(${mPy[1]}, 0o${mPy[2] === "777" ? "750" : "640"})` };
1005
+ return null;
1006
+ },
1007
+ },
1008
+ // ── Go: unchecked error ──
1009
+ {
1010
+ match: /unchecked.*error|error.*not.*checked|ignored.*error.*return/i,
1011
+ generate: (line) => {
1012
+ const m = line.match(/^(\s*)\w+\s*,\s*_\s*:?=\s*/);
1013
+ if (!m)
1014
+ return null;
1015
+ return { oldText: ", _", newText: ", err" };
1016
+ },
1017
+ },
1018
+ // ── Java: catching generic Exception ──
1019
+ {
1020
+ match: /catch.*generic.*exception|broad.*exception.*catch|catching.*exception.*instead/i,
1021
+ generate: (line) => {
1022
+ const m = line.match(/catch\s*\(\s*Exception\s+(\w+)\s*\)/);
1023
+ if (!m)
1024
+ return null;
1025
+ return { oldText: m[0], newText: `catch (/* TODO: use specific exception type */ Exception ${m[1]})` };
1026
+ },
1027
+ },
1028
+ // ── Hardcoded Port ──
1029
+ {
1030
+ match: /hardcoded.*port|port.*hardcoded|magic.*number.*port/i,
1031
+ generate: (line) => {
1032
+ const m = line.match(/(\.listen\s*\(\s*)(\d{4,5})\s*([,)])/);
1033
+ if (!m)
1034
+ return null;
1035
+ return { oldText: m[0], newText: `${m[1]}parseInt(process.env.PORT || "${m[2]}")${m[3]}` };
1036
+ },
1037
+ },
1038
+ // ── Prototype Pollution ──
1039
+ {
1040
+ match: /prototype.*pollut|__proto__.*inject|property.*inject/i,
1041
+ generate: (line) => {
1042
+ const m = line.match(/(\w+)\[(\w+)\]\s*=\s*/);
1043
+ if (!m)
1044
+ return null;
1045
+ return { oldText: m[0], newText: `/* TODO: validate key is not __proto__, constructor, or prototype */ ${m[0]}` };
1046
+ },
1047
+ },
1048
+ // ── SSRF Prevention ──
1049
+ {
1050
+ match: /ssrf|server.?side.*request.*forg|unvalidat.*url.*fetch/i,
1051
+ generate: (line) => {
1052
+ const m = line.match(/((?:fetch|axios\.get|http\.get|got)\s*\(\s*)([\w.]+)\s*\)/);
1053
+ if (!m)
1054
+ return null;
1055
+ return { oldText: m[0], newText: `${m[1]}/* TODO: validate URL against allowlist to prevent SSRF */ ${m[2]})` };
1056
+ },
1057
+ },
1058
+ // ── Mass Assignment ──
1059
+ {
1060
+ match: /mass.*assign|over.?post|unfiltered.*body|object.*spread.*request/i,
1061
+ generate: (line) => {
1062
+ const m = line.match(/(\.create\s*\(\s*)req\.body\s*\)/);
1063
+ if (!m)
1064
+ return null;
1065
+ return { oldText: m[0], newText: `${m[1]}{ /* TODO: allowlist specific fields */ ...req.body })` };
1066
+ },
1067
+ },
1068
+ // ── HTML Sanitization ──
1069
+ {
1070
+ match: /xss.*sanitiz|unsanit.*html|html.*inject.*user/i,
1071
+ generate: (line) => {
1072
+ const m = line.match(/(\.innerHTML\s*=\s*)(\w+)/);
1073
+ if (!m)
1074
+ return null;
1075
+ return { oldText: m[0], newText: `${m[1]}DOMPurify.sanitize(${m[2]})` };
1076
+ },
1077
+ },
1078
+ // ── Security Headers / Helmet ──
1079
+ {
1080
+ match: /missing.*helmet|security.*header.*missing|no.*security.*middleware/i,
1081
+ generate: (line) => {
1082
+ const m = line.match(/(const\s+app\s*=\s*express\s*\(\s*\)\s*;?)/);
1083
+ if (!m)
1084
+ return null;
1085
+ return { oldText: m[0], newText: `${m[0]} /* TODO: add app.use(helmet()) for security headers */` };
1086
+ },
1087
+ },
1088
+ // ── Ruby Patches ──
1089
+ // Ruby: system/exec → Shellwords.shellescape
1090
+ {
1091
+ match: /command.*inject|shell.*inject|os.*command|dangerous.*system/i,
1092
+ generate: (line) => {
1093
+ const m = line.match(/\bsystem\s*\(\s*(["'])(.+?)\1\s*\+\s*(\w+)\s*\)/);
1094
+ if (!m)
1095
+ return null;
1096
+ return { oldText: m[0], newText: `system(${m[1]}${m[2]}#{Shellwords.shellescape(${m[3]})}${m[1]})` };
1097
+ },
1098
+ },
1099
+ // Ruby: exec with string interpolation → shellescape
1100
+ {
1101
+ match: /command.*inject|shell.*inject|os.*command/i,
1102
+ generate: (line) => {
1103
+ const m = line.match(/`([^`]*#\{(\w+)\}[^`]*)`/);
1104
+ if (!m)
1105
+ return null;
1106
+ return { oldText: m[0], newText: `Shellwords.shelljoin(["${m[1].replace(/#\{\w+\}/, '", ' + m[2] + ', "')}"])` };
1107
+ },
1108
+ },
1109
+ // Ruby: eval → safer alternative
1110
+ {
1111
+ match: /dangerous.*eval|eval.*usage|code.*inject/i,
1112
+ generate: (line) => {
1113
+ const m = line.match(/\beval\s*\(\s*(\w+)\s*\)/);
1114
+ if (!m)
1115
+ return null;
1116
+ // Only match Ruby-style (no 'new Function' or JS context)
1117
+ if (line.includes("new Function") || line.includes("JSON.parse"))
1118
+ return null;
1119
+ return { oldText: m[0], newText: `JSON.parse(${m[1]}) # TODO: eliminate eval — use safe deserialization` };
1120
+ },
1121
+ },
1122
+ // Ruby: send with user input → allowlist
1123
+ {
1124
+ match: /dynamic.*method|unsafe.*send|method.*inject/i,
1125
+ generate: (line) => {
1126
+ const m = line.match(/(\.send\s*\(\s*)(\w+)\s*\)/);
1127
+ if (!m)
1128
+ return null;
1129
+ return { oldText: m[0], newText: `${m[1]}${m[2]}) # TODO: validate against allowlist before .send` };
1130
+ },
1131
+ },
1132
+ // Ruby: open-uri with user URL → validate
1133
+ {
1134
+ match: /ssrf|open-uri.*untrusted|server.*side.*request/i,
1135
+ generate: (line) => {
1136
+ const m = line.match(/(URI\.open\s*\(\s*)(\w+)\s*\)/);
1137
+ if (!m)
1138
+ return null;
1139
+ return { oldText: m[0], newText: `${m[1]}${m[2]}) # TODO: validate URL against allowlist to prevent SSRF` };
1140
+ },
1141
+ },
1142
+ // Ruby: yaml.load → YAML.safe_load
1143
+ {
1144
+ match: /unsafe.*yaml|yaml.*load|insecure.*yaml|deserialization/i,
1145
+ generate: (line) => {
1146
+ const m = line.match(/YAML\.load\s*\(/);
1147
+ if (!m)
1148
+ return null;
1149
+ return { oldText: m[0], newText: "YAML.safe_load(" };
1150
+ },
1151
+ },
1152
+ // Ruby: Marshal.load → JSON.parse
1153
+ {
1154
+ match: /unsafe.*deserialization|marshal.*untrusted|insecure.*deserialization/i,
1155
+ generate: (line) => {
1156
+ const m = line.match(/Marshal\.load\s*\(/);
1157
+ if (!m)
1158
+ return null;
1159
+ return { oldText: m[0], newText: "JSON.parse( # TODO: replace Marshal with safe serialization" };
1160
+ },
1161
+ },
1162
+ // Ruby: String interpolation in SQL → parameterized
1163
+ {
1164
+ match: /sql.*inject|string.*interpol.*sql|sql.*concat/i,
1165
+ generate: (line) => {
1166
+ const m = line.match(/(\.(?:where|find_by_sql|execute)\s*\(\s*)"([^"]*?)#\{(\w+)\}([^"]*)"/);
1167
+ if (!m)
1168
+ return null;
1169
+ return { oldText: m[0], newText: `${m[1]}"${m[2]}?${m[4]}", ${m[3]}` };
1170
+ },
1171
+ },
1172
+ // Ruby: Digest::MD5 → Digest::SHA256
1173
+ {
1174
+ match: /weak.*hash|insecure.*hash|md5|sha1/i,
1175
+ generate: (line) => {
1176
+ const m = line.match(/Digest::(MD5|SHA1)/);
1177
+ if (!m)
1178
+ return null;
1179
+ return { oldText: m[0], newText: "Digest::SHA256" };
1180
+ },
1181
+ },
1182
+ // Ruby: render inline with user input → sanitize
1183
+ {
1184
+ match: /xss|cross.*site.*script|render.*untrusted/i,
1185
+ generate: (line) => {
1186
+ const m = line.match(/(render\s+inline:\s*)(\w+)/);
1187
+ if (!m)
1188
+ return null;
1189
+ return { oldText: m[0], newText: `${m[1]}ERB::Util.html_escape(${m[2]})` };
1190
+ },
1191
+ },
1192
+ // ── PHP Patches ──
1193
+ // PHP: mysql_query → PDO prepared statement marker
1194
+ {
1195
+ match: /deprecated.*mysql|mysql_query|sql.*inject/i,
1196
+ generate: (line) => {
1197
+ const m = line.match(/mysql_query\s*\(\s*(".*?"|\$\w+)\s*\)/);
1198
+ if (!m)
1199
+ return null;
1200
+ return { oldText: m[0], newText: `$pdo->prepare(${m[1]})->execute() /* TODO: use PDO with bound parameters */` };
1201
+ },
1202
+ },
1203
+ // PHP: eval → safer alternative
1204
+ {
1205
+ match: /dangerous.*eval|eval.*usage|code.*inject/i,
1206
+ generate: (line) => {
1207
+ const m = line.match(/\beval\s*\(\s*(\$\w+)\s*\)/);
1208
+ if (!m)
1209
+ return null;
1210
+ return { oldText: m[0], newText: `json_decode(${m[1]}, true) /* TODO: eliminate eval — use safe parsing */` };
1211
+ },
1212
+ },
1213
+ // PHP: shell_exec/exec → escapeshellarg
1214
+ {
1215
+ match: /command.*inject|shell.*inject|os.*command/i,
1216
+ generate: (line) => {
1217
+ const m = line.match(/((?:shell_exec|exec|system|passthru)\s*\(\s*(?:["'].*?["']\s*\.\s*))(\$\w+)/);
1218
+ if (!m)
1219
+ return null;
1220
+ return { oldText: m[2], newText: `escapeshellarg(${m[2]})` };
1221
+ },
1222
+ },
1223
+ // PHP: md5/sha1 → password_hash for passwords
1224
+ {
1225
+ match: /weak.*hash|password.*hash|insecure.*hash/i,
1226
+ generate: (line) => {
1227
+ const m = line.match(/\bmd5\s*\(\s*(\$\w+)\s*\)/);
1228
+ if (!m)
1229
+ return null;
1230
+ return { oldText: m[0], newText: `password_hash(${m[1]}, PASSWORD_BCRYPT)` };
1231
+ },
1232
+ },
1233
+ // PHP: extract($_POST/GET/REQUEST) → manual assignment
1234
+ {
1235
+ match: /variable.*inject|mass.*assign|extract.*superglobal/i,
1236
+ generate: (line) => {
1237
+ const m = line.match(/extract\s*\(\s*\$_(POST|GET|REQUEST)\s*\)/);
1238
+ if (!m)
1239
+ return null;
1240
+ return { oldText: m[0], newText: `/* TODO: assign specific variables from \$_${m[1]} instead of extract() */` };
1241
+ },
1242
+ },
1243
+ // PHP: htmlspecialchars missing → add
1244
+ {
1245
+ match: /xss|cross.*site.*script|output.*encod|unescaped.*output/i,
1246
+ generate: (line) => {
1247
+ const m = line.match(/(echo\s+)(\$\w+)\s*;/);
1248
+ if (!m)
1249
+ return null;
1250
+ return { oldText: m[0], newText: `${m[1]}htmlspecialchars(${m[2]}, ENT_QUOTES, 'UTF-8');` };
1251
+ },
1252
+ },
1253
+ // PHP: unserialize → json_decode
1254
+ {
1255
+ match: /unsafe.*deserialization|unserialize.*untrusted|insecure.*deserialization/i,
1256
+ generate: (line) => {
1257
+ const m = line.match(/unserialize\s*\(\s*(\$\w+)\s*\)/);
1258
+ if (!m)
1259
+ return null;
1260
+ return { oldText: m[0], newText: `json_decode(${m[1]}, true) /* TODO: replace unserialize with safe format */` };
1261
+ },
1262
+ },
1263
+ // PHP: file_get_contents with user URL → validate
1264
+ {
1265
+ match: /ssrf|server.*side.*request|unvalidated.*url/i,
1266
+ generate: (line) => {
1267
+ const m = line.match(/(file_get_contents\s*\(\s*)(\$\w+)\s*\)/);
1268
+ if (!m)
1269
+ return null;
1270
+ return { oldText: m[0], newText: `${m[1]}${m[2]}) /* TODO: validate URL against allowlist to prevent SSRF */` };
1271
+ },
1272
+ },
1273
+ // PHP: rand() → random_int() (cryptographic)
1274
+ {
1275
+ match: /insecure.*random|weak.*random|predictable.*random/i,
1276
+ generate: (line) => {
1277
+ const m = line.match(/\brand\s*\(\s*(\d+)\s*,\s*(\d+)\s*\)/);
1278
+ if (!m)
1279
+ return null;
1280
+ return { oldText: m[0], newText: `random_int(${m[1]}, ${m[2]})` };
1281
+ },
1282
+ },
1283
+ // ── Kotlin Patches ──
1284
+ // Kotlin: !! (force unwrap) → safe call + default
1285
+ {
1286
+ match: /force.*unwrap|non-null.*assert|!!.*operator|null.*safety/i,
1287
+ generate: (line) => {
1288
+ const m = line.match(/(\w+)!!(\.\w+)/);
1289
+ if (!m)
1290
+ return null;
1291
+ return { oldText: m[0], newText: `${m[1]}?${m[2]} ?: throw IllegalStateException("${m[1]} was null")` };
1292
+ },
1293
+ },
1294
+ // Kotlin: Thread.sleep → delay (coroutines)
1295
+ {
1296
+ match: /thread.*sleep|blocking.*call|blocking.*thread/i,
1297
+ generate: (line) => {
1298
+ const m = line.match(/Thread\.sleep\s*\(\s*(\d+)\s*\)/);
1299
+ if (!m)
1300
+ return null;
1301
+ return { oldText: m[0], newText: `delay(${m[1]}) // TODO: ensure calling function is suspend` };
1302
+ },
1303
+ },
1304
+ // Kotlin: var → val (immutability)
1305
+ {
1306
+ match: /mutable.*variable|var.*instead.*val|prefer.*immutable/i,
1307
+ generate: (line) => {
1308
+ const m = line.match(/\bvar\s+(\w+)\s*[:=]/);
1309
+ if (!m)
1310
+ return null;
1311
+ return { oldText: `var ${m[1]}`, newText: `val ${m[1]}` };
1312
+ },
1313
+ },
1314
+ // Kotlin: catching generic Exception → specific
1315
+ {
1316
+ match: /catch.*generic|broad.*exception|catching.*exception/i,
1317
+ generate: (line) => {
1318
+ const m = line.match(/catch\s*\(\s*(e|ex|err)\s*:\s*Exception\s*\)/);
1319
+ if (!m)
1320
+ return null;
1321
+ return { oldText: m[0], newText: `catch (${m[1]}: Exception) /* TODO: use specific exception type */` };
1322
+ },
1323
+ },
1324
+ // Kotlin: hardcoded URL → BuildConfig
1325
+ {
1326
+ match: /hardcoded.*url|url.*hardcoded|base.*url.*literal/i,
1327
+ generate: (line) => {
1328
+ const m = line.match(/(["'])(https?:\/\/[^"']+)\1/);
1329
+ if (!m)
1330
+ return null;
1331
+ return { oldText: m[0], newText: `BuildConfig.BASE_URL /* TODO: move URL to build config */` };
1332
+ },
1333
+ },
1334
+ // Kotlin: String SQL concatenation → parameterized
1335
+ {
1336
+ match: /sql.*inject|sql.*concat|string.*template.*sql/i,
1337
+ generate: (line) => {
1338
+ const m = line.match(/(rawQuery\s*\(\s*)"([^"]*)\$(\w+)/);
1339
+ if (!m)
1340
+ return null;
1341
+ return { oldText: m[0], newText: `${m[1]}"${m[2]}?", arrayOf(${m[3]}` };
1342
+ },
1343
+ },
1344
+ // ── Swift Patches ──
1345
+ // Swift: force unwrap (!) → optional binding
1346
+ {
1347
+ match: /force.*unwrap|implicit.*unwrap|!.*operator.*crash/i,
1348
+ generate: (line) => {
1349
+ const m = line.match(/(\w+)!\s*\./);
1350
+ if (!m)
1351
+ return null;
1352
+ // Don't match Kotlin !! or negation
1353
+ if (line.includes("!!"))
1354
+ return null;
1355
+ return { oldText: m[0], newText: `${m[1]}?. // TODO: use if-let or guard-let for safe unwrapping` };
1356
+ },
1357
+ },
1358
+ // Swift: try! → do-catch reminder
1359
+ {
1360
+ match: /force.*try|try!.*crash|unhandled.*throw/i,
1361
+ generate: (line) => {
1362
+ const m = line.match(/\btry!\s+/);
1363
+ if (!m)
1364
+ return null;
1365
+ return { oldText: m[0], newText: "try /* TODO: wrap in do-catch */ " };
1366
+ },
1367
+ },
1368
+ // Swift: implicitly unwrapped optional → regular optional
1369
+ {
1370
+ match: /implicit.*unwrap.*optional|iuo.*declaration/i,
1371
+ generate: (line) => {
1372
+ const m = line.match(/(:\s*\w+)!/);
1373
+ if (!m)
1374
+ return null;
1375
+ return { oldText: m[0], newText: `${m[1]}?` };
1376
+ },
1377
+ },
1378
+ // Swift: NSLog → os_log (structured logging)
1379
+ {
1380
+ match: /nslog.*os_log|nslog.*instead|structured.*log/i,
1381
+ generate: (line) => {
1382
+ const m = line.match(/NSLog\s*\(([^)]*)\)/);
1383
+ if (!m)
1384
+ return null;
1385
+ return { oldText: m[0], newText: `os_log(.info, ${m[1]})` };
1386
+ },
1387
+ },
1388
+ // Swift: UserDefaults for sensitive data → Keychain
1389
+ {
1390
+ match: /userdefaults.*sensitive|insecure.*storage|keychain.*instead/i,
1391
+ generate: (line) => {
1392
+ const m = line.match(/(UserDefaults\.standard\.set\s*\([^,]+,\s*forKey:\s*)(["'][^"']*(?:password|token|secret|key)[^"']*["'])\s*\)/i);
1393
+ if (!m)
1394
+ return null;
1395
+ return {
1396
+ oldText: m[0],
1397
+ newText: `KeychainWrapper.standard.set(/* value */, forKey: ${m[2]}) /* TODO: use Keychain for sensitive data */`,
1398
+ };
1399
+ },
1400
+ },
1401
+ // Swift: print() → Logger
1402
+ {
1403
+ match: /print.*instead.*log|print.*production|remove.*print/i,
1404
+ generate: (line) => {
1405
+ const m = line.match(/\bprint\s*\(([^)]*)\)/);
1406
+ if (!m)
1407
+ return null;
1408
+ return { oldText: m[0], newText: `Logger().info(${m[1]})` };
1409
+ },
1410
+ },
1411
+ // ── Additional Cross-Language Patches ──
1412
+ // Terraform: overly broad CIDR → restrict
1413
+ {
1414
+ match: /overly.*broad.*cidr|0\.0\.0\.0\/0|unrestricted.*ingress|open.*to.*world/i,
1415
+ generate: (line) => {
1416
+ const m = line.match(/(["'])0\.0\.0\.0\/0\1/);
1417
+ if (!m)
1418
+ return null;
1419
+ return { oldText: m[0], newText: `${m[1]}10.0.0.0/8${m[1]} /* TODO: restrict to your CIDR range */` };
1420
+ },
1421
+ },
1422
+ // Terraform: public access enabled → private
1423
+ {
1424
+ match: /public.*access.*enabled|publicly.*accessible|public.*bucket/i,
1425
+ generate: (line) => {
1426
+ const m = line.match(/((?:publicly_accessible|public_access|public)\s*=\s*)true/i);
1427
+ if (!m)
1428
+ return null;
1429
+ return { oldText: m[0], newText: `${m[1]}false` };
1430
+ },
1431
+ },
1432
+ // Terraform: encryption disabled → enabled
1433
+ {
1434
+ match: /encryption.*disabled|unencrypted.*storage|encrypt.*at.*rest/i,
1435
+ generate: (line) => {
1436
+ const m = line.match(/((?:encrypted|encryption_enabled|encrypt)\s*=\s*)false/i);
1437
+ if (!m)
1438
+ return null;
1439
+ return { oldText: m[0], newText: `${m[1]}true` };
1440
+ },
1441
+ },
1442
+ // Bicep/ARM: HTTP allowed → HTTPS only
1443
+ {
1444
+ match: /http.*allowed|https.*only|transport.*security/i,
1445
+ generate: (line) => {
1446
+ const m = line.match(/(httpsOnly\s*:\s*)false/);
1447
+ if (!m)
1448
+ return null;
1449
+ return { oldText: m[0], newText: `${m[1]}true` };
1450
+ },
1451
+ },
1452
+ // ── Dockerfile additional patches ──
1453
+ // ADD → COPY (Docker best practice)
1454
+ {
1455
+ match: /add.*instead.*copy|docker.*add|prefer.*copy/i,
1456
+ generate: (line) => {
1457
+ const m = line.match(/^(\s*)ADD\s+(?!https?:)/);
1458
+ if (!m)
1459
+ return null;
1460
+ return { oldText: `${m[1]}ADD `, newText: `${m[1]}COPY ` };
1461
+ },
1462
+ },
1463
+ // Missing HEALTHCHECK
1464
+ {
1465
+ match: /missing.*healthcheck|no.*healthcheck|docker.*health/i,
1466
+ generate: (line) => {
1467
+ const m = line.match(/^(\s*)(CMD\s+.+)$/);
1468
+ if (!m)
1469
+ return null;
1470
+ return {
1471
+ oldText: m[0],
1472
+ newText: `HEALTHCHECK --interval=30s --timeout=3s CMD curl -f http://localhost:8080/ || exit 1\n${m[1]}${m[2]}`,
1473
+ };
1474
+ },
1475
+ },
1476
+ // ── GitHub Actions / CI Patches ──
1477
+ // Unpinned action version → pin to SHA
1478
+ {
1479
+ match: /unpinned.*action|action.*version.*pin|uses.*latest/i,
1480
+ generate: (line) => {
1481
+ const m = line.match(/(uses:\s*)(\S+)@(master|main|latest)\b/);
1482
+ if (!m)
1483
+ return null;
1484
+ return { oldText: m[0], newText: `${m[1]}${m[2]}@v4 /* TODO: pin to specific SHA */` };
1485
+ },
1486
+ },
1487
+ // ═══ Authentication Patches ═══
1488
+ // AUTH: plaintext password comparison → bcrypt
1489
+ {
1490
+ match: /AUTH-.*|plaintext.*password|password.*comparison.*plain|comparing.*password/i,
1491
+ generate: (line) => {
1492
+ const m = line.match(/(password|passwd)\s*===?\s*(\w+)/i);
1493
+ if (!m)
1494
+ return null;
1495
+ return { oldText: m[0], newText: `await bcrypt.compare(${m[2]}, hashedPassword) /* TODO: use bcrypt */` };
1496
+ },
1497
+ },
1498
+ // AUTH: session without expiry → add maxAge
1499
+ {
1500
+ match: /session.*expir|session.*timeout|session.*no.*expir/i,
1501
+ generate: (line) => {
1502
+ const m = line.match(/(session\s*\(\s*\{[^}]*?)(\})/);
1503
+ if (!m)
1504
+ return null;
1505
+ if (/maxAge|expires/.test(m[1]))
1506
+ return null;
1507
+ return { oldText: m[0], newText: `${m[1]}, maxAge: 1800000 /* 30 min */}` };
1508
+ },
1509
+ },
1510
+ // AUTH: jwt.decode → jwt.verify
1511
+ {
1512
+ match: /jwt.*decode.*verify|unverified.*jwt|jwt.*without.*verif/i,
1513
+ generate: (line) => {
1514
+ const m = line.match(/jwt\.decode\s*\(/);
1515
+ if (!m)
1516
+ return null;
1517
+ return { oldText: m[0], newText: `jwt.verify(` };
1518
+ },
1519
+ },
1520
+ // AUTH: missing rate limit on login
1521
+ {
1522
+ match: /brute.*force|login.*rate.*limit|missing.*rate.*limit.*auth/i,
1523
+ generate: (line) => {
1524
+ const m = line.match(/^(\s*)((?:app|router)\.post\s*\(\s*["']\/(?:login|auth|signin)["'])/);
1525
+ if (!m)
1526
+ return null;
1527
+ return {
1528
+ oldText: m[0],
1529
+ newText: `${m[1]}/* TODO: add rate limiting middleware (e.g., express-rate-limit) */\n${m[1]}${m[2]}`,
1530
+ };
1531
+ },
1532
+ },
1533
+ // ═══ Data Security Patches ═══
1534
+ // DSEC: storing PII in localStorage
1535
+ {
1536
+ match: /pii.*localStorage|sensitive.*local.*storage|localStorage.*personal/i,
1537
+ generate: (line) => {
1538
+ const m = line.match(/localStorage\.(setItem)\s*\(\s*(["'][^"']*(?:email|ssn|phone|name|address|dob)[^"']*["'])/i);
1539
+ if (!m)
1540
+ return null;
1541
+ return {
1542
+ oldText: `localStorage.${m[1]}`,
1543
+ newText: `sessionStorage.setItem /* TODO: encrypt or use httpOnly cookie instead */`,
1544
+ };
1545
+ },
1546
+ },
1547
+ // DSEC: logging PII fields
1548
+ {
1549
+ match: /pii.*log|logging.*personal|log.*sensitive|LOGPRIV/i,
1550
+ generate: (line) => {
1551
+ const m = line.match(/(console\.log|logger\.\w+)\s*\([^)]*\b(email|ssn|password|creditCard|phoneNumber|socialSecurity)\b/i);
1552
+ if (!m)
1553
+ return null;
1554
+ return { oldText: m[2], newText: `[REDACTED:${m[2]}]` };
1555
+ },
1556
+ },
1557
+ // ═══ Accessibility Patches ═══
1558
+ // A11Y: img without alt → add alt=""
1559
+ {
1560
+ match: /A11Y-.*|missing.*alt|img.*alt|image.*alt/i,
1561
+ generate: (line) => {
1562
+ const m = line.match(/(<img\s+(?:(?!alt=)[^>])*?)(\/?>)/i);
1563
+ if (!m)
1564
+ return null;
1565
+ if (/alt=/i.test(m[1]))
1566
+ return null;
1567
+ return { oldText: m[0], newText: `${m[1]} alt="" /* TODO: add descriptive alt text */${m[2]}` };
1568
+ },
1569
+ },
1570
+ // A11Y: button/link without aria-label (icon-only)
1571
+ {
1572
+ match: /aria.*label|icon.*button.*access|accessible.*name/i,
1573
+ generate: (line) => {
1574
+ const m = line.match(/(<(?:button|a)\s+(?:(?!aria-label)[^>])*?)(>)/i);
1575
+ if (!m)
1576
+ return null;
1577
+ if (/aria-label=/.test(m[1]))
1578
+ return null;
1579
+ if (!/icon|svg|fa-|material-icon/i.test(line))
1580
+ return null;
1581
+ return { oldText: m[0], newText: `${m[1]} aria-label="TODO: describe action"${m[2]}` };
1582
+ },
1583
+ },
1584
+ // A11Y: onClick div → button
1585
+ {
1586
+ match: /interactive.*div|div.*onclick|click.*handler.*div/i,
1587
+ generate: (line) => {
1588
+ const m = line.match(/<div(\s+[^>]*?)onClick/i);
1589
+ if (!m)
1590
+ return null;
1591
+ return { oldText: `<div${m[1]}onClick`, newText: `<button${m[1]}onClick` };
1592
+ },
1593
+ },
1594
+ // A11Y: autocomplete off on login fields
1595
+ {
1596
+ match: /autocomplete.*off.*password|login.*autocomplete/i,
1597
+ generate: (line) => {
1598
+ const m = line.match(/(type=["']password["'][^>]*?)autocomplete=["']off["']/i);
1599
+ if (!m)
1600
+ return null;
1601
+ return { oldText: `autocomplete="off"`, newText: `autocomplete="current-password"` };
1602
+ },
1603
+ },
1604
+ // ═══ AI Code Safety Patches ═══
1605
+ // AICS: user input concatenated into prompt
1606
+ {
1607
+ match: /AICS-.*|prompt.*inject|user.*input.*prompt|llm.*inject/i,
1608
+ generate: (line) => {
1609
+ const m = line.match(/(`[^`]*\$\{(?:req\.body|req\.query|request\.\w+|user[Ii]nput|input)\b[^}]*\}[^`]*`)/);
1610
+ if (!m)
1611
+ return null;
1612
+ return { oldText: m[0], newText: `/* TODO: sanitize user input before LLM prompt */ ${m[0]}` };
1613
+ },
1614
+ },
1615
+ // AICS: LLM output in innerHTML
1616
+ {
1617
+ match: /llm.*output.*html|ai.*output.*innerhtml|inject.*llm.*output/i,
1618
+ generate: (line) => {
1619
+ const m = line.match(/\.innerHTML\s*=\s*(\w+(?:\.(?:response|output|text|completion|content))?)/);
1620
+ if (!m)
1621
+ return null;
1622
+ return { oldText: `.innerHTML = ${m[1]}`, newText: `.textContent = ${m[1]} /* sanitize LLM output */` };
1623
+ },
1624
+ },
1625
+ // ═══ Compliance Patches ═══
1626
+ // COMP: cookie without consent check
1627
+ {
1628
+ match: /cookie.*consent|gdpr.*cookie|tracking.*consent/i,
1629
+ generate: (line) => {
1630
+ const m = line.match(/^(\s*)(document\.cookie\s*=)/);
1631
+ if (!m)
1632
+ return null;
1633
+ return { oldText: m[0], newText: `${m[1]}if (hasUserConsent()) ${m[2]} /* TODO: implement consent check */` };
1634
+ },
1635
+ },
1636
+ // COMP: collecting data without purpose
1637
+ {
1638
+ match: /data.*purpose|purpose.*limitation|gdpr.*purpose/i,
1639
+ generate: (line) => {
1640
+ const m = line.match(/^(\s*)((?:const|let|var)\s+\w+\s*=\s*(?:req\.body|request\.(?:form|json)))/);
1641
+ if (!m)
1642
+ return null;
1643
+ return {
1644
+ oldText: m[0],
1645
+ newText: `${m[1]}/* TODO: validate data collection purpose against privacy policy */\n${m[1]}${m[2]}`,
1646
+ };
1647
+ },
1648
+ },
1649
+ // ═══ Performance Patches ═══
1650
+ // PERF: regex in loop → pre-compile
1651
+ {
1652
+ match: /regex.*loop|regexp.*inside.*loop|pattern.*repeated/i,
1653
+ generate: (line) => {
1654
+ const m = line.match(/(new\s+RegExp\s*\(\s*(["'][^"']+["'])\s*(?:,\s*["'][^"']*["'])?\s*\))/);
1655
+ if (!m)
1656
+ return null;
1657
+ return { oldText: m[0], newText: `/* TODO: pre-compile regex outside loop */ ${m[0]}` };
1658
+ },
1659
+ },
1660
+ // PERF: Array spread in reduce → push
1661
+ {
1662
+ match: /spread.*reduce|array.*spread.*accumul|O\(n.\).*reduce/i,
1663
+ generate: (line) => {
1664
+ const m = line.match(/\[\.\.\.(acc|accumulator|result)\s*,/);
1665
+ if (!m)
1666
+ return null;
1667
+ return { oldText: `[...${m[1]},`, newText: `/* TODO: use push() instead of spread in reduce */ [...${m[1]},` };
1668
+ },
1669
+ },
1670
+ // ═══ Observability Patches ═══
1671
+ // OBS: catch without logging
1672
+ {
1673
+ match: /catch.*no.*log|error.*not.*logged|swallow.*without.*log/i,
1674
+ generate: (line) => {
1675
+ const m = line.match(/^(\s*)\}\s*catch\s*\((\w+)\)\s*\{\s*$/);
1676
+ if (!m)
1677
+ return null;
1678
+ return { oldText: m[0], newText: `${m[0]}\n${m[1]} console.error('Error:', ${m[2]});` };
1679
+ },
1680
+ },
1681
+ // ═══ IaC Security Patches ═══
1682
+ // IaC: Dockerfile USER root → USER node
1683
+ {
1684
+ match: /docker.*root|container.*root|USER.*root/i,
1685
+ generate: (line) => {
1686
+ const m = line.match(/^USER\s+root\s*$/);
1687
+ if (!m)
1688
+ return null;
1689
+ return { oldText: m[0], newText: `USER node` };
1690
+ },
1691
+ },
1692
+ // IaC: Terraform allow all ingress → restrict CIDR
1693
+ {
1694
+ match: /ingress.*0\.0\.0\.0|open.*ingress|unrestricted.*ingress/i,
1695
+ generate: (line) => {
1696
+ const m = line.match(/(cidr_blocks\s*=\s*\[)"0\.0\.0\.0\/0"(\])/);
1697
+ if (!m)
1698
+ return null;
1699
+ return { oldText: m[0], newText: `${m[1]}"10.0.0.0/8"${m[2]} /* TODO: restrict to your CIDR */` };
1700
+ },
1701
+ },
1702
+ // IaC: Kubernetes privileged container → drop privileges
1703
+ {
1704
+ match: /privileged.*true|container.*privileged|security.*context.*privileged/i,
1705
+ generate: (line) => {
1706
+ const m = line.match(/privileged:\s*true/);
1707
+ if (!m)
1708
+ return null;
1709
+ return { oldText: m[0], newText: `privileged: false` };
1710
+ },
1711
+ },
1712
+ // ═══ Database Patches ═══
1713
+ // DB: missing index comment
1714
+ {
1715
+ match: /missing.*index|no.*index.*query|full.*table.*scan/i,
1716
+ generate: (line) => {
1717
+ const m = line.match(/^(\s*)((?:SELECT|FROM|WHERE)\b.*)$/i);
1718
+ if (!m)
1719
+ return null;
1720
+ return { oldText: m[0], newText: `${m[1]}/* TODO: ensure WHERE-clause columns are indexed */ ${m[2]}` };
1721
+ },
1722
+ },
1723
+ // DB: transaction missing rollback
1724
+ {
1725
+ match: /transaction.*rollback|missing.*rollback|no.*rollback/i,
1726
+ generate: (line) => {
1727
+ const m = line.match(/^(\s*)((?:await\s+)?(?:client|conn|db|connection)\.query\s*\(\s*["']BEGIN)/);
1728
+ if (!m)
1729
+ return null;
1730
+ return { oldText: m[0], newText: `${m[1]}/* TODO: wrap in try/catch with ROLLBACK on error */\n${m[1]}${m[2]}` };
1731
+ },
1732
+ },
1733
+ // ═══ Concurrency Patches ═══
1734
+ // CONC: shared mutable variable → atomics hint
1735
+ {
1736
+ match: /race.*condition|shared.*mutable|concurrent.*access/i,
1737
+ generate: (line) => {
1738
+ const m = line.match(/^(\s*)(let|var)\s+(\w+)\s*=\s*(\d+)/);
1739
+ if (!m)
1740
+ return null;
1741
+ return { oldText: m[0], newText: `${m[1]}/* TODO: protect with mutex/lock */ ${m[2]} ${m[3]} = ${m[4]}` };
1742
+ },
1743
+ },
1744
+ // ═══ API Design Patches ═══
1745
+ // API: missing pagination
1746
+ {
1747
+ match: /missing.*pagination|no.*pagina|unbounded.*list/i,
1748
+ generate: (line) => {
1749
+ const m = line.match(/(\.find\s*\(\s*\{[^}]*\})\s*\)/);
1750
+ if (!m)
1751
+ return null;
1752
+ return { oldText: m[0], newText: `${m[1]}).limit(100) /* TODO: add proper pagination */` };
1753
+ },
1754
+ },
1755
+ // API: missing content-type validation
1756
+ {
1757
+ match: /content.*type.*valid|missing.*content.*type/i,
1758
+ generate: (line) => {
1759
+ const m = line.match(/^(\s*)((?:app|router)\.(post|put|patch)\s*\()/);
1760
+ if (!m)
1761
+ return null;
1762
+ return { oldText: m[0], newText: `${m[1]}/* TODO: validate Content-Type header */\n${m[1]}${m[2]}` };
1763
+ },
1764
+ },
1765
+ // ═══ Internationalization Patches ═══
1766
+ // I18N: hardcoded user-facing string → i18n key
1767
+ {
1768
+ match: /I18N-.*|hardcoded.*string|user.*facing.*literal/i,
1769
+ generate: (line) => {
1770
+ const m = line.match(/((?:label|title|message|placeholder|text|heading)\s*[:=]\s*)(["'])([A-Z][a-z].*?)\2/);
1771
+ if (!m)
1772
+ return null;
1773
+ const key = m[3]
1774
+ .toLowerCase()
1775
+ .replace(/\s+/g, "_")
1776
+ .replace(/[^a-z0-9_]/g, "")
1777
+ .slice(0, 30);
1778
+ return {
1779
+ oldText: `${m[1]}${m[2]}${m[3]}${m[2]}`,
1780
+ newText: `${m[1]}t("${key}") /* was: ${m[2]}${m[3]}${m[2]} */`,
1781
+ };
1782
+ },
1783
+ },
1784
+ // ═══ Scalability Patches ═══
1785
+ // SCAL: in-memory session store → comment
1786
+ {
1787
+ match: /in.*memory.*session|session.*memory.*store|express.*session.*default/i,
1788
+ generate: (line) => {
1789
+ const m = line.match(/^(\s*)(app\.use\s*\(\s*session\s*\(\s*\{)/);
1790
+ if (!m)
1791
+ return null;
1792
+ return {
1793
+ oldText: m[0],
1794
+ newText: `${m[1]}/* TODO: use Redis/database session store for multi-instance */ ${m[2]}`,
1795
+ };
1796
+ },
1797
+ },
1798
+ // ═══ Sovereignty Patches ═══
1799
+ // SOV: data sent to external analytics
1800
+ {
1801
+ match: /data.*third.*party|analytics.*external|sov.*data.*transfer/i,
1802
+ generate: (line) => {
1803
+ const m = line.match(/^(\s*)((?:fetch|axios\.\w+|https?\.(?:get|post))\s*\(\s*["']https?:\/\/(?:analytics|tracking|telemetry)\b)/);
1804
+ if (!m)
1805
+ return null;
1806
+ return { oldText: m[0], newText: `${m[1]}/* TODO: verify data residency compliance before sending */ ${m[2]}` };
1807
+ },
1808
+ },
1809
+ // ═══ Framework Safety Patches ═══
1810
+ // FW: Express without helmet → add helmet
1811
+ {
1812
+ match: /missing.*helmet|no.*security.*headers|express.*headers/i,
1813
+ generate: (line) => {
1814
+ const m = line.match(/^(\s*)(const\s+app\s*=\s*express\s*\(\s*\)\s*;?)/);
1815
+ if (!m)
1816
+ return null;
1817
+ return {
1818
+ oldText: m[0],
1819
+ newText: `${m[1]}const helmet = require("helmet"); /* TODO: npm install helmet */\n${m[1]}${m[2]}\n${m[1]}app.use(helmet());`,
1820
+ };
1821
+ },
1822
+ },
1823
+ // FW: Flask debug mode in production
1824
+ {
1825
+ match: /flask.*debug|debug.*production|app\.run.*debug/i,
1826
+ generate: (line) => {
1827
+ const m = line.match(/app\.run\s*\(\s*([^)]*)debug\s*=\s*True/);
1828
+ if (!m)
1829
+ return null;
1830
+ return { oldText: `debug=True`, newText: `debug=os.environ.get("FLASK_DEBUG", "false") == "true"` };
1831
+ },
1832
+ },
1833
+ // FW: Django SECRET_KEY hardcoded
1834
+ {
1835
+ match: /django.*secret|SECRET_KEY.*hardcoded|hardcoded.*django/i,
1836
+ generate: (line) => {
1837
+ const m = line.match(/^(\s*)SECRET_KEY\s*=\s*(["'])[^"']+\2/);
1838
+ if (!m)
1839
+ return null;
1840
+ return {
1841
+ oldText: m[0],
1842
+ newText: `${m[1]}SECRET_KEY = os.environ.get("DJANGO_SECRET_KEY", "change-me-in-production")`,
1843
+ };
1844
+ },
1845
+ },
1846
+ // ═══ Supply Chain Patches ═══
1847
+ // DEP: importing from CDN without SRI
1848
+ {
1849
+ match: /sri.*missing|subresource.*integrity|cdn.*integrity/i,
1850
+ generate: (line) => {
1851
+ const m = line.match(/(<script\s+src=["']https?:\/\/cdn[^"']*["'])(\s*>)/i);
1852
+ if (!m)
1853
+ return null;
1854
+ if (/integrity=/i.test(m[1]))
1855
+ return null;
1856
+ return { oldText: m[0], newText: `${m[1]} integrity="TODO:sha384-hash" crossorigin="anonymous"${m[2]}` };
1857
+ },
1858
+ },
1859
+ ];
1860
+ const MULTI_LINE_PATCH_RULES = [
1861
+ // ── Multi-line empty catch block → re-throw with error parameter ──
1862
+ {
1863
+ match: /empty.*catch|catch.*swallow|catch.*discard/i,
1864
+ contextLines: 6,
1865
+ generate: (windowLines, windowStart, _findingLine) => {
1866
+ for (let i = 0; i < windowLines.length; i++) {
1867
+ const line = windowLines[i];
1868
+ const catchMatch = line.match(/^(\s*)(?:}\s*)?catch\s*\(([^)]*)\)\s*\{\s*$/);
1869
+ if (!catchMatch)
1870
+ continue;
1871
+ const indent = catchMatch[1];
1872
+ const param = catchMatch[2].trim() || "error";
1873
+ // Find matching closing brace — everything inside must be empty/comments
1874
+ let braceDepth = 1;
1875
+ let endIdx = -1;
1876
+ for (let j = i + 1; j < windowLines.length; j++) {
1877
+ const inner = windowLines[j];
1878
+ for (const ch of inner) {
1879
+ if (ch === "{")
1880
+ braceDepth++;
1881
+ if (ch === "}")
1882
+ braceDepth--;
1883
+ }
1884
+ if (braceDepth === 0) {
1885
+ endIdx = j;
1886
+ break;
1887
+ }
1888
+ // Non-empty, non-comment line means the catch isn't truly empty
1889
+ if (inner.trim() !== "" && !/^\s*\/\//.test(inner))
1890
+ return null;
1891
+ }
1892
+ if (endIdx <= i)
1893
+ continue;
1894
+ const oldText = windowLines.slice(i, endIdx + 1).join("\n");
1895
+ const newText = `${indent}catch (${param}) {\n${indent} /* TODO: handle error appropriately */ throw ${param};\n${indent}}`;
1896
+ return { oldText, newText, startLine: windowStart + i, endLine: windowStart + endIdx };
1897
+ }
1898
+ return null;
1899
+ },
1900
+ },
1901
+ // ── Bare JSON.parse → try/catch wrapped ──
1902
+ {
1903
+ match: /unsafe.*json|json.*parse.*unguard|deserialization(?!.*already)/i,
1904
+ contextLines: 2,
1905
+ generate: (windowLines, windowStart, findingLine) => {
1906
+ const idx = findingLine - windowStart;
1907
+ if (idx < 0 || idx >= windowLines.length)
1908
+ return null;
1909
+ const line = windowLines[idx];
1910
+ const m = line.match(/^(\s*)(const|let|var)\s+(\w+)\s*=\s*JSON\.parse\s*\(([^)]+)\)\s*;?\s*$/);
1911
+ if (!m)
1912
+ return null;
1913
+ const [, indent, , varName, arg] = m;
1914
+ const oldText = line;
1915
+ const newText = [
1916
+ `${indent}let ${varName};`,
1917
+ `${indent}try { ${varName} = JSON.parse(${arg}); }`,
1918
+ `${indent}catch { ${varName} = null; /* TODO: handle parse error */ }`,
1919
+ ].join("\n");
1920
+ return { oldText, newText, startLine: findingLine, endLine: findingLine };
1921
+ },
1922
+ },
1923
+ // ── Server .listen() without error callback → add error handler ──
1924
+ {
1925
+ match: /no.*error.*callback|listen.*without.*error|server.*error.*handling/i,
1926
+ contextLines: 2,
1927
+ generate: (windowLines, windowStart, findingLine) => {
1928
+ const idx = findingLine - windowStart;
1929
+ if (idx < 0 || idx >= windowLines.length)
1930
+ return null;
1931
+ const line = windowLines[idx];
1932
+ const m = line.match(/^(\s*)((?:\w+\.)?listen\s*\(\s*(\d+|[\w.]+)\s*)\)\s*;?\s*$/);
1933
+ if (!m)
1934
+ return null;
1935
+ const [, indent, prefix, port] = m;
1936
+ const oldText = line;
1937
+ const newText = [
1938
+ `${indent}${prefix}, () => {`,
1939
+ `${indent} console.log(\`Server listening on port ${port}\`);`,
1940
+ `${indent}}).on("error", (err) => {`,
1941
+ `${indent} console.error("Server failed to start:", err);`,
1942
+ `${indent} process.exitCode = 1;`,
1943
+ `${indent}});`,
1944
+ ].join("\n");
1945
+ return { oldText, newText, startLine: findingLine, endLine: findingLine };
1946
+ },
1947
+ },
1948
+ // ── Bare await without try/catch → wrap in try/catch ──
1949
+ {
1950
+ match: /unhandled.*reject|await.*without.*catch|async.*error.*handling/i,
1951
+ contextLines: 3,
1952
+ generate: (windowLines, windowStart, findingLine) => {
1953
+ const idx = findingLine - windowStart;
1954
+ if (idx < 0 || idx >= windowLines.length)
1955
+ return null;
1956
+ const line = windowLines[idx];
1957
+ const m = line.match(/^(\s*)((?:const|let|var)\s+\w+\s*=\s*await\s+.+?)\s*;?\s*$/);
1958
+ if (!m)
1959
+ return null;
1960
+ // Check that there is no try/catch wrapping already
1961
+ const before = windowLines.slice(Math.max(0, idx - 3), idx).join("\n");
1962
+ if (/\btry\s*\{/.test(before))
1963
+ return null;
1964
+ const [, indent, stmt] = m;
1965
+ const oldText = line;
1966
+ const newText = [
1967
+ `${indent}try {`,
1968
+ `${indent} ${stmt.trim()};`,
1969
+ `${indent}} catch (error) {`,
1970
+ `${indent} /* TODO: handle async error */ throw error;`,
1971
+ `${indent}}`,
1972
+ ].join("\n");
1973
+ return { oldText, newText, startLine: findingLine, endLine: findingLine };
1974
+ },
1975
+ },
1976
+ // ── Dockerfile FROM :latest → pinned with comment ──
1977
+ {
1978
+ match: /latest.*tag|docker.*latest|unpinned.*base/i,
1979
+ contextLines: 1,
1980
+ generate: (windowLines, windowStart, findingLine) => {
1981
+ const idx = findingLine - windowStart;
1982
+ if (idx < 0 || idx >= windowLines.length)
1983
+ return null;
1984
+ const line = windowLines[idx];
1985
+ const m = line.match(/^(\s*)(FROM\s+)(\S+):latest(\s+AS\s+\S+)?\s*$/i);
1986
+ if (!m)
1987
+ return null;
1988
+ const [, indent, from, image, alias] = m;
1989
+ const oldText = line;
1990
+ const newText = `${indent}# TODO: pin to a specific version for reproducibility\n${indent}${from}${image}:lts-slim${alias || ""}`;
1991
+ return { oldText, newText, startLine: findingLine, endLine: findingLine };
1992
+ },
1993
+ },
1994
+ // ── Express app without helmet → add helmet middleware ──
1995
+ {
1996
+ match: /missing.*helmet|security.*headers.*middleware|no.*helmet/i,
1997
+ contextLines: 5,
1998
+ generate: (windowLines, windowStart, findingLine) => {
1999
+ const idx = findingLine - windowStart;
2000
+ if (idx < 0 || idx >= windowLines.length)
2001
+ return null;
2002
+ const line = windowLines[idx];
2003
+ const m = line.match(/^(\s*)(const\s+app\s*=\s*express\s*\(\s*\)\s*;?\s*)$/);
2004
+ if (!m)
2005
+ return null;
2006
+ const [, indent, appInit] = m;
2007
+ const oldText = line;
2008
+ const newText = [
2009
+ `${indent}const helmet = require("helmet"); /* TODO: npm install helmet */`,
2010
+ `${indent}${appInit}`,
2011
+ `${indent}app.use(helmet());`,
2012
+ ].join("\n");
2013
+ return { oldText, newText, startLine: findingLine, endLine: findingLine };
2014
+ },
2015
+ },
2016
+ // ── Missing rate limiting → add express-rate-limit middleware ──
2017
+ {
2018
+ match: /rate.*limit.*missing|no.*rate.*limit|missing.*rate.*limit/i,
2019
+ contextLines: 5,
2020
+ generate: (windowLines, windowStart, findingLine) => {
2021
+ const idx = findingLine - windowStart;
2022
+ if (idx < 0 || idx >= windowLines.length)
2023
+ return null;
2024
+ const line = windowLines[idx];
2025
+ const m = line.match(/^(\s*)(const\s+app\s*=\s*express\s*\(\s*\)\s*;?\s*)$/);
2026
+ if (!m)
2027
+ return null;
2028
+ const [, indent, appInit] = m;
2029
+ const oldText = line;
2030
+ const newText = [
2031
+ `${indent}const rateLimit = require("express-rate-limit"); /* TODO: npm install express-rate-limit */`,
2032
+ `${indent}${appInit}`,
2033
+ `${indent}app.use(rateLimit({ windowMs: 15 * 60 * 1000, max: 100 }));`,
2034
+ ].join("\n");
2035
+ return { oldText, newText, startLine: findingLine, endLine: findingLine };
2036
+ },
2037
+ },
2038
+ // ── String concatenation SQL → parameterized query (Node.js) ──
2039
+ {
2040
+ match: /sql.*inject|sql.*concatenat|string.*concat.*query/i,
2041
+ contextLines: 3,
2042
+ generate: (windowLines, windowStart, findingLine) => {
2043
+ const idx = findingLine - windowStart;
2044
+ if (idx < 0 || idx >= windowLines.length)
2045
+ return null;
2046
+ const line = windowLines[idx];
2047
+ const m = line.match(/^(\s*)([\w.]+\.query\s*\(\s*)(["'`])(.+?)\3\s*\+\s*(\w+)\s*\)/);
2048
+ if (!m)
2049
+ return null;
2050
+ const [, indent, queryCall, quote, sql, param] = m;
2051
+ const oldText = line;
2052
+ const newText = `${indent}${queryCall}${quote}${sql}$1${quote}, [${param}])`;
2053
+ return { oldText, newText, startLine: findingLine, endLine: findingLine };
2054
+ },
2055
+ },
2056
+ // ── Error handler leaking stack trace → sanitized response ──
2057
+ {
2058
+ match: /error.*handler.*leak|stack.*trace.*response|error.*detail.*client/i,
2059
+ contextLines: 6,
2060
+ generate: (windowLines, windowStart) => {
2061
+ for (let i = 0; i < windowLines.length; i++) {
2062
+ const line = windowLines[i];
2063
+ if (!line.match(/app\.use\s*\(\s*\(\s*(?:err|error)\s*,\s*req\s*,\s*res\s*,\s*next\s*\)/))
2064
+ continue;
2065
+ const indent = line.match(/^(\s*)/)?.[1] || "";
2066
+ for (let j = i + 1; j < Math.min(i + 8, windowLines.length); j++) {
2067
+ const bodyLine = windowLines[j];
2068
+ if (bodyLine.match(/res\.(?:json|send)\s*\(\s*\{[^}]*(?:stack|trace)/)) {
2069
+ const oldText = bodyLine;
2070
+ const newText = `${indent} res.status(err.status || 500).json({ error: process.env.NODE_ENV === "production" ? "Internal server error" : err.message });`;
2071
+ return { oldText, newText, startLine: windowStart + j, endLine: windowStart + j };
2072
+ }
2073
+ }
2074
+ }
2075
+ return null;
2076
+ },
2077
+ },
2078
+ // ── Missing input validation → add schema guard ──
2079
+ {
2080
+ match: /input.*validation.*missing|no.*input.*valid|request.*body.*unvalid/i,
2081
+ contextLines: 3,
2082
+ generate: (windowLines, windowStart, findingLine) => {
2083
+ const idx = findingLine - windowStart;
2084
+ if (idx < 0 || idx >= windowLines.length)
2085
+ return null;
2086
+ const line = windowLines[idx];
2087
+ const m = line.match(/^(\s*)(app\.(?:post|put|patch)\s*\(\s*["'][^"']+["']\s*,\s*(?:async\s*)?\(\s*req\s*,\s*res\s*\)\s*=>\s*\{)\s*$/);
2088
+ if (!m)
2089
+ return null;
2090
+ const [, indent, handler] = m;
2091
+ const oldText = line;
2092
+ const newText = [
2093
+ `${indent}${handler}`,
2094
+ `${indent} /* TODO: add input validation (e.g. Zod, Joi, or express-validator) */`,
2095
+ `${indent} if (!req.body || typeof req.body !== "object") { return res.status(400).json({ error: "Invalid request body" }); }`,
2096
+ ].join("\n");
2097
+ return { oldText, newText, startLine: findingLine, endLine: findingLine };
2098
+ },
2099
+ },
2100
+ // ── Python: bare except with pass → specific exception with logging ──
2101
+ {
2102
+ match: /bare.*except|broad.*except.*python|pokemon.*except/i,
2103
+ contextLines: 4,
2104
+ generate: (windowLines, windowStart, findingLine) => {
2105
+ const idx = findingLine - windowStart;
2106
+ if (idx < 0 || idx >= windowLines.length)
2107
+ return null;
2108
+ const line = windowLines[idx];
2109
+ const m = line.match(/^(\s*)except\s*:\s*$/);
2110
+ if (!m)
2111
+ return null;
2112
+ const indent = m[1];
2113
+ const nextIdx = idx + 1;
2114
+ if (nextIdx < windowLines.length && windowLines[nextIdx].match(/^\s*pass\s*$/)) {
2115
+ const oldText = windowLines.slice(idx, nextIdx + 1).join("\n");
2116
+ const newText = `${indent}except Exception as e: # TODO: use specific exception\n${indent} logging.exception("Unexpected error: %s", e)`;
2117
+ return { oldText, newText, startLine: findingLine, endLine: windowStart + nextIdx };
2118
+ }
2119
+ const oldText = line;
2120
+ const newText = `${indent}except Exception as e: # TODO: use specific exception`;
2121
+ return { oldText, newText, startLine: findingLine, endLine: findingLine };
2122
+ },
2123
+ },
2124
+ // ── Go HTTP server without timeout → add timeouts ──
2125
+ {
2126
+ match: /http.*server.*timeout|missing.*timeout.*server|server.*no.*timeout/i,
2127
+ contextLines: 3,
2128
+ generate: (windowLines, windowStart, findingLine) => {
2129
+ const idx = findingLine - windowStart;
2130
+ if (idx < 0 || idx >= windowLines.length)
2131
+ return null;
2132
+ const line = windowLines[idx];
2133
+ const m = line.match(/^(\s*)((?:srv|server|s)\s*:?=\s*&http\.Server\s*\{)\s*$/);
2134
+ if (!m)
2135
+ return null;
2136
+ const [, indent, serverInit] = m;
2137
+ const rest = windowLines.slice(idx + 1, idx + 6).join("\n");
2138
+ if (/ReadTimeout|WriteTimeout/.test(rest))
2139
+ return null;
2140
+ const oldText = line;
2141
+ const newText = [
2142
+ `${indent}${serverInit}`,
2143
+ `${indent}\tReadTimeout: 15 * time.Second,`,
2144
+ `${indent}\tWriteTimeout: 15 * time.Second,`,
2145
+ `${indent}\tIdleTimeout: 60 * time.Second,`,
2146
+ ].join("\n");
2147
+ return { oldText, newText, startLine: findingLine, endLine: findingLine };
2148
+ },
2149
+ },
2150
+ // ── Missing CORS configuration → proper CORS setup ──
2151
+ {
2152
+ match: /cors.*not.*config|missing.*cors|cors.*missing/i,
2153
+ contextLines: 5,
2154
+ generate: (windowLines, windowStart, findingLine) => {
2155
+ const idx = findingLine - windowStart;
2156
+ if (idx < 0 || idx >= windowLines.length)
2157
+ return null;
2158
+ const line = windowLines[idx];
2159
+ const m = line.match(/^(\s*)(const\s+app\s*=\s*express\s*\(\s*\)\s*;?\s*)$/);
2160
+ if (!m)
2161
+ return null;
2162
+ const [, indent, appInit] = m;
2163
+ const oldText = line;
2164
+ const newText = [
2165
+ `${indent}const cors = require("cors"); /* TODO: npm install cors */`,
2166
+ `${indent}${appInit}`,
2167
+ `${indent}app.use(cors({ origin: process.env.ALLOWED_ORIGIN || "http://localhost:3000", credentials: true }));`,
2168
+ ].join("\n");
2169
+ return { oldText, newText, startLine: findingLine, endLine: findingLine };
2170
+ },
2171
+ },
2172
+ // ── Ruby: begin/rescue without specific exception → add specific ──
2173
+ {
2174
+ match: /bare.*rescue|rescue.*generic|rescue.*exception/i,
2175
+ contextLines: 4,
2176
+ generate: (windowLines, windowStart, findingLine) => {
2177
+ const idx = findingLine - windowStart;
2178
+ if (idx < 0 || idx >= windowLines.length)
2179
+ return null;
2180
+ const line = windowLines[idx];
2181
+ const m = line.match(/^(\s*)rescue\s*$/);
2182
+ if (!m)
2183
+ return null;
2184
+ return {
2185
+ oldText: line,
2186
+ newText: `${m[1]}rescue StandardError => e # TODO: use specific exception class`,
2187
+ startLine: findingLine,
2188
+ endLine: findingLine,
2189
+ };
2190
+ },
2191
+ },
2192
+ // ── PHP: missing CSRF token in form → add hidden field ──
2193
+ {
2194
+ match: /csrf.*missing|cross.*site.*request|no.*csrf/i,
2195
+ contextLines: 5,
2196
+ generate: (windowLines, windowStart, findingLine) => {
2197
+ const idx = findingLine - windowStart;
2198
+ if (idx < 0 || idx >= windowLines.length)
2199
+ return null;
2200
+ const line = windowLines[idx];
2201
+ const m = line.match(/^(\s*)(<form\s[^>]*method=["']post["'][^>]*>)/i);
2202
+ if (!m)
2203
+ return null;
2204
+ const [, indent, formTag] = m;
2205
+ return {
2206
+ oldText: line,
2207
+ newText: `${indent}${formTag}\n${indent} <input type="hidden" name="csrf_token" value="<?= htmlspecialchars($csrfToken) ?>" />`,
2208
+ startLine: findingLine,
2209
+ endLine: findingLine,
2210
+ };
2211
+ },
2212
+ },
2213
+ // ── Kotlin: runOnUiThread with long operation → coroutine ──
2214
+ {
2215
+ match: /blocking.*main.*thread|ui.*thread.*block|network.*main/i,
2216
+ contextLines: 5,
2217
+ generate: (windowLines, windowStart, findingLine) => {
2218
+ const idx = findingLine - windowStart;
2219
+ if (idx < 0 || idx >= windowLines.length)
2220
+ return null;
2221
+ const line = windowLines[idx];
2222
+ const m = line.match(/^(\s*)runOnUiThread\s*\{/);
2223
+ if (!m)
2224
+ return null;
2225
+ return {
2226
+ oldText: line,
2227
+ newText: `${m[1]}lifecycleScope.launch(Dispatchers.IO) { // TODO: move I/O-bound work off main thread`,
2228
+ startLine: findingLine,
2229
+ endLine: findingLine,
2230
+ };
2231
+ },
2232
+ },
2233
+ // ── Swift: DispatchQueue.main.sync → async ──
2234
+ {
2235
+ match: /deadlock|main.*thread.*sync|dispatch.*main.*sync/i,
2236
+ contextLines: 3,
2237
+ generate: (windowLines, windowStart, findingLine) => {
2238
+ const idx = findingLine - windowStart;
2239
+ if (idx < 0 || idx >= windowLines.length)
2240
+ return null;
2241
+ const line = windowLines[idx];
2242
+ const m = line.match(/^(\s*)DispatchQueue\.main\.sync\b/);
2243
+ if (!m)
2244
+ return null;
2245
+ return {
2246
+ oldText: "DispatchQueue.main.sync",
2247
+ newText: "DispatchQueue.main.async",
2248
+ startLine: findingLine,
2249
+ endLine: findingLine,
2250
+ };
2251
+ },
2252
+ },
2253
+ // ── Terraform: missing logging/monitoring block ──
2254
+ {
2255
+ match: /missing.*logging|no.*monitoring|audit.*log.*disabled/i,
2256
+ contextLines: 5,
2257
+ generate: (windowLines, windowStart, findingLine) => {
2258
+ const idx = findingLine - windowStart;
2259
+ if (idx < 0 || idx >= windowLines.length)
2260
+ return null;
2261
+ const line = windowLines[idx];
2262
+ const m = line.match(/^(\s*)(resource\s+"[^"]+"\s+"[^"]+"\s*\{)/);
2263
+ if (!m)
2264
+ return null;
2265
+ const [, indent, resourceBlock] = m;
2266
+ return {
2267
+ oldText: line,
2268
+ newText: `${indent}${resourceBlock}\n${indent} # TODO: add logging/monitoring configuration\n${indent} # logging { enabled = true }`,
2269
+ startLine: findingLine,
2270
+ endLine: findingLine,
2271
+ };
2272
+ },
2273
+ },
2274
+ // ── v3.35.0 — Additional multi-line patches ──
2275
+ // ── Timing-safe comparison → crypto.timingSafeEqual ──
2276
+ {
2277
+ match: /timing.*attack|timing.*safe|constant.*time.*compar|non.*constant.*time/i,
2278
+ contextLines: 3,
2279
+ generate: (windowLines, windowStart, findingLine) => {
2280
+ const idx = findingLine - windowStart;
2281
+ if (idx < 0 || idx >= windowLines.length)
2282
+ return null;
2283
+ const line = windowLines[idx];
2284
+ const m = line.match(/^(\s*)(?:if\s*\(\s*)?([\w.]+)\s*===?\s*([\w.]+)/);
2285
+ if (!m)
2286
+ return null;
2287
+ const [, indent, left, right] = m;
2288
+ const oldText = line;
2289
+ const newText = [
2290
+ `${indent}// TODO: ensure crypto is imported: const crypto = require("crypto");`,
2291
+ `${indent}const _a = Buffer.from(String(${left}));`,
2292
+ `${indent}const _b = Buffer.from(String(${right}));`,
2293
+ `${indent}if (_a.length === _b.length && crypto.timingSafeEqual(_a, _b)) {`,
2294
+ ].join("\n");
2295
+ return { oldText, newText, startLine: findingLine, endLine: findingLine };
2296
+ },
2297
+ },
2298
+ // ── Path traversal → sanitize with path.resolve + prefix check ──
2299
+ {
2300
+ match: /path.*traversal|directory.*traversal|dot.*dot.*slash|\.\..*path/i,
2301
+ contextLines: 3,
2302
+ generate: (windowLines, windowStart, findingLine) => {
2303
+ const idx = findingLine - windowStart;
2304
+ if (idx < 0 || idx >= windowLines.length)
2305
+ return null;
2306
+ const line = windowLines[idx];
2307
+ const m = line.match(/^(\s*)((?:const|let|var)\s+(\w+)\s*=\s*path\.(?:join|resolve)\s*\([^)]*(?:req\.\w+|params|query|body)[^)]*\))\s*;?\s*$/);
2308
+ if (!m)
2309
+ return null;
2310
+ const [, indent, stmt, varName] = m;
2311
+ const oldText = line;
2312
+ const newText = [
2313
+ `${indent}const __baseDir = path.resolve("./safe-root"); // TODO: set allowed base directory`,
2314
+ `${indent}${stmt};`,
2315
+ `${indent}if (!path.resolve(${varName}).startsWith(__baseDir)) { throw new Error("Path traversal blocked"); }`,
2316
+ ].join("\n");
2317
+ return { oldText, newText, startLine: findingLine, endLine: findingLine };
2318
+ },
2319
+ },
2320
+ // ── Hardcoded secret/password → use environment variable ──
2321
+ {
2322
+ match: /hardcoded.*secret|hardcoded.*password|hardcoded.*key|embedded.*credential|hardcoded.*token/i,
2323
+ contextLines: 2,
2324
+ generate: (windowLines, windowStart, findingLine) => {
2325
+ const idx = findingLine - windowStart;
2326
+ if (idx < 0 || idx >= windowLines.length)
2327
+ return null;
2328
+ const line = windowLines[idx];
2329
+ const m = line.match(/^(\s*)(const|let|var)\s+(\w*(?:secret|password|key|token|apiKey|api_key)\w*)\s*=\s*["'`]([^"'`]+)["'`]\s*;?\s*$/i);
2330
+ if (!m)
2331
+ return null;
2332
+ const [, indent, decl, varName] = m;
2333
+ const envName = varName.replace(/([a-z])([A-Z])/g, "$1_$2").toUpperCase();
2334
+ const oldText = line;
2335
+ const newText = `${indent}${decl} ${varName} = process.env.${envName}; // TODO: set ${envName} in environment`;
2336
+ return { oldText, newText, startLine: findingLine, endLine: findingLine };
2337
+ },
2338
+ },
2339
+ // ── Open redirect → validate redirect URL ──
2340
+ {
2341
+ match: /open.*redirect|unvalidated.*redirect|url.*redirect.*uncheck/i,
2342
+ contextLines: 3,
2343
+ generate: (windowLines, windowStart, findingLine) => {
2344
+ const idx = findingLine - windowStart;
2345
+ if (idx < 0 || idx >= windowLines.length)
2346
+ return null;
2347
+ const line = windowLines[idx];
2348
+ const m = line.match(/^(\s*)(?:res\.redirect|return\s+res\.redirect)\s*\(\s*(req\.(?:query|params|body)\.\w+|[\w]+)\s*\)/);
2349
+ if (!m)
2350
+ return null;
2351
+ const [, indent, urlExpr] = m;
2352
+ const oldText = line;
2353
+ const newText = [
2354
+ `${indent}const __redirectUrl = new URL(${urlExpr}, req.protocol + "://" + req.get("host"));`,
2355
+ `${indent}if (__redirectUrl.origin !== req.protocol + "://" + req.get("host")) { return res.status(400).send("Invalid redirect"); }`,
2356
+ `${indent}res.redirect(__redirectUrl.pathname);`,
2357
+ ].join("\n");
2358
+ return { oldText, newText, startLine: findingLine, endLine: findingLine };
2359
+ },
2360
+ },
2361
+ // ── SSRF → validate URL before HTTP request ──
2362
+ {
2363
+ match: /ssrf|server.*side.*request.*forgery|unvalidated.*url.*fetch/i,
2364
+ contextLines: 3,
2365
+ generate: (windowLines, windowStart, findingLine) => {
2366
+ const idx = findingLine - windowStart;
2367
+ if (idx < 0 || idx >= windowLines.length)
2368
+ return null;
2369
+ const line = windowLines[idx];
2370
+ const m = line.match(/^(\s*)((?:const|let|var)\s+\w+\s*=\s*)?(?:await\s+)?(?:fetch|axios\.(?:get|post|put|delete)|got|request)\s*\(\s*([\w.]+)\s*/);
2371
+ if (!m)
2372
+ return null;
2373
+ const [, indent, , urlVar] = m;
2374
+ const oldText = line;
2375
+ const newText = [
2376
+ `${indent}// TODO: validate URL against allowlist to prevent SSRF`,
2377
+ `${indent}const __parsedUrl = new URL(${urlVar});`,
2378
+ `${indent}const __allowedHosts = (process.env.ALLOWED_HOSTS || "").split(",");`,
2379
+ `${indent}if (!__allowedHosts.includes(__parsedUrl.hostname)) { throw new Error("Blocked: host not in allowlist"); }`,
2380
+ `${indent}${line.trim()}`,
2381
+ ].join("\n");
2382
+ return { oldText, newText, startLine: findingLine, endLine: findingLine };
2383
+ },
2384
+ },
2385
+ // ── Insecure cookie → add secure flags ──
2386
+ {
2387
+ match: /insecure.*cookie|cookie.*secure.*flag|cookie.*httponly|session.*cookie.*flag/i,
2388
+ contextLines: 4,
2389
+ generate: (windowLines, windowStart, findingLine) => {
2390
+ const idx = findingLine - windowStart;
2391
+ if (idx < 0 || idx >= windowLines.length)
2392
+ return null;
2393
+ const line = windowLines[idx];
2394
+ const m = line.match(/^(\s*)res\.cookie\s*\(\s*["'](\w+)["']\s*,\s*(\S+)\s*\)\s*;?\s*$/);
2395
+ if (!m)
2396
+ return null;
2397
+ const [, indent, name, value] = m;
2398
+ const oldText = line;
2399
+ const newText = `${indent}res.cookie("${name}", ${value}, { httpOnly: true, secure: true, sameSite: "strict" });`;
2400
+ return { oldText, newText, startLine: findingLine, endLine: findingLine };
2401
+ },
2402
+ },
2403
+ // ── Java SQL injection → PreparedStatement ──
2404
+ {
2405
+ match: /sql.*inject|sql.*concatenat|jdbc.*inject/i,
2406
+ contextLines: 4,
2407
+ generate: (windowLines, windowStart, findingLine) => {
2408
+ const idx = findingLine - windowStart;
2409
+ if (idx < 0 || idx >= windowLines.length)
2410
+ return null;
2411
+ const line = windowLines[idx];
2412
+ const m = line.match(/^(\s*)(Statement\s+\w+\s*=\s*\w+\.createStatement\s*\(\s*\))\s*;?\s*$/);
2413
+ if (!m)
2414
+ return null;
2415
+ const [, indent] = m;
2416
+ // Look for executeQuery with concatenation on subsequent lines
2417
+ for (let j = idx + 1; j < Math.min(idx + 4, windowLines.length); j++) {
2418
+ const next = windowLines[j];
2419
+ const qm = next.match(/^(\s*)\w+\.executeQuery\s*\(\s*"([^"]+)"\s*\+\s*(\w+)/);
2420
+ if (!qm)
2421
+ continue;
2422
+ const [, , sql, param] = qm;
2423
+ const oldText = windowLines.slice(idx, j + 1).join("\n");
2424
+ const newText = [
2425
+ `${indent}PreparedStatement pstmt = conn.prepareStatement("${sql}?");`,
2426
+ `${indent}pstmt.setString(1, ${param});`,
2427
+ `${indent}ResultSet rs = pstmt.executeQuery();`,
2428
+ ].join("\n");
2429
+ return { oldText, newText, startLine: findingLine, endLine: windowStart + j };
2430
+ }
2431
+ return null;
2432
+ },
2433
+ },
2434
+ // ── Python f-string/format SQL → parameterized query ──
2435
+ {
2436
+ match: /sql.*inject|python.*sql.*format|f.*string.*sql/i,
2437
+ contextLines: 3,
2438
+ generate: (windowLines, windowStart, findingLine) => {
2439
+ const idx = findingLine - windowStart;
2440
+ if (idx < 0 || idx >= windowLines.length)
2441
+ return null;
2442
+ const line = windowLines[idx];
2443
+ const m = line.match(/^(\s*)(\w+)\.execute\s*\(\s*f["']([^"']*)\{(\w+)\}([^"']*)["']\s*\)/);
2444
+ if (!m)
2445
+ return null;
2446
+ const [, indent, cursor, sqlBefore, param, sqlAfter] = m;
2447
+ const oldText = line;
2448
+ const newText = `${indent}${cursor}.execute("${sqlBefore}%s${sqlAfter}", (${param},))`;
2449
+ return { oldText, newText, startLine: findingLine, endLine: findingLine };
2450
+ },
2451
+ },
2452
+ // ── Missing Content-Security-Policy header → add CSP ──
2453
+ {
2454
+ match: /content.*security.*policy|missing.*csp|csp.*header/i,
2455
+ contextLines: 5,
2456
+ generate: (windowLines, windowStart, findingLine) => {
2457
+ const idx = findingLine - windowStart;
2458
+ if (idx < 0 || idx >= windowLines.length)
2459
+ return null;
2460
+ const line = windowLines[idx];
2461
+ const m = line.match(/^(\s*)(const\s+app\s*=\s*express\s*\(\s*\)\s*;?\s*)$/);
2462
+ if (!m)
2463
+ return null;
2464
+ const [, indent, appInit] = m;
2465
+ const oldText = line;
2466
+ const newText = [
2467
+ `${indent}${appInit}`,
2468
+ `${indent}app.use((_req, res, next) => {`,
2469
+ `${indent} res.setHeader("Content-Security-Policy", "default-src 'self'"); // TODO: adjust CSP policy`,
2470
+ `${indent} next();`,
2471
+ `${indent}});`,
2472
+ ].join("\n");
2473
+ return { oldText, newText, startLine: findingLine, endLine: findingLine };
2474
+ },
2475
+ },
2476
+ // ── C# SQL injection → SqlParameter ──
2477
+ {
2478
+ match: /sql.*inject|csharp.*sql|ado.*net.*inject/i,
2479
+ contextLines: 3,
2480
+ generate: (windowLines, windowStart, findingLine) => {
2481
+ const idx = findingLine - windowStart;
2482
+ if (idx < 0 || idx >= windowLines.length)
2483
+ return null;
2484
+ const line = windowLines[idx];
2485
+ const m = line.match(/^(\s*)(?:var|string)\s+\w+\s*=\s*\$?"[^"]*"\s*\+\s*(\w+)\s*;/);
2486
+ if (!m)
2487
+ return null;
2488
+ // Look for SqlCommand nearby
2489
+ const window = windowLines.join("\n");
2490
+ if (!/SqlCommand|ExecuteReader|ExecuteNonQuery/.test(window))
2491
+ return null;
2492
+ const [, indent, param] = m;
2493
+ const oldText = line;
2494
+ const newText = [
2495
+ `${indent}// TODO: use parameterized queries instead of string concatenation`,
2496
+ `${indent}cmd.Parameters.AddWithValue("@param", ${param});`,
2497
+ ].join("\n");
2498
+ return { oldText, newText, startLine: findingLine, endLine: findingLine };
2499
+ },
2500
+ },
2501
+ ];
2502
+ export function enrichWithPatches(findings, code) {
2503
+ const lines = code.split("\n");
2504
+ return findings.map((f) => {
2505
+ // Skip if patch already present or no line numbers
2506
+ if (f.patch || !f.lineNumbers || f.lineNumbers.length === 0)
2507
+ return f;
2508
+ // 1. Try single-line rules first
2509
+ for (const rule of PATCH_RULES) {
2510
+ if (!rule.match.test(f.title) && !rule.match.test(f.ruleId))
2511
+ continue;
2512
+ // Try the first affected line
2513
+ const lineIdx = f.lineNumbers[0] - 1;
2514
+ if (lineIdx < 0 || lineIdx >= lines.length)
2515
+ continue;
2516
+ const result = rule.generate(lines[lineIdx]);
2517
+ if (result) {
2518
+ return {
2519
+ ...f,
2520
+ patch: {
2521
+ oldText: result.oldText,
2522
+ newText: result.newText,
2523
+ startLine: f.lineNumbers[0],
2524
+ endLine: f.lineNumbers[0],
2525
+ },
2526
+ };
2527
+ }
2528
+ }
2529
+ // 2. Try multi-line rules
2530
+ for (const rule of MULTI_LINE_PATCH_RULES) {
2531
+ if (!rule.match.test(f.title) && !rule.match.test(f.ruleId))
2532
+ continue;
2533
+ const findingLine = f.lineNumbers[0];
2534
+ const windowStart = Math.max(1, findingLine - rule.contextLines);
2535
+ const windowEnd = Math.min(lines.length, findingLine + rule.contextLines);
2536
+ const windowLines = lines.slice(windowStart - 1, windowEnd);
2537
+ const result = rule.generate(windowLines, windowStart, findingLine);
2538
+ if (result) {
2539
+ return { ...f, patch: result };
2540
+ }
2541
+ }
2542
+ return f;
2543
+ });
2544
+ }