@oddessentials/odd-ai-reviewers 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (370) hide show
  1. package/README.md +190 -0
  2. package/dist/__tests__/hermetic-setup.d.ts +55 -0
  3. package/dist/__tests__/hermetic-setup.d.ts.map +1 -0
  4. package/dist/__tests__/hermetic-setup.js +62 -0
  5. package/dist/__tests__/hermetic-setup.js.map +1 -0
  6. package/dist/__tests__/test-utils/hermetic.d.ts +84 -0
  7. package/dist/__tests__/test-utils/hermetic.d.ts.map +1 -0
  8. package/dist/__tests__/test-utils/hermetic.js +147 -0
  9. package/dist/__tests__/test-utils/hermetic.js.map +1 -0
  10. package/dist/agents/ai_semantic_review.d.ts +12 -0
  11. package/dist/agents/ai_semantic_review.d.ts.map +1 -0
  12. package/dist/agents/ai_semantic_review.js +317 -0
  13. package/dist/agents/ai_semantic_review.js.map +1 -0
  14. package/dist/agents/control_flow/budget.d.ts +162 -0
  15. package/dist/agents/control_flow/budget.d.ts.map +1 -0
  16. package/dist/agents/control_flow/budget.js +331 -0
  17. package/dist/agents/control_flow/budget.js.map +1 -0
  18. package/dist/agents/control_flow/cfg-builder.d.ts +26 -0
  19. package/dist/agents/control_flow/cfg-builder.d.ts.map +1 -0
  20. package/dist/agents/control_flow/cfg-builder.js +776 -0
  21. package/dist/agents/control_flow/cfg-builder.js.map +1 -0
  22. package/dist/agents/control_flow/cfg-types.d.ts +186 -0
  23. package/dist/agents/control_flow/cfg-types.d.ts.map +1 -0
  24. package/dist/agents/control_flow/cfg-types.js +114 -0
  25. package/dist/agents/control_flow/cfg-types.js.map +1 -0
  26. package/dist/agents/control_flow/finding-generator.d.ts +118 -0
  27. package/dist/agents/control_flow/finding-generator.d.ts.map +1 -0
  28. package/dist/agents/control_flow/finding-generator.js +354 -0
  29. package/dist/agents/control_flow/finding-generator.js.map +1 -0
  30. package/dist/agents/control_flow/index.d.ts +39 -0
  31. package/dist/agents/control_flow/index.d.ts.map +1 -0
  32. package/dist/agents/control_flow/index.js +270 -0
  33. package/dist/agents/control_flow/index.js.map +1 -0
  34. package/dist/agents/control_flow/logger.d.ts +333 -0
  35. package/dist/agents/control_flow/logger.d.ts.map +1 -0
  36. package/dist/agents/control_flow/logger.js +607 -0
  37. package/dist/agents/control_flow/logger.js.map +1 -0
  38. package/dist/agents/control_flow/mitigation-detector.d.ts +207 -0
  39. package/dist/agents/control_flow/mitigation-detector.d.ts.map +1 -0
  40. package/dist/agents/control_flow/mitigation-detector.js +625 -0
  41. package/dist/agents/control_flow/mitigation-detector.js.map +1 -0
  42. package/dist/agents/control_flow/mitigation-patterns.d.ts +53 -0
  43. package/dist/agents/control_flow/mitigation-patterns.d.ts.map +1 -0
  44. package/dist/agents/control_flow/mitigation-patterns.js +620 -0
  45. package/dist/agents/control_flow/mitigation-patterns.js.map +1 -0
  46. package/dist/agents/control_flow/path-analyzer.d.ts +287 -0
  47. package/dist/agents/control_flow/path-analyzer.d.ts.map +1 -0
  48. package/dist/agents/control_flow/path-analyzer.js +695 -0
  49. package/dist/agents/control_flow/path-analyzer.js.map +1 -0
  50. package/dist/agents/control_flow/pattern-validator.d.ts +132 -0
  51. package/dist/agents/control_flow/pattern-validator.d.ts.map +1 -0
  52. package/dist/agents/control_flow/pattern-validator.js +420 -0
  53. package/dist/agents/control_flow/pattern-validator.js.map +1 -0
  54. package/dist/agents/control_flow/timeout-regex.d.ts +144 -0
  55. package/dist/agents/control_flow/timeout-regex.d.ts.map +1 -0
  56. package/dist/agents/control_flow/timeout-regex.js +339 -0
  57. package/dist/agents/control_flow/timeout-regex.js.map +1 -0
  58. package/dist/agents/control_flow/types.d.ts +782 -0
  59. package/dist/agents/control_flow/types.d.ts.map +1 -0
  60. package/dist/agents/control_flow/types.js +428 -0
  61. package/dist/agents/control_flow/types.js.map +1 -0
  62. package/dist/agents/control_flow/vulnerability-detector.d.ts +85 -0
  63. package/dist/agents/control_flow/vulnerability-detector.d.ts.map +1 -0
  64. package/dist/agents/control_flow/vulnerability-detector.js +493 -0
  65. package/dist/agents/control_flow/vulnerability-detector.js.map +1 -0
  66. package/dist/agents/date-utils.d.ts +19 -0
  67. package/dist/agents/date-utils.d.ts.map +1 -0
  68. package/dist/agents/date-utils.js +29 -0
  69. package/dist/agents/date-utils.js.map +1 -0
  70. package/dist/agents/index.d.ts +25 -0
  71. package/dist/agents/index.d.ts.map +1 -0
  72. package/dist/agents/index.js +50 -0
  73. package/dist/agents/index.js.map +1 -0
  74. package/dist/agents/json-utils.d.ts +34 -0
  75. package/dist/agents/json-utils.d.ts.map +1 -0
  76. package/dist/agents/json-utils.js +62 -0
  77. package/dist/agents/json-utils.js.map +1 -0
  78. package/dist/agents/local_llm.d.ts +24 -0
  79. package/dist/agents/local_llm.d.ts.map +1 -0
  80. package/dist/agents/local_llm.js +566 -0
  81. package/dist/agents/local_llm.js.map +1 -0
  82. package/dist/agents/metadata.d.ts +57 -0
  83. package/dist/agents/metadata.d.ts.map +1 -0
  84. package/dist/agents/metadata.js +45 -0
  85. package/dist/agents/metadata.js.map +1 -0
  86. package/dist/agents/opencode.d.ts +18 -0
  87. package/dist/agents/opencode.d.ts.map +1 -0
  88. package/dist/agents/opencode.js +364 -0
  89. package/dist/agents/opencode.js.map +1 -0
  90. package/dist/agents/path-filter.d.ts +25 -0
  91. package/dist/agents/path-filter.d.ts.map +1 -0
  92. package/dist/agents/path-filter.js +43 -0
  93. package/dist/agents/path-filter.js.map +1 -0
  94. package/dist/agents/pr_agent.d.ts +3 -0
  95. package/dist/agents/pr_agent.d.ts.map +1 -0
  96. package/dist/agents/pr_agent.js +312 -0
  97. package/dist/agents/pr_agent.js.map +1 -0
  98. package/dist/agents/retry.d.ts +12 -0
  99. package/dist/agents/retry.d.ts.map +1 -0
  100. package/dist/agents/retry.js +65 -0
  101. package/dist/agents/retry.js.map +1 -0
  102. package/dist/agents/reviewdog.d.ts +24 -0
  103. package/dist/agents/reviewdog.d.ts.map +1 -0
  104. package/dist/agents/reviewdog.js +259 -0
  105. package/dist/agents/reviewdog.js.map +1 -0
  106. package/dist/agents/security.d.ts +49 -0
  107. package/dist/agents/security.d.ts.map +1 -0
  108. package/dist/agents/security.js +302 -0
  109. package/dist/agents/security.js.map +1 -0
  110. package/dist/agents/semgrep.d.ts +8 -0
  111. package/dist/agents/semgrep.d.ts.map +1 -0
  112. package/dist/agents/semgrep.js +157 -0
  113. package/dist/agents/semgrep.js.map +1 -0
  114. package/dist/agents/types.d.ts +450 -0
  115. package/dist/agents/types.d.ts.map +1 -0
  116. package/dist/agents/types.js +127 -0
  117. package/dist/agents/types.js.map +1 -0
  118. package/dist/budget.d.ts +59 -0
  119. package/dist/budget.d.ts.map +1 -0
  120. package/dist/budget.js +82 -0
  121. package/dist/budget.js.map +1 -0
  122. package/dist/cache/key.d.ts +49 -0
  123. package/dist/cache/key.d.ts.map +1 -0
  124. package/dist/cache/key.js +71 -0
  125. package/dist/cache/key.js.map +1 -0
  126. package/dist/cache/store.d.ts +47 -0
  127. package/dist/cache/store.d.ts.map +1 -0
  128. package/dist/cache/store.js +328 -0
  129. package/dist/cache/store.js.map +1 -0
  130. package/dist/cli/commands/check.d.ts +60 -0
  131. package/dist/cli/commands/check.d.ts.map +1 -0
  132. package/dist/cli/commands/check.js +163 -0
  133. package/dist/cli/commands/check.js.map +1 -0
  134. package/dist/cli/commands/index.d.ts +12 -0
  135. package/dist/cli/commands/index.d.ts.map +1 -0
  136. package/dist/cli/commands/index.js +12 -0
  137. package/dist/cli/commands/index.js.map +1 -0
  138. package/dist/cli/commands/local-review.d.ts +149 -0
  139. package/dist/cli/commands/local-review.d.ts.map +1 -0
  140. package/dist/cli/commands/local-review.js +755 -0
  141. package/dist/cli/commands/local-review.js.map +1 -0
  142. package/dist/cli/config-wizard.d.ts +87 -0
  143. package/dist/cli/config-wizard.d.ts.map +1 -0
  144. package/dist/cli/config-wizard.js +240 -0
  145. package/dist/cli/config-wizard.js.map +1 -0
  146. package/dist/cli/dependencies/catalog.d.ts +44 -0
  147. package/dist/cli/dependencies/catalog.d.ts.map +1 -0
  148. package/dist/cli/dependencies/catalog.js +89 -0
  149. package/dist/cli/dependencies/catalog.js.map +1 -0
  150. package/dist/cli/dependencies/checker.d.ts +42 -0
  151. package/dist/cli/dependencies/checker.d.ts.map +1 -0
  152. package/dist/cli/dependencies/checker.js +240 -0
  153. package/dist/cli/dependencies/checker.js.map +1 -0
  154. package/dist/cli/dependencies/index.d.ts +16 -0
  155. package/dist/cli/dependencies/index.d.ts.map +1 -0
  156. package/dist/cli/dependencies/index.js +16 -0
  157. package/dist/cli/dependencies/index.js.map +1 -0
  158. package/dist/cli/dependencies/messages.d.ts +58 -0
  159. package/dist/cli/dependencies/messages.d.ts.map +1 -0
  160. package/dist/cli/dependencies/messages.js +183 -0
  161. package/dist/cli/dependencies/messages.js.map +1 -0
  162. package/dist/cli/dependencies/platform.d.ts +25 -0
  163. package/dist/cli/dependencies/platform.d.ts.map +1 -0
  164. package/dist/cli/dependencies/platform.js +42 -0
  165. package/dist/cli/dependencies/platform.js.map +1 -0
  166. package/dist/cli/dependencies/schemas.d.ts +65 -0
  167. package/dist/cli/dependencies/schemas.d.ts.map +1 -0
  168. package/dist/cli/dependencies/schemas.js +42 -0
  169. package/dist/cli/dependencies/schemas.js.map +1 -0
  170. package/dist/cli/dependencies/types.d.ts +112 -0
  171. package/dist/cli/dependencies/types.d.ts.map +1 -0
  172. package/dist/cli/dependencies/types.js +6 -0
  173. package/dist/cli/dependencies/types.js.map +1 -0
  174. package/dist/cli/dependencies/version.d.ts +67 -0
  175. package/dist/cli/dependencies/version.d.ts.map +1 -0
  176. package/dist/cli/dependencies/version.js +125 -0
  177. package/dist/cli/dependencies/version.js.map +1 -0
  178. package/dist/cli/git-context.d.ts +105 -0
  179. package/dist/cli/git-context.d.ts.map +1 -0
  180. package/dist/cli/git-context.js +313 -0
  181. package/dist/cli/git-context.js.map +1 -0
  182. package/dist/cli/interactive-prompts.d.ts +126 -0
  183. package/dist/cli/interactive-prompts.d.ts.map +1 -0
  184. package/dist/cli/interactive-prompts.js +128 -0
  185. package/dist/cli/interactive-prompts.js.map +1 -0
  186. package/dist/cli/options/index.d.ts +7 -0
  187. package/dist/cli/options/index.d.ts.map +1 -0
  188. package/dist/cli/options/index.js +11 -0
  189. package/dist/cli/options/index.js.map +1 -0
  190. package/dist/cli/options/local-review-options.d.ts +221 -0
  191. package/dist/cli/options/local-review-options.d.ts.map +1 -0
  192. package/dist/cli/options/local-review-options.js +332 -0
  193. package/dist/cli/options/local-review-options.js.map +1 -0
  194. package/dist/cli/output/colors.d.ts +154 -0
  195. package/dist/cli/output/colors.d.ts.map +1 -0
  196. package/dist/cli/output/colors.js +255 -0
  197. package/dist/cli/output/colors.js.map +1 -0
  198. package/dist/cli/output/errors.d.ts +157 -0
  199. package/dist/cli/output/errors.d.ts.map +1 -0
  200. package/dist/cli/output/errors.js +266 -0
  201. package/dist/cli/output/errors.js.map +1 -0
  202. package/dist/cli/output/index.d.ts +12 -0
  203. package/dist/cli/output/index.d.ts.map +1 -0
  204. package/dist/cli/output/index.js +15 -0
  205. package/dist/cli/output/index.js.map +1 -0
  206. package/dist/cli/output/progress.d.ts +237 -0
  207. package/dist/cli/output/progress.d.ts.map +1 -0
  208. package/dist/cli/output/progress.js +405 -0
  209. package/dist/cli/output/progress.js.map +1 -0
  210. package/dist/cli/signals.d.ts +145 -0
  211. package/dist/cli/signals.d.ts.map +1 -0
  212. package/dist/cli/signals.js +223 -0
  213. package/dist/cli/signals.js.map +1 -0
  214. package/dist/cli/validation-report.d.ts +106 -0
  215. package/dist/cli/validation-report.d.ts.map +1 -0
  216. package/dist/cli/validation-report.js +108 -0
  217. package/dist/cli/validation-report.js.map +1 -0
  218. package/dist/config/index.d.ts +9 -0
  219. package/dist/config/index.d.ts.map +1 -0
  220. package/dist/config/index.js +12 -0
  221. package/dist/config/index.js.map +1 -0
  222. package/dist/config/mitigation-config.d.ts +94 -0
  223. package/dist/config/mitigation-config.d.ts.map +1 -0
  224. package/dist/config/mitigation-config.js +430 -0
  225. package/dist/config/mitigation-config.js.map +1 -0
  226. package/dist/config/providers.d.ts +118 -0
  227. package/dist/config/providers.d.ts.map +1 -0
  228. package/dist/config/providers.js +229 -0
  229. package/dist/config/providers.js.map +1 -0
  230. package/dist/config/schemas.d.ts +278 -0
  231. package/dist/config/schemas.d.ts.map +1 -0
  232. package/dist/config/schemas.js +111 -0
  233. package/dist/config/schemas.js.map +1 -0
  234. package/dist/config/zero-config.d.ts +126 -0
  235. package/dist/config/zero-config.d.ts.map +1 -0
  236. package/dist/config/zero-config.js +243 -0
  237. package/dist/config/zero-config.js.map +1 -0
  238. package/dist/config.d.ts +110 -0
  239. package/dist/config.d.ts.map +1 -0
  240. package/dist/config.js +302 -0
  241. package/dist/config.js.map +1 -0
  242. package/dist/diff.d.ts +224 -0
  243. package/dist/diff.d.ts.map +1 -0
  244. package/dist/diff.js +832 -0
  245. package/dist/diff.js.map +1 -0
  246. package/dist/git-validators.d.ts +106 -0
  247. package/dist/git-validators.d.ts.map +1 -0
  248. package/dist/git-validators.js +224 -0
  249. package/dist/git-validators.js.map +1 -0
  250. package/dist/main.d.ts +61 -0
  251. package/dist/main.d.ts.map +1 -0
  252. package/dist/main.js +704 -0
  253. package/dist/main.js.map +1 -0
  254. package/dist/phases/execute.d.ts +60 -0
  255. package/dist/phases/execute.d.ts.map +1 -0
  256. package/dist/phases/execute.js +168 -0
  257. package/dist/phases/execute.js.map +1 -0
  258. package/dist/phases/index.d.ts +9 -0
  259. package/dist/phases/index.d.ts.map +1 -0
  260. package/dist/phases/index.js +9 -0
  261. package/dist/phases/index.js.map +1 -0
  262. package/dist/phases/preflight.d.ts +40 -0
  263. package/dist/phases/preflight.d.ts.map +1 -0
  264. package/dist/phases/preflight.js +122 -0
  265. package/dist/phases/preflight.js.map +1 -0
  266. package/dist/phases/report.d.ts +51 -0
  267. package/dist/phases/report.d.ts.map +1 -0
  268. package/dist/phases/report.js +152 -0
  269. package/dist/phases/report.js.map +1 -0
  270. package/dist/policy.d.ts +33 -0
  271. package/dist/policy.d.ts.map +1 -0
  272. package/dist/policy.js +34 -0
  273. package/dist/policy.js.map +1 -0
  274. package/dist/preflight.d.ts +181 -0
  275. package/dist/preflight.d.ts.map +1 -0
  276. package/dist/preflight.js +627 -0
  277. package/dist/preflight.js.map +1 -0
  278. package/dist/report/ado.d.ts +53 -0
  279. package/dist/report/ado.d.ts.map +1 -0
  280. package/dist/report/ado.js +411 -0
  281. package/dist/report/ado.js.map +1 -0
  282. package/dist/report/agent-icons.d.ts +36 -0
  283. package/dist/report/agent-icons.d.ts.map +1 -0
  284. package/dist/report/agent-icons.js +46 -0
  285. package/dist/report/agent-icons.js.map +1 -0
  286. package/dist/report/base.d.ts +30 -0
  287. package/dist/report/base.d.ts.map +1 -0
  288. package/dist/report/base.js +64 -0
  289. package/dist/report/base.js.map +1 -0
  290. package/dist/report/formats.d.ts +206 -0
  291. package/dist/report/formats.d.ts.map +1 -0
  292. package/dist/report/formats.js +481 -0
  293. package/dist/report/formats.js.map +1 -0
  294. package/dist/report/github.d.ts +44 -0
  295. package/dist/report/github.d.ts.map +1 -0
  296. package/dist/report/github.js +409 -0
  297. package/dist/report/github.js.map +1 -0
  298. package/dist/report/line-resolver.d.ts +208 -0
  299. package/dist/report/line-resolver.d.ts.map +1 -0
  300. package/dist/report/line-resolver.js +578 -0
  301. package/dist/report/line-resolver.js.map +1 -0
  302. package/dist/report/resolution.d.ts +158 -0
  303. package/dist/report/resolution.d.ts.map +1 -0
  304. package/dist/report/resolution.js +272 -0
  305. package/dist/report/resolution.js.map +1 -0
  306. package/dist/report/sanitize.d.ts +32 -0
  307. package/dist/report/sanitize.d.ts.map +1 -0
  308. package/dist/report/sanitize.js +84 -0
  309. package/dist/report/sanitize.js.map +1 -0
  310. package/dist/report/terminal.d.ts +440 -0
  311. package/dist/report/terminal.d.ts.map +1 -0
  312. package/dist/report/terminal.js +840 -0
  313. package/dist/report/terminal.js.map +1 -0
  314. package/dist/reviewignore.d.ts +125 -0
  315. package/dist/reviewignore.d.ts.map +1 -0
  316. package/dist/reviewignore.js +335 -0
  317. package/dist/reviewignore.js.map +1 -0
  318. package/dist/security-logger.d.ts +178 -0
  319. package/dist/security-logger.d.ts.map +1 -0
  320. package/dist/security-logger.js +256 -0
  321. package/dist/security-logger.js.map +1 -0
  322. package/dist/telemetry/backends/console.d.ts +24 -0
  323. package/dist/telemetry/backends/console.d.ts.map +1 -0
  324. package/dist/telemetry/backends/console.js +54 -0
  325. package/dist/telemetry/backends/console.js.map +1 -0
  326. package/dist/telemetry/backends/jsonl.d.ts +31 -0
  327. package/dist/telemetry/backends/jsonl.d.ts.map +1 -0
  328. package/dist/telemetry/backends/jsonl.js +121 -0
  329. package/dist/telemetry/backends/jsonl.js.map +1 -0
  330. package/dist/telemetry/emitter.d.ts +43 -0
  331. package/dist/telemetry/emitter.d.ts.map +1 -0
  332. package/dist/telemetry/emitter.js +83 -0
  333. package/dist/telemetry/emitter.js.map +1 -0
  334. package/dist/telemetry/hook.d.ts +53 -0
  335. package/dist/telemetry/hook.d.ts.map +1 -0
  336. package/dist/telemetry/hook.js +118 -0
  337. package/dist/telemetry/hook.js.map +1 -0
  338. package/dist/telemetry/index.d.ts +58 -0
  339. package/dist/telemetry/index.d.ts.map +1 -0
  340. package/dist/telemetry/index.js +143 -0
  341. package/dist/telemetry/index.js.map +1 -0
  342. package/dist/telemetry/types.d.ts +139 -0
  343. package/dist/telemetry/types.d.ts.map +1 -0
  344. package/dist/telemetry/types.js +133 -0
  345. package/dist/telemetry/types.js.map +1 -0
  346. package/dist/trust.d.ts +65 -0
  347. package/dist/trust.d.ts.map +1 -0
  348. package/dist/trust.js +78 -0
  349. package/dist/trust.js.map +1 -0
  350. package/dist/types/assert-never.d.ts +30 -0
  351. package/dist/types/assert-never.d.ts.map +1 -0
  352. package/dist/types/assert-never.js +32 -0
  353. package/dist/types/assert-never.js.map +1 -0
  354. package/dist/types/branded.d.ts +172 -0
  355. package/dist/types/branded.d.ts.map +1 -0
  356. package/dist/types/branded.js +262 -0
  357. package/dist/types/branded.js.map +1 -0
  358. package/dist/types/errors.d.ts +320 -0
  359. package/dist/types/errors.d.ts.map +1 -0
  360. package/dist/types/errors.js +551 -0
  361. package/dist/types/errors.js.map +1 -0
  362. package/dist/types/index.d.ts +37 -0
  363. package/dist/types/index.d.ts.map +1 -0
  364. package/dist/types/index.js +77 -0
  365. package/dist/types/index.js.map +1 -0
  366. package/dist/types/result.d.ts +323 -0
  367. package/dist/types/result.d.ts.map +1 -0
  368. package/dist/types/result.js +423 -0
  369. package/dist/types/result.js.map +1 -0
  370. package/package.json +63 -0
