agentic-qe 3.13.0 → 3.13.1

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 (378) hide show
  1. package/.agents/skills/aqe-plan-quality/SKILL.md +25 -0
  2. package/.agents/skills/aqe-plan-quality/agents/openai.yaml +4 -0
  3. package/.agents/skills/aqe-plan-quality/references/qe-routing.md +22 -0
  4. package/.agents/skills/aqe-review-quality/SKILL.md +24 -0
  5. package/.agents/skills/aqe-review-quality/agents/openai.yaml +4 -0
  6. package/.agents/skills/aqe-review-quality/references/quality-gates.md +20 -0
  7. package/.agents/skills/aqe-test-change/SKILL.md +26 -0
  8. package/.agents/skills/aqe-test-change/agents/openai.yaml +4 -0
  9. package/.agents/skills/aqe-test-change/references/test-specialties.md +23 -0
  10. package/.claude/helpers/ruflo-hook.cjs +5 -1
  11. package/.claude/skills/skills-manifest.json +1 -1
  12. package/.codex/hooks/aqe-codex-hook.cjs +69 -0
  13. package/.codex/hooks/ruflo-codex-hook.cjs +94 -0
  14. package/.codex/hooks.json +169 -0
  15. package/CHANGELOG.md +94 -0
  16. package/assets/skills/skills-manifest.json +1 -1
  17. package/dist/cli/bundle.js +5 -5
  18. package/dist/cli/chunks/adapter-VRZNL53W.js +2 -0
  19. package/dist/cli/chunks/{agent-booster-wasm-ACX2DK7Y.js → agent-booster-wasm-4VM3DE42.js} +2 -2
  20. package/dist/cli/chunks/{agent-handler-B45WP4ZJ.js → agent-handler-ZDLMZQQX.js} +2 -2
  21. package/dist/cli/chunks/{agent-memory-branch-QQLZDE56.js → agent-memory-branch-P72MDHHV.js} +2 -2
  22. package/dist/cli/chunks/aqe-learning-engine-XCNMNERX.js +2 -0
  23. package/dist/cli/chunks/{arena-G3IKZAG5.js → arena-55FZGKEV.js} +4 -4
  24. package/dist/cli/chunks/{arena-SDB7723R.js → arena-GCRBQ26R.js} +2 -2
  25. package/dist/cli/chunks/{audit-GY46XUZA.js → audit-VYAYVLIV.js} +3 -3
  26. package/dist/cli/chunks/base-VZZNR4UR.js +2 -0
  27. package/dist/cli/chunks/{hnswlib-node-RJPBJU2Q.js → better-sqlite3-JDDFYVCX.js} +2 -2
  28. package/dist/cli/chunks/{brain-handler-347CYMPN.js → brain-handler-IUKMRGWO.js} +3 -3
  29. package/dist/cli/chunks/{branch-enumerator-Z3ULBFSM.js → branch-enumerator-TUI3RWLX.js} +2 -2
  30. package/dist/cli/chunks/{browser-OYEIHD7F.js → browser-NBQTZYX2.js} +2 -2
  31. package/dist/cli/chunks/browser-workflow-5DZNIFUY.js +2 -0
  32. package/dist/cli/chunks/{chunk-2NRZYQSF.js → chunk-23MT7OBY.js} +2 -2
  33. package/dist/cli/chunks/{chunk-7UNY32PU.js → chunk-2CQAWYYE.js} +1 -1
  34. package/dist/cli/chunks/{chunk-ZLXBNNNT.js → chunk-2D2XFUKI.js} +2 -2
  35. package/dist/cli/chunks/{chunk-SHCTEXNH.js → chunk-2G2QWV7B.js} +2 -2
  36. package/dist/cli/chunks/{chunk-TZ73SXQ5.js → chunk-2ISLQU3G.js} +1 -1
  37. package/dist/cli/chunks/{chunk-VLNPJAVH.js → chunk-2OM3TDC4.js} +1 -1
  38. package/dist/cli/chunks/{chunk-JGM6XCCP.js → chunk-2XZ4BHWS.js} +1 -1
  39. package/dist/cli/chunks/{chunk-32ZGV4Q4.js → chunk-3F4XH4ZA.js} +1 -1
  40. package/dist/cli/chunks/{chunk-RDU4WTV2.js → chunk-3K4YC3GC.js} +2 -2
  41. package/dist/cli/chunks/chunk-3KGCBAUH.js +2 -0
  42. package/dist/cli/chunks/{chunk-DYUC7WFA.js → chunk-3Y6CHW67.js} +1 -1
  43. package/dist/cli/chunks/{chunk-3JVUWKCO.js → chunk-4QMWWYNU.js} +2 -2
  44. package/dist/cli/chunks/{chunk-L4LLA5U7.js → chunk-4WGSMODQ.js} +1 -1
  45. package/dist/cli/chunks/{chunk-KUA4HHU6.js → chunk-55WDVSCM.js} +2 -2
  46. package/dist/cli/chunks/{chunk-RVJPWRV6.js → chunk-5BB5DUL4.js} +2 -2
  47. package/dist/cli/chunks/{chunk-ZOXWASCC.js → chunk-6C3MZLYW.js} +2 -2
  48. package/dist/cli/chunks/{chunk-CFVEDUTW.js → chunk-6QKQFHS7.js} +2 -2
  49. package/dist/cli/chunks/{chunk-YFGAHNCG.js → chunk-6XZXMEK4.js} +3 -3
  50. package/dist/cli/chunks/{chunk-Z6QCOZ2H.js → chunk-7D7XFZZI.js} +2 -2
  51. package/dist/cli/chunks/{chunk-AO7AHX6K.js → chunk-7WEHZCSK.js} +2 -2
  52. package/dist/cli/chunks/{chunk-K5N6SLHO.js → chunk-A2MG3YXO.js} +1 -1
  53. package/dist/cli/chunks/{chunk-LXPB7H2P.js → chunk-AHTOWWSE.js} +1 -1
  54. package/dist/cli/chunks/{chunk-U2SW6KK5.js → chunk-AOMXMFDH.js} +2 -2
  55. package/dist/cli/chunks/{chunk-VSNRPMAZ.js → chunk-ARTLSAXO.js} +2 -2
  56. package/dist/cli/chunks/{chunk-FBBZHATF.js → chunk-AY7S7AWN.js} +1 -1
  57. package/dist/cli/chunks/{chunk-CYL2FV23.js → chunk-AYYDO52G.js} +2 -2
  58. package/dist/cli/chunks/chunk-BBLWZT5I.js +2 -0
  59. package/dist/cli/chunks/{chunk-QTU3CVOB.js → chunk-BF5BKSDU.js} +2 -2
  60. package/dist/cli/chunks/{chunk-CWUBOLKY.js → chunk-BOCEOLLJ.js} +2 -2
  61. package/dist/cli/chunks/{chunk-FL3BM54K.js → chunk-CE6LYEHT.js} +1 -1
  62. package/dist/cli/chunks/{chunk-THBTN7XB.js → chunk-CWP4RMOM.js} +2 -2
  63. package/dist/cli/chunks/{chunk-Q7PBGNUD.js → chunk-CWXDL7AH.js} +1 -1
  64. package/dist/cli/chunks/{chunk-RVRBTOWX.js → chunk-DTRFZD7N.js} +2 -2
  65. package/dist/cli/chunks/{chunk-IZRLIWFN.js → chunk-DVPGQG4W.js} +2 -2
  66. package/dist/cli/chunks/{chunk-3NOCK6ED.js → chunk-E4D47QTF.js} +2 -2
  67. package/dist/cli/chunks/{chunk-FQLWQWRU.js → chunk-EAKHU5YX.js} +3 -3
  68. package/dist/cli/chunks/{chunk-56WZFXTQ.js → chunk-EGMGOWCE.js} +2 -2
  69. package/dist/cli/chunks/{chunk-OXXMVQDF.js → chunk-ELMUHNXN.js} +2 -2
  70. package/dist/cli/chunks/{chunk-SNTUKW4Q.js → chunk-EVDYFGVH.js} +2 -2
  71. package/dist/cli/chunks/{chunk-RLCWR7TS.js → chunk-FDUSWM6O.js} +98 -88
  72. package/dist/cli/chunks/{chunk-D3MPV5G7.js → chunk-FM272B4O.js} +2 -2
  73. package/dist/cli/chunks/{chunk-DRIJYTSK.js → chunk-FQUUMC57.js} +2 -2
  74. package/dist/cli/chunks/{chunk-5KAT6WBQ.js → chunk-FQXQJMSF.js} +2 -2
  75. package/dist/cli/chunks/{chunk-BCKTBGDM.js → chunk-FRAGSKXQ.js} +3 -3
  76. package/dist/cli/chunks/{chunk-SRQ3CPJE.js → chunk-GASOBSNB.js} +4 -4
  77. package/dist/cli/chunks/{chunk-GTUFX7AR.js → chunk-GJEEPKAT.js} +2 -2
  78. package/dist/cli/chunks/{chunk-5EIOQCGN.js → chunk-GOV2MHLV.js} +2 -2
  79. package/dist/cli/chunks/{chunk-QI4CGJNK.js → chunk-GTPZVLL6.js} +1 -1
  80. package/dist/cli/chunks/chunk-H7YZ2YF2.js +3 -0
  81. package/dist/cli/chunks/{chunk-ANIDFJCT.js → chunk-HFI5PHG5.js} +3 -3
  82. package/dist/cli/chunks/{chunk-2VQVEQS4.js → chunk-HUMQU4ES.js} +2 -2
  83. package/dist/cli/chunks/{chunk-VHYMSZNF.js → chunk-HYIRFJDB.js} +2 -2
  84. package/dist/cli/chunks/{chunk-A4QLGPYO.js → chunk-IBSBOHUX.js} +2 -2
  85. package/dist/cli/chunks/{chunk-6SXKCIN5.js → chunk-IJA4WS7B.js} +1 -1
  86. package/dist/cli/chunks/{chunk-3GSYD5SL.js → chunk-IJP42OGW.js} +2 -2
  87. package/dist/cli/chunks/{chunk-PERJO2DY.js → chunk-IMQKEFW6.js} +1 -1
  88. package/dist/cli/chunks/{chunk-ZEIG5IQ4.js → chunk-INYS35DV.js} +2 -2
  89. package/dist/cli/chunks/{chunk-J3L52EA4.js → chunk-IV2VCR75.js} +5 -5
  90. package/dist/cli/chunks/{chunk-TVMFH5N2.js → chunk-IZO6TPGX.js} +2 -2
  91. package/dist/cli/chunks/{chunk-ZJG6N2OK.js → chunk-J45DX3IK.js} +1 -1
  92. package/dist/cli/chunks/{chunk-HL2QMM4M.js → chunk-J4T6D2OQ.js} +2 -2
  93. package/dist/cli/chunks/{chunk-5ICQL42E.js → chunk-JAPOMPFD.js} +2 -2
  94. package/dist/cli/chunks/{chunk-L2SFGFE6.js → chunk-JELNVHBF.js} +1 -1
  95. package/dist/cli/chunks/{chunk-RSFIOR2I.js → chunk-JOTNKZ7A.js} +87 -87
  96. package/dist/cli/chunks/{chunk-34PEINFS.js → chunk-KNWDXI3I.js} +2 -2
  97. package/dist/cli/chunks/{chunk-FUU32QY5.js → chunk-KW5NBORV.js} +2 -2
  98. package/dist/cli/chunks/{chunk-N5MMBA35.js → chunk-L7IOTWWY.js} +1 -1
  99. package/dist/cli/chunks/{chunk-RJZRWVL4.js → chunk-LJQ27PUE.js} +1 -1
  100. package/dist/cli/chunks/{chunk-QQB55ZJJ.js → chunk-LSKQUUUN.js} +2 -2
  101. package/dist/cli/chunks/{chunk-NETN3OUG.js → chunk-LSZZQ7H6.js} +1 -1
  102. package/dist/cli/chunks/{chunk-IYDYJ33J.js → chunk-LTKNCYMO.js} +2 -2
  103. package/dist/cli/chunks/{chunk-6DTOGSDV.js → chunk-LTWT4GZD.js} +4 -4
  104. package/dist/cli/chunks/{chunk-NQNKKVNO.js → chunk-LVHMXGDI.js} +3 -3
  105. package/dist/cli/chunks/{chunk-3UHEZ5HZ.js → chunk-M3T6FB54.js} +2 -2
  106. package/dist/cli/chunks/{chunk-ZJIX5FGQ.js → chunk-MAYZTGJ2.js} +2 -2
  107. package/dist/cli/chunks/{chunk-3K4SF57Q.js → chunk-MCIO7BDK.js} +1 -1
  108. package/dist/cli/chunks/{chunk-A7GLWWSE.js → chunk-MPD7RR4P.js} +1 -1
  109. package/dist/cli/chunks/{chunk-FAQLI3P5.js → chunk-MUFYDKVC.js} +2 -2
  110. package/dist/cli/chunks/{chunk-XFCWYQHW.js → chunk-MX5ZDKRR.js} +2 -2
  111. package/dist/cli/chunks/{chunk-MBCGI3M2.js → chunk-MXKHIZVM.js} +5 -5
  112. package/dist/cli/chunks/chunk-MY47CR27.js +2 -0
  113. package/dist/cli/chunks/chunk-N7WAZ2Y6.js +2 -0
  114. package/dist/cli/chunks/{chunk-VC6EXDGY.js → chunk-NHV4PTG6.js} +2 -2
  115. package/dist/cli/chunks/{chunk-LBE2P6UC.js → chunk-NP4CP3LR.js} +2 -2
  116. package/dist/cli/chunks/{chunk-6AOBLBR4.js → chunk-OCKTPTQ7.js} +2 -2
  117. package/dist/cli/chunks/{chunk-ES7WCYOU.js → chunk-OE4B6LDZ.js} +1 -1
  118. package/dist/cli/chunks/{chunk-IPHLXAMX.js → chunk-OPQY2333.js} +2 -2
  119. package/dist/cli/chunks/{chunk-7DMXCCSD.js → chunk-ORDH4VPL.js} +1 -1
  120. package/dist/cli/chunks/{chunk-HTPM3URI.js → chunk-P4Y3G6OB.js} +2 -2
  121. package/dist/cli/chunks/{chunk-TNRIGQ6U.js → chunk-PIOO2M4W.js} +2 -2
  122. package/dist/cli/chunks/{chunk-BGYLNCL6.js → chunk-PKMCZFET.js} +2 -2
  123. package/dist/cli/chunks/{chunk-G7FMYFTN.js → chunk-QES4QHQW.js} +1 -1
  124. package/dist/cli/chunks/{chunk-UIPPJKON.js → chunk-QG6BXSNJ.js} +2 -2
  125. package/dist/cli/chunks/{chunk-7YXT6BXN.js → chunk-QLOOW23R.js} +3 -3
  126. package/dist/cli/chunks/{chunk-CQFT7H3F.js → chunk-RSCGBHLM.js} +2 -2
  127. package/dist/cli/chunks/{chunk-QCEW4ZDW.js → chunk-RZ6CO3RZ.js} +2 -2
  128. package/dist/cli/chunks/{chunk-OETDMOOE.js → chunk-S6F3IJMK.js} +1 -1
  129. package/dist/cli/chunks/{chunk-KVL63BSU.js → chunk-S6VNPKHO.js} +1 -1
  130. package/dist/cli/chunks/{chunk-BUGWPTMF.js → chunk-SHWXADCI.js} +2 -2
  131. package/dist/cli/chunks/{chunk-FQY3UTGA.js → chunk-SPJQJWGK.js} +2 -2
  132. package/dist/cli/chunks/{chunk-BOVH6WSM.js → chunk-SS6K4FBH.js} +2 -2
  133. package/dist/cli/chunks/{chunk-4BESADKE.js → chunk-SXADKQJN.js} +2 -2
  134. package/dist/cli/chunks/{chunk-USMDIIHY.js → chunk-TBQTGQ75.js} +2 -2
  135. package/dist/cli/chunks/{chunk-4BDLD7V2.js → chunk-TDGE52HJ.js} +1 -1
  136. package/dist/cli/chunks/{chunk-JPIBPKBP.js → chunk-THFLRJT6.js} +3 -3
  137. package/dist/cli/chunks/{chunk-ZCFZ4USU.js → chunk-TQ2MA3SR.js} +1 -1
  138. package/dist/cli/chunks/{chunk-G5DFYX3J.js → chunk-UCQ66N6M.js} +2 -2
  139. package/dist/cli/chunks/{chunk-CPH5JP4L.js → chunk-UHGMS2PJ.js} +1 -1
  140. package/dist/cli/chunks/{chunk-ANYYTWOQ.js → chunk-UHKXKWMD.js} +2 -2
  141. package/dist/cli/chunks/{chunk-YRQLVGCI.js → chunk-UJ6TMZC6.js} +2 -2
  142. package/dist/cli/chunks/{chunk-EECM5XKY.js → chunk-UKBDH27A.js} +1 -1
  143. package/dist/cli/chunks/{chunk-VLBV2VL3.js → chunk-UMCEEXQN.js} +1 -1
  144. package/dist/cli/chunks/{chunk-LOXVVMS4.js → chunk-USUFTHHT.js} +3 -3
  145. package/dist/cli/chunks/{chunk-HOKON5EL.js → chunk-V32MDID3.js} +2 -2
  146. package/dist/cli/chunks/{chunk-KZTBNDNE.js → chunk-VAJT6QWX.js} +1 -1
  147. package/dist/cli/chunks/{chunk-UNIBND6A.js → chunk-VLUJWI56.js} +1 -1
  148. package/dist/cli/chunks/{chunk-QWYISZTN.js → chunk-WINA3XUT.js} +2 -2
  149. package/dist/cli/chunks/{chunk-YPTGE5NJ.js → chunk-WWCH5SSF.js} +2 -2
  150. package/dist/cli/chunks/{chunk-W5YEIHIO.js → chunk-WWP2VXYJ.js} +2 -2
  151. package/dist/cli/chunks/{chunk-GFBLWFRV.js → chunk-WZROSTQZ.js} +1 -1
  152. package/dist/cli/chunks/{chunk-UMG5URNV.js → chunk-XFUF654L.js} +1 -1
  153. package/dist/cli/chunks/{chunk-54MFKCLT.js → chunk-XN2CD5S6.js} +2 -2
  154. package/dist/cli/chunks/{chunk-IHQTXJAQ.js → chunk-XOQQGZFY.js} +1 -1
  155. package/dist/cli/chunks/{chunk-WRYT4HTZ.js → chunk-XSCOEY4C.js} +2 -2
  156. package/dist/cli/chunks/{chunk-R3GEXYO4.js → chunk-Y734CWHJ.js} +2 -2
  157. package/dist/cli/chunks/{chunk-NUQBJGGF.js → chunk-YBPCBFEE.js} +2 -2
  158. package/dist/cli/chunks/{chunk-GUEZQOHL.js → chunk-YLAEIS6F.js} +1 -1
  159. package/dist/cli/chunks/{chunk-EFRESRLB.js → chunk-YMMVCOPF.js} +3 -3
  160. package/dist/cli/chunks/{chunk-N7VOOI3U.js → chunk-YQCAXYBF.js} +2 -2
  161. package/dist/cli/chunks/{chunk-5FLTZ3KT.js → chunk-YRVUYM62.js} +2 -2
  162. package/dist/cli/chunks/{chunk-GJMZR7WU.js → chunk-YVKMHXQK.js} +3 -3
  163. package/dist/cli/chunks/{chunk-TZPKTRJB.js → chunk-ZCLFAOVT.js} +2 -2
  164. package/dist/cli/chunks/{chunk-L4S722JD.js → chunk-ZH6ZBDVV.js} +1 -1
  165. package/dist/cli/chunks/{chunk-KSYLRM4Q.js → chunk-ZHEKGB4A.js} +2 -2
  166. package/dist/cli/chunks/{chunk-E3B5XTXJ.js → chunk-ZIBW7CB4.js} +1 -1
  167. package/dist/cli/chunks/{chunk-2DIT5AUU.js → chunk-ZLCATRXI.js} +2 -2
  168. package/dist/cli/chunks/{chunk-LWYLW7RX.js → chunk-ZXX2VFMA.js} +2 -2
  169. package/dist/cli/chunks/{chunk-XKFE3FLI.js → chunk-ZYPESQ4M.js} +2 -2
  170. package/dist/cli/chunks/{ci-74ZUCO5V.js → ci-HHL5WQXQ.js} +2 -2
  171. package/dist/cli/chunks/{ci-output-HD6IZNJA.js → ci-output-HVOJC2KN.js} +2 -2
  172. package/dist/cli/chunks/{circuit-breaker-USZVMA42.js → circuit-breaker-HRXMIY2G.js} +2 -2
  173. package/dist/cli/chunks/{claude-flow-setup-S4XKNCD5.js → claude-flow-setup-3I7WVMZN.js} +2 -2
  174. package/dist/cli/chunks/client-EY2IYQDL.js +2 -0
  175. package/dist/cli/chunks/{cline-installer-6EW4CHAR.js → cline-installer-NBREL4QT.js} +2 -2
  176. package/dist/cli/chunks/{code-TOLWD2XL.js → code-TX4E2RWU.js} +2 -2
  177. package/dist/cli/chunks/{code-index-extractor-UA4QQ7B3.js → code-index-extractor-YELOFLSL.js} +2 -2
  178. package/dist/cli/chunks/codex-installer-HEX3KFRB.js +10 -0
  179. package/dist/cli/chunks/{completions-KVUMQQ4K.js → completions-72GGFRGG.js} +2 -2
  180. package/dist/cli/chunks/{complexity-analyzer-DFH6LMK2.js → complexity-analyzer-WRAKDYUK.js} +2 -2
  181. package/dist/cli/chunks/{continuedev-installer-LYDQSAU7.js → continuedev-installer-UGYKSKTI.js} +2 -2
  182. package/dist/cli/chunks/{copilot-installer-7USXLZHZ.js → copilot-installer-RPCRUKIJ.js} +2 -2
  183. package/dist/cli/chunks/core-handlers-G4GLA4DT.js +2 -0
  184. package/dist/cli/chunks/{cost-tracker-JBDIUMKZ.js → cost-tracker-CNHJ7G4M.js} +2 -2
  185. package/dist/cli/chunks/{coverage-RGO3K357.js → coverage-RHIQ4XEX.js} +3 -3
  186. package/dist/cli/chunks/cross-domain-router-P3K4IH5H.js +2 -0
  187. package/dist/cli/chunks/{cursor-installer-YEZGD37F.js → cursor-installer-KSRVA4V2.js} +2 -2
  188. package/dist/cli/chunks/{daemon-FVETQ3LL.js → daemon-IT4AAFBW.js} +3 -3
  189. package/dist/cli/chunks/{daemon-LPEXHNYG.js → daemon-QBXSJABV.js} +4 -4
  190. package/dist/cli/chunks/{dag-attention-scheduler-UKYE2FII.js → dag-attention-scheduler-F7WCQTLY.js} +2 -2
  191. package/dist/cli/chunks/{detect-WBG5P7ER.js → detect-2IYU332U.js} +2 -2
  192. package/dist/cli/chunks/{dist-node-YW6YRBCU.js → dist-node-CIYNYCYN.js} +2 -2
  193. package/dist/cli/chunks/{domain-handler-HH7J4A32.js → domain-handler-QRYQO2QK.js} +2 -2
  194. package/dist/cli/chunks/{domain-transfer-V34GXD5I.js → domain-transfer-2OQDOD3G.js} +2 -2
  195. package/dist/cli/chunks/dream-IT4ZQGEO.js +2 -0
  196. package/dist/cli/chunks/{embed-and-insert-pattern-WYLRS3CL.js → embed-and-insert-pattern-P2IFC7JL.js} +2 -2
  197. package/dist/cli/chunks/{eval-EIMVXY5J.js → eval-SBPK37IB.js} +2 -2
  198. package/dist/cli/chunks/{experience-capture-middleware-QMZHRUKM.js → experience-capture-middleware-3GMFND3F.js} +3 -3
  199. package/dist/cli/chunks/{fast-paths-NHLW6XS6.js → fast-paths-4OYYII2F.js} +2 -2
  200. package/dist/cli/chunks/{feature-flags-NE3MBL3P.js → feature-flags-BM6QTMMC.js} +2 -2
  201. package/dist/cli/chunks/{feature-flags-N3UHMSZ3.js → feature-flags-NFCAYUWO.js} +2 -2
  202. package/dist/cli/chunks/{file-discovery-SI44X4YS.js → file-discovery-2M3ZUAGC.js} +2 -2
  203. package/dist/cli/chunks/{fleet-MMYUXRRM.js → fleet-QMGGVIDV.js} +3 -3
  204. package/dist/cli/chunks/{gnn-wrapper-RLYXYU2Q.js → gnn-wrapper-WGMAGZMO.js} +2 -2
  205. package/dist/cli/chunks/{heartbeat-handler-6EDRUYLV.js → heartbeat-handler-5RSMEZGG.js} +4 -4
  206. package/dist/cli/chunks/heartbeat-scheduler-UUWSPHF2.js +2 -0
  207. package/dist/cli/chunks/hnsw-adapter-YUJVSFPD.js +2 -0
  208. package/dist/cli/chunks/hnsw-index-FQZ47RSJ.js +2 -0
  209. package/dist/cli/chunks/{hnsw-legacy-bridge-RVM7EAIH.js → hnsw-legacy-bridge-TYPQ2T6P.js} +2 -2
  210. package/dist/cli/chunks/{better-sqlite3-DUZ6FFAH.js → hnswlib-node-GMRPPMDM.js} +2 -2
  211. package/dist/cli/chunks/{hooks-ZF4VKHEO.js → hooks-NUC5P3OJ.js} +10 -10
  212. package/dist/cli/chunks/hybrid-router-T5MF73NF.js +2 -0
  213. package/dist/cli/chunks/{hypergraph-engine-YWS66PGO.js → hypergraph-engine-OIB7WK54.js} +2 -2
  214. package/dist/cli/chunks/{hypergraph-handler-OQHVRPWB.js → hypergraph-handler-XX2N75QC.js} +3 -3
  215. package/dist/cli/chunks/impact-analyzer-AEGELYMD.js +2 -0
  216. package/dist/cli/chunks/{init-handler-YW74YF2V.js → init-handler-AKSTJMZY.js} +6 -6
  217. package/dist/cli/chunks/init-wizard-WKX3OGWM.js +2 -0
  218. package/dist/cli/chunks/kernel-5CVWFIGR.js +2 -0
  219. package/dist/cli/chunks/{kilocode-installer-APWB2GMA.js → kilocode-installer-375V5ZZB.js} +2 -2
  220. package/dist/cli/chunks/{kiro-installer-DICKFVNC.js → kiro-installer-GKY5GB5Q.js} +2 -2
  221. package/dist/cli/chunks/knowledge-graph-EGPMNDMT.js +2 -0
  222. package/dist/cli/chunks/{learning-MXHNYW5D.js → learning-2CQE3QP6.js} +3 -3
  223. package/dist/cli/chunks/{llm-router-LTFIX7NY.js → llm-router-FTQNRF45.js} +4 -4
  224. package/dist/cli/chunks/llm-router-service-H4LXOARB.js +2 -0
  225. package/dist/cli/chunks/{load-JUMIQ4LZ.js → load-3DBAO5ZG.js} +2 -2
  226. package/dist/cli/chunks/load-test-OOOGITSN.js +2 -0
  227. package/dist/cli/chunks/{mcp-WHIARJGO.js → mcp-AWR6TDXM.js} +2 -2
  228. package/dist/cli/chunks/{memory-KAHS6Z5A.js → memory-GI4LCNXY.js} +5 -5
  229. package/dist/cli/chunks/memory-backend-O2YOT4LW.js +2 -0
  230. package/dist/cli/chunks/{memory-handlers-DG3RRXB6.js → memory-handlers-MALKG7GP.js} +2 -2
  231. package/dist/cli/chunks/{multi-model-executor-E3Y2RHMX.js → multi-model-executor-SWFT5U72.js} +2 -2
  232. package/dist/cli/chunks/{opencode-installer-3RKGNGGE.js → opencode-installer-EYXGYJX5.js} +2 -2
  233. package/dist/cli/chunks/{orchestrator-TXITUKWD.js → orchestrator-MP3EAZVC.js} +5 -5
  234. package/dist/cli/chunks/pattern-null-store-WBOHE2XL.js +2 -0
  235. package/dist/cli/chunks/{pattern-usage-recorder-EE2BUFZT.js → pattern-usage-recorder-25P3R3W7.js} +2 -2
  236. package/dist/cli/chunks/{pipeline-AXTT6KZB.js → pipeline-LSAFL25D.js} +2 -2
  237. package/dist/cli/chunks/{platform-TICPVKE2.js → platform-IJ6DJ2PG.js} +2 -2
  238. package/dist/cli/chunks/{plugin-VQKNV3EM.js → plugin-OXOZRZW2.js} +2 -2
  239. package/dist/cli/chunks/{prime-radiant-advanced-wasm-6GY5YY7D.js → prime-radiant-advanced-wasm-HJNJQQ3R.js} +2 -2
  240. package/dist/cli/chunks/protocol-executor-JCNTPW5J.js +2 -0
  241. package/dist/cli/chunks/{protocol-handler-YFWDR7UZ.js → protocol-handler-TCMUH2HL.js} +2 -2
  242. package/dist/cli/chunks/{prove-FUMRCXAA.js → prove-ADXQ2GOX.js} +2 -2
  243. package/dist/cli/chunks/provider-manager-LPGQ5GOO.js +2 -0
  244. package/dist/cli/chunks/qe-reasoning-bank-FWVYVSPP.js +2 -0
  245. package/dist/cli/chunks/{quality-2APISBW5.js → quality-EWP36ORX.js} +2 -2
  246. package/dist/cli/chunks/{quality-gate-MCC3E5TM.js → quality-gate-3BIG7PVU.js} +3 -3
  247. package/dist/cli/chunks/queen-coordinator-UXNALRVD.js +2 -0
  248. package/dist/cli/chunks/{real-embeddings-CC5TNOTI.js → real-embeddings-D4NBT7W5.js} +2 -2
  249. package/dist/cli/chunks/{roocode-installer-YAHTEVPI.js → roocode-installer-DOPWH6YV.js} +2 -2
  250. package/dist/cli/chunks/router-C6LUIQYY.js +2 -0
  251. package/dist/cli/chunks/routing-feedback-KMSGGDVD.js +2 -0
  252. package/dist/cli/chunks/{routing-handler-6NQBW4TQ.js → routing-handler-5ADEFOHS.js} +2 -2
  253. package/dist/cli/chunks/{ruvector-commands-ZHXLHUPG.js → ruvector-commands-PLMEIHSN.js} +2 -2
  254. package/dist/cli/chunks/{rvf-dual-writer-5KF2DGCW.js → rvf-dual-writer-EQWKVNQB.js} +2 -2
  255. package/dist/cli/chunks/{rvf-migration-adapter-BBU57BGF.js → rvf-migration-adapter-2OWFUUCG.js} +2 -2
  256. package/dist/cli/chunks/{rvf-migration-coordinator-VN4VRZA4.js → rvf-migration-coordinator-URAETAPU.js} +2 -2
  257. package/dist/cli/chunks/rvf-native-adapter-K54BELUE.js +2 -0
  258. package/dist/cli/chunks/{rvf-store-integrity-XCY2XQZA.js → rvf-store-integrity-4AWPW4TF.js} +2 -2
  259. package/dist/cli/chunks/safe-db-NGOZWF2D.js +2 -0
  260. package/dist/cli/chunks/schedule-B3Y5P64E.js +2 -0
  261. package/dist/cli/chunks/scheduler-Z6QVRMTB.js +2 -0
  262. package/dist/cli/chunks/{security-PYP4H3KN.js → security-HDLZVM62.js} +3 -3
  263. package/dist/cli/chunks/{shared-rvf-adapter-3CJHRNX6.js → shared-rvf-adapter-YQT7PF7X.js} +2 -2
  264. package/dist/cli/chunks/{shared-rvf-dual-writer-MKSLKWDI.js → shared-rvf-dual-writer-N5D3NSJ7.js} +2 -2
  265. package/dist/cli/chunks/sqlite-persistence-PLOUGATS.js +2 -0
  266. package/dist/cli/chunks/{status-handler-VYIZ3VJF.js → status-handler-KLYRJ2MR.js} +2 -2
  267. package/dist/cli/chunks/{structural-health-MVV4OWXP.js → structural-health-6LKVRP6Y.js} +2 -2
  268. package/dist/cli/chunks/{sync-VNX6L3TI.js → sync-7VMFPBVB.js} +2 -2
  269. package/dist/cli/chunks/{sync-G47OYIQ3.js → sync-YYOW6L6W.js} +2 -2
  270. package/dist/cli/chunks/{task-handler-GOWF2GEH.js → task-handler-RKQDGFN2.js} +2 -2
  271. package/dist/cli/chunks/{task-handlers-J2WC6J37.js → task-handlers-6YJ4QTEP.js} +3 -3
  272. package/dist/cli/chunks/{test-DMCJ3BXS.js → test-ASPUIUJH.js} +4 -4
  273. package/dist/cli/chunks/{test-scheduling-TRFHHKFM.js → test-scheduling-I7ABQBBU.js} +3 -3
  274. package/dist/cli/chunks/{token-bootstrap-KEQ7AHFF.js → token-bootstrap-2XZBTODN.js} +2 -2
  275. package/dist/cli/chunks/{token-usage-B54FOFOF.js → token-usage-TMUE6PTF.js} +2 -2
  276. package/dist/cli/chunks/{transformers-IACZG7IV.js → transformers-FDHHH4SL.js} +2 -2
  277. package/dist/cli/chunks/{tree-sitter-wasm-parser-N7H4X37E.js → tree-sitter-wasm-parser-G7PGZA5C.js} +2 -2
  278. package/dist/cli/chunks/{types-B3SHT4OD.js → types-JGT57UFP.js} +2 -2
  279. package/dist/cli/chunks/unified-memory-P5YVLMFI.js +2 -0
  280. package/dist/cli/chunks/unified-memory-hnsw-7HI43A2O.js +2 -0
  281. package/dist/cli/chunks/unified-persistence-U26YP3N3.js +2 -0
  282. package/dist/cli/chunks/{upgrade-A2PQ5EWK.js → upgrade-V6UQODJF.js} +2 -2
  283. package/dist/cli/chunks/{validate-UXV7UQUT.js → validate-UBZAE5RW.js} +2 -2
  284. package/dist/cli/chunks/{validate-swarm-MMBU4FPP.js → validate-swarm-TSO2MI5X.js} +2 -2
  285. package/dist/cli/chunks/{vibium-R4GUVADA.js → vibium-7G3VYSQA.js} +2 -2
  286. package/dist/cli/chunks/visual-security-6FCDY5FF.js +2 -0
  287. package/dist/cli/chunks/{web-tree-sitter-MP6E6CJB.js → web-tree-sitter-MIYJSF2L.js} +2 -2
  288. package/dist/cli/chunks/{windsurf-installer-Z6BWMUUO.js → windsurf-installer-5TLZSQIJ.js} +2 -2
  289. package/dist/cli/chunks/witness-chain-I3K3WQID.js +2 -0
  290. package/dist/cli/chunks/{witness-chain-EFLTABBA.js → witness-chain-LTV7H2HM.js} +2 -2
  291. package/dist/cli/chunks/{witness-key-manager-PN36TV43.js → witness-key-manager-PAJ2J4AL.js} +2 -2
  292. package/dist/cli/chunks/{workflow-A2AX3RJU.js → workflow-DL3ESR2H.js} +4 -4
  293. package/dist/cli/chunks/workflow-orchestrator-MAALP4WA.js +2 -0
  294. package/dist/cli/chunks/{wrappers-NA6FHA63.js → wrappers-5HSU665E.js} +2 -2
  295. package/dist/cli/handlers/init-handler.js +1 -1
  296. package/dist/coordination/handlers/coverage-collection.d.ts +161 -0
  297. package/dist/coordination/handlers/coverage-collection.js +639 -0
  298. package/dist/coordination/handlers/coverage-handlers.js +199 -146
  299. package/dist/coordination/handlers/handler-types.d.ts +6 -1
  300. package/dist/coordination/handlers/handler-utils.js +10 -3
  301. package/dist/coordination/handlers/security-handlers.js +17 -2
  302. package/dist/coordination/handlers/test-execution-handlers.js +16 -1
  303. package/dist/coordination/result-saver.js +119 -97
  304. package/dist/coordination/task-executor.d.ts +26 -1
  305. package/dist/coordination/task-executor.js +52 -4
  306. package/dist/domains/code-intelligence/services/knowledge-graph.js +8 -0
  307. package/dist/domains/coverage-analysis/services/coverage-analyzer.js +4 -0
  308. package/dist/domains/coverage-analysis/services/gap-detector.js +4 -0
  309. package/dist/domains/defect-intelligence/services/defect-predictor.js +4 -0
  310. package/dist/domains/defect-intelligence/services/root-cause-analyzer.js +4 -0
  311. package/dist/domains/quality-assessment/services/deployment-advisor.js +4 -0
  312. package/dist/domains/quality-assessment/services/quality-analyzer.js +4 -0
  313. package/dist/domains/security-compliance/services/scanners/sast-scanner.js +4 -0
  314. package/dist/domains/test-generation/index.js +17 -2
  315. package/dist/domains/test-generation/services/test-generator.js +31 -9
  316. package/dist/init/codex-installer.d.ts +13 -0
  317. package/dist/init/codex-installer.js +122 -1
  318. package/dist/init/phases/09-assets.js +4 -0
  319. package/dist/init/phases/phase-interface.d.ts +1 -1
  320. package/dist/learning/real-embeddings.js +15 -1
  321. package/dist/mcp/bundle.js +429 -419
  322. package/dist/mcp/handlers/domain-handler-configs.js +79 -14
  323. package/dist/mcp/types.d.ts +42 -4
  324. package/dist/optimization/session-cache.d.ts +13 -1
  325. package/dist/optimization/session-cache.js +27 -2
  326. package/dist/shared/llm/llm-router-service.js +59 -4
  327. package/dist/shared/llm/router/agent-router-config.d.ts +46 -2
  328. package/dist/shared/llm/router/agent-router-config.js +124 -2
  329. package/dist/shared/llm/router/config-store.d.ts +17 -1
  330. package/dist/shared/llm/router/config-store.js +103 -0
  331. package/dist/shared/llm/router/index.d.ts +2 -2
  332. package/dist/shared/llm/router/index.js +2 -0
  333. package/dist/shared/llm/router/types.d.ts +44 -0
  334. package/dist/shared/llm/router/types.js +1 -0
  335. package/package.json +9 -6
  336. package/dist/cli/chunks/adapter-CWIMFWAI.js +0 -2
  337. package/dist/cli/chunks/aqe-learning-engine-OTXT2DLN.js +0 -2
  338. package/dist/cli/chunks/base-O3SPSWBA.js +0 -2
  339. package/dist/cli/chunks/browser-workflow-MXS3ZKY2.js +0 -2
  340. package/dist/cli/chunks/chunk-G4GTE3RJ.js +0 -2
  341. package/dist/cli/chunks/chunk-HVB2L52I.js +0 -2
  342. package/dist/cli/chunks/chunk-MVI2QMRW.js +0 -2
  343. package/dist/cli/chunks/chunk-OZR25R7W.js +0 -2
  344. package/dist/cli/chunks/chunk-PP2RYSHT.js +0 -3
  345. package/dist/cli/chunks/client-33PGO5FA.js +0 -2
  346. package/dist/cli/chunks/codex-installer-C2CUP4FW.js +0 -8
  347. package/dist/cli/chunks/core-handlers-CSNZIM3A.js +0 -2
  348. package/dist/cli/chunks/cross-domain-router-DRIBR5L3.js +0 -2
  349. package/dist/cli/chunks/dream-WUNO723O.js +0 -2
  350. package/dist/cli/chunks/heartbeat-scheduler-VAFQDJLL.js +0 -2
  351. package/dist/cli/chunks/hnsw-adapter-TIRPA7XE.js +0 -2
  352. package/dist/cli/chunks/hnsw-index-SSQBRQCQ.js +0 -2
  353. package/dist/cli/chunks/hybrid-router-AKBWZOQ3.js +0 -2
  354. package/dist/cli/chunks/impact-analyzer-46FQIZ6Y.js +0 -2
  355. package/dist/cli/chunks/init-wizard-U3NHGYSS.js +0 -2
  356. package/dist/cli/chunks/kernel-ZDXHT6QF.js +0 -2
  357. package/dist/cli/chunks/knowledge-graph-6XTW6WO6.js +0 -2
  358. package/dist/cli/chunks/llm-router-service-3F4E64SY.js +0 -2
  359. package/dist/cli/chunks/load-test-SWZNGEIY.js +0 -2
  360. package/dist/cli/chunks/memory-backend-PR74ZPBA.js +0 -2
  361. package/dist/cli/chunks/pattern-null-store-EPE36BVT.js +0 -2
  362. package/dist/cli/chunks/protocol-executor-IELENNST.js +0 -2
  363. package/dist/cli/chunks/provider-manager-3R3KOBHG.js +0 -2
  364. package/dist/cli/chunks/qe-reasoning-bank-S2R2PCBS.js +0 -2
  365. package/dist/cli/chunks/queen-coordinator-2E23NEV4.js +0 -2
  366. package/dist/cli/chunks/router-3FVLWO6S.js +0 -2
  367. package/dist/cli/chunks/routing-feedback-ZQLRNNR7.js +0 -2
  368. package/dist/cli/chunks/rvf-native-adapter-YFGLQNEB.js +0 -2
  369. package/dist/cli/chunks/safe-db-4SBLBTW7.js +0 -2
  370. package/dist/cli/chunks/schedule-5Y3BGVAA.js +0 -2
  371. package/dist/cli/chunks/scheduler-DOID3QF3.js +0 -2
  372. package/dist/cli/chunks/sqlite-persistence-M4JEQO57.js +0 -2
  373. package/dist/cli/chunks/unified-memory-WNYWTGVX.js +0 -2
  374. package/dist/cli/chunks/unified-memory-hnsw-YPAV7U4E.js +0 -2
  375. package/dist/cli/chunks/unified-persistence-TJ252S7L.js +0 -2
  376. package/dist/cli/chunks/visual-security-VKYXEGJB.js +0 -2
  377. package/dist/cli/chunks/witness-chain-WVXRXKQP.js +0 -2
  378. package/dist/cli/chunks/workflow-orchestrator-GOWSPR3G.js +0 -2
