agentic-qe 3.15.11 → 3.15.12

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 (431) hide show
  1. package/.claude/hooks/aqe-hook.cjs +38 -2
  2. package/.claude/skills/skills-manifest.json +1 -1
  3. package/CHANGELOG.md +149 -0
  4. package/assets/skills/skills-manifest.json +1 -1
  5. package/dist/cli/bundle.js +6 -6
  6. package/dist/cli/chunks/adapter-HL7MOCQN.js +2 -0
  7. package/dist/cli/chunks/{agent-booster-wasm-TIDSQ3ZK.js → agent-booster-wasm-5VZCKTIJ.js} +2 -2
  8. package/dist/cli/chunks/{agent-handler-G3EPBVA7.js → agent-handler-K3C6CQCD.js} +2 -2
  9. package/dist/cli/chunks/{agent-memory-branch-ARC5C7GW.js → agent-memory-branch-NVFQ25WS.js} +2 -2
  10. package/dist/cli/chunks/aqe-learning-engine-OZ2DXB4G.js +2 -0
  11. package/dist/cli/chunks/{arena-K4I4QDXB.js → arena-QGWIJADQ.js} +2 -2
  12. package/dist/cli/chunks/{arena-36DTATJV.js → arena-TSZVDSXS.js} +4 -4
  13. package/dist/cli/chunks/{audit-WQSJSJZF.js → audit-KIEE2SHJ.js} +3 -3
  14. package/dist/cli/chunks/base-WIM7G3HC.js +2 -0
  15. package/dist/cli/chunks/{better-sqlite3-BB4K67MT.js → better-sqlite3-BNB32NW3.js} +2 -2
  16. package/dist/cli/chunks/{brain-handler-CU3GOIU3.js → brain-handler-MPC5SPYI.js} +3 -3
  17. package/dist/cli/chunks/{branch-enumerator-NJQX7ZNB.js → branch-enumerator-LZ7UXKAY.js} +2 -2
  18. package/dist/cli/chunks/{browser-6YJF4FQW.js → browser-VDHAW4RK.js} +2 -2
  19. package/dist/cli/chunks/browser-workflow-QRKCFVR3.js +2 -0
  20. package/dist/cli/chunks/{chunk-V7DA4HAK.js → chunk-23PQF7NN.js} +1 -1
  21. package/dist/cli/chunks/{chunk-IENZSO3K.js → chunk-26672ISV.js} +2 -2
  22. package/dist/cli/chunks/{chunk-OURITHFV.js → chunk-2ASQRBK2.js} +2 -2
  23. package/dist/cli/chunks/{chunk-VBK2YAYY.js → chunk-2E2QO44T.js} +2 -2
  24. package/dist/cli/chunks/{chunk-NT7JRHMH.js → chunk-2IVE5AR3.js} +1 -1
  25. package/dist/cli/chunks/{chunk-672XOJDG.js → chunk-2JYUA27M.js} +1 -1
  26. package/dist/cli/chunks/{chunk-OHR7C777.js → chunk-2PPSS4JD.js} +2 -2
  27. package/dist/cli/chunks/{chunk-FUYOOKTH.js → chunk-32UTHIY5.js} +3 -3
  28. package/dist/cli/chunks/{chunk-UKKYMW3S.js → chunk-33I2ZP6E.js} +2 -2
  29. package/dist/cli/chunks/{chunk-76SNL7GU.js → chunk-35MIUSXQ.js} +2 -2
  30. package/dist/cli/chunks/{chunk-4X4MWMHB.js → chunk-35NW676P.js} +2 -2
  31. package/dist/cli/chunks/{chunk-BZPE3LDO.js → chunk-3EWQN37E.js} +2 -2
  32. package/dist/cli/chunks/{chunk-5N25I53C.js → chunk-3IU4LDZR.js} +2 -2
  33. package/dist/cli/chunks/{chunk-NKTWKYHB.js → chunk-47RMGDG4.js} +2 -2
  34. package/dist/cli/chunks/chunk-4A76VPU4.js +3 -0
  35. package/dist/cli/chunks/{chunk-4RH5I24Q.js → chunk-4CB3QPZM.js} +2 -2
  36. package/dist/cli/chunks/{chunk-U3LJNNVJ.js → chunk-4HWUECVD.js} +2 -2
  37. package/dist/cli/chunks/{chunk-T5KHJ3J7.js → chunk-4KUOYDY2.js} +2 -2
  38. package/dist/cli/chunks/{chunk-XNLIWQYE.js → chunk-4LWMAAWK.js} +2 -2
  39. package/dist/cli/chunks/{chunk-KKYO2NKV.js → chunk-4PU5GTZW.js} +2 -2
  40. package/dist/cli/chunks/{chunk-VWUZSNVC.js → chunk-4SA7M34P.js} +1 -1
  41. package/dist/cli/chunks/{chunk-5WYZHDIZ.js → chunk-4Y6OEBJZ.js} +1 -1
  42. package/dist/cli/chunks/{chunk-J4JMCZVA.js → chunk-5A66EGEW.js} +2 -2
  43. package/dist/cli/chunks/{chunk-HFFPYC4G.js → chunk-5ADXFUMO.js} +2 -2
  44. package/dist/cli/chunks/{chunk-KJCIMNHS.js → chunk-5S4UIDFK.js} +1 -1
  45. package/dist/cli/chunks/{chunk-YBBT3YYG.js → chunk-5TAEW5OV.js} +1 -1
  46. package/dist/cli/chunks/{chunk-FLU5FDSC.js → chunk-5Z23ZMXZ.js} +59 -59
  47. package/dist/cli/chunks/{chunk-YNOCQ2SL.js → chunk-65TH6RPD.js} +1 -1
  48. package/dist/cli/chunks/{chunk-XGPTZUKQ.js → chunk-66PXR3NI.js} +2 -2
  49. package/dist/cli/chunks/{chunk-ITPGWGQS.js → chunk-6E6HB4N4.js} +4 -4
  50. package/dist/cli/chunks/{chunk-EJPK7OTR.js → chunk-6QRI3JVE.js} +2 -2
  51. package/dist/cli/chunks/{chunk-ZP75ASUU.js → chunk-7DNR4KKR.js} +1 -1
  52. package/dist/cli/chunks/{chunk-V5AADCBC.js → chunk-7JFDLL2F.js} +1 -1
  53. package/dist/cli/chunks/chunk-7OEFBWAG.js +5 -0
  54. package/dist/cli/chunks/{chunk-EIDJNT5C.js → chunk-7QEUHNKO.js} +1 -1
  55. package/dist/cli/chunks/{chunk-7R5HC56U.js → chunk-7TA5MUPW.js} +1 -1
  56. package/dist/cli/chunks/{chunk-LCVEEII4.js → chunk-A2JCRXTK.js} +2 -2
  57. package/dist/cli/chunks/{chunk-JUMICXM6.js → chunk-A5Y7DAVQ.js} +2 -2
  58. package/dist/cli/chunks/{chunk-FZHSG75I.js → chunk-ADUAJIAU.js} +2 -2
  59. package/dist/cli/chunks/{chunk-TFW7CCKS.js → chunk-AJEXPFAB.js} +1 -1
  60. package/dist/cli/chunks/{chunk-JGJXXAS6.js → chunk-BC4T6SCV.js} +4 -4
  61. package/dist/cli/chunks/{chunk-4RAQ7PJA.js → chunk-BMG2JLSQ.js} +2 -2
  62. package/dist/cli/chunks/{chunk-Y7B5EUIJ.js → chunk-BOSMELJX.js} +2 -2
  63. package/dist/cli/chunks/{chunk-CIAL4YRY.js → chunk-BYRCB5JT.js} +2 -2
  64. package/dist/cli/chunks/{chunk-XS2XF3YG.js → chunk-C3YOVASQ.js} +1 -1
  65. package/dist/cli/chunks/{chunk-FL32MTKT.js → chunk-C74M4WUI.js} +2 -2
  66. package/dist/cli/chunks/{chunk-S6IYEBAI.js → chunk-CA5UNWQF.js} +2 -2
  67. package/dist/cli/chunks/{chunk-5MTWCCZJ.js → chunk-CDA5Z74H.js} +2 -2
  68. package/dist/cli/chunks/{chunk-DOFREOPQ.js → chunk-CPIBIR3X.js} +2 -2
  69. package/dist/cli/chunks/{chunk-UMVSWQNB.js → chunk-CU36D7TN.js} +2 -2
  70. package/dist/cli/chunks/{chunk-G4CKPWF6.js → chunk-DAUEK66C.js} +1 -1
  71. package/dist/cli/chunks/{chunk-2KFFEKSI.js → chunk-DRCBRUGN.js} +2 -2
  72. package/dist/cli/chunks/{chunk-EH2S6AOR.js → chunk-DZGPUGUG.js} +2 -2
  73. package/dist/cli/chunks/{chunk-HYXUN7BW.js → chunk-EF6OERRR.js} +1 -1
  74. package/dist/cli/chunks/{chunk-G77MLBDF.js → chunk-EN7GRVEQ.js} +2 -2
  75. package/dist/cli/chunks/{chunk-XDI5X3FR.js → chunk-ENGL7FIJ.js} +1 -1
  76. package/dist/cli/chunks/{chunk-HDNWSKHA.js → chunk-FAGKBOX2.js} +2 -2
  77. package/dist/cli/chunks/{chunk-FWSGPE3V.js → chunk-FNUFTWEO.js} +3 -3
  78. package/dist/cli/chunks/{chunk-AUUJBXWX.js → chunk-FZJCBSN4.js} +2 -2
  79. package/dist/cli/chunks/{chunk-ERN43HOX.js → chunk-G24SWTAX.js} +35 -35
  80. package/dist/cli/chunks/{chunk-VEEYL2CZ.js → chunk-G3AABG4Q.js} +2 -2
  81. package/dist/cli/chunks/{chunk-35M2X3C5.js → chunk-GJKZ7UQO.js} +2 -2
  82. package/dist/cli/chunks/{chunk-OV5RPLKV.js → chunk-GKFV6CUD.js} +2 -2
  83. package/dist/cli/chunks/{chunk-4HJKQIX5.js → chunk-HLGFHHWV.js} +2 -2
  84. package/dist/cli/chunks/{chunk-R5LGV6GZ.js → chunk-HM3LSFTY.js} +2 -2
  85. package/dist/cli/chunks/{chunk-M7XFBSIK.js → chunk-HSA5IGGW.js} +2 -2
  86. package/dist/cli/chunks/{chunk-GWJWSLDA.js → chunk-HZBXJFGN.js} +2 -2
  87. package/dist/cli/chunks/{chunk-4MUBW4RT.js → chunk-IA55PFLG.js} +2 -2
  88. package/dist/cli/chunks/{chunk-RBZCA7SD.js → chunk-ICKUINKD.js} +2 -2
  89. package/dist/cli/chunks/{chunk-KDI5JOYZ.js → chunk-IETBWYHW.js} +2 -2
  90. package/dist/cli/chunks/{chunk-325QCVDI.js → chunk-IL7GQNNE.js} +2 -2
  91. package/dist/cli/chunks/{chunk-BTVWA35P.js → chunk-INZARYUD.js} +2 -2
  92. package/dist/cli/chunks/{chunk-G2IJFNZS.js → chunk-IPA7K556.js} +2 -2
  93. package/dist/cli/chunks/{chunk-UTTSH4NH.js → chunk-IVTQF55W.js} +3 -3
  94. package/dist/cli/chunks/{chunk-2CW7VRPH.js → chunk-J7Y7ZBIT.js} +5 -5
  95. package/dist/cli/chunks/{chunk-M5RQ6U3G.js → chunk-JGIJPDGD.js} +2 -2
  96. package/dist/cli/chunks/{chunk-RQMCZQN2.js → chunk-JNXK47OL.js} +2 -2
  97. package/dist/cli/chunks/{chunk-X4J73KP3.js → chunk-JOWUS2X5.js} +1 -1
  98. package/dist/cli/chunks/{chunk-ZMC543GI.js → chunk-JR6CUKAI.js} +2 -2
  99. package/dist/cli/chunks/chunk-JRYWLOBD.js +21 -0
  100. package/dist/cli/chunks/{chunk-ETVAYGCB.js → chunk-JW5PDJ5O.js} +3 -3
  101. package/dist/cli/chunks/{chunk-OD5D4LSZ.js → chunk-K3A3NWT3.js} +2 -2
  102. package/dist/cli/chunks/{chunk-LPU6PAJE.js → chunk-KA5SHLMW.js} +2 -2
  103. package/dist/cli/chunks/{chunk-NPZOBSAN.js → chunk-KGA7VAI4.js} +2 -2
  104. package/dist/cli/chunks/{chunk-ZMHCMJ4J.js → chunk-KJDI5CHX.js} +2 -2
  105. package/dist/cli/chunks/{chunk-KSLLHFVY.js → chunk-L3PV7VXK.js} +1 -1
  106. package/dist/cli/chunks/{chunk-LD5CFK53.js → chunk-L7NGKANW.js} +2 -2
  107. package/dist/cli/chunks/{chunk-6NA3KZZT.js → chunk-LFBA735S.js} +7 -7
  108. package/dist/cli/chunks/{chunk-Z2EA7A4Z.js → chunk-MAJXZYGK.js} +1 -1
  109. package/dist/cli/chunks/{chunk-TCYSBC7Y.js → chunk-MCPEC6OO.js} +1 -1
  110. package/dist/cli/chunks/{chunk-LBX7M4LW.js → chunk-MCPXNUDK.js} +2 -2
  111. package/dist/cli/chunks/{chunk-5YLOLACR.js → chunk-MMEALJ4D.js} +2 -2
  112. package/dist/cli/chunks/{chunk-IOZRKXR5.js → chunk-MYF5CNGV.js} +2 -2
  113. package/dist/cli/chunks/{chunk-X3PZCXWG.js → chunk-MYUMJ2ZI.js} +1 -1
  114. package/dist/cli/chunks/{chunk-VYTILW4R.js → chunk-N7O3PF6Y.js} +2 -2
  115. package/dist/cli/chunks/{chunk-GVKVJJQX.js → chunk-NA3F6FEO.js} +2 -2
  116. package/dist/cli/chunks/{chunk-TL6OFMXF.js → chunk-NNBQZR73.js} +2 -2
  117. package/dist/cli/chunks/{chunk-KXS3Y2AX.js → chunk-NV74SICL.js} +2 -2
  118. package/dist/cli/chunks/chunk-NVRYELCY.js +13 -0
  119. package/dist/cli/chunks/{chunk-OH5V5EJW.js → chunk-NX4BCSOZ.js} +2 -2
  120. package/dist/cli/chunks/{chunk-XJKZ7FTR.js → chunk-O3IM4WRZ.js} +2 -2
  121. package/dist/cli/chunks/{chunk-3RHOPP7A.js → chunk-O4QJMANM.js} +1 -1
  122. package/dist/cli/chunks/{chunk-O4JAKWWM.js → chunk-OHVYINGM.js} +17 -17
  123. package/dist/cli/chunks/{chunk-APPZATXA.js → chunk-P5E26N2X.js} +2 -2
  124. package/dist/cli/chunks/{chunk-5ERFHEEE.js → chunk-P7UFJ6DO.js} +1 -1
  125. package/dist/cli/chunks/{chunk-5MNASJOH.js → chunk-PGSJBXTD.js} +2 -2
  126. package/dist/cli/chunks/{chunk-WCAVIJ64.js → chunk-PT2NXS43.js} +1 -1
  127. package/dist/cli/chunks/{chunk-EWPUQCN4.js → chunk-PTBOLBM4.js} +2 -2
  128. package/dist/cli/chunks/{chunk-EK5GMOSO.js → chunk-PX5OPXY6.js} +1 -1
  129. package/dist/cli/chunks/chunk-QCPVUNN3.js +2 -0
  130. package/dist/cli/chunks/{chunk-K2HBNYAZ.js → chunk-QSGEBCDB.js} +2 -2
  131. package/dist/cli/chunks/{chunk-G4FAPO57.js → chunk-QUJJYTJH.js} +2 -2
  132. package/dist/cli/chunks/{chunk-H7BLYMNU.js → chunk-QWG3SILX.js} +3 -3
  133. package/dist/cli/chunks/{chunk-LXQ3B4RY.js → chunk-RCOLPF3B.js} +2 -2
  134. package/dist/cli/chunks/{chunk-E44NNCEU.js → chunk-RYHG3I7J.js} +2 -2
  135. package/dist/cli/chunks/{chunk-RTFKTKSO.js → chunk-SBHM5X2S.js} +2 -2
  136. package/dist/cli/chunks/{chunk-DOBZPSKE.js → chunk-SDRJJUPO.js} +1 -1
  137. package/dist/cli/chunks/{chunk-RTY7VSZB.js → chunk-SG2TX72G.js} +2 -2
  138. package/dist/cli/chunks/{chunk-NTB342NJ.js → chunk-SITL5YZV.js} +4 -4
  139. package/dist/cli/chunks/{chunk-WM3SRRA6.js → chunk-SPC4RBLF.js} +2 -2
  140. package/dist/cli/chunks/{chunk-ITL3IN2E.js → chunk-SQVZ3TRU.js} +2 -2
  141. package/dist/cli/chunks/{chunk-CO3DX2AX.js → chunk-SUX5XB2Z.js} +2 -2
  142. package/dist/cli/chunks/{chunk-KSE5TDM5.js → chunk-T4EN5VVK.js} +2 -2
  143. package/dist/cli/chunks/{chunk-5HQP4SLM.js → chunk-TGMXUZZC.js} +2 -2
  144. package/dist/cli/chunks/{chunk-YOCULVHR.js → chunk-TLRHAMX5.js} +1 -1
  145. package/dist/cli/chunks/{chunk-GBFUANTC.js → chunk-TOWOJGEI.js} +1 -1
  146. package/dist/cli/chunks/{chunk-4UBVAJFO.js → chunk-TSOQ2QLT.js} +2 -2
  147. package/dist/cli/chunks/{chunk-SMVVAVN2.js → chunk-TVA5GRIU.js} +2 -2
  148. package/dist/cli/chunks/{chunk-K7V2WZNF.js → chunk-TXEUVUMO.js} +1 -1
  149. package/dist/cli/chunks/{chunk-LQ4NUC6Q.js → chunk-U6IXYQO4.js} +2 -2
  150. package/dist/cli/chunks/{chunk-HDJUYAZG.js → chunk-U7ZHDGXG.js} +1 -1
  151. package/dist/cli/chunks/{chunk-2VLYUF7U.js → chunk-UCSK2RMI.js} +2 -2
  152. package/dist/cli/chunks/{chunk-4UX35V7P.js → chunk-UIKQPO4Y.js} +2 -2
  153. package/dist/cli/chunks/chunk-UJNGGFGX.js +2 -0
  154. package/dist/cli/chunks/{chunk-AFFN6E6Q.js → chunk-ULCW6IVQ.js} +2 -2
  155. package/dist/cli/chunks/{chunk-WCVCOT4E.js → chunk-UREDS662.js} +2 -2
  156. package/dist/cli/chunks/{chunk-E6PF35JZ.js → chunk-URSTP3WI.js} +2 -2
  157. package/dist/cli/chunks/{chunk-I36CRDHF.js → chunk-UUZZXHUF.js} +2 -2
  158. package/dist/cli/chunks/{chunk-MIK4RBEH.js → chunk-UZED4YZ5.js} +1 -1
  159. package/dist/cli/chunks/{chunk-ZQHDA4O7.js → chunk-VF7FTD64.js} +1 -1
  160. package/dist/cli/chunks/{chunk-AMZKAJLJ.js → chunk-VUR5THML.js} +2 -2
  161. package/dist/cli/chunks/{chunk-H43AFUKL.js → chunk-VXVTFKRA.js} +2 -2
  162. package/dist/cli/chunks/chunk-VZBC6DP7.js +2 -0
  163. package/dist/cli/chunks/{chunk-DDEOZPWJ.js → chunk-W4II6SIH.js} +2 -2
  164. package/dist/cli/chunks/{chunk-55CH76ZO.js → chunk-W5HQIYQU.js} +3 -3
  165. package/dist/cli/chunks/{chunk-YPX2TV3M.js → chunk-W7H55PY4.js} +1 -1
  166. package/dist/cli/chunks/{chunk-CFWGGRE7.js → chunk-WDEXOLK2.js} +1 -1
  167. package/dist/cli/chunks/{chunk-XGBU3KEM.js → chunk-WGTEZT7G.js} +2 -2
  168. package/dist/cli/chunks/{chunk-NC6K7SCQ.js → chunk-WLRU6ESI.js} +2 -2
  169. package/dist/cli/chunks/{chunk-JFLU7L3W.js → chunk-WTAUF6O4.js} +2 -2
  170. package/dist/cli/chunks/chunk-XCNSGSKV.js +3 -0
  171. package/dist/cli/chunks/{chunk-57LNKSW7.js → chunk-XZOYKB22.js} +2 -2
  172. package/dist/cli/chunks/chunk-YIDAXOUX.js +8 -0
  173. package/dist/cli/chunks/{chunk-25P77WA5.js → chunk-YLKIXEPP.js} +1 -1
  174. package/dist/cli/chunks/{chunk-R5GRABPQ.js → chunk-YNVEDFPQ.js} +1 -1
  175. package/dist/cli/chunks/{chunk-NQZNMCZU.js → chunk-YUA6ZKKY.js} +2 -2
  176. package/dist/cli/chunks/{chunk-OYJC3YON.js → chunk-YVJEUX3I.js} +2 -2
  177. package/dist/cli/chunks/{chunk-QDESWOZP.js → chunk-YWWMNTBF.js} +2 -2
  178. package/dist/cli/chunks/{chunk-7HEMJHPP.js → chunk-ZGROHCOW.js} +1 -1
  179. package/dist/cli/chunks/{chunk-AP3ADWDK.js → chunk-ZPVGX4DI.js} +2 -2
  180. package/dist/cli/chunks/{chunk-M5XYIQYZ.js → chunk-ZROAMFX2.js} +2 -2
  181. package/dist/cli/chunks/{chunk-I4K2HTQU.js → chunk-ZYOYR3UR.js} +1 -1
  182. package/dist/cli/chunks/ci-BZNWW3I3.js +81 -0
  183. package/dist/cli/chunks/{ci-config-J665XNOX.js → ci-config-LOHNXOKV.js} +2 -2
  184. package/dist/cli/chunks/{ci-output-PEQQQWVD.js → ci-output-LCOQBSJL.js} +2 -2
  185. package/dist/cli/chunks/{circuit-breaker-HHB2JSKH.js → circuit-breaker-7LRXTLFE.js} +2 -2
  186. package/dist/cli/chunks/{claude-flow-setup-JKUJRWPN.js → claude-flow-setup-HBU4VWC3.js} +2 -2
  187. package/dist/cli/chunks/client-4PNYDFYS.js +2 -0
  188. package/dist/cli/chunks/{cline-installer-Y77BWTAN.js → cline-installer-CO6MLH6X.js} +2 -2
  189. package/dist/cli/chunks/{code-LV2HAGJY.js → code-SIXBS6JM.js} +3 -3
  190. package/dist/cli/chunks/{code-index-extractor-4GKKSETB.js → code-index-extractor-GWJKZ2IQ.js} +2 -2
  191. package/dist/cli/chunks/{codex-installer-WMKBYE5Y.js → codex-installer-6NINVWXJ.js} +2 -2
  192. package/dist/cli/chunks/{completions-SBGFAOIJ.js → completions-7VIX3GML.js} +2 -2
  193. package/dist/cli/chunks/{complexity-analyzer-AQHFIJXC.js → complexity-analyzer-FBQR6ZP2.js} +2 -2
  194. package/dist/cli/chunks/{continuedev-installer-26AYFS2E.js → continuedev-installer-VA7RIXW5.js} +2 -2
  195. package/dist/cli/chunks/{copilot-installer-4UD3DK55.js → copilot-installer-4QEBC4MU.js} +2 -2
  196. package/dist/cli/chunks/core-handlers-ODO6LUWQ.js +2 -0
  197. package/dist/cli/chunks/{cost-tracker-TP4NZCG4.js → cost-tracker-GRYKHPWL.js} +2 -2
  198. package/dist/cli/chunks/{coverage-B2KIXHAI.js → coverage-USPMNKOU.js} +11 -10
  199. package/dist/cli/chunks/cross-domain-router-DT4MHJKK.js +2 -0
  200. package/dist/cli/chunks/{cursor-installer-AVZEQZ4W.js → cursor-installer-ZXIPSZVH.js} +2 -2
  201. package/dist/cli/chunks/{daemon-XM2A7LQU.js → daemon-D7F3RGI5.js} +3 -3
  202. package/dist/cli/chunks/{daemon-P574WWBW.js → daemon-N2VRHPSJ.js} +4 -4
  203. package/dist/cli/chunks/{dag-attention-scheduler-MIWOZ6ET.js → dag-attention-scheduler-NL6BA7BY.js} +2 -2
  204. package/dist/cli/chunks/{detect-TYR7HT23.js → detect-XC2HCIIT.js} +2 -2
  205. package/dist/cli/chunks/{dist-node-2DGVQGLS.js → dist-node-A3Y26MEI.js} +2 -2
  206. package/dist/cli/chunks/{domain-handler-RRA4ZOMF.js → domain-handler-WV6SFXRB.js} +2 -2
  207. package/dist/cli/chunks/{domain-plugins-IVZEZ5RB.js → domain-plugins-KJIF6Z2B.js} +2 -2
  208. package/dist/cli/chunks/{domain-transfer-DOBI67K6.js → domain-transfer-L3F6AES2.js} +2 -2
  209. package/dist/cli/chunks/dream-QOB3JCOM.js +2 -0
  210. package/dist/cli/chunks/{embed-and-insert-pattern-VNIEOVPO.js → embed-and-insert-pattern-PA3Y4KGO.js} +2 -2
  211. package/dist/cli/chunks/{eval-QV4LVPUF.js → eval-YGEZNUVE.js} +2 -2
  212. package/dist/cli/chunks/{experience-capture-middleware-DAPKT763.js → experience-capture-middleware-D4T7NW6B.js} +3 -3
  213. package/dist/cli/chunks/{fast-paths-WVRFPHX7.js → fast-paths-6JYK7RYQ.js} +2 -2
  214. package/dist/cli/chunks/{feature-flags-O7ZXDDCD.js → feature-flags-DKXMDVPE.js} +2 -2
  215. package/dist/cli/chunks/{feature-flags-DEFTUIYT.js → feature-flags-RBH2GDSR.js} +2 -2
  216. package/dist/cli/chunks/file-discovery-BN76S2PR.js +2 -0
  217. package/dist/cli/chunks/fleet-43YMXACN.js +46 -0
  218. package/dist/cli/chunks/{gnn-wrapper-LS4LZJDR.js → gnn-wrapper-MV54UC4C.js} +2 -2
  219. package/dist/cli/chunks/{heartbeat-handler-RFTERD4K.js → heartbeat-handler-7DKMVQQH.js} +4 -4
  220. package/dist/cli/chunks/heartbeat-scheduler-3NNP4WCP.js +2 -0
  221. package/dist/cli/chunks/hnsw-adapter-MZR7Y4WF.js +2 -0
  222. package/dist/cli/chunks/hnsw-index-HE4AX22U.js +2 -0
  223. package/dist/cli/chunks/{hnsw-legacy-bridge-GPKGFFHY.js → hnsw-legacy-bridge-6IWREDQC.js} +2 -2
  224. package/dist/cli/chunks/{hnswlib-node-PHL3F2PR.js → hnswlib-node-5BIESSCK.js} +2 -2
  225. package/dist/cli/chunks/{hooks-GYJ6D4QM.js → hooks-3EETRM62.js} +28 -28
  226. package/dist/cli/chunks/hybrid-backend-IHUHB3Y2.js +2 -0
  227. package/dist/cli/chunks/{hypergraph-engine-YGEQPCKJ.js → hypergraph-engine-RSWCB2D3.js} +2 -2
  228. package/dist/cli/chunks/{hypergraph-handler-ZIMM647V.js → hypergraph-handler-552LXKL3.js} +3 -3
  229. package/dist/cli/chunks/impact-analyzer-FI6GI6PD.js +2 -0
  230. package/dist/cli/chunks/{init-guard-VOMBXJXG.js → init-guard-OTDBJ5HD.js} +2 -2
  231. package/dist/cli/chunks/{init-handler-PSMUBWK5.js → init-handler-3FK3TKEA.js} +6 -6
  232. package/dist/cli/chunks/init-wizard-WLQKH5Y5.js +2 -0
  233. package/dist/cli/chunks/kernel-2WZOQEZS.js +2 -0
  234. package/dist/cli/chunks/{kilocode-installer-2YNTFBWJ.js → kilocode-installer-KZ2O4LF3.js} +2 -2
  235. package/dist/cli/chunks/{kiro-installer-XHJDPVAZ.js → kiro-installer-MLCCXRF7.js} +2 -2
  236. package/dist/cli/chunks/knowledge-graph-G3LVKK6P.js +2 -0
  237. package/dist/cli/chunks/{learning-GNSIDRNG.js → learning-QUCMBD77.js} +3 -3
  238. package/dist/cli/chunks/{llm-router-LQDM7IU2.js → llm-router-PDEV3UP2.js} +4 -4
  239. package/dist/cli/chunks/llm-router-service-MM75HKWJ.js +2 -0
  240. package/dist/cli/chunks/{load-YATHI72E.js → load-XFVVLO7E.js} +2 -2
  241. package/dist/cli/chunks/load-test-BEWEE44J.js +2 -0
  242. package/dist/cli/chunks/{mcp-4Y6GDLYK.js → mcp-74G3CL2S.js} +2 -2
  243. package/dist/cli/chunks/{memory-OUW3L7H2.js → memory-XIFM6JNX.js} +5 -5
  244. package/dist/cli/chunks/memory-backend-NYKBBKZR.js +2 -0
  245. package/dist/cli/chunks/{memory-handlers-G3LFF53U.js → memory-handlers-ZCKURV6S.js} +2 -2
  246. package/dist/cli/chunks/{multi-model-executor-UBZJXAD2.js → multi-model-executor-7L4W3O2Q.js} +2 -2
  247. package/dist/cli/chunks/{opencode-installer-AMMNWVH5.js → opencode-installer-BPG422LF.js} +2 -2
  248. package/dist/cli/chunks/{orchestrator-Y44WDOER.js → orchestrator-OEAFLAEV.js} +58 -20
  249. package/dist/cli/chunks/pattern-null-store-QGPUIV6M.js +2 -0
  250. package/dist/cli/chunks/{pattern-usage-recorder-ESR42RME.js → pattern-usage-recorder-LOPNCULT.js} +2 -2
  251. package/dist/cli/chunks/{pipeline-EDTS6OSC.js → pipeline-VWTYUZB7.js} +2 -2
  252. package/dist/cli/chunks/{platform-5WONJSUX.js → platform-WFJJ3X2E.js} +2 -2
  253. package/dist/cli/chunks/{plugin-IJXPCLD4.js → plugin-744TPUSG.js} +2 -2
  254. package/dist/cli/chunks/{prime-radiant-advanced-wasm-5ECKGZK6.js → prime-radiant-advanced-wasm-BD5BLNDR.js} +2 -2
  255. package/dist/cli/chunks/project-root-C7ELXZRK.js +2 -0
  256. package/dist/cli/chunks/protocol-executor-SUVE33BM.js +2 -0
  257. package/dist/cli/chunks/{protocol-handler-DRD3GVNW.js → protocol-handler-JIBILI74.js} +2 -2
  258. package/dist/cli/chunks/{prove-KTGW2HMJ.js → prove-MNOL5FYW.js} +2 -2
  259. package/dist/cli/chunks/qe-reasoning-bank-YWZMMGJB.js +2 -0
  260. package/dist/cli/chunks/{quality-DV2WPRRS.js → quality-JEGBDGGX.js} +2 -2
  261. package/dist/cli/chunks/{quality-gate-HFUAFVZC.js → quality-gate-SYJ6ROMI.js} +3 -3
  262. package/dist/cli/chunks/queen-coordinator-ZFAKXRN7.js +2 -0
  263. package/dist/cli/chunks/real-embeddings-ZWXS5ZFV.js +2 -0
  264. package/dist/cli/chunks/{ref-validation-QWSKS5OY.js → ref-validation-RRHUFW2N.js} +2 -2
  265. package/dist/cli/chunks/{roocode-installer-RBAYRCHX.js → roocode-installer-XFO6JSVN.js} +2 -2
  266. package/dist/cli/chunks/router-4FTAVYLJ.js +2 -0
  267. package/dist/cli/chunks/routing-feedback-IO2KOWMJ.js +2 -0
  268. package/dist/cli/chunks/{routing-handler-FMPP3XKO.js → routing-handler-L2K3JASE.js} +2 -2
  269. package/dist/cli/chunks/{ruvector-commands-KZZT4HWF.js → ruvector-commands-A6CINHGM.js} +2 -2
  270. package/dist/cli/chunks/rvf-dual-writer-KCIRNE7C.js +2 -0
  271. package/dist/cli/chunks/rvf-migration-adapter-MFC5WTJU.js +2 -0
  272. package/dist/cli/chunks/{rvf-migration-coordinator-7CHEV35N.js → rvf-migration-coordinator-T4RY7L53.js} +2 -2
  273. package/dist/cli/chunks/rvf-native-adapter-I3KWHE7X.js +2 -0
  274. package/dist/cli/chunks/{rvf-store-integrity-Q2TH52SN.js → rvf-store-integrity-IR33TGQS.js} +2 -2
  275. package/dist/cli/chunks/safe-db-QXDZ6QY3.js +2 -0
  276. package/dist/cli/chunks/schedule-CZKD6RIY.js +2 -0
  277. package/dist/cli/chunks/scheduler-BLA3Q4CH.js +2 -0
  278. package/dist/cli/chunks/{security-CUEA3UIM.js → security-Z5GDE2IH.js} +3 -3
  279. package/dist/cli/chunks/{shared-rvf-adapter-DROMBRV2.js → shared-rvf-adapter-SIZMEHPM.js} +2 -2
  280. package/dist/cli/chunks/{shared-rvf-dual-writer-DBNABOP7.js → shared-rvf-dual-writer-HLM65RDS.js} +2 -2
  281. package/dist/cli/chunks/sqlite-persistence-XIUYDJC4.js +2 -0
  282. package/dist/cli/chunks/{standalone-memory-IAHA3M6B.js → standalone-memory-SKSZG7P5.js} +2 -2
  283. package/dist/cli/chunks/{status-handler-AFUCASTX.js → status-handler-766YOOMJ.js} +2 -2
  284. package/dist/cli/chunks/{structural-health-AQRV6JJ6.js → structural-health-M45FNOLT.js} +2 -2
  285. package/dist/cli/chunks/{sync-GX7FMJHL.js → sync-6CJ24B5T.js} +2 -2
  286. package/dist/cli/chunks/{sync-XW5TLZ7M.js → sync-B2U366I3.js} +2 -2
  287. package/dist/cli/chunks/{task-handler-TFKVUTNF.js → task-handler-P6IFLCKP.js} +17 -15
  288. package/dist/cli/chunks/task-handlers-DPWMUKFC.js +9 -0
  289. package/dist/cli/chunks/{test-D2XDJNDX.js → test-TODH7KRF.js} +4 -4
  290. package/dist/cli/chunks/test-runner-process-46IPK3GH.js +2 -0
  291. package/dist/cli/chunks/{test-scheduling-TS6I2PR7.js → test-scheduling-VMVMVRHT.js} +3 -3
  292. package/dist/cli/chunks/{token-bootstrap-HBBLPCZ3.js → token-bootstrap-XQW7BMCK.js} +2 -2
  293. package/dist/cli/chunks/{token-usage-3MBUX4PR.js → token-usage-JCZEIRKO.js} +2 -2
  294. package/dist/cli/chunks/{transformers-ZWMQO3L2.js → transformers-U2ML3OHE.js} +2 -2
  295. package/dist/cli/chunks/tree-sitter-wasm-parser-MOI2WWNJ.js +2 -0
  296. package/dist/cli/chunks/{types-5YEMGPSQ.js → types-GGEPCHP6.js} +2 -2
  297. package/dist/cli/chunks/unified-memory-FL26RTV3.js +2 -0
  298. package/dist/cli/chunks/unified-memory-hnsw-E2BPTH3U.js +2 -0
  299. package/dist/cli/chunks/unified-persistence-5ZOUPKHF.js +2 -0
  300. package/dist/cli/chunks/{upgrade-2TPBKIHI.js → upgrade-T5GRM7HS.js} +2 -2
  301. package/dist/cli/chunks/{validate-XRAXXFW6.js → validate-XMUJPLP3.js} +2 -2
  302. package/dist/cli/chunks/{validate-swarm-IYSCS3BZ.js → validate-swarm-KJLF7JEH.js} +2 -2
  303. package/dist/cli/chunks/visual-security-IJVPO5FA.js +2 -0
  304. package/dist/cli/chunks/{web-tree-sitter-PZQ3ZG2P.js → web-tree-sitter-LOHVZ7G5.js} +2 -2
  305. package/dist/cli/chunks/{windsurf-installer-U6XWFRVT.js → windsurf-installer-33FBTXJU.js} +2 -2
  306. package/dist/cli/chunks/witness-chain-5FAFCQKP.js +2 -0
  307. package/dist/cli/chunks/witness-chain-V2M32W5D.js +2 -0
  308. package/dist/cli/chunks/{witness-chain-repair-K7YX2AO6.js → witness-chain-repair-VWBO4NXE.js} +2 -2
  309. package/dist/cli/chunks/{witness-chain-verifier-GUTC3W7N.js → witness-chain-verifier-BHJ3ZAEK.js} +2 -2
  310. package/dist/cli/chunks/{witness-key-manager-YBNKMOP6.js → witness-key-manager-WNVPH2Z3.js} +2 -2
  311. package/dist/cli/chunks/{workflow-UAJUILFQ.js → workflow-6QR5MQTO.js} +4 -4
  312. package/dist/cli/chunks/workflow-orchestrator-3JLF3IX7.js +2 -0
  313. package/dist/cli/chunks/{wrappers-AVZ3GPAL.js → wrappers-EHOL62TS.js} +2 -2
  314. package/dist/cli/commands/ci.js +7 -0
  315. package/dist/cli/commands/coverage.js +7 -1
  316. package/dist/cli/commands/fleet.js +2 -2
  317. package/dist/cli/commands/hooks-handlers/stats-hooks.d.ts +4 -3
  318. package/dist/cli/commands/hooks-handlers/stats-hooks.js +22 -4
  319. package/dist/cli/handlers/task-handler.js +6 -0
  320. package/dist/cli/utils/coverage-verdict.d.ts +11 -2
  321. package/dist/cli/utils/coverage-verdict.js +26 -6
  322. package/dist/cli/utils/fleet-operation.d.ts +5 -0
  323. package/dist/cli/utils/fleet-operation.js +7 -1
  324. package/dist/cli/utils/fleet-result.d.ts +5 -3
  325. package/dist/cli/utils/fleet-result.js +9 -3
  326. package/dist/coordination/handlers/coverage-collection.d.ts +2 -0
  327. package/dist/coordination/handlers/coverage-collection.js +2 -1
  328. package/dist/coordination/handlers/coverage-evidence.d.ts +75 -0
  329. package/dist/coordination/handlers/coverage-evidence.js +159 -0
  330. package/dist/coordination/handlers/coverage-handlers.js +16 -3
  331. package/dist/coordination/handlers/coverage-scope.d.ts +40 -0
  332. package/dist/coordination/handlers/coverage-scope.js +321 -0
  333. package/dist/coordination/handlers/coverage-target.d.ts +9 -0
  334. package/dist/coordination/handlers/coverage-target.js +15 -5
  335. package/dist/coordination/handlers/handler-utils.d.ts +5 -0
  336. package/dist/coordination/handlers/handler-utils.js +8 -4
  337. package/dist/domains/code-intelligence/services/metric-collector/listing-process-owner.js +4 -1
  338. package/dist/domains/code-intelligence/services/semantic-analyzer.d.ts +8 -0
  339. package/dist/domains/code-intelligence/services/semantic-analyzer.js +10 -7
  340. package/dist/init/phases/10-workers.js +42 -4
  341. package/dist/integrations/agentic-flow/reasoning-bank/experience-replay.d.ts +23 -1
  342. package/dist/integrations/agentic-flow/reasoning-bank/experience-replay.js +50 -15
  343. package/dist/integrations/agentic-flow/reasoning-bank/index.d.ts +7 -2
  344. package/dist/integrations/agentic-flow/reasoning-bank/index.js +8 -0
  345. package/dist/learning/embedder-endpoint-client.d.ts +8 -0
  346. package/dist/learning/embedder-endpoint-client.js +20 -0
  347. package/dist/learning/embedder-recovery.d.ts +63 -0
  348. package/dist/learning/embedder-recovery.js +94 -0
  349. package/dist/learning/qe-reasoning-bank-types.d.ts +5 -0
  350. package/dist/learning/qe-reasoning-bank.d.ts +21 -0
  351. package/dist/learning/qe-reasoning-bank.js +54 -8
  352. package/dist/learning/real-embeddings.d.ts +23 -0
  353. package/dist/learning/real-embeddings.js +69 -2
  354. package/dist/learning/real-qe-reasoning-bank.d.ts +24 -4
  355. package/dist/learning/real-qe-reasoning-bank.js +58 -20
  356. package/dist/logging/redaction.js +142 -12
  357. package/dist/mcp/bundle.js +504 -492
  358. package/dist/mcp/daemon-mode.d.ts +126 -0
  359. package/dist/mcp/daemon-mode.js +257 -0
  360. package/dist/mcp/entry.d.ts +4 -0
  361. package/dist/mcp/entry.js +50 -2
  362. package/dist/mcp/handlers/domain-handler-configs.js +5 -0
  363. package/dist/mcp/handlers/orchestrate-routes.d.ts +6 -1
  364. package/dist/mcp/handlers/orchestrate-routes.js +53 -0
  365. package/dist/mcp/handlers/task-handlers.d.ts +11 -2
  366. package/dist/mcp/handlers/task-handlers.js +50 -5
  367. package/dist/mcp/protocol-server.js +3 -0
  368. package/dist/mcp/services/reasoning-bank-service.d.ts +6 -1
  369. package/dist/mcp/services/reasoning-bank-service.js +9 -0
  370. package/dist/mcp/types.d.ts +14 -0
  371. package/dist/routing/advisor/redaction.js +22 -2
  372. package/dist/shared/llm/providers/response-deadline.js +16 -2
  373. package/dist/shared/types/index.js +3 -1
  374. package/dist/strange-loop/infra-healing/infra-aware-agent-provider.js +8 -1
  375. package/package.json +3 -3
  376. package/dist/cli/chunks/adapter-V4GSGOOK.js +0 -2
  377. package/dist/cli/chunks/aqe-learning-engine-6WQTM5YR.js +0 -2
  378. package/dist/cli/chunks/base-AK7BXBX2.js +0 -2
  379. package/dist/cli/chunks/browser-workflow-VTDFBW7T.js +0 -2
  380. package/dist/cli/chunks/chunk-2DTX7YAZ.js +0 -6
  381. package/dist/cli/chunks/chunk-72ZBJD2E.js +0 -3
  382. package/dist/cli/chunks/chunk-EBPJY4DI.js +0 -3
  383. package/dist/cli/chunks/chunk-HJ3XNTTJ.js +0 -2
  384. package/dist/cli/chunks/chunk-IO5537OM.js +0 -2
  385. package/dist/cli/chunks/chunk-IW6WDGHM.js +0 -2
  386. package/dist/cli/chunks/chunk-LRL56ZYL.js +0 -21
  387. package/dist/cli/chunks/chunk-VLD7Z2ED.js +0 -13
  388. package/dist/cli/chunks/chunk-VO3DRK4P.js +0 -3
  389. package/dist/cli/chunks/ci-6GUFAZMJ.js +0 -81
  390. package/dist/cli/chunks/client-HL2COSFM.js +0 -2
  391. package/dist/cli/chunks/core-handlers-IX7ATLM6.js +0 -2
  392. package/dist/cli/chunks/cross-domain-router-YYKLAPJO.js +0 -2
  393. package/dist/cli/chunks/dream-T6EP7B3F.js +0 -2
  394. package/dist/cli/chunks/file-discovery-JYMVTDMU.js +0 -2
  395. package/dist/cli/chunks/fleet-FVAUMKUT.js +0 -46
  396. package/dist/cli/chunks/heartbeat-scheduler-4N5MUJ7S.js +0 -2
  397. package/dist/cli/chunks/hnsw-adapter-ZPAJDSLR.js +0 -2
  398. package/dist/cli/chunks/hnsw-index-4CTH6RHB.js +0 -2
  399. package/dist/cli/chunks/hybrid-backend-AW6UTXQS.js +0 -2
  400. package/dist/cli/chunks/impact-analyzer-MZK3JMSV.js +0 -2
  401. package/dist/cli/chunks/init-wizard-FUC7KDVX.js +0 -2
  402. package/dist/cli/chunks/kernel-ZCPMCVMW.js +0 -2
  403. package/dist/cli/chunks/knowledge-graph-NUJKEDNF.js +0 -2
  404. package/dist/cli/chunks/llm-router-service-B2BFBQ76.js +0 -2
  405. package/dist/cli/chunks/load-test-ZHQ2MUGO.js +0 -2
  406. package/dist/cli/chunks/memory-backend-AAMQG6WH.js +0 -2
  407. package/dist/cli/chunks/pattern-null-store-RFNVA46O.js +0 -2
  408. package/dist/cli/chunks/project-root-7QL4KP5C.js +0 -2
  409. package/dist/cli/chunks/protocol-executor-2NW5BD4R.js +0 -2
  410. package/dist/cli/chunks/qe-reasoning-bank-G2JZOGKD.js +0 -2
  411. package/dist/cli/chunks/queen-coordinator-GRG5FT2A.js +0 -2
  412. package/dist/cli/chunks/real-embeddings-RQRVOKVM.js +0 -2
  413. package/dist/cli/chunks/router-LQB5SWAF.js +0 -2
  414. package/dist/cli/chunks/routing-feedback-OEEXA55N.js +0 -2
  415. package/dist/cli/chunks/rvf-dual-writer-BZK4M7BO.js +0 -2
  416. package/dist/cli/chunks/rvf-migration-adapter-EZZUJL2E.js +0 -2
  417. package/dist/cli/chunks/rvf-native-adapter-6COXTQZ3.js +0 -2
  418. package/dist/cli/chunks/safe-db-PE6G3L55.js +0 -2
  419. package/dist/cli/chunks/schedule-OLKQ6QYW.js +0 -2
  420. package/dist/cli/chunks/scheduler-LSGBDFAT.js +0 -2
  421. package/dist/cli/chunks/sqlite-persistence-HH4DNTYH.js +0 -2
  422. package/dist/cli/chunks/task-handlers-SS4ZDXNF.js +0 -9
  423. package/dist/cli/chunks/test-runner-process-PSSBNNGR.js +0 -2
  424. package/dist/cli/chunks/tree-sitter-wasm-parser-TYRQRJ2W.js +0 -2
  425. package/dist/cli/chunks/unified-memory-AGDZQ5XD.js +0 -2
  426. package/dist/cli/chunks/unified-memory-hnsw-X5TJ3JDE.js +0 -2
  427. package/dist/cli/chunks/unified-persistence-UCV7YETW.js +0 -2
  428. package/dist/cli/chunks/visual-security-ZLXRIQZV.js +0 -2
  429. package/dist/cli/chunks/witness-chain-CVIWYTD2.js +0 -2
  430. package/dist/cli/chunks/witness-chain-VBKORKOX.js +0 -2
  431. package/dist/cli/chunks/workflow-orchestrator-3ZN7MVCE.js +0 -2
