agentic-qe 3.15.16 → 3.15.17
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 +78 -0
- package/assets/skills/skills-manifest.json +1 -1
- package/dist/cli/bundle.js +6 -6
- package/dist/cli/chunks/adapter-OMILP6KH.js +2 -0
- package/dist/cli/chunks/{agent-booster-wasm-45NWEKVS.js → agent-booster-wasm-6BUOFQZA.js} +2 -2
- package/dist/cli/chunks/{agent-handler-LVHMYFEF.js → agent-handler-HPDK3JI3.js} +2 -2
- package/dist/cli/chunks/{agent-memory-branch-YDWOJFEQ.js → agent-memory-branch-5QKUTWK5.js} +2 -2
- package/dist/cli/chunks/aqe-learning-engine-OXH5CCOS.js +2 -0
- package/dist/cli/chunks/{arena-CZKHXDDS.js → arena-7OKPMNHD.js} +2 -2
- package/dist/cli/chunks/{arena-ELDZH3CZ.js → arena-HZ35LESR.js} +4 -4
- package/dist/cli/chunks/{audit-5MT4T47Z.js → audit-XI575SVK.js} +3 -3
- package/dist/cli/chunks/base-MAK2BLTG.js +2 -0
- package/dist/cli/chunks/{better-sqlite3-6TGYPC2B.js → better-sqlite3-YO5X7ZJS.js} +2 -2
- package/dist/cli/chunks/{brain-handler-HQWZFO52.js → brain-handler-GCQZFZGQ.js} +3 -3
- package/dist/cli/chunks/{branch-enumerator-WVILM4SO.js → branch-enumerator-N6G44UU2.js} +2 -2
- package/dist/cli/chunks/{browser-RX5ALU3H.js → browser-EVKPTLOI.js} +2 -2
- package/dist/cli/chunks/browser-workflow-IR3VF2TL.js +2 -0
- package/dist/cli/chunks/{chunk-F742SZAX.js → chunk-2EQK7B5L.js} +2 -2
- package/dist/cli/chunks/{chunk-5NNNEWLS.js → chunk-2PCEMDIX.js} +67 -65
- package/dist/cli/chunks/{chunk-FBDVGRSC.js → chunk-2UUZCQSD.js} +7 -7
- package/dist/cli/chunks/{chunk-AG2EWGXS.js → chunk-2YWYW7NU.js} +2 -2
- package/dist/cli/chunks/{chunk-4LQFBY5L.js → chunk-45223KK6.js} +3 -3
- package/dist/cli/chunks/chunk-4EJLHNER.js +12 -0
- package/dist/cli/chunks/{chunk-KQYJ4VQ5.js → chunk-4L6WX5KC.js} +1 -1
- package/dist/cli/chunks/{chunk-KVF4NXGQ.js → chunk-4NKZU2JZ.js} +2 -2
- package/dist/cli/chunks/{chunk-YRAX7SFJ.js → chunk-4UKTIQDT.js} +2 -2
- package/dist/cli/chunks/{chunk-YTHTQPWR.js → chunk-4YM45Z5B.js} +1 -1
- package/dist/cli/chunks/{chunk-XIIQ5QTT.js → chunk-5FSPELOG.js} +2 -2
- package/dist/cli/chunks/{chunk-LKTTUHLF.js → chunk-5WATBVU6.js} +2 -2
- package/dist/cli/chunks/{chunk-SR52XP5F.js → chunk-5WYZVSL2.js} +1 -1
- package/dist/cli/chunks/{chunk-GQ6TUIKY.js → chunk-6LSZCEW2.js} +1 -1
- package/dist/cli/chunks/{chunk-NDJ7P2EP.js → chunk-6V6BD6PH.js} +1 -1
- package/dist/cli/chunks/{chunk-63GMRQ25.js → chunk-74MDUIAZ.js} +1 -1
- package/dist/cli/chunks/{chunk-4D4DENG6.js → chunk-776K4ZLE.js} +2 -2
- package/dist/cli/chunks/{chunk-ZJH5MU2I.js → chunk-7BSOO3CY.js} +2 -2
- package/dist/cli/chunks/{chunk-IOQ6ZQ5W.js → chunk-7SNSI4VY.js} +1 -1
- package/dist/cli/chunks/{chunk-LRSX2FJM.js → chunk-A4BVDYIL.js} +1 -1
- package/dist/cli/chunks/{chunk-SASBO5Y5.js → chunk-AGCS5GSO.js} +2 -2
- package/dist/cli/chunks/{chunk-GAHNO6JJ.js → chunk-AVHYJ3XP.js} +2 -2
- package/dist/cli/chunks/{chunk-CGGUM2YJ.js → chunk-BE7ZHM34.js} +2 -2
- package/dist/cli/chunks/{chunk-7TE5ONQQ.js → chunk-BHQ2DLJU.js} +1 -1
- package/dist/cli/chunks/{chunk-IESR7TNB.js → chunk-BKHEQIRZ.js} +2 -2
- package/dist/cli/chunks/{chunk-J4ELZNLY.js → chunk-BSIWI4ES.js} +2 -2
- package/dist/cli/chunks/{chunk-NVEWF4JV.js → chunk-C7QLLMYI.js} +1 -1
- package/dist/cli/chunks/{chunk-V5NHZV7S.js → chunk-CMN7PU2H.js} +2 -2
- package/dist/cli/chunks/{chunk-PPUZWYUG.js → chunk-COTQ44YO.js} +2 -2
- package/dist/cli/chunks/{chunk-5V3TI2LG.js → chunk-CQER6IJ5.js} +1 -1
- package/dist/cli/chunks/{chunk-SI6DPU5D.js → chunk-CVPXHDQU.js} +1 -1
- package/dist/cli/chunks/{chunk-6ZBXSOX6.js → chunk-CVYPMGUM.js} +2 -2
- package/dist/cli/chunks/{chunk-DXD6K2ZP.js → chunk-CXCMATZ6.js} +2 -2
- package/dist/cli/chunks/{chunk-PF7RBAYL.js → chunk-D75GLKEL.js} +2 -2
- package/dist/cli/chunks/chunk-DCDSN67A.js +2 -0
- package/dist/cli/chunks/{chunk-MAFQV4U4.js → chunk-DHKSPOUQ.js} +2 -2
- package/dist/cli/chunks/{chunk-RJIEG3NA.js → chunk-DJDVD6RM.js} +2 -2
- package/dist/cli/chunks/{chunk-GFWHUQSF.js → chunk-DNVRTJKB.js} +2 -2
- package/dist/cli/chunks/{chunk-G5RHFBAY.js → chunk-DS5IFRY6.js} +2 -2
- package/dist/cli/chunks/{chunk-BEKDKVQT.js → chunk-E7XIMOKW.js} +2 -2
- package/dist/cli/chunks/{chunk-5JZRZI4S.js → chunk-ECKHDHR2.js} +2 -2
- package/dist/cli/chunks/chunk-EPVPXHL7.js +2 -0
- package/dist/cli/chunks/{chunk-HVRRLYX6.js → chunk-ERYADKMZ.js} +2 -2
- package/dist/cli/chunks/{chunk-SUDMM5SO.js → chunk-EUWG2JG4.js} +2 -2
- package/dist/cli/chunks/{chunk-VSIKHWZ4.js → chunk-FAQ24UHB.js} +3 -3
- package/dist/cli/chunks/{chunk-YNMJEDN5.js → chunk-FBBPRVNF.js} +2 -2
- package/dist/cli/chunks/{chunk-72XSEQMW.js → chunk-FBSBXCZS.js} +2 -2
- package/dist/cli/chunks/{chunk-J7I6PABJ.js → chunk-G2X3OLMN.js} +2 -2
- package/dist/cli/chunks/{chunk-YU2BDRSD.js → chunk-GG7PMTHD.js} +1 -1
- package/dist/cli/chunks/{chunk-HLUXXCHF.js → chunk-GN6OE3JT.js} +1 -1
- package/dist/cli/chunks/{chunk-AGRV5B3T.js → chunk-GPPTRKEM.js} +2 -2
- package/dist/cli/chunks/{chunk-ZQ2XW3IP.js → chunk-H2LHWZRE.js} +2 -2
- package/dist/cli/chunks/{chunk-6DPYNAOK.js → chunk-HAQJFUAQ.js} +2 -2
- package/dist/cli/chunks/{chunk-SSUAAX3F.js → chunk-HD6W6PHV.js} +2 -2
- package/dist/cli/chunks/{chunk-L2DWPVNJ.js → chunk-HFZD5KLR.js} +1 -1
- package/dist/cli/chunks/{chunk-QVDCVD5D.js → chunk-HRUHHHVR.js} +2 -2
- package/dist/cli/chunks/{chunk-PINSJCM3.js → chunk-HVT7RMGV.js} +1 -1
- package/dist/cli/chunks/chunk-HWQPMUSN.js +2 -0
- package/dist/cli/chunks/{chunk-4NFQLP6R.js → chunk-HZ5O7G2P.js} +1 -1
- package/dist/cli/chunks/{chunk-C6D5AHBO.js → chunk-IHQGNDMX.js} +2 -2
- package/dist/cli/chunks/{chunk-QQWBWEJS.js → chunk-IJSROBM6.js} +3 -3
- package/dist/cli/chunks/{chunk-OCV2XEWQ.js → chunk-IJZFJPHS.js} +2 -2
- package/dist/cli/chunks/{chunk-N7HL5PHH.js → chunk-IKB3M7OF.js} +1 -1
- package/dist/cli/chunks/{chunk-24OX5TQJ.js → chunk-INI3Q4CN.js} +1 -1
- package/dist/cli/chunks/{chunk-SJ6Y4725.js → chunk-IOWEBPXJ.js} +2 -2
- package/dist/cli/chunks/{chunk-VXFLJNCA.js → chunk-IQL6XRF5.js} +2 -2
- package/dist/cli/chunks/{chunk-WP4RETKG.js → chunk-IRHXGCQR.js} +2 -2
- package/dist/cli/chunks/{chunk-63ZKI4PX.js → chunk-J3QFJI2Y.js} +2 -2
- package/dist/cli/chunks/{chunk-UHEOGZLX.js → chunk-J6QRNQJF.js} +5 -5
- package/dist/cli/chunks/{chunk-KNSRL6NO.js → chunk-J7Q5TXFZ.js} +2 -2
- package/dist/cli/chunks/{chunk-L6QSTQME.js → chunk-JHKKIJT2.js} +2 -2
- package/dist/cli/chunks/{chunk-VMDFFTCK.js → chunk-JI33PMPZ.js} +1 -1
- package/dist/cli/chunks/{chunk-E3D4GPLP.js → chunk-JRIJM4LE.js} +3 -3
- package/dist/cli/chunks/{chunk-XIQW7EFL.js → chunk-JVWZAE2H.js} +2 -2
- package/dist/cli/chunks/{chunk-YPBSUGMI.js → chunk-K7WAI662.js} +1 -1
- package/dist/cli/chunks/{chunk-RV74I3YO.js → chunk-KB34MTFZ.js} +2 -2
- package/dist/cli/chunks/{chunk-MI5MFHRA.js → chunk-KPIPVSIP.js} +2 -2
- package/dist/cli/chunks/{chunk-Y4PFUMOU.js → chunk-KR2TAAF6.js} +1 -1
- package/dist/cli/chunks/{chunk-W5HQUIML.js → chunk-KT2QCXO6.js} +2 -2
- package/dist/cli/chunks/{chunk-SSYAQZXA.js → chunk-KTORRIX3.js} +2 -2
- package/dist/cli/chunks/{chunk-CRPIYUTJ.js → chunk-LCWEQRZI.js} +2 -2
- package/dist/cli/chunks/{chunk-NO3IV5Q5.js → chunk-LG5PPJT7.js} +1 -1
- package/dist/cli/chunks/{chunk-5VZL4UVN.js → chunk-LIF6UWHV.js} +2 -2
- package/dist/cli/chunks/{chunk-32BPDLRZ.js → chunk-LN7NKE3N.js} +2 -2
- package/dist/cli/chunks/{chunk-ZB3LEFYG.js → chunk-LOLSZG5J.js} +2 -2
- package/dist/cli/chunks/{chunk-6XXZDV2C.js → chunk-LOMT4UC2.js} +2 -2
- package/dist/cli/chunks/{chunk-JDIYMZCQ.js → chunk-LRKLATSH.js} +2 -2
- package/dist/cli/chunks/{chunk-5SPCGMBB.js → chunk-LRY6UIRI.js} +2 -2
- package/dist/cli/chunks/{chunk-5PBLPQ5T.js → chunk-LV7UIK4Q.js} +2 -2
- package/dist/cli/chunks/{chunk-FDDC72IA.js → chunk-M2YI5YUR.js} +2 -2
- package/dist/cli/chunks/{chunk-D6COXLYE.js → chunk-MCXW3DKE.js} +2 -2
- package/dist/cli/chunks/{chunk-J442IZLE.js → chunk-MGZ6XZHU.js} +1 -1
- package/dist/cli/chunks/{chunk-TIUKLYAI.js → chunk-MLMD3I75.js} +1 -1
- package/dist/cli/chunks/{chunk-PHT5N7SC.js → chunk-MVVVGQJ6.js} +2 -2
- package/dist/cli/chunks/{chunk-525CFDUE.js → chunk-ND72UDVH.js} +2 -2
- package/dist/cli/chunks/{chunk-XWUWX7BV.js → chunk-NE3LRUNC.js} +4 -4
- package/dist/cli/chunks/{chunk-DTMAS2GB.js → chunk-NKUHMA4T.js} +2 -2
- package/dist/cli/chunks/{chunk-QPEOLAAS.js → chunk-NQFDJ6BT.js} +1 -1
- package/dist/cli/chunks/{chunk-MO55CVMT.js → chunk-NZJVDOUN.js} +14 -14
- package/dist/cli/chunks/{chunk-NZU4ACBZ.js → chunk-O7VJ3VKD.js} +2 -2
- package/dist/cli/chunks/{chunk-32GN3JKR.js → chunk-OJIUIEI4.js} +1 -1
- package/dist/cli/chunks/{chunk-UNGBRZDK.js → chunk-OO2M2QUV.js} +3 -3
- package/dist/cli/chunks/{chunk-CJSHWQXP.js → chunk-ORQ2YBRR.js} +2 -2
- package/dist/cli/chunks/chunk-OWIQR6N2.js +4 -0
- package/dist/cli/chunks/{chunk-NAEWCFQT.js → chunk-OWIZBZLN.js} +2 -2
- package/dist/cli/chunks/{chunk-24QHCVX6.js → chunk-P3D7SEHW.js} +1 -1
- package/dist/cli/chunks/{chunk-YLMNVLDK.js → chunk-P4OB6WDJ.js} +1 -1
- package/dist/cli/chunks/{chunk-PEQDY4BO.js → chunk-PCL5JRKN.js} +2 -2
- package/dist/cli/chunks/{chunk-IUBJVHNB.js → chunk-PIWGKGWP.js} +2 -2
- package/dist/cli/chunks/{chunk-GJYHWYXR.js → chunk-PK34KJH7.js} +2 -2
- package/dist/cli/chunks/{chunk-5B5QPCNU.js → chunk-POPSZDI2.js} +4 -4
- package/dist/cli/chunks/{chunk-HCH4Y6XX.js → chunk-Q6F3DYZN.js} +2 -2
- package/dist/cli/chunks/{chunk-SHKOCGNK.js → chunk-QJSSUBO3.js} +2 -2
- package/dist/cli/chunks/{chunk-DVYHMDFR.js → chunk-QN7HP2UW.js} +421 -418
- package/dist/cli/chunks/{chunk-ZFL436FN.js → chunk-QSQNXBD2.js} +2 -2
- package/dist/cli/chunks/{chunk-TVGI32MB.js → chunk-QTQDX4TZ.js} +3 -3
- package/dist/cli/chunks/{chunk-EK7OLYOZ.js → chunk-R3KBOQ3O.js} +2 -2
- package/dist/cli/chunks/{chunk-LE4QJREF.js → chunk-REY52O7J.js} +1 -1
- package/dist/cli/chunks/{chunk-LQLPB2T6.js → chunk-RKCN4B26.js} +2 -2
- package/dist/cli/chunks/{chunk-ZR2TKVXQ.js → chunk-S3DT5TPR.js} +2 -2
- package/dist/cli/chunks/{chunk-6ICX3FEG.js → chunk-S3TBOKAZ.js} +22 -22
- package/dist/cli/chunks/{chunk-JHQCRRJI.js → chunk-SAEECT23.js} +2 -2
- package/dist/cli/chunks/{chunk-VWPM27GU.js → chunk-SAZ4PJBR.js} +2 -2
- package/dist/cli/chunks/{chunk-KPRCB5LT.js → chunk-SFITYZLV.js} +2 -2
- package/dist/cli/chunks/{chunk-5LAVKGLH.js → chunk-SRBCBVSI.js} +2 -2
- package/dist/cli/chunks/{chunk-O5W3FIO6.js → chunk-SUAZ5Z47.js} +2 -2
- package/dist/cli/chunks/{chunk-KU2AUFGX.js → chunk-TDZ6N43D.js} +2 -2
- package/dist/cli/chunks/{chunk-YAPLJR7K.js → chunk-TIVKDIF7.js} +2 -2
- package/dist/cli/chunks/{chunk-U2A7NHZA.js → chunk-TM75GAXG.js} +2 -2
- package/dist/cli/chunks/{chunk-A5GBXCP5.js → chunk-TWBZONKT.js} +2 -2
- package/dist/cli/chunks/{chunk-I7MQIM2U.js → chunk-U4S74IIZ.js} +1 -1
- package/dist/cli/chunks/{chunk-3HD7E6HN.js → chunk-U5SMBJ6F.js} +2 -2
- package/dist/cli/chunks/{chunk-JQ3DYUMS.js → chunk-UHJVZEQA.js} +2 -2
- package/dist/cli/chunks/{chunk-C5FP5GW3.js → chunk-UOVCTK5L.js} +2 -2
- package/dist/cli/chunks/{chunk-HJ6ZGVTB.js → chunk-VDEKVIP5.js} +2 -2
- package/dist/cli/chunks/{chunk-KXCLACFG.js → chunk-VITV7AEC.js} +2 -2
- package/dist/cli/chunks/{chunk-P3EYRILV.js → chunk-VKREKVFI.js} +2 -2
- package/dist/cli/chunks/{chunk-2H4XH6FT.js → chunk-VLTDW7XJ.js} +2 -2
- package/dist/cli/chunks/{chunk-MD43XRX5.js → chunk-VQFV2IPV.js} +1 -1
- package/dist/cli/chunks/{chunk-67Z5R7RJ.js → chunk-VYPVU3JF.js} +2 -2
- package/dist/cli/chunks/{chunk-SDLWKRVL.js → chunk-WAOEQA3W.js} +2 -2
- package/dist/cli/chunks/{chunk-IOYG4VFL.js → chunk-WBDWHHKP.js} +2 -2
- package/dist/cli/chunks/{chunk-ASEOFRIG.js → chunk-WX4PO65Q.js} +2 -2
- package/dist/cli/chunks/chunk-X2DWHGCC.js +6 -0
- package/dist/cli/chunks/{chunk-CEYSYSK5.js → chunk-X5QD76IU.js} +2 -2
- package/dist/cli/chunks/{chunk-GSKMOPL7.js → chunk-XBTGEYED.js} +2 -2
- package/dist/cli/chunks/{chunk-FL64OUBA.js → chunk-XEMCHGAJ.js} +2 -2
- package/dist/cli/chunks/{chunk-2YZ4G6NW.js → chunk-XEYFZLIT.js} +1 -1
- package/dist/cli/chunks/{chunk-EA4YQVKS.js → chunk-XFTX3KLE.js} +1 -1
- package/dist/cli/chunks/{chunk-HGWXF45W.js → chunk-XPTCQKVE.js} +1 -1
- package/dist/cli/chunks/{chunk-CAKMOVZ6.js → chunk-YAJOBZE5.js} +2 -2
- package/dist/cli/chunks/{chunk-NQXXI77K.js → chunk-YCVLKU6H.js} +2 -2
- package/dist/cli/chunks/{chunk-AR67RJPY.js → chunk-YD2C6EPN.js} +2 -2
- package/dist/cli/chunks/{chunk-S75SOOZL.js → chunk-YKRLUTK7.js} +2 -2
- package/dist/cli/chunks/{chunk-IOKYCMTJ.js → chunk-YMUY3TES.js} +2 -2
- package/dist/cli/chunks/{chunk-5QO3R3TU.js → chunk-YR5QBUHZ.js} +2 -2
- package/dist/cli/chunks/{chunk-AJMJNQMP.js → chunk-Z7SKUC6P.js} +1 -1
- package/dist/cli/chunks/{chunk-KITOPKRG.js → chunk-ZAQMRFBB.js} +2 -2
- package/dist/cli/chunks/{chunk-AAMLQ2LF.js → chunk-ZC3KDNJW.js} +3 -3
- package/dist/cli/chunks/{chunk-VJCIEHEF.js → chunk-ZGV7L4MW.js} +1 -1
- package/dist/cli/chunks/{chunk-BY5OF7OH.js → chunk-ZN35XSKF.js} +2 -2
- package/dist/cli/chunks/{chunk-KKU2QGSJ.js → chunk-ZNXM6WVL.js} +2 -2
- package/dist/cli/chunks/{chunk-FLNAW7C4.js → chunk-ZP5AWQRO.js} +2 -2
- package/dist/cli/chunks/{chunk-IHRXZZQM.js → chunk-ZTP3DQ5M.js} +1 -1
- package/dist/cli/chunks/{chunk-OAEE6JWQ.js → chunk-ZVMSSCTH.js} +2 -2
- package/dist/cli/chunks/{chunk-M7WJCTG3.js → chunk-ZWUF27P4.js} +2 -2
- package/dist/cli/chunks/{ci-MFUR4CWV.js → ci-3RTTTS2D.js} +2 -2
- package/dist/cli/chunks/{ci-config-PNDLQ6XV.js → ci-config-XRUR3I4K.js} +2 -2
- package/dist/cli/chunks/{ci-output-PFZ4M7NC.js → ci-output-E5IAMU2U.js} +2 -2
- package/dist/cli/chunks/{circuit-breaker-5HH6NLZN.js → circuit-breaker-SHR2P44P.js} +2 -2
- package/dist/cli/chunks/{claude-flow-setup-QCKYLGLC.js → claude-flow-setup-ZDDILFMF.js} +2 -2
- package/dist/cli/chunks/client-NO5FOWT4.js +2 -0
- package/dist/cli/chunks/{cline-installer-EASVPFXR.js → cline-installer-BGYVUM6G.js} +2 -2
- package/dist/cli/chunks/{code-UJXDVYRK.js → code-PJ4MC3MC.js} +3 -3
- package/dist/cli/chunks/{code-index-extractor-BZJ3UDP4.js → code-index-extractor-IW2P22YG.js} +2 -2
- package/dist/cli/chunks/{codex-installer-XSQZUVOZ.js → codex-installer-A7WZ6OGL.js} +2 -2
- package/dist/cli/chunks/{completions-OWOOJFI2.js → completions-KS23WD5J.js} +2 -2
- package/dist/cli/chunks/{complexity-analyzer-KP5TOHDT.js → complexity-analyzer-Q7GLSR2E.js} +2 -2
- package/dist/cli/chunks/{continuedev-installer-IFKQXLHM.js → continuedev-installer-SK55BFW2.js} +2 -2
- package/dist/cli/chunks/copilot-installer-3N5J3WTM.js +3 -0
- package/dist/cli/chunks/core-handlers-JNAZPXE2.js +2 -0
- package/dist/cli/chunks/{cost-tracker-MMDDNKZB.js → cost-tracker-NENVSO4A.js} +2 -2
- package/dist/cli/chunks/{coverage-LUH2B7NT.js → coverage-5L7UQWDH.js} +3 -3
- package/dist/cli/chunks/cross-domain-router-HEBM767Z.js +2 -0
- package/dist/cli/chunks/{cursor-installer-4YLM5GWM.js → cursor-installer-XXBO2ZE6.js} +2 -2
- package/dist/cli/chunks/{daemon-MZKVM4CJ.js → daemon-CDCQU3LR.js} +3 -3
- package/dist/cli/chunks/{daemon-CAVZ7OFV.js → daemon-JEBJGEUK.js} +4 -4
- package/dist/cli/chunks/{dag-attention-scheduler-X4CYW665.js → dag-attention-scheduler-HOMMF7FA.js} +2 -2
- package/dist/cli/chunks/{detect-7BM2XINO.js → detect-FXCOUG6X.js} +2 -2
- package/dist/cli/chunks/{dist-node-Y5APLEYB.js → dist-node-GXQ7FMTY.js} +2 -2
- package/dist/cli/chunks/{domain-handler-X3ZRJNAH.js → domain-handler-TI3JBAPC.js} +2 -2
- package/dist/cli/chunks/{domain-plugins-2UW5KQJB.js → domain-plugins-R7LTUM32.js} +2 -2
- package/dist/cli/chunks/{domain-transfer-35W4CIBV.js → domain-transfer-LBIAFHIQ.js} +2 -2
- package/dist/cli/chunks/dream-GQDCEJMS.js +2 -0
- package/dist/cli/chunks/embed-and-insert-pattern-33KLHDD5.js +3 -0
- package/dist/cli/chunks/{embedding-space-SBM2MZD2.js → embedding-space-HHLWTBF5.js} +2 -2
- package/dist/cli/chunks/{eval-4QA2SROK.js → eval-KDOZMAXJ.js} +2 -2
- package/dist/cli/chunks/{experience-capture-middleware-Z6BF6KYM.js → experience-capture-middleware-X45PECQN.js} +3 -3
- package/dist/cli/chunks/{fast-paths-FIORX6GN.js → fast-paths-462V6UUB.js} +2 -2
- package/dist/cli/chunks/{feature-flags-ZOO7LMIC.js → feature-flags-G66OT3AS.js} +2 -2
- package/dist/cli/chunks/{feature-flags-6LYI2T4G.js → feature-flags-NIRQ4YDM.js} +2 -2
- package/dist/cli/chunks/file-discovery-33USPLB5.js +2 -0
- package/dist/cli/chunks/{fleet-7WF53H4F.js → fleet-PXWGB7CU.js} +3 -3
- package/dist/cli/chunks/{gnn-wrapper-KJ6B7BRM.js → gnn-wrapper-7MUW3M5M.js} +2 -2
- package/dist/cli/chunks/{heartbeat-handler-DEKKMOVW.js → heartbeat-handler-5237PB35.js} +4 -4
- package/dist/cli/chunks/heartbeat-scheduler-LIXLC5IH.js +2 -0
- package/dist/cli/chunks/hnsw-adapter-62D5UH27.js +2 -0
- package/dist/cli/chunks/hnsw-index-GSGUMQQC.js +2 -0
- package/dist/cli/chunks/{hnsw-legacy-bridge-L27WS27N.js → hnsw-legacy-bridge-OSQPW7JP.js} +2 -2
- package/dist/cli/chunks/{hnswlib-node-4YOQC6L4.js → hnswlib-node-GX6WG2GB.js} +2 -2
- package/dist/cli/chunks/{hooks-TAOKV4EJ.js → hooks-GUWHL7VC.js} +10 -10
- package/dist/cli/chunks/hybrid-backend-FRWP4BOY.js +2 -0
- package/dist/cli/chunks/{hypergraph-engine-BODRJLHL.js → hypergraph-engine-SRWLLCU3.js} +2 -2
- package/dist/cli/chunks/{hypergraph-handler-RKMYJNTU.js → hypergraph-handler-AVOPRHHO.js} +3 -3
- package/dist/cli/chunks/impact-analyzer-7KF3AQXV.js +2 -0
- package/dist/cli/chunks/{init-guard-MXHSLSB2.js → init-guard-P4N6EVZS.js} +2 -2
- package/dist/cli/chunks/{init-handler-HUE57IFW.js → init-handler-LRGWOJMD.js} +6 -6
- package/dist/cli/chunks/init-wizard-XWWAXY25.js +2 -0
- package/dist/cli/chunks/kernel-ZEJPNDBW.js +2 -0
- package/dist/cli/chunks/{kilocode-installer-S333IKYQ.js → kilocode-installer-7R2EPOQ6.js} +2 -2
- package/dist/cli/chunks/{kiro-installer-WM5DLQWC.js → kiro-installer-QNM7DPOB.js} +2 -2
- package/dist/cli/chunks/knowledge-graph-RRZQS7KY.js +2 -0
- package/dist/cli/chunks/{learning-LNHMQLH5.js → learning-7OIZBPXZ.js} +3 -3
- package/dist/cli/chunks/{llm-router-EWFXYZZR.js → llm-router-SIDXES23.js} +4 -4
- package/dist/cli/chunks/llm-router-service-3OSW67LC.js +2 -0
- package/dist/cli/chunks/{load-FGYGWVDK.js → load-EI2E2C3S.js} +2 -2
- package/dist/cli/chunks/load-test-7TRIH2WJ.js +2 -0
- package/dist/cli/chunks/{mcp-2FHNAAOM.js → mcp-IOE5WOCS.js} +2 -2
- package/dist/cli/chunks/{memory-DZMQ73AB.js → memory-DLYGJAP7.js} +5 -5
- package/dist/cli/chunks/memory-backend-G7ZW6Q2B.js +2 -0
- package/dist/cli/chunks/memory-handlers-TPF3KCO5.js +2 -0
- package/dist/cli/chunks/{multi-model-executor-6F2UAEUW.js → multi-model-executor-WHH4YCHM.js} +2 -2
- package/dist/cli/chunks/{opencode-installer-XY3BGOTZ.js → opencode-installer-63FDZAMS.js} +2 -2
- package/dist/cli/chunks/{orchestrator-B4CNKUOS.js → orchestrator-3LA776KK.js} +5 -5
- package/dist/cli/chunks/pattern-null-store-OU3ZC3NR.js +2 -0
- package/dist/cli/chunks/{pattern-usage-recorder-R4GUFNMD.js → pattern-usage-recorder-NW54QUGI.js} +2 -2
- package/dist/cli/chunks/{pipeline-FG5RKVRO.js → pipeline-P3TYX6J6.js} +2 -2
- package/dist/cli/chunks/{platform-3BT4KEVJ.js → platform-FNA2WLI6.js} +2 -2
- package/dist/cli/chunks/{plugin-WI4RIN7O.js → plugin-NJS7BC2S.js} +2 -2
- package/dist/cli/chunks/{prime-radiant-advanced-wasm-7ECDNQFS.js → prime-radiant-advanced-wasm-NIAVL2OT.js} +2 -2
- package/dist/cli/chunks/project-root-GMOFJEKD.js +2 -0
- package/dist/cli/chunks/protocol-executor-AD345XRO.js +2 -0
- package/dist/cli/chunks/{protocol-handler-WNODKPGW.js → protocol-handler-JU5C4JHY.js} +2 -2
- package/dist/cli/chunks/{prove-5RHAEPYZ.js → prove-35VOSLYP.js} +2 -2
- package/dist/cli/chunks/qe-reasoning-bank-NLTP26RC.js +2 -0
- package/dist/cli/chunks/{quality-WPHR7BGQ.js → quality-ET74X7HN.js} +2 -2
- package/dist/cli/chunks/{quality-gate-4RKTEZMX.js → quality-gate-FEDQISNB.js} +3 -3
- package/dist/cli/chunks/queen-coordinator-2TB4FWS6.js +2 -0
- package/dist/cli/chunks/real-embeddings-II6CXTCI.js +2 -0
- package/dist/cli/chunks/{ref-validation-TPAWHOHH.js → ref-validation-DTBPYCEB.js} +2 -2
- package/dist/cli/chunks/{roocode-installer-7AVHFNDI.js → roocode-installer-LYQEMR4J.js} +2 -2
- package/dist/cli/chunks/router-PLM3MWME.js +2 -0
- package/dist/cli/chunks/routing-feedback-I7VOX2HU.js +2 -0
- package/dist/cli/chunks/{routing-handler-YKEDVJSH.js → routing-handler-DJOJFPII.js} +2 -2
- package/dist/cli/chunks/{ruvector-commands-JUAMM354.js → ruvector-commands-VXYGJDPW.js} +2 -2
- package/dist/cli/chunks/rvf-dual-writer-GQZHFWO2.js +2 -0
- package/dist/cli/chunks/rvf-migration-adapter-3TVKBCAM.js +2 -0
- package/dist/cli/chunks/rvf-migration-coordinator-XUHKLMT6.js +2 -0
- package/dist/cli/chunks/rvf-native-adapter-5GUTYOWS.js +2 -0
- package/dist/cli/chunks/{rvf-store-integrity-VJDUIRTX.js → rvf-store-integrity-GA2ZYOEG.js} +2 -2
- package/dist/cli/chunks/safe-db-RZPQGLGQ.js +2 -0
- package/dist/cli/chunks/schedule-G7JMQDUX.js +2 -0
- package/dist/cli/chunks/scheduler-4SEGPCKD.js +2 -0
- package/dist/cli/chunks/{security-ORDN3RD2.js → security-MM6YOECX.js} +3 -3
- package/dist/cli/chunks/{shared-rvf-adapter-CF4BCIO7.js → shared-rvf-adapter-6AHPA3V5.js} +2 -2
- package/dist/cli/chunks/{shared-rvf-dual-writer-C32UBR6D.js → shared-rvf-dual-writer-EYAVY2GZ.js} +2 -2
- package/dist/cli/chunks/sqlite-persistence-IVE4SQXR.js +2 -0
- package/dist/cli/chunks/{standalone-memory-OXRJYZXN.js → standalone-memory-A3PLB4CZ.js} +2 -2
- package/dist/cli/chunks/{status-handler-BCX5D4HY.js → status-handler-OSSFAP4Z.js} +2 -2
- package/dist/cli/chunks/{structural-health-LFG7RUU6.js → structural-health-PGY5XUNO.js} +2 -2
- package/dist/cli/chunks/{sync-YJEE2K2L.js → sync-CWEHYGNN.js} +2 -2
- package/dist/cli/chunks/sync-PM6D7EQF.js +2 -0
- package/dist/cli/chunks/{task-handler-6LXKPTXJ.js → task-handler-LHMQ75W4.js} +2 -2
- package/dist/cli/chunks/{task-handlers-CILP36I7.js → task-handlers-S2TX5FTR.js} +3 -3
- package/dist/cli/chunks/test-4EGZZ6NJ.js +34 -0
- package/dist/cli/chunks/test-runner-process-72YACW6M.js +2 -0
- package/dist/cli/chunks/{test-scheduling-ISI2O4Q5.js → test-scheduling-YJQHH3XE.js} +3 -3
- package/dist/cli/chunks/{token-bootstrap-VUELSBOS.js → token-bootstrap-DJNETMVW.js} +2 -2
- package/dist/cli/chunks/{token-usage-XOC5KG7S.js → token-usage-WPNOJR6H.js} +2 -2
- package/dist/cli/chunks/{transformers-LSLQAARK.js → transformers-4MRPXCPU.js} +2 -2
- package/dist/cli/chunks/tree-sitter-wasm-parser-UVWSDXFR.js +2 -0
- package/dist/cli/chunks/{types-5BLCGLCR.js → types-6P5FB4EB.js} +2 -2
- package/dist/cli/chunks/unified-memory-2VMGSGQL.js +2 -0
- package/dist/cli/chunks/unified-memory-hnsw-3KULVD3N.js +2 -0
- package/dist/cli/chunks/unified-persistence-QCSLU2SV.js +2 -0
- package/dist/cli/chunks/{upgrade-RQJYLK3J.js → upgrade-4ICTN63Y.js} +2 -2
- package/dist/cli/chunks/{validate-QBHWXXCK.js → validate-HQF5GZ7L.js} +2 -2
- package/dist/cli/chunks/{validate-swarm-IKXBKFB5.js → validate-swarm-45JYG7VW.js} +2 -2
- package/dist/cli/chunks/visual-security-ZYP2KPH7.js +2 -0
- package/dist/cli/chunks/{web-tree-sitter-ZF6FIE5R.js → web-tree-sitter-UOTWZLNH.js} +2 -2
- package/dist/cli/chunks/{windsurf-installer-HQGDZT5D.js → windsurf-installer-WDWSBXGN.js} +2 -2
- package/dist/cli/chunks/witness-chain-5QRT7EMX.js +2 -0
- package/dist/cli/chunks/{witness-chain-DCHCAMSQ.js → witness-chain-DOYMNPC7.js} +2 -2
- package/dist/cli/chunks/{witness-chain-repair-PUX2NFDL.js → witness-chain-repair-CUF2AFQB.js} +2 -2
- package/dist/cli/chunks/{witness-chain-verifier-PX2OQ6XT.js → witness-chain-verifier-JB42X62J.js} +2 -2
- package/dist/cli/chunks/{witness-key-manager-RXYQNFJB.js → witness-key-manager-LXXO6L2G.js} +2 -2
- package/dist/cli/chunks/{workflow-FBKCA4H6.js → workflow-6ARK47NF.js} +4 -4
- package/dist/cli/chunks/workflow-orchestrator-RYDDWIXN.js +2 -0
- package/dist/cli/chunks/{wrappers-TWSKBTWD.js → wrappers-CYQBOMPL.js} +2 -2
- package/dist/cli/commands/test.js +26 -4
- package/dist/coordination/handlers/test-execution-handlers.js +64 -20
- package/dist/domains/code-intelligence/services/semantic-analyzer.d.ts +8 -3
- package/dist/domains/code-intelligence/services/semantic-analyzer.js +39 -25
- package/dist/domains/code-intelligence/services/text-relevance.d.ts +32 -0
- package/dist/domains/code-intelligence/services/text-relevance.js +63 -0
- package/dist/domains/test-execution/coordinator.d.ts +3 -1
- package/dist/domains/test-execution/coordinator.js +13 -4
- package/dist/domains/test-execution/interfaces.d.ts +5 -0
- package/dist/domains/test-execution/plugin.js +2 -0
- package/dist/domains/test-execution/services/flaky-detector.d.ts +9 -1
- package/dist/domains/test-execution/services/flaky-detector.js +26 -8
- package/dist/domains/test-execution/services/retry-handler.d.ts +7 -1
- package/dist/domains/test-execution/services/retry-handler.js +44 -5
- package/dist/domains/test-execution/services/runner-test-cases.d.ts +2 -0
- package/dist/domains/test-execution/services/runner-test-cases.js +7 -3
- package/dist/domains/test-execution/services/test-executor.d.ts +5 -1
- package/dist/domains/test-execution/services/test-executor.js +79 -15
- package/dist/init/copilot-installer.d.ts +6 -0
- package/dist/init/copilot-installer.js +37 -17
- package/dist/init/platform-config-generator.d.ts +10 -0
- package/dist/init/platform-config-generator.js +26 -1
- package/dist/kernel/unified-memory.d.ts +8 -0
- package/dist/kernel/unified-memory.js +13 -0
- package/dist/learning/embedder-endpoint-client.d.ts +45 -0
- package/dist/learning/embedder-endpoint-client.js +98 -3
- package/dist/learning/embedding-space-registry.d.ts +75 -0
- package/dist/learning/embedding-space-registry.js +142 -0
- package/dist/learning/real-embeddings.d.ts +3 -0
- package/dist/learning/real-embeddings.js +49 -11
- package/dist/mcp/bundle.js +564 -555
- package/dist/mcp/protocol-server.js +1 -1
- package/dist/shared/embeddings/index.d.ts +2 -2
- package/dist/shared/embeddings/index.js +1 -1
- package/dist/shared/embeddings/nomic-embedder.d.ts +8 -2
- package/dist/shared/embeddings/nomic-embedder.js +19 -11
- package/dist/shared/embeddings/ollama-client.d.ts +28 -2
- package/dist/shared/embeddings/ollama-client.js +84 -22
- package/dist/shared/embeddings/types.d.ts +15 -0
- package/dist/shared/embeddings/types.js +4 -0
- package/dist/shared/pytest-junit-report.d.ts +93 -0
- package/dist/shared/pytest-junit-report.js +241 -0
- package/dist/shared/test-runner-project.d.ts +51 -1
- package/dist/shared/test-runner-project.js +140 -25
- package/package.json +1 -1
- package/dist/cli/chunks/adapter-6CQ2PIP5.js +0 -2
- package/dist/cli/chunks/aqe-learning-engine-73RR52VS.js +0 -2
- package/dist/cli/chunks/base-SMCMMVGP.js +0 -2
- package/dist/cli/chunks/browser-workflow-A2MEZ66K.js +0 -2
- package/dist/cli/chunks/chunk-EGYE5UPQ.js +0 -2
- package/dist/cli/chunks/chunk-KL7OKSU2.js +0 -4
- package/dist/cli/chunks/chunk-M4FRQ4TE.js +0 -12
- package/dist/cli/chunks/chunk-UE5ZOZR2.js +0 -2
- package/dist/cli/chunks/client-MHQRTZM4.js +0 -2
- package/dist/cli/chunks/copilot-installer-IGJ6KGQY.js +0 -3
- package/dist/cli/chunks/core-handlers-UAK3LLJE.js +0 -2
- package/dist/cli/chunks/cross-domain-router-WTRZQPNQ.js +0 -2
- package/dist/cli/chunks/dream-EJY24JN6.js +0 -2
- package/dist/cli/chunks/embed-and-insert-pattern-COG4C7ZI.js +0 -3
- package/dist/cli/chunks/file-discovery-UZSFSS4V.js +0 -2
- package/dist/cli/chunks/heartbeat-scheduler-NVR356I7.js +0 -2
- package/dist/cli/chunks/hnsw-adapter-LFMPLUJU.js +0 -2
- package/dist/cli/chunks/hnsw-index-POCPMVJH.js +0 -2
- package/dist/cli/chunks/hybrid-backend-4STAO7CV.js +0 -2
- package/dist/cli/chunks/impact-analyzer-3VIIISBQ.js +0 -2
- package/dist/cli/chunks/init-wizard-PL6QN6RQ.js +0 -2
- package/dist/cli/chunks/kernel-CCDWT7KS.js +0 -2
- package/dist/cli/chunks/knowledge-graph-KFOMEN3H.js +0 -2
- package/dist/cli/chunks/llm-router-service-7NBE2EX6.js +0 -2
- package/dist/cli/chunks/load-test-UNZUWY3F.js +0 -2
- package/dist/cli/chunks/memory-backend-DFGKWA2Q.js +0 -2
- package/dist/cli/chunks/memory-handlers-MP426XRJ.js +0 -2
- package/dist/cli/chunks/pattern-null-store-SSVF5TE5.js +0 -2
- package/dist/cli/chunks/project-root-BEANNYWU.js +0 -2
- package/dist/cli/chunks/protocol-executor-FQVIHXZ7.js +0 -2
- package/dist/cli/chunks/qe-reasoning-bank-5TFYSE24.js +0 -2
- package/dist/cli/chunks/queen-coordinator-Y2OUL7IN.js +0 -2
- package/dist/cli/chunks/real-embeddings-OXLYU7JW.js +0 -2
- package/dist/cli/chunks/router-EP34O3KB.js +0 -2
- package/dist/cli/chunks/routing-feedback-FJCRKXNG.js +0 -2
- package/dist/cli/chunks/rvf-dual-writer-ILITJSFG.js +0 -2
- package/dist/cli/chunks/rvf-migration-adapter-XF6W4C2N.js +0 -2
- package/dist/cli/chunks/rvf-migration-coordinator-CMKG56AR.js +0 -2
- package/dist/cli/chunks/rvf-native-adapter-7YFW6S4Y.js +0 -2
- package/dist/cli/chunks/safe-db-TCAU4FUT.js +0 -2
- package/dist/cli/chunks/schedule-NB5KV435.js +0 -2
- package/dist/cli/chunks/scheduler-JKXGKVK6.js +0 -2
- package/dist/cli/chunks/sqlite-persistence-IXCNZRTW.js +0 -2
- package/dist/cli/chunks/sync-OSF7C2NL.js +0 -2
- package/dist/cli/chunks/test-SD457QJ6.js +0 -34
- package/dist/cli/chunks/test-runner-process-VKD65QQU.js +0 -2
- package/dist/cli/chunks/tree-sitter-wasm-parser-YAIPHRIL.js +0 -2
- package/dist/cli/chunks/unified-memory-GI76TXFV.js +0 -2
- package/dist/cli/chunks/unified-memory-hnsw-GXJ5BTZO.js +0 -2
- package/dist/cli/chunks/unified-persistence-OP7FDQPD.js +0 -2
- package/dist/cli/chunks/visual-security-GZ2MOKWB.js +0 -2
- package/dist/cli/chunks/witness-chain-P3XXXA62.js +0 -2
- package/dist/cli/chunks/workflow-orchestrator-P2APAJAA.js +0 -2
|
@@ -7,6 +7,7 @@ import { spawn } from 'node:child_process';
|
|
|
7
7
|
import { createVitestJsonReport } from '../../../shared/vitest-json-report.js';
|
|
8
8
|
import { jestExactPathPattern, nameFilterArg, runnerFilePath } from '../../../shared/test-runner-args.js';
|
|
9
9
|
import { runnerCwdFor } from '../../../shared/test-runner-project.js';
|
|
10
|
+
import { createPytestJunitReport, isPythonTestFile, parsePytestJunitXml, pytestCommand, PYTEST_ENV, } from '../../../shared/pytest-junit-report.js';
|
|
10
11
|
import { existsSync, readFileSync, realpathSync } from 'node:fs';
|
|
11
12
|
import { resolve as resolvePath } from 'node:path';
|
|
12
13
|
import { ok, err } from '../../../shared/types/index.js';
|
|
@@ -300,8 +301,8 @@ export class RetryHandlerService {
|
|
|
300
301
|
// projectRoot, else a configured directory, else the file's runner
|
|
301
302
|
// project. The file path stays relative to `cwd`.
|
|
302
303
|
const runCwd = projectRoot ?? this.config.cwd ?? runnerCwdFor(testFile);
|
|
303
|
-
// Detect or use configured test runner
|
|
304
|
-
const runner = await this.detectTestRunner(runCwd);
|
|
304
|
+
// Detect or use configured test runner. #1248: a Python file is pytest's.
|
|
305
|
+
const runner = isPythonTestFile(testFile) ? 'pytest' : await this.detectTestRunner(runCwd);
|
|
305
306
|
if (!runner) {
|
|
306
307
|
throw new Error(`No test runner detected or configured. Install vitest, jest, or mocha, ` +
|
|
307
308
|
`or configure testRunner in RetryHandlerConfig. Cannot execute retry for: ${testFile}`);
|
|
@@ -309,7 +310,7 @@ export class RetryHandlerService {
|
|
|
309
310
|
// Build command based on runner
|
|
310
311
|
const { command, args, report } = this.buildTestCommand(runner, testFile, testName, cwd);
|
|
311
312
|
// Execute the test
|
|
312
|
-
return this.spawnTestProcess(command, args, runCwd, report, runner === 'vitest' ? testFile : undefined);
|
|
313
|
+
return this.spawnTestProcess(command, args, runCwd, report, runner === 'vitest' ? testFile : undefined, runner === 'pytest' ? (code, reportText, output) => this.parsePytestRetry(code, reportText, output) : undefined);
|
|
313
314
|
}
|
|
314
315
|
/**
|
|
315
316
|
* Detect which test runner is available in the project
|
|
@@ -415,6 +416,13 @@ export class RetryHandlerService {
|
|
|
415
416
|
mochaArgs.push(nameFilterArg('mocha', testName));
|
|
416
417
|
return { command: npx, args: mochaArgs };
|
|
417
418
|
}
|
|
419
|
+
case 'pytest':
|
|
420
|
+
// #1248: the failed test's node id is <file>::<name> (name from the run).
|
|
421
|
+
{
|
|
422
|
+
const report = createPytestJunitReport();
|
|
423
|
+
const file = runnerFilePath(testFile, cwd);
|
|
424
|
+
return { ...pytestCommand([filterByName ? `${file}::${testName}` : file], report.path), report };
|
|
425
|
+
}
|
|
418
426
|
default:
|
|
419
427
|
throw new Error(`Unsupported test runner: ${runner}`);
|
|
420
428
|
}
|
|
@@ -422,7 +430,7 @@ export class RetryHandlerService {
|
|
|
422
430
|
/**
|
|
423
431
|
* Spawn a test process and parse the result
|
|
424
432
|
*/
|
|
425
|
-
spawnTestProcess(command, args, cwd, report, targetFile) {
|
|
433
|
+
spawnTestProcess(command, args, cwd, report, targetFile, parseReport) {
|
|
426
434
|
return new Promise((resolve, reject) => {
|
|
427
435
|
const timeout = this.config.testTimeout;
|
|
428
436
|
let stdout = '';
|
|
@@ -439,7 +447,7 @@ export class RetryHandlerService {
|
|
|
439
447
|
const proc = spawn(command, args, {
|
|
440
448
|
cwd,
|
|
441
449
|
detached: process.platform !== 'win32',
|
|
442
|
-
env: { ...process.env, FORCE_COLOR: '0', CI: 'true' },
|
|
450
|
+
env: { ...process.env, FORCE_COLOR: '0', CI: 'true', ...PYTEST_ENV },
|
|
443
451
|
});
|
|
444
452
|
const untrackExit = trackTestRunnerExit(proc);
|
|
445
453
|
const timeoutHandle = setTimeout(() => {
|
|
@@ -470,6 +478,10 @@ export class RetryHandlerService {
|
|
|
470
478
|
// report to the --outputFile; read it back rather than trusting stdout).
|
|
471
479
|
try {
|
|
472
480
|
const reportText = report ? report.read(stdout) : stdout;
|
|
481
|
+
if (parseReport) {
|
|
482
|
+
settle(resolve, parseReport(code, reportText, `${stderr}\n${stdout}`.trim()));
|
|
483
|
+
return;
|
|
484
|
+
}
|
|
473
485
|
if (reportText === undefined) {
|
|
474
486
|
throw new Error('The current Vitest JSON report is missing for the retry run.');
|
|
475
487
|
}
|
|
@@ -489,6 +501,33 @@ export class RetryHandlerService {
|
|
|
489
501
|
});
|
|
490
502
|
});
|
|
491
503
|
}
|
|
504
|
+
/**
|
|
505
|
+
* #1248: a pytest retry passes only when its JUnit report shows the test
|
|
506
|
+
* passed. A node id pytest cannot find (exit code 4) or no collected test
|
|
507
|
+
* (exit code 5) reran nothing.
|
|
508
|
+
*/
|
|
509
|
+
parsePytestRetry(exitCode, report, output) {
|
|
510
|
+
const failure = (text) => ({
|
|
511
|
+
passed: false,
|
|
512
|
+
error: redactFailureText(text || `pytest exited with code ${exitCode}`).substring(0, 1000),
|
|
513
|
+
});
|
|
514
|
+
if (exitCode === 4 || exitCode === 5)
|
|
515
|
+
return UNMATCHED;
|
|
516
|
+
if (report === undefined)
|
|
517
|
+
return failure(output);
|
|
518
|
+
try {
|
|
519
|
+
const cases = parsePytestJunitXml(report);
|
|
520
|
+
if (cases.length === 0)
|
|
521
|
+
return UNMATCHED;
|
|
522
|
+
const failed = cases.find(c => c.status === 'failed' || c.status === 'error');
|
|
523
|
+
if (exitCode === 0 && !failed && cases.some(c => c.status === 'passed'))
|
|
524
|
+
return { passed: true };
|
|
525
|
+
return failure(failed ? [failed.message, failed.details].filter(Boolean).join('\n') : output);
|
|
526
|
+
}
|
|
527
|
+
catch {
|
|
528
|
+
return failure(output);
|
|
529
|
+
}
|
|
530
|
+
}
|
|
492
531
|
/**
|
|
493
532
|
* Parse test runner output to determine pass/fail status
|
|
494
533
|
*/
|
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
* derived from aggregate counts.
|
|
7
7
|
*/
|
|
8
8
|
import type { ITestCaseResult } from '../interfaces';
|
|
9
|
+
/** A test case's failure text: redacted (#1122) and capped. */
|
|
10
|
+
export declare function testCaseFailureMessage(text: string): string | undefined;
|
|
9
11
|
/**
|
|
10
12
|
* #1122: failure text goes back over MCP and into saved results, so
|
|
11
13
|
* credential-shaped values (e.g. a connection string) are redacted first.
|
|
@@ -12,10 +12,14 @@ const MAX_FAILURE_MESSAGE_LENGTH = 4000;
|
|
|
12
12
|
function failureMessageOf(assertion) {
|
|
13
13
|
if (!Array.isArray(assertion.failureMessages))
|
|
14
14
|
return undefined;
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
return testCaseFailureMessage(assertion.failureMessages.filter((m) => typeof m === 'string').join('\n'));
|
|
16
|
+
}
|
|
17
|
+
/** A test case's failure text: redacted (#1122) and capped. */
|
|
18
|
+
export function testCaseFailureMessage(text) {
|
|
19
|
+
const trimmed = text.trim();
|
|
20
|
+
if (!trimmed)
|
|
17
21
|
return undefined;
|
|
18
|
-
const message = redactFailureText(
|
|
22
|
+
const message = redactFailureText(trimmed);
|
|
19
23
|
return message.length > MAX_FAILURE_MESSAGE_LENGTH
|
|
20
24
|
? `${message.slice(0, MAX_FAILURE_MESSAGE_LENGTH)}… [truncated]`
|
|
21
25
|
: message;
|
|
@@ -115,7 +115,7 @@ export declare class TestExecutorService implements ITestExecutionService {
|
|
|
115
115
|
private executeTestFiles;
|
|
116
116
|
private executeProjectFiles;
|
|
117
117
|
/**
|
|
118
|
-
* Spawn actual test runner process (vitest, jest, mocha)
|
|
118
|
+
* Spawn actual test runner process (vitest, jest, mocha, node:test, pytest)
|
|
119
119
|
*/
|
|
120
120
|
private spawnTestRunner;
|
|
121
121
|
/**
|
|
@@ -126,6 +126,10 @@ export declare class TestExecutorService implements ITestExecutionService {
|
|
|
126
126
|
* Parse test runner output to extract results
|
|
127
127
|
*/
|
|
128
128
|
private parseTestOutput;
|
|
129
|
+
/**
|
|
130
|
+
* #1248: a pytest run from its JUnit report (undefined when pytest wrote none).
|
|
131
|
+
*/
|
|
132
|
+
private parsePytestOutput;
|
|
129
133
|
/**
|
|
130
134
|
* Parse the TAP or spec summary emitted by Node's built-in test runner.
|
|
131
135
|
*/
|
|
@@ -17,11 +17,12 @@ import { secureRandom, secureRandomInt } from '../../../shared/utils/crypto-rand
|
|
|
17
17
|
import { writeTestRunEvidence } from '../../quality-assessment/quality-evidence.js';
|
|
18
18
|
import { istanbulLineHits } from '../../../coordination/handlers/handler-utils.js';
|
|
19
19
|
import { fileCoverageKey, projectFileCoverageKeys } from '../../coverage-analysis/collected-metrics.js';
|
|
20
|
-
import { mergeTestCases, redactFailedTests, redactFailureText, testCasesFromRunnerReport } from './runner-test-cases.js';
|
|
20
|
+
import { mergeTestCases, redactFailedTests, redactFailureText, testCaseFailureMessage, testCasesFromRunnerReport } from './runner-test-cases.js';
|
|
21
21
|
import { capDiagnostics, getTestRunnerExecutionError, TestRunnerExecutionError } from '../../../shared/test-runner-verdict.js';
|
|
22
22
|
import { createVitestJsonReport } from '../../../shared/vitest-json-report.js';
|
|
23
|
+
import { createPytestJunitReport, isPythonTestFile, pytestCommand, pytestRunFromReport, PYTEST_ENV } from '../../../shared/pytest-junit-report.js';
|
|
23
24
|
import { jestExactPathPattern, runnerFilePath } from '../../../shared/test-runner-args.js';
|
|
24
|
-
import { groupByRunnerProject } from '../../../shared/test-runner-project.js';
|
|
25
|
+
import { groupByRunnerProject, runnerFrameworkFor } from '../../../shared/test-runner-project.js';
|
|
25
26
|
import { getClaudeModelForTier } from '../../../shared/llm/model-registry.js';
|
|
26
27
|
import { terminateTestRunner, trackTestRunnerExit } from '../../../shared/test-runner-process.js';
|
|
27
28
|
const DEFAULT_CONFIG = {
|
|
@@ -315,7 +316,7 @@ Provide:
|
|
|
315
316
|
return ok(undefined);
|
|
316
317
|
}
|
|
317
318
|
async runTests(request) {
|
|
318
|
-
const { testFiles, framework, timeout = 30000, projectRoot } = request;
|
|
319
|
+
const { testFiles, framework, timeout = 30000, projectRoot, frameworkFromConfig } = request;
|
|
319
320
|
const failedTests = [];
|
|
320
321
|
const coverages = [];
|
|
321
322
|
const allFileCoverages = [];
|
|
@@ -324,7 +325,7 @@ Provide:
|
|
|
324
325
|
let failed = 0;
|
|
325
326
|
let skipped = 0;
|
|
326
327
|
for (const file of testFiles) {
|
|
327
|
-
const result = await this.executeTestFile(file, framework, timeout, projectRoot);
|
|
328
|
+
const result = await this.executeTestFile(file, framework, timeout, projectRoot, frameworkFromConfig);
|
|
328
329
|
executionResults.push(result);
|
|
329
330
|
passed += result.passed;
|
|
330
331
|
failed += result.failed;
|
|
@@ -394,25 +395,40 @@ Provide:
|
|
|
394
395
|
const coverage = this.extractCoverageFromJson({ coverageMap: merged });
|
|
395
396
|
return coverage.summary ? { summary: coverage.summary, perFile: coverage.perFile } : undefined;
|
|
396
397
|
}
|
|
397
|
-
async executeTestFile(file, framework, timeout, projectRoot) {
|
|
398
|
-
return this.executeTestFiles([file], framework, timeout, projectRoot);
|
|
398
|
+
async executeTestFile(file, framework, timeout, projectRoot, frameworkFromConfig = false) {
|
|
399
|
+
return this.executeTestFiles([file], framework, timeout, projectRoot, frameworkFromConfig);
|
|
399
400
|
}
|
|
400
|
-
async executeTestFiles(files, framework, timeout, projectRoot) {
|
|
401
|
+
async executeTestFiles(files, framework, timeout, projectRoot, frameworkFromConfig = false) {
|
|
401
402
|
// In simulation mode (for unit testing), use random behavior
|
|
402
403
|
if (this.config.simulateForTesting) {
|
|
403
404
|
return this.aggregateResults(files.map(file => this.simulateTestExecution(file)));
|
|
404
405
|
}
|
|
405
406
|
// #1247: a runner loads the config of the directory it starts in, so each
|
|
406
407
|
// file runs from its own runner project (or the caller's projectRoot).
|
|
408
|
+
// #1248: Python files run apart from the others, with pytest.
|
|
407
409
|
const groups = projectRoot
|
|
408
|
-
? [
|
|
410
|
+
? [files.filter(isPythonTestFile), files.filter(file => !isPythonTestFile(file))]
|
|
411
|
+
.filter(group => group.length > 0)
|
|
412
|
+
.map(group => ({ cwd: projectRoot, files: group }))
|
|
409
413
|
: groupByRunnerProject(files);
|
|
414
|
+
// #1272: an explicit framework wins; otherwise the project's config decides.
|
|
415
|
+
// #1248: Python files run with pytest, never with a JavaScript runner.
|
|
416
|
+
const frameworkIn = (group) => {
|
|
417
|
+
if (group.files.some(isPythonTestFile)) {
|
|
418
|
+
if (frameworkFromConfig || framework.toLowerCase() === 'pytest')
|
|
419
|
+
return 'pytest';
|
|
420
|
+
throw new TestRunnerExecutionError(`Python test files cannot run with ${framework}: ${group.files.filter(isPythonTestFile).join(', ')}. ` +
|
|
421
|
+
`Use framework 'pytest', or leave the framework unset.`);
|
|
422
|
+
}
|
|
423
|
+
return (frameworkFromConfig ? runnerFrameworkFor(group.cwd) : undefined) ?? framework;
|
|
424
|
+
};
|
|
410
425
|
if (groups.length === 1) {
|
|
411
|
-
return this.executeProjectFiles(groups[0].files,
|
|
426
|
+
return this.executeProjectFiles(groups[0].files, frameworkIn(groups[0]), timeout, groups[0].cwd);
|
|
412
427
|
}
|
|
413
428
|
// Each project gets its own runner and timeout. Their coverage maps are
|
|
414
429
|
// merged from raw counters, or left unmeasured (#1030).
|
|
415
|
-
const
|
|
430
|
+
const frameworks = groups.map(frameworkIn);
|
|
431
|
+
const results = await Promise.all(groups.map((group, index) => this.executeProjectFiles(group.files, frameworks[index], timeout, group.cwd)));
|
|
416
432
|
const combined = this.aggregateResults(results);
|
|
417
433
|
const merged = this.mergeSequentialCoverage(results);
|
|
418
434
|
combined.coverage = merged?.summary;
|
|
@@ -445,7 +461,7 @@ Provide:
|
|
|
445
461
|
return result.value;
|
|
446
462
|
}
|
|
447
463
|
/**
|
|
448
|
-
* Spawn actual test runner process (vitest, jest, mocha)
|
|
464
|
+
* Spawn actual test runner process (vitest, jest, mocha, node:test, pytest)
|
|
449
465
|
*/
|
|
450
466
|
async spawnTestRunner(files, framework, timeout, cwd = process.cwd()) {
|
|
451
467
|
// Verify test file exists
|
|
@@ -490,6 +506,7 @@ Provide:
|
|
|
490
506
|
env: {
|
|
491
507
|
...process.env,
|
|
492
508
|
FORCE_COLOR: '0', // Disable color codes for easier parsing
|
|
509
|
+
...PYTEST_ENV, // pytest reads any FORCE_COLOR as "force colour" (#1248)
|
|
493
510
|
CI: 'true', // Enable CI mode for consistent output
|
|
494
511
|
},
|
|
495
512
|
});
|
|
@@ -534,11 +551,15 @@ Provide:
|
|
|
534
551
|
finish(err(toError(error)));
|
|
535
552
|
return;
|
|
536
553
|
}
|
|
537
|
-
|
|
554
|
+
// #1248: pytest reports its own missing report (pytest not installed).
|
|
555
|
+
const pytest = framework.toLowerCase() === 'pytest';
|
|
556
|
+
if (reportText === undefined && !pytest) {
|
|
538
557
|
finish(err(new TestRunnerExecutionError(`The current Vitest JSON report is missing for ${fileLabel}.`)));
|
|
539
558
|
return;
|
|
540
559
|
}
|
|
541
|
-
const parseResult =
|
|
560
|
+
const parseResult = pytest
|
|
561
|
+
? this.parsePytestOutput(reportText, `${stderr}\n${stdout}`, files, code, command)
|
|
562
|
+
: this.parseTestOutput(reportText ?? '', stderr, fileLabel, framework, code);
|
|
542
563
|
// Read only this invocation's coverage artifacts. A previous or
|
|
543
564
|
// concurrent run's project coverage directory is not evidence.
|
|
544
565
|
if (parseResult.success && coverageDirectory) {
|
|
@@ -611,8 +632,14 @@ Provide:
|
|
|
611
632
|
command: process.execPath,
|
|
612
633
|
args: ['--test', ...files],
|
|
613
634
|
};
|
|
635
|
+
case 'pytest': {
|
|
636
|
+
// #1248: results come from the JUnit report file; no coverage is collected.
|
|
637
|
+
const report = createPytestJunitReport();
|
|
638
|
+
return { ...pytestCommand(files, report.path), report };
|
|
639
|
+
}
|
|
614
640
|
default: {
|
|
615
|
-
// Default to vitest
|
|
641
|
+
// Default to vitest. Python files never get here: executeTestFiles
|
|
642
|
+
// sends them to pytest or refuses the run (#1248).
|
|
616
643
|
const coverageDirectory = createCoverageDirectory();
|
|
617
644
|
let report;
|
|
618
645
|
try {
|
|
@@ -655,6 +682,43 @@ Provide:
|
|
|
655
682
|
`stdout: ${capDiagnostics(stdout, 500)}\nstderr: ${capDiagnostics(stderr, 500)}`));
|
|
656
683
|
}
|
|
657
684
|
}
|
|
685
|
+
/**
|
|
686
|
+
* #1248: a pytest run from its JUnit report (undefined when pytest wrote none).
|
|
687
|
+
*/
|
|
688
|
+
parsePytestOutput(report, output, files, exitCode, python) {
|
|
689
|
+
const run = pytestRunFromReport(report, files, exitCode, output, python);
|
|
690
|
+
if (!run.success)
|
|
691
|
+
return run;
|
|
692
|
+
const failedTests = run.value.tests
|
|
693
|
+
.filter(test => test.status === 'failed')
|
|
694
|
+
.map(test => ({
|
|
695
|
+
testId: uuidv4(),
|
|
696
|
+
testName: test.name,
|
|
697
|
+
file: test.file,
|
|
698
|
+
error: test.failureMessage ?? 'Test failed',
|
|
699
|
+
stack: test.failureMessage ?? '',
|
|
700
|
+
duration: test.duration ?? 0,
|
|
701
|
+
}));
|
|
702
|
+
const testCases = run.value.tests.map(test => {
|
|
703
|
+
const failureMessage = test.failureMessage && testCaseFailureMessage(test.failureMessage);
|
|
704
|
+
return {
|
|
705
|
+
name: test.name,
|
|
706
|
+
file: test.file,
|
|
707
|
+
status: test.status,
|
|
708
|
+
...(test.duration !== undefined ? { duration: test.duration } : {}),
|
|
709
|
+
...(failureMessage ? { failureMessage } : {}),
|
|
710
|
+
};
|
|
711
|
+
});
|
|
712
|
+
return ok({
|
|
713
|
+
total: run.value.total,
|
|
714
|
+
passed: run.value.passed,
|
|
715
|
+
failed: run.value.failed,
|
|
716
|
+
skipped: run.value.skipped,
|
|
717
|
+
failedTests,
|
|
718
|
+
testCases,
|
|
719
|
+
coverage: undefined,
|
|
720
|
+
});
|
|
721
|
+
}
|
|
658
722
|
/**
|
|
659
723
|
* Parse the TAP or spec summary emitted by Node's built-in test runner.
|
|
660
724
|
*/
|
|
@@ -1018,7 +1082,7 @@ Provide:
|
|
|
1018
1082
|
return shards;
|
|
1019
1083
|
}
|
|
1020
1084
|
async executeWorker(files, _workerIndex, _isolation, request) {
|
|
1021
|
-
return this.executeTestFiles(files, request.framework, request.timeout ?? 30000, request.projectRoot);
|
|
1085
|
+
return this.executeTestFiles(files, request.framework, request.timeout ?? 30000, request.projectRoot, request.frameworkFromConfig);
|
|
1022
1086
|
}
|
|
1023
1087
|
aggregateResults(results) {
|
|
1024
1088
|
const aggregated = {
|
|
@@ -29,6 +29,12 @@ export declare class CopilotInstaller {
|
|
|
29
29
|
private generator;
|
|
30
30
|
constructor(options: CopilotInstallerOptions);
|
|
31
31
|
install(): Promise<CopilotInstallResult>;
|
|
32
|
+
/**
|
|
33
|
+
* Replace AQE's server entry in an existing config, keeping everything else.
|
|
34
|
+
* Returns null when the file cannot be merged safely (e.g. JSONC comments,
|
|
35
|
+
* which VS Code accepts but JSON.parse does not) so the user's file is never
|
|
36
|
+
* clobbered wholesale.
|
|
37
|
+
*/
|
|
32
38
|
private mergeExistingConfig;
|
|
33
39
|
}
|
|
34
40
|
export declare function createCopilotInstaller(options: CopilotInstallerOptions): CopilotInstaller;
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
|
|
9
9
|
import { join, dirname } from 'path';
|
|
10
10
|
import { toErrorMessage } from '../shared/error-utils.js';
|
|
11
|
+
import { writeFileIfChanged } from './idempotent-write.js';
|
|
11
12
|
import { createPlatformConfigGenerator, } from './platform-config-generator.js';
|
|
12
13
|
// ============================================================================
|
|
13
14
|
// Copilot Installer Class
|
|
@@ -37,20 +38,28 @@ export class CopilotInstaller {
|
|
|
37
38
|
const mcpConfig = this.generator.generateMcpConfig('copilot', { memoryBackend: this.options.memoryBackend });
|
|
38
39
|
const configPath = join(this.projectRoot, mcpConfig.path);
|
|
39
40
|
result.configPath = configPath;
|
|
40
|
-
|
|
41
|
+
// AQE's own server entry is refreshed on every init, independent of
|
|
42
|
+
// `overwrite` (#1269): its launch config is version-pinned, and a stale one
|
|
43
|
+
// leaves VS Code serving tool schemas cached from an older server. Other
|
|
44
|
+
// servers and top-level keys in the file are preserved.
|
|
45
|
+
if (!existsSync(configPath)) {
|
|
41
46
|
const configDir = dirname(configPath);
|
|
42
47
|
if (!existsSync(configDir)) {
|
|
43
48
|
mkdirSync(configDir, { recursive: true });
|
|
44
49
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
50
|
+
writeFileSync(configPath, mcpConfig.content);
|
|
51
|
+
result.mcpConfigured = true;
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
const merged = this.mergeExistingConfig(configPath, mcpConfig.content);
|
|
55
|
+
if (merged === null) {
|
|
56
|
+
result.errors.push(`${configPath} is not plain JSON (comments?) and was left unchanged; ` +
|
|
57
|
+
`update its "agentic-qe" server entry by hand`);
|
|
49
58
|
}
|
|
50
59
|
else {
|
|
51
|
-
|
|
60
|
+
writeFileIfChanged(configPath, merged);
|
|
61
|
+
result.mcpConfigured = true;
|
|
52
62
|
}
|
|
53
|
-
result.mcpConfigured = true;
|
|
54
63
|
}
|
|
55
64
|
// Generate behavioral rules
|
|
56
65
|
const rules = this.generator.generateBehavioralRules('copilot');
|
|
@@ -71,23 +80,34 @@ export class CopilotInstaller {
|
|
|
71
80
|
}
|
|
72
81
|
return result;
|
|
73
82
|
}
|
|
83
|
+
/**
|
|
84
|
+
* Replace AQE's server entry in an existing config, keeping everything else.
|
|
85
|
+
* Returns null when the file cannot be merged safely (e.g. JSONC comments,
|
|
86
|
+
* which VS Code accepts but JSON.parse does not) so the user's file is never
|
|
87
|
+
* clobbered wholesale.
|
|
88
|
+
*/
|
|
74
89
|
mergeExistingConfig(configPath, newContent) {
|
|
90
|
+
let existing;
|
|
75
91
|
try {
|
|
76
|
-
|
|
77
|
-
const incoming = JSON.parse(newContent);
|
|
78
|
-
// Merge servers
|
|
79
|
-
if (!existing.servers) {
|
|
80
|
-
existing.servers = {};
|
|
81
|
-
}
|
|
82
|
-
Object.assign(existing.servers, incoming.servers);
|
|
83
|
-
return JSON.stringify(existing, null, 2) + '\n';
|
|
92
|
+
existing = JSON.parse(readFileSync(configPath, 'utf-8'));
|
|
84
93
|
}
|
|
85
94
|
catch {
|
|
86
|
-
|
|
87
|
-
return newContent;
|
|
95
|
+
return null;
|
|
88
96
|
}
|
|
97
|
+
if (!isPlainObject(existing))
|
|
98
|
+
return null;
|
|
99
|
+
if (existing.servers === undefined)
|
|
100
|
+
existing.servers = {};
|
|
101
|
+
if (!isPlainObject(existing.servers))
|
|
102
|
+
return null;
|
|
103
|
+
const incoming = JSON.parse(newContent);
|
|
104
|
+
Object.assign(existing.servers, incoming.servers);
|
|
105
|
+
return JSON.stringify(existing, null, 2) + '\n';
|
|
89
106
|
}
|
|
90
107
|
}
|
|
108
|
+
function isPlainObject(value) {
|
|
109
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
110
|
+
}
|
|
91
111
|
// ============================================================================
|
|
92
112
|
// Factory Function
|
|
93
113
|
// ============================================================================
|
|
@@ -23,6 +23,16 @@ export interface GeneratedConfig {
|
|
|
23
23
|
format: string;
|
|
24
24
|
}
|
|
25
25
|
export declare const PLATFORM_REGISTRY: Record<PlatformId, PlatformDefinition>;
|
|
26
|
+
/**
|
|
27
|
+
* Issue #1269: VS Code caches each MCP server's tool list keyed by a hash of its
|
|
28
|
+
* launch config (command/args/env) and only restarts the server when that hash
|
|
29
|
+
* changes. The `agentic-qe@latest` entry is identical across releases, so tool
|
|
30
|
+
* schemas cached from an older server (the pre-#1185 "array type must have items"
|
|
31
|
+
* ones) survived upgrades. Stamping the installing version into the Copilot
|
|
32
|
+
* entry's env changes the hash whenever `aqe init` runs after an upgrade, without
|
|
33
|
+
* pinning which server version npx launches. The server does not read it.
|
|
34
|
+
*/
|
|
35
|
+
export declare function getCopilotInitVersionEnv(): Record<string, string>;
|
|
26
36
|
export declare class PlatformConfigGenerator {
|
|
27
37
|
/**
|
|
28
38
|
* Get the platform definition for a given platform ID
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Supports: GitHub Copilot, Cursor, Cline, Kilo Code, Roo Code, OpenAI Codex, Windsurf, Continue.dev
|
|
6
6
|
*/
|
|
7
|
+
import { createRequire } from 'module';
|
|
7
8
|
// ============================================================================
|
|
8
9
|
// Platform Registry
|
|
9
10
|
// ============================================================================
|
|
@@ -146,6 +147,29 @@ function getMcpServerEnv(dbFree) {
|
|
|
146
147
|
? { AQE_MEMORY_BACKEND: 'memory', AQE_V3_MODE: 'true' }
|
|
147
148
|
: { AQE_MEMORY_PATH: '.agentic-qe/memory.db', AQE_V3_MODE: 'true' };
|
|
148
149
|
}
|
|
150
|
+
/**
|
|
151
|
+
* Installed AQE version: the build-time define in the CLI/MCP bundles, otherwise
|
|
152
|
+
* package.json (tsc output and tests). Both src/init/ and dist/cli/ sit two levels
|
|
153
|
+
* below the package root.
|
|
154
|
+
*/
|
|
155
|
+
function getInstalledAqeVersion() {
|
|
156
|
+
if (typeof __CLI_VERSION__ !== 'undefined')
|
|
157
|
+
return __CLI_VERSION__;
|
|
158
|
+
const pkg = createRequire(import.meta.url)('../../package.json');
|
|
159
|
+
return pkg.version;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Issue #1269: VS Code caches each MCP server's tool list keyed by a hash of its
|
|
163
|
+
* launch config (command/args/env) and only restarts the server when that hash
|
|
164
|
+
* changes. The `agentic-qe@latest` entry is identical across releases, so tool
|
|
165
|
+
* schemas cached from an older server (the pre-#1185 "array type must have items"
|
|
166
|
+
* ones) survived upgrades. Stamping the installing version into the Copilot
|
|
167
|
+
* entry's env changes the hash whenever `aqe init` runs after an upgrade, without
|
|
168
|
+
* pinning which server version npx launches. The server does not read it.
|
|
169
|
+
*/
|
|
170
|
+
export function getCopilotInitVersionEnv() {
|
|
171
|
+
return { AQE_INIT_VERSION: getInstalledAqeVersion() };
|
|
172
|
+
}
|
|
149
173
|
function getMcpServerEntry(withAutoApprove, dbFree) {
|
|
150
174
|
const entry = {
|
|
151
175
|
command: 'npx',
|
|
@@ -164,12 +188,13 @@ function getMcpServerEntry(withAutoApprove, dbFree) {
|
|
|
164
188
|
function generateJsonConfig(platform, dbFree) {
|
|
165
189
|
const serverEntry = getMcpServerEntry(platform.supportsAutoApprove, dbFree);
|
|
166
190
|
if (platform.id === 'copilot') {
|
|
167
|
-
// Copilot uses "servers" key with "type": "stdio"
|
|
191
|
+
// Copilot uses "servers" key with "type": "stdio"; env carries the init version stamp (#1269)
|
|
168
192
|
const config = {
|
|
169
193
|
[platform.configKey]: {
|
|
170
194
|
'agentic-qe': {
|
|
171
195
|
type: 'stdio',
|
|
172
196
|
...serverEntry,
|
|
197
|
+
env: { ...serverEntry.env, ...getCopilotInitVersionEnv() },
|
|
173
198
|
},
|
|
174
199
|
},
|
|
175
200
|
};
|
|
@@ -82,6 +82,8 @@ export declare class UnifiedMemoryManager {
|
|
|
82
82
|
private constructor();
|
|
83
83
|
static getInstance(config?: Partial<UnifiedMemoryConfig>): UnifiedMemoryManager;
|
|
84
84
|
static getInstanceAsync(config?: Partial<UnifiedMemoryConfig>): Promise<UnifiedMemoryManager>;
|
|
85
|
+
/** The shared instance when it is initialized; never creates one. */
|
|
86
|
+
static peekInitialized(): UnifiedMemoryManager | null;
|
|
85
87
|
static resetInstance(): void;
|
|
86
88
|
initialize(options?: {
|
|
87
89
|
signal?: AbortSignal;
|
|
@@ -227,6 +229,12 @@ export declare class UnifiedMemoryManager {
|
|
|
227
229
|
}
|
|
228
230
|
export declare function getUnifiedMemory(config?: Partial<UnifiedMemoryConfig>): UnifiedMemoryManager;
|
|
229
231
|
export declare function initializeUnifiedMemory(config?: Partial<UnifiedMemoryConfig>): Promise<UnifiedMemoryManager>;
|
|
232
|
+
/**
|
|
233
|
+
* The shared memory.db connection when UnifiedMemory is already initialized,
|
|
234
|
+
* else null. Never opens it: callers that run before it keep their
|
|
235
|
+
* no-database behavior (#1298).
|
|
236
|
+
*/
|
|
237
|
+
export declare function getOpenUnifiedMemoryDatabase(): DatabaseType | null;
|
|
230
238
|
export declare function resetUnifiedMemory(): void;
|
|
231
239
|
/**
|
|
232
240
|
* Run a write on `db` through the shared manager's writeWhenUnlocked queue
|
|
@@ -174,6 +174,11 @@ export class UnifiedMemoryManager {
|
|
|
174
174
|
}
|
|
175
175
|
return UnifiedMemoryManager.instancePromise;
|
|
176
176
|
}
|
|
177
|
+
/** The shared instance when it is initialized; never creates one. */
|
|
178
|
+
static peekInitialized() {
|
|
179
|
+
const instance = UnifiedMemoryManager.instance;
|
|
180
|
+
return instance?.initialized ? instance : null;
|
|
181
|
+
}
|
|
177
182
|
static resetInstance() {
|
|
178
183
|
if (UnifiedMemoryManager.instance) {
|
|
179
184
|
UnifiedMemoryManager.instance.close();
|
|
@@ -1118,6 +1123,14 @@ export async function initializeUnifiedMemory(config) {
|
|
|
1118
1123
|
await manager.initialize();
|
|
1119
1124
|
return manager;
|
|
1120
1125
|
}
|
|
1126
|
+
/**
|
|
1127
|
+
* The shared memory.db connection when UnifiedMemory is already initialized,
|
|
1128
|
+
* else null. Never opens it: callers that run before it keep their
|
|
1129
|
+
* no-database behavior (#1298).
|
|
1130
|
+
*/
|
|
1131
|
+
export function getOpenUnifiedMemoryDatabase() {
|
|
1132
|
+
return UnifiedMemoryManager.peekInitialized()?.getDatabase() ?? null;
|
|
1133
|
+
}
|
|
1121
1134
|
export function resetUnifiedMemory() {
|
|
1122
1135
|
UnifiedMemoryManager.resetInstance();
|
|
1123
1136
|
}
|
|
@@ -15,6 +15,8 @@
|
|
|
15
15
|
* - Bearer auth from env only; URL userinfo stripped + warned on construct.
|
|
16
16
|
* - Probe + identity fingerprint required before `embed()`; breaker recovery
|
|
17
17
|
* invalidates identity so re-probe runs against a fresh endpoint.
|
|
18
|
+
* - The first identity is bound for the client's lifetime: a re-probe that
|
|
19
|
+
* finds another model is refused, never adopted (#1282).
|
|
18
20
|
* - True TCP connect timeout via socket-level setTimeout (not req.setTimeout).
|
|
19
21
|
* - TLS knobs (ca / cert / key / rejectUnauthorized / servername) for self-hosted.
|
|
20
22
|
*/
|
|
@@ -64,6 +66,8 @@ export interface EmbedderEndpointClientOptions {
|
|
|
64
66
|
/** TLS overrides for https transport. Ignored for http/unix. */
|
|
65
67
|
tlsOptions?: EmbedderTlsOptions;
|
|
66
68
|
}
|
|
69
|
+
/** The text every probe embeds; its vector is the endpoint's identity evidence. */
|
|
70
|
+
export declare const ENDPOINT_IDENTITY_CANARY = "AQE embedder endpoint identity canary v1";
|
|
67
71
|
/**
|
|
68
72
|
* Parsed endpoint — either an HTTP(S) URL or a Unix socket path.
|
|
69
73
|
*/
|
|
@@ -92,6 +96,17 @@ export declare class EmbedderEndpointTimeoutError extends Error {
|
|
|
92
96
|
readonly limitMs: number;
|
|
93
97
|
constructor(phase: 'connect' | 'request', limitMs: number);
|
|
94
98
|
}
|
|
99
|
+
/**
|
|
100
|
+
* #1282: a probe found a different endpoint identity than the one the client
|
|
101
|
+
* bound to. Vectors from the new identity are not comparable with stored ones,
|
|
102
|
+
* so the client refuses to embed until the endpoint serves the bound identity
|
|
103
|
+
* again or the process restarts.
|
|
104
|
+
*/
|
|
105
|
+
export declare class EmbedderEndpointIdentityChangedError extends Error {
|
|
106
|
+
readonly bound: EndpointIdentity;
|
|
107
|
+
readonly current: EndpointIdentity;
|
|
108
|
+
constructor(bound: EndpointIdentity, current: EndpointIdentity);
|
|
109
|
+
}
|
|
95
110
|
/**
|
|
96
111
|
* OpenAI-compatible embeddings client with keep-alive, circuit breaker, and identity probe.
|
|
97
112
|
*/
|
|
@@ -101,6 +116,15 @@ export declare class EmbedderEndpointClient {
|
|
|
101
116
|
private readonly breaker;
|
|
102
117
|
private readonly opts;
|
|
103
118
|
private cachedIdentity;
|
|
119
|
+
/**
|
|
120
|
+
* #1282: the first identity a probe found. Every embedding this client
|
|
121
|
+
* returns belongs to it; later probes must find it again.
|
|
122
|
+
*/
|
|
123
|
+
private boundIdentity;
|
|
124
|
+
/** #1282: the canary vector behind `boundIdentity`. */
|
|
125
|
+
private boundCanary;
|
|
126
|
+
/** #1282: set while the endpoint serves an identity other than the bound one. */
|
|
127
|
+
private identityChange;
|
|
104
128
|
/** True while a probe is in flight — prevents the embed() lazy-probe race. */
|
|
105
129
|
private probeInFlight;
|
|
106
130
|
/**
|
|
@@ -146,7 +170,28 @@ export declare class EmbedderEndpointClient {
|
|
|
146
170
|
probe(): Promise<EndpointIdentity>;
|
|
147
171
|
private ensureProbed;
|
|
148
172
|
private doProbe;
|
|
173
|
+
/**
|
|
174
|
+
* #1282: true when a re-probe found the bound model. The int16 fingerprint
|
|
175
|
+
* flips on noise of about 3e-5 per component, which the same model restarted
|
|
176
|
+
* on other hardware or kernels can produce, so a changed hash alone is not a
|
|
177
|
+
* changed model: the canary must also have moved below the ADR-097
|
|
178
|
+
* round-trip cosine.
|
|
179
|
+
*/
|
|
180
|
+
private isBoundModel;
|
|
181
|
+
/**
|
|
182
|
+
* #1282: the endpoint answers, but as a different model than the one this
|
|
183
|
+
* client bound to (an endpoint restarted with another model of the same
|
|
184
|
+
* dimension, typically seen when the breaker recovers). Treat it as down:
|
|
185
|
+
* open the breaker so every caller fast-fails with this error, and retry
|
|
186
|
+
* as a half-open trial after each window, in case the bound model returns.
|
|
187
|
+
* Reported once per new identity.
|
|
188
|
+
*/
|
|
189
|
+
private refuseIdentityChange;
|
|
149
190
|
getCachedIdentity(): EndpointIdentity | null;
|
|
191
|
+
/** #1282: the identity every vector from this client belongs to. */
|
|
192
|
+
getBoundIdentity(): EndpointIdentity | null;
|
|
193
|
+
/** #1298: the canary vector behind the bound identity (ENDPOINT_IDENTITY_CANARY). */
|
|
194
|
+
getBoundCanary(): readonly number[] | null;
|
|
150
195
|
getBreakerState(): {
|
|
151
196
|
open: boolean;
|
|
152
197
|
failures: number;
|