@@ -5,106 +5,155 @@
5
5
  * Covers: analyze-coverage
6
6
  */
7
7
  import * as fs from 'fs/promises';
8
- import * as fsSync from 'fs';
9
8
  import * as path from 'path';
10
9
  import { ok, err } from '../../shared/types';
11
10
  import { toError } from '../../shared/error-utils.js';
12
11
  import { safeJsonParse } from '../../shared/safe-json.js';
13
12
  import { loadCoverageData } from './handler-utils';
13
+ import { buildEstimatedCoverage, collectRustCoverage, isCoverageExecDisabled, isRustProject, isTestPath, } from './coverage-collection';
14
14
  /**
15
- * Build heuristic coverage data from source files when no instrumented
16
- * coverage is available. Uses the same logic as the CLI's buildCoverageData.
15
+ * Try to produce a JS/TS coverage report by running the project's test runner.
16
+ * Returns true if the runner completed (which does not guarantee a report was
17
+ * written — the caller re-checks disk).
17
18
  */
18
- function buildHeuristicCoverage(targetPath) {
19
- const SOURCE_EXTENSIONS = new Set(['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs', '.py', '.go', '.rs', '.java', '.rb']);
20
- const SKIP_DIRS = new Set(['node_modules', 'dist', 'build', 'coverage', '.git', '.claude', '.agentic-qe', '__pycache__', '.venv']);
21
- const TEST_PATTERNS = ['.test.', '.spec.', '_test.', '_spec.'];
22
- if (!fsSync.existsSync(targetPath) || !fsSync.statSync(targetPath).isDirectory())
23
- return null;
24
- const sourceFiles = [];
25
- function walk(dir, depth) {
26
- if (depth > 6)
27
- return;
28
- let entries;
19
+ async function tryRunJsCoverage(targetPath) {
20
+ // Running the project's test suite executes code from the analyzed repository
21
+ // (the tests themselves, plus npm lifecycle scripts via npx). Honor the
22
+ // opt-out before doing that.
23
+ if (isCoverageExecDisabled())
24
+ return false;
25
+ try {
26
+ const { execSync } = await import('child_process');
27
+ let coverageCmd = 'npx vitest run --coverage --reporter=json 2>/dev/null';
29
28
  try {
30
- entries = fsSync.readdirSync(dir, { withFileTypes: true });
31
- }
32
- catch {
33
- return;
34
- }
35
- for (const entry of entries) {
36
- if (entry.isDirectory()) {
37
- if (SKIP_DIRS.has(entry.name))
38
- continue;
39
- walk(path.join(dir, entry.name), depth + 1);
29
+ const pkgContent = await fs.readFile(path.join(targetPath, 'package.json'), 'utf-8');
30
+ const pkg = safeJsonParse(pkgContent);
31
+ const deps = {
32
+ ...(pkg.devDependencies || {}),
33
+ ...(pkg.dependencies || {}),
34
+ };
35
+ if (deps['jest'] || deps['@jest/core']) {
36
+ coverageCmd = 'npx jest --coverage --json 2>/dev/null';
40
37
  }
41
- else if (entry.isFile()) {
42
- const ext = path.extname(entry.name);
43
- if (!SOURCE_EXTENSIONS.has(ext))
44
- continue;
45
- if (TEST_PATTERNS.some(p => entry.name.includes(p)))
46
- continue;
47
- sourceFiles.push(path.join(dir, entry.name));
38
+ else if (deps['mocha'] || deps['nyc']) {
39
+ coverageCmd = 'npx nyc mocha 2>/dev/null';
48
40
  }
41
+ // vitest is the default — covers vitest, @vitest/coverage-v8, etc.
49
42
  }
43
+ catch {
44
+ // No package.json — use default vitest
45
+ }
46
+ execSync(coverageCmd, {
47
+ cwd: targetPath,
48
+ timeout: 120000,
49
+ encoding: 'utf-8',
50
+ stdio: ['pipe', 'pipe', 'pipe'],
51
+ });
52
+ return true;
50
53
  }
51
- walk(targetPath, 0);
52
- if (sourceFiles.length === 0)
54
+ catch {
55
+ // Test runner failed or not available.
56
+ return false;
57
+ }
58
+ }
59
+ /**
60
+ * Narrow an instrumented report to production files only, recomputing the
61
+ * aggregate from what survives.
62
+ *
63
+ * Returns `null` when the report contains no production files at all — the
64
+ * caller must NOT fall back to the unfiltered set, because that reports the test
65
+ * files' own coverage as the project's (#569's third contradiction).
66
+ */
67
+ function productionOnly(report, targetPath) {
68
+ const files = report.files.filter(f => !isTestPath(f.path, targetPath));
69
+ if (files.length === 0)
53
70
  return null;
54
- const files = sourceFiles.map(filePath => {
55
- let content = '';
56
- try {
57
- content = fsSync.readFileSync(filePath, 'utf-8');
58
- }
59
- catch { /* skip */ }
60
- const lines = content.split('\n');
61
- const totalLines = lines.length;
62
- const functionCount = Math.max((content.match(/\b(function|=>)\b/g) || []).length, 1);
63
- const branchCount = Math.max((content.match(/\b(if|switch|case|\?\?|\|\|)\b/g) || []).length, 1);
64
- // Check for co-located test file
65
- const testVariants = [
66
- filePath.replace('.ts', '.test.ts').replace('/src/', '/tests/'),
67
- filePath.replace('.ts', '.spec.ts').replace('/src/', '/tests/'),
68
- filePath.replace('.ts', '.test.ts'),
69
- filePath.replace('.js', '.test.js'),
70
- filePath.replace('.js', '.test.js').replace('/src/', '/tests/'),
71
- ];
72
- const hasTest = testVariants.some(t => fsSync.existsSync(t));
73
- const complexityPenalty = Math.min(branchCount * 0.005, 0.15);
74
- const sizePenalty = Math.min(totalLines * 0.0001, 0.1);
75
- const coverageRate = Math.max(0.05, Math.min(0.95, hasTest ? 0.85 - complexityPenalty - sizePenalty : 0.20));
76
- const coveredLines = Math.floor(totalLines * coverageRate);
77
- const branchCoverage = Math.min(Math.floor(coveredLines * 0.7), branchCount);
78
- const functionCoverage = Math.min(Math.floor(functionCount * coverageRate * 0.9), functionCount);
79
- const uncoveredLines = Array.from({ length: totalLines - coveredLines }, (_, i) => i + coveredLines + 1);
80
- return {
81
- path: filePath,
82
- lines: { covered: coveredLines, total: totalLines },
83
- branches: { covered: branchCoverage, total: branchCount },
84
- functions: { covered: functionCoverage, total: functionCount },
85
- statements: { covered: coveredLines, total: totalLines },
86
- uncoveredLines,
87
- uncoveredBranches: uncoveredLines.slice(0, Math.floor(uncoveredLines.length / 2)),
88
- };
89
- });
90
- const totalLines = files.reduce((s, f) => s + f.lines.total, 0);
91
- const coveredLines = files.reduce((s, f) => s + f.lines.covered, 0);
92
- const totalBranches = files.reduce((s, f) => s + f.branches.total, 0);
93
- const coveredBranches = files.reduce((s, f) => s + f.branches.covered, 0);
94
- const totalFunctions = files.reduce((s, f) => s + f.functions.total, 0);
95
- const coveredFunctions = files.reduce((s, f) => s + f.functions.covered, 0);
96
- const safeDiv = (a, b) => b > 0 ? Math.round((a / b) * 100) : 0;
71
+ // Recompute rather than carrying the original summary: it was computed over
72
+ // the unfiltered set, so keeping it would blend test-file coverage into the
73
+ // production headline figure.
74
+ const sum = (pick) => files.reduce((acc, f) => acc + pick(f), 0);
75
+ const pct = (covered, total) => total > 0 ? Math.round((covered / total) * 100) : 0;
76
+ const totalLines = sum(f => f.lines.total);
77
+ const coveredLines = sum(f => f.lines.covered);
78
+ const branchDataCollected = files.some(f => f.branches.total > 0);
79
+ const functionDataCollected = files.some(f => f.functions.total > 0);
97
80
  return {
98
- files,
99
- summary: {
100
- line: safeDiv(coveredLines, totalLines),
101
- branch: safeDiv(coveredBranches, totalBranches),
102
- function: safeDiv(coveredFunctions, totalFunctions),
103
- statement: safeDiv(coveredLines, totalLines),
104
- files: files.length,
81
+ data: {
82
+ files,
83
+ summary: {
84
+ line: pct(coveredLines, totalLines),
85
+ branch: pct(sum(f => f.branches.covered), sum(f => f.branches.total)),
86
+ function: pct(sum(f => f.functions.covered), sum(f => f.functions.total)),
87
+ statement: pct(coveredLines, totalLines),
88
+ files: files.length,
89
+ },
90
+ },
91
+ provenance: {
92
+ method: 'instrumented-report',
93
+ estimated: false,
94
+ branchDataCollected,
95
+ functionDataCollected,
96
+ notes: [],
105
97
  },
106
98
  };
107
99
  }
100
+ /**
101
+ * Collect coverage for a target, preferring real measurement over estimation
102
+ * and always reporting which one happened (#569).
103
+ *
104
+ * Cascade:
105
+ * 1. an instrumented report already on disk (istanbul/lcov/cobertura)
106
+ * 2. language-specific instrumentation we can run — `cargo llvm-cov` for Rust,
107
+ * the project's test runner for JS/TS
108
+ * 3. static estimation, explicitly labelled `estimated: true`
109
+ */
110
+ async function collectCoverage(targetPath) {
111
+ const existing = await loadCoverageData(targetPath);
112
+ if (existing) {
113
+ const fromReport = productionOnly(existing, targetPath);
114
+ // A report whose only entries are test files yields NO production coverage.
115
+ // Falling back to the unfiltered set here would report the test files'
116
+ // own coverage as the project's — recreating #569's third contradiction
117
+ // (`tests/verifier_matrix.rs` analysed at 79.2% as if it were a target).
118
+ if (!fromReport)
119
+ return { collected: null, ranTests: false, testOnlyReport: true };
120
+ return { collected: fromReport, ranTests: false };
121
+ }
122
+ // #569 work item 1: delegate to real instrumentation where available.
123
+ if (isRustProject(targetPath)) {
124
+ const rust = await collectRustCoverage(targetPath);
125
+ if (rust)
126
+ return { collected: rust, ranTests: true };
127
+ }
128
+ const ranTests = await tryRunJsCoverage(targetPath);
129
+ const afterRun = await loadCoverageData(targetPath);
130
+ if (afterRun) {
131
+ const fromRun = productionOnly(afterRun, targetPath);
132
+ if (!fromRun)
133
+ return { collected: null, ranTests, testOnlyReport: true };
134
+ return { collected: fromRun, ranTests };
135
+ }
136
+ return { collected: buildEstimatedCoverage(targetPath), ranTests };
137
+ }
138
+ /**
139
+ * Build the guidance string shown when a result is an estimate rather than a
140
+ * measurement, tailored to what the target actually is.
141
+ */
142
+ function estimationGuidance(targetPath) {
143
+ // When the caller turned execution off, naming the tool to install is the
144
+ // wrong advice — nothing will be run either way until they opt back in.
145
+ if (isCoverageExecDisabled()) {
146
+ return 'Coverage tooling execution is disabled (AQE_COVERAGE_NO_EXEC). No tests ' +
147
+ 'were run and no build tooling was invoked. Unset it, or generate a coverage ' +
148
+ 'report yourself and re-run, to get real measurements.';
149
+ }
150
+ if (isRustProject(targetPath)) {
151
+ return 'To get real measurements for this Rust crate, install cargo-llvm-cov ' +
152
+ '(`cargo install cargo-llvm-cov`) and re-run; agentic-qe will invoke it automatically.';
153
+ }
154
+ return 'To get real measurements, run your tests with coverage enabled ' +
155
+ '(e.g. `npm test -- --coverage`, `pytest --cov`) and re-run this analysis.';
156
+ }
108
157
  export function registerCoverageHandlers(ctx) {
109
158
  // Register coverage analysis handler - REAL IMPLEMENTATION
110
159
  ctx.registerHandler('analyze-coverage', async (task) => {
@@ -113,63 +162,30 @@ export function registerCoverageHandlers(ctx) {
113
162
  const analyzer = ctx.getCoverageAnalyzer();
114
163
  const targetPath = payload.target || process.cwd();
115
164
  const threshold = payload.threshold || 80;
116
- // Try to find and read actual coverage files
117
- let coverageData = await loadCoverageData(targetPath);
118
- if (!coverageData) {
119
- // No coverage data found — attempt to collect it by running tests with coverage
120
- let collected = false;
121
- try {
122
- const { execSync } = await import('child_process');
123
- // Detect test runner from package.json
124
- let coverageCmd = 'npx vitest run --coverage --reporter=json 2>/dev/null';
125
- try {
126
- const pkgContent = await fs.readFile(path.join(targetPath, 'package.json'), 'utf-8');
127
- const pkg = safeJsonParse(pkgContent);
128
- const deps = { ...(pkg.devDependencies || {}), ...(pkg.dependencies || {}) };
129
- if (deps['jest'] || deps['@jest/core']) {
130
- coverageCmd = 'npx jest --coverage --json 2>/dev/null';
131
- }
132
- else if (deps['mocha'] || deps['nyc']) {
133
- coverageCmd = 'npx nyc mocha 2>/dev/null';
134
- }
135
- // vitest is the default — covers vitest, @vitest/coverage-v8, etc.
136
- }
137
- catch {
138
- // No package.json — use default vitest
139
- }
140
- execSync(coverageCmd, {
141
- cwd: targetPath,
142
- timeout: 120000,
143
- encoding: 'utf-8',
144
- stdio: ['pipe', 'pipe', 'pipe'],
145
- });
146
- collected = true;
147
- }
148
- catch {
149
- // Test runner failed or not available — that's OK, we'll check for output anyway
150
- }
151
- // Re-check for coverage data after collection attempt
152
- coverageData = await loadCoverageData(targetPath);
153
- // Still no instrumented coverage — fall back to heuristic estimation
154
- if (!coverageData) {
155
- coverageData = buildHeuristicCoverage(targetPath);
156
- }
157
- if (!coverageData) {
158
- return ok({
159
- lineCoverage: 0,
160
- branchCoverage: 0,
161
- functionCoverage: 0,
162
- statementCoverage: 0,
163
- totalFiles: 0,
164
- coverageByFile: [],
165
- gaps: [],
166
- algorithm: 'sublinear-O(log n)',
167
- warning: collected
165
+ const { collected, ranTests, testOnlyReport } = await collectCoverage(targetPath);
166
+ if (!collected) {
167
+ return ok({
168
+ lineCoverage: null,
169
+ branchCoverage: null,
170
+ functionCoverage: null,
171
+ statementCoverage: null,
172
+ totalFiles: 0,
173
+ coverageByFile: [],
174
+ gaps: [],
175
+ estimated: false,
176
+ measured: false,
177
+ coverageMethod: 'none',
178
+ algorithm: 'sublinear-O(log n)',
179
+ warning: testOnlyReport
180
+ ? 'The coverage report contains only test files, so there is no production ' +
181
+ 'coverage to report. Coverage OF a test file is not a meaningful metric. ' +
182
+ 'Check that your coverage tool is instrumenting your source directory.'
183
+ : ranTests
168
184
  ? 'Tests ran but no coverage output was generated. Ensure a coverage provider is configured (e.g., @vitest/coverage-v8, istanbul).'
169
- : 'No coverage data found and could not run tests automatically. Run: npm test -- --coverage',
170
- });
171
- }
185
+ : 'No coverage data found and could not run tests automatically. ' + estimationGuidance(targetPath),
186
+ });
172
187
  }
188
+ const { data: coverageData, provenance } = collected;
173
189
  // Analyze coverage using the real CoverageAnalyzerService
174
190
  const analysisResult = await analyzer.analyze({
175
191
  coverageData,
@@ -189,26 +205,63 @@ export function registerCoverageHandlers(ctx) {
189
205
  file: gap.file,
190
206
  lines: gap.lines,
191
207
  risk: gap.severity,
208
+ // #569: a gap derived from an estimate is a hypothesis, not a
209
+ // finding. Carry that all the way to the caller rather than letting
210
+ // it inherit a default riskScore/confidence downstream.
211
+ estimated: provenance.estimated,
212
+ ...(provenance.estimated
213
+ ? {
214
+ confidence: 0.2,
215
+ reason: 'Possible coverage gap (STATIC ESTIMATE — no instrumentation ran)',
216
+ }
217
+ : {}),
192
218
  }));
193
219
  }
194
220
  }
221
+ const round = (n) => Math.round(n * 10) / 10;
222
+ const pct = (covered, total) => total > 0 ? Math.round((covered / total) * 1000) / 10 : null;
223
+ const warnings = [...provenance.notes];
224
+ if (provenance.estimated)
225
+ warnings.push(estimationGuidance(targetPath));
226
+ // #569: the analyzer generates recommendations from the summary numbers.
227
+ // When branch or function data was never collected, those numbers are 0
228
+ // by construction, and the resulting advice ("Branch coverage is
229
+ // significantly lower than line coverage", "Function coverage is below
230
+ // 70%") is a statement about a metric nobody measured. Drop it rather
231
+ // than send a developer to fix a number that doesn't exist.
232
+ const recommendations = report.recommendations.filter(rec => {
233
+ if (!provenance.branchDataCollected && /branch coverage/i.test(rec))
234
+ return false;
235
+ if (!provenance.functionDataCollected && /function coverage/i.test(rec))
236
+ return false;
237
+ return true;
238
+ });
195
239
  return ok({
196
- lineCoverage: Math.round(report.summary.line * 10) / 10,
197
- branchCoverage: Math.round(report.summary.branch * 10) / 10,
198
- functionCoverage: Math.round(report.summary.function * 10) / 10,
199
- statementCoverage: Math.round(report.summary.statement * 10) / 10,
240
+ lineCoverage: round(report.summary.line),
241
+ // #569 work item 4: never report a branch percentage least of all
242
+ // 100% when no branch data was collected.
243
+ branchCoverage: provenance.branchDataCollected ? round(report.summary.branch) : null,
244
+ functionCoverage: provenance.functionDataCollected ? round(report.summary.function) : null,
245
+ statementCoverage: round(report.summary.statement),
200
246
  totalFiles: report.summary.files,
201
247
  coverageByFile: coverageData.files.map(f => ({
202
248
  file: f.path,
203
- lineCoverage: f.lines.total > 0 ? Math.round((f.lines.covered / f.lines.total) * 1000) / 10 : 0,
204
- branchCoverage: f.branches.total > 0 ? Math.round((f.branches.covered / f.branches.total) * 1000) / 10 : 0,
205
- functionCoverage: f.functions.total > 0 ? Math.round((f.functions.covered / f.functions.total) * 1000) / 10 : 0,
249
+ lineCoverage: pct(f.lines.covered, f.lines.total) ?? 0,
250
+ branchCoverage: provenance.branchDataCollected ? pct(f.branches.covered, f.branches.total) : null,
251
+ functionCoverage: provenance.functionDataCollected ? pct(f.functions.covered, f.functions.total) : null,
206
252
  })),
207
253
  gaps,
208
254
  meetsThreshold: report.meetsThreshold,
209
255
  delta: report.delta,
210
- recommendations: report.recommendations,
256
+ recommendations,
211
257
  algorithm: 'sublinear-O(log n)',
258
+ // #569 work item 5: the caller must be able to tell measurement from guess.
259
+ estimated: provenance.estimated,
260
+ measured: !provenance.estimated,
261
+ coverageMethod: provenance.method,
262
+ branchDataCollected: provenance.branchDataCollected,
263
+ functionDataCollected: provenance.functionDataCollected,
264
+ ...(warnings.length > 0 ? { warning: warnings.join(' ') } : {}),
212
265
  });
213
266
  }
214
267
  catch (error) {
@@ -23,7 +23,12 @@ export interface TaskHandlerContext {
23
23
  /** Lazy service getters */
24
24
  getCoverageAnalyzer(): CoverageAnalyzerService;
25
25
  getSecurityScanner(): SecurityScannerService;
26
- getTestGenerator(): TestGeneratorService;
26
+ /**
27
+ * Async (#567): resolves the ADR-043 LLM router before constructing the
28
+ * service. Pass `useLLM: false` to get a router-free generator (deterministic
29
+ * templates only) for callers that set `aiEnhancement: false`.
30
+ */
31
+ getTestGenerator(useLLM?: boolean): Promise<TestGeneratorService>;
27
32
  getKnowledgeGraph(): KnowledgeGraphService;
28
33
  getQualityAnalyzer(): QualityAnalyzerService;
29
34
  /** Executor configuration */
@@ -295,10 +295,17 @@ export function parseCoberturaXml(content) {
295
295
  functionsCovered++;
296
296
  }
297
297
  }
298
- // If no lines parsed, estimate from rates
298
+ // No per-line <line> entries fall back to the file's reported line-rate.
299
+ //
300
+ // #569/ADR-126: the previous form (`linesTotal = 1; linesCovered = rate >= 0.5
301
+ // ? 1 : 0`) turned a measured 47% into 0% and a measured 51% into 100%, and
302
+ // the result was still labelled `estimated: false`. The line-rate itself IS
303
+ // instrumented data; only the per-line detail is missing. Scale it to a
304
+ // 100-line denominator so the measured rate survives at 1% granularity
305
+ // instead of being rounded to an extreme.
299
306
  if (linesTotal === 0 && !isNaN(lineRate)) {
300
- linesTotal = 1;
301
- linesCovered = lineRate >= 0.5 ? 1 : 0;
307
+ linesTotal = 100;
308
+ linesCovered = Math.round(Math.max(0, Math.min(1, lineRate)) * 100);
302
309
  }
303
310
  files.push({
304
311
  path: filename,
@@ -242,8 +242,23 @@ export function registerSecurityHandlers(ctx) {
242
242
  jstsFilesScanned: jstsFiles.length,
243
243
  otherFilesScanned: otherFiles.length,
244
244
  coverage: sastResult?.coverage,
245
- ...(otherFiles.length > 0 && jstsFiles.length === 0 ? {
246
- note: 'Non-JS/TS files were scanned with cross-language pattern matching. For deeper analysis, use language-specific security tools.',
245
+ // #569 (companion note): "zero findings" from a scan that ran no
246
+ // language-specific analysis is not evidence of absence, and combined
247
+ // with a coverage number it reads as "this code is clean and covered".
248
+ // Say plainly which depth of analysis actually ran.
249
+ deepAnalysisPerformed: jstsFiles.length > 0,
250
+ analysisDepth: jstsFiles.length > 0
251
+ ? (otherFiles.length > 0 ? 'full-sast-on-js-ts; pattern-matching-on-other-languages' : 'full-sast')
252
+ : 'pattern-matching-only',
253
+ ...(jstsFiles.length === 0 ? {
254
+ note: otherFiles.length > 0
255
+ ? 'NO LANGUAGE-SPECIFIC ANALYSIS RAN. Only cross-language pattern matching ' +
256
+ '(secrets, CORS, eval/exec) was applied to these files — full SAST is ' +
257
+ 'implemented for JS/TS only. A zero-finding result here means "nothing ' +
258
+ 'matched a generic pattern", NOT "no vulnerabilities". Run a ' +
259
+ 'language-specific tool (cargo audit / clippy, bandit, gosec, semgrep) ' +
260
+ 'for real coverage of this codebase.'
261
+ : 'No source files were analyzed.',
247
262
  } : {}),
248
263
  });
249
264
  }
@@ -56,7 +56,8 @@ export function registerTestExecutionHandlers(ctx) {
56
56
  ctx.registerHandler('generate-tests', async (task) => {
57
57
  const payload = task.payload;
58
58
  try {
59
- const generator = ctx.getTestGenerator();
59
+ // #567: honor the tool's documented `aiEnhancement` knob (default true).
60
+ const generator = await ctx.getTestGenerator(payload.aiEnhancement !== false);
60
61
  // Determine source files to analyze
61
62
  let sourceFiles = [];
62
63
  let tempPath;
@@ -134,11 +135,25 @@ export function registerTestExecutionHandlers(ctx) {
134
135
  testCode: rewritten.testCode,
135
136
  };
136
137
  });
138
+ // #567: surface whether the LLM branch actually ran. Previously the only
139
+ // clue that generation had silently fallen back to template scaffolding
140
+ // was a suspiciously constant coverage estimate and a sub-20ms duration.
141
+ const llmEnhanced = generatedTests.tests.some(t => t.llmEnhanced === true);
137
142
  return ok({
138
143
  testsGenerated: tests.length,
139
144
  coverageEstimate: generatedTests.coverageEstimate,
140
145
  tests,
141
146
  patternsUsed: generatedTests.patternsUsed,
147
+ llmEnhanced,
148
+ ...(llmEnhanced ? {} : {
149
+ generationMode: 'deterministic-template',
150
+ note: payload.aiEnhancement === false
151
+ ? 'LLM enhancement was disabled by the caller (aiEnhancement: false).'
152
+ : 'No LLM provider was available, so tests are deterministic template ' +
153
+ 'scaffolding rather than source-aware. Configure a provider in ' +
154
+ '.agentic-qe/llm-config.json (or set a provider API key) and ensure ' +
155
+ 'AQE_LLM_ROUTER_DISABLED is not set.',
156
+ }),
142
157
  });
143
158
  }
144
159
  catch (error) {