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
@@ -0,0 +1,639 @@
1
+ /**
2
+ * Coverage collection and provenance (issue #569).
3
+ *
4
+ * Two things live here, and the distinction between them is the whole point:
5
+ *
6
+ * 1. **Measurement** — run real instrumentation and parse what it reports.
7
+ * 2. **Estimation** — a static guess from source shape, used only when no
8
+ * instrumentation could run.
9
+ *
10
+ * Before #569 these were indistinguishable in the output. `coverage_analyze_sublinear`
11
+ * on a Rust crate reported `lineCoverage: 78.3 / branchCoverage: 100 /
12
+ * functionCoverage: 0` with `confidence: 0.7` attached to gaps that pointed at
13
+ * `#[cfg(test)]` blocks and at line numbers past end-of-file. Every one of those
14
+ * numbers came from a JS-shaped regex heuristic; none was a measurement. A caller
15
+ * had no way to tell.
16
+ *
17
+ * So: every collector returns a `CoverageProvenance` alongside the data, and
18
+ * estimation is labelled as estimation, at the source, all the way out to the
19
+ * caller.
20
+ */
21
+ import * as fs from 'fs';
22
+ import * as os from 'os';
23
+ import * as path from 'path';
24
+ import { parseLcovInfo } from './handler-utils';
25
+ /**
26
+ * Is the "never execute build tooling" kill-switch set?
27
+ *
28
+ * Measuring coverage means *running the project's own tests*, which means
29
+ * executing code from the analyzed repository: `npx vitest/jest/nyc` runs its
30
+ * test suite and npm lifecycle scripts, and `cargo llvm-cov` additionally
31
+ * compiles and runs `build.rs` and honors any `runner`/linker directive in that
32
+ * repo's `.cargo/config.toml`. For a trusted project — your own repo, CI on your
33
+ * own code — that is exactly what the caller wants and is how coverage has always
34
+ * been collected here.
35
+ *
36
+ * It is surprising, though, for an operation that reads like a static query, and
37
+ * an agent can be pointed at an untrusted checkout. `AQE_COVERAGE_NO_EXEC=1`
38
+ * disables execution entirely: already-present coverage reports are still parsed,
39
+ * and everything else degrades to clearly-labelled static estimation.
40
+ *
41
+ * Follows the same parsing convention as `AQE_LLM_ROUTER_DISABLED`.
42
+ */
43
+ export function isCoverageExecDisabled(env = process.env) {
44
+ const v = (env.AQE_COVERAGE_NO_EXEC ?? '').trim().toLowerCase();
45
+ if (!v)
46
+ return false;
47
+ return v !== 'false' && v !== '0' && v !== 'no' && v !== 'off';
48
+ }
49
+ // ============================================================================
50
+ // Shared file classification
51
+ // ============================================================================
52
+ const SOURCE_EXTENSIONS = new Set([
53
+ '.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs',
54
+ '.py', '.go', '.rs', '.java', '.rb',
55
+ ]);
56
+ const SKIP_DIRS = new Set([
57
+ 'node_modules', 'dist', 'build', 'coverage', '.git', '.claude', '.agentic-qe',
58
+ '__pycache__', '.venv', 'target', 'vendor',
59
+ ]);
60
+ /** Directory names whose entire contents are test/bench/example code, not production code. */
61
+ const TEST_DIRS = new Set(['tests', 'test', '__tests__', 'benches', 'examples', 'spec']);
62
+ /**
63
+ * Test-file naming conventions, as ANCHORED patterns.
64
+ *
65
+ * Anchoring matters: a bare `includes('test_')` also matches `latest_parser.rs`,
66
+ * `contest_runner.ts`, and `fastest_path.rs`, silently dropping production files
67
+ * from the analysis entirely. `test_` is a Python/Rust *prefix* convention, so it
68
+ * only counts at the start of the basename.
69
+ */
70
+ const TEST_FILENAME_PATTERNS = [
71
+ /\.test\./i, // foo.test.ts
72
+ /\.spec\./i, // foo.spec.ts
73
+ /_test\./i, // foo_test.rs, foo_test.go
74
+ /_spec\./i, // foo_spec.rb
75
+ /^test_/i, // test_foo.py (prefix only — NOT `latest_parser`)
76
+ /^test\./i, // test.ts
77
+ /^conftest\./i, // pytest fixture module — support code, not production
78
+ ];
79
+ /**
80
+ * Is this path test code rather than production code?
81
+ *
82
+ * #569 work item: "Exclude `tests/` files from 'uncovered production code'".
83
+ * Coverage *of* a test file is not a meaningful metric — reporting
84
+ * `tests/verifier_matrix.rs` at 79.2% with its own gap entry sends a developer
85
+ * to write tests for their tests.
86
+ *
87
+ * Erring in either direction costs something: a false negative reports test code
88
+ * as a production gap (the original bug), a false positive silently drops real
89
+ * production code from the denominator. Hence anchored patterns, not substrings.
90
+ */
91
+ export function isTestPath(filePath, rootDir) {
92
+ const normalized = filePath.split(path.sep).join('/');
93
+ const basename = path.basename(normalized);
94
+ if (TEST_FILENAME_PATTERNS.some(p => p.test(basename)))
95
+ return true;
96
+ // Directory check must run on the path RELATIVE to the analysis root.
97
+ // Against the absolute path, a project that merely *lives* under a directory
98
+ // called `tests` — `~/examples/myapp`, a CI workspace at `/build/spec/proj`,
99
+ // a monorepo `packages/test-utils/` — has every one of its source files
100
+ // classified as test code, and coverage analysis returns null for the whole
101
+ // project. Only directories *inside* the analyzed tree are meaningful.
102
+ let relative = normalized;
103
+ if (rootDir) {
104
+ const normalizedRoot = path.resolve(rootDir).split(path.sep).join('/');
105
+ const absolute = path.resolve(filePath).split(path.sep).join('/');
106
+ if (absolute === normalizedRoot || absolute.startsWith(`${normalizedRoot}/`)) {
107
+ relative = absolute.slice(normalizedRoot.length).replace(/^\//, '');
108
+ }
109
+ }
110
+ // Rust convention: `foo_test.rs` handled above; `tests/` dir handled here.
111
+ return relative.split('/').some(segment => TEST_DIRS.has(segment));
112
+ }
113
+ /**
114
+ * Blank out Rust string literals, char literals, and comments so brace counting
115
+ * sees only structural braces.
116
+ *
117
+ * Without this, a `#[cfg(test)]` module containing `assert_eq!("}", "}")` closes
118
+ * its range early, and every test line after that point is reported as uncovered
119
+ * *production* code — exactly the #569 failure this function exists to prevent.
120
+ * Characters are replaced with spaces rather than removed so line and column
121
+ * positions are preserved.
122
+ */
123
+ function maskRustLiteralsAndComments(source) {
124
+ const out = source.split('');
125
+ const n = source.length;
126
+ let i = 0;
127
+ const blank = (from, to) => {
128
+ for (let j = from; j < to && j < n; j++) {
129
+ if (source[j] !== '\n')
130
+ out[j] = ' ';
131
+ }
132
+ };
133
+ while (i < n) {
134
+ const ch = source[i];
135
+ // Line comment
136
+ if (ch === '/' && source[i + 1] === '/') {
137
+ const end = source.indexOf('\n', i);
138
+ const stop = end === -1 ? n : end;
139
+ blank(i, stop);
140
+ i = stop;
141
+ continue;
142
+ }
143
+ // Block comment (Rust allows nesting)
144
+ if (ch === '/' && source[i + 1] === '*') {
145
+ let depth = 0;
146
+ const start = i;
147
+ while (i < n) {
148
+ if (source[i] === '/' && source[i + 1] === '*') {
149
+ depth++;
150
+ i += 2;
151
+ continue;
152
+ }
153
+ if (source[i] === '*' && source[i + 1] === '/') {
154
+ depth--;
155
+ i += 2;
156
+ if (depth === 0)
157
+ break;
158
+ continue;
159
+ }
160
+ i++;
161
+ }
162
+ blank(start, i);
163
+ continue;
164
+ }
165
+ // Raw string: r"...", r#"..."#, br##"..."##.
166
+ // The slice must be wide enough for the longest realistic hash run — a
167
+ // 15-hash opener is 17 chars and would otherwise fall through to the normal
168
+ // string branch, which stops at the first internal quote and re-exposes any
169
+ // `}` after it.
170
+ const raw = /^b?r(#*)"/.exec(source.slice(i, i + 300));
171
+ if (raw) {
172
+ const terminator = `"${raw[1]}`;
173
+ const bodyStart = i + raw[0].length;
174
+ const end = source.indexOf(terminator, bodyStart);
175
+ const stop = end === -1 ? n : end + terminator.length;
176
+ blank(i, stop);
177
+ i = stop;
178
+ continue;
179
+ }
180
+ // Normal string literal
181
+ if (ch === '"') {
182
+ const start = i;
183
+ i++;
184
+ while (i < n) {
185
+ if (source[i] === '\\') {
186
+ i += 2;
187
+ continue;
188
+ }
189
+ if (source[i] === '"') {
190
+ i++;
191
+ break;
192
+ }
193
+ i++;
194
+ }
195
+ blank(start, i);
196
+ continue;
197
+ }
198
+ // Char literal. Must not swallow a lifetime (`&'a str`), so only treat it as
199
+ // a literal when a closing quote lands where a char literal would put one.
200
+ if (ch === "'") {
201
+ let stop = -1;
202
+ if (source[i + 1] === '\\') {
203
+ const close = source.indexOf("'", i + 2);
204
+ if (close !== -1 && close <= i + 5)
205
+ stop = close + 1;
206
+ }
207
+ else if (source[i + 2] === "'") {
208
+ stop = i + 3;
209
+ }
210
+ if (stop !== -1) {
211
+ blank(i, stop);
212
+ i = stop;
213
+ continue;
214
+ }
215
+ }
216
+ i++;
217
+ }
218
+ return out.join('');
219
+ }
220
+ /**
221
+ * Line ranges occupied by inline test code, 1-indexed and inclusive.
222
+ *
223
+ * Rust puts unit tests in the same file as the code under test, inside a
224
+ * `#[cfg(test)] mod tests { ... }` block. #569's first and worst symptom was
225
+ * exactly this: gap `gap-…-0` flagged `src/jwks.rs` 335–449 as "Missing test
226
+ * case", where line 335 is an `assert!` inside a *passing* test.
227
+ *
228
+ * Brace-matched rather than "assume the block runs to EOF", because a
229
+ * `#[cfg(test)]` module is not always last in the file.
230
+ */
231
+ export function findInlineTestRanges(content, ext) {
232
+ if (ext !== '.rs')
233
+ return [];
234
+ // Brace-match against a copy with strings/chars/comments masked out. Counting
235
+ // a `}` inside `assert_eq!("}", "}")` closes the range early and re-exposes
236
+ // the rest of the test module as "uncovered production code". Attribute
237
+ // detection also runs on the MASKED text, so a `/* #[cfg(test)] */` in a
238
+ // comment doesn't cause real production code to be excluded.
239
+ const maskedLines = maskRustLiteralsAndComments(content).split('\n');
240
+ const ranges = [];
241
+ for (let i = 0; i < maskedLines.length; i++) {
242
+ if (!/#\s*\[\s*cfg\s*\(\s*test\s*\)\s*\]/.test(maskedLines[i]))
243
+ continue;
244
+ // The attribute must actually be attached to a `mod` — `#[cfg(test)]` also
245
+ // decorates consts, `use` statements, and single functions, and blindly
246
+ // taking "the next `{` within 10 lines" would then swallow the *following*
247
+ // production item's body and drop real code from the analysis.
248
+ let openLine = -1;
249
+ for (let j = i; j < Math.min(maskedLines.length, i + 10); j++) {
250
+ const line = maskedLines[j];
251
+ // Stop at a terminator before any `{`: that means this attribute applied
252
+ // to a non-block item (`#[cfg(test)] const X: &str = "...";`).
253
+ const braceAt = line.indexOf('{');
254
+ const semiAt = line.indexOf(';');
255
+ if (semiAt !== -1 && (braceAt === -1 || semiAt < braceAt))
256
+ break;
257
+ if (braceAt !== -1) {
258
+ // Only a module body counts. Look for `mod` between the attribute and
259
+ // the brace.
260
+ const headers = maskedLines.slice(i, j + 1).join(' ');
261
+ if (/\bmod\s+\w+/.test(headers))
262
+ openLine = j;
263
+ break;
264
+ }
265
+ }
266
+ if (openLine === -1)
267
+ continue;
268
+ let depth = 0;
269
+ let closeLine = -1;
270
+ for (let j = openLine; j < maskedLines.length; j++) {
271
+ for (const ch of maskedLines[j]) {
272
+ if (ch === '{')
273
+ depth++;
274
+ else if (ch === '}')
275
+ depth--;
276
+ }
277
+ if (depth <= 0) {
278
+ closeLine = j;
279
+ break;
280
+ }
281
+ }
282
+ ranges.push([i + 1, (closeLine === -1 ? maskedLines.length - 1 : closeLine) + 1]);
283
+ i = closeLine === -1 ? maskedLines.length : closeLine;
284
+ }
285
+ return ranges;
286
+ }
287
+ /**
288
+ * Effective line count for a file.
289
+ *
290
+ * #569 work item: "Never emit a line number beyond the file's length."
291
+ * `content.split('\n')` on a file with a trailing newline yields one extra
292
+ * empty element — which is how a 448-line `jwks.rs` produced a gap ending at
293
+ * line 449, and a 292-line `verify.rs` one ending at 293.
294
+ */
295
+ export function countLines(content) {
296
+ if (content.length === 0)
297
+ return 0;
298
+ const parts = content.split('\n');
299
+ if (parts[parts.length - 1] === '')
300
+ parts.pop();
301
+ return parts.length;
302
+ }
303
+ // ============================================================================
304
+ // Rust: real instrumentation
305
+ // ============================================================================
306
+ /**
307
+ * Find the Rust crate/workspace root for a target, or null if there isn't one.
308
+ *
309
+ * Walks UP from the target rather than only checking the target itself: the
310
+ * common invocation is `analyze(target: "src/")` or a package subdirectory, and
311
+ * `Cargo.toml` lives at the crate root. Checking only the target meant every
312
+ * such call silently skipped real instrumentation and fell through to labelled
313
+ * estimation — a measurement quietly downgraded to a guess.
314
+ *
315
+ * Bounded to `maxDepth` ancestors so a stray target can't walk to `/`.
316
+ */
317
+ export function findCargoRoot(targetPath, maxDepth = 6) {
318
+ let dir = path.resolve(targetPath);
319
+ try {
320
+ // A target that doesn't exist must NOT resolve to its nearest crate — that
321
+ // would run a full-crate `cargo llvm-cov` for a typo'd path and report the
322
+ // whole crate's coverage as if it were the requested target's.
323
+ if (!fs.existsSync(dir))
324
+ return null;
325
+ if (!fs.statSync(dir).isDirectory())
326
+ dir = path.dirname(dir);
327
+ }
328
+ catch {
329
+ return null;
330
+ }
331
+ for (let i = 0; i <= maxDepth; i++) {
332
+ if (fs.existsSync(path.join(dir, 'Cargo.toml')))
333
+ return dir;
334
+ const parent = path.dirname(dir);
335
+ if (parent === dir)
336
+ break; // reached filesystem root
337
+ dir = parent;
338
+ }
339
+ return null;
340
+ }
341
+ /** Is there at least one `.rs` file in this subtree? Bounded, early-exit. */
342
+ function containsRustSources(dir, depth = 0) {
343
+ if (depth > 4)
344
+ return false;
345
+ let entries;
346
+ try {
347
+ entries = fs.readdirSync(dir, { withFileTypes: true });
348
+ }
349
+ catch {
350
+ return false;
351
+ }
352
+ for (const entry of entries) {
353
+ if (entry.isFile() && path.extname(entry.name) === '.rs')
354
+ return true;
355
+ }
356
+ for (const entry of entries) {
357
+ if (entry.isDirectory() && !SKIP_DIRS.has(entry.name)) {
358
+ if (containsRustSources(path.join(dir, entry.name), depth + 1))
359
+ return true;
360
+ }
361
+ }
362
+ return false;
363
+ }
364
+ /**
365
+ * Does this target belong to a Rust crate/workspace *and* actually contain Rust
366
+ * code?
367
+ *
368
+ * Both halves are load-bearing. Without the upward walk, `analyze(target:"src/")`
369
+ * on a crate skips instrumentation. Without the `.rs` check, a polyglot monorepo
370
+ * with a `Cargo.toml` at its root would route `analyze(target:"frontend/")`
371
+ * through `cargo llvm-cov` and return whole-crate Rust coverage for a
372
+ * TypeScript directory.
373
+ */
374
+ export function isRustProject(targetPath) {
375
+ const root = findCargoRoot(targetPath);
376
+ if (root === null)
377
+ return false;
378
+ const resolved = path.resolve(targetPath);
379
+ // The crate root itself always qualifies; a subdirectory must hold Rust code.
380
+ return resolved === root || containsRustSources(resolved);
381
+ }
382
+ /**
383
+ * Run `cargo llvm-cov` and parse its LCOV output.
384
+ *
385
+ * #569 work item: "Detect language and delegate to real instrumentation where
386
+ * available." LCOV rather than `--json`: it carries per-line `DA:` records (so
387
+ * we get genuine uncovered line numbers for gap detection) plus `BRF:`/`BRH:`
388
+ * and `FNF:`/`FNH:`, and it reuses `parseLcovInfo`, which is already exercised
389
+ * by the JS path.
390
+ *
391
+ * Returns `null` — never throws, never guesses — when cargo or the
392
+ * `cargo-llvm-cov` subcommand is unavailable or the run fails. The caller then
393
+ * decides whether to estimate (and label it) or report nothing.
394
+ */
395
+ export async function collectRustCoverage(targetPath, options = {}) {
396
+ // Running cargo compiles and executes code from the analyzed repository
397
+ // (test binaries, `build.rs`, `.cargo/config.toml` runner directives).
398
+ // Honor the opt-out before doing any of that.
399
+ if (isCoverageExecDisabled())
400
+ return null;
401
+ const { execSync } = await import('child_process');
402
+ const timeout = options.timeoutMs ?? 300000;
403
+ // cargo must run from the crate root, not from whatever subdirectory the
404
+ // caller happened to point at.
405
+ const crateRoot = findCargoRoot(targetPath);
406
+ if (!crateRoot)
407
+ return null;
408
+ try {
409
+ execSync('cargo llvm-cov --version', {
410
+ cwd: crateRoot, timeout: 30000, stdio: ['pipe', 'pipe', 'pipe'],
411
+ });
412
+ }
413
+ catch {
414
+ return null; // cargo-llvm-cov not installed — not an error, just unavailable.
415
+ }
416
+ const outPath = path.join(fs.mkdtempSync(path.join(os.tmpdir(), 'aqe-rust-cov-')), 'lcov.info');
417
+ try {
418
+ execSync(`cargo llvm-cov --lcov --output-path ${JSON.stringify(outPath)}`, {
419
+ cwd: crateRoot, timeout, encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'],
420
+ });
421
+ if (!fs.existsSync(outPath))
422
+ return null;
423
+ const parsed = parseLcovInfo(fs.readFileSync(outPath, 'utf-8'));
424
+ // Drop test targets from the production-coverage view (#569 contradiction 3).
425
+ const productionFiles = parsed.files.filter(f => !isTestPath(f.path, crateRoot));
426
+ if (productionFiles.length === 0)
427
+ return null;
428
+ const data = withRecomputedSummary(productionFiles);
429
+ const branchDataCollected = productionFiles.some(f => f.branches.total > 0);
430
+ return {
431
+ data,
432
+ provenance: {
433
+ method: 'cargo-llvm-cov',
434
+ estimated: false,
435
+ branchDataCollected,
436
+ functionDataCollected: productionFiles.some(f => f.functions.total > 0),
437
+ notes: branchDataCollected
438
+ ? []
439
+ : [
440
+ 'cargo-llvm-cov reported no branch data (Rust branch coverage requires a ' +
441
+ 'nightly toolchain with -Z coverage-options=branch). Branch coverage is ' +
442
+ 'reported as null rather than assumed.',
443
+ ],
444
+ },
445
+ };
446
+ }
447
+ catch {
448
+ return null;
449
+ }
450
+ finally {
451
+ try {
452
+ fs.rmSync(path.dirname(outPath), { recursive: true, force: true });
453
+ }
454
+ catch { /* best-effort */ }
455
+ }
456
+ }
457
+ // ============================================================================
458
+ // Static estimation (clearly labelled as such)
459
+ // ============================================================================
460
+ /**
461
+ * Per-language patterns for counting declarations.
462
+ *
463
+ * #569 contradictions 4 and 5 both trace to a single JS-shaped regex,
464
+ * `/\b(function|=>)\b/`, applied to every language. On Rust it matched nothing,
465
+ * so `functionCount` fell to its `Math.max(..., 1)` floor and every file
466
+ * reported 0% function coverage — right next to a 100% branch figure derived
467
+ * from a formula that saturates. Language-specific patterns at least count the
468
+ * right things; the result is still an estimate and still labelled one.
469
+ */
470
+ const LANGUAGE_PATTERNS = {
471
+ '.rs': { fn: /\bfn\s+\w+/g, branch: /\b(if|match|while|for)\b|\?\?|\|\||&&/g },
472
+ '.go': { fn: /\bfunc\s+\w*/g, branch: /\b(if|switch|case|for|select)\b|\|\||&&/g },
473
+ '.py': { fn: /\b(def|lambda)\b/g, branch: /\b(if|elif|for|while|except)\b|\band\b|\bor\b/g },
474
+ '.java': { fn: /\b(public|private|protected|static)[\w<>,\s[\]]+\w+\s*\(/g, branch: /\b(if|switch|case|for|while|catch)\b|\|\||&&/g },
475
+ '.rb': { fn: /\bdef\s+\w+/g, branch: /\b(if|elsif|unless|case|when|while)\b|\|\||&&/g },
476
+ default: { fn: /\bfunction\b|=>|\b\w+\s*\([^)]*\)\s*\{/g, branch: /\b(if|switch|case|for|while|catch)\b|\?\?|\|\||&&/g },
477
+ };
478
+ function patternsFor(ext) {
479
+ return LANGUAGE_PATTERNS[ext] ?? LANGUAGE_PATTERNS.default;
480
+ }
481
+ function countMatches(content, pattern) {
482
+ return (content.match(new RegExp(pattern.source, pattern.flags)) || []).length;
483
+ }
484
+ /** Recompute the aggregate summary from a file list. */
485
+ function withRecomputedSummary(files) {
486
+ const sum = (pick) => files.reduce((s, f) => s + pick(f), 0);
487
+ const safeDiv = (a, b) => (b > 0 ? Math.round((a / b) * 100) : 0);
488
+ const totalLines = sum(f => f.lines.total);
489
+ const coveredLines = sum(f => f.lines.covered);
490
+ return {
491
+ files,
492
+ summary: {
493
+ line: safeDiv(coveredLines, totalLines),
494
+ branch: safeDiv(sum(f => f.branches.covered), sum(f => f.branches.total)),
495
+ function: safeDiv(sum(f => f.functions.covered), sum(f => f.functions.total)),
496
+ statement: safeDiv(coveredLines, totalLines),
497
+ files: files.length,
498
+ },
499
+ };
500
+ }
501
+ function walkSourceFiles(targetPath) {
502
+ const found = [];
503
+ // Classification is relative to the analysis root (see isTestPath).
504
+ const rootDir = targetPath;
505
+ function walk(dir, depth) {
506
+ if (depth > 6)
507
+ return;
508
+ let entries;
509
+ try {
510
+ entries = fs.readdirSync(dir, { withFileTypes: true });
511
+ }
512
+ catch {
513
+ return;
514
+ }
515
+ for (const entry of entries) {
516
+ const full = path.join(dir, entry.name);
517
+ if (entry.isDirectory()) {
518
+ if (SKIP_DIRS.has(entry.name) || TEST_DIRS.has(entry.name))
519
+ continue;
520
+ walk(full, depth + 1);
521
+ }
522
+ else if (entry.isFile()) {
523
+ if (!SOURCE_EXTENSIONS.has(path.extname(entry.name)))
524
+ continue;
525
+ if (isTestPath(full, rootDir))
526
+ continue;
527
+ found.push(full);
528
+ }
529
+ }
530
+ }
531
+ walk(targetPath, 0);
532
+ return found;
533
+ }
534
+ /**
535
+ * Static coverage estimate from source shape, for when no instrumentation could
536
+ * be run.
537
+ *
538
+ * This is a *guess*. It is returned with `estimated: true` and
539
+ * `branchDataCollected: false` so no caller can mistake it for a measurement —
540
+ * which is the core of #569, where a caller had "no signal that no
541
+ * instrumentation ran".
542
+ *
543
+ * Fixed here relative to the pre-#569 version:
544
+ * - trailing-newline off-by-one no longer emits line numbers past EOF
545
+ * - `#[cfg(test)]` blocks and `tests/` files are excluded from both the
546
+ * denominator and the gap list
547
+ * - declaration counting is language-aware instead of JS-shaped
548
+ * - branch counts are reported as uncollected rather than invented
549
+ */
550
+ export function buildEstimatedCoverage(targetPath) {
551
+ if (!fs.existsSync(targetPath) || !fs.statSync(targetPath).isDirectory())
552
+ return null;
553
+ const sourceFiles = walkSourceFiles(targetPath);
554
+ if (sourceFiles.length === 0)
555
+ return null;
556
+ const files = sourceFiles.map(filePath => {
557
+ let content = '';
558
+ try {
559
+ content = fs.readFileSync(filePath, 'utf-8');
560
+ }
561
+ catch { /* unreadable — treat as empty */ }
562
+ const ext = path.extname(filePath);
563
+ const totalLines = countLines(content);
564
+ // Lines belonging to inline test modules are not production code and must
565
+ // never be reported as an uncovered production gap.
566
+ const testRanges = findInlineTestRanges(content, ext);
567
+ const isTestLine = (line) => testRanges.some(([lo, hi]) => line >= lo && line <= hi);
568
+ const testLineCount = testRanges.reduce((s, [lo, hi]) => s + (hi - lo + 1), 0);
569
+ const productionLines = Math.max(totalLines - testLineCount, 0);
570
+ const patterns = patternsFor(ext);
571
+ const functionCount = countMatches(content, patterns.fn);
572
+ // Presence of *any* test signal for this file: a co-located test module, or
573
+ // a sibling/mirrored test file.
574
+ const hasInlineTests = testRanges.length > 0;
575
+ const hasTestFile = hasSiblingTestFile(filePath);
576
+ const hasTest = hasInlineTests || hasTestFile;
577
+ const branchCount = countMatches(content, patterns.branch);
578
+ const complexityPenalty = Math.min(branchCount * 0.005, 0.15);
579
+ const sizePenalty = Math.min(productionLines * 0.0001, 0.1);
580
+ const coverageRate = Math.max(0.05, Math.min(0.95, hasTest ? 0.85 - complexityPenalty - sizePenalty : 0.20));
581
+ const coveredLines = Math.floor(productionLines * coverageRate);
582
+ // Uncovered lines are drawn from real production line numbers only:
583
+ // within [1, totalLines] and never inside a test block.
584
+ const candidates = [];
585
+ for (let line = 1; line <= totalLines; line++) {
586
+ if (!isTestLine(line))
587
+ candidates.push(line);
588
+ }
589
+ const uncoveredLines = candidates.slice(coveredLines);
590
+ return {
591
+ path: filePath,
592
+ lines: { covered: coveredLines, total: productionLines },
593
+ // Branch and function data were NOT collected. Reporting 0/0 keeps the
594
+ // aggregate honest; the provenance flags tell the caller to render null.
595
+ branches: { covered: 0, total: 0 },
596
+ functions: { covered: 0, total: functionCount },
597
+ statements: { covered: coveredLines, total: productionLines },
598
+ uncoveredLines,
599
+ uncoveredBranches: [],
600
+ };
601
+ });
602
+ return {
603
+ data: withRecomputedSummary(files),
604
+ provenance: {
605
+ method: 'static-estimation',
606
+ estimated: true,
607
+ branchDataCollected: false,
608
+ functionDataCollected: false,
609
+ notes: [
610
+ 'No instrumentation ran. These numbers are a STATIC ESTIMATE derived from ' +
611
+ 'source shape (file size, declaration counts, presence of a test file) — ' +
612
+ 'they are not measured coverage and must not be reported as such.',
613
+ 'Branch and function coverage were not collected and are reported as null.',
614
+ ],
615
+ },
616
+ };
617
+ }
618
+ /** Does a sibling or mirrored test file exist for this source file? */
619
+ function hasSiblingTestFile(filePath) {
620
+ const ext = path.extname(filePath);
621
+ const stem = filePath.slice(0, -ext.length);
622
+ const candidates = [
623
+ `${stem}.test${ext}`,
624
+ `${stem}.spec${ext}`,
625
+ `${stem}_test${ext}`,
626
+ `${stem}.test${ext}`.replace('/src/', '/tests/'),
627
+ `${stem}.spec${ext}`.replace('/src/', '/tests/'),
628
+ `${stem}${ext}`.replace('/src/', '/tests/'),
629
+ ];
630
+ return candidates.some(c => {
631
+ try {
632
+ return fs.existsSync(c);
633
+ }
634
+ catch {
635
+ return false;
636
+ }
637
+ });
638
+ }
639
+ //# sourceMappingURL=coverage-collection.js.map