agentic-qe 3.15.4 → 3.15.5

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 (402) hide show
  1. package/.claude/skills/skills-manifest.json +1 -1
  2. package/CHANGELOG.md +70 -0
  3. package/assets/skills/skills-manifest.json +1 -1
  4. package/dist/bridge/captured-experience-bridge.js +7 -9
  5. package/dist/cli/bundle.js +5 -5
  6. package/dist/cli/chunks/adapter-EGIPTX5H.js +2 -0
  7. package/dist/cli/chunks/{agent-booster-wasm-MHJBRXMK.js → agent-booster-wasm-CCTTGCQS.js} +2 -2
  8. package/dist/cli/chunks/{agent-handler-G64SD7J2.js → agent-handler-DHYUF3NX.js} +2 -2
  9. package/dist/cli/chunks/{agent-memory-branch-G4UXFPKH.js → agent-memory-branch-642W7CYX.js} +2 -2
  10. package/dist/cli/chunks/aqe-learning-engine-WP4GCBDT.js +2 -0
  11. package/dist/cli/chunks/{arena-QJMKYPHS.js → arena-MUCC7UUN.js} +4 -4
  12. package/dist/cli/chunks/{arena-63M3M6EW.js → arena-NW2JVAFY.js} +2 -2
  13. package/dist/cli/chunks/{audit-UDFVTWSX.js → audit-VKQTZJAA.js} +3 -3
  14. package/dist/cli/chunks/base-6ORFD62I.js +2 -0
  15. package/dist/cli/chunks/{better-sqlite3-JLX2G56I.js → better-sqlite3-7ZUFVWLQ.js} +2 -2
  16. package/dist/cli/chunks/{brain-handler-PWF32LLW.js → brain-handler-7LKAWSBI.js} +3 -3
  17. package/dist/cli/chunks/{branch-enumerator-PB7QWXDP.js → branch-enumerator-HUNXJKM4.js} +2 -2
  18. package/dist/cli/chunks/{browser-CYNV2F3U.js → browser-ZSZEYUDP.js} +2 -2
  19. package/dist/cli/chunks/browser-workflow-PIXGERWP.js +2 -0
  20. package/dist/cli/chunks/{chunk-RWZ4F44Y.js → chunk-2KWI3MT3.js} +2 -2
  21. package/dist/cli/chunks/{chunk-UORI2CZ4.js → chunk-2WFTZSRT.js} +1 -1
  22. package/dist/cli/chunks/{chunk-HCDTLV5J.js → chunk-2XYTS2WY.js} +2 -2
  23. package/dist/cli/chunks/{chunk-DBIK4OFX.js → chunk-35MDATQE.js} +1 -1
  24. package/dist/cli/chunks/{chunk-54XTJBHV.js → chunk-3AYYGR6W.js} +1 -1
  25. package/dist/cli/chunks/{chunk-SJB4KMZS.js → chunk-3DTEQHFB.js} +3 -3
  26. package/dist/cli/chunks/{chunk-RG67RZIX.js → chunk-3OAQPN2N.js} +2 -2
  27. package/dist/cli/chunks/{chunk-2DRMTRBM.js → chunk-3QD7U3FY.js} +2 -2
  28. package/dist/cli/chunks/{chunk-VMSO6DMF.js → chunk-3SH23PS3.js} +2 -2
  29. package/dist/cli/chunks/{chunk-RJ5CZ7B6.js → chunk-3YASZPLO.js} +2 -2
  30. package/dist/cli/chunks/{chunk-JFQDWAU3.js → chunk-3YNP33GB.js} +2 -2
  31. package/dist/cli/chunks/{chunk-I53365HG.js → chunk-47GEI2LT.js} +3 -3
  32. package/dist/cli/chunks/{chunk-PCWZCXBD.js → chunk-4AZP7ZCW.js} +2 -2
  33. package/dist/cli/chunks/{chunk-54ITMOFM.js → chunk-4PT5KNXL.js} +4 -4
  34. package/dist/cli/chunks/{chunk-SIUUAKCE.js → chunk-4UXPDV7E.js} +1 -1
  35. package/dist/cli/chunks/{chunk-LZSLJJII.js → chunk-4XSCZVON.js} +2 -2
  36. package/dist/cli/chunks/{chunk-DFJGXXCL.js → chunk-5BOZCMXZ.js} +1 -1
  37. package/dist/cli/chunks/{chunk-B7J3O2WM.js → chunk-644DFAGS.js} +1 -1
  38. package/dist/cli/chunks/{chunk-2ICC4H6K.js → chunk-663ZFPUL.js} +2 -2
  39. package/dist/cli/chunks/{chunk-YUWUFYHK.js → chunk-6JFGB2JB.js} +1 -1
  40. package/dist/cli/chunks/{chunk-MBV57LKC.js → chunk-6LG5UEQE.js} +2 -2
  41. package/dist/cli/chunks/{chunk-LRTF5RMG.js → chunk-6UYN5PHA.js} +4 -4
  42. package/dist/cli/chunks/{chunk-5SS2Z7JC.js → chunk-6ZIDZ4TJ.js} +2 -2
  43. package/dist/cli/chunks/{chunk-2534PXIV.js → chunk-7BIYJRQJ.js} +2 -2
  44. package/dist/cli/chunks/{chunk-HX5KQK7I.js → chunk-7EZLOC4K.js} +2 -2
  45. package/dist/cli/chunks/{chunk-ZAOQIVHG.js → chunk-7YB2KELI.js} +2 -2
  46. package/dist/cli/chunks/{chunk-SOSJFEFB.js → chunk-A2WOQO2N.js} +2 -2
  47. package/dist/cli/chunks/{chunk-M6SJALLA.js → chunk-A337MD3C.js} +2 -2
  48. package/dist/cli/chunks/{chunk-YZ2AGC7O.js → chunk-A5J4XJS6.js} +1 -1
  49. package/dist/cli/chunks/{chunk-PEA4DVXW.js → chunk-AQN5EDBM.js} +1 -1
  50. package/dist/cli/chunks/{chunk-EGHK6NMH.js → chunk-AUZXRFOX.js} +2 -2
  51. package/dist/cli/chunks/{chunk-BBKLVHDQ.js → chunk-B2UHTA4Q.js} +1 -1
  52. package/dist/cli/chunks/{chunk-LY53L6NH.js → chunk-BBL6YXD3.js} +2 -2
  53. package/dist/cli/chunks/chunk-BJ5P4IV2.js +2 -0
  54. package/dist/cli/chunks/{chunk-I43QRLLB.js → chunk-BMWAWZAN.js} +2 -2
  55. package/dist/cli/chunks/chunk-BO4PKNYP.js +102 -0
  56. package/dist/cli/chunks/{chunk-PMXWDTDK.js → chunk-BY646JOM.js} +2 -2
  57. package/dist/cli/chunks/{chunk-OFQDM73J.js → chunk-BYXNHGQC.js} +2 -2
  58. package/dist/cli/chunks/{chunk-73MTUM6F.js → chunk-BZFT4QDQ.js} +2 -2
  59. package/dist/cli/chunks/{chunk-RA3MI5WK.js → chunk-CFPR24YK.js} +2 -2
  60. package/dist/cli/chunks/{chunk-WEDVLKRB.js → chunk-CQMHDAJS.js} +2 -2
  61. package/dist/cli/chunks/{chunk-HFSBONCS.js → chunk-CR2JUANW.js} +2 -2
  62. package/dist/cli/chunks/{chunk-BY3IL56R.js → chunk-CXOXUBYU.js} +1 -1
  63. package/dist/cli/chunks/{chunk-AOKSLWON.js → chunk-D3G2NN7F.js} +77 -78
  64. package/dist/cli/chunks/{chunk-I5A3HGO6.js → chunk-DEGWCUMY.js} +2 -2
  65. package/dist/cli/chunks/{chunk-CQ3WSTJ2.js → chunk-DFPL5N3Q.js} +2 -2
  66. package/dist/cli/chunks/{chunk-TVQPYP2Z.js → chunk-DL5JENWD.js} +3 -3
  67. package/dist/cli/chunks/{chunk-V3NZ23X6.js → chunk-DLY4YEN3.js} +2 -2
  68. package/dist/cli/chunks/{chunk-HEKCN5XQ.js → chunk-DPV33C77.js} +2 -2
  69. package/dist/cli/chunks/{chunk-KOLHZSEC.js → chunk-DPYDUKVZ.js} +2 -2
  70. package/dist/cli/chunks/{chunk-3MSBVOYW.js → chunk-DTJODGCE.js} +2 -2
  71. package/dist/cli/chunks/{chunk-MGH4XIHH.js → chunk-DWZI3IVB.js} +2 -2
  72. package/dist/cli/chunks/{chunk-DPL4ZXTE.js → chunk-DXVZBJE4.js} +1 -1
  73. package/dist/cli/chunks/{chunk-LXYTC62V.js → chunk-E4VIVMDL.js} +2 -2
  74. package/dist/cli/chunks/{chunk-DVE5SM5G.js → chunk-EAYQCBXL.js} +3 -3
  75. package/dist/cli/chunks/{chunk-BY5PLEPZ.js → chunk-EOR3RECZ.js} +2 -2
  76. package/dist/cli/chunks/chunk-ERGWWI4Y.js +3 -0
  77. package/dist/cli/chunks/{chunk-LPSE6DOQ.js → chunk-EUEHBERE.js} +1 -1
  78. package/dist/cli/chunks/{chunk-3BDDOFYW.js → chunk-EVCFUYYK.js} +2 -2
  79. package/dist/cli/chunks/{chunk-SZWXUG36.js → chunk-FBEXG4HD.js} +2 -2
  80. package/dist/cli/chunks/{chunk-5GWTJJEO.js → chunk-FE3AIZI6.js} +1 -1
  81. package/dist/cli/chunks/{chunk-4GLR2S2M.js → chunk-FHUJCVT3.js} +2 -2
  82. package/dist/cli/chunks/{chunk-6TMUZGM2.js → chunk-FNAYDITO.js} +1 -1
  83. package/dist/cli/chunks/{chunk-U2E5F3VZ.js → chunk-FQKEZVN6.js} +2 -2
  84. package/dist/cli/chunks/{chunk-2LL35V3A.js → chunk-FWYJ6UDX.js} +2 -2
  85. package/dist/cli/chunks/{chunk-ISASRHZP.js → chunk-GGDKOJVF.js} +2 -2
  86. package/dist/cli/chunks/{chunk-ZKXZTIVF.js → chunk-GKPRECLL.js} +2 -2
  87. package/dist/cli/chunks/{chunk-OHH6BUZK.js → chunk-GRIPCYW5.js} +1 -1
  88. package/dist/cli/chunks/{chunk-XZ5Z56OP.js → chunk-GTSOFCMQ.js} +1 -1
  89. package/dist/cli/chunks/{chunk-2MU4WCMQ.js → chunk-HBYQYGXP.js} +2 -2
  90. package/dist/cli/chunks/{chunk-YQ6BK7QC.js → chunk-HGBJ2QQ4.js} +2 -2
  91. package/dist/cli/chunks/{chunk-N6CRIUTO.js → chunk-HIUNCO2W.js} +2 -2
  92. package/dist/cli/chunks/{chunk-5H7MR6HP.js → chunk-HLFDC4SF.js} +1 -1
  93. package/dist/cli/chunks/{chunk-GAXTPQCZ.js → chunk-HPLMX62I.js} +2 -2
  94. package/dist/cli/chunks/{chunk-WO4NSPLX.js → chunk-IHFUEPZH.js} +2 -2
  95. package/dist/cli/chunks/{chunk-ADF6LGHZ.js → chunk-IJ2EXSMO.js} +2 -2
  96. package/dist/cli/chunks/{chunk-GLKLEHK3.js → chunk-IJOFZBXD.js} +2 -2
  97. package/dist/cli/chunks/{chunk-IKWAPHJA.js → chunk-JANLATHN.js} +2 -2
  98. package/dist/cli/chunks/{chunk-J3RNVHDH.js → chunk-JCC7QEKZ.js} +1 -1
  99. package/dist/cli/chunks/{chunk-C5EN5WB6.js → chunk-JI77KJP7.js} +1 -1
  100. package/dist/cli/chunks/{chunk-B7GJXQD2.js → chunk-JNMUVBAJ.js} +2 -2
  101. package/dist/cli/chunks/{chunk-ZP6ANUP7.js → chunk-JYY7AYGA.js} +1 -1
  102. package/dist/cli/chunks/{chunk-6HTO4BLV.js → chunk-KHCALIFP.js} +2 -2
  103. package/dist/cli/chunks/{chunk-BND6M2JX.js → chunk-KJ3KBP24.js} +2 -2
  104. package/dist/cli/chunks/{chunk-O7TMY4GS.js → chunk-KZVJW2SD.js} +2 -2
  105. package/dist/cli/chunks/chunk-L336HFFE.js +2 -0
  106. package/dist/cli/chunks/{chunk-W3PPYNHF.js → chunk-L375O3CZ.js} +2 -2
  107. package/dist/cli/chunks/{chunk-PJAXWCFC.js → chunk-L6SVCNXK.js} +1 -1
  108. package/dist/cli/chunks/{chunk-VAXQUD5G.js → chunk-LNO5IWGH.js} +1 -1
  109. package/dist/cli/chunks/{chunk-CFXFGQEN.js → chunk-LRASYSGV.js} +2 -2
  110. package/dist/cli/chunks/{chunk-MVTUFPM2.js → chunk-MB4VFAJC.js} +2 -2
  111. package/dist/cli/chunks/{chunk-SCL2OYN7.js → chunk-MNQ36MAF.js} +2 -2
  112. package/dist/cli/chunks/{chunk-W6TJXK5Y.js → chunk-MQGEZA2A.js} +2 -2
  113. package/dist/cli/chunks/{chunk-73PCVMGA.js → chunk-MS3Z2CP5.js} +2 -2
  114. package/dist/cli/chunks/{chunk-WI5AEB7Q.js → chunk-N2TJNIHA.js} +2 -2
  115. package/dist/cli/chunks/{chunk-DEJM2P5K.js → chunk-NF6AFIAX.js} +1 -1
  116. package/dist/cli/chunks/{chunk-JL3TI43V.js → chunk-NLDFNAOS.js} +2 -2
  117. package/dist/cli/chunks/{chunk-UK5HY6LC.js → chunk-NMJVG22Z.js} +1 -1
  118. package/dist/cli/chunks/{chunk-WW6WUMS7.js → chunk-OGYWWZU7.js} +2 -2
  119. package/dist/cli/chunks/{chunk-3C2BFLYC.js → chunk-ONCH5AXU.js} +3 -3
  120. package/dist/cli/chunks/{chunk-OG4KHX7S.js → chunk-OQDC7GCM.js} +2 -2
  121. package/dist/cli/chunks/{chunk-3ZIVBTX6.js → chunk-ORTBRO7F.js} +2 -2
  122. package/dist/cli/chunks/{chunk-NIJMLEAX.js → chunk-OU4ZAWCC.js} +2 -2
  123. package/dist/cli/chunks/{chunk-FDK2GF4G.js → chunk-OW42F2TX.js} +2 -2
  124. package/dist/cli/chunks/{chunk-TB22Y3WW.js → chunk-PCCIZFD7.js} +1 -1
  125. package/dist/cli/chunks/{chunk-BZWZTGMF.js → chunk-PDPEMBFV.js} +2 -2
  126. package/dist/cli/chunks/{chunk-D7RVZ5C2.js → chunk-PHAQWAEV.js} +2 -2
  127. package/dist/cli/chunks/{chunk-P7GM3EE7.js → chunk-PHP4UJYP.js} +1 -1
  128. package/dist/cli/chunks/{chunk-6QPW4OVH.js → chunk-PURHGLEC.js} +1 -1
  129. package/dist/cli/chunks/{chunk-BPGFCUDO.js → chunk-PVAE65B4.js} +1 -1
  130. package/dist/cli/chunks/{chunk-7X2IVMXN.js → chunk-QPV3OKX2.js} +2 -2
  131. package/dist/cli/chunks/{chunk-DAYMT7TH.js → chunk-QXY3IRBW.js} +3 -3
  132. package/dist/cli/chunks/{chunk-QIAX3JJB.js → chunk-RCXMUEZN.js} +2 -2
  133. package/dist/cli/chunks/{chunk-RB2SL5GD.js → chunk-RMJ7PJOS.js} +2 -2
  134. package/dist/cli/chunks/{chunk-FRBCX46J.js → chunk-RUJLVJDE.js} +2 -2
  135. package/dist/cli/chunks/{chunk-S5D3HCGN.js → chunk-RUSLEOMC.js} +2 -2
  136. package/dist/cli/chunks/chunk-SAPIRK2G.js +3 -0
  137. package/dist/cli/chunks/{chunk-A4OPQJ4A.js → chunk-SDWMLT7B.js} +5 -5
  138. package/dist/cli/chunks/{chunk-RJMBHZYL.js → chunk-SEZLYRCS.js} +1 -1
  139. package/dist/cli/chunks/{chunk-AHVN3UQZ.js → chunk-TDLKXLJC.js} +2 -2
  140. package/dist/cli/chunks/{chunk-EWUFVWRT.js → chunk-U4TV75AC.js} +2 -2
  141. package/dist/cli/chunks/{chunk-X5S5UEM6.js → chunk-U6OVPMQX.js} +2 -2
  142. package/dist/cli/chunks/{chunk-5B5D5KCV.js → chunk-UE22ODHN.js} +1 -1
  143. package/dist/cli/chunks/{chunk-I6E4X3L3.js → chunk-UXZEVIFX.js} +1 -1
  144. package/dist/cli/chunks/{chunk-DF4Y3HPO.js → chunk-V7GNUVYI.js} +1 -1
  145. package/dist/cli/chunks/{chunk-OOK6GPJR.js → chunk-VCKDVOPD.js} +2 -2
  146. package/dist/cli/chunks/{chunk-G3ZUB3HD.js → chunk-VH3EB6ZG.js} +2 -2
  147. package/dist/cli/chunks/{chunk-PB2WSCBW.js → chunk-VLOIEVER.js} +3 -3
  148. package/dist/cli/chunks/{chunk-7INP6HZH.js → chunk-VML4SG3X.js} +3 -3
  149. package/dist/cli/chunks/{chunk-K2VUYRMG.js → chunk-VRJPH3LG.js} +2 -2
  150. package/dist/cli/chunks/{chunk-RI4JPBZD.js → chunk-VYDNLQJN.js} +2 -2
  151. package/dist/cli/chunks/{chunk-35A22AUL.js → chunk-W3ZGNNDV.js} +1 -1
  152. package/dist/cli/chunks/{chunk-R47LNH5W.js → chunk-WC47GICZ.js} +2 -2
  153. package/dist/cli/chunks/{chunk-Z56QTRRB.js → chunk-WLIYWBQR.js} +2 -2
  154. package/dist/cli/chunks/{chunk-ZURYZEHX.js → chunk-WN55MNZ2.js} +2 -2
  155. package/dist/cli/chunks/chunk-WOZIXXY5.js +7 -0
  156. package/dist/cli/chunks/{chunk-NBMQOP2R.js → chunk-WR64BKUE.js} +1 -1
  157. package/dist/cli/chunks/{chunk-T3BMCEQR.js → chunk-WT3JC4A6.js} +2 -2
  158. package/dist/cli/chunks/{chunk-WYO5VN2L.js → chunk-X52TMBHU.js} +1 -1
  159. package/dist/cli/chunks/{chunk-6EHVPFHW.js → chunk-XIE7OHML.js} +1 -1
  160. package/dist/cli/chunks/{chunk-LOLAEDZD.js → chunk-XNEEYXR2.js} +2 -2
  161. package/dist/cli/chunks/{chunk-EY5IUF7U.js → chunk-XNHB6TLC.js} +2 -2
  162. package/dist/cli/chunks/{chunk-GJVRQBLI.js → chunk-XQRE2HWM.js} +2 -2
  163. package/dist/cli/chunks/{chunk-33IUCP34.js → chunk-Y2E3IJ53.js} +2 -2
  164. package/dist/cli/chunks/{chunk-6HO3XRXE.js → chunk-Y2WMPEUP.js} +2 -2
  165. package/dist/cli/chunks/{chunk-LGA6J4I4.js → chunk-Y7GPLOXB.js} +2 -2
  166. package/dist/cli/chunks/{chunk-76PRW2KY.js → chunk-YINFES3E.js} +2 -2
  167. package/dist/cli/chunks/{chunk-LJRZAALA.js → chunk-ZLBBX24Q.js} +133 -133
  168. package/dist/cli/chunks/{chunk-ASKPTGUU.js → chunk-ZT3GUYM5.js} +2 -2
  169. package/dist/cli/chunks/{chunk-XHCCH7UC.js → chunk-ZTC5FBL6.js} +3 -3
  170. package/dist/cli/chunks/ci-KP4GZKJ7.js +81 -0
  171. package/dist/cli/chunks/ci-config-XDDZOOEI.js +2 -0
  172. package/dist/cli/chunks/{ci-output-BMJABAEX.js → ci-output-7ZUQI4U6.js} +2 -2
  173. package/dist/cli/chunks/{circuit-breaker-GYD5CMJQ.js → circuit-breaker-ALXKCFAL.js} +2 -2
  174. package/dist/cli/chunks/{claude-flow-setup-MMOYVBVD.js → claude-flow-setup-RL7K2NI2.js} +2 -2
  175. package/dist/cli/chunks/client-C3KHVRM6.js +2 -0
  176. package/dist/cli/chunks/{cline-installer-B2SOZ44R.js → cline-installer-2Z2QQKC3.js} +2 -2
  177. package/dist/cli/chunks/{code-V3FIRAXD.js → code-QSZTDINQ.js} +4 -4
  178. package/dist/cli/chunks/{code-index-extractor-CV6A756Z.js → code-index-extractor-5CGR5D3Y.js} +2 -2
  179. package/dist/cli/chunks/{codex-installer-EUC6J47Y.js → codex-installer-7JLSEDE5.js} +2 -2
  180. package/dist/cli/chunks/{completions-DQQIBAHR.js → completions-U4NBSXEB.js} +2 -2
  181. package/dist/cli/chunks/{complexity-analyzer-HPXMXP5I.js → complexity-analyzer-WYZD2YSY.js} +2 -2
  182. package/dist/cli/chunks/{continuedev-installer-RCIYXH6V.js → continuedev-installer-UPXINJFT.js} +2 -2
  183. package/dist/cli/chunks/{copilot-installer-VUH32SHF.js → copilot-installer-WIVYQRIF.js} +2 -2
  184. package/dist/cli/chunks/core-handlers-KSQM6Q6S.js +2 -0
  185. package/dist/cli/chunks/{cost-tracker-YLCKLOAL.js → cost-tracker-RIN4JDDM.js} +2 -2
  186. package/dist/cli/chunks/coverage-SPFVHRRU.js +43 -0
  187. package/dist/cli/chunks/coverage-target-GSRBNHXE.js +2 -0
  188. package/dist/cli/chunks/cross-domain-router-CTGNOVCF.js +2 -0
  189. package/dist/cli/chunks/{cursor-installer-B42FN62K.js → cursor-installer-POM7NGCC.js} +2 -2
  190. package/dist/cli/chunks/{daemon-DECQRQII.js → daemon-HFGKQ6LB.js} +3 -3
  191. package/dist/cli/chunks/{daemon-IPTOSCHM.js → daemon-M5TD5Y6T.js} +4 -4
  192. package/dist/cli/chunks/{dag-attention-scheduler-RY7CDYSC.js → dag-attention-scheduler-HJXM7Q5P.js} +2 -2
  193. package/dist/cli/chunks/{detect-NW53BMJN.js → detect-XKQGLZYN.js} +2 -2
  194. package/dist/cli/chunks/{dist-node-LE6KHXAB.js → dist-node-SSKB53QL.js} +2 -2
  195. package/dist/cli/chunks/{domain-handler-JGXFT4LW.js → domain-handler-6BNDHATU.js} +2 -2
  196. package/dist/cli/chunks/{domain-plugins-GY3RYKKK.js → domain-plugins-DOX54YE3.js} +2 -2
  197. package/dist/cli/chunks/{domain-transfer-CGBRXNTC.js → domain-transfer-FW4ZX3Z7.js} +2 -2
  198. package/dist/cli/chunks/dream-MIK2E4UL.js +2 -0
  199. package/dist/cli/chunks/{embed-and-insert-pattern-65H4XHWR.js → embed-and-insert-pattern-QST77T2B.js} +2 -2
  200. package/dist/cli/chunks/{eval-YPYIZQUR.js → eval-K7E4XXBS.js} +2 -2
  201. package/dist/cli/chunks/{experience-capture-middleware-4JXVF5PL.js → experience-capture-middleware-X66IYSRV.js} +3 -3
  202. package/dist/cli/chunks/{fast-paths-HYQTAF2S.js → fast-paths-5JXXTYAG.js} +2 -2
  203. package/dist/cli/chunks/{feature-flags-HNSAFFX2.js → feature-flags-2CR3CO23.js} +2 -2
  204. package/dist/cli/chunks/{feature-flags-YACUH6OW.js → feature-flags-RB72LHOJ.js} +2 -2
  205. package/dist/cli/chunks/{file-discovery-R73BYEXB.js → file-discovery-3NHRUQQB.js} +2 -2
  206. package/dist/cli/chunks/{fleet-6M3BP4OO.js → fleet-SDU7QEOA.js} +3 -3
  207. package/dist/cli/chunks/{gnn-wrapper-QLD7KHXV.js → gnn-wrapper-AWCFODUV.js} +2 -2
  208. package/dist/cli/chunks/{heartbeat-handler-EZP333X4.js → heartbeat-handler-A4PJ3NFP.js} +4 -4
  209. package/dist/cli/chunks/heartbeat-scheduler-OCKRACUW.js +2 -0
  210. package/dist/cli/chunks/hnsw-adapter-X67XG73C.js +2 -0
  211. package/dist/cli/chunks/hnsw-index-I7KCQBQR.js +2 -0
  212. package/dist/cli/chunks/{hnsw-legacy-bridge-47CUCSAU.js → hnsw-legacy-bridge-KRS7SSFM.js} +2 -2
  213. package/dist/cli/chunks/{hnswlib-node-SVNYDJZH.js → hnswlib-node-OGGCPKPO.js} +2 -2
  214. package/dist/cli/chunks/{hooks-6V5LMWP6.js → hooks-XNRNMUBW.js} +10 -10
  215. package/dist/cli/chunks/hybrid-backend-FOUHTKAK.js +2 -0
  216. package/dist/cli/chunks/{hypergraph-engine-L2FOBIFF.js → hypergraph-engine-X35LTXYT.js} +2 -2
  217. package/dist/cli/chunks/{hypergraph-handler-DU6Z57EE.js → hypergraph-handler-M6THKAG6.js} +3 -3
  218. package/dist/cli/chunks/impact-analyzer-GXYVX46O.js +2 -0
  219. package/dist/cli/chunks/{init-handler-HETPWU67.js → init-handler-2AXMXHYF.js} +6 -6
  220. package/dist/cli/chunks/init-wizard-C2MRX2QG.js +2 -0
  221. package/dist/cli/chunks/kernel-Q2IUDIDC.js +2 -0
  222. package/dist/cli/chunks/{kilocode-installer-NHKYGJ7Q.js → kilocode-installer-TEPR2ZJD.js} +2 -2
  223. package/dist/cli/chunks/{kiro-installer-24UK6GGR.js → kiro-installer-RUKHGDEE.js} +2 -2
  224. package/dist/cli/chunks/knowledge-graph-E2Z6K5EE.js +2 -0
  225. package/dist/cli/chunks/{learning-QLVRZNHT.js → learning-BEA26RNA.js} +3 -3
  226. package/dist/cli/chunks/{llm-router-XRMI2VMG.js → llm-router-7GECMDCP.js} +4 -4
  227. package/dist/cli/chunks/llm-router-service-YATYFEDD.js +2 -0
  228. package/dist/cli/chunks/{load-W5UWL5C7.js → load-NTJ4Y4ZR.js} +2 -2
  229. package/dist/cli/chunks/load-test-LV77JXWA.js +2 -0
  230. package/dist/cli/chunks/{mcp-N7ALQ4BL.js → mcp-4335GTTG.js} +2 -2
  231. package/dist/cli/chunks/{memory-WV52DLSA.js → memory-HYC4M4XS.js} +5 -5
  232. package/dist/cli/chunks/memory-backend-XME3X3QX.js +2 -0
  233. package/dist/cli/chunks/memory-handlers-VG47X5DX.js +2 -0
  234. package/dist/cli/chunks/{multi-model-executor-3FVTZCSO.js → multi-model-executor-T7FYKM6T.js} +2 -2
  235. package/dist/cli/chunks/{opencode-installer-NTPWGHUW.js → opencode-installer-3USXVT5M.js} +2 -2
  236. package/dist/cli/chunks/{orchestrator-ORGJ6VAA.js → orchestrator-VHUXUYIM.js} +5 -5
  237. package/dist/cli/chunks/pattern-null-store-TAXMLENP.js +2 -0
  238. package/dist/cli/chunks/{pattern-usage-recorder-WWXHUH5U.js → pattern-usage-recorder-CMZLPX2K.js} +2 -2
  239. package/dist/cli/chunks/{pipeline-ZOKZFXTH.js → pipeline-BTRZOVSL.js} +2 -2
  240. package/dist/cli/chunks/{platform-CDNL322F.js → platform-2MCRKC25.js} +2 -2
  241. package/dist/cli/chunks/{plugin-ZVLFNZZ4.js → plugin-2VAYWAO3.js} +2 -2
  242. package/dist/cli/chunks/{prime-radiant-advanced-wasm-FVJDU2JY.js → prime-radiant-advanced-wasm-TXFEMBP6.js} +2 -2
  243. package/dist/cli/chunks/{project-root-UCHQH3QL.js → project-root-CFFPBGPX.js} +2 -2
  244. package/dist/cli/chunks/protocol-executor-ML76QAVQ.js +2 -0
  245. package/dist/cli/chunks/{protocol-handler-4YBN5R23.js → protocol-handler-DZ26OYVZ.js} +2 -2
  246. package/dist/cli/chunks/{prove-BHDHY664.js → prove-QWONEJWX.js} +2 -2
  247. package/dist/cli/chunks/qe-reasoning-bank-LUZH6RYV.js +2 -0
  248. package/dist/cli/chunks/quality-WFH54FY7.js +8 -0
  249. package/dist/cli/chunks/{quality-gate-WANE7TCN.js → quality-gate-ONJB7XU7.js} +3 -3
  250. package/dist/cli/chunks/queen-coordinator-EWXNIXB6.js +2 -0
  251. package/dist/cli/chunks/{real-embeddings-56MNGJGJ.js → real-embeddings-GZV4VKK4.js} +2 -2
  252. package/dist/cli/chunks/{ref-validation-S7UWXQIP.js → ref-validation-HW5Y55ZC.js} +2 -2
  253. package/dist/cli/chunks/{roocode-installer-TEYOQYL6.js → roocode-installer-5OABDNZT.js} +2 -2
  254. package/dist/cli/chunks/router-MXOBVEBF.js +2 -0
  255. package/dist/cli/chunks/routing-feedback-T6CCRUEK.js +2 -0
  256. package/dist/cli/chunks/{routing-handler-KDTLMRWD.js → routing-handler-CVHVOQTC.js} +2 -2
  257. package/dist/cli/chunks/{ruvector-commands-AOUDXCYE.js → ruvector-commands-KKDKFGIQ.js} +2 -2
  258. package/dist/cli/chunks/rvf-dual-writer-WHXVT3V3.js +2 -0
  259. package/dist/cli/chunks/rvf-migration-adapter-JFPWIRCG.js +2 -0
  260. package/dist/cli/chunks/{rvf-migration-coordinator-V74MVBHS.js → rvf-migration-coordinator-D4KUBNRZ.js} +2 -2
  261. package/dist/cli/chunks/rvf-native-adapter-KOXR7TJL.js +2 -0
  262. package/dist/cli/chunks/{rvf-store-integrity-QI47Y354.js → rvf-store-integrity-UGUXKIFX.js} +2 -2
  263. package/dist/cli/chunks/safe-db-CI6IPSIN.js +2 -0
  264. package/dist/cli/chunks/schedule-X4HW6TVJ.js +2 -0
  265. package/dist/cli/chunks/scheduler-KCNJ2ON3.js +2 -0
  266. package/dist/cli/chunks/{security-SN6MWOJT.js → security-7723AZZ4.js} +3 -3
  267. package/dist/cli/chunks/{shared-rvf-adapter-2LB56LP4.js → shared-rvf-adapter-KEQ5CLNI.js} +2 -2
  268. package/dist/cli/chunks/{shared-rvf-dual-writer-WU7PFKQM.js → shared-rvf-dual-writer-ZSHYG5IA.js} +2 -2
  269. package/dist/cli/chunks/sqlite-persistence-PGHU6VUR.js +2 -0
  270. package/dist/cli/chunks/{standalone-memory-F6FSRFWC.js → standalone-memory-MHZEEYMK.js} +2 -2
  271. package/dist/cli/chunks/{status-handler-DHD5MS4G.js → status-handler-JKXPJ22K.js} +2 -2
  272. package/dist/cli/chunks/{structural-health-P6HPSQMR.js → structural-health-J4RKCYWF.js} +2 -2
  273. package/dist/cli/chunks/{sync-SNAXAVCN.js → sync-EFWXMA2H.js} +2 -2
  274. package/dist/cli/chunks/{sync-LISJGDSE.js → sync-PDPORHVN.js} +2 -2
  275. package/dist/cli/chunks/{task-handler-ZT44NT5Z.js → task-handler-VERADM44.js} +2 -2
  276. package/dist/cli/chunks/{task-handlers-R6DQ5324.js → task-handlers-4RUCWUR2.js} +3 -3
  277. package/dist/cli/chunks/{test-MUFHR4JQ.js → test-DMBJFQNL.js} +4 -4
  278. package/dist/cli/chunks/{test-scheduling-TAUSLZJP.js → test-scheduling-LUPTVGCD.js} +3 -3
  279. package/dist/cli/chunks/{token-bootstrap-UGRH7OPU.js → token-bootstrap-S346YBVO.js} +2 -2
  280. package/dist/cli/chunks/{token-usage-IX65ECBR.js → token-usage-VOA34IKM.js} +2 -2
  281. package/dist/cli/chunks/{transformers-QKPSVW2W.js → transformers-GU4TYAN5.js} +2 -2
  282. package/dist/cli/chunks/{tree-sitter-wasm-parser-Z7PPA2JO.js → tree-sitter-wasm-parser-MZPXAH7C.js} +2 -2
  283. package/dist/cli/chunks/{types-ULNNGGGH.js → types-K4FLXR2K.js} +2 -2
  284. package/dist/cli/chunks/unified-memory-6CK3TUNQ.js +2 -0
  285. package/dist/cli/chunks/unified-memory-hnsw-A7BWBGYN.js +2 -0
  286. package/dist/cli/chunks/unified-persistence-GEPMDBQZ.js +2 -0
  287. package/dist/cli/chunks/{upgrade-ECI3YUYA.js → upgrade-M3ATDRMK.js} +2 -2
  288. package/dist/cli/chunks/{validate-3JKRUW2S.js → validate-AAP773B3.js} +2 -2
  289. package/dist/cli/chunks/{validate-swarm-LZWANCIE.js → validate-swarm-7RGAZX5F.js} +2 -2
  290. package/dist/cli/chunks/visual-security-L4J7LQWT.js +2 -0
  291. package/dist/cli/chunks/{web-tree-sitter-N5V4A6XG.js → web-tree-sitter-GQMRHGGI.js} +2 -2
  292. package/dist/cli/chunks/{windsurf-installer-5TBM5B3C.js → windsurf-installer-HG6HF2GF.js} +2 -2
  293. package/dist/cli/chunks/witness-chain-CDUMX623.js +2 -0
  294. package/dist/cli/chunks/{witness-chain-MFP3HBWQ.js → witness-chain-WKU3ZIBQ.js} +2 -2
  295. package/dist/cli/chunks/{witness-chain-repair-5QWRFVUK.js → witness-chain-repair-WNYH6O4L.js} +2 -2
  296. package/dist/cli/chunks/{witness-chain-verifier-SRAT7LVY.js → witness-chain-verifier-Q2KW3QEQ.js} +2 -2
  297. package/dist/cli/chunks/{witness-key-manager-FYZXQTLJ.js → witness-key-manager-NQ5DAAC4.js} +2 -2
  298. package/dist/cli/chunks/{workflow-M7TUYYXY.js → workflow-CX6SHFBW.js} +4 -4
  299. package/dist/cli/chunks/workflow-orchestrator-USJDWVDR.js +2 -0
  300. package/dist/cli/chunks/{wrappers-COU73OQ6.js → wrappers-CZDI6Z3X.js} +2 -2
  301. package/dist/cli/commands/ci.js +14 -6
  302. package/dist/cli/commands/code.js +1 -0
  303. package/dist/cli/commands/coverage.d.ts +28 -0
  304. package/dist/cli/commands/coverage.js +258 -143
  305. package/dist/cli/commands/quality.d.ts +12 -1
  306. package/dist/cli/commands/quality.js +51 -3
  307. package/dist/cli/utils/ci-output.d.ts +14 -4
  308. package/dist/cli/utils/ci-output.js +21 -4
  309. package/dist/cli/utils/coverage-data.d.ts +7 -0
  310. package/dist/cli/utils/coverage-data.js +21 -27
  311. package/dist/contracts/verdicts.d.ts +14 -0
  312. package/dist/contracts/verdicts.js +44 -3
  313. package/dist/coordination/handlers/coverage-handlers.js +121 -120
  314. package/dist/coordination/handlers/coverage-runner.d.ts +121 -0
  315. package/dist/coordination/handlers/coverage-runner.js +367 -0
  316. package/dist/coordination/handlers/coverage-target.d.ts +144 -0
  317. package/dist/coordination/handlers/coverage-target.js +311 -0
  318. package/dist/coordination/handlers/handler-utils.d.ts +9 -0
  319. package/dist/coordination/handlers/handler-utils.js +44 -1
  320. package/dist/coordination/handlers/quality-handlers.js +101 -15
  321. package/dist/coordination/result-saver.js +17 -3
  322. package/dist/coordination/task-executor.d.ts +5 -0
  323. package/dist/coordination/task-executor.js +7 -0
  324. package/dist/domains/code-intelligence/coordinator.d.ts +2 -1
  325. package/dist/domains/code-intelligence/coordinator.js +10 -32
  326. package/dist/domains/code-intelligence/interfaces.d.ts +5 -0
  327. package/dist/domains/code-intelligence/plugin.js +1 -0
  328. package/dist/domains/code-intelligence/project-root-resolver.d.ts +50 -0
  329. package/dist/domains/code-intelligence/project-root-resolver.js +121 -0
  330. package/dist/domains/coverage-analysis/coordinator.js +4 -1
  331. package/dist/domains/coverage-analysis/interfaces.d.ts +15 -0
  332. package/dist/domains/coverage-analysis/plugin.js +7 -1
  333. package/dist/domains/coverage-analysis/services/coverage-analyzer.d.ts +7 -0
  334. package/dist/domains/coverage-analysis/services/coverage-analyzer.js +29 -9
  335. package/dist/domains/quality-assessment/coordinator-claim-verifier.js +2 -1
  336. package/dist/domains/quality-assessment/coordinator.js +8 -8
  337. package/dist/domains/quality-assessment/coverage-report-event.d.ts +25 -0
  338. package/dist/domains/quality-assessment/coverage-report-event.js +36 -0
  339. package/dist/domains/quality-assessment/evidence-sufficiency.d.ts +57 -0
  340. package/dist/domains/quality-assessment/evidence-sufficiency.js +97 -0
  341. package/dist/domains/quality-assessment/index.d.ts +1 -1
  342. package/dist/domains/quality-assessment/index.js +1 -1
  343. package/dist/domains/quality-assessment/plugin.js +8 -8
  344. package/dist/domains/quality-assessment/quality-evidence.d.ts +50 -2
  345. package/dist/domains/quality-assessment/quality-evidence.js +90 -8
  346. package/dist/domains/quality-assessment/services/quality-analyzer.js +13 -9
  347. package/dist/mcp/bundle.js +456 -451
  348. package/dist/mcp/handlers/domain-handler-configs.d.ts +18 -1
  349. package/dist/mcp/handlers/domain-handler-configs.js +42 -4
  350. package/dist/mcp/handlers/handler-factory.js +3 -0
  351. package/dist/mcp/handlers/wrapped-domain-handlers.js +7 -1
  352. package/dist/mcp/protocol-server.js +3 -2
  353. package/dist/mcp/tools/coverage-analysis/index.js +1 -0
  354. package/dist/mcp/types.d.ts +6 -0
  355. package/dist/shared/events/domain-events.d.ts +2 -0
  356. package/package.json +1 -1
  357. package/dist/cli/chunks/adapter-T54G3TBK.js +0 -2
  358. package/dist/cli/chunks/aqe-learning-engine-HLCJJ3JM.js +0 -2
  359. package/dist/cli/chunks/base-VLD755UU.js +0 -2
  360. package/dist/cli/chunks/browser-workflow-6M6VLWRF.js +0 -2
  361. package/dist/cli/chunks/chunk-5XXLWJU7.js +0 -2
  362. package/dist/cli/chunks/chunk-HEDLZWPM.js +0 -96
  363. package/dist/cli/chunks/chunk-XKIFNKHV.js +0 -2
  364. package/dist/cli/chunks/chunk-ZF5JTQEE.js +0 -4
  365. package/dist/cli/chunks/ci-NGMGB43T.js +0 -82
  366. package/dist/cli/chunks/client-FUHNNK5O.js +0 -2
  367. package/dist/cli/chunks/core-handlers-F7TLX4LM.js +0 -2
  368. package/dist/cli/chunks/coverage-IVKDV236.js +0 -27
  369. package/dist/cli/chunks/cross-domain-router-EGWPY67O.js +0 -2
  370. package/dist/cli/chunks/dream-V4QN6OF5.js +0 -2
  371. package/dist/cli/chunks/heartbeat-scheduler-3N3L6CRM.js +0 -2
  372. package/dist/cli/chunks/hnsw-adapter-2BXJYDXI.js +0 -2
  373. package/dist/cli/chunks/hnsw-index-2DLI5OVO.js +0 -2
  374. package/dist/cli/chunks/hybrid-backend-OW4J65YH.js +0 -2
  375. package/dist/cli/chunks/impact-analyzer-ZH5I2RG6.js +0 -2
  376. package/dist/cli/chunks/init-wizard-NIKM3ZOK.js +0 -2
  377. package/dist/cli/chunks/kernel-2EOSVM6X.js +0 -2
  378. package/dist/cli/chunks/knowledge-graph-D3BPWNNO.js +0 -2
  379. package/dist/cli/chunks/llm-router-service-TJPPZFUN.js +0 -2
  380. package/dist/cli/chunks/load-test-RFT7IDOL.js +0 -2
  381. package/dist/cli/chunks/memory-backend-O2O4CFKZ.js +0 -2
  382. package/dist/cli/chunks/memory-handlers-DAEGUDBD.js +0 -2
  383. package/dist/cli/chunks/pattern-null-store-TUBNXS34.js +0 -2
  384. package/dist/cli/chunks/protocol-executor-6FQTTO3Y.js +0 -2
  385. package/dist/cli/chunks/qe-reasoning-bank-TKPND56C.js +0 -2
  386. package/dist/cli/chunks/quality-46AK277P.js +0 -7
  387. package/dist/cli/chunks/queen-coordinator-DWMXLPJG.js +0 -2
  388. package/dist/cli/chunks/router-QIMUYRCC.js +0 -2
  389. package/dist/cli/chunks/routing-feedback-4OH5ZNF4.js +0 -2
  390. package/dist/cli/chunks/rvf-dual-writer-S6JBZL54.js +0 -2
  391. package/dist/cli/chunks/rvf-migration-adapter-TSGMLMYR.js +0 -2
  392. package/dist/cli/chunks/rvf-native-adapter-Z7QOW47S.js +0 -2
  393. package/dist/cli/chunks/safe-db-JLOVBJNC.js +0 -2
  394. package/dist/cli/chunks/schedule-IM6XOBGR.js +0 -2
  395. package/dist/cli/chunks/scheduler-XL2SVVK5.js +0 -2
  396. package/dist/cli/chunks/sqlite-persistence-LWMIIC4U.js +0 -2
  397. package/dist/cli/chunks/unified-memory-F5IJY7W7.js +0 -2
  398. package/dist/cli/chunks/unified-memory-hnsw-C3WAMAQL.js +0 -2
  399. package/dist/cli/chunks/unified-persistence-EWXXOTCB.js +0 -2
  400. package/dist/cli/chunks/visual-security-CKLTAIAB.js +0 -2
  401. package/dist/cli/chunks/witness-chain-Z6LWFEZS.js +0 -2
  402. package/dist/cli/chunks/workflow-orchestrator-OFTAR2NA.js +0 -2
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Run a JS/TS project's test runner with coverage — safely (issue #995).
3
+ *
4
+ * Properties, each learned the hard way:
5
+ *
6
+ * 1. **Run from the project root, write to a private temp dir.** The coverage
7
+ * report and the runner's JSON result go to `reportDir`, never into the
8
+ * project tree (#995 wrote `src/coverage/`). The result file is set with
9
+ * plain `--outputFile=` — vitest ignores `--outputFile.json=` when the
10
+ * user's config sets `outputFile` as a string.
11
+ * 2. **No shell, no download.** The runner's own JS entry point is resolved
12
+ * from the project's `node_modules` and started with `process.execPath`.
13
+ * Arguments are an array, so `$(…)`, spaces, `& ^ %` in a path are data on
14
+ * every platform. A runner that isn't installed is reported, never fetched
15
+ * (`npx` would silently download one).
16
+ * 3. **Kill the whole process tree.** Runner → workers is several levels deep.
17
+ * The child is started in its own process group (POSIX) and the group is
18
+ * killed on timeout (`taskkill /T /F` on Windows).
19
+ * 4. **Die with the host.** Every live run is registered; a synchronous
20
+ * `process.on('exit')` hook kills each group and removes its temp dir. That
21
+ * covers every path that ends in `process.exit()` or a natural exit — the
22
+ * MCP server's shutdown on SIGTERM/SIGINT/stdin EOF routes there. It cannot
23
+ * cover SIGKILL of the host (or a signal with no handler installed): no
24
+ * code runs in that case, and the group is left to its own timeout-less
25
+ * fate. Hosts should shut down via a handled signal.
26
+ */
27
+ import type { CoverageData } from '../../domains/coverage-analysis/interfaces';
28
+ export type JsRunnerName = 'vitest' | 'jest' | 'nyc';
29
+ export interface JsCoverageInvocation {
30
+ runner: JsRunnerName;
31
+ /** `process.execPath`, or null when the runner is not installed. */
32
+ command: string | null;
33
+ /** `[<runner JS entry>, ...runner args]`. */
34
+ args: string[];
35
+ /** Where the runner writes its own JSON result (tests run / passed), if supported. */
36
+ resultsFile: string | null;
37
+ }
38
+ export interface JsCoverageRun {
39
+ runner: JsRunnerName;
40
+ /** The runner package was not found in the project's node_modules. Nothing ran. */
41
+ missing: boolean;
42
+ exitCode: number | null;
43
+ exitedCleanly: boolean;
44
+ timedOut: boolean;
45
+ timeoutMs: number;
46
+ /**
47
+ * Parsed istanbul report, or null when none was written. A report that was
48
+ * written but lists no files is `{ files: [] }` — NOT null: "the run covered
49
+ * nothing" is different from "the run produced no report".
50
+ */
51
+ data: CoverageData | null;
52
+ /**
53
+ * Number of tests the runner reports having run, from its own JSON result.
54
+ * `null` when the runner gives no machine-readable result (nyc) or it could
55
+ * not be read — "unknown", which callers must not treat as 0.
56
+ */
57
+ numTotalTests: number | null;
58
+ /** The runner's first error line plus the last ~2 KB of its stderr, for diagnosing a crash. */
59
+ stderrTail: string;
60
+ }
61
+ /**
62
+ * Summarise a runner's stderr for a caller: the FIRST error-looking line (or
63
+ * the first ~512 bytes) plus the last ~2 KB (#995 review NB-C). A tail alone
64
+ * loses the cause when a long stack follows it — a vitest config syntax error
65
+ * prints `[PARSE_ERROR] …` first and then kilobytes of frames.
66
+ */
67
+ export declare function summarizeStderr(head: string, tail: string, totalBytes: number): string;
68
+ /**
69
+ * Find an installed package's bin script, walking up `node_modules` from the
70
+ * project root (hoisted monorepo installs live above the package).
71
+ */
72
+ export declare function findPackageBin(projectRoot: string, pkg: string, binName?: string, maxDepth?: number): string | null;
73
+ /**
74
+ * Pick the runner and its argv. No shell is involved: `command` is the Node
75
+ * binary and `args[0]` the runner's JS entry, so paths are passed verbatim.
76
+ */
77
+ export declare function buildJsCoverageInvocation(projectRoot: string, reportDir: string): JsCoverageInvocation;
78
+ /**
79
+ * Synchronously kill every live coverage run and remove its temp dir. Runs from
80
+ * `process.on('exit')`, where only synchronous work is possible.
81
+ */
82
+ export declare function killAllLiveRunsSync(): void;
83
+ /** Number of runs currently registered (for tests and diagnostics). */
84
+ export declare function liveRunCount(): number;
85
+ export interface ProcessTreeResult {
86
+ exitCode: number | null;
87
+ timedOut: boolean;
88
+ spawnError: boolean;
89
+ pid: number | undefined;
90
+ stderrTail: string;
91
+ }
92
+ /**
93
+ * Spawn `command args` in `cwd` (no shell) as the leader of a new process
94
+ * group, wait for it, and on timeout kill the entire group. Resolves only once
95
+ * no process of the group remains (bounded), so the caller can safely delete
96
+ * its temp dir. While running, the group and `cleanupDir` are registered with
97
+ * the exit hook so they never outlive the host process.
98
+ */
99
+ export declare function runProcessTree(command: string, args: string[], options: {
100
+ cwd: string;
101
+ timeoutMs: number;
102
+ graceMs?: number;
103
+ cleanupDir?: string;
104
+ env?: NodeJS.ProcessEnv;
105
+ }): Promise<ProcessTreeResult>;
106
+ /**
107
+ * Run the project's test runner with coverage from `projectRoot`.
108
+ *
109
+ * Everything the runner writes goes to a fresh temp dir that is removed before
110
+ * this returns — after the whole process group is gone — or by the exit hook if
111
+ * the host exits first.
112
+ */
113
+ export declare function runJsCoverage(projectRoot: string, options?: {
114
+ timeoutMs?: number;
115
+ }): Promise<JsCoverageRun>;
116
+ /**
117
+ * One-line, caller-facing explanation of why a run produced no usable report.
118
+ * Never "No instrumentation ran" when the runner did run and failed.
119
+ */
120
+ export declare function describeRunFailure(run: JsCoverageRun, projectRoot: string): string;
121
+ //# sourceMappingURL=coverage-runner.d.ts.map
@@ -0,0 +1,367 @@
1
+ /**
2
+ * Run a JS/TS project's test runner with coverage — safely (issue #995).
3
+ *
4
+ * Properties, each learned the hard way:
5
+ *
6
+ * 1. **Run from the project root, write to a private temp dir.** The coverage
7
+ * report and the runner's JSON result go to `reportDir`, never into the
8
+ * project tree (#995 wrote `src/coverage/`). The result file is set with
9
+ * plain `--outputFile=` — vitest ignores `--outputFile.json=` when the
10
+ * user's config sets `outputFile` as a string.
11
+ * 2. **No shell, no download.** The runner's own JS entry point is resolved
12
+ * from the project's `node_modules` and started with `process.execPath`.
13
+ * Arguments are an array, so `$(…)`, spaces, `& ^ %` in a path are data on
14
+ * every platform. A runner that isn't installed is reported, never fetched
15
+ * (`npx` would silently download one).
16
+ * 3. **Kill the whole process tree.** Runner → workers is several levels deep.
17
+ * The child is started in its own process group (POSIX) and the group is
18
+ * killed on timeout (`taskkill /T /F` on Windows).
19
+ * 4. **Die with the host.** Every live run is registered; a synchronous
20
+ * `process.on('exit')` hook kills each group and removes its temp dir. That
21
+ * covers every path that ends in `process.exit()` or a natural exit — the
22
+ * MCP server's shutdown on SIGTERM/SIGINT/stdin EOF routes there. It cannot
23
+ * cover SIGKILL of the host (or a signal with no handler installed): no
24
+ * code runs in that case, and the group is left to its own timeout-less
25
+ * fate. Hosts should shut down via a handled signal.
26
+ */
27
+ import { spawn, spawnSync } from 'child_process';
28
+ import * as fs from 'fs';
29
+ import * as os from 'os';
30
+ import * as path from 'path';
31
+ import { safeJsonParse } from '../../shared/safe-json.js';
32
+ import { loadCoverageReportFile } from './coverage-target.js';
33
+ const RESULTS_FILE = 'test-results.json';
34
+ const STDERR_TAIL_BYTES = 2048;
35
+ const STDERR_HEAD_BYTES = 4096;
36
+ const STDERR_PREFIX_BYTES = 512;
37
+ const ERROR_LINE_RE = /^.*(?:error|\[[A-Z][A-Z_]{2,}\]|ERR_[A-Z_]+).*$/im;
38
+ /**
39
+ * Summarise a runner's stderr for a caller: the FIRST error-looking line (or
40
+ * the first ~512 bytes) plus the last ~2 KB (#995 review NB-C). A tail alone
41
+ * loses the cause when a long stack follows it — a vitest config syntax error
42
+ * prints `[PARSE_ERROR] …` first and then kilobytes of frames.
43
+ */
44
+ export function summarizeStderr(head, tail, totalBytes) {
45
+ if (totalBytes <= STDERR_TAIL_BYTES)
46
+ return tail.trim();
47
+ const errorLine = ERROR_LINE_RE.exec(head)?.[0]?.trim();
48
+ const prefix = (errorLine ?? head.slice(0, STDERR_PREFIX_BYTES)).trim();
49
+ if (prefix && tail.includes(prefix))
50
+ return tail.trim();
51
+ return `${prefix}\n…\n${tail.trim()}`;
52
+ }
53
+ // ============================================================================
54
+ // Locating the runner
55
+ // ============================================================================
56
+ /**
57
+ * Find an installed package's bin script, walking up `node_modules` from the
58
+ * project root (hoisted monorepo installs live above the package).
59
+ */
60
+ export function findPackageBin(projectRoot, pkg, binName = pkg, maxDepth = 10) {
61
+ let dir = path.resolve(projectRoot);
62
+ for (let i = 0; i <= maxDepth; i++) {
63
+ const pkgDir = path.join(dir, 'node_modules', pkg);
64
+ try {
65
+ const manifest = JSON.parse(fs.readFileSync(path.join(pkgDir, 'package.json'), 'utf-8'));
66
+ const rel = typeof manifest.bin === 'string' ? manifest.bin : manifest.bin?.[binName];
67
+ if (rel) {
68
+ const binPath = path.join(pkgDir, rel);
69
+ if (fs.existsSync(binPath))
70
+ return binPath;
71
+ }
72
+ }
73
+ catch {
74
+ // not installed at this level
75
+ }
76
+ const parent = path.dirname(dir);
77
+ if (parent === dir)
78
+ break;
79
+ dir = parent;
80
+ }
81
+ return null;
82
+ }
83
+ function readDeps(projectRoot) {
84
+ try {
85
+ const pkg = safeJsonParse(fs.readFileSync(path.join(projectRoot, 'package.json'), 'utf-8'));
86
+ return {
87
+ ...(pkg.devDependencies || {}),
88
+ ...(pkg.dependencies || {}),
89
+ };
90
+ }
91
+ catch {
92
+ return {};
93
+ }
94
+ }
95
+ /**
96
+ * Pick the runner and its argv. No shell is involved: `command` is the Node
97
+ * binary and `args[0]` the runner's JS entry, so paths are passed verbatim.
98
+ */
99
+ export function buildJsCoverageInvocation(projectRoot, reportDir) {
100
+ const resultsFile = path.join(reportDir, RESULTS_FILE);
101
+ const deps = readDeps(projectRoot);
102
+ let runner = 'vitest';
103
+ let runnerArgs;
104
+ let results = resultsFile;
105
+ if (deps['jest'] || deps['@jest/core']) {
106
+ runner = 'jest';
107
+ runnerArgs = ['--coverage', `--coverageDirectory=${reportDir}`, '--coverageReporters=json',
108
+ '--json', `--outputFile=${resultsFile}`];
109
+ }
110
+ else if (deps['mocha'] || deps['nyc']) {
111
+ runner = 'nyc';
112
+ runnerArgs = [`--report-dir=${reportDir}`, `--temp-dir=${path.join(reportDir, '.nyc_output')}`,
113
+ '--reporter=json', 'mocha'];
114
+ results = null;
115
+ }
116
+ else {
117
+ // vitest is the default — covers vitest, @vitest/coverage-v8, etc.
118
+ // Plain `--outputFile=` (not `.json=`): it overrides a string, object, or
119
+ // absent `outputFile` in the user's config alike.
120
+ runnerArgs = ['run', '--coverage', `--coverage.reportsDirectory=${reportDir}`,
121
+ '--coverage.reporter=json', '--reporter=json', `--outputFile=${resultsFile}`];
122
+ }
123
+ const bin = findPackageBin(projectRoot, runner === 'jest' ? 'jest' : runner);
124
+ return {
125
+ runner,
126
+ command: bin ? process.execPath : null,
127
+ args: bin ? [bin, ...runnerArgs] : runnerArgs,
128
+ resultsFile: results,
129
+ };
130
+ }
131
+ function readNumTotalTests(resultsFile) {
132
+ if (!resultsFile)
133
+ return null;
134
+ try {
135
+ const parsed = JSON.parse(fs.readFileSync(resultsFile, 'utf-8'));
136
+ return typeof parsed.numTotalTests === 'number' ? parsed.numTotalTests : null;
137
+ }
138
+ catch {
139
+ return null;
140
+ }
141
+ }
142
+ /**
143
+ * Read the istanbul report the runner wrote. Distinguishes an EMPTY report
144
+ * (`{}` — the run instrumented nothing) from NO report.
145
+ */
146
+ async function readRunReport(file) {
147
+ const data = await loadCoverageReportFile(file);
148
+ if (data)
149
+ return data;
150
+ try {
151
+ const parsed = JSON.parse(fs.readFileSync(file, 'utf-8'));
152
+ if (parsed && typeof parsed === 'object' && !Array.isArray(parsed) && Object.keys(parsed).length === 0) {
153
+ return { files: [], summary: { line: 0, branch: 0, function: 0, statement: 0, files: 0 } };
154
+ }
155
+ }
156
+ catch {
157
+ // absent or unparseable
158
+ }
159
+ return null;
160
+ }
161
+ // ============================================================================
162
+ // Process-tree lifecycle
163
+ // ============================================================================
164
+ /** Live runs: process-group leader pid → temp dir to remove. */
165
+ const liveRuns = new Map();
166
+ let exitHookInstalled = false;
167
+ function killTree(pid, signal) {
168
+ if (process.platform === 'win32') {
169
+ // Windows has no process groups; taskkill /T walks the tree.
170
+ try {
171
+ spawnSync('taskkill', ['/pid', String(pid), '/T', '/F'], { stdio: 'ignore' });
172
+ }
173
+ catch { /* gone */ }
174
+ return;
175
+ }
176
+ try {
177
+ process.kill(-pid, signal);
178
+ }
179
+ catch { /* group already gone */ }
180
+ }
181
+ /**
182
+ * Synchronously kill every live coverage run and remove its temp dir. Runs from
183
+ * `process.on('exit')`, where only synchronous work is possible.
184
+ */
185
+ export function killAllLiveRunsSync() {
186
+ for (const [pid, dir] of liveRuns) {
187
+ killTree(pid, 'SIGKILL');
188
+ if (dir) {
189
+ try {
190
+ fs.rmSync(dir, { recursive: true, force: true });
191
+ }
192
+ catch { /* best-effort */ }
193
+ }
194
+ }
195
+ liveRuns.clear();
196
+ }
197
+ /** Number of runs currently registered (for tests and diagnostics). */
198
+ export function liveRunCount() {
199
+ return liveRuns.size;
200
+ }
201
+ function ensureExitHook() {
202
+ if (exitHookInstalled)
203
+ return;
204
+ process.on('exit', killAllLiveRunsSync);
205
+ exitHookInstalled = true;
206
+ }
207
+ /** Is any process of this group still alive? */
208
+ function groupAlive(pgid) {
209
+ try {
210
+ process.kill(-pgid, 0);
211
+ return true;
212
+ }
213
+ catch {
214
+ return false;
215
+ }
216
+ }
217
+ async function waitForGroupExit(pid, maxMs) {
218
+ if (process.platform === 'win32')
219
+ return;
220
+ const deadline = Date.now() + maxMs;
221
+ while (groupAlive(pid) && Date.now() < deadline) {
222
+ await new Promise(r => setTimeout(r, 50));
223
+ }
224
+ }
225
+ /**
226
+ * Spawn `command args` in `cwd` (no shell) as the leader of a new process
227
+ * group, wait for it, and on timeout kill the entire group. Resolves only once
228
+ * no process of the group remains (bounded), so the caller can safely delete
229
+ * its temp dir. While running, the group and `cleanupDir` are registered with
230
+ * the exit hook so they never outlive the host process.
231
+ */
232
+ export async function runProcessTree(command, args, options) {
233
+ const graceMs = options.graceMs ?? 3000;
234
+ const isWindows = process.platform === 'win32';
235
+ ensureExitHook();
236
+ return new Promise(resolve => {
237
+ let timedOut = false;
238
+ let settled = false;
239
+ let stderrTail = '';
240
+ let stderrHead = '';
241
+ let stderrBytes = 0;
242
+ const child = spawn(command, args, {
243
+ cwd: options.cwd,
244
+ env: options.env ?? process.env,
245
+ // Own process group (POSIX) so the whole tree can be signalled at once.
246
+ detached: !isWindows,
247
+ shell: false,
248
+ stdio: ['ignore', 'ignore', 'pipe'],
249
+ windowsHide: true,
250
+ });
251
+ if (child.pid !== undefined)
252
+ liveRuns.set(child.pid, options.cleanupDir);
253
+ child.stderr?.on('data', (chunk) => {
254
+ const text = chunk.toString('utf-8');
255
+ stderrBytes += chunk.length;
256
+ if (stderrHead.length < STDERR_HEAD_BYTES)
257
+ stderrHead = (stderrHead + text).slice(0, STDERR_HEAD_BYTES);
258
+ stderrTail = (stderrTail + text).slice(-STDERR_TAIL_BYTES);
259
+ });
260
+ // A grandchild holding the pipe open must not keep the host alive.
261
+ child.stderr?.on('error', () => { });
262
+ const finish = async (exitCode, spawnError) => {
263
+ if (settled)
264
+ return;
265
+ settled = true;
266
+ clearTimeout(timer);
267
+ if (child.pid !== undefined && !isWindows && groupAlive(child.pid)) {
268
+ // Anything left in the group after the runner exited is orphaned work
269
+ // (stray workers, a hung watcher). Sweep it before the caller cleans up.
270
+ killTree(child.pid, 'SIGTERM');
271
+ await waitForGroupExit(child.pid, graceMs);
272
+ if (groupAlive(child.pid))
273
+ killTree(child.pid, 'SIGKILL');
274
+ await waitForGroupExit(child.pid, graceMs);
275
+ }
276
+ child.stderr?.destroy();
277
+ if (child.pid !== undefined)
278
+ liveRuns.delete(child.pid);
279
+ resolve({
280
+ exitCode, timedOut, spawnError, pid: child.pid,
281
+ stderrTail: summarizeStderr(stderrHead, stderrTail, stderrBytes),
282
+ });
283
+ };
284
+ const timer = setTimeout(() => {
285
+ timedOut = true;
286
+ if (child.pid === undefined)
287
+ return;
288
+ killTree(child.pid, 'SIGTERM');
289
+ setTimeout(() => { if (!settled && child.pid !== undefined)
290
+ killTree(child.pid, 'SIGKILL'); }, graceMs).unref();
291
+ }, options.timeoutMs);
292
+ child.on('error', () => { void finish(null, true); });
293
+ child.on('exit', code => { void finish(code, false); });
294
+ });
295
+ }
296
+ /**
297
+ * Run the project's test runner with coverage from `projectRoot`.
298
+ *
299
+ * Everything the runner writes goes to a fresh temp dir that is removed before
300
+ * this returns — after the whole process group is gone — or by the exit hook if
301
+ * the host exits first.
302
+ */
303
+ export async function runJsCoverage(projectRoot, options = {}) {
304
+ const timeoutMs = options.timeoutMs ?? 120000;
305
+ const reportDir = fs.mkdtempSync(path.join(os.tmpdir(), 'aqe-js-cov-'));
306
+ try {
307
+ const inv = buildJsCoverageInvocation(projectRoot, reportDir);
308
+ if (!inv.command) {
309
+ return {
310
+ runner: inv.runner, missing: true, exitCode: null, exitedCleanly: false, timedOut: false,
311
+ timeoutMs, data: null, numTotalTests: null, stderrTail: '',
312
+ };
313
+ }
314
+ // Runners that shell out to sibling tools (nyc → mocha) find them here.
315
+ const binDir = path.join(projectRoot, 'node_modules', '.bin');
316
+ // The runner's own temp files (vite's SSR cache, etc.) go inside reportDir
317
+ // too, so a killed run leaves nothing behind in the system temp dir.
318
+ const runnerTmp = path.join(reportDir, 'tmp');
319
+ fs.mkdirSync(runnerTmp);
320
+ const env = {
321
+ ...process.env,
322
+ PATH: `${binDir}${path.delimiter}${process.env.PATH ?? ''}`,
323
+ TMPDIR: runnerTmp, TMP: runnerTmp, TEMP: runnerTmp,
324
+ };
325
+ const run = await runProcessTree(inv.command, inv.args, {
326
+ cwd: projectRoot, timeoutMs, cleanupDir: reportDir, env,
327
+ });
328
+ const data = run.timedOut ? null : await readRunReport(path.join(reportDir, 'coverage-final.json'));
329
+ return {
330
+ runner: inv.runner,
331
+ missing: false,
332
+ exitCode: run.exitCode,
333
+ exitedCleanly: run.exitCode === 0 && !run.timedOut,
334
+ timedOut: run.timedOut,
335
+ timeoutMs,
336
+ data,
337
+ numTotalTests: run.timedOut ? null : readNumTotalTests(inv.resultsFile),
338
+ stderrTail: run.stderrTail,
339
+ };
340
+ }
341
+ finally {
342
+ try {
343
+ fs.rmSync(reportDir, { recursive: true, force: true });
344
+ }
345
+ catch { /* best-effort */ }
346
+ }
347
+ }
348
+ /**
349
+ * One-line, caller-facing explanation of why a run produced no usable report.
350
+ * Never "No instrumentation ran" when the runner did run and failed.
351
+ */
352
+ export function describeRunFailure(run, projectRoot) {
353
+ if (run.missing) {
354
+ return `${run.runner} is not installed in ${projectRoot} (no node_modules/${run.runner} found); ` +
355
+ 'nothing was run and nothing was downloaded. Install it, or generate a coverage report and pass it as the target.';
356
+ }
357
+ if (run.timedOut) {
358
+ return `The coverage run timed out after ${Math.round(run.timeoutMs / 1000)}s and was stopped.`;
359
+ }
360
+ if (run.exitCode !== 0) {
361
+ const tail = run.stderrTail ? `: ${run.stderrTail}` : '';
362
+ return `Test runner (${run.runner}) exited with code ${run.exitCode ?? 'unknown'} without a coverage report${tail}`;
363
+ }
364
+ return `Test runner (${run.runner}) exited cleanly but wrote no coverage report. ` +
365
+ 'Ensure a coverage provider is configured (e.g., @vitest/coverage-v8, istanbul).';
366
+ }
367
+ //# sourceMappingURL=coverage-runner.js.map
@@ -0,0 +1,144 @@
1
+ /**
2
+ * Coverage target resolution (issue #995).
3
+ *
4
+ * A coverage target can be the project root, a subfolder of it, a single source
5
+ * file, or an existing coverage report. Before #995 every target was treated as
6
+ * if it were the project root: `target: "src/"` ran vitest FROM `src/` (which
7
+ * found no tests, reported 0%, and wrote `src/coverage/` into the source tree),
8
+ * and `target: "coverage/lcov.info"` was searched for a `coverage/` folder
9
+ * inside a file and came back empty.
10
+ *
11
+ * This module answers the three questions every collector needs first:
12
+ * 1. Which project does the target belong to? (`findCoverageProjectRoot`)
13
+ * 2. Is the target itself a coverage report? (`isCoverageReportFile` /
14
+ * `loadCoverageReportFile`)
15
+ * 3. Which entries of a project-wide report belong to the target?
16
+ * (`scopeCoverageToTarget`)
17
+ *
18
+ * Kept free of task-executor and child-process imports so both the MCP handler
19
+ * and the CLI `coverage` command can share it.
20
+ */
21
+ import type { CoverageData, FileCoverage } from '../../domains/coverage-analysis/interfaces';
22
+ /**
23
+ * Walk up from a target to the nearest directory that holds a project marker.
24
+ *
25
+ * NEAREST rather than topmost: in a monorepo, `packages/core/src` belongs to
26
+ * `packages/core` (its own package.json and test config), not the workspace
27
+ * root. This intentionally differs from `kernel/findProjectRoot`, which locates
28
+ * the AQE data root (honouring AQE_PROJECT_ROOT and `.agentic-qe`).
29
+ *
30
+ * Returns `null` when the target does not exist (a typo must not silently
31
+ * resolve to — and run tests for — an ancestor project) or when no marker is
32
+ * found below the home directory / filesystem root within `maxDepth` levels.
33
+ */
34
+ export declare function findCoverageProjectRoot(target: string, maxDepth?: number): string | null;
35
+ /** Is this path (by name) a coverage report rather than source code? */
36
+ export declare function isCoverageReportFile(filePath: string): boolean;
37
+ /**
38
+ * Parse a coverage report file of any supported format.
39
+ *
40
+ * Returns `null` — never an empty "0%" report — when the file can't be read,
41
+ * can't be parsed, or lists no files.
42
+ */
43
+ export declare function loadCoverageReportFile(filePath: string): Promise<CoverageData | null>;
44
+ /**
45
+ * Keep only the report entries that lie under `target`.
46
+ *
47
+ * Report paths come in two shapes: absolute (istanbul `coverage-final.json`)
48
+ * and project-root-relative (vitest/jest `lcov.info` writes `SF:src/math.ts`).
49
+ * Relative entries are resolved against `root` before comparing. Entry paths are
50
+ * returned unchanged.
51
+ */
52
+ export declare function scopeCoverageToTarget(data: CoverageData, root: string, target: string): FileCoverage[];
53
+ /** Why there are no coverage figures for a target. */
54
+ export type NoDataReason =
55
+ /** The target path does not exist. */
56
+ 'target-missing'
57
+ /** A coverage report was given but cannot be parsed (malformed, raw V8, empty). */
58
+ | 'unreadable-report'
59
+ /** The report lists only test files. */
60
+ | 'test-only-report'
61
+ /** The report has no entries under the target — it did not measure it. */
62
+ | 'target-not-covered'
63
+ /** The test runner itself reports running zero tests. */
64
+ | 'no-tests-ran';
65
+ export type CoverageEvaluation = {
66
+ status: 'measured';
67
+ files: FileCoverage[];
68
+ } | {
69
+ status: 'no-data';
70
+ reason: NoDataReason;
71
+ };
72
+ /**
73
+ * Decide what a report says about `target`. Shared by the MCP handler and the
74
+ * CLI so the two cannot disagree (#995 review B2).
75
+ *
76
+ * "Unmeasured" is decided ONLY from evidence that nothing was measured:
77
+ * - the runner's own result says it ran 0 tests (`numTotalTests === 0`), or
78
+ * - the report has no entry under the target.
79
+ * Hit counts are never used: a file listed with 0 hits is a measured 0%,
80
+ * whether the report came from our run or from the user (#995 review B3).
81
+ */
82
+ export declare function evaluateCoverageForTarget(report: CoverageData, projectRoot: string, target: string, options?: {
83
+ numTotalTests?: number | null;
84
+ }): CoverageEvaluation;
85
+ export type ExistingCoverage = {
86
+ status: 'target-missing';
87
+ target: string;
88
+ } | {
89
+ status: 'no-report';
90
+ target: string;
91
+ projectRoot: string;
92
+ } | {
93
+ status: 'evaluated';
94
+ target: string;
95
+ projectRoot: string;
96
+ source: 'report-file' | 'project-report';
97
+ evaluation: CoverageEvaluation;
98
+ };
99
+ /**
100
+ * Resolve a target to coverage that already exists on disk, without running
101
+ * anything:
102
+ * - a coverage report passed as the target is parsed and analysed whole;
103
+ * - otherwise the PROJECT ROOT's report (not the cwd's, not the subfolder's)
104
+ * is scoped to the target;
105
+ * - `no-report` tells the caller it may run tooling from `projectRoot`.
106
+ */
107
+ export declare function resolveExistingCoverage(targetPath: string): Promise<ExistingCoverage>;
108
+ /**
109
+ * Threshold verdict over the metrics that were actually collected. Shared by
110
+ * MCP and CLI (#995 review NB5): an uncollected metric (no branch data in the
111
+ * report) is null, and a null must not drag the average down as a fake 0.
112
+ */
113
+ export declare function thresholdVerdict(summary: {
114
+ line: number;
115
+ branch: number;
116
+ function: number;
117
+ statement: number;
118
+ }, threshold: number, collected: {
119
+ branch: boolean;
120
+ function: boolean;
121
+ }): {
122
+ overall: number;
123
+ meetsThreshold: boolean;
124
+ };
125
+ /**
126
+ * Make the analyzer's recommendations agree with `thresholdVerdict`
127
+ * (#995 review NB-A). The analyzer computes its "Coverage is X% below
128
+ * threshold" line from a 4-metric average that counts an uncollected metric as
129
+ * 0 — so a line-only report at 90% got "Met" next to "35.0% below threshold".
130
+ * Here the shortfall line is recomputed from the collected-metrics verdict,
131
+ * and advice about a metric that was never collected is dropped.
132
+ */
133
+ export declare function reconcileRecommendations(recommendations: string[], verdict: {
134
+ overall: number;
135
+ meetsThreshold: boolean;
136
+ }, threshold: number, collected: {
137
+ branch: boolean;
138
+ function: boolean;
139
+ }): string[];
140
+ /** Is this verdict "no measurement exists" (as opposed to an error or test-only report)? */
141
+ export declare function isUnmeasured(reason: NoDataReason): boolean;
142
+ /** Caller-facing explanation of a no-data verdict. Shared by MCP and CLI. */
143
+ export declare function describeNoData(reason: NoDataReason, target: string, projectRoot: string | null): string;
144
+ //# sourceMappingURL=coverage-target.d.ts.map