circle-ir-ai 1.1.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 (420) hide show
  1. package/CHANGELOG.md +105 -0
  2. package/LICENSE +15 -0
  3. package/README.md +336 -0
  4. package/dist/action-queue/aggregator.d.ts +40 -0
  5. package/dist/action-queue/aggregator.d.ts.map +1 -0
  6. package/dist/action-queue/aggregator.js +375 -0
  7. package/dist/action-queue/aggregator.js.map +1 -0
  8. package/dist/action-queue/index.d.ts +14 -0
  9. package/dist/action-queue/index.d.ts.map +1 -0
  10. package/dist/action-queue/index.js +17 -0
  11. package/dist/action-queue/index.js.map +1 -0
  12. package/dist/action-queue/queue.d.ts +74 -0
  13. package/dist/action-queue/queue.d.ts.map +1 -0
  14. package/dist/action-queue/queue.js +433 -0
  15. package/dist/action-queue/queue.js.map +1 -0
  16. package/dist/action-queue/types.d.ts +162 -0
  17. package/dist/action-queue/types.d.ts.map +1 -0
  18. package/dist/action-queue/types.js +44 -0
  19. package/dist/action-queue/types.js.map +1 -0
  20. package/dist/agents/enrichment-agent.d.ts +16 -0
  21. package/dist/agents/enrichment-agent.d.ts.map +1 -0
  22. package/dist/agents/enrichment-agent.js +102 -0
  23. package/dist/agents/enrichment-agent.js.map +1 -0
  24. package/dist/agents/index.d.ts +12 -0
  25. package/dist/agents/index.d.ts.map +1 -0
  26. package/dist/agents/index.js +15 -0
  27. package/dist/agents/index.js.map +1 -0
  28. package/dist/agents/mastra/agents.d.ts +373 -0
  29. package/dist/agents/mastra/agents.d.ts.map +1 -0
  30. package/dist/agents/mastra/agents.js +347 -0
  31. package/dist/agents/mastra/agents.js.map +1 -0
  32. package/dist/agents/mastra/index.d.ts +12 -0
  33. package/dist/agents/mastra/index.d.ts.map +1 -0
  34. package/dist/agents/mastra/index.js +17 -0
  35. package/dist/agents/mastra/index.js.map +1 -0
  36. package/dist/agents/mastra/instance.d.ts +383 -0
  37. package/dist/agents/mastra/instance.d.ts.map +1 -0
  38. package/dist/agents/mastra/instance.js +37 -0
  39. package/dist/agents/mastra/instance.js.map +1 -0
  40. package/dist/agents/mastra/steps.d.ts +300 -0
  41. package/dist/agents/mastra/steps.d.ts.map +1 -0
  42. package/dist/agents/mastra/steps.js +468 -0
  43. package/dist/agents/mastra/steps.js.map +1 -0
  44. package/dist/agents/mastra/swarm.d.ts +106 -0
  45. package/dist/agents/mastra/swarm.d.ts.map +1 -0
  46. package/dist/agents/mastra/swarm.js +501 -0
  47. package/dist/agents/mastra/swarm.js.map +1 -0
  48. package/dist/agents/mastra/workflow.d.ts +81 -0
  49. package/dist/agents/mastra/workflow.d.ts.map +1 -0
  50. package/dist/agents/mastra/workflow.js +460 -0
  51. package/dist/agents/mastra/workflow.js.map +1 -0
  52. package/dist/agents/multi/agents/security.d.ts +29 -0
  53. package/dist/agents/multi/agents/security.d.ts.map +1 -0
  54. package/dist/agents/multi/agents/security.js +830 -0
  55. package/dist/agents/multi/agents/security.js.map +1 -0
  56. package/dist/agents/multi/extractor.d.ts +21 -0
  57. package/dist/agents/multi/extractor.d.ts.map +1 -0
  58. package/dist/agents/multi/extractor.js +483 -0
  59. package/dist/agents/multi/extractor.js.map +1 -0
  60. package/dist/agents/multi/index.d.ts +32 -0
  61. package/dist/agents/multi/index.d.ts.map +1 -0
  62. package/dist/agents/multi/index.js +34 -0
  63. package/dist/agents/multi/index.js.map +1 -0
  64. package/dist/agents/multi/runner.d.ts +79 -0
  65. package/dist/agents/multi/runner.d.ts.map +1 -0
  66. package/dist/agents/multi/runner.js +323 -0
  67. package/dist/agents/multi/runner.js.map +1 -0
  68. package/dist/agents/security-agent.d.ts +16 -0
  69. package/dist/agents/security-agent.d.ts.map +1 -0
  70. package/dist/agents/security-agent.js +299 -0
  71. package/dist/agents/security-agent.js.map +1 -0
  72. package/dist/agents/types.d.ts +373 -0
  73. package/dist/agents/types.d.ts.map +1 -0
  74. package/dist/agents/types.js +14 -0
  75. package/dist/agents/types.js.map +1 -0
  76. package/dist/agents/verification-agent.d.ts +23 -0
  77. package/dist/agents/verification-agent.d.ts.map +1 -0
  78. package/dist/agents/verification-agent.js +217 -0
  79. package/dist/agents/verification-agent.js.map +1 -0
  80. package/dist/agents/workflow.d.ts +30 -0
  81. package/dist/agents/workflow.d.ts.map +1 -0
  82. package/dist/agents/workflow.js +79 -0
  83. package/dist/agents/workflow.js.map +1 -0
  84. package/dist/analysis/enriched.d.ts +16 -0
  85. package/dist/analysis/enriched.d.ts.map +1 -0
  86. package/dist/analysis/enriched.js +297 -0
  87. package/dist/analysis/enriched.js.map +1 -0
  88. package/dist/analysis/llm-correlated-predicates.d.ts +80 -0
  89. package/dist/analysis/llm-correlated-predicates.d.ts.map +1 -0
  90. package/dist/analysis/llm-correlated-predicates.js +255 -0
  91. package/dist/analysis/llm-correlated-predicates.js.map +1 -0
  92. package/dist/analysis/llm-cross-file-taint.d.ts +86 -0
  93. package/dist/analysis/llm-cross-file-taint.d.ts.map +1 -0
  94. package/dist/analysis/llm-cross-file-taint.js +264 -0
  95. package/dist/analysis/llm-cross-file-taint.js.map +1 -0
  96. package/dist/analysis/pattern-discovery.d.ts +79 -0
  97. package/dist/analysis/pattern-discovery.d.ts.map +1 -0
  98. package/dist/analysis/pattern-discovery.js +447 -0
  99. package/dist/analysis/pattern-discovery.js.map +1 -0
  100. package/dist/cache/file-cache.d.ts +89 -0
  101. package/dist/cache/file-cache.d.ts.map +1 -0
  102. package/dist/cache/file-cache.js +208 -0
  103. package/dist/cache/file-cache.js.map +1 -0
  104. package/dist/cache/index.d.ts +6 -0
  105. package/dist/cache/index.d.ts.map +1 -0
  106. package/dist/cache/index.js +5 -0
  107. package/dist/cache/index.js.map +1 -0
  108. package/dist/cli/args.d.ts +52 -0
  109. package/dist/cli/args.d.ts.map +1 -0
  110. package/dist/cli/args.js +422 -0
  111. package/dist/cli/args.js.map +1 -0
  112. package/dist/cli/colors.d.ts +31 -0
  113. package/dist/cli/colors.d.ts.map +1 -0
  114. package/dist/cli/colors.js +80 -0
  115. package/dist/cli/colors.js.map +1 -0
  116. package/dist/cli/commands/analyze-skill.d.ts +33 -0
  117. package/dist/cli/commands/analyze-skill.d.ts.map +1 -0
  118. package/dist/cli/commands/analyze-skill.js +217 -0
  119. package/dist/cli/commands/analyze-skill.js.map +1 -0
  120. package/dist/cli/commands/analyze.d.ts +18 -0
  121. package/dist/cli/commands/analyze.d.ts.map +1 -0
  122. package/dist/cli/commands/analyze.js +30 -0
  123. package/dist/cli/commands/analyze.js.map +1 -0
  124. package/dist/cli/commands/benchmark-runner.d.ts +42 -0
  125. package/dist/cli/commands/benchmark-runner.d.ts.map +1 -0
  126. package/dist/cli/commands/benchmark-runner.js +18 -0
  127. package/dist/cli/commands/benchmark-runner.js.map +1 -0
  128. package/dist/cli/commands/benchmark.d.ts +11 -0
  129. package/dist/cli/commands/benchmark.d.ts.map +1 -0
  130. package/dist/cli/commands/benchmark.js +90 -0
  131. package/dist/cli/commands/benchmark.js.map +1 -0
  132. package/dist/cli/commands/dead-code.d.ts +11 -0
  133. package/dist/cli/commands/dead-code.d.ts.map +1 -0
  134. package/dist/cli/commands/dead-code.js +65 -0
  135. package/dist/cli/commands/dead-code.js.map +1 -0
  136. package/dist/cli/commands/generate-spec.d.ts +11 -0
  137. package/dist/cli/commands/generate-spec.d.ts.map +1 -0
  138. package/dist/cli/commands/generate-spec.js +67 -0
  139. package/dist/cli/commands/generate-spec.js.map +1 -0
  140. package/dist/cli/commands/health.d.ts +11 -0
  141. package/dist/cli/commands/health.d.ts.map +1 -0
  142. package/dist/cli/commands/health.js +67 -0
  143. package/dist/cli/commands/health.js.map +1 -0
  144. package/dist/cli/commands/project.d.ts +21 -0
  145. package/dist/cli/commands/project.d.ts.map +1 -0
  146. package/dist/cli/commands/project.js +92 -0
  147. package/dist/cli/commands/project.js.map +1 -0
  148. package/dist/cli/commands/scan.d.ts +11 -0
  149. package/dist/cli/commands/scan.d.ts.map +1 -0
  150. package/dist/cli/commands/scan.js +68 -0
  151. package/dist/cli/commands/scan.js.map +1 -0
  152. package/dist/cli/commands/secrets.d.ts +11 -0
  153. package/dist/cli/commands/secrets.d.ts.map +1 -0
  154. package/dist/cli/commands/secrets.js +71 -0
  155. package/dist/cli/commands/secrets.js.map +1 -0
  156. package/dist/cli/commands/swarm.d.ts +20 -0
  157. package/dist/cli/commands/swarm.d.ts.map +1 -0
  158. package/dist/cli/commands/swarm.js +174 -0
  159. package/dist/cli/commands/swarm.js.map +1 -0
  160. package/dist/cli/config.d.ts +103 -0
  161. package/dist/cli/config.d.ts.map +1 -0
  162. package/dist/cli/config.js +307 -0
  163. package/dist/cli/config.js.map +1 -0
  164. package/dist/cli/discovery.d.ts +31 -0
  165. package/dist/cli/discovery.d.ts.map +1 -0
  166. package/dist/cli/discovery.js +212 -0
  167. package/dist/cli/discovery.js.map +1 -0
  168. package/dist/cli/formatters/index.d.ts +15 -0
  169. package/dist/cli/formatters/index.d.ts.map +1 -0
  170. package/dist/cli/formatters/index.js +51 -0
  171. package/dist/cli/formatters/index.js.map +1 -0
  172. package/dist/cli/formatters/json.d.ts +11 -0
  173. package/dist/cli/formatters/json.d.ts.map +1 -0
  174. package/dist/cli/formatters/json.js +12 -0
  175. package/dist/cli/formatters/json.js.map +1 -0
  176. package/dist/cli/formatters/project-json.d.ts +11 -0
  177. package/dist/cli/formatters/project-json.d.ts.map +1 -0
  178. package/dist/cli/formatters/project-json.js +12 -0
  179. package/dist/cli/formatters/project-json.js.map +1 -0
  180. package/dist/cli/formatters/project-sarif.d.ts +11 -0
  181. package/dist/cli/formatters/project-sarif.d.ts.map +1 -0
  182. package/dist/cli/formatters/project-sarif.js +127 -0
  183. package/dist/cli/formatters/project-sarif.js.map +1 -0
  184. package/dist/cli/formatters/project-summary.d.ts +11 -0
  185. package/dist/cli/formatters/project-summary.d.ts.map +1 -0
  186. package/dist/cli/formatters/project-summary.js +202 -0
  187. package/dist/cli/formatters/project-summary.js.map +1 -0
  188. package/dist/cli/formatters/sarif-shared.d.ts +101 -0
  189. package/dist/cli/formatters/sarif-shared.d.ts.map +1 -0
  190. package/dist/cli/formatters/sarif-shared.js +57 -0
  191. package/dist/cli/formatters/sarif-shared.js.map +1 -0
  192. package/dist/cli/formatters/sarif.d.ts +12 -0
  193. package/dist/cli/formatters/sarif.d.ts.map +1 -0
  194. package/dist/cli/formatters/sarif.js +92 -0
  195. package/dist/cli/formatters/sarif.js.map +1 -0
  196. package/dist/cli/formatters/summary.d.ts +11 -0
  197. package/dist/cli/formatters/summary.d.ts.map +1 -0
  198. package/dist/cli/formatters/summary.js +240 -0
  199. package/dist/cli/formatters/summary.js.map +1 -0
  200. package/dist/cli/formatters/two-phase-summary.d.ts +11 -0
  201. package/dist/cli/formatters/two-phase-summary.d.ts.map +1 -0
  202. package/dist/cli/formatters/two-phase-summary.js +188 -0
  203. package/dist/cli/formatters/two-phase-summary.js.map +1 -0
  204. package/dist/cli/index.d.ts +15 -0
  205. package/dist/cli/index.d.ts.map +1 -0
  206. package/dist/cli/index.js +555 -0
  207. package/dist/cli/index.js.map +1 -0
  208. package/dist/components/clustering.d.ts +60 -0
  209. package/dist/components/clustering.d.ts.map +1 -0
  210. package/dist/components/clustering.js +129 -0
  211. package/dist/components/clustering.js.map +1 -0
  212. package/dist/components/enrichment.d.ts +45 -0
  213. package/dist/components/enrichment.d.ts.map +1 -0
  214. package/dist/components/enrichment.js +193 -0
  215. package/dist/components/enrichment.js.map +1 -0
  216. package/dist/components/index.d.ts +29 -0
  217. package/dist/components/index.d.ts.map +1 -0
  218. package/dist/components/index.js +56 -0
  219. package/dist/components/index.js.map +1 -0
  220. package/dist/dead-code/detector.d.ts +200 -0
  221. package/dist/dead-code/detector.d.ts.map +1 -0
  222. package/dist/dead-code/detector.js +1003 -0
  223. package/dist/dead-code/detector.js.map +1 -0
  224. package/dist/dead-code/index.d.ts +7 -0
  225. package/dist/dead-code/index.d.ts.map +1 -0
  226. package/dist/dead-code/index.js +7 -0
  227. package/dist/dead-code/index.js.map +1 -0
  228. package/dist/extractors/index.d.ts +15 -0
  229. package/dist/extractors/index.d.ts.map +1 -0
  230. package/dist/extractors/index.js +14 -0
  231. package/dist/extractors/index.js.map +1 -0
  232. package/dist/extractors/natural-language.d.ts +46 -0
  233. package/dist/extractors/natural-language.d.ts.map +1 -0
  234. package/dist/extractors/natural-language.js +228 -0
  235. package/dist/extractors/natural-language.js.map +1 -0
  236. package/dist/extractors/tree-sitter.d.ts +33 -0
  237. package/dist/extractors/tree-sitter.d.ts.map +1 -0
  238. package/dist/extractors/tree-sitter.js +69 -0
  239. package/dist/extractors/tree-sitter.js.map +1 -0
  240. package/dist/extractors/types.d.ts +62 -0
  241. package/dist/extractors/types.d.ts.map +1 -0
  242. package/dist/extractors/types.js +54 -0
  243. package/dist/extractors/types.js.map +1 -0
  244. package/dist/health-score/calculator.d.ts +123 -0
  245. package/dist/health-score/calculator.d.ts.map +1 -0
  246. package/dist/health-score/calculator.js +444 -0
  247. package/dist/health-score/calculator.js.map +1 -0
  248. package/dist/health-score/index.d.ts +12 -0
  249. package/dist/health-score/index.d.ts.map +1 -0
  250. package/dist/health-score/index.js +14 -0
  251. package/dist/health-score/index.js.map +1 -0
  252. package/dist/health-score/metrics.d.ts +142 -0
  253. package/dist/health-score/metrics.d.ts.map +1 -0
  254. package/dist/health-score/metrics.js +332 -0
  255. package/dist/health-score/metrics.js.map +1 -0
  256. package/dist/index.d.ts +26 -0
  257. package/dist/index.d.ts.map +1 -0
  258. package/dist/index.js +43 -0
  259. package/dist/index.js.map +1 -0
  260. package/dist/llm/ax-client.d.ts +477 -0
  261. package/dist/llm/ax-client.d.ts.map +1 -0
  262. package/dist/llm/ax-client.js +1641 -0
  263. package/dist/llm/ax-client.js.map +1 -0
  264. package/dist/llm/config.d.ts +58 -0
  265. package/dist/llm/config.d.ts.map +1 -0
  266. package/dist/llm/config.js +97 -0
  267. package/dist/llm/config.js.map +1 -0
  268. package/dist/llm/discovery.d.ts +123 -0
  269. package/dist/llm/discovery.d.ts.map +1 -0
  270. package/dist/llm/discovery.js +505 -0
  271. package/dist/llm/discovery.js.map +1 -0
  272. package/dist/llm/enrichment.d.ts +108 -0
  273. package/dist/llm/enrichment.d.ts.map +1 -0
  274. package/dist/llm/enrichment.js +312 -0
  275. package/dist/llm/enrichment.js.map +1 -0
  276. package/dist/llm/index.d.ts +13 -0
  277. package/dist/llm/index.d.ts.map +1 -0
  278. package/dist/llm/index.js +22 -0
  279. package/dist/llm/index.js.map +1 -0
  280. package/dist/llm/language-context.d.ts +64 -0
  281. package/dist/llm/language-context.d.ts.map +1 -0
  282. package/dist/llm/language-context.js +492 -0
  283. package/dist/llm/language-context.js.map +1 -0
  284. package/dist/llm/pattern-verification.d.ts +39 -0
  285. package/dist/llm/pattern-verification.d.ts.map +1 -0
  286. package/dist/llm/pattern-verification.js +127 -0
  287. package/dist/llm/pattern-verification.js.map +1 -0
  288. package/dist/llm/prompt-security.d.ts +120 -0
  289. package/dist/llm/prompt-security.d.ts.map +1 -0
  290. package/dist/llm/prompt-security.js +301 -0
  291. package/dist/llm/prompt-security.js.map +1 -0
  292. package/dist/llm/prompts/index.d.ts +31 -0
  293. package/dist/llm/prompts/index.d.ts.map +1 -0
  294. package/dist/llm/prompts/index.js +92 -0
  295. package/dist/llm/prompts/index.js.map +1 -0
  296. package/dist/llm/prompts/rust.d.ts +30 -0
  297. package/dist/llm/prompts/rust.d.ts.map +1 -0
  298. package/dist/llm/prompts/rust.js +121 -0
  299. package/dist/llm/prompts/rust.js.map +1 -0
  300. package/dist/llm/schemas.d.ts +892 -0
  301. package/dist/llm/schemas.d.ts.map +1 -0
  302. package/dist/llm/schemas.js +258 -0
  303. package/dist/llm/schemas.js.map +1 -0
  304. package/dist/llm/verification.d.ts +127 -0
  305. package/dist/llm/verification.d.ts.map +1 -0
  306. package/dist/llm/verification.js +394 -0
  307. package/dist/llm/verification.js.map +1 -0
  308. package/dist/project/analyzer.d.ts +30 -0
  309. package/dist/project/analyzer.d.ts.map +1 -0
  310. package/dist/project/analyzer.js +358 -0
  311. package/dist/project/analyzer.js.map +1 -0
  312. package/dist/project/call-graph.d.ts +22 -0
  313. package/dist/project/call-graph.d.ts.map +1 -0
  314. package/dist/project/call-graph.js +246 -0
  315. package/dist/project/call-graph.js.map +1 -0
  316. package/dist/project/index.d.ts +18 -0
  317. package/dist/project/index.d.ts.map +1 -0
  318. package/dist/project/index.js +20 -0
  319. package/dist/project/index.js.map +1 -0
  320. package/dist/project/taint-paths.d.ts +22 -0
  321. package/dist/project/taint-paths.d.ts.map +1 -0
  322. package/dist/project/taint-paths.js +265 -0
  323. package/dist/project/taint-paths.js.map +1 -0
  324. package/dist/project/two-phase-analyzer.d.ts +143 -0
  325. package/dist/project/two-phase-analyzer.d.ts.map +1 -0
  326. package/dist/project/two-phase-analyzer.js +646 -0
  327. package/dist/project/two-phase-analyzer.js.map +1 -0
  328. package/dist/project/type-hierarchy.d.ts +28 -0
  329. package/dist/project/type-hierarchy.d.ts.map +1 -0
  330. package/dist/project/type-hierarchy.js +218 -0
  331. package/dist/project/type-hierarchy.js.map +1 -0
  332. package/dist/secret-scan/index.d.ts +12 -0
  333. package/dist/secret-scan/index.d.ts.map +1 -0
  334. package/dist/secret-scan/index.js +14 -0
  335. package/dist/secret-scan/index.js.map +1 -0
  336. package/dist/secret-scan/patterns.d.ts +38 -0
  337. package/dist/secret-scan/patterns.d.ts.map +1 -0
  338. package/dist/secret-scan/patterns.js +473 -0
  339. package/dist/secret-scan/patterns.js.map +1 -0
  340. package/dist/secret-scan/scanner.d.ts +162 -0
  341. package/dist/secret-scan/scanner.d.ts.map +1 -0
  342. package/dist/secret-scan/scanner.js +511 -0
  343. package/dist/secret-scan/scanner.js.map +1 -0
  344. package/dist/security-scan/index.d.ts +12 -0
  345. package/dist/security-scan/index.d.ts.map +1 -0
  346. package/dist/security-scan/index.js +15 -0
  347. package/dist/security-scan/index.js.map +1 -0
  348. package/dist/security-scan/owasp-mapping.d.ts +29 -0
  349. package/dist/security-scan/owasp-mapping.d.ts.map +1 -0
  350. package/dist/security-scan/owasp-mapping.js +246 -0
  351. package/dist/security-scan/owasp-mapping.js.map +1 -0
  352. package/dist/security-scan/scanner.d.ts +204 -0
  353. package/dist/security-scan/scanner.d.ts.map +1 -0
  354. package/dist/security-scan/scanner.js +693 -0
  355. package/dist/security-scan/scanner.js.map +1 -0
  356. package/dist/security-scan/trend-tracker.d.ts +150 -0
  357. package/dist/security-scan/trend-tracker.d.ts.map +1 -0
  358. package/dist/security-scan/trend-tracker.js +299 -0
  359. package/dist/security-scan/trend-tracker.js.map +1 -0
  360. package/dist/skills/bundle-loader.d.ts +26 -0
  361. package/dist/skills/bundle-loader.d.ts.map +1 -0
  362. package/dist/skills/bundle-loader.js +284 -0
  363. package/dist/skills/bundle-loader.js.map +1 -0
  364. package/dist/skills/capability-mismatch.d.ts +21 -0
  365. package/dist/skills/capability-mismatch.d.ts.map +1 -0
  366. package/dist/skills/capability-mismatch.js +188 -0
  367. package/dist/skills/capability-mismatch.js.map +1 -0
  368. package/dist/skills/index.d.ts +10 -0
  369. package/dist/skills/index.d.ts.map +1 -0
  370. package/dist/skills/index.js +9 -0
  371. package/dist/skills/index.js.map +1 -0
  372. package/dist/skills/skill-analyzer.d.ts +16 -0
  373. package/dist/skills/skill-analyzer.d.ts.map +1 -0
  374. package/dist/skills/skill-analyzer.js +361 -0
  375. package/dist/skills/skill-analyzer.js.map +1 -0
  376. package/dist/skills/types.d.ts +195 -0
  377. package/dist/skills/types.d.ts.map +1 -0
  378. package/dist/skills/types.js +7 -0
  379. package/dist/skills/types.js.map +1 -0
  380. package/dist/specifica/conflict-resolver.d.ts +23 -0
  381. package/dist/specifica/conflict-resolver.d.ts.map +1 -0
  382. package/dist/specifica/conflict-resolver.js +129 -0
  383. package/dist/specifica/conflict-resolver.js.map +1 -0
  384. package/dist/specifica/evidence-aggregator.d.ts +33 -0
  385. package/dist/specifica/evidence-aggregator.d.ts.map +1 -0
  386. package/dist/specifica/evidence-aggregator.js +236 -0
  387. package/dist/specifica/evidence-aggregator.js.map +1 -0
  388. package/dist/specifica/evidence-extractor.d.ts +13 -0
  389. package/dist/specifica/evidence-extractor.d.ts.map +1 -0
  390. package/dist/specifica/evidence-extractor.js +431 -0
  391. package/dist/specifica/evidence-extractor.js.map +1 -0
  392. package/dist/specifica/feature-clustering.d.ts +19 -0
  393. package/dist/specifica/feature-clustering.d.ts.map +1 -0
  394. package/dist/specifica/feature-clustering.js +231 -0
  395. package/dist/specifica/feature-clustering.js.map +1 -0
  396. package/dist/specifica/generator.d.ts +16 -0
  397. package/dist/specifica/generator.d.ts.map +1 -0
  398. package/dist/specifica/generator.js +277 -0
  399. package/dist/specifica/generator.js.map +1 -0
  400. package/dist/specifica/index.d.ts +15 -0
  401. package/dist/specifica/index.d.ts.map +1 -0
  402. package/dist/specifica/index.js +18 -0
  403. package/dist/specifica/index.js.map +1 -0
  404. package/dist/specifica/prompts.d.ts +21 -0
  405. package/dist/specifica/prompts.d.ts.map +1 -0
  406. package/dist/specifica/prompts.js +196 -0
  407. package/dist/specifica/prompts.js.map +1 -0
  408. package/dist/specifica/spec-generator.d.ts +22 -0
  409. package/dist/specifica/spec-generator.d.ts.map +1 -0
  410. package/dist/specifica/spec-generator.js +229 -0
  411. package/dist/specifica/spec-generator.js.map +1 -0
  412. package/dist/specifica/types.d.ts +213 -0
  413. package/dist/specifica/types.d.ts.map +1 -0
  414. package/dist/specifica/types.js +7 -0
  415. package/dist/specifica/types.js.map +1 -0
  416. package/dist/utils/logger.d.ts +17 -0
  417. package/dist/utils/logger.d.ts.map +1 -0
  418. package/dist/utils/logger.js +51 -0
  419. package/dist/utils/logger.js.map +1 -0
  420. package/package.json +99 -0
