agentic-qe 3.15.2 → 3.15.4
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/helpers/brain-checkpoint.cjs +46 -6
- package/.claude/hooks/aqe-hook.cjs +280 -51
- package/.claude/skills/skills-manifest.json +1 -1
- package/CHANGELOG.md +155 -0
- package/assets/skills/skills-manifest.json +1 -1
- package/dist/adapters/ag-ui/state-delta-cache.js +14 -5
- package/dist/adapters/trajectory-adapter.js +3 -1
- package/dist/cli/bundle.js +5 -5
- package/dist/cli/chunks/adapter-T54G3TBK.js +2 -0
- package/dist/cli/chunks/{agent-booster-wasm-664M7426.js → agent-booster-wasm-MHJBRXMK.js} +2 -2
- package/dist/cli/chunks/{agent-handler-E47ITH45.js → agent-handler-G64SD7J2.js} +2 -2
- package/dist/cli/chunks/{agent-memory-branch-CFWVOJX3.js → agent-memory-branch-G4UXFPKH.js} +2 -2
- package/dist/cli/chunks/aqe-learning-engine-HLCJJ3JM.js +2 -0
- package/dist/cli/chunks/{arena-ZU5CGBGH.js → arena-63M3M6EW.js} +2 -2
- package/dist/cli/chunks/{arena-JM3OY263.js → arena-QJMKYPHS.js} +4 -4
- package/dist/cli/chunks/{audit-HVBRC5AS.js → audit-UDFVTWSX.js} +3 -3
- package/dist/cli/chunks/base-VLD755UU.js +2 -0
- package/dist/cli/chunks/{better-sqlite3-45JLBQX3.js → better-sqlite3-JLX2G56I.js} +2 -2
- package/dist/cli/chunks/{brain-handler-FKDONZYA.js → brain-handler-PWF32LLW.js} +3 -3
- package/dist/cli/chunks/{branch-enumerator-M3DPS3D5.js → branch-enumerator-PB7QWXDP.js} +2 -2
- package/dist/cli/chunks/{browser-TG2TV6NR.js → browser-CYNV2F3U.js} +2 -2
- package/dist/cli/chunks/browser-workflow-6M6VLWRF.js +2 -0
- package/dist/cli/chunks/{chunk-JFFVYCTV.js → chunk-2534PXIV.js} +2 -2
- package/dist/cli/chunks/{chunk-GHXNRF63.js → chunk-2DRMTRBM.js} +2 -2
- package/dist/cli/chunks/{chunk-L77Z3Q6L.js → chunk-2ICC4H6K.js} +2 -2
- package/dist/cli/chunks/{chunk-EATZW5T2.js → chunk-2LL35V3A.js} +2 -2
- package/dist/cli/chunks/{chunk-MEUJWTOX.js → chunk-2MU4WCMQ.js} +2 -2
- package/dist/cli/chunks/{chunk-3RC5UMRJ.js → chunk-33IUCP34.js} +2 -2
- package/dist/cli/chunks/{chunk-UX4BOI6K.js → chunk-35A22AUL.js} +1 -1
- package/dist/cli/chunks/{chunk-Z7XCXHEB.js → chunk-3BDDOFYW.js} +2 -2
- package/dist/cli/chunks/chunk-3C2BFLYC.js +54 -0
- package/dist/cli/chunks/{chunk-56CE7UO4.js → chunk-3MSBVOYW.js} +6 -6
- package/dist/cli/chunks/{chunk-EDRIROCG.js → chunk-3ZIVBTX6.js} +2 -2
- package/dist/cli/chunks/{chunk-CRYZXTSQ.js → chunk-4GLR2S2M.js} +2 -2
- package/dist/cli/chunks/{chunk-DHSGCI6H.js → chunk-54ITMOFM.js} +6 -6
- package/dist/cli/chunks/{chunk-2AWU2E6R.js → chunk-54XTJBHV.js} +1 -1
- package/dist/cli/chunks/{chunk-JSTKSPYT.js → chunk-5B5D5KCV.js} +1 -1
- package/dist/cli/chunks/{chunk-NP2WWIZ3.js → chunk-5GWTJJEO.js} +1 -1
- package/dist/cli/chunks/{chunk-D75HDHX3.js → chunk-5H7MR6HP.js} +1 -1
- package/dist/cli/chunks/{chunk-NWYAV2UG.js → chunk-5SS2Z7JC.js} +2 -2
- package/dist/cli/chunks/chunk-5XXLWJU7.js +2 -0
- package/dist/cli/chunks/{chunk-B4H66LPR.js → chunk-6EHVPFHW.js} +1 -1
- package/dist/cli/chunks/{chunk-HSXLHNSS.js → chunk-6HO3XRXE.js} +2 -2
- package/dist/cli/chunks/chunk-6HTO4BLV.js +2 -0
- package/dist/cli/chunks/{chunk-SVHFSOGT.js → chunk-6QPW4OVH.js} +1 -1
- package/dist/cli/chunks/{chunk-BKZSTZDB.js → chunk-6TMUZGM2.js} +1 -1
- package/dist/cli/chunks/{chunk-2AOAEMJG.js → chunk-73MTUM6F.js} +2 -2
- package/dist/cli/chunks/{chunk-ANI3KPB7.js → chunk-73PCVMGA.js} +2 -2
- package/dist/cli/chunks/{chunk-HADOG2PT.js → chunk-76PRW2KY.js} +2 -2
- package/dist/cli/chunks/{chunk-NL6HKEPR.js → chunk-7INP6HZH.js} +3 -3
- package/dist/cli/chunks/{chunk-QB7H62A4.js → chunk-7X2IVMXN.js} +2 -2
- package/dist/cli/chunks/{chunk-ZVQSIH7Y.js → chunk-A4OPQJ4A.js} +8 -8
- package/dist/cli/chunks/{chunk-SKQTRYE7.js → chunk-ADF6LGHZ.js} +2 -2
- package/dist/cli/chunks/{chunk-5YS2DF5G.js → chunk-AHVN3UQZ.js} +2 -2
- package/dist/cli/chunks/{chunk-3XF7YTQC.js → chunk-AOKSLWON.js} +54 -54
- package/dist/cli/chunks/{chunk-CFDIYZGA.js → chunk-ASKPTGUU.js} +2 -2
- package/dist/cli/chunks/{chunk-LH3H4V7C.js → chunk-B7GJXQD2.js} +2 -2
- package/dist/cli/chunks/{chunk-HOBBYORR.js → chunk-B7J3O2WM.js} +1 -1
- package/dist/cli/chunks/{chunk-J4EJMAH3.js → chunk-BBKLVHDQ.js} +1 -1
- package/dist/cli/chunks/{chunk-WMNVFCKY.js → chunk-BND6M2JX.js} +2 -2
- package/dist/cli/chunks/{chunk-LRVR56PD.js → chunk-BPGFCUDO.js} +1 -1
- package/dist/cli/chunks/{chunk-O6QTCUSL.js → chunk-BY3IL56R.js} +1 -1
- package/dist/cli/chunks/{chunk-3KXKJSKS.js → chunk-BY5PLEPZ.js} +32 -32
- package/dist/cli/chunks/{chunk-DGKPGRBT.js → chunk-BZWZTGMF.js} +2 -2
- package/dist/cli/chunks/{chunk-AS27JP67.js → chunk-C5EN5WB6.js} +1 -1
- package/dist/cli/chunks/chunk-CFXFGQEN.js +15 -0
- package/dist/cli/chunks/{chunk-X4CADOSD.js → chunk-CQ3WSTJ2.js} +2 -2
- package/dist/cli/chunks/{chunk-HFF5ERIE.js → chunk-D7RVZ5C2.js} +2 -2
- package/dist/cli/chunks/{chunk-HS3O763N.js → chunk-DAYMT7TH.js} +21 -21
- package/dist/cli/chunks/{chunk-W6PLBRRS.js → chunk-DBIK4OFX.js} +1 -1
- package/dist/cli/chunks/{chunk-OWZ3F7DJ.js → chunk-DEJM2P5K.js} +1 -1
- package/dist/cli/chunks/{chunk-TC4B5D4Z.js → chunk-DF4Y3HPO.js} +1 -1
- package/dist/cli/chunks/{chunk-7UA7SMM4.js → chunk-DFJGXXCL.js} +1 -1
- package/dist/cli/chunks/{chunk-SZYK5JL7.js → chunk-DPL4ZXTE.js} +1 -1
- package/dist/cli/chunks/{chunk-6WVEICL2.js → chunk-DVE5SM5G.js} +4 -4
- package/dist/cli/chunks/{chunk-QR5ILM34.js → chunk-EGHK6NMH.js} +2 -2
- package/dist/cli/chunks/{chunk-E6GANSLP.js → chunk-EWUFVWRT.js} +2 -2
- package/dist/cli/chunks/{chunk-HBMBO4FD.js → chunk-EY5IUF7U.js} +2 -2
- package/dist/cli/chunks/{chunk-JCB6K24D.js → chunk-FDK2GF4G.js} +2 -2
- package/dist/cli/chunks/{chunk-QZNFZ5IQ.js → chunk-FRBCX46J.js} +2 -2
- package/dist/cli/chunks/{chunk-FCMCQ6OX.js → chunk-G3ZUB3HD.js} +2 -2
- package/dist/cli/chunks/{chunk-QGCFMACF.js → chunk-GAXTPQCZ.js} +2 -2
- package/dist/cli/chunks/{chunk-6O4KVU4K.js → chunk-GJVRQBLI.js} +2 -2
- package/dist/cli/chunks/{chunk-NLY5NUHZ.js → chunk-GLKLEHK3.js} +2 -2
- package/dist/cli/chunks/{chunk-IM67YHDK.js → chunk-HCDTLV5J.js} +2 -2
- package/dist/cli/chunks/{chunk-MY2XZHW3.js → chunk-HEDLZWPM.js} +1 -1
- package/dist/cli/chunks/{chunk-WUSSZ2S6.js → chunk-HEKCN5XQ.js} +2 -2
- package/dist/cli/chunks/{chunk-FRZVLRVR.js → chunk-HFSBONCS.js} +2 -2
- package/dist/cli/chunks/{chunk-IAOB2G3X.js → chunk-HX5KQK7I.js} +2 -2
- package/dist/cli/chunks/{chunk-BT6TZTCL.js → chunk-I43QRLLB.js} +2 -2
- package/dist/cli/chunks/{chunk-QJN5RW2U.js → chunk-I53365HG.js} +3 -3
- package/dist/cli/chunks/{chunk-55T7PDYP.js → chunk-I5A3HGO6.js} +2 -2
- package/dist/cli/chunks/{chunk-AR5V7VNC.js → chunk-I6E4X3L3.js} +1 -1
- package/dist/cli/chunks/chunk-IKWAPHJA.js +2 -0
- package/dist/cli/chunks/{chunk-UKRK3IE3.js → chunk-ISASRHZP.js} +2 -2
- package/dist/cli/chunks/{chunk-IHKRKRAV.js → chunk-J3RNVHDH.js} +1 -1
- package/dist/cli/chunks/{chunk-T75PWWK4.js → chunk-JFQDWAU3.js} +2 -2
- package/dist/cli/chunks/{chunk-3KTAMNKI.js → chunk-JL3TI43V.js} +2 -2
- package/dist/cli/chunks/{chunk-3DCRAW43.js → chunk-K2VUYRMG.js} +2 -2
- package/dist/cli/chunks/{chunk-RIAKRZCZ.js → chunk-KOLHZSEC.js} +2 -2
- package/dist/cli/chunks/{chunk-HXT4XDQO.js → chunk-LGA6J4I4.js} +2 -2
- package/dist/cli/chunks/{chunk-MDDECCAC.js → chunk-LJRZAALA.js} +169 -168
- package/dist/cli/chunks/{chunk-2B2MGJ2W.js → chunk-LOLAEDZD.js} +2 -2
- package/dist/cli/chunks/{chunk-2JEPRQMT.js → chunk-LPSE6DOQ.js} +1 -1
- package/dist/cli/chunks/{chunk-6KEYA4EH.js → chunk-LRTF5RMG.js} +4 -4
- package/dist/cli/chunks/{chunk-CV7E627D.js → chunk-LXYTC62V.js} +2 -2
- package/dist/cli/chunks/{chunk-YYVLMW65.js → chunk-LY53L6NH.js} +2 -2
- package/dist/cli/chunks/{chunk-HMDSBWF6.js → chunk-LZSLJJII.js} +2 -2
- package/dist/cli/chunks/{chunk-IT753IPZ.js → chunk-M6SJALLA.js} +2 -2
- package/dist/cli/chunks/{chunk-GDSLQTJC.js → chunk-MBV57LKC.js} +2 -2
- package/dist/cli/chunks/{chunk-I7J2ESGR.js → chunk-MGH4XIHH.js} +2 -2
- package/dist/cli/chunks/{chunk-Q32UGPWK.js → chunk-MVTUFPM2.js} +2 -2
- package/dist/cli/chunks/{chunk-UZL4JYVW.js → chunk-N6CRIUTO.js} +2 -2
- package/dist/cli/chunks/{chunk-326V7N25.js → chunk-NBMQOP2R.js} +1 -1
- package/dist/cli/chunks/{chunk-ZIKH7U5A.js → chunk-NIJMLEAX.js} +2 -2
- package/dist/cli/chunks/{chunk-MYDZBABD.js → chunk-O7TMY4GS.js} +2 -2
- package/dist/cli/chunks/{chunk-LVDZ25VX.js → chunk-OFQDM73J.js} +2 -2
- package/dist/cli/chunks/{chunk-WBZIOTY6.js → chunk-OG4KHX7S.js} +2 -2
- package/dist/cli/chunks/{chunk-GJTH6VBH.js → chunk-OHH6BUZK.js} +1 -1
- package/dist/cli/chunks/{chunk-T5N2PIPS.js → chunk-OOK6GPJR.js} +2 -2
- package/dist/cli/chunks/{chunk-AXJ75X6I.js → chunk-P7GM3EE7.js} +1 -1
- package/dist/cli/chunks/{chunk-IQB5ZBYO.js → chunk-PB2WSCBW.js} +3 -3
- package/dist/cli/chunks/{chunk-M36DAETL.js → chunk-PCWZCXBD.js} +2 -2
- package/dist/cli/chunks/{chunk-Z3PANQUT.js → chunk-PEA4DVXW.js} +1 -1
- package/dist/cli/chunks/{chunk-WBCE6V2N.js → chunk-PJAXWCFC.js} +1 -1
- package/dist/cli/chunks/{chunk-V67UQRQN.js → chunk-PMXWDTDK.js} +2 -2
- package/dist/cli/chunks/chunk-QIAX3JJB.js +3 -0
- package/dist/cli/chunks/chunk-R47LNH5W.js +2 -0
- package/dist/cli/chunks/{chunk-A6L2OCMO.js → chunk-RA3MI5WK.js} +2 -2
- package/dist/cli/chunks/{chunk-ITM26I6O.js → chunk-RB2SL5GD.js} +2 -2
- package/dist/cli/chunks/{chunk-XQBH3366.js → chunk-RG67RZIX.js} +2 -2
- package/dist/cli/chunks/{chunk-NBV37CEK.js → chunk-RI4JPBZD.js} +2 -2
- package/dist/cli/chunks/{chunk-2Q4Y3VQ6.js → chunk-RJ5CZ7B6.js} +2 -2
- package/dist/cli/chunks/{chunk-ATGIGJSL.js → chunk-RJMBHZYL.js} +1 -1
- package/dist/cli/chunks/{chunk-MOSXT6AO.js → chunk-RWZ4F44Y.js} +2 -2
- package/dist/cli/chunks/{chunk-URWT3EQT.js → chunk-S5D3HCGN.js} +2 -2
- package/dist/cli/chunks/{chunk-KQMCCHPO.js → chunk-SCL2OYN7.js} +2 -2
- package/dist/cli/chunks/{chunk-Y5VPLOA7.js → chunk-SIUUAKCE.js} +1 -1
- package/dist/cli/chunks/{chunk-JIRX6KUR.js → chunk-SJB4KMZS.js} +3 -3
- package/dist/cli/chunks/{chunk-TZH2QAFZ.js → chunk-SOSJFEFB.js} +2 -2
- package/dist/cli/chunks/{chunk-IBAXNCR2.js → chunk-SZWXUG36.js} +2 -2
- package/dist/cli/chunks/{chunk-KTLYL3BS.js → chunk-T3BMCEQR.js} +2 -2
- package/dist/cli/chunks/chunk-TB22Y3WW.js +4 -0
- package/dist/cli/chunks/{chunk-GJ7DON5S.js → chunk-TVQPYP2Z.js} +3 -3
- package/dist/cli/chunks/chunk-U2E5F3VZ.js +14 -0
- package/dist/cli/chunks/{chunk-ZSKQPXRW.js → chunk-UK5HY6LC.js} +1 -1
- package/dist/cli/chunks/{chunk-RO6HAZLV.js → chunk-UORI2CZ4.js} +1 -1
- package/dist/cli/chunks/{chunk-VTGAPHJE.js → chunk-V3NZ23X6.js} +2 -2
- package/dist/cli/chunks/{chunk-W7P7EOJ4.js → chunk-VAXQUD5G.js} +1 -1
- package/dist/cli/chunks/{chunk-EQG3JYSV.js → chunk-VMSO6DMF.js} +2 -2
- package/dist/cli/chunks/{chunk-6UO5YSNN.js → chunk-W3PPYNHF.js} +2 -2
- package/dist/cli/chunks/{chunk-FH6N2LKG.js → chunk-W6TJXK5Y.js} +2 -2
- package/dist/cli/chunks/{chunk-WJ7657IX.js → chunk-WEDVLKRB.js} +2 -2
- package/dist/cli/chunks/{chunk-N653RGT3.js → chunk-WI5AEB7Q.js} +2 -2
- package/dist/cli/chunks/{chunk-W5EKSBS4.js → chunk-WO4NSPLX.js} +2 -2
- package/dist/cli/chunks/{chunk-YH7VOLBP.js → chunk-WW6WUMS7.js} +2 -2
- package/dist/cli/chunks/{chunk-6OL2WES5.js → chunk-WYO5VN2L.js} +1 -1
- package/dist/cli/chunks/{chunk-PZK7O445.js → chunk-X5S5UEM6.js} +2 -2
- package/dist/cli/chunks/{chunk-NKWMTXBL.js → chunk-XHCCH7UC.js} +3 -3
- package/dist/cli/chunks/{chunk-GSC6JXDE.js → chunk-XKIFNKHV.js} +1 -1
- package/dist/cli/chunks/{chunk-FNPZINHV.js → chunk-XZ5Z56OP.js} +1 -1
- package/dist/cli/chunks/{chunk-6XLCFDIB.js → chunk-YQ6BK7QC.js} +2 -2
- package/dist/cli/chunks/{chunk-DNS37AHW.js → chunk-YUWUFYHK.js} +1 -1
- package/dist/cli/chunks/{chunk-YJSKT6G6.js → chunk-YZ2AGC7O.js} +1 -1
- package/dist/cli/chunks/{chunk-5TEPPW4J.js → chunk-Z56QTRRB.js} +2 -2
- package/dist/cli/chunks/{chunk-4MCO43NX.js → chunk-ZAOQIVHG.js} +4 -4
- package/dist/cli/chunks/{chunk-TMYGGYRY.js → chunk-ZF5JTQEE.js} +1 -1
- package/dist/cli/chunks/{chunk-HYWW4A2E.js → chunk-ZKXZTIVF.js} +2 -2
- package/dist/cli/chunks/{chunk-N4MNSEKY.js → chunk-ZP6ANUP7.js} +1 -1
- package/dist/cli/chunks/{chunk-5DFPAJ5O.js → chunk-ZURYZEHX.js} +2 -2
- package/dist/cli/chunks/{ci-JNBOR6FP.js → ci-NGMGB43T.js} +3 -3
- package/dist/cli/chunks/{ci-output-FYNKONEQ.js → ci-output-BMJABAEX.js} +2 -2
- package/dist/cli/chunks/{circuit-breaker-KOIXRDAD.js → circuit-breaker-GYD5CMJQ.js} +2 -2
- package/dist/cli/chunks/{claude-flow-setup-4CO7KHRN.js → claude-flow-setup-MMOYVBVD.js} +2 -2
- package/dist/cli/chunks/client-FUHNNK5O.js +2 -0
- package/dist/cli/chunks/{cline-installer-CMYAPKK5.js → cline-installer-B2SOZ44R.js} +2 -2
- package/dist/cli/chunks/{code-WFIAEP3H.js → code-V3FIRAXD.js} +3 -3
- package/dist/cli/chunks/{code-index-extractor-IYM6HWJN.js → code-index-extractor-CV6A756Z.js} +2 -2
- package/dist/cli/chunks/{codex-installer-DORVWRSU.js → codex-installer-EUC6J47Y.js} +2 -2
- package/dist/cli/chunks/{completions-54VM2MX2.js → completions-DQQIBAHR.js} +2 -2
- package/dist/cli/chunks/{complexity-analyzer-EGZDP5N4.js → complexity-analyzer-HPXMXP5I.js} +2 -2
- package/dist/cli/chunks/{continuedev-installer-4SDVDD4T.js → continuedev-installer-RCIYXH6V.js} +2 -2
- package/dist/cli/chunks/{copilot-installer-7FJQ7PCL.js → copilot-installer-VUH32SHF.js} +2 -2
- package/dist/cli/chunks/core-handlers-F7TLX4LM.js +2 -0
- package/dist/cli/chunks/cost-tracker-YLCKLOAL.js +2 -0
- package/dist/cli/chunks/{coverage-DI5LDRJ7.js → coverage-IVKDV236.js} +3 -3
- package/dist/cli/chunks/cross-domain-router-EGWPY67O.js +2 -0
- package/dist/cli/chunks/{cursor-installer-RTSZP5YD.js → cursor-installer-B42FN62K.js} +2 -2
- package/dist/cli/chunks/{daemon-SP3APEZY.js → daemon-DECQRQII.js} +3 -3
- package/dist/cli/chunks/{daemon-LM7LETPV.js → daemon-IPTOSCHM.js} +4 -4
- package/dist/cli/chunks/{dag-attention-scheduler-C3QBODFE.js → dag-attention-scheduler-RY7CDYSC.js} +2 -2
- package/dist/cli/chunks/{detect-I4RBUFFJ.js → detect-NW53BMJN.js} +2 -2
- package/dist/cli/chunks/{dist-node-PT6TCBCO.js → dist-node-LE6KHXAB.js} +2 -2
- package/dist/cli/chunks/{domain-handler-MJMTMB5X.js → domain-handler-JGXFT4LW.js} +2 -2
- package/dist/cli/chunks/{domain-plugins-Y4A2WYJW.js → domain-plugins-GY3RYKKK.js} +2 -2
- package/dist/cli/chunks/{domain-transfer-DUO42TLA.js → domain-transfer-CGBRXNTC.js} +2 -2
- package/dist/cli/chunks/dream-V4QN6OF5.js +2 -0
- package/dist/cli/chunks/{embed-and-insert-pattern-66ZQK4AI.js → embed-and-insert-pattern-65H4XHWR.js} +2 -2
- package/dist/cli/chunks/{eval-NQ7H27UF.js → eval-YPYIZQUR.js} +2 -2
- package/dist/cli/chunks/{experience-capture-middleware-MHEYPTIG.js → experience-capture-middleware-4JXVF5PL.js} +3 -3
- package/dist/cli/chunks/{fast-paths-YYDGN6ZC.js → fast-paths-HYQTAF2S.js} +2 -2
- package/dist/cli/chunks/{feature-flags-FY4DOYS2.js → feature-flags-HNSAFFX2.js} +2 -2
- package/dist/cli/chunks/{feature-flags-YFGUORHY.js → feature-flags-YACUH6OW.js} +2 -2
- package/dist/cli/chunks/{file-discovery-TOMDY7TK.js → file-discovery-R73BYEXB.js} +2 -2
- package/dist/cli/chunks/{fleet-MO3UCWB4.js → fleet-6M3BP4OO.js} +3 -3
- package/dist/cli/chunks/{gnn-wrapper-SLW4PPXQ.js → gnn-wrapper-QLD7KHXV.js} +2 -2
- package/dist/cli/chunks/{heartbeat-handler-36RFCP4E.js → heartbeat-handler-EZP333X4.js} +4 -4
- package/dist/cli/chunks/heartbeat-scheduler-3N3L6CRM.js +2 -0
- package/dist/cli/chunks/hnsw-adapter-2BXJYDXI.js +2 -0
- package/dist/cli/chunks/hnsw-index-2DLI5OVO.js +2 -0
- package/dist/cli/chunks/{hnsw-legacy-bridge-BJLWBKHE.js → hnsw-legacy-bridge-47CUCSAU.js} +2 -2
- package/dist/cli/chunks/{hnswlib-node-RAYNVJCJ.js → hnswlib-node-SVNYDJZH.js} +2 -2
- package/dist/cli/chunks/{hooks-JMHFWVEQ.js → hooks-6V5LMWP6.js} +10 -10
- package/dist/cli/chunks/hybrid-backend-OW4J65YH.js +2 -0
- package/dist/cli/chunks/{hypergraph-engine-JUDBKPOX.js → hypergraph-engine-L2FOBIFF.js} +2 -2
- package/dist/cli/chunks/{hypergraph-handler-AXTWXOZU.js → hypergraph-handler-DU6Z57EE.js} +3 -3
- package/dist/cli/chunks/impact-analyzer-ZH5I2RG6.js +2 -0
- package/dist/cli/chunks/{init-handler-PARJNZFF.js → init-handler-HETPWU67.js} +6 -6
- package/dist/cli/chunks/init-wizard-NIKM3ZOK.js +2 -0
- package/dist/cli/chunks/kernel-2EOSVM6X.js +2 -0
- package/dist/cli/chunks/{kilocode-installer-22HX2E4V.js → kilocode-installer-NHKYGJ7Q.js} +2 -2
- package/dist/cli/chunks/{kiro-installer-OVPBLY7J.js → kiro-installer-24UK6GGR.js} +2 -2
- package/dist/cli/chunks/knowledge-graph-D3BPWNNO.js +2 -0
- package/dist/cli/chunks/{learning-DWXPJ3R6.js → learning-QLVRZNHT.js} +3 -3
- package/dist/cli/chunks/{llm-router-7PPVVKNG.js → llm-router-XRMI2VMG.js} +4 -4
- package/dist/cli/chunks/llm-router-service-TJPPZFUN.js +2 -0
- package/dist/cli/chunks/{load-VI5XHNZA.js → load-W5UWL5C7.js} +2 -2
- package/dist/cli/chunks/load-test-RFT7IDOL.js +2 -0
- package/dist/cli/chunks/{mcp-UW4Z3Z64.js → mcp-N7ALQ4BL.js} +2 -2
- package/dist/cli/chunks/{memory-UD2KCB5M.js → memory-WV52DLSA.js} +5 -5
- package/dist/cli/chunks/memory-backend-O2O4CFKZ.js +2 -0
- package/dist/cli/chunks/memory-handlers-DAEGUDBD.js +2 -0
- package/dist/cli/chunks/{multi-model-executor-5O4WWU5Z.js → multi-model-executor-3FVTZCSO.js} +2 -2
- package/dist/cli/chunks/{opencode-installer-DTRFDGM7.js → opencode-installer-NTPWGHUW.js} +2 -2
- package/dist/cli/chunks/{orchestrator-ENJIKV6Z.js → orchestrator-ORGJ6VAA.js} +85 -26
- package/dist/cli/chunks/pattern-null-store-TUBNXS34.js +2 -0
- package/dist/cli/chunks/{pattern-usage-recorder-QPNIU5PD.js → pattern-usage-recorder-WWXHUH5U.js} +2 -2
- package/dist/cli/chunks/{pipeline-G3JYDNPE.js → pipeline-ZOKZFXTH.js} +2 -2
- package/dist/cli/chunks/{platform-P4WR6N3D.js → platform-CDNL322F.js} +2 -2
- package/dist/cli/chunks/{plugin-C7763Q5W.js → plugin-ZVLFNZZ4.js} +2 -2
- package/dist/cli/chunks/{prime-radiant-advanced-wasm-DH6R3XSZ.js → prime-radiant-advanced-wasm-FVJDU2JY.js} +2 -2
- package/dist/cli/chunks/{project-root-7DTXDLEG.js → project-root-UCHQH3QL.js} +2 -2
- package/dist/cli/chunks/protocol-executor-6FQTTO3Y.js +2 -0
- package/dist/cli/chunks/{protocol-handler-EODULGOZ.js → protocol-handler-4YBN5R23.js} +2 -2
- package/dist/cli/chunks/{prove-A7G3SIOF.js → prove-BHDHY664.js} +2 -2
- package/dist/cli/chunks/qe-reasoning-bank-TKPND56C.js +2 -0
- package/dist/cli/chunks/{quality-JTURFUX3.js → quality-46AK277P.js} +2 -2
- package/dist/cli/chunks/{quality-gate-M2EI754V.js → quality-gate-WANE7TCN.js} +3 -3
- package/dist/cli/chunks/queen-coordinator-DWMXLPJG.js +2 -0
- package/dist/cli/chunks/{real-embeddings-DI7JMCG7.js → real-embeddings-56MNGJGJ.js} +2 -2
- package/dist/cli/chunks/{ref-validation-MSFMNKDR.js → ref-validation-S7UWXQIP.js} +2 -2
- package/dist/cli/chunks/{roocode-installer-XIMFFHOH.js → roocode-installer-TEYOQYL6.js} +2 -2
- package/dist/cli/chunks/router-QIMUYRCC.js +2 -0
- package/dist/cli/chunks/routing-feedback-4OH5ZNF4.js +2 -0
- package/dist/cli/chunks/{routing-handler-MCDKNBQW.js → routing-handler-KDTLMRWD.js} +2 -2
- package/dist/cli/chunks/{ruvector-commands-OBSYAK2X.js → ruvector-commands-AOUDXCYE.js} +2 -2
- package/dist/cli/chunks/rvf-dual-writer-S6JBZL54.js +2 -0
- package/dist/cli/chunks/rvf-migration-adapter-TSGMLMYR.js +2 -0
- package/dist/cli/chunks/{rvf-migration-coordinator-4DTRIHY6.js → rvf-migration-coordinator-V74MVBHS.js} +2 -2
- package/dist/cli/chunks/rvf-native-adapter-Z7QOW47S.js +2 -0
- package/dist/cli/chunks/{rvf-store-integrity-CWAVMRC4.js → rvf-store-integrity-QI47Y354.js} +2 -2
- package/dist/cli/chunks/safe-db-JLOVBJNC.js +2 -0
- package/dist/cli/chunks/schedule-IM6XOBGR.js +2 -0
- package/dist/cli/chunks/scheduler-XL2SVVK5.js +2 -0
- package/dist/cli/chunks/{security-74TWSO74.js → security-SN6MWOJT.js} +3 -3
- package/dist/cli/chunks/{shared-rvf-adapter-ZHNAGE5H.js → shared-rvf-adapter-2LB56LP4.js} +2 -2
- package/dist/cli/chunks/{shared-rvf-dual-writer-BS5WAVCC.js → shared-rvf-dual-writer-WU7PFKQM.js} +2 -2
- package/dist/cli/chunks/sqlite-persistence-LWMIIC4U.js +2 -0
- package/dist/cli/chunks/{standalone-memory-3HGHTE7S.js → standalone-memory-F6FSRFWC.js} +2 -2
- package/dist/cli/chunks/{status-handler-XWEEGNGH.js → status-handler-DHD5MS4G.js} +2 -2
- package/dist/cli/chunks/{structural-health-TB5JGMVS.js → structural-health-P6HPSQMR.js} +2 -2
- package/dist/cli/chunks/{sync-T4VLBURM.js → sync-LISJGDSE.js} +2 -2
- package/dist/cli/chunks/sync-SNAXAVCN.js +2 -0
- package/dist/cli/chunks/{task-handler-RQ65QKXX.js → task-handler-ZT44NT5Z.js} +2 -2
- package/dist/cli/chunks/{task-handlers-USYWJ4H2.js → task-handlers-R6DQ5324.js} +3 -3
- package/dist/cli/chunks/test-MUFHR4JQ.js +34 -0
- package/dist/cli/chunks/test-scheduling-TAUSLZJP.js +15 -0
- package/dist/cli/chunks/token-bootstrap-UGRH7OPU.js +2 -0
- package/dist/cli/chunks/{token-usage-CISTB5K5.js → token-usage-IX65ECBR.js} +2 -2
- package/dist/cli/chunks/{transformers-C7LV763N.js → transformers-QKPSVW2W.js} +2 -2
- package/dist/cli/chunks/{tree-sitter-wasm-parser-P26JC3YV.js → tree-sitter-wasm-parser-Z7PPA2JO.js} +2 -2
- package/dist/cli/chunks/{types-YMVMKIWB.js → types-ULNNGGGH.js} +2 -2
- package/dist/cli/chunks/unified-memory-F5IJY7W7.js +2 -0
- package/dist/cli/chunks/unified-memory-hnsw-C3WAMAQL.js +2 -0
- package/dist/cli/chunks/unified-persistence-EWXXOTCB.js +2 -0
- package/dist/cli/chunks/{upgrade-U2REOPAW.js → upgrade-ECI3YUYA.js} +2 -2
- package/dist/cli/chunks/{validate-NDTCKN7P.js → validate-3JKRUW2S.js} +2 -2
- package/dist/cli/chunks/{validate-swarm-OJUGVH5Q.js → validate-swarm-LZWANCIE.js} +2 -2
- package/dist/cli/chunks/visual-security-CKLTAIAB.js +2 -0
- package/dist/cli/chunks/{web-tree-sitter-2CLRSA7K.js → web-tree-sitter-N5V4A6XG.js} +2 -2
- package/dist/cli/chunks/{windsurf-installer-DSUJJ4PG.js → windsurf-installer-5TBM5B3C.js} +2 -2
- package/dist/cli/chunks/{witness-chain-TEGL4ZWB.js → witness-chain-MFP3HBWQ.js} +2 -2
- package/dist/cli/chunks/witness-chain-Z6LWFEZS.js +2 -0
- package/dist/cli/chunks/witness-chain-repair-5QWRFVUK.js +2 -0
- package/dist/cli/chunks/{witness-chain-verifier-SPXKFC67.js → witness-chain-verifier-SRAT7LVY.js} +2 -2
- package/dist/cli/chunks/{witness-key-manager-EALOV4OV.js → witness-key-manager-FYZXQTLJ.js} +2 -2
- package/dist/cli/chunks/{workflow-PYI6HCAG.js → workflow-M7TUYYXY.js} +5 -5
- package/dist/cli/chunks/workflow-orchestrator-OFTAR2NA.js +2 -0
- package/dist/cli/chunks/wrappers-COU73OQ6.js +2 -0
- package/dist/cli/commands/test.js +30 -12
- 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/generated-test-writer.d.ts +35 -0
- package/dist/cli/utils/generated-test-writer.js +44 -0
- package/dist/context/compiler.js +4 -1
- package/dist/coordination/consensus/providers/ollama-provider.js +16 -27
- package/dist/coordination/consensus/providers/openrouter-provider.js +13 -24
- package/dist/coordination/handlers/test-execution-handlers.js +4 -2
- package/dist/coordination/protocols/defect-investigation.js +4 -1
- 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 +127 -39
- package/dist/domains/coverage-analysis/services/gap-detector.js +3 -1
- package/dist/domains/learning-optimization/services/learning-coordinator.js +4 -2
- package/dist/domains/test-execution/services/flaky-detector.js +8 -2
- package/dist/domains/test-execution/services/retry-handler.js +23 -20
- package/dist/domains/test-execution/services/test-executor.js +5 -2
- package/dist/domains/test-generation/services/test-generator.js +5 -2
- package/dist/governance/compliance-reporter.js +8 -7
- package/dist/governance/proof-envelope-integration.js +3 -1
- package/dist/init/phases/07-hooks.js +30 -4
- package/dist/init/phases/10-workers.js +42 -6
- package/dist/integrations/agentic-flow/onnx-embeddings/embedding-generator.d.ts +4 -1
- package/dist/integrations/agentic-flow/onnx-embeddings/embedding-generator.js +6 -2
- package/dist/integrations/browser/qe-dashboard/wasm-vector-store.js +2 -1
- package/dist/integrations/ruvector/coverage-router.d.ts +3 -1
- package/dist/integrations/ruvector/coverage-router.js +7 -6
- package/dist/integrations/ruvector/diff-risk-classifier.js +5 -4
- package/dist/integrations/ruvector/rvf-dual-writer.js +10 -1
- package/dist/integrations/vibium/runtime.js +2 -6
- package/dist/learning/dream/dream-engine.d.ts +5 -0
- package/dist/learning/dream/dream-engine.js +20 -3
- package/dist/learning/embedding-space.d.ts +18 -0
- package/dist/learning/embedding-space.js +33 -0
- package/dist/learning/rvf-pattern-store.js +19 -5
- package/dist/mcp/bundle.js +442 -441
- package/dist/mcp/handlers/domain-handler-configs.d.ts +42 -0
- package/dist/mcp/handlers/handler-factory.js +3 -1
- package/dist/mcp/handlers/save-results-option.d.ts +62 -0
- package/dist/mcp/handlers/save-results-option.js +35 -0
- package/dist/mcp/protocol-server.js +22 -11
- package/dist/mcp/security/rate-limiter.d.ts +8 -1
- package/dist/mcp/security/rate-limiter.js +33 -4
- package/dist/mcp/services/session-resume.js +11 -0
- package/dist/mcp/services/session-store.d.ts +31 -2
- package/dist/mcp/services/session-store.js +95 -16
- package/dist/mcp/services/session-write-buffer.d.ts +55 -0
- package/dist/mcp/services/session-write-buffer.js +144 -0
- package/dist/mcp/types.d.ts +18 -0
- package/dist/memory/crdt/convergence-tracker.js +14 -24
- package/dist/memory/crdt/crdt-store.js +15 -0
- package/dist/memory/crdt/g-counter.js +10 -8
- 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/embeddings/ollama-client.d.ts +1 -1
- package/dist/shared/embeddings/ollama-client.js +30 -31
- package/dist/shared/git/git-analyzer.d.ts +4 -1
- package/dist/shared/git/git-analyzer.js +9 -4
- package/dist/shared/llm/cache.js +1 -1
- package/dist/shared/llm/cost-tracker.js +8 -6
- package/dist/shared/llm/providers/azure-openai.js +5 -21
- package/dist/shared/llm/providers/bedrock.js +5 -21
- package/dist/shared/llm/providers/claude.js +5 -21
- package/dist/shared/llm/providers/cognitum.js +5 -17
- package/dist/shared/llm/providers/gemini.js +9 -23
- package/dist/shared/llm/providers/ollama.js +5 -21
- package/dist/shared/llm/providers/openai.js +5 -21
- package/dist/shared/llm/providers/openrouter.js +9 -23
- package/dist/shared/llm/providers/response-deadline.d.ts +3 -0
- package/dist/shared/llm/providers/response-deadline.js +100 -0
- package/dist/shared/llm/spend-ledger.js +3 -2
- package/dist/shared/metrics/code-metrics.d.ts +1 -0
- package/dist/shared/metrics/code-metrics.js +3 -44
- package/dist/shared/metrics/cognitive-complexity.d.ts +17 -0
- package/dist/shared/metrics/cognitive-complexity.js +108 -0
- package/dist/shared/npm-cli-invocation.d.ts +21 -0
- package/dist/shared/npm-cli-invocation.js +28 -0
- package/dist/shared/optional-module.js +24 -0
- package/dist/shared/test-runner-args.d.ts +42 -0
- package/dist/shared/test-runner-args.js +74 -0
- package/dist/shared/utils/safe-record.d.ts +18 -0
- package/dist/shared/utils/safe-record.js +28 -0
- package/dist/test-scheduling/executors/vitest-executor.js +23 -5
- package/dist/workers/quality-daemon/git-watcher.js +5 -0
- package/package.json +1 -1
- package/dist/adapters/ag-ui/json-patch-utils.d.ts +0 -136
- package/dist/adapters/ag-ui/json-patch-utils.js +0 -575
- package/dist/cli/chunks/adapter-EUIELRLI.js +0 -2
- package/dist/cli/chunks/aqe-learning-engine-LXRKHASR.js +0 -2
- package/dist/cli/chunks/base-4DSLX33Y.js +0 -2
- package/dist/cli/chunks/browser-workflow-AWCQLQZK.js +0 -2
- package/dist/cli/chunks/chunk-E2QHUMCR.js +0 -2
- package/dist/cli/chunks/chunk-I7ECEOFV.js +0 -2
- package/dist/cli/chunks/chunk-LW4BCFIV.js +0 -15
- package/dist/cli/chunks/chunk-QJGKL67W.js +0 -54
- package/dist/cli/chunks/chunk-RLQ4MYB6.js +0 -3
- package/dist/cli/chunks/chunk-X43HA3RF.js +0 -14
- package/dist/cli/chunks/chunk-Z3K4JZXQ.js +0 -4
- package/dist/cli/chunks/client-UJVHZXNQ.js +0 -2
- package/dist/cli/chunks/core-handlers-AFXZOSH3.js +0 -2
- package/dist/cli/chunks/cost-tracker-D6YSKTQC.js +0 -2
- package/dist/cli/chunks/cross-domain-router-ZLNVKLIR.js +0 -2
- package/dist/cli/chunks/dream-4OPJXXEG.js +0 -2
- package/dist/cli/chunks/heartbeat-scheduler-J5KLHO6C.js +0 -2
- package/dist/cli/chunks/hnsw-adapter-56P6XSFR.js +0 -2
- package/dist/cli/chunks/hnsw-index-GFZ6XCEW.js +0 -2
- package/dist/cli/chunks/hybrid-backend-TUBWJDDN.js +0 -2
- package/dist/cli/chunks/impact-analyzer-FXVGKS6B.js +0 -2
- package/dist/cli/chunks/init-wizard-LK73HQ7W.js +0 -2
- package/dist/cli/chunks/kernel-TCZDKRSI.js +0 -2
- package/dist/cli/chunks/knowledge-graph-TWMB2GH2.js +0 -2
- package/dist/cli/chunks/llm-router-service-HPDH3P77.js +0 -2
- package/dist/cli/chunks/load-test-HTYOUYSN.js +0 -2
- package/dist/cli/chunks/memory-backend-X5BE2MPK.js +0 -2
- package/dist/cli/chunks/memory-handlers-SQXMFX5X.js +0 -2
- package/dist/cli/chunks/pattern-null-store-OCQGQZU6.js +0 -2
- package/dist/cli/chunks/protocol-executor-CYEQHQCL.js +0 -2
- package/dist/cli/chunks/qe-reasoning-bank-GSTA5WJ4.js +0 -2
- package/dist/cli/chunks/queen-coordinator-Y2Q5RQL7.js +0 -2
- package/dist/cli/chunks/router-4QB5L4IW.js +0 -2
- package/dist/cli/chunks/routing-feedback-YBVHJY5L.js +0 -2
- package/dist/cli/chunks/rvf-dual-writer-T5B456SW.js +0 -2
- package/dist/cli/chunks/rvf-migration-adapter-2O2NL7ZF.js +0 -2
- package/dist/cli/chunks/rvf-native-adapter-RDB3GWTW.js +0 -2
- package/dist/cli/chunks/safe-db-YXVMLFU4.js +0 -2
- package/dist/cli/chunks/schedule-K6XWCCSK.js +0 -2
- package/dist/cli/chunks/scheduler-4MW22D6Q.js +0 -2
- package/dist/cli/chunks/sqlite-persistence-UVDHUSAU.js +0 -2
- package/dist/cli/chunks/sync-LSPNSVDI.js +0 -2
- package/dist/cli/chunks/test-M2XTKD62.js +0 -33
- package/dist/cli/chunks/test-scheduling-GYXJQHJL.js +0 -15
- package/dist/cli/chunks/token-bootstrap-OTEMRUFR.js +0 -2
- package/dist/cli/chunks/unified-memory-UUK77NSE.js +0 -2
- package/dist/cli/chunks/unified-memory-hnsw-JOUE6WNF.js +0 -2
- package/dist/cli/chunks/unified-persistence-3DRJGNQE.js +0 -2
- package/dist/cli/chunks/visual-security-EM7FQG5X.js +0 -2
- package/dist/cli/chunks/witness-chain-7NZ6IIUN.js +0 -2
- package/dist/cli/chunks/witness-chain-repair-ZWS5WXFL.js +0 -2
- package/dist/cli/chunks/workflow-orchestrator-3C3S5FIM.js +0 -2
- package/dist/cli/chunks/wrappers-NXJHGK3W.js +0 -2
|
@@ -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.
|
|
201
|
+
}
|
|
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);
|
|
209
278
|
}
|
|
210
|
-
//
|
|
211
|
-
//
|
|
212
|
-
|
|
213
|
-
const
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
)
|
|
217
|
-
|
|
218
|
-
|
|
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
|
+
}
|
|
219
295
|
}
|
|
220
|
-
//
|
|
221
|
-
|
|
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
|
|
@@ -274,10 +362,10 @@ function countCargoTests(projectPath, config) {
|
|
|
274
362
|
// Count lines ending with ": test"
|
|
275
363
|
const testLines = output.split('\n').filter(line => line.endsWith(': test'));
|
|
276
364
|
const total = testLines.length;
|
|
277
|
-
//
|
|
278
|
-
const unit = testLines.filter(t => !t.includes('integration') && !t.includes('e2e')).length;
|
|
279
|
-
const integration = testLines.filter(t => t.includes('integration')).length;
|
|
365
|
+
// Disjoint categories, e2e before integration: `tests::integration::e2e_x` counts once.
|
|
280
366
|
const e2e = testLines.filter(t => t.includes('e2e')).length;
|
|
367
|
+
const integration = testLines.filter(t => !t.includes('e2e') && t.includes('integration')).length;
|
|
368
|
+
const unit = total - integration - e2e;
|
|
281
369
|
return {
|
|
282
370
|
total,
|
|
283
371
|
unit,
|
|
@@ -9,6 +9,7 @@ import { ok, err } from '../../../shared/types/index.js';
|
|
|
9
9
|
import { toError } from '../../../shared/error-utils.js';
|
|
10
10
|
import { safeJsonParse } from '../../../shared/safe-json.js';
|
|
11
11
|
import { getClaudeModelForTier } from '../../../shared/llm/model-registry.js';
|
|
12
|
+
import { createSafeRecord } from '../../../shared/utils/safe-record.js';
|
|
12
13
|
const DEFAULT_CONFIG = {
|
|
13
14
|
minCoverage: 80,
|
|
14
15
|
enableLLMAnalysis: true, // On by default - opt-out
|
|
@@ -212,7 +213,8 @@ Return JSON in this exact format:
|
|
|
212
213
|
* Calculate effort breakdown by file
|
|
213
214
|
*/
|
|
214
215
|
calculateEffortBreakdown(gaps) {
|
|
215
|
-
|
|
216
|
+
// File paths are data, so the buckets must not inherit from Object.prototype (#914).
|
|
217
|
+
const breakdown = createSafeRecord();
|
|
216
218
|
for (const gap of gaps) {
|
|
217
219
|
const effort = Math.ceil(gap.lines.length / 15);
|
|
218
220
|
breakdown[gap.file] = (breakdown[gap.file] || 0) + effort;
|
|
@@ -9,6 +9,7 @@ import { rehydrateDates } from '../../../shared/utils/kv-date-rehydrate.js';
|
|
|
9
9
|
import { toError } from '../../../shared/error-utils.js';
|
|
10
10
|
import { createQEFlashAttention, } from '../../../integrations/ruvector/wrappers.js';
|
|
11
11
|
import { getClaudeModelForTier } from '../../../shared/llm/model-registry.js';
|
|
12
|
+
import { createSafeRecord } from '../../../shared/utils/safe-record.js';
|
|
12
13
|
const DEFAULT_CONFIG = {
|
|
13
14
|
minExperiencesForPattern: 5,
|
|
14
15
|
patternConfidenceThreshold: 0.7,
|
|
@@ -943,8 +944,9 @@ Provide:
|
|
|
943
944
|
return false;
|
|
944
945
|
}
|
|
945
946
|
calculateCentroid(experiences) {
|
|
946
|
-
|
|
947
|
-
const
|
|
947
|
+
// Metric names come from stored experiences (#914).
|
|
948
|
+
const avgMetrics = createSafeRecord();
|
|
949
|
+
const metricCounts = createSafeRecord();
|
|
948
950
|
for (const exp of experiences) {
|
|
949
951
|
for (const [key, value] of Object.entries(exp.state.metrics)) {
|
|
950
952
|
avgMetrics[key] = (avgMetrics[key] || 0) + value;
|
|
@@ -13,6 +13,7 @@ import { toError } from '../../../shared/error-utils.js';
|
|
|
13
13
|
import { safeJsonParse } from '../../../shared/safe-json.js';
|
|
14
14
|
import { getTestRunnerExecutionError } from '../../../shared/test-runner-verdict.js';
|
|
15
15
|
import { createVitestJsonReport, needsVitestJsonReportFile } from '../../../shared/vitest-json-report.js';
|
|
16
|
+
import { isJestCommand, jestExactPathPattern, runnerFilePath } from '../../../shared/test-runner-args.js';
|
|
16
17
|
import { secureRandom } from '../../../shared/utils/crypto-random.js';
|
|
17
18
|
const DEFAULT_FLAKY_CONFIG = {
|
|
18
19
|
simulateForTesting: false,
|
|
@@ -256,14 +257,19 @@ export class FlakyDetectorService {
|
|
|
256
257
|
const runId = uuidv4();
|
|
257
258
|
const startTime = Date.now();
|
|
258
259
|
return new Promise((resolve, reject) => {
|
|
259
|
-
const
|
|
260
|
+
const cwd = this.config.cwd ?? process.cwd();
|
|
261
|
+
// #909: pass an absolute path (never read as a flag); Jest reads it as a
|
|
262
|
+
// regex, so escape and anchor it to select exactly this file.
|
|
263
|
+
const fileArg = isJestCommand([this.config.testRunner, ...this.config.testRunnerArgs])
|
|
264
|
+
? jestExactPathPattern(file, cwd)
|
|
265
|
+
: runnerFilePath(file, cwd);
|
|
266
|
+
const baseArgs = [...this.config.testRunnerArgs, fileArg];
|
|
260
267
|
// Vitest 5 writes --reporter=json output to a file, not stdout. Detect
|
|
261
268
|
// Vitest from the runner command too (testRunner: 'vitest', args: ['run', ...]).
|
|
262
269
|
const report = needsVitestJsonReportFile([this.config.testRunner, ...baseArgs])
|
|
263
270
|
? createVitestJsonReport()
|
|
264
271
|
: undefined;
|
|
265
272
|
const args = report ? [...baseArgs, ...report.args] : baseArgs;
|
|
266
|
-
const cwd = this.config.cwd ?? process.cwd();
|
|
267
273
|
const child = spawn(this.config.testRunner, args, {
|
|
268
274
|
cwd,
|
|
269
275
|
env: { ...process.env, ...this.config.env },
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import { LoggerFactory } from '../../../logging/index.js';
|
|
6
6
|
import { spawn } from 'node:child_process';
|
|
7
7
|
import { createVitestJsonReport } from '../../../shared/vitest-json-report.js';
|
|
8
|
+
import { jestExactPathPattern, nameFilterArg, runnerFilePath } from '../../../shared/test-runner-args.js';
|
|
8
9
|
import { existsSync, readFileSync } from 'node:fs';
|
|
9
10
|
import { ok, err } from '../../../shared/types/index.js';
|
|
10
11
|
import { TEST_EXECUTION_CONSTANTS, RETRY_CONSTANTS } from '../../constants.js';
|
|
@@ -264,7 +265,7 @@ export class RetryHandlerService {
|
|
|
264
265
|
`or configure testRunner in RetryHandlerConfig. Cannot execute retry for: ${testFile}`);
|
|
265
266
|
}
|
|
266
267
|
// Build command based on runner
|
|
267
|
-
const { command, args, report } = this.buildTestCommand(runner, testFile, testName);
|
|
268
|
+
const { command, args, report } = this.buildTestCommand(runner, testFile, testName, cwd);
|
|
268
269
|
// Execute the test
|
|
269
270
|
return this.spawnTestProcess(command, args, cwd, report);
|
|
270
271
|
}
|
|
@@ -334,40 +335,42 @@ export class RetryHandlerService {
|
|
|
334
335
|
/**
|
|
335
336
|
* Build the command and arguments for the test runner
|
|
336
337
|
*/
|
|
337
|
-
buildTestCommand(runner, testFile, testName) {
|
|
338
|
+
buildTestCommand(runner, testFile, testName, cwd = this.config.cwd ?? process.cwd()) {
|
|
338
339
|
const npx = this.config.npxPath;
|
|
339
|
-
//
|
|
340
|
-
//
|
|
341
|
-
|
|
340
|
+
// A FailedTest holds the literal assertion name and path from the previous
|
|
341
|
+
// run. Name filters are regex-escaped and passed as --flag=value; file
|
|
342
|
+
// filters are absolute (Jest: escaped and anchored), so neither can be
|
|
343
|
+
// misread as a regex or as a flag when it starts with '-' (#886, #909).
|
|
344
|
+
const filterByName = Boolean(testName) && testName !== testFile;
|
|
342
345
|
switch (runner) {
|
|
343
346
|
case 'vitest':
|
|
344
|
-
// vitest run --reporter=json
|
|
347
|
+
// vitest run --reporter=json <abs file> --testNamePattern=<name>
|
|
345
348
|
// --outputFile: Vitest 5 no longer prints the JSON report to stdout.
|
|
346
349
|
{
|
|
347
350
|
const report = createVitestJsonReport();
|
|
348
|
-
const vitestArgs = ['vitest', 'run', '--reporter=json', testFile];
|
|
349
|
-
if (
|
|
350
|
-
vitestArgs.push('
|
|
351
|
-
}
|
|
351
|
+
const vitestArgs = ['vitest', 'run', '--reporter=json', runnerFilePath(testFile, cwd)];
|
|
352
|
+
if (filterByName)
|
|
353
|
+
vitestArgs.push(nameFilterArg('vitest', testName));
|
|
352
354
|
vitestArgs.push(...report.args);
|
|
353
355
|
return { command: npx, args: vitestArgs, report };
|
|
354
356
|
}
|
|
355
357
|
case 'jest':
|
|
356
|
-
// jest --json
|
|
358
|
+
// jest --json --testNamePattern=<name> ^<escaped abs file>$
|
|
359
|
+
// Positional TestPathPatterns work on Jest 29 and 30 (Jest 30 rejects
|
|
360
|
+
// the old --testPathPattern flag).
|
|
357
361
|
{
|
|
358
|
-
const jestArgs = ['jest', '--json'
|
|
359
|
-
if (
|
|
360
|
-
jestArgs.push('
|
|
361
|
-
|
|
362
|
+
const jestArgs = ['jest', '--json'];
|
|
363
|
+
if (filterByName)
|
|
364
|
+
jestArgs.push(nameFilterArg('jest', testName));
|
|
365
|
+
jestArgs.push(jestExactPathPattern(testFile, cwd));
|
|
362
366
|
return { command: npx, args: jestArgs };
|
|
363
367
|
}
|
|
364
368
|
case 'mocha':
|
|
365
|
-
// mocha --reporter json
|
|
369
|
+
// mocha --reporter json <abs file> --grep=<name>
|
|
366
370
|
{
|
|
367
|
-
const mochaArgs = ['mocha', '--reporter', 'json', testFile];
|
|
368
|
-
if (
|
|
369
|
-
mochaArgs.push('
|
|
370
|
-
}
|
|
371
|
+
const mochaArgs = ['mocha', '--reporter', 'json', runnerFilePath(testFile, cwd)];
|
|
372
|
+
if (filterByName)
|
|
373
|
+
mochaArgs.push(nameFilterArg('mocha', testName));
|
|
371
374
|
return { command: npx, args: mochaArgs };
|
|
372
375
|
}
|
|
373
376
|
default:
|
|
@@ -16,6 +16,7 @@ import { secureRandom, secureRandomInt } from '../../../shared/utils/crypto-rand
|
|
|
16
16
|
import { writeQualityEvidence } from '../../quality-assessment/quality-evidence.js';
|
|
17
17
|
import { getTestRunnerExecutionError, TestRunnerExecutionError } from '../../../shared/test-runner-verdict.js';
|
|
18
18
|
import { createVitestJsonReport } from '../../../shared/vitest-json-report.js';
|
|
19
|
+
import { jestExactPathPattern, runnerFilePath } from '../../../shared/test-runner-args.js';
|
|
19
20
|
import { getClaudeModelForTier } from '../../../shared/llm/model-registry.js';
|
|
20
21
|
import { terminateTestRunner, trackTestRunnerExit } from '../../../shared/test-runner-process.js';
|
|
21
22
|
const DEFAULT_CONFIG = {
|
|
@@ -481,7 +482,9 @@ Provide:
|
|
|
481
482
|
* Build test command based on framework
|
|
482
483
|
*/
|
|
483
484
|
buildTestCommand(fileOrFiles, framework) {
|
|
484
|
-
|
|
485
|
+
// #909: absolute paths never start with '-', so a file cannot be read as a
|
|
486
|
+
// flag; Jest's positional patterns are regexes, so escape and anchor them.
|
|
487
|
+
const files = (Array.isArray(fileOrFiles) ? fileOrFiles : [fileOrFiles]).map(file => runnerFilePath(file));
|
|
485
488
|
const createCoverageDirectory = () => mkdtempSync(join(tmpdir(), 'aqe-test-coverage-'));
|
|
486
489
|
switch (framework.toLowerCase()) {
|
|
487
490
|
case 'vitest': {
|
|
@@ -507,7 +510,7 @@ Provide:
|
|
|
507
510
|
const coverageDirectory = createCoverageDirectory();
|
|
508
511
|
return {
|
|
509
512
|
command: 'npx',
|
|
510
|
-
args: ['jest', ...files, '--json', '--no-colors', '--testLocationInResults', `--coverageDirectory=${coverageDirectory}`],
|
|
513
|
+
args: ['jest', ...files.map(file => jestExactPathPattern(file)), '--json', '--no-colors', '--testLocationInResults', `--coverageDirectory=${coverageDirectory}`],
|
|
511
514
|
coverageDirectory,
|
|
512
515
|
};
|
|
513
516
|
}
|
|
@@ -993,8 +993,11 @@ Return a JSON array of test suggestions, each with: { "name": "test name", "desc
|
|
|
993
993
|
if (lang && lang !== 'typescript' && lang !== 'javascript') {
|
|
994
994
|
return resolveTestFilePath(sourceFile, lang);
|
|
995
995
|
}
|
|
996
|
-
|
|
997
|
-
|
|
996
|
+
// #936 follow-up: strip only the trailing extension. A first-match
|
|
997
|
+
// replace turned /home/u/my.ts-app/src/a.ts into /home/u/my-app/src/a.ts,
|
|
998
|
+
// pointing the test file at a sibling directory outside the project.
|
|
999
|
+
const ext = fileExt ? fileExt.slice(1) : 'ts';
|
|
1000
|
+
const base = fileExt ? sourceFile.slice(0, -fileExt.length) : sourceFile;
|
|
998
1001
|
if (framework === 'pytest') {
|
|
999
1002
|
return `test_${base.split('/').pop()}.py`;
|
|
1000
1003
|
}
|
|
@@ -19,6 +19,7 @@ import { governanceFlags, } from './feature-flags.js';
|
|
|
19
19
|
import { proofEnvelopeIntegration, } from './proof-envelope-integration.js';
|
|
20
20
|
import { getUnifiedMemory } from '../kernel/unified-memory.js';
|
|
21
21
|
import { toErrorMessage } from '../shared/error-utils.js';
|
|
22
|
+
import { createSafeRecord } from '../shared/utils/safe-record.js';
|
|
22
23
|
// ============================================================================
|
|
23
24
|
// Default Configuration
|
|
24
25
|
// ============================================================================
|
|
@@ -274,14 +275,14 @@ export class ComplianceReporter {
|
|
|
274
275
|
});
|
|
275
276
|
// Calculate overall score
|
|
276
277
|
const overall = this.calculateOverallScore(violations);
|
|
277
|
-
// Calculate score by gate
|
|
278
|
-
const byGate =
|
|
278
|
+
// Calculate score by gate. Gate and agent names are data (#914).
|
|
279
|
+
const byGate = createSafeRecord();
|
|
279
280
|
const gateViolations = this.groupBy(violations, 'gate');
|
|
280
281
|
for (const [gate, gateViols] of Object.entries(gateViolations)) {
|
|
281
282
|
byGate[gate] = this.calculateOverallScore(gateViols);
|
|
282
283
|
}
|
|
283
284
|
// Calculate score by agent
|
|
284
|
-
const byAgent =
|
|
285
|
+
const byAgent = createSafeRecord();
|
|
285
286
|
const agentViolations = this.groupBy(violations, 'agentId');
|
|
286
287
|
for (const [agentId, agentViols] of Object.entries(agentViolations)) {
|
|
287
288
|
if (agentId !== 'undefined') {
|
|
@@ -572,13 +573,13 @@ export class ComplianceReporter {
|
|
|
572
573
|
for (const v of allViolations) {
|
|
573
574
|
bySeverity[v.severity]++;
|
|
574
575
|
}
|
|
575
|
-
// Count by gate
|
|
576
|
-
const byGate =
|
|
576
|
+
// Count by gate. Gate and agent names are data (#914).
|
|
577
|
+
const byGate = createSafeRecord();
|
|
577
578
|
for (const v of allViolations) {
|
|
578
579
|
byGate[v.gate] = (byGate[v.gate] || 0) + 1;
|
|
579
580
|
}
|
|
580
581
|
// Count by agent
|
|
581
|
-
const byAgent =
|
|
582
|
+
const byAgent = createSafeRecord();
|
|
582
583
|
for (const v of allViolations) {
|
|
583
584
|
if (v.agentId) {
|
|
584
585
|
byAgent[v.agentId] = (byAgent[v.agentId] || 0) + 1;
|
|
@@ -984,7 +985,7 @@ export class ComplianceReporter {
|
|
|
984
985
|
* Group violations by a field
|
|
985
986
|
*/
|
|
986
987
|
groupBy(violations, field) {
|
|
987
|
-
const groups =
|
|
988
|
+
const groups = createSafeRecord();
|
|
988
989
|
for (const v of violations) {
|
|
989
990
|
const key = String(v[field]);
|
|
990
991
|
if (!groups[key]) {
|
|
@@ -19,6 +19,7 @@ import { safeJsonParse } from '../shared/safe-json.js';
|
|
|
19
19
|
*/
|
|
20
20
|
import { wasmKernelIntegration, } from './wasm-kernel-integration.js';
|
|
21
21
|
import { governanceFlags, } from './feature-flags.js';
|
|
22
|
+
import { createSafeRecord } from '../shared/utils/safe-record.js';
|
|
22
23
|
/**
|
|
23
24
|
* Genesis envelope hash constant
|
|
24
25
|
*/
|
|
@@ -514,7 +515,8 @@ export class ProofEnvelopeIntegration {
|
|
|
514
515
|
* Get chain statistics
|
|
515
516
|
*/
|
|
516
517
|
getProofStats() {
|
|
517
|
-
|
|
518
|
+
// Action names are data, so the buckets must not inherit from Object.prototype (#914).
|
|
519
|
+
const actionCounts = createSafeRecord();
|
|
518
520
|
const agents = new Set();
|
|
519
521
|
for (const envelope of this.chain) {
|
|
520
522
|
agents.add(envelope.agentId);
|
|
@@ -259,10 +259,13 @@ export class HooksPhase extends BasePhase {
|
|
|
259
259
|
mkdirSync(helpersDir, { recursive: true });
|
|
260
260
|
}
|
|
261
261
|
const destPath = join(helpersDir, 'brain-checkpoint.cjs');
|
|
262
|
-
// Try to copy from our own installation first
|
|
262
|
+
// Try to copy from our own installation first. The last candidate is this
|
|
263
|
+
// package's own copy (relative to the compiled init module), so a GLOBAL
|
|
264
|
+
// install also refreshes an existing project's helper on re-init (#872).
|
|
263
265
|
const sourcePaths = [
|
|
264
266
|
join(projectRoot, '.claude', 'helpers', 'brain-checkpoint.cjs'),
|
|
265
267
|
join(projectRoot, 'node_modules', 'agentic-qe', '.claude', 'helpers', 'brain-checkpoint.cjs'),
|
|
268
|
+
join(__dirname, '..', '..', '..', '.claude', 'helpers', 'brain-checkpoint.cjs'),
|
|
266
269
|
];
|
|
267
270
|
for (const src of sourcePaths) {
|
|
268
271
|
if (existsSync(src) && src !== destPath) {
|
|
@@ -399,16 +402,39 @@ const AQE_DIR = path.join(PROJECT_ROOT, '.agentic-qe');
|
|
|
399
402
|
const RVF_PATH = path.join(AQE_DIR, 'aqe.rvf');
|
|
400
403
|
const DB_PATH = path.join(AQE_DIR, 'memory.db');
|
|
401
404
|
const MAX_AGE_HOURS = 24;
|
|
402
|
-
|
|
405
|
+
// Windows (#872): never execFile aqe.cmd (EINVAL without a shell); reuse the
|
|
406
|
+
// hook shim's resolver, which runs the AQE bundle via node instead.
|
|
407
|
+
function aqeInvocation() {
|
|
408
|
+
if (process.platform !== 'win32') return { cmd: process.env.AQE_HOOK_BIN || 'aqe', args: [] };
|
|
409
|
+
const shimPath = path.join(__dirname, '..', 'hooks', 'aqe-hook.cjs');
|
|
410
|
+
let src = '';
|
|
411
|
+
try { src = fs.readFileSync(shimPath, 'utf8'); } catch { /* missing */ }
|
|
412
|
+
// An older shim runs its hook main (spawn + exit) when required.
|
|
413
|
+
if (!src.includes('resolveAqeInvocation') || !src.includes('require.main === module')) {
|
|
414
|
+
return { cmd: null, args: [], reason: '.claude/hooks/aqe-hook.cjs is missing or predates #872; re-run aqe init' };
|
|
415
|
+
}
|
|
416
|
+
try {
|
|
417
|
+
return require(shimPath).resolveAqeInvocation({ project: PROJECT_ROOT });
|
|
418
|
+
} catch (e) {
|
|
419
|
+
return { cmd: null, args: [], reason: 'aqe-hook.cjs failed to load: ' + e.message };
|
|
420
|
+
}
|
|
421
|
+
}
|
|
403
422
|
|
|
404
423
|
function log(msg) { process.stderr.write('[brain-checkpoint] ' + msg + '\\n'); }
|
|
405
424
|
|
|
406
425
|
function exportBrain() {
|
|
407
426
|
if (!fs.existsSync(DB_PATH)) { log('No memory.db, skipping'); return { exported: false }; }
|
|
427
|
+
const aqe = aqeInvocation();
|
|
428
|
+
if (!aqe.cmd) { log('Export skipped: ' + aqe.reason); return { exported: false, reason: aqe.reason }; }
|
|
429
|
+
// Never write through a committed symlink: .agentic-qe must be a real dir, and
|
|
430
|
+
// unlink (not existsSync) drops a planted aqe.rvf link, even a dangling one.
|
|
431
|
+
let st; try { st = fs.lstatSync(AQE_DIR); } catch { /* missing */ }
|
|
432
|
+
if (!st || !st.isDirectory()) { log('Export skipped: .agentic-qe is a symlink'); return { exported: false }; }
|
|
433
|
+
for (const f of [RVF_PATH, RVF_PATH + '.idmap.json']) { try { fs.unlinkSync(f); } catch { /* absent */ } }
|
|
408
434
|
try {
|
|
409
435
|
const result = execFileSync(
|
|
410
|
-
|
|
411
|
-
{ timeout: 60000, encoding: 'utf-8' }
|
|
436
|
+
aqe.cmd, [...aqe.args, 'brain', 'export', '-o', RVF_PATH, '--format', 'rvf'],
|
|
437
|
+
{ timeout: 60000, encoding: 'utf-8', windowsHide: true }
|
|
412
438
|
);
|
|
413
439
|
const m = result.match(/Patterns:\\s+(\\d+)/);
|
|
414
440
|
const p = m ? m[1] : '0';
|
|
@@ -109,8 +109,9 @@ export class WorkersPhase extends BasePhase {
|
|
|
109
109
|
// Generated by aqe init
|
|
110
110
|
// Starts the MCP server with background workers enabled
|
|
111
111
|
|
|
112
|
-
const
|
|
113
|
-
const {
|
|
112
|
+
const fs = require('fs');
|
|
113
|
+
const { existsSync, readFileSync } = fs;
|
|
114
|
+
const { join, dirname } = require('path');
|
|
114
115
|
const { spawn } = require('child_process');
|
|
115
116
|
|
|
116
117
|
const projectRoot = join(__dirname, '..', '..');
|
|
@@ -118,8 +119,33 @@ const workersDir = join(projectRoot, '.agentic-qe', 'workers');
|
|
|
118
119
|
const pidFile = join(workersDir, 'daemon.pid');
|
|
119
120
|
const logFile = join(workersDir, 'daemon.log');
|
|
120
121
|
|
|
121
|
-
//
|
|
122
|
-
|
|
122
|
+
// A repository can commit .agentic-qe, workers/ or a file in it as a symlink.
|
|
123
|
+
// Never write through one (#970): real directories only, appends only to a
|
|
124
|
+
// regular file (lstat + O_NOFOLLOW where the platform has it), and the pid file
|
|
125
|
+
// is replaced by rename instead of being written in place.
|
|
126
|
+
function isRealDir(d) { try { const s = fs.lstatSync(d); return s.isDirectory() && !s.isSymbolicLink(); } catch { return false; } }
|
|
127
|
+
function isRegularOrAbsent(f) { try { return fs.lstatSync(f).isFile(); } catch (e) { return !!e && e.code === 'ENOENT'; } }
|
|
128
|
+
if (!isRealDir(join(projectRoot, '.agentic-qe')) || !isRealDir(workersDir)) {
|
|
129
|
+
console.error('AQE v3 Worker Daemon not started: .agentic-qe/workers must be a real directory, not a symlink');
|
|
130
|
+
process.exit(1);
|
|
131
|
+
}
|
|
132
|
+
function appendFileSync(file, data) {
|
|
133
|
+
if (!isRegularOrAbsent(file)) return;
|
|
134
|
+
const c = fs.constants;
|
|
135
|
+
let fd;
|
|
136
|
+
try {
|
|
137
|
+
fd = fs.openSync(file, c.O_APPEND | c.O_CREAT | c.O_WRONLY | (c.O_NOFOLLOW || 0), 0o644);
|
|
138
|
+
fs.writeSync(fd, data);
|
|
139
|
+
} catch {} finally { if (fd !== undefined) { try { fs.closeSync(fd); } catch {} } }
|
|
140
|
+
}
|
|
141
|
+
function writeFileSync(file, data) {
|
|
142
|
+
const tmp = file + '.' + process.pid + '.' + Date.now() + '.tmp';
|
|
143
|
+
try { fs.writeFileSync(tmp, data, { flag: 'wx' }); fs.renameSync(tmp, file); }
|
|
144
|
+
catch { try { fs.unlinkSync(tmp); } catch {} }
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Check if already running (only trust a regular pid file, never a link target)
|
|
148
|
+
if (existsSync(pidFile) && isRegularOrAbsent(pidFile)) {
|
|
123
149
|
const pid = parseInt(readFileSync(pidFile, 'utf-8').trim(), 10);
|
|
124
150
|
try { process.kill(pid, 0); console.log('Daemon already running (PID: ' + pid + ')'); process.exit(0); } catch {}
|
|
125
151
|
}
|
|
@@ -161,8 +187,18 @@ if (binCandidate && binCandidate.endsWith('bundle.js')) {
|
|
|
161
187
|
mcpCmd = binCandidate;
|
|
162
188
|
mcpArgs = [];
|
|
163
189
|
} else {
|
|
164
|
-
|
|
165
|
-
|
|
190
|
+
// Windows (#872): npx is npx.cmd, which spawn() refuses to start without a
|
|
191
|
+
// shell (EINVAL since CVE-2024-27980). Run npm's bundled npx CLI via node.
|
|
192
|
+
const npxCli = join(dirname(process.execPath), 'node_modules', 'npm', 'bin', 'npx-cli.js');
|
|
193
|
+
if (process.platform === 'win32' && !existsSync(npxCli)) {
|
|
194
|
+
appendFileSync(logFile, '[' + ts + '] ERROR: no AQE MCP bundle found and npx-cli.js is missing next to node.exe; install agentic-qe locally (npm install -D agentic-qe).\\n');
|
|
195
|
+
console.error('AQE v3 Worker Daemon not started: agentic-qe MCP bundle not found (see ' + logFile + ')');
|
|
196
|
+
process.exit(1);
|
|
197
|
+
}
|
|
198
|
+
mcpCmd = process.platform === 'win32' ? process.execPath : 'npx';
|
|
199
|
+
mcpArgs = process.platform === 'win32'
|
|
200
|
+
? [npxCli, '--yes', 'agentic-qe', 'mcp']
|
|
201
|
+
: ['--yes', 'agentic-qe', 'mcp'];
|
|
166
202
|
appendFileSync(logFile, '[' + ts + '] WARNING: using npx fallback — daemon.pid will point at the npx wrapper, not the MCP server. \`aqe daemon status\` may misreport liveness after the wrapper exits.\\n');
|
|
167
203
|
}
|
|
168
204
|
|
|
@@ -43,7 +43,10 @@ export declare class EmbeddingGenerator {
|
|
|
43
43
|
*/
|
|
44
44
|
updateConfig(config: Partial<EmbeddingConfig>): void;
|
|
45
45
|
/**
|
|
46
|
-
* Generate cache key from text and config
|
|
46
|
+
* Generate cache key from text and every config field that changes the vector.
|
|
47
|
+
* A JSON tuple keeps field boundaries intact when the model or text contains
|
|
48
|
+
* ':' (#914, as #863 did for the shared embedding cache). The cache is
|
|
49
|
+
* in-memory only, so no persisted keys need migrating.
|
|
47
50
|
*/
|
|
48
51
|
private getCacheKey;
|
|
49
52
|
/**
|
|
@@ -240,10 +240,14 @@ export class EmbeddingGenerator {
|
|
|
240
240
|
}
|
|
241
241
|
}
|
|
242
242
|
/**
|
|
243
|
-
* Generate cache key from text and config
|
|
243
|
+
* Generate cache key from text and every config field that changes the vector.
|
|
244
|
+
* A JSON tuple keeps field boundaries intact when the model or text contains
|
|
245
|
+
* ':' (#914, as #863 did for the shared embedding cache). The cache is
|
|
246
|
+
* in-memory only, so no persisted keys need migrating.
|
|
244
247
|
*/
|
|
245
248
|
getCacheKey(text) {
|
|
246
|
-
|
|
249
|
+
const { model, hyperbolic, normalize, curvature } = this.config;
|
|
250
|
+
return JSON.stringify([model, hyperbolic, normalize, curvature, text]);
|
|
247
251
|
}
|
|
248
252
|
/**
|
|
249
253
|
* Convert Euclidean embedding to Poincaré ball
|