agentic-qe 3.15.3 → 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 +139 -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-CYG3PKHH.js → agent-booster-wasm-CCTTGCQS.js} +2 -2
- package/dist/cli/chunks/{agent-handler-WTFYFZKL.js → agent-handler-DHYUF3NX.js} +2 -2
- package/dist/cli/chunks/{agent-memory-branch-G6WE3ZXU.js → agent-memory-branch-642W7CYX.js} +2 -2
- package/dist/cli/chunks/aqe-learning-engine-WP4GCBDT.js +2 -0
- package/dist/cli/chunks/{arena-S72QW44C.js → arena-MUCC7UUN.js} +4 -4
- package/dist/cli/chunks/{arena-ZFXQEVUQ.js → arena-NW2JVAFY.js} +2 -2
- package/dist/cli/chunks/{audit-KPYIEQJ3.js → audit-VKQTZJAA.js} +3 -3
- package/dist/cli/chunks/base-6ORFD62I.js +2 -0
- package/dist/cli/chunks/{better-sqlite3-L2M3TI5D.js → better-sqlite3-7ZUFVWLQ.js} +2 -2
- package/dist/cli/chunks/{brain-handler-FHKLQTB4.js → brain-handler-7LKAWSBI.js} +3 -3
- package/dist/cli/chunks/{branch-enumerator-3BSHOPOK.js → branch-enumerator-HUNXJKM4.js} +2 -2
- package/dist/cli/chunks/{browser-JUIJPL6Y.js → browser-ZSZEYUDP.js} +2 -2
- package/dist/cli/chunks/browser-workflow-PIXGERWP.js +2 -0
- package/dist/cli/chunks/{chunk-VHBZADYK.js → chunk-2KWI3MT3.js} +2 -2
- package/dist/cli/chunks/{chunk-35VDOH4Y.js → chunk-2WFTZSRT.js} +1 -1
- package/dist/cli/chunks/{chunk-UTALYUMW.js → chunk-2XYTS2WY.js} +2 -2
- package/dist/cli/chunks/{chunk-OTTTHNIT.js → chunk-35MDATQE.js} +1 -1
- package/dist/cli/chunks/{chunk-Z7UGEQ4G.js → chunk-3AYYGR6W.js} +1 -1
- package/dist/cli/chunks/{chunk-LPZAB3N2.js → chunk-3DTEQHFB.js} +3 -3
- package/dist/cli/chunks/{chunk-YHZGFWJE.js → chunk-3OAQPN2N.js} +2 -2
- package/dist/cli/chunks/{chunk-PUPEKA2J.js → chunk-3QD7U3FY.js} +2 -2
- package/dist/cli/chunks/{chunk-3Y4GX5FL.js → chunk-3SH23PS3.js} +2 -2
- package/dist/cli/chunks/{chunk-NT6FYFJA.js → chunk-3YASZPLO.js} +2 -2
- package/dist/cli/chunks/{chunk-QVNMTMDJ.js → chunk-3YNP33GB.js} +2 -2
- package/dist/cli/chunks/{chunk-AQTQ24SK.js → chunk-47GEI2LT.js} +3 -3
- package/dist/cli/chunks/{chunk-JJBTM4JO.js → chunk-4AZP7ZCW.js} +2 -2
- package/dist/cli/chunks/{chunk-6W6GZHQA.js → chunk-4PT5KNXL.js} +4 -4
- package/dist/cli/chunks/{chunk-EQGT4VLC.js → chunk-4UXPDV7E.js} +1 -1
- package/dist/cli/chunks/{chunk-SP2JO53K.js → chunk-4XSCZVON.js} +2 -2
- package/dist/cli/chunks/{chunk-DWG4TN6A.js → chunk-5BOZCMXZ.js} +1 -1
- package/dist/cli/chunks/{chunk-PBUWNMZ2.js → chunk-644DFAGS.js} +1 -1
- package/dist/cli/chunks/{chunk-6EQDA4EC.js → chunk-663ZFPUL.js} +2 -2
- package/dist/cli/chunks/{chunk-HU474NXP.js → chunk-6JFGB2JB.js} +1 -1
- package/dist/cli/chunks/{chunk-AS54N3H7.js → chunk-6LG5UEQE.js} +2 -2
- package/dist/cli/chunks/{chunk-3UUMGWHW.js → chunk-6UYN5PHA.js} +4 -4
- package/dist/cli/chunks/{chunk-RQUSJEON.js → chunk-6ZIDZ4TJ.js} +2 -2
- package/dist/cli/chunks/{chunk-P36IODAM.js → chunk-7BIYJRQJ.js} +2 -2
- package/dist/cli/chunks/{chunk-5LEUEWJY.js → chunk-7EZLOC4K.js} +2 -2
- package/dist/cli/chunks/{chunk-EBIMVSPH.js → chunk-7YB2KELI.js} +2 -2
- package/dist/cli/chunks/{chunk-YCGU2LI7.js → chunk-A2WOQO2N.js} +2 -2
- package/dist/cli/chunks/{chunk-HSR53REE.js → chunk-A337MD3C.js} +2 -2
- package/dist/cli/chunks/{chunk-ZJW4HRUA.js → chunk-A5J4XJS6.js} +1 -1
- package/dist/cli/chunks/{chunk-POTVF6BY.js → chunk-AQN5EDBM.js} +1 -1
- package/dist/cli/chunks/{chunk-X335K4SU.js → chunk-AUZXRFOX.js} +2 -2
- package/dist/cli/chunks/{chunk-WI7I6LMM.js → chunk-B2UHTA4Q.js} +1 -1
- package/dist/cli/chunks/{chunk-W7EHNX3Y.js → chunk-BBL6YXD3.js} +2 -2
- package/dist/cli/chunks/chunk-BJ5P4IV2.js +2 -0
- package/dist/cli/chunks/{chunk-RDTR43YN.js → chunk-BMWAWZAN.js} +2 -2
- package/dist/cli/chunks/chunk-BO4PKNYP.js +102 -0
- package/dist/cli/chunks/{chunk-KGS6H2HB.js → chunk-BY646JOM.js} +2 -2
- package/dist/cli/chunks/{chunk-PPA53NJB.js → chunk-BYXNHGQC.js} +2 -2
- package/dist/cli/chunks/{chunk-RRSZ27A7.js → chunk-BZFT4QDQ.js} +2 -2
- package/dist/cli/chunks/{chunk-M3ACHBC7.js → chunk-CFPR24YK.js} +2 -2
- package/dist/cli/chunks/{chunk-SRDECRTL.js → chunk-CQMHDAJS.js} +2 -2
- package/dist/cli/chunks/{chunk-WW4RJ6BH.js → chunk-CR2JUANW.js} +2 -2
- package/dist/cli/chunks/{chunk-QSVNVDA5.js → chunk-CXOXUBYU.js} +1 -1
- package/dist/cli/chunks/chunk-D3G2NN7F.js +741 -0
- package/dist/cli/chunks/{chunk-RGD2CG23.js → chunk-DEGWCUMY.js} +2 -2
- package/dist/cli/chunks/{chunk-AEL4XJGJ.js → chunk-DFPL5N3Q.js} +2 -2
- package/dist/cli/chunks/{chunk-FTUNC4EI.js → chunk-DL5JENWD.js} +3 -3
- package/dist/cli/chunks/{chunk-DH5NWHH2.js → chunk-DLY4YEN3.js} +2 -2
- package/dist/cli/chunks/{chunk-V5NYGDSX.js → chunk-DPV33C77.js} +2 -2
- package/dist/cli/chunks/{chunk-A5H7TF7C.js → chunk-DPYDUKVZ.js} +2 -2
- package/dist/cli/chunks/{chunk-4JVVVKAX.js → chunk-DTJODGCE.js} +2 -2
- package/dist/cli/chunks/{chunk-6AKJ73X3.js → chunk-DWZI3IVB.js} +2 -2
- package/dist/cli/chunks/{chunk-7UUSV2SK.js → chunk-DXVZBJE4.js} +1 -1
- package/dist/cli/chunks/{chunk-FPFGN2Z5.js → chunk-E4VIVMDL.js} +2 -2
- package/dist/cli/chunks/{chunk-GPZH6OPP.js → chunk-EAYQCBXL.js} +3 -3
- package/dist/cli/chunks/{chunk-7SWHW5AC.js → chunk-EOR3RECZ.js} +20 -20
- package/dist/cli/chunks/chunk-ERGWWI4Y.js +3 -0
- package/dist/cli/chunks/{chunk-XXW4KFBB.js → chunk-EUEHBERE.js} +1 -1
- package/dist/cli/chunks/{chunk-VUBLJBHQ.js → chunk-EVCFUYYK.js} +2 -2
- package/dist/cli/chunks/{chunk-YQ3ZW47V.js → chunk-FBEXG4HD.js} +2 -2
- package/dist/cli/chunks/{chunk-HV3ZVUHO.js → chunk-FE3AIZI6.js} +1 -1
- package/dist/cli/chunks/{chunk-TBVPNN65.js → chunk-FHUJCVT3.js} +2 -2
- package/dist/cli/chunks/{chunk-3ZTBV6M3.js → chunk-FNAYDITO.js} +1 -1
- package/dist/cli/chunks/{chunk-JVQK6NGI.js → chunk-FQKEZVN6.js} +2 -2
- package/dist/cli/chunks/{chunk-MUSYQF53.js → chunk-FWYJ6UDX.js} +2 -2
- package/dist/cli/chunks/{chunk-QUXX2DP7.js → chunk-GGDKOJVF.js} +2 -2
- package/dist/cli/chunks/{chunk-VRT736E3.js → chunk-GKPRECLL.js} +2 -2
- package/dist/cli/chunks/{chunk-3MNKYCLH.js → chunk-GRIPCYW5.js} +1 -1
- package/dist/cli/chunks/{chunk-DE3QNPTG.js → chunk-GTSOFCMQ.js} +1 -1
- package/dist/cli/chunks/{chunk-2MEWIXW4.js → chunk-HBYQYGXP.js} +2 -2
- package/dist/cli/chunks/{chunk-RWLOERKK.js → chunk-HGBJ2QQ4.js} +2 -2
- package/dist/cli/chunks/{chunk-4IYHYHTG.js → chunk-HIUNCO2W.js} +2 -2
- package/dist/cli/chunks/{chunk-WSUYEVSY.js → chunk-HLFDC4SF.js} +1 -1
- package/dist/cli/chunks/{chunk-OKNMZLGB.js → chunk-HPLMX62I.js} +2 -2
- package/dist/cli/chunks/{chunk-Z7JPWXW2.js → chunk-IHFUEPZH.js} +2 -2
- package/dist/cli/chunks/{chunk-2TBHPYOU.js → chunk-IJ2EXSMO.js} +2 -2
- package/dist/cli/chunks/{chunk-SKHP5WUP.js → chunk-IJOFZBXD.js} +2 -2
- package/dist/cli/chunks/{chunk-YW4GM36K.js → chunk-JANLATHN.js} +2 -2
- package/dist/cli/chunks/{chunk-BDKQSEEY.js → chunk-JCC7QEKZ.js} +1 -1
- package/dist/cli/chunks/{chunk-7PDC4SKR.js → chunk-JI77KJP7.js} +1 -1
- package/dist/cli/chunks/{chunk-LEB6O2IN.js → chunk-JNMUVBAJ.js} +2 -2
- package/dist/cli/chunks/{chunk-ZI6NJEBY.js → chunk-JYY7AYGA.js} +1 -1
- package/dist/cli/chunks/{chunk-ASUXS4N4.js → chunk-KHCALIFP.js} +2 -2
- package/dist/cli/chunks/{chunk-ED5HUPUR.js → chunk-KJ3KBP24.js} +2 -2
- package/dist/cli/chunks/{chunk-YTRGMILO.js → chunk-KZVJW2SD.js} +2 -2
- package/dist/cli/chunks/chunk-L336HFFE.js +2 -0
- package/dist/cli/chunks/{chunk-GJB3LPCS.js → chunk-L375O3CZ.js} +2 -2
- package/dist/cli/chunks/{chunk-WQZBKLAG.js → chunk-L6SVCNXK.js} +1 -1
- package/dist/cli/chunks/{chunk-YGKU2QRC.js → chunk-LNO5IWGH.js} +1 -1
- package/dist/cli/chunks/{chunk-APV5UWTU.js → chunk-LRASYSGV.js} +2 -2
- package/dist/cli/chunks/{chunk-HW4V7BVV.js → chunk-MB4VFAJC.js} +2 -2
- package/dist/cli/chunks/{chunk-366IBPZB.js → chunk-MNQ36MAF.js} +2 -2
- package/dist/cli/chunks/{chunk-7TW5UGDP.js → chunk-MQGEZA2A.js} +2 -2
- package/dist/cli/chunks/{chunk-CFXROOIU.js → chunk-MS3Z2CP5.js} +2 -2
- package/dist/cli/chunks/{chunk-4TM5K6EZ.js → chunk-N2TJNIHA.js} +2 -2
- package/dist/cli/chunks/{chunk-DLA3EHKJ.js → chunk-NF6AFIAX.js} +1 -1
- package/dist/cli/chunks/{chunk-2GJJGO5D.js → chunk-NLDFNAOS.js} +2 -2
- package/dist/cli/chunks/{chunk-UCSGZVJX.js → chunk-NMJVG22Z.js} +1 -1
- package/dist/cli/chunks/{chunk-WSND64RL.js → chunk-OGYWWZU7.js} +2 -2
- package/dist/cli/chunks/{chunk-FXTZXZCU.js → chunk-ONCH5AXU.js} +3 -3
- package/dist/cli/chunks/{chunk-M3ONCPSU.js → chunk-OQDC7GCM.js} +2 -2
- package/dist/cli/chunks/{chunk-P6EGRAQG.js → chunk-ORTBRO7F.js} +2 -2
- package/dist/cli/chunks/{chunk-D6PUDLJ4.js → chunk-OU4ZAWCC.js} +2 -2
- package/dist/cli/chunks/{chunk-AOZJ6UUZ.js → chunk-OW42F2TX.js} +2 -2
- package/dist/cli/chunks/{chunk-4N7YXTV3.js → chunk-PCCIZFD7.js} +1 -1
- package/dist/cli/chunks/{chunk-OT6SOPAL.js → chunk-PDPEMBFV.js} +2 -2
- package/dist/cli/chunks/{chunk-A3IQU2ND.js → chunk-PHAQWAEV.js} +2 -2
- package/dist/cli/chunks/{chunk-XV2TIODR.js → chunk-PHP4UJYP.js} +1 -1
- package/dist/cli/chunks/{chunk-POVP6O6K.js → chunk-PURHGLEC.js} +1 -1
- package/dist/cli/chunks/{chunk-5QUOM357.js → chunk-PVAE65B4.js} +1 -1
- package/dist/cli/chunks/{chunk-ZL2GYU7H.js → chunk-QPV3OKX2.js} +2 -2
- package/dist/cli/chunks/{chunk-B23ROYST.js → chunk-QXY3IRBW.js} +21 -21
- package/dist/cli/chunks/chunk-RCXMUEZN.js +3 -0
- package/dist/cli/chunks/{chunk-HVIFA73X.js → chunk-RMJ7PJOS.js} +2 -2
- package/dist/cli/chunks/{chunk-OGARNKLS.js → chunk-RUJLVJDE.js} +2 -2
- package/dist/cli/chunks/{chunk-UGNTLSBL.js → chunk-RUSLEOMC.js} +2 -2
- package/dist/cli/chunks/chunk-SAPIRK2G.js +3 -0
- package/dist/cli/chunks/{chunk-F5BREV2Q.js → chunk-SDWMLT7B.js} +5 -5
- package/dist/cli/chunks/{chunk-A6PII4R4.js → chunk-SEZLYRCS.js} +1 -1
- package/dist/cli/chunks/{chunk-RWQDRPN5.js → chunk-TDLKXLJC.js} +2 -2
- package/dist/cli/chunks/{chunk-YJH7UFA2.js → chunk-U4TV75AC.js} +2 -2
- package/dist/cli/chunks/{chunk-34Y4CIHD.js → chunk-U6OVPMQX.js} +2 -2
- package/dist/cli/chunks/{chunk-L6OSEWOS.js → chunk-UE22ODHN.js} +1 -1
- package/dist/cli/chunks/{chunk-IARE5VGI.js → chunk-UXZEVIFX.js} +1 -1
- package/dist/cli/chunks/{chunk-OMHISPPF.js → chunk-V7GNUVYI.js} +1 -1
- package/dist/cli/chunks/{chunk-HR7RL4PB.js → chunk-VCKDVOPD.js} +2 -2
- package/dist/cli/chunks/{chunk-UZDTRCVU.js → chunk-VH3EB6ZG.js} +2 -2
- package/dist/cli/chunks/{chunk-6V6XVGCL.js → chunk-VLOIEVER.js} +3 -3
- package/dist/cli/chunks/{chunk-XTGVGZ4J.js → chunk-VML4SG3X.js} +3 -3
- package/dist/cli/chunks/{chunk-6TYTBQPV.js → chunk-VRJPH3LG.js} +2 -2
- package/dist/cli/chunks/{chunk-5WOBFN2T.js → chunk-VYDNLQJN.js} +2 -2
- package/dist/cli/chunks/{chunk-U5AVZ3T2.js → chunk-W3ZGNNDV.js} +1 -1
- package/dist/cli/chunks/{chunk-YGEC3PSD.js → chunk-WC47GICZ.js} +2 -2
- package/dist/cli/chunks/{chunk-WLOHTLHO.js → chunk-WLIYWBQR.js} +2 -2
- package/dist/cli/chunks/{chunk-I5VJ3FBC.js → chunk-WN55MNZ2.js} +2 -2
- package/dist/cli/chunks/chunk-WOZIXXY5.js +7 -0
- package/dist/cli/chunks/{chunk-X33LID2T.js → chunk-WR64BKUE.js} +1 -1
- package/dist/cli/chunks/{chunk-VGN46ZT4.js → chunk-WT3JC4A6.js} +2 -2
- package/dist/cli/chunks/{chunk-VOKIUF7I.js → chunk-X52TMBHU.js} +1 -1
- package/dist/cli/chunks/{chunk-ZATQLTYL.js → chunk-XIE7OHML.js} +1 -1
- package/dist/cli/chunks/{chunk-BO43BGHX.js → chunk-XNEEYXR2.js} +2 -2
- package/dist/cli/chunks/{chunk-KCBCYF7M.js → chunk-XNHB6TLC.js} +2 -2
- package/dist/cli/chunks/{chunk-VX7CQUO7.js → chunk-XQRE2HWM.js} +2 -2
- package/dist/cli/chunks/{chunk-CNQUU6CF.js → chunk-Y2E3IJ53.js} +2 -2
- package/dist/cli/chunks/{chunk-2M75CW5Q.js → chunk-Y2WMPEUP.js} +2 -2
- package/dist/cli/chunks/{chunk-WTMLRMKW.js → chunk-Y7GPLOXB.js} +2 -2
- package/dist/cli/chunks/{chunk-O66D4NEJ.js → chunk-YINFES3E.js} +2 -2
- package/dist/cli/chunks/{chunk-CF3BPD2R.js → chunk-ZLBBX24Q.js} +163 -164
- package/dist/cli/chunks/{chunk-S7D4GD7H.js → chunk-ZT3GUYM5.js} +2 -2
- package/dist/cli/chunks/{chunk-D5V6C3XG.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-DPHTFIGX.js → ci-output-7ZUQI4U6.js} +2 -2
- package/dist/cli/chunks/{circuit-breaker-PQ65VU2M.js → circuit-breaker-ALXKCFAL.js} +2 -2
- package/dist/cli/chunks/{claude-flow-setup-GKHVO7AD.js → claude-flow-setup-RL7K2NI2.js} +2 -2
- package/dist/cli/chunks/client-C3KHVRM6.js +2 -0
- package/dist/cli/chunks/{cline-installer-HWMQZJ64.js → cline-installer-2Z2QQKC3.js} +2 -2
- package/dist/cli/chunks/{code-OTY7BF3D.js → code-QSZTDINQ.js} +4 -4
- package/dist/cli/chunks/{code-index-extractor-FG3TMHHR.js → code-index-extractor-5CGR5D3Y.js} +2 -2
- package/dist/cli/chunks/{codex-installer-63JARKKS.js → codex-installer-7JLSEDE5.js} +2 -2
- package/dist/cli/chunks/{completions-4ZHONFML.js → completions-U4NBSXEB.js} +2 -2
- package/dist/cli/chunks/{complexity-analyzer-FYHTJW5Y.js → complexity-analyzer-WYZD2YSY.js} +2 -2
- package/dist/cli/chunks/{continuedev-installer-ZAWDSUR3.js → continuedev-installer-UPXINJFT.js} +2 -2
- package/dist/cli/chunks/{copilot-installer-5QK565JX.js → copilot-installer-WIVYQRIF.js} +2 -2
- package/dist/cli/chunks/core-handlers-KSQM6Q6S.js +2 -0
- package/dist/cli/chunks/{cost-tracker-AWWMPPBJ.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-3BL7JACV.js → cursor-installer-POM7NGCC.js} +2 -2
- package/dist/cli/chunks/{daemon-R6ULBHHF.js → daemon-HFGKQ6LB.js} +3 -3
- package/dist/cli/chunks/{daemon-OJ624POF.js → daemon-M5TD5Y6T.js} +4 -4
- package/dist/cli/chunks/{dag-attention-scheduler-J6I3LTMY.js → dag-attention-scheduler-HJXM7Q5P.js} +2 -2
- package/dist/cli/chunks/{detect-5Q5W33UR.js → detect-XKQGLZYN.js} +2 -2
- package/dist/cli/chunks/{dist-node-GJNW56NA.js → dist-node-SSKB53QL.js} +2 -2
- package/dist/cli/chunks/{domain-handler-IZQY2G44.js → domain-handler-6BNDHATU.js} +2 -2
- package/dist/cli/chunks/{domain-plugins-PIGO3KI2.js → domain-plugins-DOX54YE3.js} +2 -2
- package/dist/cli/chunks/{domain-transfer-NU3B4FQG.js → domain-transfer-FW4ZX3Z7.js} +2 -2
- package/dist/cli/chunks/dream-MIK2E4UL.js +2 -0
- package/dist/cli/chunks/{embed-and-insert-pattern-5QDDRPWV.js → embed-and-insert-pattern-QST77T2B.js} +2 -2
- package/dist/cli/chunks/{eval-TB5HOAUY.js → eval-K7E4XXBS.js} +2 -2
- package/dist/cli/chunks/{experience-capture-middleware-SIYVLKDE.js → experience-capture-middleware-X66IYSRV.js} +3 -3
- package/dist/cli/chunks/{fast-paths-T7QELS6D.js → fast-paths-5JXXTYAG.js} +2 -2
- package/dist/cli/chunks/{feature-flags-TNZ7ZAJV.js → feature-flags-2CR3CO23.js} +2 -2
- package/dist/cli/chunks/{feature-flags-T3CNNYMJ.js → feature-flags-RB72LHOJ.js} +2 -2
- package/dist/cli/chunks/{file-discovery-M45P2ZCY.js → file-discovery-3NHRUQQB.js} +2 -2
- package/dist/cli/chunks/{fleet-DSBZPHBZ.js → fleet-SDU7QEOA.js} +3 -3
- package/dist/cli/chunks/{gnn-wrapper-EHODCF32.js → gnn-wrapper-AWCFODUV.js} +2 -2
- package/dist/cli/chunks/{heartbeat-handler-V5DBVF7V.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-IYKDYA2F.js → hnsw-legacy-bridge-KRS7SSFM.js} +2 -2
- package/dist/cli/chunks/{hnswlib-node-DKG4LW3X.js → hnswlib-node-OGGCPKPO.js} +2 -2
- package/dist/cli/chunks/{hooks-VKNMAILY.js → hooks-XNRNMUBW.js} +10 -10
- package/dist/cli/chunks/hybrid-backend-FOUHTKAK.js +2 -0
- package/dist/cli/chunks/{hypergraph-engine-AXZVP7A7.js → hypergraph-engine-X35LTXYT.js} +2 -2
- package/dist/cli/chunks/{hypergraph-handler-6EO6JN4Z.js → hypergraph-handler-M6THKAG6.js} +3 -3
- package/dist/cli/chunks/impact-analyzer-GXYVX46O.js +2 -0
- package/dist/cli/chunks/{init-handler-N3NG3RHN.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-JICGAHLM.js → kilocode-installer-TEPR2ZJD.js} +2 -2
- package/dist/cli/chunks/{kiro-installer-VYBFP6ZH.js → kiro-installer-RUKHGDEE.js} +2 -2
- package/dist/cli/chunks/knowledge-graph-E2Z6K5EE.js +2 -0
- package/dist/cli/chunks/{learning-3BHEZEPK.js → learning-BEA26RNA.js} +3 -3
- package/dist/cli/chunks/{llm-router-GPTEZCUN.js → llm-router-7GECMDCP.js} +4 -4
- package/dist/cli/chunks/llm-router-service-YATYFEDD.js +2 -0
- package/dist/cli/chunks/{load-W5BIRPU4.js → load-NTJ4Y4ZR.js} +2 -2
- package/dist/cli/chunks/load-test-LV77JXWA.js +2 -0
- package/dist/cli/chunks/{mcp-EBV4DZPG.js → mcp-4335GTTG.js} +2 -2
- package/dist/cli/chunks/{memory-7F6YYKNL.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-3ZIA2YOL.js → multi-model-executor-T7FYKM6T.js} +2 -2
- package/dist/cli/chunks/{opencode-installer-2XRZUTLR.js → opencode-installer-3USXVT5M.js} +2 -2
- package/dist/cli/chunks/{orchestrator-VSZVJUJW.js → orchestrator-VHUXUYIM.js} +5 -5
- package/dist/cli/chunks/pattern-null-store-TAXMLENP.js +2 -0
- package/dist/cli/chunks/{pattern-usage-recorder-I2IGVHRL.js → pattern-usage-recorder-CMZLPX2K.js} +2 -2
- package/dist/cli/chunks/{pipeline-5G3O6WBY.js → pipeline-BTRZOVSL.js} +2 -2
- package/dist/cli/chunks/{platform-6GUFDIA3.js → platform-2MCRKC25.js} +2 -2
- package/dist/cli/chunks/{plugin-GYXE4CIC.js → plugin-2VAYWAO3.js} +2 -2
- package/dist/cli/chunks/{prime-radiant-advanced-wasm-THX6JLGZ.js → prime-radiant-advanced-wasm-TXFEMBP6.js} +2 -2
- package/dist/cli/chunks/{project-root-QJRBKZQU.js → project-root-CFFPBGPX.js} +2 -2
- package/dist/cli/chunks/protocol-executor-ML76QAVQ.js +2 -0
- package/dist/cli/chunks/{protocol-handler-B54LRU26.js → protocol-handler-DZ26OYVZ.js} +2 -2
- package/dist/cli/chunks/{prove-PCY2WQOD.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-L3KXL6WE.js → quality-gate-ONJB7XU7.js} +3 -3
- package/dist/cli/chunks/queen-coordinator-EWXNIXB6.js +2 -0
- package/dist/cli/chunks/{real-embeddings-N3H523PJ.js → real-embeddings-GZV4VKK4.js} +2 -2
- package/dist/cli/chunks/{ref-validation-6BKDPHZ7.js → ref-validation-HW5Y55ZC.js} +2 -2
- package/dist/cli/chunks/{roocode-installer-NSGGTWXE.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-SRQNUBG3.js → routing-handler-CVHVOQTC.js} +2 -2
- package/dist/cli/chunks/{ruvector-commands-2IGULGDE.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-ZD6WK5CK.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-QULKUBBI.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-JW4EBARW.js → security-7723AZZ4.js} +3 -3
- package/dist/cli/chunks/{shared-rvf-adapter-VQ7NJTGY.js → shared-rvf-adapter-KEQ5CLNI.js} +2 -2
- package/dist/cli/chunks/{shared-rvf-dual-writer-SKTS52HK.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-3N4YJCSY.js → standalone-memory-MHZEEYMK.js} +2 -2
- package/dist/cli/chunks/{status-handler-5BQ2IIDG.js → status-handler-JKXPJ22K.js} +2 -2
- package/dist/cli/chunks/{structural-health-WGYR2RJB.js → structural-health-J4RKCYWF.js} +2 -2
- package/dist/cli/chunks/{sync-R5OKUBTQ.js → sync-EFWXMA2H.js} +2 -2
- package/dist/cli/chunks/{sync-DLKSXTIR.js → sync-PDPORHVN.js} +2 -2
- package/dist/cli/chunks/{task-handler-Z5KNTSUX.js → task-handler-VERADM44.js} +2 -2
- package/dist/cli/chunks/{task-handlers-RZFMYFSC.js → task-handlers-4RUCWUR2.js} +3 -3
- package/dist/cli/chunks/{test-LHWKZJRN.js → test-DMBJFQNL.js} +4 -4
- package/dist/cli/chunks/{test-scheduling-EN7WXUMS.js → test-scheduling-LUPTVGCD.js} +3 -3
- package/dist/cli/chunks/{token-bootstrap-4V3OO4EC.js → token-bootstrap-S346YBVO.js} +2 -2
- package/dist/cli/chunks/{token-usage-PFC2BYBS.js → token-usage-VOA34IKM.js} +2 -2
- package/dist/cli/chunks/{transformers-VZCC4SHC.js → transformers-GU4TYAN5.js} +2 -2
- package/dist/cli/chunks/{tree-sitter-wasm-parser-ZYDQXGKN.js → tree-sitter-wasm-parser-MZPXAH7C.js} +2 -2
- package/dist/cli/chunks/{types-I6AWHZZQ.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-T7SG75PA.js → upgrade-M3ATDRMK.js} +2 -2
- package/dist/cli/chunks/{validate-YLYEHTY3.js → validate-AAP773B3.js} +2 -2
- package/dist/cli/chunks/{validate-swarm-VTLTRUE3.js → validate-swarm-7RGAZX5F.js} +2 -2
- package/dist/cli/chunks/visual-security-L4J7LQWT.js +2 -0
- package/dist/cli/chunks/{web-tree-sitter-JUM7ZY5M.js → web-tree-sitter-GQMRHGGI.js} +2 -2
- package/dist/cli/chunks/{windsurf-installer-4KS2466T.js → windsurf-installer-HG6HF2GF.js} +2 -2
- package/dist/cli/chunks/witness-chain-CDUMX623.js +2 -0
- package/dist/cli/chunks/{witness-chain-E4X6TOCT.js → witness-chain-WKU3ZIBQ.js} +2 -2
- package/dist/cli/chunks/{witness-chain-repair-MB53OZO6.js → witness-chain-repair-WNYH6O4L.js} +2 -2
- package/dist/cli/chunks/{witness-chain-verifier-LBWJHO7Y.js → witness-chain-verifier-Q2KW3QEQ.js} +2 -2
- package/dist/cli/chunks/{witness-key-manager-5IHVMXHJ.js → witness-key-manager-NQ5DAAC4.js} +2 -2
- package/dist/cli/chunks/{workflow-XUQXIRNE.js → workflow-CX6SHFBW.js} +5 -5
- package/dist/cli/chunks/workflow-orchestrator-USJDWVDR.js +2 -0
- package/dist/cli/chunks/{wrappers-YVF5SQUN.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/commands/workflow.js +3 -0
- package/dist/cli/scheduler/persistent-scheduler.d.ts +2 -0
- package/dist/cli/scheduler/persistent-scheduler.js +12 -2
- 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/code-intelligence/services/metric-collector/listing-process-owner.d.ts +3 -0
- package/dist/domains/code-intelligence/services/metric-collector/listing-process-owner.js +57 -0
- package/dist/domains/code-intelligence/services/metric-collector/test-counter.js +124 -36
- 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 +457 -453
- package/dist/mcp/handlers/domain-handler-configs.d.ts +60 -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/services/session-store.js +11 -1
- package/dist/mcp/tools/coverage-analysis/index.js +1 -0
- package/dist/mcp/types.d.ts +24 -0
- package/dist/memory/crdt/convergence-tracker.js +14 -24
- package/dist/memory/crdt/crdt-store.js +15 -0
- package/dist/memory/crdt/lww-register.js +3 -3
- package/dist/memory/crdt/or-set.js +18 -0
- package/dist/planning/goap-planner.js +18 -10
- package/dist/shared/embeddings/embedding-cache.d.ts +3 -3
- package/dist/shared/embeddings/embedding-cache.js +8 -8
- package/dist/shared/embeddings/nomic-embedder.js +9 -6
- package/dist/shared/events/domain-events.d.ts +2 -0
- package/dist/shared/llm/cache.js +1 -1
- package/package.json +1 -1
- package/dist/cli/chunks/adapter-WQSFQES5.js +0 -2
- package/dist/cli/chunks/aqe-learning-engine-TDHBBADE.js +0 -2
- package/dist/cli/chunks/base-CZSB27VO.js +0 -2
- package/dist/cli/chunks/browser-workflow-AEMIS6PA.js +0 -2
- package/dist/cli/chunks/chunk-7IJVCDDC.js +0 -96
- package/dist/cli/chunks/chunk-INVDDFJC.js +0 -2
- package/dist/cli/chunks/chunk-K65X6CQA.js +0 -4
- package/dist/cli/chunks/chunk-MZDUBFLP.js +0 -2
- package/dist/cli/chunks/chunk-QDQLL2QB.js +0 -3
- package/dist/cli/chunks/chunk-QZBFMXO5.js +0 -742
- package/dist/cli/chunks/ci-JPISJ25U.js +0 -82
- package/dist/cli/chunks/client-BS7I637W.js +0 -2
- package/dist/cli/chunks/core-handlers-UG7RMTK5.js +0 -2
- package/dist/cli/chunks/coverage-SMFQEGKE.js +0 -27
- package/dist/cli/chunks/cross-domain-router-NX7F6TOF.js +0 -2
- package/dist/cli/chunks/dream-GYEH57FW.js +0 -2
- package/dist/cli/chunks/heartbeat-scheduler-4TJ3T7LR.js +0 -2
- package/dist/cli/chunks/hnsw-adapter-PHFK4EAP.js +0 -2
- package/dist/cli/chunks/hnsw-index-434XDDBH.js +0 -2
- package/dist/cli/chunks/hybrid-backend-DYVJQENQ.js +0 -2
- package/dist/cli/chunks/impact-analyzer-CBAST6M2.js +0 -2
- package/dist/cli/chunks/init-wizard-DWIJW7HY.js +0 -2
- package/dist/cli/chunks/kernel-AQGCS4X2.js +0 -2
- package/dist/cli/chunks/knowledge-graph-2ICXFUUV.js +0 -2
- package/dist/cli/chunks/llm-router-service-C47RGTH6.js +0 -2
- package/dist/cli/chunks/load-test-LRDAW3N6.js +0 -2
- package/dist/cli/chunks/memory-backend-UFBAYPQ6.js +0 -2
- package/dist/cli/chunks/memory-handlers-OGLJHAAJ.js +0 -2
- package/dist/cli/chunks/pattern-null-store-27FCITT3.js +0 -2
- package/dist/cli/chunks/protocol-executor-XWXXTMEW.js +0 -2
- package/dist/cli/chunks/qe-reasoning-bank-3RMYXENE.js +0 -2
- package/dist/cli/chunks/quality-LPVDZC7U.js +0 -7
- package/dist/cli/chunks/queen-coordinator-AS6DZ7UJ.js +0 -2
- package/dist/cli/chunks/router-OVNLNGHO.js +0 -2
- package/dist/cli/chunks/routing-feedback-TBOWEB6H.js +0 -2
- package/dist/cli/chunks/rvf-dual-writer-YJYRCYGT.js +0 -2
- package/dist/cli/chunks/rvf-migration-adapter-VMRQ2SFO.js +0 -2
- package/dist/cli/chunks/rvf-native-adapter-B75L3ALW.js +0 -2
- package/dist/cli/chunks/safe-db-CRQHMCV6.js +0 -2
- package/dist/cli/chunks/schedule-L3DKJRXU.js +0 -2
- package/dist/cli/chunks/scheduler-VRHYUGY5.js +0 -2
- package/dist/cli/chunks/sqlite-persistence-JVAZETTL.js +0 -2
- package/dist/cli/chunks/unified-memory-WOOCCIUM.js +0 -2
- package/dist/cli/chunks/unified-memory-hnsw-PDDHFLUB.js +0 -2
- package/dist/cli/chunks/unified-persistence-6ETD3JSC.js +0 -2
- package/dist/cli/chunks/visual-security-O4OT2YPY.js +0 -2
- package/dist/cli/chunks/witness-chain-67JHPDCN.js +0 -2
- package/dist/cli/chunks/workflow-orchestrator-ZVFSNRYZ.js +0 -2
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* - QEGNNEmbeddingIndex: Code graph embeddings with HNSW for fast similarity search
|
|
7
7
|
* - QESONA: Learns and adapts code patterns for improved intelligence
|
|
8
8
|
*/
|
|
9
|
-
import {
|
|
9
|
+
import { resolveProjectRootFromPaths } from './project-root-resolver.js';
|
|
10
10
|
import { LoggerFactory } from '../../logging/index.js';
|
|
11
11
|
import { v4 as uuidv4 } from 'uuid';
|
|
12
12
|
import { err } from '../../shared/types/index.js';
|
|
@@ -300,11 +300,14 @@ export class CodeIntelligenceCoordinator extends BaseDomainCoordinator {
|
|
|
300
300
|
this.updateWorkflowProgress(workflowId, 60);
|
|
301
301
|
// V3: Collect real project metrics using actual tooling (Phase 5)
|
|
302
302
|
if (this.config.enableMetricCollector && this.metricCollector && request.paths.length > 0) {
|
|
303
|
-
// Determine project root from
|
|
304
|
-
const projectPath = this.getProjectRootFromPaths(request.paths);
|
|
303
|
+
// Determine project root from the caller's target (or the indexed paths)
|
|
304
|
+
const projectPath = this.getProjectRootFromPaths(request.paths, request.target);
|
|
305
305
|
if (projectPath) {
|
|
306
306
|
await this.collectProjectMetrics(projectPath);
|
|
307
307
|
}
|
|
308
|
+
else {
|
|
309
|
+
logger.debug('Skipping project metrics: no project root resolved (filesystem root or no paths)');
|
|
310
|
+
}
|
|
308
311
|
}
|
|
309
312
|
this.updateWorkflowProgress(workflowId, 70);
|
|
310
313
|
// Index content for semantic search
|
|
@@ -941,36 +944,11 @@ export class CodeIntelligenceCoordinator extends BaseDomainCoordinator {
|
|
|
941
944
|
return this.metricCollector;
|
|
942
945
|
}
|
|
943
946
|
/**
|
|
944
|
-
* Determine project root from indexed paths
|
|
947
|
+
* Determine project root from indexed paths (nearest marker, bottom-up; #994).
|
|
948
|
+
* Relative paths resolve against the process cwd, matching the CLI/MCP callers.
|
|
945
949
|
*/
|
|
946
|
-
getProjectRootFromPaths(paths) {
|
|
947
|
-
|
|
948
|
-
return null;
|
|
949
|
-
// Get the first path and find the project root
|
|
950
|
-
const firstPath = paths[0];
|
|
951
|
-
// Walk up the path to find package.json, Cargo.toml, go.mod, etc.
|
|
952
|
-
const parts = firstPath.split('/');
|
|
953
|
-
let currentPath = '';
|
|
954
|
-
for (const part of parts) {
|
|
955
|
-
currentPath = currentPath ? `${currentPath}/${part}` : part;
|
|
956
|
-
// Check for common project markers
|
|
957
|
-
const markers = ['package.json', 'Cargo.toml', 'go.mod', 'pyproject.toml', '.git'];
|
|
958
|
-
for (const marker of markers) {
|
|
959
|
-
try {
|
|
960
|
-
const markerPath = `${currentPath}/${marker}`;
|
|
961
|
-
// Synchronous existence check (we're in an async context anyway).
|
|
962
|
-
if (existsSync(markerPath)) {
|
|
963
|
-
return currentPath;
|
|
964
|
-
}
|
|
965
|
-
}
|
|
966
|
-
catch {
|
|
967
|
-
// Continue checking
|
|
968
|
-
}
|
|
969
|
-
}
|
|
970
|
-
}
|
|
971
|
-
// If no marker found, return the parent directory of the first path
|
|
972
|
-
const lastSlash = firstPath.lastIndexOf('/');
|
|
973
|
-
return lastSlash > 0 ? firstPath.substring(0, lastSlash) : firstPath;
|
|
950
|
+
getProjectRootFromPaths(paths, target) {
|
|
951
|
+
return resolveProjectRootFromPaths(paths, { target });
|
|
974
952
|
}
|
|
975
953
|
// ============================================================================
|
|
976
954
|
// V3: Hypergraph Integration for Intelligent Code Analysis (GOAP Action 7)
|
|
@@ -17,6 +17,11 @@ export interface CodeIntelligenceAPI {
|
|
|
17
17
|
}
|
|
18
18
|
export interface IndexRequest {
|
|
19
19
|
paths: string[];
|
|
20
|
+
/**
|
|
21
|
+
* The directory or file the caller asked to index, before it was expanded
|
|
22
|
+
* into `paths`. Used to resolve the project root for metrics (#994).
|
|
23
|
+
*/
|
|
24
|
+
target?: string;
|
|
20
25
|
incremental?: boolean;
|
|
21
26
|
includeTests?: boolean;
|
|
22
27
|
languages?: string[];
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project root resolution for code-intelligence metric collection (#994).
|
|
3
|
+
*
|
|
4
|
+
* `index()` receives an expanded list of files (the CLI walks the target
|
|
5
|
+
* directory first). When the caller also passes the original `target`, the
|
|
6
|
+
* walk starts at the target directory (its parent for a file target), so a `.`
|
|
7
|
+
* at a monorepo root whose source all lives in one package resolves to the
|
|
8
|
+
* root. Without a target we start from the deepest directory that contains
|
|
9
|
+
* every indexed path. Either way we walk UP (bottom-up, using `path.dirname`,
|
|
10
|
+
* so absolute paths and Windows drive roots are handled by the `path` module)
|
|
11
|
+
* and return the NEAREST directory that holds a project marker.
|
|
12
|
+
*
|
|
13
|
+
* Starting from the common directory rather than the first file keeps a stray
|
|
14
|
+
* marker inside one subtree (for example `.agentic-qe/workers/package.json`)
|
|
15
|
+
* from capturing an index that spans the whole project.
|
|
16
|
+
*
|
|
17
|
+
* When no marker exists anywhere up to the filesystem root, the start
|
|
18
|
+
* directory itself is returned (the target, the files' common directory, or a
|
|
19
|
+
* single file's directory). A filesystem or drive root is never returned:
|
|
20
|
+
* measuring `/` would walk the whole disk, so the result is null instead.
|
|
21
|
+
*
|
|
22
|
+
* @module domains/code-intelligence/project-root-resolver
|
|
23
|
+
*/
|
|
24
|
+
import * as path from 'node:path';
|
|
25
|
+
/** Files or directories whose presence marks a project root. */
|
|
26
|
+
export declare const PROJECT_ROOT_MARKERS: readonly string[];
|
|
27
|
+
export interface ResolveProjectRootOptions {
|
|
28
|
+
/** Base directory for relative inputs. Defaults to `process.cwd()`. */
|
|
29
|
+
cwd?: string;
|
|
30
|
+
/** Existence check, injectable for tests. Defaults to `fs.existsSync`. */
|
|
31
|
+
exists?: (p: string) => boolean;
|
|
32
|
+
/** Directory check, injectable for tests. Defaults to `fs.statSync(...).isDirectory()`. */
|
|
33
|
+
isDirectory?: (p: string) => boolean;
|
|
34
|
+
/** Path implementation. Defaults to the platform `path`; tests pass `path.win32`. */
|
|
35
|
+
pathImpl?: path.PlatformPath;
|
|
36
|
+
/**
|
|
37
|
+
* The directory (or file) the caller asked to index, before expansion. When
|
|
38
|
+
* set, the walk starts here instead of at the common directory of `paths`.
|
|
39
|
+
*/
|
|
40
|
+
target?: string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Resolve the project root for a set of indexed paths.
|
|
44
|
+
*
|
|
45
|
+
* @param paths - Files and/or directories, absolute or relative to `options.cwd`
|
|
46
|
+
* @returns Absolute project root, or null when there is nothing to resolve or
|
|
47
|
+
* the result would be a filesystem/drive root
|
|
48
|
+
*/
|
|
49
|
+
export declare function resolveProjectRootFromPaths(paths: readonly string[], options?: ResolveProjectRootOptions): string | null;
|
|
50
|
+
//# sourceMappingURL=project-root-resolver.d.ts.map
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project root resolution for code-intelligence metric collection (#994).
|
|
3
|
+
*
|
|
4
|
+
* `index()` receives an expanded list of files (the CLI walks the target
|
|
5
|
+
* directory first). When the caller also passes the original `target`, the
|
|
6
|
+
* walk starts at the target directory (its parent for a file target), so a `.`
|
|
7
|
+
* at a monorepo root whose source all lives in one package resolves to the
|
|
8
|
+
* root. Without a target we start from the deepest directory that contains
|
|
9
|
+
* every indexed path. Either way we walk UP (bottom-up, using `path.dirname`,
|
|
10
|
+
* so absolute paths and Windows drive roots are handled by the `path` module)
|
|
11
|
+
* and return the NEAREST directory that holds a project marker.
|
|
12
|
+
*
|
|
13
|
+
* Starting from the common directory rather than the first file keeps a stray
|
|
14
|
+
* marker inside one subtree (for example `.agentic-qe/workers/package.json`)
|
|
15
|
+
* from capturing an index that spans the whole project.
|
|
16
|
+
*
|
|
17
|
+
* When no marker exists anywhere up to the filesystem root, the start
|
|
18
|
+
* directory itself is returned (the target, the files' common directory, or a
|
|
19
|
+
* single file's directory). A filesystem or drive root is never returned:
|
|
20
|
+
* measuring `/` would walk the whole disk, so the result is null instead.
|
|
21
|
+
*
|
|
22
|
+
* @module domains/code-intelligence/project-root-resolver
|
|
23
|
+
*/
|
|
24
|
+
import { existsSync, statSync } from 'node:fs';
|
|
25
|
+
import * as path from 'node:path';
|
|
26
|
+
/** Files or directories whose presence marks a project root. */
|
|
27
|
+
export const PROJECT_ROOT_MARKERS = Object.freeze([
|
|
28
|
+
'package.json',
|
|
29
|
+
'Cargo.toml',
|
|
30
|
+
'go.mod',
|
|
31
|
+
'pyproject.toml',
|
|
32
|
+
'.git',
|
|
33
|
+
]);
|
|
34
|
+
function defaultIsDirectory(p) {
|
|
35
|
+
try {
|
|
36
|
+
return statSync(p).isDirectory();
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/** True when `child` is `parent` or lies inside it. */
|
|
43
|
+
function isWithin(p, child, parent) {
|
|
44
|
+
const rel = p.relative(parent, child);
|
|
45
|
+
return rel === '' || (!rel.startsWith('..') && !p.isAbsolute(rel));
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Deepest directory containing every input directory, or null when the inputs
|
|
49
|
+
* share no ancestor (for example different Windows drives).
|
|
50
|
+
*/
|
|
51
|
+
function commonAncestor(p, dirs) {
|
|
52
|
+
let common = dirs[0];
|
|
53
|
+
for (const dir of dirs.slice(1)) {
|
|
54
|
+
while (!isWithin(p, dir, common)) {
|
|
55
|
+
const parent = p.dirname(common);
|
|
56
|
+
if (parent === common)
|
|
57
|
+
return null;
|
|
58
|
+
common = parent;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return common;
|
|
62
|
+
}
|
|
63
|
+
/** Walk from `startDir` up to the filesystem root; return the nearest marker directory. */
|
|
64
|
+
function findNearestMarkerDir(p, startDir, exists) {
|
|
65
|
+
let current = startDir;
|
|
66
|
+
for (;;) {
|
|
67
|
+
for (const marker of PROJECT_ROOT_MARKERS) {
|
|
68
|
+
try {
|
|
69
|
+
if (exists(p.join(current, marker)))
|
|
70
|
+
return current;
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
// Unreadable entry: keep checking the remaining markers.
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
const parent = p.dirname(current);
|
|
77
|
+
if (parent === current)
|
|
78
|
+
return null;
|
|
79
|
+
current = parent;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Resolve the project root for a set of indexed paths.
|
|
84
|
+
*
|
|
85
|
+
* @param paths - Files and/or directories, absolute or relative to `options.cwd`
|
|
86
|
+
* @returns Absolute project root, or null when there is nothing to resolve or
|
|
87
|
+
* the result would be a filesystem/drive root
|
|
88
|
+
*/
|
|
89
|
+
export function resolveProjectRootFromPaths(paths, options = {}) {
|
|
90
|
+
const usable = paths.filter((p) => typeof p === 'string' && p.length > 0);
|
|
91
|
+
const target = typeof options.target === 'string' && options.target.length > 0 ? options.target : undefined;
|
|
92
|
+
if (usable.length === 0 && !target)
|
|
93
|
+
return null;
|
|
94
|
+
const p = options.pathImpl ?? path;
|
|
95
|
+
const cwd = options.cwd ?? process.cwd();
|
|
96
|
+
const exists = options.exists ?? existsSync;
|
|
97
|
+
const isDirectory = options.isDirectory ?? defaultIsDirectory;
|
|
98
|
+
// A directory contributes itself; a file contributes its parent directory.
|
|
99
|
+
const dirOf = (input) => {
|
|
100
|
+
const abs = p.resolve(cwd, input);
|
|
101
|
+
return isDirectory(abs) ? abs : p.dirname(abs);
|
|
102
|
+
};
|
|
103
|
+
let start;
|
|
104
|
+
if (target) {
|
|
105
|
+
// The caller's own target wins over the expanded file list: a `.` at a
|
|
106
|
+
// monorepo root whose source all lives in packages/a is still the root.
|
|
107
|
+
start = dirOf(target);
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
const dirs = usable.map(dirOf);
|
|
111
|
+
// Inputs on different roots (Windows drives): use the first path's directory.
|
|
112
|
+
start = commonAncestor(p, dirs) ?? dirs[0];
|
|
113
|
+
}
|
|
114
|
+
const root = findNearestMarkerDir(p, start, exists) ?? start;
|
|
115
|
+
// Never measure a whole filesystem / drive root (review N1).
|
|
116
|
+
return isFilesystemRoot(p, root) ? null : root;
|
|
117
|
+
}
|
|
118
|
+
function isFilesystemRoot(p, dir) {
|
|
119
|
+
return p.parse(dir).root === dir || p.dirname(dir) === dir;
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=project-root-resolver.js.map
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Own detached listing subprocesses until completion or caller termination.
|
|
3
|
+
* Normal attempt completion removes the handlers; interrupted callers must
|
|
4
|
+
* synchronously kill every owned group before deleting listing artifacts.
|
|
5
|
+
*/
|
|
6
|
+
import { rmSync } from 'node:fs';
|
|
7
|
+
const owners = new Set();
|
|
8
|
+
const signals = ['SIGINT', 'SIGTERM', 'SIGHUP'];
|
|
9
|
+
function removeHandlers() {
|
|
10
|
+
process.removeListener('exit', cleanup);
|
|
11
|
+
for (const signal of signals)
|
|
12
|
+
process.removeListener(signal, signalHandlers[signal]);
|
|
13
|
+
}
|
|
14
|
+
function cleanup() {
|
|
15
|
+
const pending = [...owners];
|
|
16
|
+
owners.clear();
|
|
17
|
+
for (const owner of pending) {
|
|
18
|
+
try {
|
|
19
|
+
owner.stopTree();
|
|
20
|
+
}
|
|
21
|
+
catch { /* Continue terminating other owned trees. */ }
|
|
22
|
+
}
|
|
23
|
+
for (const directory of new Set(pending.map(owner => owner.directory))) {
|
|
24
|
+
try {
|
|
25
|
+
rmSync(directory, { recursive: true, force: true });
|
|
26
|
+
}
|
|
27
|
+
catch { /* Best effort during exit. */ }
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function interrupted(signal) {
|
|
31
|
+
cleanup();
|
|
32
|
+
removeHandlers();
|
|
33
|
+
// Restore signal termination (including its exit status) instead of swallowing
|
|
34
|
+
// Ctrl-C or converting a requested shutdown into a successful metrics result.
|
|
35
|
+
process.kill(process.pid, signal);
|
|
36
|
+
}
|
|
37
|
+
const signalHandlers = {
|
|
38
|
+
SIGINT: () => interrupted('SIGINT'),
|
|
39
|
+
SIGTERM: () => interrupted('SIGTERM'),
|
|
40
|
+
SIGHUP: () => interrupted('SIGHUP'),
|
|
41
|
+
};
|
|
42
|
+
/** Register a process-tree owner, returning an idempotent release callback. */
|
|
43
|
+
export function ownListingProcess(directory, stopTree) {
|
|
44
|
+
if (owners.size === 0) {
|
|
45
|
+
process.once('exit', cleanup);
|
|
46
|
+
for (const signal of signals)
|
|
47
|
+
process.on(signal, signalHandlers[signal]);
|
|
48
|
+
}
|
|
49
|
+
const owner = { directory, stopTree };
|
|
50
|
+
owners.add(owner);
|
|
51
|
+
return () => {
|
|
52
|
+
owners.delete(owner);
|
|
53
|
+
if (owners.size === 0)
|
|
54
|
+
removeHandlers();
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=listing-process-owner.js.map
|
|
@@ -12,11 +12,14 @@
|
|
|
12
12
|
*
|
|
13
13
|
* @see docs/plans/AQE_V3_IMPROVEMENTS_PLAN.md - Phase 5, RM-003
|
|
14
14
|
*/
|
|
15
|
-
import { execSync, spawnSync } from 'child_process';
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
15
|
+
import { execSync, spawn, spawnSync } from 'child_process';
|
|
16
|
+
import { createRequire } from 'module';
|
|
17
|
+
import { existsSync, mkdtempSync, readFileSync, readdirSync, rmSync, statSync } from 'fs';
|
|
18
|
+
import { tmpdir } from 'os';
|
|
19
|
+
import { join, extname, resolve } from 'path';
|
|
18
20
|
import { DEFAULT_METRIC_CONFIG, } from './interfaces.js';
|
|
19
21
|
import { safeJsonParse } from '../../../../shared/safe-json.js';
|
|
22
|
+
import { ownListingProcess } from './listing-process-owner.js';
|
|
20
23
|
// ============================================================================
|
|
21
24
|
// Main Test Counting Function
|
|
22
25
|
// ============================================================================
|
|
@@ -177,53 +180,138 @@ export function checkTestRunners(projectPath) {
|
|
|
177
180
|
// ============================================================================
|
|
178
181
|
/**
|
|
179
182
|
* Count tests using Vitest
|
|
180
|
-
* Uses `vitest list` for accurate test discovery
|
|
183
|
+
* Uses `vitest list` for accurate test discovery without executing test callbacks.
|
|
181
184
|
*
|
|
182
185
|
* IMPORTANT: We use `vitest list` (not `vitest --run`) because:
|
|
183
186
|
* - `vitest --run` EXECUTES tests, causing OOM in test-of-tests scenarios
|
|
184
|
-
* -
|
|
187
|
+
* - Collection imports test modules but does not run test callbacks
|
|
185
188
|
*/
|
|
186
|
-
function countVitestTests(projectPath, config) {
|
|
189
|
+
async function countVitestTests(projectPath, config) {
|
|
190
|
+
let listingDirectory;
|
|
187
191
|
try {
|
|
188
|
-
|
|
189
|
-
// entry per discovered test in Vitest 4 and 5; --reporter=json does not.
|
|
190
|
-
const output = execSync('npx vitest list --json', {
|
|
191
|
-
cwd: projectPath,
|
|
192
|
-
encoding: 'utf-8',
|
|
193
|
-
timeout: Math.min(config.timeout, 30000), // Cap at 30s for listing
|
|
194
|
-
maxBuffer: 10 * 1024 * 1024, // 10MB buffer (reduced from 50MB)
|
|
195
|
-
});
|
|
192
|
+
let supportsStaticParse = false;
|
|
196
193
|
try {
|
|
197
|
-
const
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
}
|
|
202
|
-
// Preserve compatibility with older structured runner output.
|
|
203
|
-
if (data && typeof data.numTotalTests === 'number') {
|
|
204
|
-
return classifyTests(data.numTotalTests, 'vitest', projectPath);
|
|
205
|
-
}
|
|
194
|
+
const projectRequire = createRequire(resolve(projectPath, 'package.json'));
|
|
195
|
+
const pkg = safeJsonParse(readFileSync(projectRequire.resolve('vitest/package.json'), 'utf-8'));
|
|
196
|
+
const [major, minor] = String(pkg.version).split('.').map(Number);
|
|
197
|
+
supportsStaticParse = major > 4 || (major === 4 && minor >= 1);
|
|
206
198
|
}
|
|
207
199
|
catch {
|
|
208
|
-
//
|
|
200
|
+
// Retain native listing without new flags for unresolved/older runners.
|
|
209
201
|
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
202
|
+
listingDirectory = mkdtempSync(join(tmpdir(), 'aqe-vitest-list-'));
|
|
203
|
+
const readListing = (file) => {
|
|
204
|
+
try {
|
|
205
|
+
if (statSync(file).size > 10 * 1024 * 1024)
|
|
206
|
+
return undefined;
|
|
207
|
+
const data = safeJsonParse(readFileSync(file, 'utf-8'));
|
|
208
|
+
if (Array.isArray(data) && data.every(test => test && typeof test.name === 'string' && typeof test.file === 'string'))
|
|
209
|
+
return data.length;
|
|
210
|
+
if (data && typeof data.numTotalTests === 'number')
|
|
211
|
+
return data.numTotalTests;
|
|
212
|
+
}
|
|
213
|
+
catch { /* Missing/invalid artifacts are not authoritative counts. */ }
|
|
214
|
+
return undefined;
|
|
215
|
+
};
|
|
216
|
+
const listTests = async (mode) => {
|
|
217
|
+
// Separate artifacts prevent a failed attempt from contaminating recovery.
|
|
218
|
+
const file = join(listingDirectory, `${mode}.json`);
|
|
219
|
+
const args = ['vitest', 'list', `--json=${file}`];
|
|
220
|
+
if (mode !== 'legacy')
|
|
221
|
+
args.push(mode === 'static' ? '--static-parse' : '--no-static-parse');
|
|
222
|
+
const succeeded = await new Promise((resolveAttempt) => {
|
|
223
|
+
const windows = process.platform === 'win32';
|
|
224
|
+
// Keep Windows artifact paths in a quoted environment expansion;
|
|
225
|
+
// interpolating a caller-controlled temporary path into cmd is unsafe.
|
|
226
|
+
const flag = mode === 'legacy' ? ''
|
|
227
|
+
: mode === 'static' ? ' --static-parse' : ' --no-static-parse';
|
|
228
|
+
const command = windows ? `npx vitest list --json="%AQE_VITEST_LIST_JSON%"${flag}` : 'npx';
|
|
229
|
+
const child = spawn(command, windows ? [] : args, {
|
|
230
|
+
cwd: projectPath, detached: !windows, shell: windows,
|
|
231
|
+
env: { ...process.env, AQE_VITEST_LIST_JSON: file },
|
|
232
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
233
|
+
});
|
|
234
|
+
let stopped = false;
|
|
235
|
+
let bytes = 0;
|
|
236
|
+
const stopTree = () => {
|
|
237
|
+
if (!child.pid)
|
|
238
|
+
return;
|
|
239
|
+
try {
|
|
240
|
+
if (windows) {
|
|
241
|
+
// Windows has no POSIX process groups; terminate this owned tree.
|
|
242
|
+
spawnSync('taskkill', ['/PID', String(child.pid), '/T', '/F'], {
|
|
243
|
+
stdio: 'ignore', timeout: 5000,
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
process.kill(-child.pid, 'SIGKILL');
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
catch { /* The process group may already have exited. */ }
|
|
251
|
+
};
|
|
252
|
+
const releaseOwnership = ownListingProcess(listingDirectory, stopTree);
|
|
253
|
+
const timer = setTimeout(() => { stopped = true; stopTree(); }, Math.min(config.timeout, 30000));
|
|
254
|
+
const consume = (chunk) => {
|
|
255
|
+
bytes += chunk.length;
|
|
256
|
+
if (bytes > 10 * 1024 * 1024) {
|
|
257
|
+
stopped = true;
|
|
258
|
+
stopTree();
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
child.stdout?.on('data', consume);
|
|
262
|
+
child.stderr?.on('data', consume);
|
|
263
|
+
child.once('error', () => { clearTimeout(timer); stopTree(); releaseOwnership(); resolveAttempt(false); });
|
|
264
|
+
child.once('close', (code) => {
|
|
265
|
+
clearTimeout(timer);
|
|
266
|
+
// A wrapper may exit while its descendants are still importing modules.
|
|
267
|
+
stopTree();
|
|
268
|
+
releaseOwnership();
|
|
269
|
+
resolveAttempt(!stopped && code === 0);
|
|
270
|
+
});
|
|
271
|
+
});
|
|
272
|
+
return succeeded ? readListing(file) : undefined;
|
|
273
|
+
};
|
|
274
|
+
if (!supportsStaticParse) {
|
|
275
|
+
const total = await listTests('legacy');
|
|
276
|
+
return total === undefined ? countTestsByFilePattern(projectPath, config)
|
|
277
|
+
: classifyTests(total, 'vitest', projectPath);
|
|
219
278
|
}
|
|
220
|
-
//
|
|
221
|
-
|
|
279
|
+
// Inspect cheap static discovery before importing project test modules.
|
|
280
|
+
// Above 1,000 static declarations or 100 files, retain the native static
|
|
281
|
+
// count instead of paying the collection timeout for every metrics call.
|
|
282
|
+
const staticTotal = await listTests('static');
|
|
283
|
+
const staticFile = join(listingDirectory, 'static.json');
|
|
284
|
+
let staticFiles = 0;
|
|
285
|
+
if (staticTotal !== undefined) {
|
|
286
|
+
try {
|
|
287
|
+
const data = safeJsonParse(readFileSync(staticFile, 'utf-8'));
|
|
288
|
+
if (Array.isArray(data))
|
|
289
|
+
staticFiles = new Set(data.map(test => test.file)).size;
|
|
290
|
+
}
|
|
291
|
+
catch { /* The validated count remains usable. */ }
|
|
292
|
+
if (staticTotal > 1000 || staticFiles > 100) {
|
|
293
|
+
return classifyTests(staticTotal, 'vitest', projectPath);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
// Collection expands parameterized/computed declarations but imports every
|
|
297
|
+
// test module (with setup/describe side effects). One throwing import loses
|
|
298
|
+
// expansion for the whole suite; preserve its static count when available.
|
|
299
|
+
const collectedTotal = await listTests('collection');
|
|
300
|
+
const total = collectedTotal ?? staticTotal;
|
|
301
|
+
return total === undefined ? countTestsByFilePattern(projectPath, config)
|
|
302
|
+
: classifyTests(total, 'vitest', projectPath);
|
|
222
303
|
}
|
|
223
304
|
catch {
|
|
224
|
-
// vitest list failed (not installed, timeout, etc.) - fall back to file pattern
|
|
225
305
|
return countTestsByFilePattern(projectPath, config);
|
|
226
306
|
}
|
|
307
|
+
finally {
|
|
308
|
+
if (listingDirectory) {
|
|
309
|
+
try {
|
|
310
|
+
rmSync(listingDirectory, { recursive: true, force: true });
|
|
311
|
+
}
|
|
312
|
+
catch { /* Cleanup failure must not change an otherwise valid count. */ }
|
|
313
|
+
}
|
|
314
|
+
}
|
|
227
315
|
}
|
|
228
316
|
/**
|
|
229
317
|
* Count tests using Jest
|
|
@@ -361,7 +361,9 @@ export class CoverageAnalysisCoordinator extends BaseDomainCoordinator {
|
|
|
361
361
|
return err(new Error('Coverage analysis paused: topology is in critical state'));
|
|
362
362
|
}
|
|
363
363
|
const result = await this.coverageAnalyzer.analyze(request);
|
|
364
|
-
|
|
364
|
+
// #1008: subscribers (quality-assessment) store the report as
|
|
365
|
+
// `coverage:latest`. A static estimate must never reach them.
|
|
366
|
+
if (result.success && result.value.measured !== false) {
|
|
365
367
|
// Publish coverage report event
|
|
366
368
|
await this.publishCoverageReport(result.value);
|
|
367
369
|
}
|
|
@@ -613,6 +615,7 @@ export class CoverageAnalysisCoordinator extends BaseDomainCoordinator {
|
|
|
613
615
|
function: report.summary.function,
|
|
614
616
|
statement: report.summary.statement,
|
|
615
617
|
files: report.summary.files,
|
|
618
|
+
measured: true,
|
|
616
619
|
};
|
|
617
620
|
const event = createEvent(CoverageAnalysisEvents.CoverageReportCreated, 'coverage-analysis', payload);
|
|
618
621
|
await this.eventBus.publish(event);
|
|
@@ -19,10 +19,20 @@ export interface AnalyzeCoverageRequest {
|
|
|
19
19
|
coverageData: CoverageData;
|
|
20
20
|
threshold?: number;
|
|
21
21
|
includeFileDetails?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Whether `coverageData` came from instrumentation (#1008). `false` marks a
|
|
24
|
+
* static estimate: it is analyzed and returned, but never persisted as
|
|
25
|
+
* `coverage:latest`, history, per-file coverage or quality evidence.
|
|
26
|
+
* Takes precedence over `coverageData.instrumented`. Fail-closed: when both
|
|
27
|
+
* are absent the data is treated as UNMEASURED and nothing is persisted.
|
|
28
|
+
*/
|
|
29
|
+
measured?: boolean;
|
|
22
30
|
}
|
|
23
31
|
export interface CoverageData {
|
|
24
32
|
files: FileCoverage[];
|
|
25
33
|
summary: CoverageSummary;
|
|
34
|
+
/** Set by producers that know their provenance; `false` = static estimate (#1008). */
|
|
35
|
+
instrumented?: boolean;
|
|
26
36
|
}
|
|
27
37
|
export interface FileCoverage {
|
|
28
38
|
path: string;
|
|
@@ -57,6 +67,11 @@ export interface CoverageReport {
|
|
|
57
67
|
meetsThreshold: boolean;
|
|
58
68
|
delta?: CoverageDelta;
|
|
59
69
|
recommendations: string[];
|
|
70
|
+
/**
|
|
71
|
+
* False when the report was computed from a static estimate (#1008). Such a
|
|
72
|
+
* report was not persisted and must not be published or stored as evidence.
|
|
73
|
+
*/
|
|
74
|
+
measured?: boolean;
|
|
60
75
|
}
|
|
61
76
|
export interface CoverageDelta {
|
|
62
77
|
line: number;
|
|
@@ -60,10 +60,16 @@ export class CoverageAnalysisPlugin extends BaseDomainPlugin {
|
|
|
60
60
|
this._activeAnalyses++;
|
|
61
61
|
this.updateAgentMetrics();
|
|
62
62
|
try {
|
|
63
|
+
// #1008: coverage numbers supplied in a task payload (e.g. MCP
|
|
64
|
+
// `task_submit`) are caller claims, not an instrumented run. Never
|
|
65
|
+
// trust a caller-supplied `measured`/`instrumented` flag: analyze
|
|
66
|
+
// and return the data, but do not persist it as coverage evidence.
|
|
67
|
+
const { instrumented: _claimed, ...callerData } = coverageData;
|
|
63
68
|
return await this.coordinator.analyze({
|
|
64
|
-
coverageData,
|
|
69
|
+
coverageData: callerData,
|
|
65
70
|
threshold: payload.threshold,
|
|
66
71
|
includeFileDetails: payload.includeFileDetails,
|
|
72
|
+
measured: false,
|
|
67
73
|
});
|
|
68
74
|
}
|
|
69
75
|
finally {
|
|
@@ -8,6 +8,13 @@ import { Result } from '../../../shared/types';
|
|
|
8
8
|
import { MemoryBackend } from '../../../kernel/interfaces';
|
|
9
9
|
import { AnalyzeCoverageRequest, CoverageReport, CoverageData, CoverageSummary, CoverageGaps, CoverageGap } from '../interfaces';
|
|
10
10
|
import type { HybridRouter } from '../../../shared/llm';
|
|
11
|
+
/**
|
|
12
|
+
* Whether an analyze request carries instrumented (measured) coverage (#1008).
|
|
13
|
+
* Fail-closed: an explicit `request.measured` wins; otherwise only data a
|
|
14
|
+
* producer marked `instrumented: true` is measured. Anything without
|
|
15
|
+
* provenance is analyzed and returned, but never persisted as evidence.
|
|
16
|
+
*/
|
|
17
|
+
export declare function isMeasuredCoverage(request: AnalyzeCoverageRequest): boolean;
|
|
11
18
|
export interface ICoverageAnalysisService {
|
|
12
19
|
/** Analyze coverage from reports */
|
|
13
20
|
analyze(request: AnalyzeCoverageRequest): Promise<Result<CoverageReport, Error>>;
|