@@ -0,0 +1,297 @@
1
+ /**
2
+ * Enriched section builder
3
+ *
4
+ * Provides structure for LLM-enhanced metadata:
5
+ * - Function roles (controller, service, repository)
6
+ * - Risk levels
7
+ * - Trust boundaries
8
+ * - Additional sources/sinks discovered by analysis
9
+ */
10
+ /**
11
+ * Build the enriched section with heuristic-based analysis.
12
+ * This provides a baseline that LLM can enhance.
13
+ */
14
+ export function buildEnriched(types, calls, existingSources, existingSinks) {
15
+ const functions = analyzeMethodRoles(types);
16
+ const additionalSources = findAdditionalSources(calls, existingSources);
17
+ const additionalSinks = findAdditionalSinks(calls, existingSinks);
18
+ const resolvedCalls = suggestCallResolutions(calls);
19
+ return {
20
+ functions: functions.length > 0 ? functions : undefined,
21
+ additional_sources: additionalSources.length > 0 ? additionalSources : undefined,
22
+ additional_sinks: additionalSinks.length > 0 ? additionalSinks : undefined,
23
+ resolved_calls: resolvedCalls.length > 0 ? resolvedCalls : undefined,
24
+ };
25
+ }
26
+ /**
27
+ * Analyze method roles based on naming conventions and annotations.
28
+ */
29
+ function analyzeMethodRoles(types) {
30
+ const functions = [];
31
+ for (const type of types) {
32
+ const classRole = inferClassRole(type);
33
+ for (const method of type.methods) {
34
+ const role = inferMethodRole(method.name, type, classRole);
35
+ const risk = assessMethodRisk(method, type);
36
+ const trustBoundary = determineTrustBoundary(method, type);
37
+ // Only include if we have meaningful analysis
38
+ if (role !== 'utility' || risk !== 'low' || trustBoundary !== 'internal') {
39
+ functions.push({
40
+ method_name: `${type.name}.${method.name}`,
41
+ role,
42
+ risk,
43
+ trust_boundary: trustBoundary,
44
+ summary: generateMethodSummary(method.name, role, type.name),
45
+ });
46
+ }
47
+ }
48
+ }
49
+ return functions;
50
+ }
51
+ /**
52
+ * Infer the role of a class based on naming and annotations.
53
+ */
54
+ function inferClassRole(type) {
55
+ const name = type.name.toLowerCase();
56
+ const annotations = type.annotations.map(a => a.toLowerCase());
57
+ // Check annotations first
58
+ if (annotations.some(a => a.includes('controller') || a.includes('restcontroller'))) {
59
+ return 'controller';
60
+ }
61
+ if (annotations.some(a => a.includes('service'))) {
62
+ return 'service';
63
+ }
64
+ if (annotations.some(a => a.includes('repository'))) {
65
+ return 'repository';
66
+ }
67
+ // Check naming conventions
68
+ if (name.includes('controller') || name.includes('resource') || name.includes('endpoint')) {
69
+ return 'controller';
70
+ }
71
+ if (name.includes('service') || name.includes('manager') || name.includes('handler')) {
72
+ return 'service';
73
+ }
74
+ if (name.includes('repository') || name.includes('dao') || name.includes('store')) {
75
+ return 'repository';
76
+ }
77
+ return 'utility';
78
+ }
79
+ /**
80
+ * Infer method role based on naming and context.
81
+ */
82
+ function inferMethodRole(methodName, type, classRole) {
83
+ const name = methodName.toLowerCase();
84
+ // HTTP handler methods in controllers
85
+ if (classRole === 'controller') {
86
+ const httpMethods = ['get', 'post', 'put', 'delete', 'patch', 'handle', 'do'];
87
+ if (httpMethods.some(m => name.startsWith(m))) {
88
+ return 'controller';
89
+ }
90
+ }
91
+ // Data access methods
92
+ if (classRole === 'repository' || name.startsWith('find') || name.startsWith('save') ||
93
+ name.startsWith('delete') || name.startsWith('update') || name.startsWith('query')) {
94
+ return 'repository';
95
+ }
96
+ // Business logic methods
97
+ if (classRole === 'service' || name.includes('process') || name.includes('validate') ||
98
+ name.includes('calculate') || name.includes('compute')) {
99
+ return 'service';
100
+ }
101
+ return classRole;
102
+ }
103
+ /**
104
+ * Assess risk level of a method.
105
+ */
106
+ function assessMethodRisk(method, type) {
107
+ const methodName = method.name.toLowerCase();
108
+ const annotations = [...method.annotations, ...type.annotations].map(a => a.toLowerCase());
109
+ // High risk: authentication, authorization, crypto
110
+ const highRiskPatterns = [
111
+ 'auth', 'login', 'password', 'credential', 'token',
112
+ 'encrypt', 'decrypt', 'hash', 'sign', 'verify',
113
+ 'admin', 'privilege', 'permission', 'role',
114
+ ];
115
+ if (highRiskPatterns.some(p => methodName.includes(p))) {
116
+ return 'high';
117
+ }
118
+ // High risk: SQL/command execution
119
+ const dangerousPatterns = ['execute', 'query', 'eval', 'exec', 'run'];
120
+ if (dangerousPatterns.some(p => methodName.includes(p))) {
121
+ return 'high';
122
+ }
123
+ // Medium risk: data processing with user input
124
+ if (annotations.some(a => a.includes('requestparam') || a.includes('requestbody') ||
125
+ a.includes('pathvariable'))) {
126
+ return 'medium';
127
+ }
128
+ // Medium risk: file operations
129
+ const filePatterns = ['file', 'read', 'write', 'upload', 'download', 'stream'];
130
+ if (filePatterns.some(p => methodName.includes(p))) {
131
+ return 'medium';
132
+ }
133
+ return 'low';
134
+ }
135
+ /**
136
+ * Determine trust boundary for a method.
137
+ */
138
+ function determineTrustBoundary(method, type) {
139
+ const annotations = [...method.annotations, ...type.annotations];
140
+ // Entry points: HTTP endpoints
141
+ const entryPointAnnotations = [
142
+ 'GetMapping', 'PostMapping', 'PutMapping', 'DeleteMapping', 'PatchMapping',
143
+ 'RequestMapping', 'GET', 'POST', 'PUT', 'DELETE',
144
+ 'Path', 'Consumes', 'Produces',
145
+ ];
146
+ if (entryPointAnnotations.some(a => annotations.some(ann => ann.includes(a)))) {
147
+ return 'entry_point';
148
+ }
149
+ // External: calls to external services
150
+ const externalPatterns = ['client', 'remote', 'external', 'api', 'http', 'rest'];
151
+ if (externalPatterns.some(p => method.name.toLowerCase().includes(p))) {
152
+ return 'external';
153
+ }
154
+ // Check if class is a controller (all public methods are entry points)
155
+ if (type.annotations.some(a => a.includes('Controller') || a.includes('RestController'))) {
156
+ if (method.modifiers.includes('public')) {
157
+ return 'entry_point';
158
+ }
159
+ }
160
+ return 'internal';
161
+ }
162
+ /**
163
+ * Generate a summary for a method.
164
+ */
165
+ function generateMethodSummary(methodName, role, className) {
166
+ const summaries = {
167
+ controller: `HTTP endpoint handler in ${className}`,
168
+ service: `Business logic method in ${className}`,
169
+ repository: `Data access method in ${className}`,
170
+ utility: `Utility method in ${className}`,
171
+ };
172
+ return summaries[role] || `Method ${methodName} in ${className}`;
173
+ }
174
+ /**
175
+ * Find additional sources that heuristics might have missed.
176
+ */
177
+ function findAdditionalSources(calls, existingSources) {
178
+ const additional = [];
179
+ const existingLines = new Set(existingSources.map(s => s.line));
180
+ // Patterns that might indicate sources
181
+ const sourcePatterns = [
182
+ { pattern: /read/i, type: 'io_input' },
183
+ { pattern: /input/i, type: 'io_input' },
184
+ { pattern: /parse/i, type: 'io_input' },
185
+ { pattern: /deserialize/i, type: 'io_input' },
186
+ { pattern: /decode/i, type: 'io_input' },
187
+ { pattern: /fetch/i, type: 'network_input' },
188
+ { pattern: /download/i, type: 'network_input' },
189
+ { pattern: /receive/i, type: 'network_input' },
190
+ ];
191
+ for (const call of calls) {
192
+ // Skip if already identified
193
+ if (existingLines.has(call.location.line))
194
+ continue;
195
+ for (const { pattern, type } of sourcePatterns) {
196
+ if (pattern.test(call.method_name)) {
197
+ additional.push({
198
+ type,
199
+ location: `${call.receiver ? call.receiver + '.' : ''}${call.method_name}() in ${call.in_method || 'unknown'}`,
200
+ severity: 'medium',
201
+ line: call.location.line,
202
+ confidence: 0.6, // Lower confidence for heuristic matches
203
+ });
204
+ break;
205
+ }
206
+ }
207
+ }
208
+ return additional;
209
+ }
210
+ /**
211
+ * Find additional sinks that heuristics might have missed.
212
+ */
213
+ function findAdditionalSinks(calls, existingSinks) {
214
+ const additional = [];
215
+ const existingLines = new Set(existingSinks.map(s => s.line));
216
+ // Patterns that might indicate sinks
217
+ const sinkPatterns = [
218
+ { pattern: /write/i, type: 'xss', cwe: 'CWE-79' },
219
+ { pattern: /print/i, type: 'xss', cwe: 'CWE-79' },
220
+ { pattern: /render/i, type: 'xss', cwe: 'CWE-79' },
221
+ { pattern: /redirect/i, type: 'ssrf', cwe: 'CWE-918' },
222
+ { pattern: /forward/i, type: 'ssrf', cwe: 'CWE-918' },
223
+ { pattern: /send/i, type: 'ssrf', cwe: 'CWE-918' },
224
+ { pattern: /log/i, type: 'xss', cwe: 'CWE-117' }, // Log injection
225
+ ];
226
+ for (const call of calls) {
227
+ // Skip if already identified
228
+ if (existingLines.has(call.location.line))
229
+ continue;
230
+ // Only consider calls with arguments (potential data flow)
231
+ if (call.arguments.length === 0)
232
+ continue;
233
+ for (const { pattern, type, cwe } of sinkPatterns) {
234
+ if (pattern.test(call.method_name)) {
235
+ additional.push({
236
+ type,
237
+ cwe,
238
+ location: `${call.receiver ? call.receiver + '.' : ''}${call.method_name}() in ${call.in_method || 'unknown'}`,
239
+ line: call.location.line,
240
+ confidence: 0.5, // Lower confidence for heuristic matches
241
+ });
242
+ break;
243
+ }
244
+ }
245
+ }
246
+ return additional;
247
+ }
248
+ /**
249
+ * Suggest resolutions for unresolved calls based on heuristics.
250
+ */
251
+ function suggestCallResolutions(calls) {
252
+ const resolved = [];
253
+ for (let i = 0; i < calls.length; i++) {
254
+ const call = calls[i];
255
+ // Skip already resolved calls
256
+ if (call.resolved)
257
+ continue;
258
+ // Try to resolve based on common patterns
259
+ const suggestion = suggestResolution(call);
260
+ if (suggestion) {
261
+ resolved.push({
262
+ call_id: i,
263
+ resolved_to: suggestion.target,
264
+ confidence: suggestion.confidence,
265
+ reason: suggestion.reason,
266
+ });
267
+ }
268
+ }
269
+ return resolved;
270
+ }
271
+ /**
272
+ * Suggest a resolution for an unresolved call.
273
+ */
274
+ function suggestResolution(call) {
275
+ // Common Spring/Java patterns
276
+ const commonResolutions = {
277
+ save: { suffix: 'Impl', confidence: 0.7, reason: 'Common repository pattern' },
278
+ find: { suffix: 'Impl', confidence: 0.7, reason: 'Common repository pattern' },
279
+ delete: { suffix: 'Impl', confidence: 0.7, reason: 'Common repository pattern' },
280
+ update: { suffix: 'Impl', confidence: 0.7, reason: 'Common repository pattern' },
281
+ process: { suffix: 'Impl', confidence: 0.6, reason: 'Common service pattern' },
282
+ handle: { suffix: 'Impl', confidence: 0.6, reason: 'Common handler pattern' },
283
+ execute: { suffix: 'Impl', confidence: 0.6, reason: 'Common command pattern' },
284
+ };
285
+ const methodLower = call.method_name.toLowerCase();
286
+ for (const [pattern, resolution] of Object.entries(commonResolutions)) {
287
+ if (methodLower.startsWith(pattern) && call.receiver) {
288
+ return {
289
+ target: `${call.receiver}${resolution.suffix}.${call.method_name}`,
290
+ confidence: resolution.confidence,
291
+ reason: resolution.reason,
292
+ };
293
+ }
294
+ }
295
+ return null;
296
+ }
297
+ //# sourceMappingURL=enriched.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enriched.js","sourceRoot":"","sources":["../../src/analysis/enriched.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * LLM-based Correlated Predicate Analysis
3
+ *
4
+ * Detects when predicates (conditions) are correlated, meaning:
5
+ * - They use the same variable
6
+ * - One implies the other
7
+ * - They are logically opposite
8
+ *
9
+ * Example:
10
+ * if (choice) { name = getParameter(); } // taint source
11
+ * if (choice) { println(name); } // taint sink
12
+ *
13
+ * Since both conditions use the same 'choice' variable,
14
+ * if choice=true, BOTH branches execute (vulnerable)
15
+ * if choice=false, NEITHER branch executes (safe)
16
+ *
17
+ * A naive analyzer might think name could be tainted when reaching the sink,
18
+ * but correlated predicate analysis reveals the true dataflow.
19
+ */
20
+ import type { CFG } from 'circle-ir';
21
+ import { type AxLLMClient } from '../llm/ax-client.js';
22
+ /**
23
+ * Predicate location with its condition
24
+ */
25
+ export interface PredicateLocation {
26
+ line: number;
27
+ condition: string;
28
+ blockId: number;
29
+ trueTargets: number[];
30
+ falseTargets: number[];
31
+ }
32
+ /**
33
+ * Correlation type between predicates
34
+ */
35
+ export type CorrelationType = 'same_variable' | 'opposite' | 'implies' | 'mutual_exclusive' | 'independent' | 'unknown';
36
+ /**
37
+ * Correlated predicate group
38
+ */
39
+ export interface CorrelatedGroup {
40
+ predicates: PredicateLocation[];
41
+ correlation: CorrelationType;
42
+ confidence: number;
43
+ reasoning: string;
44
+ bothTrueReachable: boolean;
45
+ bothFalseReachable: boolean;
46
+ mixedReachable: boolean;
47
+ }
48
+ /**
49
+ * Result of correlated predicate analysis
50
+ */
51
+ export interface CorrelatedPredicateResult {
52
+ predicates: PredicateLocation[];
53
+ groups: CorrelatedGroup[];
54
+ unreachableLines: Set<number>;
55
+ unreachablePairs: Array<{
56
+ sourceLine: number;
57
+ sinkLine: number;
58
+ reason: string;
59
+ }>;
60
+ }
61
+ /**
62
+ * Extract predicates from CFG
63
+ */
64
+ export declare function extractPredicates(cfg: CFG, code: string): PredicateLocation[];
65
+ /**
66
+ * Find obviously correlated predicates using simple pattern matching
67
+ */
68
+ export declare function findSimpleCorrelations(predicates: PredicateLocation[]): CorrelatedGroup[];
69
+ /**
70
+ * Analyze correlated predicates using LLM
71
+ */
72
+ export declare function analyzeCorrelatedPredicates(code: string, predicates: PredicateLocation[], llmClient?: AxLLMClient): Promise<CorrelatedPredicateResult>;
73
+ /**
74
+ * Check if a source-sink pair is unreachable due to correlated predicates
75
+ */
76
+ export declare function isPairUnreachableDueToCorrelation(sourceLine: number, sinkLine: number, analysisResult: CorrelatedPredicateResult): {
77
+ unreachable: boolean;
78
+ reason?: string;
79
+ };
80
+ //# sourceMappingURL=llm-correlated-predicates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm-correlated-predicates.d.ts","sourceRoot":"","sources":["../../src/analysis/llm-correlated-predicates.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAY,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvE;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,MAAM,eAAe,GACvB,eAAe,GACf,UAAU,GACV,SAAS,GACT,kBAAkB,GAClB,aAAa,GACb,SAAS,CAAC;AAEd;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,iBAAiB,EAAE,CAAC;IAChC,WAAW,EAAE,eAAe,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAElB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,kBAAkB,EAAE,OAAO,CAAC;IAC5B,cAAc,EAAE,OAAO,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,UAAU,EAAE,iBAAiB,EAAE,CAAC;IAChC,MAAM,EAAE,eAAe,EAAE,CAAC;IAE1B,gBAAgB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAE9B,gBAAgB,EAAE,KAAK,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACnF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAwC7E;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,iBAAiB,EAAE,GAAG,eAAe,EAAE,CA2DzF;AAiBD;;GAEG;AACH,wBAAsB,2BAA2B,CAC/C,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,iBAAiB,EAAE,EAC/B,SAAS,CAAC,EAAE,WAAW,GACtB,OAAO,CAAC,yBAAyB,CAAC,CAsGpC;AAED;;GAEG;AACH,wBAAgB,iCAAiC,CAC/C,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,yBAAyB,GACxC;IAAE,WAAW,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAkC3C"}
@@ -0,0 +1,255 @@
1
+ /**
2
+ * LLM-based Correlated Predicate Analysis
3
+ *
4
+ * Detects when predicates (conditions) are correlated, meaning:
5
+ * - They use the same variable
6
+ * - One implies the other
7
+ * - They are logically opposite
8
+ *
9
+ * Example:
10
+ * if (choice) { name = getParameter(); } // taint source
11
+ * if (choice) { println(name); } // taint sink
12
+ *
13
+ * Since both conditions use the same 'choice' variable,
14
+ * if choice=true, BOTH branches execute (vulnerable)
15
+ * if choice=false, NEITHER branch executes (safe)
16
+ *
17
+ * A naive analyzer might think name could be tainted when reaching the sink,
18
+ * but correlated predicate analysis reveals the true dataflow.
19
+ */
20
+ import { getAxLLMClient } from '../llm/ax-client.js';
21
+ /**
22
+ * Extract predicates from CFG
23
+ */
24
+ export function extractPredicates(cfg, code) {
25
+ const predicates = [];
26
+ const lines = code.split('\n');
27
+ for (const block of cfg.blocks) {
28
+ if (block.type === 'conditional') {
29
+ // Find the condition in the code
30
+ const startLine = block.start_line;
31
+ const endLine = block.end_line || startLine;
32
+ // Extract condition text
33
+ let condition = '';
34
+ for (let i = startLine - 1; i < endLine && i < lines.length; i++) {
35
+ const line = lines[i];
36
+ // Look for if/while/for conditions
37
+ const match = line.match(/(?:if|while|for)\s*\(([^)]+)\)/);
38
+ if (match) {
39
+ condition = match[1].trim();
40
+ break;
41
+ }
42
+ }
43
+ if (condition) {
44
+ // Find edges from this block
45
+ const edges = cfg.edges.filter(e => e.from === block.id);
46
+ const trueTargets = edges.filter(e => e.type === 'true').map(e => e.to);
47
+ const falseTargets = edges.filter(e => e.type === 'false').map(e => e.to);
48
+ predicates.push({
49
+ line: startLine,
50
+ condition,
51
+ blockId: block.id,
52
+ trueTargets,
53
+ falseTargets,
54
+ });
55
+ }
56
+ }
57
+ }
58
+ return predicates;
59
+ }
60
+ /**
61
+ * Find obviously correlated predicates using simple pattern matching
62
+ */
63
+ export function findSimpleCorrelations(predicates) {
64
+ const groups = [];
65
+ for (let i = 0; i < predicates.length; i++) {
66
+ for (let j = i + 1; j < predicates.length; j++) {
67
+ const p1 = predicates[i];
68
+ const p2 = predicates[j];
69
+ // Check for same condition
70
+ if (p1.condition === p2.condition) {
71
+ groups.push({
72
+ predicates: [p1, p2],
73
+ correlation: 'same_variable',
74
+ confidence: 1.0,
75
+ reasoning: `Both conditions are identical: "${p1.condition}"`,
76
+ bothTrueReachable: true,
77
+ bothFalseReachable: true,
78
+ mixedReachable: false,
79
+ });
80
+ continue;
81
+ }
82
+ // Check for negation
83
+ if (p1.condition === `!${p2.condition}` ||
84
+ `!${p1.condition}` === p2.condition ||
85
+ p1.condition === `!(${p2.condition})` ||
86
+ `!(${p1.condition})` === p2.condition) {
87
+ groups.push({
88
+ predicates: [p1, p2],
89
+ correlation: 'opposite',
90
+ confidence: 1.0,
91
+ reasoning: `Conditions are negations: "${p1.condition}" vs "${p2.condition}"`,
92
+ bothTrueReachable: false,
93
+ bothFalseReachable: false,
94
+ mixedReachable: true,
95
+ });
96
+ continue;
97
+ }
98
+ // Check for same variable in condition (basic check)
99
+ const vars1 = extractVariables(p1.condition);
100
+ const vars2 = extractVariables(p2.condition);
101
+ const commonVars = vars1.filter(v => vars2.includes(v));
102
+ if (commonVars.length > 0) {
103
+ groups.push({
104
+ predicates: [p1, p2],
105
+ correlation: 'same_variable',
106
+ confidence: 0.7,
107
+ reasoning: `Both conditions use variable(s): ${commonVars.join(', ')}`,
108
+ bothTrueReachable: true, // Conservative: assume both can be true
109
+ bothFalseReachable: true,
110
+ mixedReachable: true,
111
+ });
112
+ }
113
+ }
114
+ }
115
+ return groups;
116
+ }
117
+ /**
118
+ * Extract variable names from a condition string
119
+ */
120
+ function extractVariables(condition) {
121
+ // Remove string literals
122
+ const withoutStrings = condition.replace(/"[^"]*"/g, '').replace(/'[^']*'/g, '');
123
+ // Remove numbers
124
+ const withoutNumbers = withoutStrings.replace(/\b\d+\b/g, '');
125
+ // Extract identifiers
126
+ const matches = withoutNumbers.match(/\b[a-zA-Z_][a-zA-Z0-9_]*\b/g) || [];
127
+ // Filter out keywords
128
+ const keywords = new Set(['if', 'else', 'while', 'for', 'true', 'false', 'null', 'new', 'instanceof', 'return']);
129
+ return matches.filter(m => !keywords.has(m));
130
+ }
131
+ /**
132
+ * Analyze correlated predicates using LLM
133
+ */
134
+ export async function analyzeCorrelatedPredicates(code, predicates, llmClient) {
135
+ // First, find simple correlations
136
+ const simpleGroups = findSimpleCorrelations(predicates);
137
+ // If we have predicates that might need deeper analysis
138
+ const needsLLMAnalysis = predicates.length > 1 &&
139
+ simpleGroups.length < (predicates.length * (predicates.length - 1)) / 2;
140
+ let llmGroups = [];
141
+ if (needsLLMAnalysis) {
142
+ try {
143
+ const client = llmClient || getAxLLMClient();
144
+ const result = await client.analyzeCorrelatedPredicates({
145
+ code,
146
+ predicateLocations: predicates.map(p => ({
147
+ line: p.line,
148
+ condition: p.condition,
149
+ })),
150
+ });
151
+ // Convert LLM results to our format
152
+ for (const group of result.correlatedGroups) {
153
+ const predIndices = group.predicates || [];
154
+ const groupPredicates = predIndices
155
+ .map(idx => predicates[idx])
156
+ .filter(p => p !== undefined);
157
+ if (groupPredicates.length >= 2) {
158
+ const correlation = group.correlation || 'independent';
159
+ llmGroups.push({
160
+ predicates: groupPredicates,
161
+ correlation,
162
+ confidence: typeof group.confidence === 'number' ? group.confidence : 0.5,
163
+ reasoning: result.reasoning || '',
164
+ bothTrueReachable: correlation !== 'opposite' && correlation !== 'mutual_exclusive',
165
+ bothFalseReachable: correlation !== 'opposite' && correlation !== 'mutual_exclusive',
166
+ mixedReachable: correlation === 'opposite' || correlation === 'independent',
167
+ });
168
+ }
169
+ }
170
+ }
171
+ catch (error) {
172
+ // Fall back to simple analysis only
173
+ console.warn('LLM correlated predicate analysis failed, using simple analysis');
174
+ }
175
+ }
176
+ // Merge simple and LLM groups (prefer LLM if available)
177
+ const allGroups = [...simpleGroups];
178
+ for (const llmGroup of llmGroups) {
179
+ // Check if this group already exists in simple groups
180
+ const exists = allGroups.some(g => g.predicates.length === llmGroup.predicates.length &&
181
+ g.predicates.every(p => llmGroup.predicates.some(lp => lp.line === p.line)));
182
+ if (!exists) {
183
+ allGroups.push(llmGroup);
184
+ }
185
+ else {
186
+ // Update existing group with LLM analysis
187
+ const existing = allGroups.find(g => g.predicates.length === llmGroup.predicates.length &&
188
+ g.predicates.every(p => llmGroup.predicates.some(lp => lp.line === p.line)));
189
+ if (existing && llmGroup.confidence > existing.confidence) {
190
+ Object.assign(existing, llmGroup);
191
+ }
192
+ }
193
+ }
194
+ // Determine unreachable lines and pairs
195
+ const unreachableLines = new Set();
196
+ const unreachablePairs = [];
197
+ for (const group of allGroups) {
198
+ if (group.correlation === 'opposite' && group.confidence > 0.8) {
199
+ // If predicates are opposite, code in one true branch can't reach code in other true branch
200
+ const [p1, p2] = group.predicates;
201
+ // Add unreachable pair
202
+ unreachablePairs.push({
203
+ sourceLine: p1.line,
204
+ sinkLine: p2.line,
205
+ reason: `Predicates at lines ${p1.line} and ${p2.line} are opposite: ${p1.condition} vs ${p2.condition}`,
206
+ });
207
+ }
208
+ if (group.correlation === 'mutual_exclusive' && group.confidence > 0.8) {
209
+ const [p1, p2] = group.predicates;
210
+ unreachablePairs.push({
211
+ sourceLine: p1.line,
212
+ sinkLine: p2.line,
213
+ reason: `Predicates at lines ${p1.line} and ${p2.line} are mutually exclusive`,
214
+ });
215
+ }
216
+ }
217
+ return {
218
+ predicates,
219
+ groups: allGroups,
220
+ unreachableLines,
221
+ unreachablePairs,
222
+ };
223
+ }
224
+ /**
225
+ * Check if a source-sink pair is unreachable due to correlated predicates
226
+ */
227
+ export function isPairUnreachableDueToCorrelation(sourceLine, sinkLine, analysisResult) {
228
+ // Check direct unreachable pairs
229
+ const pair = analysisResult.unreachablePairs.find(p => (p.sourceLine <= sourceLine && p.sinkLine >= sinkLine) ||
230
+ (p.sourceLine <= sinkLine && p.sinkLine >= sourceLine));
231
+ if (pair) {
232
+ return { unreachable: true, reason: pair.reason };
233
+ }
234
+ // Check if source and sink are in mutually exclusive branches
235
+ for (const group of analysisResult.groups) {
236
+ if (group.correlation !== 'same_variable' && group.correlation !== 'implies') {
237
+ continue;
238
+ }
239
+ // Find predicates that guard source and sink
240
+ // (This is a simplified check - full implementation would need CFG traversal)
241
+ const [p1, p2] = group.predicates;
242
+ // If both predicates guard both source and sink with same condition,
243
+ // they are reachable together (either both execute or neither)
244
+ if (p1.line < sourceLine && p2.line < sinkLine) {
245
+ // Source is after p1, sink is after p2
246
+ // If same_variable correlation, they execute together
247
+ if (group.correlation === 'same_variable' && group.confidence > 0.9) {
248
+ // This is actually reachable together!
249
+ return { unreachable: false };
250
+ }
251
+ }
252
+ }
253
+ return { unreachable: false };
254
+ }
255
+ //# sourceMappingURL=llm-correlated-predicates.js.map