@@ -0,0 +1,159 @@
1
+ /**
2
+ * Coverage evidence: is a report complete and current for its target? (#1154)
3
+ *
4
+ * A report judged over only the files it happens to contain says nothing
5
+ * about the target's other files. `aqe fleet run analyze --target src` printed
6
+ * "100% over 1 files" and "Verdict: PASSED" from a report that listed
7
+ * `src/math.js` while `src/unsafe.js` had no measurement at all, and a report
8
+ * written before the sources last changed was judged as if it were current.
9
+ *
10
+ * This module answers two questions for every caller of the shared resolver
11
+ * (MCP `coverage_analyze_sublinear` / `task_orchestrate`, `aqe coverage`,
12
+ * `aqe ci`, `aqe fleet run analyze`):
13
+ * 1. Which production source files under the target are not in the report?
14
+ * They are UNMEASURED: not 0%, and not left out silently.
15
+ * 2. Is the report older than source files it is judged against? (stale)
16
+ * Either one makes the evidence insufficient: no verdict may pass on it.
17
+ */
18
+ import * as fs from 'fs';
19
+ import * as path from 'path';
20
+ import { walkSourceFiles } from './coverage-collection.js';
21
+ import { inCoverageScope, readCoverageScope } from './coverage-scope.js';
22
+ /** Source files that share a coverage tool with each other (one report covers one family). */
23
+ const LANGUAGE_FAMILIES = [
24
+ ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs'],
25
+ ['.py'], ['.go'], ['.rs'], ['.java'], ['.rb'],
26
+ ];
27
+ function familyOf(file) {
28
+ const ext = path.extname(file).toLowerCase();
29
+ return LANGUAGE_FAMILIES.find(family => family.includes(ext));
30
+ }
31
+ /**
32
+ * Files no coverage tool instruments by default: type declarations and tool
33
+ * configuration (`vitest.config.ts`, `eslint.config.js`, `.prettierrc.js`).
34
+ */
35
+ function isNeverInstrumented(file) {
36
+ const base = path.basename(file);
37
+ return base.endsWith('.d.ts') || base.startsWith('.') || /\.config\.[cm]?[jt]sx?$/.test(base);
38
+ }
39
+ function canonical(p) {
40
+ try {
41
+ return fs.realpathSync(p);
42
+ }
43
+ catch {
44
+ return path.resolve(p);
45
+ }
46
+ }
47
+ /** Absolute, canonical paths of the report's entries (relative entries resolve against `projectRoot`). */
48
+ function reportPaths(files, projectRoot) {
49
+ const rootAbs = canonical(projectRoot);
50
+ return new Set(files.map(f => path.isAbsolute(f.path) ? canonical(f.path) : canonical(path.resolve(rootAbs, f.path))));
51
+ }
52
+ /**
53
+ * Production source files under a directory `target` that the report has no
54
+ * entry for. Only files in a language the report covers count: a JS report
55
+ * does not make a Python helper script unmeasured. Files the project's coverage
56
+ * config leaves out (include/exclude) were never meant to be measured and do
57
+ * not count either.
58
+ */
59
+ export function findUnmeasuredSourceFiles(reportFiles, projectRoot, target) {
60
+ let isDir = false;
61
+ try {
62
+ isDir = fs.statSync(target).isDirectory();
63
+ }
64
+ catch { /* missing: nothing to compare */ }
65
+ if (!isDir)
66
+ return { targetFiles: [], unmeasured: [] };
67
+ const rootAbs = canonical(projectRoot);
68
+ const scope = readCoverageScope(rootAbs);
69
+ const families = new Set(reportFiles.map(f => familyOf(f.path)).filter(Boolean));
70
+ const inReport = reportPaths(reportFiles, projectRoot);
71
+ const targetFiles = walkSourceFiles(target)
72
+ .filter(file => families.has(familyOf(file)) && !isNeverInstrumented(file))
73
+ .map(canonical)
74
+ .filter(file => inCoverageScope(scope, file, rootAbs));
75
+ return {
76
+ targetFiles,
77
+ unmeasured: targetFiles.filter(file => !inReport.has(file)).sort(),
78
+ ...(scope ? { coverageScope: { source: scope.source, readable: scope.readable } } : {}),
79
+ };
80
+ }
81
+ /** Source files modified after the report was written; `undefined` when the report is current. */
82
+ export function findStaleness(reportPath, sourceFiles) {
83
+ let reportMtime;
84
+ try {
85
+ reportMtime = fs.statSync(reportPath).mtimeMs;
86
+ }
87
+ catch {
88
+ return undefined;
89
+ }
90
+ const newerFiles = sourceFiles.filter(file => {
91
+ try {
92
+ return fs.statSync(file).mtimeMs > reportMtime;
93
+ }
94
+ catch {
95
+ return false;
96
+ }
97
+ }).sort();
98
+ return newerFiles.length > 0
99
+ ? { reportPath, reportModified: new Date(reportMtime).toISOString(), newerFiles }
100
+ : undefined;
101
+ }
102
+ /**
103
+ * The evidence a report gives for `target`.
104
+ *
105
+ * `measuredFiles` are the report entries already scoped to the target.
106
+ * Completeness is checked only when `checkCompleteness` is set (a directory
107
+ * target, not a report file given as the target), staleness only when the
108
+ * report's path is known (not for a report the run just wrote).
109
+ */
110
+ export function assessCoverageEvidence(report, measuredFiles, projectRoot, target, options = {}) {
111
+ const { targetFiles, unmeasured, coverageScope } = options.checkCompleteness === false
112
+ ? { targetFiles: [], unmeasured: [], coverageScope: undefined }
113
+ : findUnmeasuredSourceFiles(report.files, projectRoot, target);
114
+ const sources = new Set([...targetFiles, ...reportPaths(measuredFiles, projectRoot)]);
115
+ const stale = options.reportPath
116
+ ? findStaleness(options.reportPath, [...sources].filter(file => fs.existsSync(file)))
117
+ : undefined;
118
+ return {
119
+ status: unmeasured.length > 0 || stale ? 'insufficient-evidence' : 'complete',
120
+ unmeasuredFiles: unmeasured,
121
+ targetFiles: sources.size,
122
+ ...(stale ? { stale } : {}),
123
+ ...(coverageScope ? { coverageScope } : {}),
124
+ };
125
+ }
126
+ const MAX_LISTED = 5;
127
+ function listFiles(files, root) {
128
+ const shown = files.slice(0, MAX_LISTED).map(f => path.relative(root, f) || f);
129
+ return shown.join(', ') + (files.length > MAX_LISTED ? `, … ${files.length - MAX_LISTED} more` : '');
130
+ }
131
+ /**
132
+ * Why the evidence is insufficient, one sentence per problem; empty when it is
133
+ * complete. Shared by MCP and CLI so the wording cannot drift.
134
+ */
135
+ export function describeEvidence(evidence, projectRoot) {
136
+ if (!evidence)
137
+ return [];
138
+ const reasons = [];
139
+ const n = evidence.unmeasuredFiles.length;
140
+ if (n > 0) {
141
+ const scope = evidence.coverageScope;
142
+ const scopeNote = scope && !scope.readable
143
+ ? ` The coverage include/exclude in ${scope.source} could not be read statically, so files it leaves out ` +
144
+ 'may be listed here; write them as literal string arrays to have them honoured.'
145
+ : '';
146
+ reasons.push(`${n} of ${evidence.targetFiles} source files under the target are not in the coverage report ` +
147
+ `(UNMEASURED, not counted as covered): ${listFiles(evidence.unmeasuredFiles, projectRoot)}. Regenerate ` +
148
+ 'the report with coverage for the whole target, or exclude files that are not meant to be measured in the ' +
149
+ `coverage tool's include/exclude config.${scopeNote}`);
150
+ }
151
+ if (evidence.stale) {
152
+ const m = evidence.stale.newerFiles.length;
153
+ reasons.push(`the coverage report ${path.relative(projectRoot, evidence.stale.reportPath) || evidence.stale.reportPath} ` +
154
+ `is STALE: ${m} source file${m === 1 ? ' was' : 's were'} modified after it was written ` +
155
+ `(${evidence.stale.reportModified}): ${listFiles(evidence.stale.newerFiles, projectRoot)}`);
156
+ }
157
+ return reasons;
158
+ }
159
+ //# sourceMappingURL=coverage-evidence.js.map
@@ -9,6 +9,7 @@ import { toError } from '../../shared/error-utils.js';
9
9
  import { requirePayloadPath } from '../../shared/io/payload-path-guard.js';
