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.
- package/.claude/skills/skills-manifest.json +1 -1
- package/CHANGELOG.md +70 -0
- package/assets/skills/skills-manifest.json +1 -1
- package/dist/bridge/captured-experience-bridge.js +7 -9
- package/dist/cli/bundle.js +5 -5
- package/dist/cli/chunks/adapter-EGIPTX5H.js +2 -0
- package/dist/cli/chunks/{agent-booster-wasm-MHJBRXMK.js → agent-booster-wasm-CCTTGCQS.js} +2 -2
- package/dist/cli/chunks/{agent-handler-G64SD7J2.js → agent-handler-DHYUF3NX.js} +2 -2
- package/dist/cli/chunks/{agent-memory-branch-G4UXFPKH.js → agent-memory-branch-642W7CYX.js} +2 -2
- package/dist/cli/chunks/aqe-learning-engine-WP4GCBDT.js +2 -0
- package/dist/cli/chunks/{arena-QJMKYPHS.js → arena-MUCC7UUN.js} +4 -4
- package/dist/cli/chunks/{arena-63M3M6EW.js → arena-NW2JVAFY.js} +2 -2
- package/dist/cli/chunks/{audit-UDFVTWSX.js → audit-VKQTZJAA.js} +3 -3
- package/dist/cli/chunks/base-6ORFD62I.js +2 -0
- package/dist/cli/chunks/{better-sqlite3-JLX2G56I.js → better-sqlite3-7ZUFVWLQ.js} +2 -2
- package/dist/cli/chunks/{brain-handler-PWF32LLW.js → brain-handler-7LKAWSBI.js} +3 -3
- package/dist/cli/chunks/{branch-enumerator-PB7QWXDP.js → branch-enumerator-HUNXJKM4.js} +2 -2
- package/dist/cli/chunks/{browser-CYNV2F3U.js → browser-ZSZEYUDP.js} +2 -2
- package/dist/cli/chunks/browser-workflow-PIXGERWP.js +2 -0
- package/dist/cli/chunks/{chunk-RWZ4F44Y.js → chunk-2KWI3MT3.js} +2 -2
- package/dist/cli/chunks/{chunk-UORI2CZ4.js → chunk-2WFTZSRT.js} +1 -1
- package/dist/cli/chunks/{chunk-HCDTLV5J.js → chunk-2XYTS2WY.js} +2 -2
- package/dist/cli/chunks/{chunk-DBIK4OFX.js → chunk-35MDATQE.js} +1 -1
- package/dist/cli/chunks/{chunk-54XTJBHV.js → chunk-3AYYGR6W.js} +1 -1
- package/dist/cli/chunks/{chunk-SJB4KMZS.js → chunk-3DTEQHFB.js} +3 -3
- package/dist/cli/chunks/{chunk-RG67RZIX.js → chunk-3OAQPN2N.js} +2 -2
- package/dist/cli/chunks/{chunk-2DRMTRBM.js → chunk-3QD7U3FY.js} +2 -2
- package/dist/cli/chunks/{chunk-VMSO6DMF.js → chunk-3SH23PS3.js} +2 -2
- package/dist/cli/chunks/{chunk-RJ5CZ7B6.js → chunk-3YASZPLO.js} +2 -2
- package/dist/cli/chunks/{chunk-JFQDWAU3.js → chunk-3YNP33GB.js} +2 -2
- package/dist/cli/chunks/{chunk-I53365HG.js → chunk-47GEI2LT.js} +3 -3
- package/dist/cli/chunks/{chunk-PCWZCXBD.js → chunk-4AZP7ZCW.js} +2 -2
- package/dist/cli/chunks/{chunk-54ITMOFM.js → chunk-4PT5KNXL.js} +4 -4
- package/dist/cli/chunks/{chunk-SIUUAKCE.js → chunk-4UXPDV7E.js} +1 -1
- package/dist/cli/chunks/{chunk-LZSLJJII.js → chunk-4XSCZVON.js} +2 -2
- package/dist/cli/chunks/{chunk-DFJGXXCL.js → chunk-5BOZCMXZ.js} +1 -1
- package/dist/cli/chunks/{chunk-B7J3O2WM.js → chunk-644DFAGS.js} +1 -1
- package/dist/cli/chunks/{chunk-2ICC4H6K.js → chunk-663ZFPUL.js} +2 -2
- package/dist/cli/chunks/{chunk-YUWUFYHK.js → chunk-6JFGB2JB.js} +1 -1
- package/dist/cli/chunks/{chunk-MBV57LKC.js → chunk-6LG5UEQE.js} +2 -2
- package/dist/cli/chunks/{chunk-LRTF5RMG.js → chunk-6UYN5PHA.js} +4 -4
- package/dist/cli/chunks/{chunk-5SS2Z7JC.js → chunk-6ZIDZ4TJ.js} +2 -2
- package/dist/cli/chunks/{chunk-2534PXIV.js → chunk-7BIYJRQJ.js} +2 -2
- package/dist/cli/chunks/{chunk-HX5KQK7I.js → chunk-7EZLOC4K.js} +2 -2
- package/dist/cli/chunks/{chunk-ZAOQIVHG.js → chunk-7YB2KELI.js} +2 -2
- package/dist/cli/chunks/{chunk-SOSJFEFB.js → chunk-A2WOQO2N.js} +2 -2
- package/dist/cli/chunks/{chunk-M6SJALLA.js → chunk-A337MD3C.js} +2 -2
- package/dist/cli/chunks/{chunk-YZ2AGC7O.js → chunk-A5J4XJS6.js} +1 -1
- package/dist/cli/chunks/{chunk-PEA4DVXW.js → chunk-AQN5EDBM.js} +1 -1
- package/dist/cli/chunks/{chunk-EGHK6NMH.js → chunk-AUZXRFOX.js} +2 -2
- package/dist/cli/chunks/{chunk-BBKLVHDQ.js → chunk-B2UHTA4Q.js} +1 -1
- package/dist/cli/chunks/{chunk-LY53L6NH.js → chunk-BBL6YXD3.js} +2 -2
- package/dist/cli/chunks/chunk-BJ5P4IV2.js +2 -0
- package/dist/cli/chunks/{chunk-I43QRLLB.js → chunk-BMWAWZAN.js} +2 -2
- package/dist/cli/chunks/chunk-BO4PKNYP.js +102 -0
- package/dist/cli/chunks/{chunk-PMXWDTDK.js → chunk-BY646JOM.js} +2 -2
- package/dist/cli/chunks/{chunk-OFQDM73J.js → chunk-BYXNHGQC.js} +2 -2
- package/dist/cli/chunks/{chunk-73MTUM6F.js → chunk-BZFT4QDQ.js} +2 -2
- package/dist/cli/chunks/{chunk-RA3MI5WK.js → chunk-CFPR24YK.js} +2 -2
- package/dist/cli/chunks/{chunk-WEDVLKRB.js → chunk-CQMHDAJS.js} +2 -2
- package/dist/cli/chunks/{chunk-HFSBONCS.js → chunk-CR2JUANW.js} +2 -2
- package/dist/cli/chunks/{chunk-BY3IL56R.js → chunk-CXOXUBYU.js} +1 -1
- package/dist/cli/chunks/{chunk-AOKSLWON.js → chunk-D3G2NN7F.js} +77 -78
- package/dist/cli/chunks/{chunk-I5A3HGO6.js → chunk-DEGWCUMY.js} +2 -2
- package/dist/cli/chunks/{chunk-CQ3WSTJ2.js → chunk-DFPL5N3Q.js} +2 -2
- package/dist/cli/chunks/{chunk-TVQPYP2Z.js → chunk-DL5JENWD.js} +3 -3
- package/dist/cli/chunks/{chunk-V3NZ23X6.js → chunk-DLY4YEN3.js} +2 -2
- package/dist/cli/chunks/{chunk-HEKCN5XQ.js → chunk-DPV33C77.js} +2 -2
- package/dist/cli/chunks/{chunk-KOLHZSEC.js → chunk-DPYDUKVZ.js} +2 -2
- package/dist/cli/chunks/{chunk-3MSBVOYW.js → chunk-DTJODGCE.js} +2 -2
- package/dist/cli/chunks/{chunk-MGH4XIHH.js → chunk-DWZI3IVB.js} +2 -2
- package/dist/cli/chunks/{chunk-DPL4ZXTE.js → chunk-DXVZBJE4.js} +1 -1
- package/dist/cli/chunks/{chunk-LXYTC62V.js → chunk-E4VIVMDL.js} +2 -2
- package/dist/cli/chunks/{chunk-DVE5SM5G.js → chunk-EAYQCBXL.js} +3 -3
- package/dist/cli/chunks/{chunk-BY5PLEPZ.js → chunk-EOR3RECZ.js} +2 -2
- package/dist/cli/chunks/chunk-ERGWWI4Y.js +3 -0
- package/dist/cli/chunks/{chunk-LPSE6DOQ.js → chunk-EUEHBERE.js} +1 -1
- package/dist/cli/chunks/{chunk-3BDDOFYW.js → chunk-EVCFUYYK.js} +2 -2
- package/dist/cli/chunks/{chunk-SZWXUG36.js → chunk-FBEXG4HD.js} +2 -2
- package/dist/cli/chunks/{chunk-5GWTJJEO.js → chunk-FE3AIZI6.js} +1 -1
- package/dist/cli/chunks/{chunk-4GLR2S2M.js → chunk-FHUJCVT3.js} +2 -2
- package/dist/cli/chunks/{chunk-6TMUZGM2.js → chunk-FNAYDITO.js} +1 -1
- package/dist/cli/chunks/{chunk-U2E5F3VZ.js → chunk-FQKEZVN6.js} +2 -2
- package/dist/cli/chunks/{chunk-2LL35V3A.js → chunk-FWYJ6UDX.js} +2 -2
- package/dist/cli/chunks/{chunk-ISASRHZP.js → chunk-GGDKOJVF.js} +2 -2
- package/dist/cli/chunks/{chunk-ZKXZTIVF.js → chunk-GKPRECLL.js} +2 -2
- package/dist/cli/chunks/{chunk-OHH6BUZK.js → chunk-GRIPCYW5.js} +1 -1
- package/dist/cli/chunks/{chunk-XZ5Z56OP.js → chunk-GTSOFCMQ.js} +1 -1
- package/dist/cli/chunks/{chunk-2MU4WCMQ.js → chunk-HBYQYGXP.js} +2 -2
- package/dist/cli/chunks/{chunk-YQ6BK7QC.js → chunk-HGBJ2QQ4.js} +2 -2
- package/dist/cli/chunks/{chunk-N6CRIUTO.js → chunk-HIUNCO2W.js} +2 -2
- package/dist/cli/chunks/{chunk-5H7MR6HP.js → chunk-HLFDC4SF.js} +1 -1
- package/dist/cli/chunks/{chunk-GAXTPQCZ.js → chunk-HPLMX62I.js} +2 -2
- package/dist/cli/chunks/{chunk-WO4NSPLX.js → chunk-IHFUEPZH.js} +2 -2
- package/dist/cli/chunks/{chunk-ADF6LGHZ.js → chunk-IJ2EXSMO.js} +2 -2
- package/dist/cli/chunks/{chunk-GLKLEHK3.js → chunk-IJOFZBXD.js} +2 -2
- package/dist/cli/chunks/{chunk-IKWAPHJA.js → chunk-JANLATHN.js} +2 -2
- package/dist/cli/chunks/{chunk-J3RNVHDH.js → chunk-JCC7QEKZ.js} +1 -1
- package/dist/cli/chunks/{chunk-C5EN5WB6.js → chunk-JI77KJP7.js} +1 -1
- package/dist/cli/chunks/{chunk-B7GJXQD2.js → chunk-JNMUVBAJ.js} +2 -2
- package/dist/cli/chunks/{chunk-ZP6ANUP7.js → chunk-JYY7AYGA.js} +1 -1
- package/dist/cli/chunks/{chunk-6HTO4BLV.js → chunk-KHCALIFP.js} +2 -2
- package/dist/cli/chunks/{chunk-BND6M2JX.js → chunk-KJ3KBP24.js} +2 -2
- package/dist/cli/chunks/{chunk-O7TMY4GS.js → chunk-KZVJW2SD.js} +2 -2
- package/dist/cli/chunks/chunk-L336HFFE.js +2 -0
- package/dist/cli/chunks/{chunk-W3PPYNHF.js → chunk-L375O3CZ.js} +2 -2
- package/dist/cli/chunks/{chunk-PJAXWCFC.js → chunk-L6SVCNXK.js} +1 -1
- package/dist/cli/chunks/{chunk-VAXQUD5G.js → chunk-LNO5IWGH.js} +1 -1
- package/dist/cli/chunks/{chunk-CFXFGQEN.js → chunk-LRASYSGV.js} +2 -2
- package/dist/cli/chunks/{chunk-MVTUFPM2.js → chunk-MB4VFAJC.js} +2 -2
- package/dist/cli/chunks/{chunk-SCL2OYN7.js → chunk-MNQ36MAF.js} +2 -2
- package/dist/cli/chunks/{chunk-W6TJXK5Y.js → chunk-MQGEZA2A.js} +2 -2
- package/dist/cli/chunks/{chunk-73PCVMGA.js → chunk-MS3Z2CP5.js} +2 -2
- package/dist/cli/chunks/{chunk-WI5AEB7Q.js → chunk-N2TJNIHA.js} +2 -2
- package/dist/cli/chunks/{chunk-DEJM2P5K.js → chunk-NF6AFIAX.js} +1 -1
- package/dist/cli/chunks/{chunk-JL3TI43V.js → chunk-NLDFNAOS.js} +2 -2
- package/dist/cli/chunks/{chunk-UK5HY6LC.js → chunk-NMJVG22Z.js} +1 -1
- package/dist/cli/chunks/{chunk-WW6WUMS7.js → chunk-OGYWWZU7.js} +2 -2
- package/dist/cli/chunks/{chunk-3C2BFLYC.js → chunk-ONCH5AXU.js} +3 -3
- package/dist/cli/chunks/{chunk-OG4KHX7S.js → chunk-OQDC7GCM.js} +2 -2
- package/dist/cli/chunks/{chunk-3ZIVBTX6.js → chunk-ORTBRO7F.js} +2 -2
- package/dist/cli/chunks/{chunk-NIJMLEAX.js → chunk-OU4ZAWCC.js} +2 -2
- package/dist/cli/chunks/{chunk-FDK2GF4G.js → chunk-OW42F2TX.js} +2 -2
- package/dist/cli/chunks/{chunk-TB22Y3WW.js → chunk-PCCIZFD7.js} +1 -1
- package/dist/cli/chunks/{chunk-BZWZTGMF.js → chunk-PDPEMBFV.js} +2 -2
- package/dist/cli/chunks/{chunk-D7RVZ5C2.js → chunk-PHAQWAEV.js} +2 -2
- package/dist/cli/chunks/{chunk-P7GM3EE7.js → chunk-PHP4UJYP.js} +1 -1
- package/dist/cli/chunks/{chunk-6QPW4OVH.js → chunk-PURHGLEC.js} +1 -1
- package/dist/cli/chunks/{chunk-BPGFCUDO.js → chunk-PVAE65B4.js} +1 -1
- package/dist/cli/chunks/{chunk-7X2IVMXN.js → chunk-QPV3OKX2.js} +2 -2
- package/dist/cli/chunks/{chunk-DAYMT7TH.js → chunk-QXY3IRBW.js} +3 -3
- package/dist/cli/chunks/{chunk-QIAX3JJB.js → chunk-RCXMUEZN.js} +2 -2
- package/dist/cli/chunks/{chunk-RB2SL5GD.js → chunk-RMJ7PJOS.js} +2 -2
- package/dist/cli/chunks/{chunk-FRBCX46J.js → chunk-RUJLVJDE.js} +2 -2
- package/dist/cli/chunks/{chunk-S5D3HCGN.js → chunk-RUSLEOMC.js} +2 -2
- package/dist/cli/chunks/chunk-SAPIRK2G.js +3 -0
- package/dist/cli/chunks/{chunk-A4OPQJ4A.js → chunk-SDWMLT7B.js} +5 -5
- package/dist/cli/chunks/{chunk-RJMBHZYL.js → chunk-SEZLYRCS.js} +1 -1
- package/dist/cli/chunks/{chunk-AHVN3UQZ.js → chunk-TDLKXLJC.js} +2 -2
- package/dist/cli/chunks/{chunk-EWUFVWRT.js → chunk-U4TV75AC.js} +2 -2
- package/dist/cli/chunks/{chunk-X5S5UEM6.js → chunk-U6OVPMQX.js} +2 -2
- package/dist/cli/chunks/{chunk-5B5D5KCV.js → chunk-UE22ODHN.js} +1 -1
- package/dist/cli/chunks/{chunk-I6E4X3L3.js → chunk-UXZEVIFX.js} +1 -1
- package/dist/cli/chunks/{chunk-DF4Y3HPO.js → chunk-V7GNUVYI.js} +1 -1
- package/dist/cli/chunks/{chunk-OOK6GPJR.js → chunk-VCKDVOPD.js} +2 -2
- package/dist/cli/chunks/{chunk-G3ZUB3HD.js → chunk-VH3EB6ZG.js} +2 -2
- package/dist/cli/chunks/{chunk-PB2WSCBW.js → chunk-VLOIEVER.js} +3 -3
- package/dist/cli/chunks/{chunk-7INP6HZH.js → chunk-VML4SG3X.js} +3 -3
- package/dist/cli/chunks/{chunk-K2VUYRMG.js → chunk-VRJPH3LG.js} +2 -2
- package/dist/cli/chunks/{chunk-RI4JPBZD.js → chunk-VYDNLQJN.js} +2 -2
- package/dist/cli/chunks/{chunk-35A22AUL.js → chunk-W3ZGNNDV.js} +1 -1
- package/dist/cli/chunks/{chunk-R47LNH5W.js → chunk-WC47GICZ.js} +2 -2
- package/dist/cli/chunks/{chunk-Z56QTRRB.js → chunk-WLIYWBQR.js} +2 -2
- package/dist/cli/chunks/{chunk-ZURYZEHX.js → chunk-WN55MNZ2.js} +2 -2
- package/dist/cli/chunks/chunk-WOZIXXY5.js +7 -0
- package/dist/cli/chunks/{chunk-NBMQOP2R.js → chunk-WR64BKUE.js} +1 -1
- package/dist/cli/chunks/{chunk-T3BMCEQR.js → chunk-WT3JC4A6.js} +2 -2
- package/dist/cli/chunks/{chunk-WYO5VN2L.js → chunk-X52TMBHU.js} +1 -1
- package/dist/cli/chunks/{chunk-6EHVPFHW.js → chunk-XIE7OHML.js} +1 -1
- package/dist/cli/chunks/{chunk-LOLAEDZD.js → chunk-XNEEYXR2.js} +2 -2
- package/dist/cli/chunks/{chunk-EY5IUF7U.js → chunk-XNHB6TLC.js} +2 -2
- package/dist/cli/chunks/{chunk-GJVRQBLI.js → chunk-XQRE2HWM.js} +2 -2
- package/dist/cli/chunks/{chunk-33IUCP34.js → chunk-Y2E3IJ53.js} +2 -2
- package/dist/cli/chunks/{chunk-6HO3XRXE.js → chunk-Y2WMPEUP.js} +2 -2
- package/dist/cli/chunks/{chunk-LGA6J4I4.js → chunk-Y7GPLOXB.js} +2 -2
- package/dist/cli/chunks/{chunk-76PRW2KY.js → chunk-YINFES3E.js} +2 -2
- package/dist/cli/chunks/{chunk-LJRZAALA.js → chunk-ZLBBX24Q.js} +133 -133
- package/dist/cli/chunks/{chunk-ASKPTGUU.js → chunk-ZT3GUYM5.js} +2 -2
- package/dist/cli/chunks/{chunk-XHCCH7UC.js → chunk-ZTC5FBL6.js} +3 -3
- package/dist/cli/chunks/ci-KP4GZKJ7.js +81 -0
- package/dist/cli/chunks/ci-config-XDDZOOEI.js +2 -0
- package/dist/cli/chunks/{ci-output-BMJABAEX.js → ci-output-7ZUQI4U6.js} +2 -2
- package/dist/cli/chunks/{circuit-breaker-GYD5CMJQ.js → circuit-breaker-ALXKCFAL.js} +2 -2
- package/dist/cli/chunks/{claude-flow-setup-MMOYVBVD.js → claude-flow-setup-RL7K2NI2.js} +2 -2
- package/dist/cli/chunks/client-C3KHVRM6.js +2 -0
- package/dist/cli/chunks/{cline-installer-B2SOZ44R.js → cline-installer-2Z2QQKC3.js} +2 -2
- package/dist/cli/chunks/{code-V3FIRAXD.js → code-QSZTDINQ.js} +4 -4
- package/dist/cli/chunks/{code-index-extractor-CV6A756Z.js → code-index-extractor-5CGR5D3Y.js} +2 -2
- package/dist/cli/chunks/{codex-installer-EUC6J47Y.js → codex-installer-7JLSEDE5.js} +2 -2
- package/dist/cli/chunks/{completions-DQQIBAHR.js → completions-U4NBSXEB.js} +2 -2
- package/dist/cli/chunks/{complexity-analyzer-HPXMXP5I.js → complexity-analyzer-WYZD2YSY.js} +2 -2
- package/dist/cli/chunks/{continuedev-installer-RCIYXH6V.js → continuedev-installer-UPXINJFT.js} +2 -2
- package/dist/cli/chunks/{copilot-installer-VUH32SHF.js → copilot-installer-WIVYQRIF.js} +2 -2
- package/dist/cli/chunks/core-handlers-KSQM6Q6S.js +2 -0
- package/dist/cli/chunks/{cost-tracker-YLCKLOAL.js → cost-tracker-RIN4JDDM.js} +2 -2
- package/dist/cli/chunks/coverage-SPFVHRRU.js +43 -0
- package/dist/cli/chunks/coverage-target-GSRBNHXE.js +2 -0
- package/dist/cli/chunks/cross-domain-router-CTGNOVCF.js +2 -0
- package/dist/cli/chunks/{cursor-installer-B42FN62K.js → cursor-installer-POM7NGCC.js} +2 -2
- package/dist/cli/chunks/{daemon-DECQRQII.js → daemon-HFGKQ6LB.js} +3 -3
- package/dist/cli/chunks/{daemon-IPTOSCHM.js → daemon-M5TD5Y6T.js} +4 -4
- package/dist/cli/chunks/{dag-attention-scheduler-RY7CDYSC.js → dag-attention-scheduler-HJXM7Q5P.js} +2 -2
- package/dist/cli/chunks/{detect-NW53BMJN.js → detect-XKQGLZYN.js} +2 -2
- package/dist/cli/chunks/{dist-node-LE6KHXAB.js → dist-node-SSKB53QL.js} +2 -2
- package/dist/cli/chunks/{domain-handler-JGXFT4LW.js → domain-handler-6BNDHATU.js} +2 -2
- package/dist/cli/chunks/{domain-plugins-GY3RYKKK.js → domain-plugins-DOX54YE3.js} +2 -2
- package/dist/cli/chunks/{domain-transfer-CGBRXNTC.js → domain-transfer-FW4ZX3Z7.js} +2 -2
- package/dist/cli/chunks/dream-MIK2E4UL.js +2 -0
- package/dist/cli/chunks/{embed-and-insert-pattern-65H4XHWR.js → embed-and-insert-pattern-QST77T2B.js} +2 -2
- package/dist/cli/chunks/{eval-YPYIZQUR.js → eval-K7E4XXBS.js} +2 -2
- package/dist/cli/chunks/{experience-capture-middleware-4JXVF5PL.js → experience-capture-middleware-X66IYSRV.js} +3 -3
- package/dist/cli/chunks/{fast-paths-HYQTAF2S.js → fast-paths-5JXXTYAG.js} +2 -2
- package/dist/cli/chunks/{feature-flags-HNSAFFX2.js → feature-flags-2CR3CO23.js} +2 -2
- package/dist/cli/chunks/{feature-flags-YACUH6OW.js → feature-flags-RB72LHOJ.js} +2 -2
- package/dist/cli/chunks/{file-discovery-R73BYEXB.js → file-discovery-3NHRUQQB.js} +2 -2
- package/dist/cli/chunks/{fleet-6M3BP4OO.js → fleet-SDU7QEOA.js} +3 -3
- package/dist/cli/chunks/{gnn-wrapper-QLD7KHXV.js → gnn-wrapper-AWCFODUV.js} +2 -2
- package/dist/cli/chunks/{heartbeat-handler-EZP333X4.js → heartbeat-handler-A4PJ3NFP.js} +4 -4
- package/dist/cli/chunks/heartbeat-scheduler-OCKRACUW.js +2 -0
- package/dist/cli/chunks/hnsw-adapter-X67XG73C.js +2 -0
- package/dist/cli/chunks/hnsw-index-I7KCQBQR.js +2 -0
- package/dist/cli/chunks/{hnsw-legacy-bridge-47CUCSAU.js → hnsw-legacy-bridge-KRS7SSFM.js} +2 -2
- package/dist/cli/chunks/{hnswlib-node-SVNYDJZH.js → hnswlib-node-OGGCPKPO.js} +2 -2
- package/dist/cli/chunks/{hooks-6V5LMWP6.js → hooks-XNRNMUBW.js} +10 -10
- package/dist/cli/chunks/hybrid-backend-FOUHTKAK.js +2 -0
- package/dist/cli/chunks/{hypergraph-engine-L2FOBIFF.js → hypergraph-engine-X35LTXYT.js} +2 -2
- package/dist/cli/chunks/{hypergraph-handler-DU6Z57EE.js → hypergraph-handler-M6THKAG6.js} +3 -3
- package/dist/cli/chunks/impact-analyzer-GXYVX46O.js +2 -0
- package/dist/cli/chunks/{init-handler-HETPWU67.js → init-handler-2AXMXHYF.js} +6 -6
- package/dist/cli/chunks/init-wizard-C2MRX2QG.js +2 -0
- package/dist/cli/chunks/kernel-Q2IUDIDC.js +2 -0
- package/dist/cli/chunks/{kilocode-installer-NHKYGJ7Q.js → kilocode-installer-TEPR2ZJD.js} +2 -2
- package/dist/cli/chunks/{kiro-installer-24UK6GGR.js → kiro-installer-RUKHGDEE.js} +2 -2
- package/dist/cli/chunks/knowledge-graph-E2Z6K5EE.js +2 -0
- package/dist/cli/chunks/{learning-QLVRZNHT.js → learning-BEA26RNA.js} +3 -3
- package/dist/cli/chunks/{llm-router-XRMI2VMG.js → llm-router-7GECMDCP.js} +4 -4
- package/dist/cli/chunks/llm-router-service-YATYFEDD.js +2 -0
- package/dist/cli/chunks/{load-W5UWL5C7.js → load-NTJ4Y4ZR.js} +2 -2
- package/dist/cli/chunks/load-test-LV77JXWA.js +2 -0
- package/dist/cli/chunks/{mcp-N7ALQ4BL.js → mcp-4335GTTG.js} +2 -2
- package/dist/cli/chunks/{memory-WV52DLSA.js → memory-HYC4M4XS.js} +5 -5
- package/dist/cli/chunks/memory-backend-XME3X3QX.js +2 -0
- package/dist/cli/chunks/memory-handlers-VG47X5DX.js +2 -0
- package/dist/cli/chunks/{multi-model-executor-3FVTZCSO.js → multi-model-executor-T7FYKM6T.js} +2 -2
- package/dist/cli/chunks/{opencode-installer-NTPWGHUW.js → opencode-installer-3USXVT5M.js} +2 -2
- package/dist/cli/chunks/{orchestrator-ORGJ6VAA.js → orchestrator-VHUXUYIM.js} +5 -5
- package/dist/cli/chunks/pattern-null-store-TAXMLENP.js +2 -0
- package/dist/cli/chunks/{pattern-usage-recorder-WWXHUH5U.js → pattern-usage-recorder-CMZLPX2K.js} +2 -2
- package/dist/cli/chunks/{pipeline-ZOKZFXTH.js → pipeline-BTRZOVSL.js} +2 -2
- package/dist/cli/chunks/{platform-CDNL322F.js → platform-2MCRKC25.js} +2 -2
- package/dist/cli/chunks/{plugin-ZVLFNZZ4.js → plugin-2VAYWAO3.js} +2 -2
- package/dist/cli/chunks/{prime-radiant-advanced-wasm-FVJDU2JY.js → prime-radiant-advanced-wasm-TXFEMBP6.js} +2 -2
- package/dist/cli/chunks/{project-root-UCHQH3QL.js → project-root-CFFPBGPX.js} +2 -2
- package/dist/cli/chunks/protocol-executor-ML76QAVQ.js +2 -0
- package/dist/cli/chunks/{protocol-handler-4YBN5R23.js → protocol-handler-DZ26OYVZ.js} +2 -2
- package/dist/cli/chunks/{prove-BHDHY664.js → prove-QWONEJWX.js} +2 -2
- package/dist/cli/chunks/qe-reasoning-bank-LUZH6RYV.js +2 -0
- package/dist/cli/chunks/quality-WFH54FY7.js +8 -0
- package/dist/cli/chunks/{quality-gate-WANE7TCN.js → quality-gate-ONJB7XU7.js} +3 -3
- package/dist/cli/chunks/queen-coordinator-EWXNIXB6.js +2 -0
- package/dist/cli/chunks/{real-embeddings-56MNGJGJ.js → real-embeddings-GZV4VKK4.js} +2 -2
- package/dist/cli/chunks/{ref-validation-S7UWXQIP.js → ref-validation-HW5Y55ZC.js} +2 -2
- package/dist/cli/chunks/{roocode-installer-TEYOQYL6.js → roocode-installer-5OABDNZT.js} +2 -2
- package/dist/cli/chunks/router-MXOBVEBF.js +2 -0
- package/dist/cli/chunks/routing-feedback-T6CCRUEK.js +2 -0
- package/dist/cli/chunks/{routing-handler-KDTLMRWD.js → routing-handler-CVHVOQTC.js} +2 -2
- package/dist/cli/chunks/{ruvector-commands-AOUDXCYE.js → ruvector-commands-KKDKFGIQ.js} +2 -2
- package/dist/cli/chunks/rvf-dual-writer-WHXVT3V3.js +2 -0
- package/dist/cli/chunks/rvf-migration-adapter-JFPWIRCG.js +2 -0
- package/dist/cli/chunks/{rvf-migration-coordinator-V74MVBHS.js → rvf-migration-coordinator-D4KUBNRZ.js} +2 -2
- package/dist/cli/chunks/rvf-native-adapter-KOXR7TJL.js +2 -0
- package/dist/cli/chunks/{rvf-store-integrity-QI47Y354.js → rvf-store-integrity-UGUXKIFX.js} +2 -2
- package/dist/cli/chunks/safe-db-CI6IPSIN.js +2 -0
- package/dist/cli/chunks/schedule-X4HW6TVJ.js +2 -0
- package/dist/cli/chunks/scheduler-KCNJ2ON3.js +2 -0
- package/dist/cli/chunks/{security-SN6MWOJT.js → security-7723AZZ4.js} +3 -3
- package/dist/cli/chunks/{shared-rvf-adapter-2LB56LP4.js → shared-rvf-adapter-KEQ5CLNI.js} +2 -2
- package/dist/cli/chunks/{shared-rvf-dual-writer-WU7PFKQM.js → shared-rvf-dual-writer-ZSHYG5IA.js} +2 -2
- package/dist/cli/chunks/sqlite-persistence-PGHU6VUR.js +2 -0
- package/dist/cli/chunks/{standalone-memory-F6FSRFWC.js → standalone-memory-MHZEEYMK.js} +2 -2
- package/dist/cli/chunks/{status-handler-DHD5MS4G.js → status-handler-JKXPJ22K.js} +2 -2
- package/dist/cli/chunks/{structural-health-P6HPSQMR.js → structural-health-J4RKCYWF.js} +2 -2
- package/dist/cli/chunks/{sync-SNAXAVCN.js → sync-EFWXMA2H.js} +2 -2
- package/dist/cli/chunks/{sync-LISJGDSE.js → sync-PDPORHVN.js} +2 -2
- package/dist/cli/chunks/{task-handler-ZT44NT5Z.js → task-handler-VERADM44.js} +2 -2
- package/dist/cli/chunks/{task-handlers-R6DQ5324.js → task-handlers-4RUCWUR2.js} +3 -3
- package/dist/cli/chunks/{test-MUFHR4JQ.js → test-DMBJFQNL.js} +4 -4
- package/dist/cli/chunks/{test-scheduling-TAUSLZJP.js → test-scheduling-LUPTVGCD.js} +3 -3
- package/dist/cli/chunks/{token-bootstrap-UGRH7OPU.js → token-bootstrap-S346YBVO.js} +2 -2
- package/dist/cli/chunks/{token-usage-IX65ECBR.js → token-usage-VOA34IKM.js} +2 -2
- package/dist/cli/chunks/{transformers-QKPSVW2W.js → transformers-GU4TYAN5.js} +2 -2
- package/dist/cli/chunks/{tree-sitter-wasm-parser-Z7PPA2JO.js → tree-sitter-wasm-parser-MZPXAH7C.js} +2 -2
- package/dist/cli/chunks/{types-ULNNGGGH.js → types-K4FLXR2K.js} +2 -2
- package/dist/cli/chunks/unified-memory-6CK3TUNQ.js +2 -0
- package/dist/cli/chunks/unified-memory-hnsw-A7BWBGYN.js +2 -0
- package/dist/cli/chunks/unified-persistence-GEPMDBQZ.js +2 -0
- package/dist/cli/chunks/{upgrade-ECI3YUYA.js → upgrade-M3ATDRMK.js} +2 -2
- package/dist/cli/chunks/{validate-3JKRUW2S.js → validate-AAP773B3.js} +2 -2
- package/dist/cli/chunks/{validate-swarm-LZWANCIE.js → validate-swarm-7RGAZX5F.js} +2 -2
- package/dist/cli/chunks/visual-security-L4J7LQWT.js +2 -0
- package/dist/cli/chunks/{web-tree-sitter-N5V4A6XG.js → web-tree-sitter-GQMRHGGI.js} +2 -2
- package/dist/cli/chunks/{windsurf-installer-5TBM5B3C.js → windsurf-installer-HG6HF2GF.js} +2 -2
- package/dist/cli/chunks/witness-chain-CDUMX623.js +2 -0
- package/dist/cli/chunks/{witness-chain-MFP3HBWQ.js → witness-chain-WKU3ZIBQ.js} +2 -2
- package/dist/cli/chunks/{witness-chain-repair-5QWRFVUK.js → witness-chain-repair-WNYH6O4L.js} +2 -2
- package/dist/cli/chunks/{witness-chain-verifier-SRAT7LVY.js → witness-chain-verifier-Q2KW3QEQ.js} +2 -2
- package/dist/cli/chunks/{witness-key-manager-FYZXQTLJ.js → witness-key-manager-NQ5DAAC4.js} +2 -2
- package/dist/cli/chunks/{workflow-M7TUYYXY.js → workflow-CX6SHFBW.js} +4 -4
- package/dist/cli/chunks/workflow-orchestrator-USJDWVDR.js +2 -0
- package/dist/cli/chunks/{wrappers-COU73OQ6.js → wrappers-CZDI6Z3X.js} +2 -2
- package/dist/cli/commands/ci.js +14 -6
- package/dist/cli/commands/code.js +1 -0
- package/dist/cli/commands/coverage.d.ts +28 -0
- package/dist/cli/commands/coverage.js +258 -143
- package/dist/cli/commands/quality.d.ts +12 -1
- package/dist/cli/commands/quality.js +51 -3
- package/dist/cli/utils/ci-output.d.ts +14 -4
- package/dist/cli/utils/ci-output.js +21 -4
- package/dist/cli/utils/coverage-data.d.ts +7 -0
- package/dist/cli/utils/coverage-data.js +21 -27
- package/dist/contracts/verdicts.d.ts +14 -0
- package/dist/contracts/verdicts.js +44 -3
- package/dist/coordination/handlers/coverage-handlers.js +121 -120
- package/dist/coordination/handlers/coverage-runner.d.ts +121 -0
- package/dist/coordination/handlers/coverage-runner.js +367 -0
- package/dist/coordination/handlers/coverage-target.d.ts +144 -0
- package/dist/coordination/handlers/coverage-target.js +311 -0
- package/dist/coordination/handlers/handler-utils.d.ts +9 -0
- package/dist/coordination/handlers/handler-utils.js +44 -1
- package/dist/coordination/handlers/quality-handlers.js +101 -15
- package/dist/coordination/result-saver.js +17 -3
- package/dist/coordination/task-executor.d.ts +5 -0
- package/dist/coordination/task-executor.js +7 -0
- package/dist/domains/code-intelligence/coordinator.d.ts +2 -1
- package/dist/domains/code-intelligence/coordinator.js +10 -32
- package/dist/domains/code-intelligence/interfaces.d.ts +5 -0
- package/dist/domains/code-intelligence/plugin.js +1 -0
- package/dist/domains/code-intelligence/project-root-resolver.d.ts +50 -0
- package/dist/domains/code-intelligence/project-root-resolver.js +121 -0
- package/dist/domains/coverage-analysis/coordinator.js +4 -1
- package/dist/domains/coverage-analysis/interfaces.d.ts +15 -0
- package/dist/domains/coverage-analysis/plugin.js +7 -1
- package/dist/domains/coverage-analysis/services/coverage-analyzer.d.ts +7 -0
- package/dist/domains/coverage-analysis/services/coverage-analyzer.js +29 -9
- package/dist/domains/quality-assessment/coordinator-claim-verifier.js +2 -1
- package/dist/domains/quality-assessment/coordinator.js +8 -8
- package/dist/domains/quality-assessment/coverage-report-event.d.ts +25 -0
- package/dist/domains/quality-assessment/coverage-report-event.js +36 -0
- package/dist/domains/quality-assessment/evidence-sufficiency.d.ts +57 -0
- package/dist/domains/quality-assessment/evidence-sufficiency.js +97 -0
- package/dist/domains/quality-assessment/index.d.ts +1 -1
- package/dist/domains/quality-assessment/index.js +1 -1
- package/dist/domains/quality-assessment/plugin.js +8 -8
- package/dist/domains/quality-assessment/quality-evidence.d.ts +50 -2
- package/dist/domains/quality-assessment/quality-evidence.js +90 -8
- package/dist/domains/quality-assessment/services/quality-analyzer.js +13 -9
- package/dist/mcp/bundle.js +456 -451
- package/dist/mcp/handlers/domain-handler-configs.d.ts +18 -1
- package/dist/mcp/handlers/domain-handler-configs.js +42 -4
- package/dist/mcp/handlers/handler-factory.js +3 -0
- package/dist/mcp/handlers/wrapped-domain-handlers.js +7 -1
- package/dist/mcp/protocol-server.js +3 -2
- package/dist/mcp/tools/coverage-analysis/index.js +1 -0
- package/dist/mcp/types.d.ts +6 -0
- package/dist/shared/events/domain-events.d.ts +2 -0
- package/package.json +1 -1
- package/dist/cli/chunks/adapter-T54G3TBK.js +0 -2
- package/dist/cli/chunks/aqe-learning-engine-HLCJJ3JM.js +0 -2
- package/dist/cli/chunks/base-VLD755UU.js +0 -2
- package/dist/cli/chunks/browser-workflow-6M6VLWRF.js +0 -2
- package/dist/cli/chunks/chunk-5XXLWJU7.js +0 -2
- package/dist/cli/chunks/chunk-HEDLZWPM.js +0 -96
- package/dist/cli/chunks/chunk-XKIFNKHV.js +0 -2
- package/dist/cli/chunks/chunk-ZF5JTQEE.js +0 -4
- package/dist/cli/chunks/ci-NGMGB43T.js +0 -82
- package/dist/cli/chunks/client-FUHNNK5O.js +0 -2
- package/dist/cli/chunks/core-handlers-F7TLX4LM.js +0 -2
- package/dist/cli/chunks/coverage-IVKDV236.js +0 -27
- package/dist/cli/chunks/cross-domain-router-EGWPY67O.js +0 -2
- package/dist/cli/chunks/dream-V4QN6OF5.js +0 -2
- package/dist/cli/chunks/heartbeat-scheduler-3N3L6CRM.js +0 -2
- package/dist/cli/chunks/hnsw-adapter-2BXJYDXI.js +0 -2
- package/dist/cli/chunks/hnsw-index-2DLI5OVO.js +0 -2
- package/dist/cli/chunks/hybrid-backend-OW4J65YH.js +0 -2
- package/dist/cli/chunks/impact-analyzer-ZH5I2RG6.js +0 -2
- package/dist/cli/chunks/init-wizard-NIKM3ZOK.js +0 -2
- package/dist/cli/chunks/kernel-2EOSVM6X.js +0 -2
- package/dist/cli/chunks/knowledge-graph-D3BPWNNO.js +0 -2
- package/dist/cli/chunks/llm-router-service-TJPPZFUN.js +0 -2
- package/dist/cli/chunks/load-test-RFT7IDOL.js +0 -2
- package/dist/cli/chunks/memory-backend-O2O4CFKZ.js +0 -2
- package/dist/cli/chunks/memory-handlers-DAEGUDBD.js +0 -2
- package/dist/cli/chunks/pattern-null-store-TUBNXS34.js +0 -2
- package/dist/cli/chunks/protocol-executor-6FQTTO3Y.js +0 -2
- package/dist/cli/chunks/qe-reasoning-bank-TKPND56C.js +0 -2
- package/dist/cli/chunks/quality-46AK277P.js +0 -7
- package/dist/cli/chunks/queen-coordinator-DWMXLPJG.js +0 -2
- package/dist/cli/chunks/router-QIMUYRCC.js +0 -2
- package/dist/cli/chunks/routing-feedback-4OH5ZNF4.js +0 -2
- package/dist/cli/chunks/rvf-dual-writer-S6JBZL54.js +0 -2
- package/dist/cli/chunks/rvf-migration-adapter-TSGMLMYR.js +0 -2
- package/dist/cli/chunks/rvf-native-adapter-Z7QOW47S.js +0 -2
- package/dist/cli/chunks/safe-db-JLOVBJNC.js +0 -2
- package/dist/cli/chunks/schedule-IM6XOBGR.js +0 -2
- package/dist/cli/chunks/scheduler-XL2SVVK5.js +0 -2
- package/dist/cli/chunks/sqlite-persistence-LWMIIC4U.js +0 -2
- package/dist/cli/chunks/unified-memory-F5IJY7W7.js +0 -2
- package/dist/cli/chunks/unified-memory-hnsw-C3WAMAQL.js +0 -2
- package/dist/cli/chunks/unified-persistence-EWXXOTCB.js +0 -2
- package/dist/cli/chunks/visual-security-CKLTAIAB.js +0 -2
- package/dist/cli/chunks/witness-chain-Z6LWFEZS.js +0 -2
- 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
|
|
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
|
-
|
|
61
|
-
|
|
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
|
-
|
|
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
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
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
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
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
|
-
|
|
125
|
-
|
|
186
|
+
threshold,
|
|
187
|
+
includeFileDetails: true,
|
|
188
|
+
measured: coverageData.instrumented,
|
|
126
189
|
});
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
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
|
-
|
|
145
|
-
|
|
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
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
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
|
-
|
|
166
|
-
console.log(chalk.
|
|
281
|
+
else {
|
|
282
|
+
console.log(chalk.dim(' Ghost analysis not available (requires HNSW index)'));
|
|
167
283
|
}
|
|
168
284
|
}
|
|
169
|
-
|
|
170
|
-
console.log(chalk.dim(' Ghost analysis
|
|
285
|
+
catch {
|
|
286
|
+
console.log(chalk.dim(' Ghost analysis skipped (analyzer not initialized)'));
|
|
171
287
|
}
|
|
172
288
|
}
|
|
173
|
-
|
|
174
|
-
|
|
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
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
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
|
-
|
|
198
|
-
|
|
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
|
-
|
|
221
|
-
console.
|
|
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
|
|
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
|
|
57
|
-
|
|
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.
|