@@ -0,0 +1,317 @@
1
+ /**
2
+ * AI Semantic Review Agent
3
+ * Multi-provider AI semantic code review
4
+ *
5
+ * INVARIANTS:
6
+ * - Router owns provider/model resolution
7
+ * - Agent receives context.provider and context.effectiveModel
8
+ * - No per-agent defaults, no legacy key references
9
+ */
10
+ import OpenAI from 'openai';
11
+ import Anthropic from '@anthropic-ai/sdk';
12
+ import { z } from 'zod';
13
+ import { readFile } from 'fs/promises';
14
+ import { join } from 'path';
15
+ import { existsSync } from 'fs';
16
+ import { AgentSuccess, AgentFailure, AgentSkipped } from './types.js';
17
+ import { estimateTokens } from '../budget.js';
18
+ import { buildAgentEnv } from './security.js';
19
+ import { parseJsonResponse } from './json-utils.js';
20
+ import { withRetry } from './retry.js';
21
+ import { AgentError, AgentErrorCode } from '../types/errors.js';
22
+ const SUPPORTED_EXTENSIONS = [
23
+ '.ts',
24
+ '.tsx',
25
+ '.js',
26
+ '.jsx',
27
+ '.py',
28
+ '.go',
29
+ '.java',
30
+ '.rb',
31
+ '.php',
32
+ '.c',
33
+ '.cpp',
34
+ '.cs',
35
+ '.rs',
36
+ '.swift',
37
+ '.kt',
38
+ '.scala',
39
+ '.vue',
40
+ '.svelte',
41
+ ];
42
+ const PROMPT_PATH = join(import.meta.dirname, '../../config/prompts/semantic_review.md');
43
+ /**
44
+ * Zod schema for validating Anthropic JSON response
45
+ */
46
+ const SemanticResponseSchema = z.object({
47
+ summary: z.string(),
48
+ findings: z.array(z.object({
49
+ severity: z.enum(['critical', 'high', 'medium', 'low', 'info']),
50
+ file: z.string(),
51
+ line: z.number().optional(),
52
+ message: z.string(),
53
+ suggestion: z.string().optional(),
54
+ category: z.string(),
55
+ })),
56
+ });
57
+ /**
58
+ * Run semantic review using Anthropic Claude API
59
+ */
60
+ async function runWithAnthropic(context, apiKey, model, systemPrompt, userPrompt, supportedFiles, estimatedInputTokens) {
61
+ const agentId = 'ai_semantic_review';
62
+ const startTime = Date.now();
63
+ console.log(`[ai_semantic_review] Calling Anthropic API with model: ${model}`);
64
+ const client = new Anthropic({ apiKey });
65
+ try {
66
+ const response = await withRetry(() => client.messages.create({
67
+ model,
68
+ max_tokens: 4000,
69
+ system: systemPrompt,
70
+ messages: [{ role: 'user', content: userPrompt }],
71
+ }));
72
+ // Extract text content
73
+ const textContent = response.content.find((c) => c.type === 'text');
74
+ if (!textContent || textContent.type !== 'text') {
75
+ throw new AgentError('No text content in Anthropic response', AgentErrorCode.EXECUTION_FAILED, {
76
+ agentId,
77
+ phase: 'response-extraction',
78
+ });
79
+ }
80
+ // Parse and validate JSON (handles Claude's code fence wrapping)
81
+ const parsed = parseJsonResponse(textContent.text, 'Anthropic');
82
+ const result = SemanticResponseSchema.safeParse(parsed);
83
+ if (!result.success) {
84
+ throw new AgentError(`Schema validation failed: ${result.error.message}`, AgentErrorCode.PARSE_ERROR, { agentId, phase: 'schema-validation' });
85
+ }
86
+ const findings = result.data.findings.map((f) => ({
87
+ severity: mapSeverity(f.severity),
88
+ file: f.file,
89
+ line: f.line,
90
+ message: f.message,
91
+ suggestion: f.suggestion,
92
+ ruleId: `semantic/${f.category}`,
93
+ sourceAgent: agentId,
94
+ }));
95
+ if (result.data.summary) {
96
+ console.log(`[ai_semantic_review] Summary: ${result.data.summary}`);
97
+ }
98
+ const tokensUsed = response.usage.input_tokens + response.usage.output_tokens;
99
+ const estimatedCostUsd = response.usage.input_tokens * 0.000015 + response.usage.output_tokens * 0.000075;
100
+ return AgentSuccess({
101
+ agentId,
102
+ findings,
103
+ metrics: {
104
+ durationMs: Date.now() - startTime,
105
+ filesProcessed: supportedFiles.length,
106
+ tokensUsed,
107
+ estimatedCostUsd,
108
+ },
109
+ });
110
+ }
111
+ catch (error) {
112
+ // Convert to AgentError for consistent error handling
113
+ const agentError = error instanceof AgentError
114
+ ? error
115
+ : new AgentError(error instanceof Error ? error.message : 'Unknown Anthropic error', AgentErrorCode.EXECUTION_FAILED, { agentId, phase: 'anthropic-call' });
116
+ return AgentFailure({
117
+ agentId,
118
+ error: agentError.message,
119
+ failureStage: 'exec',
120
+ metrics: {
121
+ durationMs: Date.now() - startTime,
122
+ filesProcessed: 0,
123
+ tokensUsed: estimatedInputTokens,
124
+ },
125
+ });
126
+ }
127
+ }
128
+ export const aiSemanticReviewAgent = {
129
+ id: 'ai_semantic_review',
130
+ name: 'AI Semantic Review',
131
+ usesLlm: true,
132
+ supports(file) {
133
+ if (file.status === 'deleted')
134
+ return false;
135
+ return SUPPORTED_EXTENSIONS.some((ext) => file.path.endsWith(ext));
136
+ },
137
+ async run(context) {
138
+ const startTime = Date.now();
139
+ const agentEnv = buildAgentEnv('ai_semantic_review', context.env);
140
+ // Use router-resolved provider and model
141
+ const { provider, effectiveModel } = context;
142
+ console.log(`[ai_semantic_review] Provider: ${provider}, Model: ${effectiveModel}`);
143
+ // Get files that this agent supports (shared by all providers)
144
+ const supportedFiles = context.files.filter((f) => this.supports(f));
145
+ if (supportedFiles.length === 0) {
146
+ return AgentSkipped({
147
+ agentId: this.id,
148
+ reason: 'No supported files to process',
149
+ metrics: { durationMs: Date.now() - startTime, filesProcessed: 0 },
150
+ });
151
+ }
152
+ // Load prompt template (shared by all providers)
153
+ let systemPrompt = `You are a senior code reviewer focused on semantic analysis.
154
+ Analyze the provided diff for:
155
+ - Logic errors and edge cases
156
+ - Security vulnerabilities
157
+ - Performance issues
158
+ - API misuse or anti-patterns
159
+ - Missing error handling
160
+
161
+ Line numbering requirements:
162
+ - Use new-file line numbers from unified diff hunk headers (@@ -a,b +c,d @@)
163
+ - Only use right-side diff lines (added or context). If unsure, omit the line.
164
+
165
+ Return a JSON object with findings.`;
166
+ if (existsSync(PROMPT_PATH)) {
167
+ try {
168
+ systemPrompt = await readFile(PROMPT_PATH, 'utf-8');
169
+ }
170
+ catch {
171
+ console.log('[ai_semantic_review] Using default prompt');
172
+ }
173
+ }
174
+ const fileSummary = supportedFiles
175
+ .map((f) => `- ${f.path} (${f.status}: +${f.additions}/-${f.deletions})`)
176
+ .join('\n');
177
+ const userPrompt = `## Files Changed
178
+ ${fileSummary}
179
+
180
+ ## Diff Content
181
+ \`\`\`diff
182
+ ${context.diffContent}
183
+ \`\`\`
184
+
185
+ Analyze this code and return JSON:
186
+ {
187
+ "findings": [
188
+ {
189
+ "severity": "critical|high|medium|low|info",
190
+ "file": "path/to/file.ts",
191
+ "line": 42,
192
+ "message": "Description",
193
+ "suggestion": "How to fix",
194
+ "category": "security|performance|logic|error-handling|api-misuse"
195
+ }
196
+ ],
197
+ "summary": "Brief summary of the review"
198
+ }`;
199
+ const estimatedInputTokens = estimateTokens(systemPrompt + userPrompt);
200
+ // Switch on provider
201
+ if (provider === 'anthropic') {
202
+ const anthropicKey = agentEnv['ANTHROPIC_API_KEY'];
203
+ if (!anthropicKey) {
204
+ return AgentFailure({
205
+ agentId: this.id,
206
+ error: 'ANTHROPIC_API_KEY not found despite provider=anthropic',
207
+ failureStage: 'preflight',
208
+ metrics: { durationMs: Date.now() - startTime, filesProcessed: 0 },
209
+ });
210
+ }
211
+ return runWithAnthropic(context, anthropicKey, effectiveModel, systemPrompt, userPrompt, supportedFiles, estimatedInputTokens);
212
+ }
213
+ // OpenAI / Azure OpenAI path
214
+ const apiKey = agentEnv['OPENAI_API_KEY'];
215
+ const azureEndpoint = agentEnv['AZURE_OPENAI_ENDPOINT'];
216
+ const azureApiKey = agentEnv['AZURE_OPENAI_API_KEY'];
217
+ const azureDeployment = agentEnv['AZURE_OPENAI_DEPLOYMENT'] || 'gpt-4';
218
+ if (!apiKey && !azureApiKey) {
219
+ return AgentFailure({
220
+ agentId: this.id,
221
+ error: 'No API key configured (set OPENAI_API_KEY or AZURE_OPENAI_API_KEY)',
222
+ failureStage: 'preflight',
223
+ metrics: {
224
+ durationMs: Date.now() - startTime,
225
+ filesProcessed: 0,
226
+ },
227
+ });
228
+ }
229
+ // Initialize OpenAI client
230
+ let openai;
231
+ if (azureEndpoint && azureApiKey) {
232
+ openai = new OpenAI({
233
+ apiKey: azureApiKey,
234
+ baseURL: `${azureEndpoint}/openai/deployments/${azureDeployment}`,
235
+ defaultQuery: { 'api-version': '2024-02-15-preview' },
236
+ defaultHeaders: { 'api-key': azureApiKey },
237
+ });
238
+ }
239
+ else {
240
+ openai = new OpenAI({ apiKey });
241
+ }
242
+ try {
243
+ const response = await withRetry(() => openai.chat.completions.create({
244
+ model: effectiveModel,
245
+ messages: [
246
+ { role: 'system', content: systemPrompt },
247
+ { role: 'user', content: userPrompt },
248
+ ],
249
+ response_format: { type: 'json_object' },
250
+ max_tokens: 4000,
251
+ temperature: 0.3,
252
+ }));
253
+ const content = response.choices[0]?.message?.content;
254
+ if (!content) {
255
+ throw new AgentError('Empty response from OpenAI', AgentErrorCode.EXECUTION_FAILED, {
256
+ agentId: this.id,
257
+ phase: 'response-extraction',
258
+ });
259
+ }
260
+ const result = JSON.parse(content);
261
+ const findings = [];
262
+ for (const finding of result.findings || []) {
263
+ findings.push({
264
+ severity: mapSeverity(finding.severity),
265
+ file: finding.file,
266
+ line: finding.line,
267
+ message: finding.message,
268
+ suggestion: finding.suggestion,
269
+ ruleId: `semantic/${finding.category}`,
270
+ sourceAgent: this.id,
271
+ });
272
+ }
273
+ const tokensUsed = response.usage?.total_tokens || estimatedInputTokens;
274
+ const promptTokens = response.usage?.prompt_tokens || estimatedInputTokens;
275
+ const completionTokens = response.usage?.completion_tokens || 0;
276
+ const estimatedCostUsd = (promptTokens / 1000) * 0.00015 + (completionTokens / 1000) * 0.0006;
277
+ return AgentSuccess({
278
+ agentId: this.id,
279
+ findings,
280
+ metrics: {
281
+ durationMs: Date.now() - startTime,
282
+ filesProcessed: supportedFiles.length,
283
+ tokensUsed,
284
+ estimatedCostUsd,
285
+ },
286
+ });
287
+ }
288
+ catch (error) {
289
+ // Convert to AgentError for consistent error handling
290
+ const agentError = error instanceof AgentError
291
+ ? error
292
+ : new AgentError(error instanceof Error ? error.message : 'Unknown OpenAI error', AgentErrorCode.EXECUTION_FAILED, { agentId: this.id, phase: 'openai-call' });
293
+ return AgentFailure({
294
+ agentId: this.id,
295
+ error: agentError.message,
296
+ failureStage: 'exec',
297
+ metrics: {
298
+ durationMs: Date.now() - startTime,
299
+ filesProcessed: 0,
300
+ tokensUsed: estimatedInputTokens,
301
+ },
302
+ });
303
+ }
304
+ },
305
+ };
306
+ function mapSeverity(severity) {
307
+ switch (severity) {
308
+ case 'critical':
309
+ case 'high':
310
+ return 'error';
311
+ case 'medium':
312
+ return 'warning';
313
+ default:
314
+ return 'info';
315
+ }
316
+ }
317
+ //# sourceMappingURL=ai_semantic_review.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai_semantic_review.js","sourceRoot":"","sources":["../../src/agents/ai_semantic_review.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,162 @@
1
+ /**
2
+ * Analysis Budget Management
3
+ *
4
+ * Tracks time and size limits during control flow analysis.
5
+ * Implements FR-018 (time budget), FR-019 (size budget), FR-020 (degraded mode),
6
+ * and FR-021 (graceful termination).
7
+ *
8
+ * Tasks: T061-T066
9
+ */
10
+ import type { BudgetStatus, AnalysisLogEntry } from './types.js';
11
+ import { type AnalysisLogger } from './logger.js';
12
+ /**
13
+ * Configuration for analysis budget limits
14
+ */
15
+ export interface BudgetConfig {
16
+ /** Maximum analysis duration in milliseconds (default: 300,000 = 5 min) */
17
+ maxDurationMs: number;
18
+ /** Maximum lines to analyze (default: 10,000) */
19
+ maxLinesChanged: number;
20
+ /** Maximum call depth for inter-procedural analysis (default: 5) */
21
+ maxCallDepth: number;
22
+ /** Maximum nodes to visit per traversal (default: 10,000) */
23
+ maxNodesVisited: number;
24
+ }
25
+ /**
26
+ * Default budget configuration per FR-018, FR-019, FR-003
27
+ */
28
+ export declare const DEFAULT_BUDGET_CONFIG: BudgetConfig;
29
+ /**
30
+ * File priority levels for degraded mode filtering.
31
+ */
32
+ export type FilePriority = 'high' | 'medium' | 'low';
33
+ /**
34
+ * Patterns for determining file priority.
35
+ * High priority: security-sensitive files (always analyze)
36
+ * Medium priority: business logic (analyze if budget allows)
37
+ * Low priority: tests, config (skip in degraded mode)
38
+ */
39
+ export declare const FILE_PRIORITY_PATTERNS: Record<FilePriority, RegExp[]>;
40
+ /**
41
+ * Determine the priority of a file based on its path.
42
+ */
43
+ export declare function getFilePriority(filePath: string): FilePriority;
44
+ /**
45
+ * Analysis Budget Manager
46
+ *
47
+ * Tracks resource consumption and triggers degraded mode when limits approach.
48
+ * Ensures deterministic behavior: same input always produces same degradation.
49
+ */
50
+ export declare class AnalysisBudget {
51
+ private readonly startTime;
52
+ private readonly config;
53
+ private linesAnalyzed;
54
+ private filesAnalyzed;
55
+ private filesSkipped;
56
+ private currentDepth;
57
+ private _status;
58
+ private degradedAt;
59
+ private readonly log;
60
+ private readonly logger;
61
+ constructor(config?: Partial<BudgetConfig>, logger?: AnalysisLogger);
62
+ /**
63
+ * Get current budget status
64
+ */
65
+ get status(): BudgetStatus;
66
+ /**
67
+ * Check if analysis is in degraded mode
68
+ */
69
+ get isDegraded(): boolean;
70
+ /**
71
+ * Get effective max call depth (reduced in degraded mode)
72
+ */
73
+ get effectiveMaxCallDepth(): number;
74
+ /**
75
+ * Get elapsed time in milliseconds
76
+ */
77
+ get elapsedMs(): number;
78
+ /**
79
+ * Get time remaining before budget exceeded
80
+ */
81
+ get remainingMs(): number;
82
+ /**
83
+ * Get percentage of time budget consumed
84
+ */
85
+ get timePercentUsed(): number;
86
+ /**
87
+ * Get percentage of size budget consumed
88
+ */
89
+ get sizePercentUsed(): number;
90
+ /**
91
+ * Get analysis statistics
92
+ */
93
+ get stats(): {
94
+ linesAnalyzed: number;
95
+ filesAnalyzed: number;
96
+ filesSkipped: number;
97
+ elapsedMs: number;
98
+ status: BudgetStatus;
99
+ degraded: boolean;
100
+ timePercentUsed: number;
101
+ sizePercentUsed: number;
102
+ };
103
+ /**
104
+ * Check if a file should be analyzed based on priority and budget status.
105
+ * Per FR-020: Skip low-priority files in degraded mode.
106
+ */
107
+ shouldAnalyzeFile(filePath: string): boolean;
108
+ /**
109
+ * Sort files by priority for analysis order.
110
+ * High priority files are analyzed first.
111
+ */
112
+ sortFilesByPriority<T extends {
113
+ path: string;
114
+ }>(files: T[]): T[];
115
+ /**
116
+ * Get the analysis log
117
+ */
118
+ get analysisLog(): AnalysisLogEntry[];
119
+ /**
120
+ * Record analysis of a file
121
+ */
122
+ recordFile(lineCount: number, _filePath?: string): void;
123
+ /**
124
+ * Set current call depth for inter-procedural analysis
125
+ */
126
+ setCallDepth(depth: number): void;
127
+ /**
128
+ * Check if we can go deeper in call analysis
129
+ */
130
+ canGoDeeper(): boolean;
131
+ /**
132
+ * Check budget status and update if needed
133
+ * Returns the current status after check
134
+ */
135
+ checkBudget(): BudgetStatus;
136
+ /**
137
+ * Transition to a new budget status
138
+ */
139
+ private transitionTo;
140
+ /**
141
+ * Add an entry to the analysis log
142
+ */
143
+ addLog(level: AnalysisLogEntry['level'], message: string, context?: Record<string, unknown>): void;
144
+ /**
145
+ * Check if analysis should continue
146
+ * Returns false if budget is terminated
147
+ */
148
+ shouldContinue(): boolean;
149
+ /**
150
+ * Get reason for degradation (if degraded)
151
+ */
152
+ getDegradedReason(): string | undefined;
153
+ /**
154
+ * Create a snapshot of current budget state for finding metadata
155
+ */
156
+ toFindingMetadata(): {
157
+ analysisDepth: number;
158
+ degraded: boolean;
159
+ degradedReason?: string;
160
+ };
161
+ }
162
+ //# sourceMappingURL=budget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"budget.d.ts","sourceRoot":"","sources":["../../../src/agents/control_flow/budget.ts"],"names":[],"mappings":"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"}