ghagga-core 2.8.0 → 2.9.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 (316) hide show
  1. package/dist/acp/adapter.d.ts +91 -0
  2. package/dist/acp/adapter.d.ts.map +1 -0
  3. package/dist/acp/adapter.js +315 -0
  4. package/dist/acp/adapter.js.map +1 -0
  5. package/dist/acp/index.d.ts +4 -0
  6. package/dist/acp/index.d.ts.map +1 -0
  7. package/dist/acp/index.js +2 -0
  8. package/dist/acp/index.js.map +1 -0
  9. package/dist/acp/types.d.ts +142 -0
  10. package/dist/acp/types.d.ts.map +1 -0
  11. package/dist/acp/types.js +13 -0
  12. package/dist/acp/types.js.map +1 -0
  13. package/dist/adversarial-qa.d.ts +60 -0
  14. package/dist/adversarial-qa.d.ts.map +1 -0
  15. package/dist/adversarial-qa.js +85 -0
  16. package/dist/adversarial-qa.js.map +1 -0
  17. package/dist/agents/audit.d.ts +18 -0
  18. package/dist/agents/audit.d.ts.map +1 -0
  19. package/dist/agents/audit.js +78 -0
  20. package/dist/agents/audit.js.map +1 -0
  21. package/dist/agents/consensus.d.ts +1 -1
  22. package/dist/agents/consensus.d.ts.map +1 -1
  23. package/dist/agents/consensus.js +10 -8
  24. package/dist/agents/consensus.js.map +1 -1
  25. package/dist/agents/diagnostic.d.ts.map +1 -1
  26. package/dist/agents/diagnostic.js +22 -20
  27. package/dist/agents/diagnostic.js.map +1 -1
  28. package/dist/agents/fan-out-lenses.d.ts +41 -0
  29. package/dist/agents/fan-out-lenses.d.ts.map +1 -1
  30. package/dist/agents/fan-out-lenses.js +117 -3
  31. package/dist/agents/fan-out-lenses.js.map +1 -1
  32. package/dist/agents/prompts.d.ts +12 -0
  33. package/dist/agents/prompts.d.ts.map +1 -1
  34. package/dist/agents/prompts.js +31 -0
  35. package/dist/agents/prompts.js.map +1 -1
  36. package/dist/agents/simple.d.ts +1 -1
  37. package/dist/agents/simple.d.ts.map +1 -1
  38. package/dist/agents/simple.js +10 -6
  39. package/dist/agents/simple.js.map +1 -1
  40. package/dist/agents/workflow.d.ts +1 -1
  41. package/dist/agents/workflow.d.ts.map +1 -1
  42. package/dist/agents/workflow.js +9 -8
  43. package/dist/agents/workflow.js.map +1 -1
  44. package/dist/aisvs.d.ts +44 -0
  45. package/dist/aisvs.d.ts.map +1 -0
  46. package/dist/aisvs.js +189 -0
  47. package/dist/aisvs.js.map +1 -0
  48. package/dist/checklist/context.d.ts.map +1 -1
  49. package/dist/checklist/context.js +2 -8
  50. package/dist/checklist/context.js.map +1 -1
  51. package/dist/checklist/defaults.d.ts.map +1 -1
  52. package/dist/checklist/defaults.js.map +1 -1
  53. package/dist/checklist/scorer.d.ts.map +1 -1
  54. package/dist/checklist/scorer.js +105 -12
  55. package/dist/checklist/scorer.js.map +1 -1
  56. package/dist/code-intel/client.d.ts +30 -0
  57. package/dist/code-intel/client.d.ts.map +1 -0
  58. package/dist/code-intel/client.js +91 -0
  59. package/dist/code-intel/client.js.map +1 -0
  60. package/dist/code-intel/context.d.ts +21 -0
  61. package/dist/code-intel/context.d.ts.map +1 -0
  62. package/dist/code-intel/context.js +72 -0
  63. package/dist/code-intel/context.js.map +1 -0
  64. package/dist/code-intel/index.d.ts +10 -0
  65. package/dist/code-intel/index.d.ts.map +1 -0
  66. package/dist/code-intel/index.js +11 -0
  67. package/dist/code-intel/index.js.map +1 -0
  68. package/dist/code-intel/types.d.ts +63 -0
  69. package/dist/code-intel/types.d.ts.map +1 -0
  70. package/dist/code-intel/types.js +9 -0
  71. package/dist/code-intel/types.js.map +1 -0
  72. package/dist/compress/index.d.ts +55 -0
  73. package/dist/compress/index.d.ts.map +1 -0
  74. package/dist/compress/index.js +166 -0
  75. package/dist/compress/index.js.map +1 -0
  76. package/dist/cost-footer.d.ts +38 -0
  77. package/dist/cost-footer.d.ts.map +1 -0
  78. package/dist/cost-footer.js +95 -0
  79. package/dist/cost-footer.js.map +1 -0
  80. package/dist/critique/critique.d.ts +40 -0
  81. package/dist/critique/critique.d.ts.map +1 -0
  82. package/dist/critique/critique.js +194 -0
  83. package/dist/critique/critique.js.map +1 -0
  84. package/dist/critique/cross-model.d.ts +123 -0
  85. package/dist/critique/cross-model.d.ts.map +1 -0
  86. package/dist/critique/cross-model.js +267 -0
  87. package/dist/critique/cross-model.js.map +1 -0
  88. package/dist/critique/index.d.ts +8 -0
  89. package/dist/critique/index.d.ts.map +1 -0
  90. package/dist/critique/index.js +6 -0
  91. package/dist/critique/index.js.map +1 -0
  92. package/dist/critique/prompts.d.ts +11 -0
  93. package/dist/critique/prompts.d.ts.map +1 -0
  94. package/dist/critique/prompts.js +66 -0
  95. package/dist/critique/prompts.js.map +1 -0
  96. package/dist/critique/types.d.ts +84 -0
  97. package/dist/critique/types.d.ts.map +1 -0
  98. package/dist/critique/types.js +13 -0
  99. package/dist/critique/types.js.map +1 -0
  100. package/dist/doc-validation/index.d.ts +9 -0
  101. package/dist/doc-validation/index.d.ts.map +1 -0
  102. package/dist/doc-validation/index.js +9 -0
  103. package/dist/doc-validation/index.js.map +1 -0
  104. package/dist/doc-validation/scanner.d.ts +40 -0
  105. package/dist/doc-validation/scanner.d.ts.map +1 -0
  106. package/dist/doc-validation/scanner.js +163 -0
  107. package/dist/doc-validation/scanner.js.map +1 -0
  108. package/dist/doc-validation/types.d.ts +27 -0
  109. package/dist/doc-validation/types.d.ts.map +1 -0
  110. package/dist/doc-validation/types.js +8 -0
  111. package/dist/doc-validation/types.js.map +1 -0
  112. package/dist/embed.d.ts +27 -0
  113. package/dist/embed.d.ts.map +1 -0
  114. package/dist/embed.js +47 -0
  115. package/dist/embed.js.map +1 -0
  116. package/dist/enhance/enhance.d.ts.map +1 -1
  117. package/dist/enhance/enhance.js +7 -25
  118. package/dist/enhance/enhance.js.map +1 -1
  119. package/dist/enhance/types.d.ts +5 -0
  120. package/dist/enhance/types.d.ts.map +1 -1
  121. package/dist/exploitability/analyzer.d.ts +42 -0
  122. package/dist/exploitability/analyzer.d.ts.map +1 -1
  123. package/dist/exploitability/analyzer.js +225 -0
  124. package/dist/exploitability/analyzer.js.map +1 -1
  125. package/dist/exploitability/index.d.ts +3 -2
  126. package/dist/exploitability/index.d.ts.map +1 -1
  127. package/dist/exploitability/index.js +1 -2
  128. package/dist/exploitability/index.js.map +1 -1
  129. package/dist/exploitability/types.d.ts +27 -0
  130. package/dist/exploitability/types.d.ts.map +1 -1
  131. package/dist/fetch-fix.d.ts +60 -0
  132. package/dist/fetch-fix.d.ts.map +1 -0
  133. package/dist/fetch-fix.js +137 -0
  134. package/dist/fetch-fix.js.map +1 -0
  135. package/dist/flood/index.d.ts +34 -0
  136. package/dist/flood/index.d.ts.map +1 -0
  137. package/dist/flood/index.js +67 -0
  138. package/dist/flood/index.js.map +1 -0
  139. package/dist/format.d.ts.map +1 -1
  140. package/dist/format.js +6 -1
  141. package/dist/format.js.map +1 -1
  142. package/dist/graph/blast-radius.js +2 -2
  143. package/dist/graph/blast-radius.js.map +1 -1
  144. package/dist/graph/call-chain.d.ts +36 -0
  145. package/dist/graph/call-chain.d.ts.map +1 -0
  146. package/dist/graph/call-chain.js +291 -0
  147. package/dist/graph/call-chain.js.map +1 -0
  148. package/dist/graph/index.d.ts +4 -0
  149. package/dist/graph/index.d.ts.map +1 -1
  150. package/dist/graph/index.js +2 -0
  151. package/dist/graph/index.js.map +1 -1
  152. package/dist/graph/reverse-deps.d.ts +37 -0
  153. package/dist/graph/reverse-deps.d.ts.map +1 -0
  154. package/dist/graph/reverse-deps.js +136 -0
  155. package/dist/graph/reverse-deps.js.map +1 -0
  156. package/dist/index.d.ts +50 -11
  157. package/dist/index.d.ts.map +1 -1
  158. package/dist/index.js +34 -7
  159. package/dist/index.js.map +1 -1
  160. package/dist/injection-corpus.d.ts +41 -0
  161. package/dist/injection-corpus.d.ts.map +1 -0
  162. package/dist/injection-corpus.js +181 -0
  163. package/dist/injection-corpus.js.map +1 -0
  164. package/dist/latent-comms.d.ts +31 -0
  165. package/dist/latent-comms.d.ts.map +1 -0
  166. package/dist/latent-comms.js +139 -0
  167. package/dist/latent-comms.js.map +1 -0
  168. package/dist/memory/pageindex/chunker.d.ts +33 -0
  169. package/dist/memory/pageindex/chunker.d.ts.map +1 -0
  170. package/dist/memory/pageindex/chunker.js +112 -0
  171. package/dist/memory/pageindex/chunker.js.map +1 -0
  172. package/dist/memory/pageindex/example.d.ts +22 -0
  173. package/dist/memory/pageindex/example.d.ts.map +1 -0
  174. package/dist/memory/pageindex/example.js +94 -0
  175. package/dist/memory/pageindex/example.js.map +1 -0
  176. package/dist/memory/pageindex/index.d.ts +15 -0
  177. package/dist/memory/pageindex/index.d.ts.map +1 -0
  178. package/dist/memory/pageindex/index.js +17 -0
  179. package/dist/memory/pageindex/index.js.map +1 -0
  180. package/dist/memory/pageindex/service.d.ts +53 -0
  181. package/dist/memory/pageindex/service.d.ts.map +1 -0
  182. package/dist/memory/pageindex/service.js +229 -0
  183. package/dist/memory/pageindex/service.js.map +1 -0
  184. package/dist/memory/pageindex/types.d.ts +67 -0
  185. package/dist/memory/pageindex/types.d.ts.map +1 -0
  186. package/dist/memory/pageindex/types.js +14 -0
  187. package/dist/memory/pageindex/types.js.map +1 -0
  188. package/dist/memory/persist.d.ts.map +1 -1
  189. package/dist/memory/persist.js +6 -2
  190. package/dist/memory/persist.js.map +1 -1
  191. package/dist/memory/sqlite.d.ts +69 -2
  192. package/dist/memory/sqlite.d.ts.map +1 -1
  193. package/dist/memory/sqlite.js +312 -5
  194. package/dist/memory/sqlite.js.map +1 -1
  195. package/dist/memory/taxonomy.d.ts +34 -0
  196. package/dist/memory/taxonomy.d.ts.map +1 -0
  197. package/dist/memory/taxonomy.js +189 -0
  198. package/dist/memory/taxonomy.js.map +1 -0
  199. package/dist/memory/versioning.d.ts.map +1 -1
  200. package/dist/memory/versioning.js.map +1 -1
  201. package/dist/negative.d.ts +23 -0
  202. package/dist/negative.d.ts.map +1 -0
  203. package/dist/negative.js +40 -0
  204. package/dist/negative.js.map +1 -0
  205. package/dist/pipeline.d.ts.map +1 -1
  206. package/dist/pipeline.js +455 -46
  207. package/dist/pipeline.js.map +1 -1
  208. package/dist/prompt-intel.d.ts +39 -0
  209. package/dist/prompt-intel.d.ts.map +1 -0
  210. package/dist/prompt-intel.js +148 -0
  211. package/dist/prompt-intel.js.map +1 -0
  212. package/dist/providers/cli-bridge.d.ts +4 -0
  213. package/dist/providers/cli-bridge.d.ts.map +1 -1
  214. package/dist/providers/cli-bridge.js +4 -0
  215. package/dist/providers/cli-bridge.js.map +1 -1
  216. package/dist/providers/generate-fn.d.ts +3 -15
  217. package/dist/providers/generate-fn.d.ts.map +1 -1
  218. package/dist/providers/generate-fn.js +3 -30
  219. package/dist/providers/generate-fn.js.map +1 -1
  220. package/dist/providers/index.d.ts.map +1 -1
  221. package/dist/providers/index.js.map +1 -1
  222. package/dist/providers/ollama.d.ts +15 -0
  223. package/dist/providers/ollama.d.ts.map +1 -0
  224. package/dist/providers/ollama.js +30 -0
  225. package/dist/providers/ollama.js.map +1 -0
  226. package/dist/ranking/index.d.ts +9 -0
  227. package/dist/ranking/index.d.ts.map +1 -0
  228. package/dist/ranking/index.js +82 -0
  229. package/dist/ranking/index.js.map +1 -0
  230. package/dist/recursive/circuit-breaker.d.ts +36 -0
  231. package/dist/recursive/circuit-breaker.d.ts.map +1 -0
  232. package/dist/recursive/circuit-breaker.js +62 -0
  233. package/dist/recursive/circuit-breaker.js.map +1 -0
  234. package/dist/recursive/index.d.ts +4 -0
  235. package/dist/recursive/index.d.ts.map +1 -1
  236. package/dist/recursive/index.js +18 -1
  237. package/dist/recursive/index.js.map +1 -1
  238. package/dist/recursive/types.d.ts +2 -0
  239. package/dist/recursive/types.d.ts.map +1 -1
  240. package/dist/recursive/types.js +1 -0
  241. package/dist/recursive/types.js.map +1 -1
  242. package/dist/scope/diff-mapper.js.map +1 -1
  243. package/dist/scope/entity-diff.d.ts +58 -0
  244. package/dist/scope/entity-diff.d.ts.map +1 -0
  245. package/dist/scope/entity-diff.js +224 -0
  246. package/dist/scope/entity-diff.js.map +1 -0
  247. package/dist/scope/extractor.d.ts.map +1 -1
  248. package/dist/scope/extractor.js.map +1 -1
  249. package/dist/scope/index.d.ts +3 -1
  250. package/dist/scope/index.d.ts.map +1 -1
  251. package/dist/scope/index.js +3 -0
  252. package/dist/scope/index.js.map +1 -1
  253. package/dist/scope/parser.d.ts +1 -1
  254. package/dist/scope/parser.d.ts.map +1 -1
  255. package/dist/scope/parser.js.map +1 -1
  256. package/dist/scope/types.d.ts +32 -0
  257. package/dist/scope/types.d.ts.map +1 -1
  258. package/dist/scope/types.js +7 -1
  259. package/dist/scope/types.js.map +1 -1
  260. package/dist/search/index.d.ts +11 -0
  261. package/dist/search/index.d.ts.map +1 -0
  262. package/dist/search/index.js +10 -0
  263. package/dist/search/index.js.map +1 -0
  264. package/dist/search/indexer.d.ts +67 -0
  265. package/dist/search/indexer.d.ts.map +1 -0
  266. package/dist/search/indexer.js +196 -0
  267. package/dist/search/indexer.js.map +1 -0
  268. package/dist/search/searcher.d.ts +34 -0
  269. package/dist/search/searcher.d.ts.map +1 -0
  270. package/dist/search/searcher.js +101 -0
  271. package/dist/search/searcher.js.map +1 -0
  272. package/dist/search/types.d.ts +81 -0
  273. package/dist/search/types.d.ts.map +1 -0
  274. package/dist/search/types.js +8 -0
  275. package/dist/search/types.js.map +1 -0
  276. package/dist/self-improve/index.d.ts +53 -0
  277. package/dist/self-improve/index.d.ts.map +1 -0
  278. package/dist/self-improve/index.js +136 -0
  279. package/dist/self-improve/index.js.map +1 -0
  280. package/dist/semantic-diff/index.d.ts +31 -0
  281. package/dist/semantic-diff/index.d.ts.map +1 -0
  282. package/dist/semantic-diff/index.js +215 -0
  283. package/dist/semantic-diff/index.js.map +1 -0
  284. package/dist/testing/index.d.ts +67 -0
  285. package/dist/testing/index.d.ts.map +1 -0
  286. package/dist/testing/index.js +76 -0
  287. package/dist/testing/index.js.map +1 -0
  288. package/dist/testing/vitest-helpers.d.ts +26 -0
  289. package/dist/testing/vitest-helpers.d.ts.map +1 -0
  290. package/dist/testing/vitest-helpers.js +37 -0
  291. package/dist/testing/vitest-helpers.js.map +1 -0
  292. package/dist/tools/index.d.ts +3 -1
  293. package/dist/tools/index.d.ts.map +1 -1
  294. package/dist/tools/index.js +2 -1
  295. package/dist/tools/index.js.map +1 -1
  296. package/dist/tools/remote-query.d.ts +40 -0
  297. package/dist/tools/remote-query.d.ts.map +1 -0
  298. package/dist/tools/remote-query.js +71 -0
  299. package/dist/tools/remote-query.js.map +1 -0
  300. package/dist/tracing/index.d.ts +39 -0
  301. package/dist/tracing/index.d.ts.map +1 -0
  302. package/dist/tracing/index.js +70 -0
  303. package/dist/tracing/index.js.map +1 -0
  304. package/dist/trajectory.d.ts +65 -0
  305. package/dist/trajectory.d.ts.map +1 -0
  306. package/dist/trajectory.js +126 -0
  307. package/dist/trajectory.js.map +1 -0
  308. package/dist/trust/index.d.ts +34 -0
  309. package/dist/trust/index.d.ts.map +1 -0
  310. package/dist/trust/index.js +78 -0
  311. package/dist/trust/index.js.map +1 -0
  312. package/dist/types.d.ts +144 -5
  313. package/dist/types.d.ts.map +1 -1
  314. package/dist/types.js +2 -11
  315. package/dist/types.js.map +1 -1
  316. package/package.json +1 -3
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Context compression for static analysis tool output.
3
+ *
4
+ * Static analysis tools often return redundant, verbose output.
5
+ * This module compresses tool findings BEFORE sending to the LLM
6
+ * to reduce token usage while preserving the most important information.
7
+ */
8
+ export interface CompressionResult {
9
+ original: string;
10
+ compressed: string;
11
+ reductionPercent: number;
12
+ droppedCount: number;
13
+ }
14
+ export interface ToolFinding {
15
+ tool: string;
16
+ file: string;
17
+ line?: number;
18
+ message: string;
19
+ severity?: string;
20
+ }
21
+ export interface CompressOptions {
22
+ /** Max findings per file (default: 5) */
23
+ maxPerFile?: number;
24
+ /** Max findings per tool (default: 20) */
25
+ maxPerTool?: number;
26
+ /** Deduplicate by message prefix (default: true) */
27
+ deduplicateMessages?: boolean;
28
+ /** Rough token budget — 1 token ≈ 4 chars (default: 4000) */
29
+ maxTotalTokens?: number;
30
+ }
31
+ /**
32
+ * Compress a list of tool findings using deduplication, per-tool and per-file caps,
33
+ * and a total token budget guard.
34
+ *
35
+ * @param findings - Raw findings from static analysis tools
36
+ * @param opts - Compression options
37
+ * @returns Compressed finding list + stats
38
+ */
39
+ export declare function compressToolFindings(findings: ToolFinding[], opts?: CompressOptions): {
40
+ findings: ToolFinding[];
41
+ stats: CompressionResult;
42
+ };
43
+ /**
44
+ * Compress a raw static analysis block (string output from a tool).
45
+ *
46
+ * Finds repeated patterns — lines that are identical except for line numbers —
47
+ * and collapses them into "... and N similar issues". Returns a compressed string
48
+ * with reduction stats.
49
+ *
50
+ * @param rawOutput - Raw string output from a static analysis tool
51
+ * @param maxTokens - Max token budget (1 token ≈ 4 chars). Default: 4000
52
+ * @returns Compression result with original, compressed, and stats
53
+ */
54
+ export declare function compressStaticAnalysisBlock(rawOutput: string, maxTokens?: number): CompressionResult;
55
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/compress/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,yCAAyC;IACzC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0CAA0C;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oDAAoD;IACpD,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,6DAA6D;IAC7D,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAsBD;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,WAAW,EAAE,EACvB,IAAI,CAAC,EAAE,eAAe,GACrB;IAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;IAAC,KAAK,EAAE,iBAAiB,CAAA;CAAE,CA8EvD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,2BAA2B,CACzC,SAAS,EAAE,MAAM,EACjB,SAAS,SAAO,GACf,iBAAiB,CAyDnB"}
@@ -0,0 +1,166 @@
1
+ /**
2
+ * Context compression for static analysis tool output.
3
+ *
4
+ * Static analysis tools often return redundant, verbose output.
5
+ * This module compresses tool findings BEFORE sending to the LLM
6
+ * to reduce token usage while preserving the most important information.
7
+ */
8
+ // ─── Severity ordering ───────────────────────────────────────────
9
+ const SEVERITY_ORDER = {
10
+ critical: 0,
11
+ error: 1,
12
+ high: 2,
13
+ medium: 3,
14
+ warning: 4,
15
+ low: 5,
16
+ info: 6,
17
+ note: 7,
18
+ };
19
+ function severityRank(severity) {
20
+ if (!severity)
21
+ return 99;
22
+ return SEVERITY_ORDER[severity.toLowerCase()] ?? 99;
23
+ }
24
+ // ─── Core Functions ──────────────────────────────────────────────
25
+ /**
26
+ * Compress a list of tool findings using deduplication, per-tool and per-file caps,
27
+ * and a total token budget guard.
28
+ *
29
+ * @param findings - Raw findings from static analysis tools
30
+ * @param opts - Compression options
31
+ * @returns Compressed finding list + stats
32
+ */
33
+ export function compressToolFindings(findings, opts) {
34
+ const maxPerFile = opts?.maxPerFile ?? 5;
35
+ const maxPerTool = opts?.maxPerTool ?? 20;
36
+ const dedup = opts?.deduplicateMessages ?? true;
37
+ const maxTotalTokens = opts?.maxTotalTokens ?? 4000;
38
+ const maxTotalChars = maxTotalTokens * 4;
39
+ const originalCount = findings.length;
40
+ // ── Step 1: Group by tool ──────────────────────────────────
41
+ const byTool = new Map();
42
+ for (const finding of findings) {
43
+ const list = byTool.get(finding.tool) ?? [];
44
+ list.push(finding);
45
+ byTool.set(finding.tool, list);
46
+ }
47
+ const compressed = [];
48
+ for (const [, toolFindings] of byTool) {
49
+ // ── Step 2: Deduplicate by message prefix (first 60 chars) ──
50
+ let deduped = toolFindings;
51
+ if (dedup) {
52
+ const seen = new Set();
53
+ deduped = toolFindings.filter((f) => {
54
+ const prefix = f.message.slice(0, 60);
55
+ if (seen.has(prefix))
56
+ return false;
57
+ seen.add(prefix);
58
+ return true;
59
+ });
60
+ }
61
+ // ── Step 3: Sort by severity (highest first) then cap per tool ──
62
+ const sorted = [...deduped].sort((a, b) => severityRank(a.severity) - severityRank(b.severity));
63
+ const cappedByTool = sorted.slice(0, maxPerTool);
64
+ // ── Step 4: Cap per file within remaining findings ──────────
65
+ const byFile = new Map();
66
+ for (const finding of cappedByTool) {
67
+ const list = byFile.get(finding.file) ?? [];
68
+ list.push(finding);
69
+ byFile.set(finding.file, list);
70
+ }
71
+ for (const fileFindings of byFile.values()) {
72
+ compressed.push(...fileFindings.slice(0, maxPerFile));
73
+ }
74
+ }
75
+ // ── Step 5: Token budget guard ──────────────────────────────
76
+ const roughSize = (f) => (f.tool + f.file + (f.message ?? '')).length + 30;
77
+ let totalChars = 0;
78
+ const budgeted = [];
79
+ for (const f of compressed) {
80
+ const size = roughSize(f);
81
+ if (totalChars + size > maxTotalChars)
82
+ break;
83
+ budgeted.push(f);
84
+ totalChars += size;
85
+ }
86
+ const droppedCount = originalCount - budgeted.length;
87
+ const originalStr = JSON.stringify(findings);
88
+ const compressedStr = JSON.stringify(budgeted);
89
+ const reductionPercent = originalStr.length > 0
90
+ ? Math.round(((originalStr.length - compressedStr.length) / originalStr.length) * 100)
91
+ : 0;
92
+ return {
93
+ findings: budgeted,
94
+ stats: {
95
+ original: originalStr,
96
+ compressed: compressedStr,
97
+ reductionPercent,
98
+ droppedCount,
99
+ },
100
+ };
101
+ }
102
+ /**
103
+ * Compress a raw static analysis block (string output from a tool).
104
+ *
105
+ * Finds repeated patterns — lines that are identical except for line numbers —
106
+ * and collapses them into "... and N similar issues". Returns a compressed string
107
+ * with reduction stats.
108
+ *
109
+ * @param rawOutput - Raw string output from a static analysis tool
110
+ * @param maxTokens - Max token budget (1 token ≈ 4 chars). Default: 4000
111
+ * @returns Compression result with original, compressed, and stats
112
+ */
113
+ export function compressStaticAnalysisBlock(rawOutput, maxTokens = 4000) {
114
+ const lines = rawOutput.split('\n');
115
+ // Strip line-number references to find structurally similar lines.
116
+ // E.g. "src/foo.ts:123: unused variable 'x'" → "src/foo.ts:XX: unused variable 'x'"
117
+ const normalize = (line) => line.replace(/:\d+/g, ':XX').replace(/\b\d+\b/g, 'N');
118
+ // Group consecutive similar lines
119
+ const groups = [];
120
+ for (const line of lines) {
121
+ const key = normalize(line);
122
+ const last = groups[groups.length - 1];
123
+ if (last && last.canonical === key) {
124
+ last.lines.push(line);
125
+ }
126
+ else {
127
+ groups.push({ canonical: key, lines: [line] });
128
+ }
129
+ }
130
+ // Collapse groups with multiple similar lines
131
+ const compressedLines = [];
132
+ for (const group of groups) {
133
+ if (group.lines.length === 1) {
134
+ const first = group.lines[0];
135
+ if (first !== undefined)
136
+ compressedLines.push(first);
137
+ }
138
+ else {
139
+ const first = group.lines[0];
140
+ if (first !== undefined) {
141
+ compressedLines.push(first);
142
+ compressedLines.push(` ... and ${group.lines.length - 1} similar issue(s)`);
143
+ }
144
+ }
145
+ }
146
+ let compressed = compressedLines.join('\n');
147
+ // Hard-cap to token budget
148
+ const maxChars = maxTokens * 4;
149
+ if (compressed.length > maxChars) {
150
+ const cutoff = compressed.lastIndexOf('\n', maxChars);
151
+ compressed =
152
+ (cutoff > 0 ? compressed.slice(0, cutoff) : compressed.slice(0, maxChars)) +
153
+ '\n[... output truncated to fit token budget ...]';
154
+ }
155
+ const droppedCount = lines.length - compressedLines.length;
156
+ const reductionPercent = rawOutput.length > 0
157
+ ? Math.round(((rawOutput.length - compressed.length) / rawOutput.length) * 100)
158
+ : 0;
159
+ return {
160
+ original: rawOutput,
161
+ compressed,
162
+ reductionPercent,
163
+ droppedCount,
164
+ };
165
+ }
166
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/compress/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Cost footer — calculates and formats review cost from token usage
3
+ * and model pricing. Appended to PR review comments so teams can
4
+ * track AI review spend.
5
+ */
6
+ export interface ModelPricing {
7
+ inputPerMTok: number;
8
+ outputPerMTok: number;
9
+ }
10
+ /**
11
+ * Approximate pricing per model family. Input/output split is estimated
12
+ * at 70/30 when only total tokens are available.
13
+ */
14
+ export declare const MODEL_PRICING: Record<string, ModelPricing>;
15
+ export declare function getModelPricing(model: string): ModelPricing | null;
16
+ export interface ReviewCost {
17
+ totalTokens: number;
18
+ estimatedInputTokens: number;
19
+ estimatedOutputTokens: number;
20
+ costUSD: number;
21
+ model: string;
22
+ pricingFound: boolean;
23
+ }
24
+ /**
25
+ * Estimate cost from total token count and model.
26
+ * When only total tokens are known (no input/output split),
27
+ * we estimate 70% input / 30% output based on typical review patterns.
28
+ */
29
+ export declare function calculateReviewCost(totalTokens: number, model: string, options?: {
30
+ inputTokens?: number;
31
+ outputTokens?: number;
32
+ }): ReviewCost;
33
+ /**
34
+ * Format cost as a compact footer line for PR comments.
35
+ * Returns empty string when tokens are 0 (static-only review).
36
+ */
37
+ export declare function formatCostFooter(cost: ReviewCost): string;
38
+ //# sourceMappingURL=cost-footer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cost-footer.d.ts","sourceRoot":"","sources":["../src/cost-footer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAiBtD,CAAC;AAEF,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAYlE;AAID,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,OAAO,CAAC;CACvB;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,GACxD,UAAU,CA6BZ;AAUD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAgBzD"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Cost footer — calculates and formats review cost from token usage
3
+ * and model pricing. Appended to PR review comments so teams can
4
+ * track AI review spend.
5
+ */
6
+ /**
7
+ * Approximate pricing per model family. Input/output split is estimated
8
+ * at 70/30 when only total tokens are available.
9
+ */
10
+ export const MODEL_PRICING = {
11
+ // Anthropic
12
+ 'claude-opus-4': { inputPerMTok: 15, outputPerMTok: 75 },
13
+ 'claude-sonnet-4': { inputPerMTok: 3, outputPerMTok: 15 },
14
+ 'claude-haiku-4': { inputPerMTok: 0.8, outputPerMTok: 4 },
15
+ 'claude-3.5-sonnet': { inputPerMTok: 3, outputPerMTok: 15 },
16
+ 'claude-3-haiku': { inputPerMTok: 0.25, outputPerMTok: 1.25 },
17
+ // OpenAI
18
+ 'gpt-4o': { inputPerMTok: 2.5, outputPerMTok: 10 },
19
+ 'gpt-4o-mini': { inputPerMTok: 0.15, outputPerMTok: 0.6 },
20
+ 'gpt-4-turbo': { inputPerMTok: 10, outputPerMTok: 30 },
21
+ // Google
22
+ 'gemini-2.5-pro': { inputPerMTok: 1.25, outputPerMTok: 10 },
23
+ 'gemini-2.5-flash': { inputPerMTok: 0.15, outputPerMTok: 0.6 },
24
+ // Groq (free tier — cost is effectively 0)
25
+ 'llama-3': { inputPerMTok: 0, outputPerMTok: 0 },
26
+ mixtral: { inputPerMTok: 0, outputPerMTok: 0 },
27
+ };
28
+ export function getModelPricing(model) {
29
+ // Direct match
30
+ if (MODEL_PRICING[model])
31
+ return MODEL_PRICING[model];
32
+ // Prefix match (handles version suffixes like claude-sonnet-4-20250514)
33
+ for (const [key, pricing] of Object.entries(MODEL_PRICING)) {
34
+ if (model.includes(key) || key.includes(model.split('-').slice(0, -1).join('-'))) {
35
+ return pricing;
36
+ }
37
+ }
38
+ return null;
39
+ }
40
+ /**
41
+ * Estimate cost from total token count and model.
42
+ * When only total tokens are known (no input/output split),
43
+ * we estimate 70% input / 30% output based on typical review patterns.
44
+ */
45
+ export function calculateReviewCost(totalTokens, model, options) {
46
+ const pricing = getModelPricing(model);
47
+ const inputTokens = options?.inputTokens ?? Math.round(totalTokens * 0.7);
48
+ const outputTokens = options?.outputTokens ?? Math.round(totalTokens * 0.3);
49
+ if (!pricing) {
50
+ return {
51
+ totalTokens,
52
+ estimatedInputTokens: inputTokens,
53
+ estimatedOutputTokens: outputTokens,
54
+ costUSD: 0,
55
+ model,
56
+ pricingFound: false,
57
+ };
58
+ }
59
+ const cost = (inputTokens / 1_000_000) * pricing.inputPerMTok +
60
+ (outputTokens / 1_000_000) * pricing.outputPerMTok;
61
+ return {
62
+ totalTokens,
63
+ estimatedInputTokens: inputTokens,
64
+ estimatedOutputTokens: outputTokens,
65
+ costUSD: Math.round(cost * 10000) / 10000,
66
+ model,
67
+ pricingFound: true,
68
+ };
69
+ }
70
+ // ── Formatting ──
71
+ function formatTokens(n) {
72
+ if (n >= 1_000_000)
73
+ return `${(n / 1_000_000).toFixed(1)}M`;
74
+ if (n >= 1_000)
75
+ return `${(n / 1_000).toFixed(0)}K`;
76
+ return String(n);
77
+ }
78
+ /**
79
+ * Format cost as a compact footer line for PR comments.
80
+ * Returns empty string when tokens are 0 (static-only review).
81
+ */
82
+ export function formatCostFooter(cost) {
83
+ if (cost.totalTokens === 0)
84
+ return '';
85
+ const tokens = formatTokens(cost.totalTokens);
86
+ if (!cost.pricingFound) {
87
+ return `\n<sub>📊 ${tokens} tokens · \`${cost.model}\` · pricing unavailable</sub>\n`;
88
+ }
89
+ if (cost.costUSD === 0) {
90
+ return `\n<sub>📊 ${tokens} tokens · \`${cost.model}\` · free tier</sub>\n`;
91
+ }
92
+ const dollars = cost.costUSD >= 1 ? `$${cost.costUSD.toFixed(2)}` : `$${cost.costUSD.toFixed(4)}`;
93
+ return `\n<sub>📊 ${tokens} tokens · ${dollars} · \`${cost.model}\`</sub>\n`;
94
+ }
95
+ //# sourceMappingURL=cost-footer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cost-footer.js","sourceRoot":"","sources":["../src/cost-footer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Dual-critique review loop implementation.
3
+ *
4
+ * 3-agent pattern: initial review → self-critique → refined review.
5
+ * The self-critique step catches overreactions, false positives, and
6
+ * vague findings, producing a higher-quality final review.
7
+ */
8
+ import type { GenerateTextFn } from '../providers/generate-fn.js';
9
+ import type { ProgressCallback, ReviewFinding, ReviewResult } from '../types.js';
10
+ import type { CritiqueResult, DualCritiqueInput, DualCritiqueResult } from './types.js';
11
+ /**
12
+ * Parse the self-critique agent's structured response.
13
+ *
14
+ * Extracts OVERALL_ASSESSMENT and individual CRITIQUES with
15
+ * FINDING_INDEX, VERDICT, REASONING, and optional SUGGESTED_SEVERITY.
16
+ */
17
+ export declare function parseCritiqueResponse(text: string): CritiqueResult;
18
+ /**
19
+ * Apply critique verdicts to the initial findings.
20
+ * Returns the filtered and adjusted findings.
21
+ */
22
+ export declare function applyCritique(findings: ReviewFinding[], critique: CritiqueResult): {
23
+ refined: ReviewFinding[];
24
+ removedCount: number;
25
+ adjustedCount: number;
26
+ };
27
+ /**
28
+ * Run the dual-critique review loop.
29
+ *
30
+ * Takes an already-completed initial review and runs it through
31
+ * the self-critique → refined review pipeline.
32
+ *
33
+ * @param initialReview - The initial review result from any agent mode
34
+ * @param input - Context needed for the critique agents
35
+ * @param generateFn - LLM generation function
36
+ * @param onProgress - Optional progress callback
37
+ * @returns DualCritiqueResult with refined findings
38
+ */
39
+ export declare function runDualCritique(initialReview: ReviewResult, input: DualCritiqueInput, generateFn: GenerateTextFn, onProgress?: ProgressCallback): Promise<DualCritiqueResult>;
40
+ //# sourceMappingURL=critique.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"critique.d.ts","sourceRoot":"","sources":["../../src/critique/critique.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,KAAK,EAAmB,gBAAgB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAElG,OAAO,KAAK,EACV,cAAc,EAGd,iBAAiB,EACjB,kBAAkB,EAEnB,MAAM,YAAY,CAAC;AAiBpB;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,CAwClE;AAoBD;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,aAAa,EAAE,EACzB,QAAQ,EAAE,cAAc,GACvB;IACD,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;CACvB,CA6CA;AAID;;;;;;;;;;;GAWG;AACH,wBAAsB,eAAe,CACnC,aAAa,EAAE,YAAY,EAC3B,KAAK,EAAE,iBAAiB,EACxB,UAAU,EAAE,cAAc,EAC1B,UAAU,CAAC,EAAE,gBAAgB,GAC5B,OAAO,CAAC,kBAAkB,CAAC,CAqF7B"}
@@ -0,0 +1,194 @@
1
+ /**
2
+ * Dual-critique review loop implementation.
3
+ *
4
+ * 3-agent pattern: initial review → self-critique → refined review.
5
+ * The self-critique step catches overreactions, false positives, and
6
+ * vague findings, producing a higher-quality final review.
7
+ */
8
+ import { REFINED_REVIEW_SYSTEM, SELF_CRITIQUE_SYSTEM } from './prompts.js';
9
+ import { DEFAULT_DUAL_CRITIQUE_CONFIG } from './types.js';
10
+ // ─── Constants ─────────────────────────────────────────────────
11
+ const VALID_VERDICTS = new Set([
12
+ 'valid',
13
+ 'false-positive',
14
+ 'overreaction',
15
+ 'vague',
16
+ 'redundant',
17
+ ]);
18
+ const VALID_SEVERITIES = new Set(['critical', 'high', 'medium', 'low', 'info']);
19
+ // ─── Critique Parser ───────────────────────────────────────────
20
+ /**
21
+ * Parse the self-critique agent's structured response.
22
+ *
23
+ * Extracts OVERALL_ASSESSMENT and individual CRITIQUES with
24
+ * FINDING_INDEX, VERDICT, REASONING, and optional SUGGESTED_SEVERITY.
25
+ */
26
+ export function parseCritiqueResponse(text) {
27
+ // Extract overall assessment
28
+ const assessmentMatch = /OVERALL_ASSESSMENT:\s*(.+?)(?:\n\s*CRITIQUES:|$)/is.exec(text);
29
+ const overallAssessment = assessmentMatch?.[1]?.trim() ?? 'Assessment could not be parsed.';
30
+ // Extract individual critiques
31
+ const critiques = [];
32
+ const critiquePattern = /- FINDING_INDEX:\s*(\d+)\s*\n\s*VERDICT:\s*(\S+)\s*\n\s*REASONING:\s*(.+?)(?:\n\s*SUGGESTED_SEVERITY:\s*(\S+))?(?=\n\s*- FINDING_INDEX:|\n*$)/gis;
33
+ let match = critiquePattern.exec(text);
34
+ while (match !== null) {
35
+ const findingIndex = parseInt(match[1], 10);
36
+ const rawVerdict = match[2]?.toLowerCase();
37
+ const verdict = VALID_VERDICTS.has(rawVerdict) ? rawVerdict : 'valid';
38
+ const reasoning = match[3]?.trim() ?? '';
39
+ const critique = { findingIndex, verdict, reasoning };
40
+ if (verdict === 'overreaction' && match[4]) {
41
+ const rawSeverity = match[4].toLowerCase();
42
+ if (VALID_SEVERITIES.has(rawSeverity)) {
43
+ critique.suggestedSeverity = rawSeverity;
44
+ }
45
+ }
46
+ critiques.push(critique);
47
+ match = critiquePattern.exec(text);
48
+ }
49
+ const falsePositiveCount = critiques.filter((c) => c.verdict === 'false-positive').length;
50
+ const overreactionCount = critiques.filter((c) => c.verdict === 'overreaction').length;
51
+ return {
52
+ critiques,
53
+ overallAssessment,
54
+ falsePositiveCount,
55
+ overreactionCount,
56
+ };
57
+ }
58
+ // ─── Finding Serializer ────────────────────────────────────────
59
+ /**
60
+ * Serialize findings into a text block for the critique agent.
61
+ */
62
+ function serializeFindingsForCritique(findings) {
63
+ if (findings.length === 0)
64
+ return '(no findings)';
65
+ return findings
66
+ .map((f, i) => `[${i}] ${f.severity.toUpperCase()} | ${f.category} | ${f.file}:${f.line ?? 'N/A'}\n ${f.message}${f.suggestion ? `\n Suggestion: ${f.suggestion}` : ''}`)
67
+ .join('\n\n');
68
+ }
69
+ // ─── Apply Critique ────────────────────────────────────────────
70
+ /**
71
+ * Apply critique verdicts to the initial findings.
72
+ * Returns the filtered and adjusted findings.
73
+ */
74
+ export function applyCritique(findings, critique) {
75
+ // Build a map of critique by finding index
76
+ const critiqueMap = new Map();
77
+ for (const c of critique.critiques) {
78
+ critiqueMap.set(c.findingIndex, c);
79
+ }
80
+ const refined = [];
81
+ let removedCount = 0;
82
+ let adjustedCount = 0;
83
+ for (let i = 0; i < findings.length; i++) {
84
+ const finding = findings[i];
85
+ const crit = critiqueMap.get(i);
86
+ if (!crit) {
87
+ // No critique for this finding — keep as-is
88
+ refined.push(finding);
89
+ continue;
90
+ }
91
+ switch (crit.verdict) {
92
+ case 'false-positive':
93
+ case 'redundant':
94
+ removedCount++;
95
+ break;
96
+ case 'overreaction':
97
+ if (crit.suggestedSeverity) {
98
+ refined.push({ ...finding, severity: crit.suggestedSeverity });
99
+ adjustedCount++;
100
+ }
101
+ else {
102
+ refined.push(finding);
103
+ }
104
+ break;
105
+ case 'vague':
106
+ case 'valid':
107
+ default:
108
+ refined.push(finding);
109
+ break;
110
+ }
111
+ }
112
+ return { refined, removedCount, adjustedCount };
113
+ }
114
+ // ─── Main Function ─────────────────────────────────────────────
115
+ /**
116
+ * Run the dual-critique review loop.
117
+ *
118
+ * Takes an already-completed initial review and runs it through
119
+ * the self-critique → refined review pipeline.
120
+ *
121
+ * @param initialReview - The initial review result from any agent mode
122
+ * @param input - Context needed for the critique agents
123
+ * @param generateFn - LLM generation function
124
+ * @param onProgress - Optional progress callback
125
+ * @returns DualCritiqueResult with refined findings
126
+ */
127
+ export async function runDualCritique(initialReview, input, generateFn, onProgress) {
128
+ const emit = onProgress ?? (() => { });
129
+ const config = {
130
+ ...DEFAULT_DUAL_CRITIQUE_CONFIG,
131
+ ...input.config,
132
+ };
133
+ const initialFindings = initialReview.findings.filter((f) => f.source === 'ai');
134
+ // Short-circuit: not enough findings to justify critique
135
+ if (initialFindings.length < config.minFindingsForCritique) {
136
+ emit({
137
+ step: 'dual-critique',
138
+ message: `Skipping critique — only ${initialFindings.length} AI finding(s) (min: ${config.minFindingsForCritique})`,
139
+ });
140
+ return {
141
+ status: initialReview.status,
142
+ summary: initialReview.summary,
143
+ findings: initialReview.findings,
144
+ };
145
+ }
146
+ // ── Step 1: Self-Critique ────────────────────────────────────
147
+ emit({
148
+ step: 'dual-critique',
149
+ message: `Running self-critique on ${initialFindings.length} AI finding(s)...`,
150
+ });
151
+ const critiquePrompt = `Here is the code diff:\n\n${input.diff}\n\nHere is the initial review with ${initialFindings.length} findings:\n\n${serializeFindingsForCritique(initialFindings)}\n\nPlease critique each finding.`;
152
+ const critiqueResponse = await generateFn(SELF_CRITIQUE_SYSTEM, critiquePrompt);
153
+ const critiqueResult = parseCritiqueResponse(critiqueResponse.text);
154
+ emit({
155
+ step: 'dual-critique',
156
+ message: `Critique complete: ${critiqueResult.falsePositiveCount} false positive(s), ${critiqueResult.overreactionCount} overreaction(s)`,
157
+ });
158
+ // ── Step 2: Apply Critique (deterministic) ───────────────────
159
+ // Apply the critique verdicts to filter/adjust findings
160
+ const { refined, removedCount, adjustedCount } = applyCritique(initialFindings, critiqueResult);
161
+ // Merge back non-AI findings (static analysis) untouched
162
+ const nonAiFindings = initialReview.findings.filter((f) => f.source !== 'ai');
163
+ const allRefinedFindings = [...refined, ...nonAiFindings];
164
+ emit({
165
+ step: 'dual-critique',
166
+ message: `Refined: ${removedCount} removed, ${adjustedCount} adjusted, ${refined.length} kept`,
167
+ });
168
+ // ── Step 3: Refined Summary ──────────────────────────────────
169
+ // Ask the LLM to produce a refined summary based on the surviving findings
170
+ const refinedPrompt = `Here is the code diff:\n\n${input.diff}\n\nInitial review summary: ${initialReview.summary}\n\nSelf-critique assessment: ${critiqueResult.overallAssessment}\n\nRemaining findings after critique (${refined.length}):\n${serializeFindingsForCritique(refined)}\n\nPlease produce the refined review.`;
171
+ const refinedResponse = await generateFn(REFINED_REVIEW_SYSTEM, refinedPrompt);
172
+ // Extract refined status and summary from response
173
+ const statusMatch = /STATUS:\s*(PASSED|FAILED|NEEDS_HUMAN_REVIEW|SKIPPED)/i.exec(refinedResponse.text);
174
+ const refinedStatus = statusMatch?.[1]?.toUpperCase() ?? initialReview.status;
175
+ const summaryMatch = /SUMMARY:\s*(.+?)(?:\n(?:FINDINGS:|$))/is.exec(refinedResponse.text);
176
+ const refinedSummary = summaryMatch?.[1]?.trim() ?? initialReview.summary;
177
+ // Build result
178
+ const result = {
179
+ status: refinedStatus,
180
+ summary: refinedSummary,
181
+ findings: allRefinedFindings,
182
+ };
183
+ if (config.includeCritiqueMetadata) {
184
+ result.critiqueMetadata = {
185
+ initialFindingCount: initialFindings.length,
186
+ finalFindingCount: refined.length,
187
+ removedAsFalsePositive: removedCount,
188
+ severityAdjusted: adjustedCount,
189
+ critiqueResult,
190
+ };
191
+ }
192
+ return result;
193
+ }
194
+ //# sourceMappingURL=critique.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"critique.js","sourceRoot":"","sources":["../../src/critique/critique.ts"],"names":[],"mappings":"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"}