10
10
  import { buildEstimatedCoverage, collectRustCoverage, findCargoRoot, isCoverageExecDisabled, isRustProject, } from './coverage-collection.js';
11
11
  import { describeNoData, evaluateCoverageForTarget, isUnmeasured, packageFilterForTarget, resolveExistingCoverage, scopeCoverageToTarget, reconcileRecommendations, thresholdVerdict, } from './coverage-target.js';
12
+ import { describeEvidence } from './coverage-evidence.js';
12
13
  import { randomUUID } from 'crypto';
13
14
  import * as path from 'path';
14
15
  import { describeRunFailure, runJsCoverage, testRunStatus } from './coverage-runner.js';
@@ -54,7 +55,7 @@ function instrumented(files) {
54
55
  }
55
56
  function fromEvaluation(evaluation, ranTests, projectRoot) {
56
57
  return evaluation.status === 'measured'
57
- ? { collected: instrumented(evaluation.files), ranTests, projectRoot }
58
+ ? { collected: instrumented(evaluation.files), ranTests, projectRoot, evidence: evaluation.evidence }
58
59
  : { collected: null, ranTests, noData: evaluation.reason, projectRoot };
59
60
  }
60
61
  /**
@@ -212,7 +213,7 @@ export function registerCoverageHandlers(ctx) {
212
213
  }
213
214
  const analyzer = ctx.getCoverageAnalyzer();
214
215
  const threshold = payload.threshold || 80;
215
- const { collected, ranTests, noData, projectRoot, notes, runStatus, testRun } = await collectCoverage(targetPath);
216
+ const { collected, ranTests, noData, projectRoot, notes, runStatus, testRun, evidence } = await collectCoverage(targetPath);
216
217
  // #995 review N5: say so plainly instead of "no coverage data found".
217
218
  if (noData === 'target-missing') {
218
219
  return err(new Error(describeNoData('target-missing', targetPath, null)));
@@ -278,9 +279,16 @@ export function registerCoverageHandlers(ctx) {
278
279
  }
279
280
  const round = (n) => Math.round(n * 10) / 10;
280
281
  const pct = (covered, total) => total > 0 ? Math.round((covered / total) * 1000) / 10 : null;
282
+ // #1154: target files missing from the report, or a report older than the
283
+ // sources, leave the evidence insufficient: the figures stand for the
284
+ // measured files only, and the threshold is not met on them.
285
+ const evidenceReasons = describeEvidence(evidence, projectRoot ?? targetPath);
281
286
  const warnings = [...provenance.notes, ...(notes ?? [])];
282
287
  if (provenance.estimated)
283
288
  warnings.push(estimationGuidance(targetPath));
289
+ if (evidenceReasons.length > 0) {
290
+ warnings.push(`INSUFFICIENT EVIDENCE — the threshold is not met on this report: ${evidenceReasons.join('; ').replace(/\.?$/, '.')}`);
291
+ }
284
292
  // #569: the analyzer generates recommendations from the summary numbers.
285
293
  // When branch or function data was never collected, those numbers are 0
286
294
  // by construction, and the resulting advice ("Branch coverage is
@@ -312,7 +320,12 @@ export function registerCoverageHandlers(ctx) {
312
320
  })),
313
321
  gaps,
314
322
  // NB5: judged only on the metrics that were collected (shared with the CLI).
315
- meetsThreshold: verdict.meetsThreshold,
323
+ meetsThreshold: verdict.meetsThreshold && evidenceReasons.length === 0,
324
+ ...(evidence ? {
325
+ evidenceStatus: evidence.status,
326
+ unmeasuredFiles: evidence.unmeasuredFiles,
327
+ ...(evidence.stale ? { staleReport: evidence.stale } : {}),
328
+ } : {}),
316
329
  delta: report.delta,
317
330
  recommendations,
318
331
  algorithm: 'sublinear-O(log n)',
@@ -0,0 +1,40 @@
1
+ /**
2
+ * The project's own coverage scope (#1154 review).
3
+ *
4
+ * A file the coverage tool is configured to leave out (vitest
5
+ * `coverage.exclude: ['src/**\/index.ts']`, jest `'!src/**\/index.ts'` in
6
+ * `collectCoverageFrom`) is not "unmeasured": it was never meant to be
7
+ * measured. Counting it would fail every verdict on a normal project.
8
+ *
9
+ * The scope is read STATICALLY from literal string arrays. Config files are
10
+ * never executed (they are code from the analyzed repository). When a config
11
+ * declares a coverage scope that is not a literal, the scope is reported as
12
+ * unreadable rather than guessed.
13
+ *
14
+ * Sources, first match wins:
15
+ * - vitest.config.* / vite.config.* `coverage: { include, exclude }`
16
+ * - jest.config.* / package.json "jest" `collectCoverageFrom` (`!` = exclude),
17
+ * `coveragePathIgnorePatterns` (regular expressions)
18
+ * - .nycrc / .nycrc.json / package.json "nyc", .c8rc / .c8rc.json /
19
+ * package.json "c8" `include`, `exclude`
20
+ */
21
+ export interface CoverageScope {
22
+ /** The config the scope was read from, relative to the project root. */
23
+ source: string;
24
+ /** False when the config declares a scope that is not a literal string array. */
25
+ readable: boolean;
26
+ include: string[];
27
+ exclude: string[];
28
+ /** jest `coveragePathIgnorePatterns`, matched against the absolute path. */
29
+ ignorePatterns: RegExp[];
30
+ }
31
+ /**
32
+ * A pattern matches a project-relative POSIX path, or any path under it when it
33
+ * names a directory (nyc/test-exclude treat `src` as `src/**`).
34
+ */
35
+ export declare function globToRegExp(pattern: string): RegExp;
36
+ /** The coverage scope configured for the project at `projectRoot`; `null` when none is configured. */
37
+ export declare function readCoverageScope(projectRoot: string): CoverageScope | null;
38
+ /** Is `file` inside the configured coverage scope? Everything is, with no scope. */
39
+ export declare function inCoverageScope(scope: CoverageScope | null, file: string, projectRoot: string): boolean;
40
+ //# sourceMappingURL=coverage-scope.d.ts.map
@@ -0,0 +1,321 @@
1
+ /**
2
+ * The project's own coverage scope (#1154 review).
3
+ *
4
+ * A file the coverage tool is configured to leave out (vitest
5
+ * `coverage.exclude: ['src/**\/index.ts']`, jest `'!src/**\/index.ts'` in
6
+ * `collectCoverageFrom`) is not "unmeasured": it was never meant to be
7
+ * measured. Counting it would fail every verdict on a normal project.
8
+ *
9
+ * The scope is read STATICALLY from literal string arrays. Config files are
10
+ * never executed (they are code from the analyzed repository). When a config
11
+ * declares a coverage scope that is not a literal, the scope is reported as
12
+ * unreadable rather than guessed.
13
+ *
14
+ * Sources, first match wins:
15
+ * - vitest.config.* / vite.config.* `coverage: { include, exclude }`
16
+ * - jest.config.* / package.json "jest" `collectCoverageFrom` (`!` = exclude),
17
+ * `coveragePathIgnorePatterns` (regular expressions)
18
+ * - .nycrc / .nycrc.json / package.json "nyc", .c8rc / .c8rc.json /
19
+ * package.json "c8" `include`, `exclude`
20
+ */
21
+ import * as fs from 'fs';
22
+ import * as path from 'path';
23
+ import { readConfinedTextSync } from '../../shared/io/confined-read.js';
24
+ const JS_EXTS = ['ts', 'mts', 'cts', 'js', 'mjs', 'cjs'];
25
+ const VITEST_CONFIGS = [...JS_EXTS.map(e => `vitest.config.${e}`), ...JS_EXTS.map(e => `vite.config.${e}`)];
26
+ const JEST_CONFIGS = [...JS_EXTS.map(e => `jest.config.${e}`), 'jest.config.json'];
27
+ const NYC_CONFIGS = ['.nycrc', '.nycrc.json'];
28
+ const C8_CONFIGS = ['.c8rc', '.c8rc.json'];
29
+ // ============================================================================
30
+ // Glob matching (no glob library is a runtime dependency)
31
+ // ============================================================================
32
+ function escapeRe(s) {
33
+ return s.replace(/[.+^$()|[\]\\]/g, '\\$&');
34
+ }
35
+ /** Glob body → regex source: `**`, `*`, `?` and non-nested `{a,b}`. */
36
+ function globSource(glob) {
37
+ let re = '';
38
+ for (let i = 0; i < glob.length; i++) {
39
+ const c = glob[i];
40
+ if (c === '*' && glob[i + 1] === '*') {
41
+ if (glob[i + 2] === '/') {
42
+ re += '(?:.*/)?';
43
+ i += 2;
44
+ }
45
+ else {
46
+ re += '.*';
47
+ i += 1;
48
+ }
49
+ }
50
+ else if (c === '*') {
51
+ re += '[^/]*';
52
+ }
53
+ else if (c === '?') {
54
+ re += '[^/]';
55
+ }
56
+ else if (c === '{') {
57
+ const end = glob.indexOf('}', i);
58
+ if (end === -1) {
59
+ re += '\\{';
60
+ continue;
61
+ }
62
+ re += `(?:${glob.slice(i + 1, end).split(',').map(globSource).join('|')})`;
63
+ i = end;
64
+ }
65
+ else {
66
+ re += escapeRe(c);
67
+ }
68
+ }
69
+ return re;
70
+ }
71
+ /**
72
+ * A pattern matches a project-relative POSIX path, or any path under it when it
73
+ * names a directory (nyc/test-exclude treat `src` as `src/**`).
74
+ */
75
+ export function globToRegExp(pattern) {
76
+ const body = pattern.replace(/^<rootDir>\//, '').replace(/^\.\//, '').replace(/\/+$/, '');
77
+ return new RegExp(`^${globSource(body)}(?:/.*)?$`);
78
+ }
79
+ // ============================================================================
80
+ // Static extraction of literal arrays from config source
81
+ // ============================================================================
82
+ /** Remove comments, leaving string literals (which may contain `/*`) intact. */
83
+ function stripComments(src) {
84
+ let out = '';
85
+ for (let i = 0; i < src.length; i++) {
86
+ const c = src[i];
87
+ if (c === '"' || c === "'" || c === '`') {
88
+ const start = i;
89
+ for (i++; i < src.length && src[i] !== c; i++)
90
+ if (src[i] === '\\')
91
+ i++;
92
+ out += src.slice(start, i + 1);
93
+ }
94
+ else if (c === '/' && src[i + 1] === '/') {
95
+ while (i < src.length && src[i] !== '\n')
96
+ i++;
97
+ out += '\n';
98
+ }
99
+ else if (c === '/' && src[i + 1] === '*') {
100
+ const end = src.indexOf('*/', i + 2);
101
+ i = end === -1 ? src.length : end + 1;
102
+ }
103
+ else {
104
+ out += c;
105
+ }
106
+ }
107
+ return out;
108
+ }
109
+ /** Index just past the bracket matching the one at `open`, skipping strings. */
110
+ function matchingClose(src, open) {
111
+ const pairs = { '[': ']', '{': '}', '(': ')' };
112
+ const stack = [];
113
+ for (let i = open; i < src.length; i++) {
114
+ const c = src[i];
115
+ if (c === '"' || c === "'" || c === '`') {
116
+ for (i++; i < src.length && src[i] !== c; i++)
117
+ if (src[i] === '\\')
118
+ i++;
119
+ }
120
+ else if (pairs[c]) {
121
+ stack.push(pairs[c]);
122
+ }
123
+ else if (c === stack[stack.length - 1]) {
124
+ stack.pop();
125
+ if (stack.length === 0)
126
+ return i + 1;
127
+ }
128
+ }
129
+ return -1;
130
+ }
131
+ /** Split a bracket body on top-level commas. */
132
+ function splitTopLevel(body) {
133
+ const parts = [];
134
+ let depth = 0;
135
+ let start = 0;
136
+ for (let i = 0; i < body.length; i++) {
137
+ const c = body[i];
138
+ if (c === '"' || c === "'" || c === '`') {
139
+ for (i++; i < body.length && body[i] !== c; i++)
140
+ if (body[i] === '\\')
141
+ i++;
142
+ }
143
+ else if ('[{('.includes(c))
144
+ depth++;
145
+ else if (']})'.includes(c))
146
+ depth--;
147
+ else if (c === ',' && depth === 0) {
148
+ parts.push(body.slice(start, i));
149
+ start = i + 1;
150
+ }
151
+ }
152
+ parts.push(body.slice(start));
153
+ return parts.map(p => p.trim()).filter(p => p.length > 0);
154
+ }
155
+ const STRING_LITERAL = /^(['"])((?:\\.|(?!\1)[^\\])*)\1$|^`([^`$\\]*)`$/;
156
+ /**
157
+ * The value of `key:` in `src` as a literal string array. `undefined` when the
158
+ * key is absent, `null` when it is present but not a literal. A spread of the
159
+ * tool's own defaults (`...coverageConfigDefaults.exclude`) is skipped: those
160
+ * are tests and config files, which are never counted anyway.
161
+ */
162
+ function literalArray(src, key) {
163
+ const m = new RegExp(`(?:^|[\\s,{])['"]?${key}['"]?\\s*:\\s*`).exec(src);
164
+ if (!m)
165
+ return undefined;
166
+ const at = m.index + m[0].length;
167
+ if (src[at] === "'" || src[at] === '"') {
168
+ const single = STRING_LITERAL.exec(src.slice(at, matchingStringEnd(src, at)));
169
+ return single ? [single[2] ?? single[3]] : null;
170
+ }
171
+ if (src[at] !== '[')
172
+ return null;
173
+ const end = matchingClose(src, at);
174
+ if (end === -1)
175
+ return null;
176
+ const values = [];
177
+ for (const el of splitTopLevel(src.slice(at + 1, end - 1))) {
178
+ if (/^\.\.\.[\w$.]*defaults?\b/i.test(el))
179
+ continue;
180
+ const lit = STRING_LITERAL.exec(el);
181
+ if (!lit)
182
+ return null;
183
+ values.push(lit[2] ?? lit[3]);
184
+ }
185
+ return values;
186
+ }
187
+ function matchingStringEnd(src, at) {
188
+ let i = at + 1;
189
+ for (; i < src.length && src[i] !== src[at]; i++)
190
+ if (src[i] === '\\')
191
+ i++;
192
+ return i + 1;
193
+ }
194
+ // ============================================================================
195
+ // Readers
196
+ // ============================================================================
197
+ function readText(file) {
198
+ try {
199
+ return readConfinedTextSync(file, { outsideRoot: 'allow' });
200
+ }
201
+ catch {
202
+ return null;
203
+ }
204
+ }
205
+ function readJson(file) {
206
+ const text = readText(file);
207
+ if (text === null)
208
+ return null;
209
+ try {
210
+ const parsed = JSON.parse(text);
211
+ return typeof parsed === 'object' && parsed !== null ? parsed : null;
212
+ }
213
+ catch {
214
+ return null;
215
+ }
216
+ }
217
+ const strings = (v) => v === undefined ? undefined
218
+ : typeof v === 'string' ? [v]
219
+ : Array.isArray(v) && v.every(e => typeof e === 'string') ? v : null;
220
+ function scope(source, parts) {
221
+ const readable = [parts.include, parts.exclude, parts.collectFrom, parts.ignore].every(p => p !== null);
222
+ const collect = parts.collectFrom ?? [];
223
+ const ignorePatterns = [];
224
+ for (const p of parts.ignore ?? []) {
225
+ try {
226
+ ignorePatterns.push(new RegExp(p));
227
+ }
228
+ catch { /* jest would reject it too */ }
229
+ }
230
+ return {
231
+ source, readable, ignorePatterns,
232
+ include: [...(parts.include ?? []), ...collect.filter(g => !g.startsWith('!'))],
233
+ exclude: [...(parts.exclude ?? []), ...collect.filter(g => g.startsWith('!')).map(g => g.slice(1))],
234
+ };
235
+ }
236
+ function fromVitest(name, text) {
237
+ const src = stripComments(text);
238
+ const m = /(?:^|[\s,{])['"]?coverage['"]?\s*(?::\s*|(?=[,}]))/.exec(src);
239
+ if (!m)
240
+ return null;
241
+ const at = m.index + m[0].length;
242
+ // `coverage,` shorthand or `coverage: options`: declared, not readable.
243
+ if (!m[0].includes(':') || src[at] !== '{')
244
+ return scope(name, { include: null });
245
+ const end = matchingClose(src, at);
246
+ const block = end === -1 ? '' : src.slice(at, end);
247
+ return scope(name, { include: literalArray(block, 'include'), exclude: literalArray(block, 'exclude') });
248
+ }
249
+ function fromJestText(name, text) {
250
+ const src = stripComments(text);
251
+ const collectFrom = literalArray(src, 'collectCoverageFrom');
252
+ const ignore = literalArray(src, 'coveragePathIgnorePatterns');
253
+ if (collectFrom === undefined && ignore === undefined)
254
+ return null;
255
+ return scope(name, { collectFrom, ignore });
256
+ }
257
+ function fromJsonKeys(name, obj) {
258
+ if (!obj || typeof obj !== 'object')
259
+ return null;
260
+ if ('collectCoverageFrom' in obj || 'coveragePathIgnorePatterns' in obj) {
261
+ return scope(name, { collectFrom: strings(obj.collectCoverageFrom), ignore: strings(obj.coveragePathIgnorePatterns) });
262
+ }
263
+ if ('include' in obj || 'exclude' in obj) {
264
+ return scope(name, { include: strings(obj.include), exclude: strings(obj.exclude) });
265
+ }
266
+ return null;
267
+ }
268
+ /** The coverage scope configured for the project at `projectRoot`; `null` when none is configured. */
269
+ export function readCoverageScope(projectRoot) {
270
+ for (const name of VITEST_CONFIGS) {
271
+ const text = readText(path.join(projectRoot, name));
272
+ if (text !== null) {
273
+ const found = fromVitest(name, text);
274
+ if (found)
275
+ return found;
276
+ }
277
+ }
278
+ for (const name of JEST_CONFIGS) {
279
+ const file = path.join(projectRoot, name);
280
+ if (!fs.existsSync(file))
281
+ continue;
282
+ const found = name.endsWith('.json')
283
+ ? fromJsonKeys(name, readJson(file) ?? undefined)
284
+ : fromJestText(name, readText(file) ?? '');
285
+ if (found)
286
+ return found;
287
+ }
288
+ const pkg = readJson(path.join(projectRoot, 'package.json'));
289
+ const fromPkg = fromJsonKeys('package.json "jest"', pkg?.jest);
290
+ if (fromPkg)
291
+ return fromPkg;
292
+ for (const [names, key] of [[NYC_CONFIGS, 'nyc'], [C8_CONFIGS, 'c8']]) {
293
+ for (const name of names) {
294
+ const obj = readJson(path.join(projectRoot, name));
295
+ const found = fromJsonKeys(name, obj ?? undefined);
296
+ if (found)
297
+ return found;
298
+ // A config that exists but is not JSON (e.g. YAML) cannot be read.
299
+ if (!obj && fs.existsSync(path.join(projectRoot, name)))
300
+ return scope(name, { include: null });
301
+ }
302
+ const found = fromJsonKeys(`package.json "${key}"`, pkg?.[key]);
303
+ if (found)
304
+ return found;
305
+ }
306
+ return null;
307
+ }
308
+ /** Is `file` inside the configured coverage scope? Everything is, with no scope. */
309
+ export function inCoverageScope(scope, file, projectRoot) {
310
+ if (!scope)
311
+ return true;
312
+ const rel = path.relative(projectRoot, file).split(path.sep).join('/');
313
+ if (scope.include.length > 0 && !scope.include.some(g => globToRegExp(g).test(rel)))
314
+ return false;
315
+ if (scope.exclude.some(g => globToRegExp(g).test(rel)))
316
+ return false;
317
+ const posixAbs = file.split(path.sep).join('/');
318
+ const rootPosix = projectRoot.split(path.sep).join('/');
319
+ return !scope.ignorePatterns.some(re => re.test(posixAbs) || re.test(posixAbs.replace(rootPosix, '<rootDir>')));
320
+ }
321
+ //# sourceMappingURL=coverage-scope.js.map
@@ -19,6 +19,7 @@
19
19
  * and the CLI `coverage` command can share it.
20
20
  */
21
21
  import type { CoverageData, FileCoverage } from '../../domains/coverage-analysis/interfaces';
22
+ import { type CoverageEvidence } from './coverage-evidence';
22
23
  /**
23
24
  * Walk up from a target to the nearest directory that holds a project marker.
24
25
  *
@@ -75,6 +76,7 @@ export type NoDataReason =
75
76
  export type CoverageEvaluation = {
76
77
  status: 'measured';
77
78
  files: FileCoverage[];
79
+ evidence: CoverageEvidence;
78
80
  } | {
79
81
  status: 'no-data';
80
82
  reason: NoDataReason;
@@ -88,9 +90,16 @@ export type CoverageEvaluation = {
88
90
  * - the report has no entry under the target.
89
91
  * Hit counts are never used: a file listed with 0 hits is a measured 0%,
90
92
  * whether the report came from our run or from the user (#995 review B3).
93
+ *
94
+ * A measured result carries its evidence (#1154): the target's source files
95
+ * the report has no entry for (UNMEASURED), and whether the report at
96
+ * `reportPath` is older than the sources. Insufficient evidence keeps the
97
+ * figures for the measured files, but no caller may pass a verdict on it.
91
98
  */
92
99
  export declare function evaluateCoverageForTarget(report: CoverageData, projectRoot: string, target: string, options?: {
93
100
  numTotalTests?: number | null;
101
+ reportPath?: string;
102
+ checkCompleteness?: boolean;
94
103
  }): CoverageEvaluation;
95
104
  export type ExistingCoverage = {
96
105
  status: 'target-missing';
@@ -22,8 +22,9 @@ import * as fs from 'fs';
22
22
  import { readConfinedText, readConfinedTextSync } from '../../shared/io/confined-read.js';
23
23
  import * as os from 'os';
24
24
  import * as path from 'path';
25
- import { loadCoverageData, parseCoberturaXml, parseCoverageJson, parseCoverageSummaryJson, parseLcovInfo, } from './handler-utils.js';
25
+ import { loadCoverageReport, parseCoberturaXml, parseCoverageJson, parseCoverageSummaryJson, parseLcovInfo, } from './handler-utils.js';
26
26
  import { isTestPath } from './coverage-collection.js';
27
+ import { assessCoverageEvidence } from './coverage-evidence.js';
27
28
  import { findProjectRoot } from '../../kernel/project-root.js';
28
29
  // ============================================================================
29
30
  // Project root
@@ -418,6 +419,11 @@ export function scopeCoverageToTarget(data, root, target) {
418
419
  * - the report has no entry under the target.
419
420
  * Hit counts are never used: a file listed with 0 hits is a measured 0%,
420
421
  * whether the report came from our run or from the user (#995 review B3).
422
+ *
423
+ * A measured result carries its evidence (#1154): the target's source files
424
+ * the report has no entry for (UNMEASURED), and whether the report at
425
+ * `reportPath` is older than the sources. Insufficient evidence keeps the
426
+ * figures for the measured files, but no caller may pass a verdict on it.
421
427
  */
422
428
  export function evaluateCoverageForTarget(report, projectRoot, target, options = {}) {
423
429
  if (options.numTotalTests === 0)
@@ -430,7 +436,10 @@ export function evaluateCoverageForTarget(report, projectRoot, target, options =
430
436
  const production = scoped.filter(f => !isTestPath(f.path, projectRoot));
431
437
  if (production.length === 0)
432
438
  return { status: 'no-data', reason: 'test-only-report' };
433
- return { status: 'measured', files: production };
439
+ const evidence = assessCoverageEvidence(report, production, projectRoot, target, {
440
+ reportPath: options.reportPath, checkCompleteness: options.checkCompleteness,
441
+ });
442
+ return { status: 'measured', files: production, evidence };
434
443
  }
435
444
  /**
436
445
  * Resolve a target to coverage that already exists on disk, without running
@@ -454,18 +463,19 @@ export async function resolveExistingCoverage(targetPath) {
454
463
  const projectRoot = findCoverageProjectRoot(reportDir)
455
464
  ?? (path.basename(reportDir) === 'coverage' ? path.dirname(reportDir) : reportDir);
456
465
  const report = await loadCoverageReportFile(target);
466
+ // The report itself is the target: judged whole, but still checked for staleness.
457
467
  const evaluation = report
458
- ? evaluateCoverageForTarget(report, projectRoot, projectRoot)
468
+ ? evaluateCoverageForTarget(report, projectRoot, projectRoot, { reportPath: target, checkCompleteness: false })
459
469
  : { status: 'no-data', reason: 'unreadable-report' };
460
470
  return { status: 'evaluated', target, projectRoot, source: 'report-file', evaluation };
461
471
  }
462
472
  const projectRoot = findCoverageProjectRoot(target) ?? (stat.isDirectory() ? target : path.dirname(target));
463
- const existing = await loadCoverageData(projectRoot);
473
+ const existing = await loadCoverageReport(projectRoot);
464
474
  if (!existing)
465
475
  return { status: 'no-report', target, projectRoot };
466
476
  return {
467
477
  status: 'evaluated', target, projectRoot, source: 'project-report',
468
- evaluation: evaluateCoverageForTarget(existing, projectRoot, target),
478
+ evaluation: evaluateCoverageForTarget(existing.data, projectRoot, target, { reportPath: existing.path }),
469
479
  };
470
480
  }
471
481
  /**