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
@@ -8,7 +8,52 @@ import chalk from 'chalk';
8
8
  import { runCoverageAnalysisWizard } from '../wizards/coverage-wizard.js';
9
9
  import { walkSourceFiles } from '../utils/file-discovery.js';
10
10
  import { writeOutput, toJSON, coverageToMarkdown } from '../utils/ci-output.js';
11
- import { buildCoverageData } from '../utils/coverage-data.js';
11
+ import * as path from 'path';
12
+ import { buildCoverageData, summarizeCoverage } from '../utils/coverage-data.js';
13
+ import { describeNoData, isUnmeasured, resolveExistingCoverage, reconcileRecommendations, thresholdVerdict, } from '../../coordination/handlers/coverage-target.js';
14
+ /** Which optional metrics an instrumented report actually carries. */
15
+ function metricsCollected(data) {
16
+ if (!data.instrumented)
17
+ return { branch: true, function: true }; // labelled heuristic estimate
18
+ return {
19
+ branch: data.files.some(f => f.branches.total > 0),
20
+ function: data.files.some(f => f.functions.total > 0),
21
+ };
22
+ }
23
+ /** `aqe coverage` exit code when the target has no coverage measurement (#995). */
24
+ export const EXIT_UNMEASURED = 3;
25
+ /**
26
+ * Resolve the coverage data for a CLI target (#995).
27
+ *
28
+ * Uses the SAME resolution and verdict as the MCP `coverage_analyze_sublinear`
29
+ * handler (`resolveExistingCoverage`), so CLI and MCP cannot disagree about
30
+ * what a report says for a target:
31
+ * - a coverage report file (lcov.info, coverage-final.json, ...) is parsed
32
+ * directly;
33
+ * - a directory or source file is scoped against the instrumented report of
34
+ * its PROJECT ROOT (nearest package.json/.git above it), not the cwd;
35
+ * - with no report at the project root, the CLI falls back to its labelled
36
+ * heuristic estimate (the CLI never runs the test suite).
37
+ */
38
+ export async function resolveCliCoverageData(targetPath) {
39
+ const existing = await resolveExistingCoverage(targetPath);
40
+ if (existing.status === 'target-missing') {
41
+ return { kind: 'no-data', reason: 'target-missing', message: describeNoData('target-missing', targetPath, null) };
42
+ }
43
+ if (existing.status === 'evaluated') {
44
+ const { evaluation, projectRoot } = existing;
45
+ if (evaluation.status === 'measured') {
46
+ const files = evaluation.files;
47
+ return { kind: 'data', data: { files, summary: summarizeCoverage(files), instrumented: true } };
48
+ }
49
+ return { kind: 'no-data', reason: evaluation.reason, message: describeNoData(evaluation.reason, targetPath, projectRoot) };
50
+ }
51
+ const sourceFiles = walkSourceFiles(existing.target, { includeTests: false });
52
+ if (sourceFiles.length === 0)
53
+ return { kind: 'no-sources' };
54
+ console.log(chalk.gray(` Analyzing ${sourceFiles.length} files...\n`));
55
+ return { kind: 'data', data: buildCoverageData(sourceFiles, existing.projectRoot) };
56
+ }
12
57
  function getColorForPercent(percent) {
13
58
  if (percent >= 80)
14
59
  return chalk.green;
@@ -28,6 +73,21 @@ export function createCoverageCommand(context, cleanupAndExit, ensureInitialized
28
73
  .option('--ghost', 'Include ghost intent coverage analysis (detect untested behavioral intents)')
29
74
  .option('-F, --format <format>', 'Output format (text|json|markdown)', 'text')
30
75
  .option('-o, --output <path>', 'Write output to file')
76
+ .addHelpText('after', `
77
+ Target: a directory, a source file, or an existing coverage report
78
+ (lcov.info, coverage-final.json, coverage-summary.json, Cobertura XML).
79
+ Reports are read from the target's project root (nearest package.json / .git).
80
+
81
+ Threshold: judged on the metrics the report actually collected. A metric with
82
+ no data (e.g. a report without branch data) is shown as n/a and is excluded
83
+ from the threshold, not counted as 0%.
84
+
85
+ Exit codes:
86
+ 0 coverage meets the threshold (by more than 5%)
87
+ 1 coverage below the threshold, or an error (missing target, unreadable report)
88
+ 2 coverage within 5% above the threshold
89
+ ${EXIT_UNMEASURED} UNMEASURED: no coverage measurement exists for the target
90
+ (not in the report, the runner ran 0 tests, or only test files were reported)`)
31
91
  .action(async (target, options) => {
32
92
  let analyzeTarget = target;
33
93
  let includeRisk = options.risk;
@@ -57,169 +117,224 @@ export function createCoverageCommand(context, cleanupAndExit, ensureInitialized
57
117
  await cleanupAndExit(1);
58
118
  }
59
119
  }
60
- if (!await ensureInitialized())
61
- return;
120
+ // #995 review NB3: with a machine-readable format, stdout carries ONLY the
121
+ // document. Progress lines (ours, and anything printed while the fleet
122
+ // initializes) go to stderr; the real console.log is restored to emit.
123
+ const machineFormat = options.format !== 'text';
124
+ const stdoutLog = console.log;
125
+ if (machineFormat)
126
+ console.log = (...args) => console.error(...args);
127
+ const emit = (content) => {
128
+ console.log = stdoutLog;
129
+ writeOutput(content, options.output);
130
+ };
62
131
  try {
63
- console.log(chalk.blue(`\n Analyzing coverage for ${analyzeTarget}...\n`));
64
- const coverageAPI = await context.kernel.getDomainAPIAsync('coverage-analysis');
65
- if (!coverageAPI) {
66
- console.log(chalk.red('Coverage analysis domain not available'));
132
+ if (!await ensureInitialized())
67
133
  return;
68
- }
69
- const path = await import('path');
70
- const targetPath = path.resolve(analyzeTarget);
71
- // Fix #280: Use shared file discovery supporting all languages
72
- const sourceFiles = walkSourceFiles(targetPath, { includeTests: false });
73
- if (sourceFiles.length === 0) {
74
- console.log(chalk.yellow('No source files found'));
75
- return;
76
- }
77
- console.log(chalk.gray(` Analyzing ${sourceFiles.length} files...\n`));
78
- // Build coverage data from real V8/istanbul output or deterministic estimation
79
- const coverageData = buildCoverageData(sourceFiles);
80
- if (coverageData.instrumented) {
81
- console.log(chalk.green(' Using instrumented coverage data (V8/istanbul)\n'));
82
- }
83
- else {
84
- console.log(chalk.yellow(' No instrumented coverage found — using heuristic estimation'));
85
- console.log(chalk.gray(' Run tests with coverage first: npm test -- --coverage\n'));
86
- }
87
- const result = await coverageAPI.analyze({
88
- coverageData,
89
- threshold,
90
- includeFileDetails: true,
91
- });
92
- const format = options.format;
93
- let coverageResult;
94
- if (result.success && result.value) {
95
- const report = result.value;
96
- // For non-text formats, collect all data and output at end
97
- coverageResult = {
98
- summary: report.summary,
99
- meetsThreshold: report.meetsThreshold,
100
- threshold,
101
- recommendations: report.recommendations,
102
- };
103
- if (format === 'text') {
104
- const fmt = (v) => typeof v === 'number' ? v.toFixed(1) : v;
105
- console.log(chalk.cyan(' Coverage Summary:'));
106
- console.log(` Lines: ${getColorForPercent(report.summary.line)(fmt(report.summary.line) + '%')}`);
107
- console.log(` Branches: ${getColorForPercent(report.summary.branch)(fmt(report.summary.branch) + '%')}`);
108
- console.log(` Functions: ${getColorForPercent(report.summary.function)(fmt(report.summary.function) + '%')}`);
109
- console.log(` Statements: ${getColorForPercent(report.summary.statement)(fmt(report.summary.statement) + '%')}`);
110
- console.log(`\n Threshold: ${report.meetsThreshold ? chalk.green(`Met (${threshold}%)`) : chalk.red(`Not met (${threshold}%)`)}`);
111
- if (report.recommendations.length > 0) {
112
- console.log(chalk.cyan('\n Recommendations:'));
113
- for (const rec of report.recommendations) {
114
- console.log(chalk.gray(` - ${rec}`));
115
- }
134
+ try {
135
+ console.log(chalk.blue(`\n Analyzing coverage for ${analyzeTarget}...\n`));
136
+ const coverageAPI = await context.kernel.getDomainAPIAsync('coverage-analysis');
137
+ if (!coverageAPI) {
138
+ console.log(chalk.red('Coverage analysis domain not available'));
139
+ return;
140
+ }
141
+ const targetPath = path.resolve(analyzeTarget);
142
+ // Fix #280: shared file discovery supporting all languages.
143
+ // #995: coverage files as targets; reports resolved from the project root.
144
+ const resolved = await resolveCliCoverageData(targetPath);
145
+ if (resolved.kind === 'no-sources') {
146
+ console.log(chalk.yellow('No source files found'));
147
+ return;
148
+ }
149
+ if (resolved.kind === 'no-data') {
150
+ // Errors (missing target, unreadable report) exit 1. Everything else
151
+ // means "no measurement exists" — distinct exit code, never "0%".
152
+ const isError = resolved.reason === 'target-missing' || resolved.reason === 'unreadable-report';
153
+ if (options.format === 'json') {
154
+ // Same shape as a normal result, with nulls (#995 review N4).
155
+ emit(toJSON({
156
+ summary: { line: null, branch: null, function: null, statement: null },
157
+ meetsThreshold: null,
158
+ threshold,
159
+ measured: false,
160
+ unmeasured: isUnmeasured(resolved.reason),
161
+ reason: resolved.reason,
162
+ target: targetPath,
163
+ warning: resolved.message,
164
+ }));
165
+ }
166
+ else {
167
+ console.log((isError ? chalk.red : chalk.yellow)(` ${resolved.message}\n`));
116
168
  }
169
+ await cleanupAndExit(isError ? 1 : EXIT_UNMEASURED);
170
+ return;
117
171
  }
118
- }
119
- // Detect gaps if requested
120
- if (detectGaps) {
121
- console.log(chalk.cyan('\n Coverage Gaps:'));
122
- const gapResult = await coverageAPI.detectGaps({
172
+ const coverageData = resolved.data;
173
+ if (coverageData.instrumented) {
174
+ console.log(chalk.green(' Using instrumented coverage data (V8/istanbul)\n'));
175
+ if (coverageData.unmeasuredFiles?.length) {
176
+ console.log(chalk.yellow(` ${coverageData.unmeasuredFiles.length} file(s) not in the coverage report — UNMEASURED, excluded from the figures\n`));
177
+ }
178
+ }
179
+ else {
180
+ console.log(chalk.yellow(' No instrumented coverage found — using heuristic estimation'));
181
+ console.log(chalk.gray(' Run tests with coverage first: npm test -- --coverage\n'));
182
+ }
183
+ // #1008: a heuristic estimate is shown, never persisted as coverage evidence.
184
+ const result = await coverageAPI.analyze({
123
185
  coverageData,
124
- minCoverage: threshold,
125
- prioritize: includeRisk ? 'risk' : 'size',
186
+ threshold,
187
+ includeFileDetails: true,
188
+ measured: coverageData.instrumented,
126
189
  });
127
- if (gapResult.success && gapResult.value) {
128
- const gaps = gapResult.value;
129
- if (coverageResult)
130
- coverageResult.gaps = gaps.gaps.map(g => ({
131
- file: g.file.replace(process.cwd() + '/', ''),
132
- lines: g.lines,
133
- riskScore: g.riskScore,
134
- severity: g.severity,
135
- }));
136
- console.log(chalk.gray(` Total uncovered lines: ${gaps.totalUncoveredLines}`));
137
- console.log(chalk.gray(` Estimated effort: ${gaps.estimatedEffort} hours\n`));
138
- for (const gap of gaps.gaps.slice(0, 8)) {
139
- const severityColor = gap.severity === 'high' ? chalk.red : gap.severity === 'medium' ? chalk.yellow : chalk.gray;
140
- const filePath = gap.file.replace(process.cwd() + '/', '');
141
- console.log(` ${severityColor(`[${gap.severity}]`)} ${chalk.white(filePath)}`);
142
- console.log(chalk.gray(` ${gap.lines.length} uncovered lines, Risk: ${(gap.riskScore * 100).toFixed(0)}%`));
190
+ const format = options.format;
191
+ let coverageResult;
192
+ let overallCoverage = 0;
193
+ if (result.success && result.value) {
194
+ const report = result.value;
195
+ // #995 review NB5: a metric the report never collected is null — not
196
+ // 0 — and is left out of the threshold verdict (same rule as MCP).
197
+ const collected = metricsCollected(coverageData);
198
+ const verdict = thresholdVerdict(report.summary, threshold, collected);
199
+ const summary = {
200
+ ...report.summary,
201
+ branch: collected.branch ? report.summary.branch : null,
202
+ function: collected.function ? report.summary.function : null,
203
+ };
204
+ // NB-A: the shortfall advice comes from the same verdict (shared with MCP).
205
+ const recommendations = reconcileRecommendations(report.recommendations, verdict, threshold, collected);
206
+ overallCoverage = verdict.overall;
207
+ // For non-text formats, collect all data and output at end
208
+ coverageResult = {
209
+ summary: summary,
210
+ meetsThreshold: verdict.meetsThreshold,
211
+ threshold,
212
+ recommendations,
213
+ };
214
+ if (format === 'text') {
215
+ const fmt = (v) => v === null ? 'n/a (not collected)' : v.toFixed(1) + '%';
216
+ const color = (v) => v === null ? chalk.gray : getColorForPercent(v);
217
+ console.log(chalk.cyan(' Coverage Summary:'));
218
+ console.log(` Lines: ${color(summary.line)(fmt(summary.line))}`);
219
+ console.log(` Branches: ${color(summary.branch)(fmt(summary.branch))}`);
220
+ console.log(` Functions: ${color(summary.function)(fmt(summary.function))}`);
221
+ console.log(` Statements: ${color(summary.statement)(fmt(summary.statement))}`);
222
+ console.log(`\n Threshold: ${verdict.meetsThreshold ? chalk.green(`Met (${threshold}%)`) : chalk.red(`Not met (${threshold}%)`)}`);
223
+ if (recommendations.length > 0) {
224
+ console.log(chalk.cyan('\n Recommendations:'));
225
+ for (const rec of recommendations) {
226
+ console.log(chalk.gray(` - ${rec}`));
227
+ }
228
+ }
143
229
  }
144
- if (gaps.gaps.length > 8) {
145
- console.log(chalk.gray(` ... and ${gaps.gaps.length - 8} more gaps`));
230
+ }
231
+ // Detect gaps if requested
232
+ if (detectGaps) {
233
+ console.log(chalk.cyan('\n Coverage Gaps:'));
234
+ const gapResult = await coverageAPI.detectGaps({
235
+ coverageData,
236
+ minCoverage: threshold,
237
+ prioritize: includeRisk ? 'risk' : 'size',
238
+ });
239
+ if (gapResult.success && gapResult.value) {
240
+ const gaps = gapResult.value;
241
+ if (coverageResult)
242
+ coverageResult.gaps = gaps.gaps.map(g => ({
243
+ file: g.file.replace(process.cwd() + '/', ''),
244
+ lines: g.lines,
245
+ riskScore: g.riskScore,
246
+ severity: g.severity,
247
+ }));
248
+ console.log(chalk.gray(` Total uncovered lines: ${gaps.totalUncoveredLines}`));
249
+ console.log(chalk.gray(` Estimated effort: ${gaps.estimatedEffort} hours\n`));
250
+ for (const gap of gaps.gaps.slice(0, 8)) {
251
+ const severityColor = gap.severity === 'high' ? chalk.red : gap.severity === 'medium' ? chalk.yellow : chalk.gray;
252
+ const filePath = gap.file.replace(process.cwd() + '/', '');
253
+ console.log(` ${severityColor(`[${gap.severity}]`)} ${chalk.white(filePath)}`);
254
+ console.log(chalk.gray(` ${gap.lines.length} uncovered lines, Risk: ${(gap.riskScore * 100).toFixed(0)}%`));
255
+ }
256
+ if (gaps.gaps.length > 8) {
257
+ console.log(chalk.gray(` ... and ${gaps.gaps.length - 8} more gaps`));
258
+ }
146
259
  }
147
260
  }
148
- }
149
- // Ghost intent coverage analysis (ADR-059)
150
- if (options.ghost || detectGaps) {
151
- console.log(chalk.cyan('\n Ghost Intent Coverage (ADR-059):'));
152
- try {
153
- const testPaths = coverageData.files.map(f => f.path);
154
- const ghostResult = await coverageAPI.analyzeGhostCoverage(testPaths, analyzeTarget);
155
- if (ghostResult.success && ghostResult.value) {
156
- const ghost = ghostResult.value;
157
- console.log(chalk.gray(` Phantom gaps detected: ${ghost.gaps.length}`));
158
- console.log(chalk.gray(` Ghost score: ${(ghost.totalGhostScore * 100).toFixed(1)}%`));
159
- console.log(chalk.gray(` Coverage completeness: ${(ghost.coverageCompleteness * 100).toFixed(1)}%\n`));
160
- for (const gap of ghost.gaps.slice(0, 8)) {
161
- const severityColor = gap.severity === 'critical' ? chalk.red : gap.severity === 'high' ? chalk.red : gap.severity === 'medium' ? chalk.yellow : chalk.gray;
162
- console.log(` ${severityColor(`[${gap.severity}]`)} ${chalk.white(gap.category)}`);
163
- console.log(chalk.gray(` ${gap.description}`));
261
+ // Ghost intent coverage analysis (ADR-059)
262
+ if (options.ghost || detectGaps) {
263
+ console.log(chalk.cyan('\n Ghost Intent Coverage (ADR-059):'));
264
+ try {
265
+ const testPaths = coverageData.files.map(f => f.path);
266
+ const ghostResult = await coverageAPI.analyzeGhostCoverage(testPaths, analyzeTarget);
267
+ if (ghostResult.success && ghostResult.value) {
268
+ const ghost = ghostResult.value;
269
+ console.log(chalk.gray(` Phantom gaps detected: ${ghost.gaps.length}`));
270
+ console.log(chalk.gray(` Ghost score: ${(ghost.totalGhostScore * 100).toFixed(1)}%`));
271
+ console.log(chalk.gray(` Coverage completeness: ${(ghost.coverageCompleteness * 100).toFixed(1)}%\n`));
272
+ for (const gap of ghost.gaps.slice(0, 8)) {
273
+ const severityColor = gap.severity === 'critical' ? chalk.red : gap.severity === 'high' ? chalk.red : gap.severity === 'medium' ? chalk.yellow : chalk.gray;
274
+ console.log(` ${severityColor(`[${gap.severity}]`)} ${chalk.white(gap.category)}`);
275
+ console.log(chalk.gray(` ${gap.description}`));
276
+ }
277
+ if (ghost.gaps.length > 8) {
278
+ console.log(chalk.gray(` ... and ${ghost.gaps.length - 8} more phantom gaps`));
279
+ }
164
280
  }
165
- if (ghost.gaps.length > 8) {
166
- console.log(chalk.gray(` ... and ${ghost.gaps.length - 8} more phantom gaps`));
281
+ else {
282
+ console.log(chalk.dim(' Ghost analysis not available (requires HNSW index)'));
167
283
  }
168
284
  }
169
- else {
170
- console.log(chalk.dim(' Ghost analysis not available (requires HNSW index)'));
285
+ catch {
286
+ console.log(chalk.dim(' Ghost analysis skipped (analyzer not initialized)'));
171
287
  }
172
288
  }
173
- catch {
174
- console.log(chalk.dim(' Ghost analysis skipped (analyzer not initialized)'));
289
+ // Calculate risk if requested
290
+ if (includeRisk) {
291
+ console.log(chalk.cyan('\n Risk Analysis:'));
292
+ const lowCoverageFiles = [...coverageData.files]
293
+ .sort((a, b) => (a.lines.covered / a.lines.total) - (b.lines.covered / b.lines.total))
294
+ .slice(0, 5);
295
+ for (const file of lowCoverageFiles) {
296
+ const riskResult = await coverageAPI.calculateRisk({
297
+ file: file.path,
298
+ uncoveredLines: file.uncoveredLines,
299
+ });
300
+ if (riskResult.success && riskResult.value) {
301
+ const risk = riskResult.value;
302
+ const riskColor = risk.riskLevel === 'high' ? chalk.red : risk.riskLevel === 'medium' ? chalk.yellow : chalk.green;
303
+ const filePath = file.path.replace(process.cwd() + '/', '');
304
+ console.log(` ${riskColor(`[${risk.riskLevel}]`)} ${chalk.white(filePath)}`);
305
+ console.log(chalk.gray(` Risk: ${(risk.overallRisk * 100).toFixed(0)}%, Coverage: ${Math.round((file.lines.covered / file.lines.total) * 100)}%`));
306
+ }
307
+ }
175
308
  }
176
- }
177
- // Calculate risk if requested
178
- if (includeRisk) {
179
- console.log(chalk.cyan('\n Risk Analysis:'));
180
- const lowCoverageFiles = [...coverageData.files]
181
- .sort((a, b) => (a.lines.covered / a.lines.total) - (b.lines.covered / b.lines.total))
182
- .slice(0, 5);
183
- for (const file of lowCoverageFiles) {
184
- const riskResult = await coverageAPI.calculateRisk({
185
- file: file.path,
186
- uncoveredLines: file.uncoveredLines,
187
- });
188
- if (riskResult.success && riskResult.value) {
189
- const risk = riskResult.value;
190
- const riskColor = risk.riskLevel === 'high' ? chalk.red : risk.riskLevel === 'medium' ? chalk.yellow : chalk.green;
191
- const filePath = file.path.replace(process.cwd() + '/', '');
192
- console.log(` ${riskColor(`[${risk.riskLevel}]`)} ${chalk.white(filePath)}`);
193
- console.log(chalk.gray(` Risk: ${(risk.overallRisk * 100).toFixed(0)}%, Coverage: ${Math.round((file.lines.covered / file.lines.total) * 100)}%`));
309
+ // Non-text format output (collected all data)
310
+ if (coverageResult && format === 'json') {
311
+ emit(toJSON(coverageResult));
312
+ }
313
+ else if (coverageResult && format === 'markdown') {
314
+ emit(coverageToMarkdown(coverageResult));
315
+ }
316
+ else if (format === 'text') {
317
+ console.log(chalk.green('\n Coverage analysis complete\n'));
318
+ }
319
+ // Exit codes: 1 = below threshold, 2 = within 5% of threshold, 0 = above threshold
320
+ if (coverageResult && !coverageResult.meetsThreshold) {
321
+ await cleanupAndExit(1);
322
+ }
323
+ if (coverageResult) {
324
+ const avg = overallCoverage;
325
+ if (avg < threshold + 5 && avg >= threshold) {
326
+ await cleanupAndExit(2);
194
327
  }
195
328
  }
329
+ await cleanupAndExit(0);
196
330
  }
197
- // Non-text format output (collected all data)
198
- if (coverageResult && format === 'json') {
199
- writeOutput(toJSON(coverageResult), options.output);
200
- }
201
- else if (coverageResult && format === 'markdown') {
202
- writeOutput(coverageToMarkdown(coverageResult), options.output);
203
- }
204
- else if (format === 'text') {
205
- console.log(chalk.green('\n Coverage analysis complete\n'));
206
- }
207
- // Exit codes: 1 = below threshold, 2 = within 5% of threshold, 0 = above threshold
208
- if (coverageResult && !coverageResult.meetsThreshold) {
331
+ catch (error) {
332
+ console.error(chalk.red('\nFailed:'), error);
209
333
  await cleanupAndExit(1);
210
334
  }
211
- if (coverageResult) {
212
- const avg = (coverageResult.summary.line + coverageResult.summary.branch +
213
- coverageResult.summary.function + coverageResult.summary.statement) / 4;
214
- if (avg < threshold + 5 && avg >= threshold) {
215
- await cleanupAndExit(2);
216
- }
217
- }
218
- await cleanupAndExit(0);
219
335
  }
220
- catch (error) {
221
- console.error(chalk.red('\nFailed:'), error);
222
- await cleanupAndExit(1);
336
+ finally {
337
+ console.log = stdoutLog;
223
338
  }
224
339
  });
225
340
  // Subcommand: coverage gaps — enumerate unhandled branches via static analysis
@@ -11,12 +11,23 @@ import { type QualityGateResult } from '../utils/ci-output.js';
11
11
  import { type QualityEvidenceValues } from '../../domains/quality-assessment/quality-evidence.js';
12
12
  export declare function loadQualityEvidence(memory: MemoryBackend): Promise<QualityEvidenceValues>;
13
13
  export declare function evaluateMeasuredQualityEvidence(measured: QualityEvidenceValues): QualityGateResult;
14
+ /**
15
+ * #996: when measured evidence is missing, stale or malformed the gate cannot
16
+ * be evaluated. Report it as a structured, non-passing result with the same
17
+ * `status: 'insufficient-evidence'` and `unmeasured` list that MCP
18
+ * `quality_assess({ runGate: true })` returns alongside its error. Errors that
19
+ * are not about evidence (e.g. the store itself failing) are rethrown.
20
+ */
21
+ export declare function describeUnavailableQualityEvidence(memory: MemoryBackend, error: unknown): Promise<QualityGateResult>;
14
22
  /**
15
23
  * Published quality command exit contract:
16
24
  * 0 = passed with more than five percentage points of headroom
17
25
  * 1 = one or more measured checks failed
18
26
  * 2 = passed, but at least one measured check has less than five points of headroom
27
+ * 3 = insufficient evidence (#996): a metric is absent, stale or malformed, so
28
+ * the gate was not evaluated (UNMEASURED — neither a pass nor a measured failure)
19
29
  */
20
- export declare function getMeasuredQualityExitCode(result: QualityGateResult): 0 | 1 | 2;
30
+ export declare const INSUFFICIENT_EVIDENCE_EXIT_CODE = 3;
31
+ export declare function getMeasuredQualityExitCode(result: QualityGateResult): 0 | 1 | 2 | 3;
21
32
  export declare function createQualityCommand(context: CLIContext, cleanupAndExit: (code: number) => Promise<never>, ensureInitialized: () => Promise<boolean>): Command;
22
33
  //# sourceMappingURL=quality.d.ts.map
@@ -7,7 +7,7 @@
7
7
  import { Command } from 'commander';
8
8
  import chalk from 'chalk';
9
9
  import { writeOutput, toJSON, qualityGateToMarkdown } from '../utils/ci-output.js';
10
- import { evaluateQualityEvidence, loadQualityEvidence as loadCanonicalQualityEvidence, } from '../../domains/quality-assessment/quality-evidence.js';
10
+ import { InsufficientQualityEvidenceError, evaluateQualityEvidence, inspectQualityEvidence, loadQualityEvidence as loadCanonicalQualityEvidence, } from '../../domains/quality-assessment/quality-evidence.js';
11
11
  export async function loadQualityEvidence(memory) {
12
12
  return loadCanonicalQualityEvidence(memory);
13
13
  }
@@ -20,13 +20,48 @@ export function evaluateMeasuredQualityEvidence(measured) {
20
20
  recommendations: evaluation.recommendations,
21
21
  };
22
22
  }
23
+ /**
24
+ * #996: when measured evidence is missing, stale or malformed the gate cannot
25
+ * be evaluated. Report it as a structured, non-passing result with the same
26
+ * `status: 'insufficient-evidence'` and `unmeasured` list that MCP
27
+ * `quality_assess({ runGate: true })` returns alongside its error. Errors that
28
+ * are not about evidence (e.g. the store itself failing) are rethrown.
29
+ */
30
+ export async function describeUnavailableQualityEvidence(memory, error) {
31
+ const insufficient = error instanceof InsufficientQualityEvidenceError
32
+ ? error
33
+ : await inspectQualityEvidence(memory).then(({ problems }) => problems.length > 0 ? new InsufficientQualityEvidenceError(problems) : undefined);
34
+ if (!insufficient)
35
+ throw error;
36
+ const reason = error instanceof Error ? error.message : String(error);
37
+ const details = insufficient.toDetails();
38
+ return {
39
+ passed: false,
40
+ score: 'N/A',
41
+ checks: [],
42
+ status: details.status,
43
+ evidenceStatus: details.evidenceStatus,
44
+ unmeasured: details.unmeasured,
45
+ gateEvaluated: false,
46
+ error: reason,
47
+ recommendations: [
48
+ `Quality gate not evaluated: ${reason}`,
49
+ ...details.recommendations,
50
+ ],
51
+ };
52
+ }
23
53
  /**
24
54
  * Published quality command exit contract:
25
55
  * 0 = passed with more than five percentage points of headroom
26
56
  * 1 = one or more measured checks failed
27
57
  * 2 = passed, but at least one measured check has less than five points of headroom
58
+ * 3 = insufficient evidence (#996): a metric is absent, stale or malformed, so
59
+ * the gate was not evaluated (UNMEASURED — neither a pass nor a measured failure)
28
60
  */
61
+ export const INSUFFICIENT_EVIDENCE_EXIT_CODE = 3;
29
62
  export function getMeasuredQualityExitCode(result) {
63
+ if (result.evidenceStatus === 'insufficient-evidence')
64
+ return INSUFFICIENT_EVIDENCE_EXIT_CODE;
30
65
  if (!result.passed)
31
66
  return 1;
32
67
  return result.checks.some(check => (check.direction !== 'max'
@@ -53,14 +88,27 @@ export function createQualityCommand(context, cleanupAndExit, ensureInitialized)
53
88
  if (format === 'text') {
54
89
  console.log(chalk.blue(`\n Running quality gate evaluation...\n`));
55
90
  }
56
- const measured = await loadQualityEvidence(context.kernel.memory);
57
- const gateResult = evaluateMeasuredQualityEvidence(measured);
91
+ const memory = context.kernel.memory;
92
+ let gateResult;
93
+ try {
94
+ gateResult = evaluateMeasuredQualityEvidence(await loadQualityEvidence(memory));
95
+ }
96
+ catch (error) {
97
+ gateResult = await describeUnavailableQualityEvidence(memory, error);
98
+ }
58
99
  if (format === 'json') {
59
100
  writeOutput(toJSON(gateResult), options.output);
60
101
  }
61
102
  else if (format === 'markdown') {
62
103
  writeOutput(qualityGateToMarkdown(gateResult), options.output);
63
104
  }
105
+ else if (gateResult.evidenceStatus === 'insufficient-evidence') {
106
+ console.log(` Quality Gate: ${chalk.yellow('⚠ INSUFFICIENT EVIDENCE (not evaluated)')}`);
107
+ if (gateResult.unmeasured?.length) {
108
+ console.log(` Unmeasured: ${gateResult.unmeasured.join(', ')}`);
109
+ }
110
+ console.log(chalk.gray(` ${gateResult.error ?? ''}\n`));
111
+ }
64
112
  else {
65
113
  const statusIcon = gateResult.passed ? chalk.green('✓ PASSED') : chalk.red('✗ FAILED');
66
114
  console.log(` Quality Gate: ${statusIcon}`);
@@ -64,11 +64,12 @@ export interface TestRunSummary {
64
64
  tests?: TestResult[];
65
65
  }
66
66
  export interface CoverageResult {
67
+ /** `null` = the report never collected that metric (#995); not 0%. */
67
68
  summary: {
68
- line: number;
69
- branch: number;
70
- function: number;
71
- statement: number;
69
+ line: number | null;
70
+ branch: number | null;
71
+ function: number | null;
72
+ statement: number | null;
72
73
  };
73
74
  meetsThreshold: boolean;
74
75
  threshold: number;
@@ -96,6 +97,15 @@ export interface QualityGateResult {
96
97
  threshold: number | string;
97
98
  }>;
98
99
  recommendations?: string[];
100
+ /** #996 (additive): 'insufficient-evidence' when the gate could not be evaluated. */
101
+ status?: 'insufficient-evidence';
102
+ evidenceStatus?: 'measured' | 'insufficient-evidence';
103
+ /** #996: canonical metrics with no measured evidence. */
104
+ unmeasured?: string[];
105
+ /** #996: false when missing evidence prevented the gate from running. */
106
+ gateEvaluated?: boolean;
107
+ /** #996: why the gate could not be evaluated. */
108
+ error?: string;
99
109
  }
100
110
  /**
101
111
  * Standard --format and --output options to add to any Command.