agentic-qe 3.14.7 → 3.15.0
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/.helpers-version +1 -1
- package/.claude/helpers/auto-memory-hook.mjs +18 -9
- package/.claude/helpers/helpers.manifest.json +6 -5
- package/.claude/helpers/hook-handler.cjs +40 -12
- package/.claude/helpers/memory.cjs +86 -0
- package/.claude/helpers/router.cjs +105 -0
- package/.claude/helpers/session.cjs +166 -0
- package/.claude/helpers/statusline.cjs +73 -621
- package/.claude/skills/release/SKILL.md +6 -0
- package/.claude/skills/skills-manifest.json +1 -1
- package/CHANGELOG.md +275 -0
- package/README.md +143 -366
- package/assets/readme/credit-ruflo.svg +1 -0
- package/assets/readme/credit-ruvector.svg +1 -0
- package/assets/readme/project-header.svg +1 -0
- package/assets/readme/quality-loop.svg +1 -0
- package/assets/skills/skills-manifest.json +1 -1
- package/dist/adapters/a2a/notifications/retry-queue.js +10 -1
- package/dist/adapters/ag-ui/json-patch.js +14 -7
- package/dist/adapters/ag-ui/state-delta-cache.js +20 -12
- package/dist/adapters/claude-flow/pretrain-bridge.js +3 -2
- package/dist/agents/claim-verifier/verifiers/file-verifier.js +3 -2
- package/dist/cli/bundle.js +6 -6
- package/dist/cli/chunks/adapter-D7G5MIDQ.js +2 -0
- package/dist/cli/chunks/{agent-booster-wasm-AK2W76RG.js → agent-booster-wasm-GDHJ6QUN.js} +2 -2
- package/dist/cli/chunks/{agent-handler-MGZCWHIY.js → agent-handler-MPYYQ2RZ.js} +2 -2
- package/dist/cli/chunks/{agent-memory-branch-JZ54MCSP.js → agent-memory-branch-QBSHKLA2.js} +2 -2
- package/dist/cli/chunks/aqe-learning-engine-G6TUFGHC.js +2 -0
- package/dist/cli/chunks/{arena-YSWTKBCL.js → arena-UJE2FROF.js} +4 -4
- package/dist/cli/chunks/{arena-CUVH3V7H.js → arena-WIGSL37B.js} +2 -2
- package/dist/cli/chunks/{audit-LVU76QGA.js → audit-VT7Y2Z7V.js} +3 -3
- package/dist/cli/chunks/base-B45BOC7E.js +2 -0
- package/dist/cli/chunks/{better-sqlite3-DB3LOJQU.js → better-sqlite3-DSL7LFRK.js} +2 -2
- package/dist/cli/chunks/{brain-handler-SD63KOQ6.js → brain-handler-N3C2MDMK.js} +4 -4
- package/dist/cli/chunks/{branch-enumerator-4MNOPUC7.js → branch-enumerator-B6NSQ3PZ.js} +2 -2
- package/dist/cli/chunks/{browser-OLPNTWQE.js → browser-KQ3YNRGW.js} +2 -2
- package/dist/cli/chunks/browser-workflow-MIBU4XMV.js +2 -0
- package/dist/cli/chunks/{chunk-ZWEKAEEV.js → chunk-2ORTL5WG.js} +1 -1
- package/dist/cli/chunks/{chunk-KD2BLA5Y.js → chunk-2ZEV3O24.js} +1 -1
- package/dist/cli/chunks/{chunk-25P6JA6V.js → chunk-32YSI6OT.js} +1 -1
- package/dist/cli/chunks/{chunk-A5MA7A23.js → chunk-3DKYBHNA.js} +6 -6
- package/dist/cli/chunks/{chunk-JOZ47MV6.js → chunk-3Y24VTZ3.js} +1 -1
- package/dist/cli/chunks/{chunk-2G63VIJE.js → chunk-4BWDCUZZ.js} +1 -1
- package/dist/cli/chunks/{chunk-36VKMAMN.js → chunk-4DCDIKBX.js} +2 -2
- package/dist/cli/chunks/chunk-4EEY23JS.js +4 -0
- package/dist/cli/chunks/{chunk-BD7FEUN3.js → chunk-4FOKHGP5.js} +3 -3
- package/dist/cli/chunks/{chunk-MQZ53OR3.js → chunk-4OQSAUKR.js} +2 -2
- package/dist/cli/chunks/{chunk-EYXE2XKP.js → chunk-4YPL3OXS.js} +2 -2
- package/dist/cli/chunks/{chunk-PCJQCEBA.js → chunk-5DJGP4TA.js} +2 -2
- package/dist/cli/chunks/{chunk-RC2A4JZ5.js → chunk-5KN4QL3G.js} +2 -2
- package/dist/cli/chunks/chunk-5LN7FQZI.js +2 -0
- package/dist/cli/chunks/{chunk-LU2EDWQK.js → chunk-5PNRUMRV.js} +2 -2
- package/dist/cli/chunks/{chunk-YRHTQZU4.js → chunk-62IEVKN3.js} +2 -2
- package/dist/cli/chunks/{chunk-DOBKEXMJ.js → chunk-6GTIJNRO.js} +1 -1
- package/dist/cli/chunks/{chunk-O5V7RHVG.js → chunk-6MN4L6BS.js} +2 -2
- package/dist/cli/chunks/{chunk-6PJPQGF4.js → chunk-7D6NVIGP.js} +6 -6
- package/dist/cli/chunks/{chunk-B2YGVSOP.js → chunk-7JABIXP3.js} +2 -2
- package/dist/cli/chunks/chunk-7JC3LHA6.js +742 -0
- package/dist/cli/chunks/{chunk-P7XSPP5D.js → chunk-7WUHVGGT.js} +2 -2
- package/dist/cli/chunks/{chunk-RKI3IQKQ.js → chunk-A37YYHUD.js} +3 -3
- package/dist/cli/chunks/{chunk-UBJG3IHT.js → chunk-AAQNRZKT.js} +2 -2
- package/dist/cli/chunks/{chunk-ND4QTZOL.js → chunk-AGYPPPXR.js} +2 -2
- package/dist/cli/chunks/chunk-AIE6OKCD.js +2 -0
- package/dist/cli/chunks/{chunk-JHJUSSAU.js → chunk-ANUZGOLQ.js} +2 -2
- package/dist/cli/chunks/{chunk-RLW25X66.js → chunk-AQZSF32Y.js} +2 -2
- package/dist/cli/chunks/{chunk-OIDWDGLG.js → chunk-ATXAMGVE.js} +2 -2
- package/dist/cli/chunks/{chunk-GLGKQX2V.js → chunk-AV3RX2L5.js} +2 -2
- package/dist/cli/chunks/{chunk-7QYOTUOX.js → chunk-AW5OWYQ4.js} +2 -2
- package/dist/cli/chunks/{chunk-B4I43GE2.js → chunk-B6QTNTCU.js} +2 -2
- package/dist/cli/chunks/{chunk-P2UPYSDJ.js → chunk-BAPMEDWC.js} +1 -1
- package/dist/cli/chunks/{chunk-Y6AKKQIQ.js → chunk-BH2SQQ2N.js} +1 -1
- package/dist/cli/chunks/{chunk-O6MO5KMR.js → chunk-C6M27NQE.js} +2 -2
- package/dist/cli/chunks/{chunk-XBYQ2BS4.js → chunk-CMYZWIXS.js} +2 -2
- package/dist/cli/chunks/{chunk-DYTQHRUS.js → chunk-CZWWC7GC.js} +1 -1
- package/dist/cli/chunks/{chunk-WF6UISKW.js → chunk-D7NOHASX.js} +4 -4
- package/dist/cli/chunks/{chunk-H5RQPO3X.js → chunk-DGRE6ZAA.js} +2 -2
- package/dist/cli/chunks/{chunk-53BXTTRO.js → chunk-DSGRXW6K.js} +3 -3
- package/dist/cli/chunks/{chunk-A2VUCUTT.js → chunk-DXA7RLYU.js} +2 -2
- package/dist/cli/chunks/{chunk-GVVFTFMB.js → chunk-DZHIE5UW.js} +2 -2
- package/dist/cli/chunks/{chunk-MZB2UV2O.js → chunk-EBK6CUBD.js} +1 -1
- package/dist/cli/chunks/{chunk-WIH522AP.js → chunk-EPEKEUCF.js} +1 -1
- package/dist/cli/chunks/{chunk-SRPLERER.js → chunk-EQ4SDE4L.js} +25 -25
- package/dist/cli/chunks/{chunk-EGOIIUBD.js → chunk-EZPWSS3B.js} +2 -2
- package/dist/cli/chunks/{chunk-EADSQN5T.js → chunk-F76SYOBT.js} +1 -1
- package/dist/cli/chunks/{chunk-XL5KIYE3.js → chunk-F7JVDLOI.js} +2 -2
- package/dist/cli/chunks/{chunk-QGOWNVVG.js → chunk-FCSETOWZ.js} +4 -4
- package/dist/cli/chunks/{chunk-A3DK3XNZ.js → chunk-FFE4XAQA.js} +1 -1
- package/dist/cli/chunks/{chunk-7EZ2Z2CK.js → chunk-FPTZP7W5.js} +1 -1
- package/dist/cli/chunks/{chunk-GV4DYPJP.js → chunk-FTFIA4I5.js} +2 -2
- package/dist/cli/chunks/{chunk-SM2YJ2AL.js → chunk-FTS6NGBP.js} +2 -2
- package/dist/cli/chunks/{chunk-XWYELBZS.js → chunk-FZ3TQAPW.js} +1 -1
- package/dist/cli/chunks/{chunk-HPWWYT67.js → chunk-G35KP72N.js} +2 -2
- package/dist/cli/chunks/{chunk-HZY42OVU.js → chunk-GCHDMO5V.js} +2 -2
- package/dist/cli/chunks/{chunk-23CX7JNL.js → chunk-GRN47ANK.js} +2 -2
- package/dist/cli/chunks/{chunk-HYFQUWNB.js → chunk-GV7P5JYF.js} +2 -2
- package/dist/cli/chunks/{chunk-YO4ESCB4.js → chunk-GX5RFGW2.js} +1 -1
- package/dist/cli/chunks/{chunk-TFK2AYIN.js → chunk-H77AUJNW.js} +2 -2
- package/dist/cli/chunks/{chunk-NBLDBVAW.js → chunk-HBIV7PQH.js} +1 -1
- package/dist/cli/chunks/{chunk-VYDVI6FZ.js → chunk-HOPXHZA3.js} +2 -2
- package/dist/cli/chunks/{chunk-HYOPJHHW.js → chunk-I3BH3KIF.js} +1 -1
- package/dist/cli/chunks/{chunk-ZELWDJXT.js → chunk-ILKMNDUM.js} +2 -2
- package/dist/cli/chunks/{chunk-C3FXFU2T.js → chunk-IRHBR56R.js} +1 -1
- package/dist/cli/chunks/{chunk-FYPX5WBJ.js → chunk-ISAMM7QA.js} +1 -1
- package/dist/cli/chunks/{chunk-V5AK56DA.js → chunk-ISGFAMHZ.js} +2 -2
- package/dist/cli/chunks/{chunk-KUHLTVWC.js → chunk-J46XGXPS.js} +1 -1
- package/dist/cli/chunks/{chunk-ZS4XVJGV.js → chunk-J4XCBOPA.js} +2 -2
- package/dist/cli/chunks/{chunk-BEFTQVEW.js → chunk-JIWMFLHV.js} +2 -2
- package/dist/cli/chunks/{chunk-UFSVUBTR.js → chunk-JJ7WAU4I.js} +2 -2
- package/dist/cli/chunks/{chunk-WOV6XI3A.js → chunk-JLPNYHJJ.js} +1 -1
- package/dist/cli/chunks/{chunk-77QZHIVX.js → chunk-JO2YLIZH.js} +2 -2
- package/dist/cli/chunks/{chunk-J7AQZLIH.js → chunk-JSYNSJDQ.js} +4 -4
- package/dist/cli/chunks/{chunk-OAZX6WFU.js → chunk-JYRBOSOF.js} +2 -2
- package/dist/cli/chunks/{chunk-EJ6MMYLK.js → chunk-KEZ4PXVF.js} +1 -1
- package/dist/cli/chunks/{chunk-N5XOXPHZ.js → chunk-KLGFEHEN.js} +2 -2
- package/dist/cli/chunks/{chunk-7MIOK72I.js → chunk-KU4WLKDK.js} +7 -7
- package/dist/cli/chunks/{chunk-Z4Q5PCRZ.js → chunk-KUTMQBV4.js} +4 -4
- package/dist/cli/chunks/{chunk-VW6FRMLW.js → chunk-L6PUBB6L.js} +2 -2
- package/dist/cli/chunks/{chunk-OEPNNLR4.js → chunk-LDJ5DZT5.js} +1 -1
- package/dist/cli/chunks/{chunk-QQFQDEUE.js → chunk-LLS6JYPN.js} +2 -2
- package/dist/cli/chunks/{chunk-UOI6ULCH.js → chunk-LPCFIFZF.js} +2 -2
- package/dist/cli/chunks/{chunk-6RD44SCE.js → chunk-M5EKZA7Q.js} +1 -1
- package/dist/cli/chunks/chunk-MEYSIVMP.js +2 -0
- package/dist/cli/chunks/{chunk-YMW57PEL.js → chunk-MFGLRMO4.js} +1 -1
- package/dist/cli/chunks/{chunk-BE4KALTE.js → chunk-MM57SD2F.js} +1 -1
- package/dist/cli/chunks/{chunk-FW4DJ4FJ.js → chunk-MO3QXLF2.js} +1 -1
- package/dist/cli/chunks/{chunk-QFETNCNN.js → chunk-MRIZY6HB.js} +2 -2
- package/dist/cli/chunks/{chunk-RT6O2HW2.js → chunk-N2MDNEF7.js} +2 -2
- package/dist/cli/chunks/{chunk-UA7TDVL7.js → chunk-N5ZHIQAV.js} +4 -4
- package/dist/cli/chunks/{chunk-Q6NTEICT.js → chunk-NZ556KZN.js} +2 -2
- package/dist/cli/chunks/{chunk-CVOQ6ESD.js → chunk-O5AUOBGU.js} +2 -2
- package/dist/cli/chunks/{chunk-5D7ZFWDS.js → chunk-OBSX3I4Y.js} +2 -2
- package/dist/cli/chunks/{chunk-NOHWJOBS.js → chunk-OLD2CIDI.js} +1 -1
- package/dist/cli/chunks/{chunk-5U6N4V5M.js → chunk-OTJ22IO2.js} +4 -4
- package/dist/cli/chunks/{chunk-5GFKTJ65.js → chunk-OYVDTD3A.js} +2 -2
- package/dist/cli/chunks/{chunk-LY7MFGBD.js → chunk-P2PPJUGD.js} +147 -150
- package/dist/cli/chunks/{chunk-OZGIOKEA.js → chunk-P4FRYNHL.js} +1 -1
- package/dist/cli/chunks/{chunk-X7ADKL7T.js → chunk-P4WE6VRR.js} +2 -2
- package/dist/cli/chunks/{chunk-ZUB5YOCM.js → chunk-P725KXHX.js} +2 -2
- package/dist/cli/chunks/{chunk-74IOEOMH.js → chunk-P7MNF2SK.js} +2 -2
- package/dist/cli/chunks/{chunk-TXSPBLBT.js → chunk-PJU5HVWV.js} +2 -2
- package/dist/cli/chunks/{chunk-MT7UNBZ7.js → chunk-PN3FYSQ6.js} +2 -2
- package/dist/cli/chunks/{chunk-F2OPFVQH.js → chunk-PPFW3H7E.js} +1 -1
- package/dist/cli/chunks/{chunk-IEJ7ZV3M.js → chunk-Q4RCUCHD.js} +1 -1
- package/dist/cli/chunks/{chunk-IAENZ2DR.js → chunk-QRALXNNX.js} +2 -2
- package/dist/cli/chunks/{chunk-AJUBT4NP.js → chunk-QVX22EIM.js} +3 -3
- package/dist/cli/chunks/chunk-R6CZCMKD.js +2 -0
- package/dist/cli/chunks/chunk-ROK5YQ5P.js +3 -0
- package/dist/cli/chunks/{chunk-ON2UTP2U.js → chunk-S2GNFAOC.js} +2 -2
- package/dist/cli/chunks/{chunk-HXXHMLJ5.js → chunk-S644OORE.js} +1 -1
- package/dist/cli/chunks/{chunk-XYLQZWF6.js → chunk-S7CROKX4.js} +2 -2
- package/dist/cli/chunks/{chunk-T77GZF4B.js → chunk-S7QUHLXV.js} +1 -1
- package/dist/cli/chunks/{chunk-RDGPXENG.js → chunk-UGYXUPGN.js} +2 -2
- package/dist/cli/chunks/{chunk-QVH5Y7AP.js → chunk-URRPJ3M7.js} +1 -1
- package/dist/cli/chunks/{chunk-AEUEMVJK.js → chunk-URUOTHPO.js} +2 -2
- package/dist/cli/chunks/{chunk-VXKWNRGA.js → chunk-VCYOFWMG.js} +2 -2
- package/dist/cli/chunks/{chunk-6EGS77BB.js → chunk-VQVFGFYK.js} +1 -1
- package/dist/cli/chunks/{chunk-NHUGHAY6.js → chunk-VT5SMBEM.js} +1 -1
- package/dist/cli/chunks/{chunk-ROVZSZCS.js → chunk-VTGRGYY4.js} +3 -3
- package/dist/cli/chunks/{chunk-QPLSYEWJ.js → chunk-VWCFXCSV.js} +2 -2
- package/dist/cli/chunks/{chunk-ENK44A6Q.js → chunk-VY4557VF.js} +2 -2
- package/dist/cli/chunks/{chunk-5FSLMYAC.js → chunk-VYERAOQL.js} +2 -2
- package/dist/cli/chunks/{chunk-EIGRV3J6.js → chunk-W6H2SOIK.js} +2 -2
- package/dist/cli/chunks/{chunk-CBONQM5D.js → chunk-WBR4VRQE.js} +2 -2
- package/dist/cli/chunks/{chunk-JZT7BU44.js → chunk-WDV6CBED.js} +2 -2
- package/dist/cli/chunks/{chunk-G367W7XR.js → chunk-WO7NPGUD.js} +19 -19
- package/dist/cli/chunks/{chunk-4INST4ZL.js → chunk-WPOYFV4X.js} +1 -1
- package/dist/cli/chunks/{chunk-3M7J4U74.js → chunk-WPSGMTI4.js} +4 -4
- package/dist/cli/chunks/{chunk-RKUAWQOF.js → chunk-WQMXQO3O.js} +2 -2
- package/dist/cli/chunks/{chunk-Q3NSU24F.js → chunk-WR54SKKL.js} +2 -2
- package/dist/cli/chunks/{chunk-UYUJT6QO.js → chunk-X4OESN7M.js} +2 -2
- package/dist/cli/chunks/{chunk-ZUOVNFXK.js → chunk-X5RELRY7.js} +2 -2
- package/dist/cli/chunks/{chunk-BLG7SH4A.js → chunk-X7JEBPEW.js} +1 -1
- package/dist/cli/chunks/{chunk-FSSR6WBE.js → chunk-XEABMIUH.js} +2 -2
- package/dist/cli/chunks/{chunk-ONR2NXXD.js → chunk-XELFJC77.js} +3 -3
- package/dist/cli/chunks/{chunk-MM56VPNE.js → chunk-XPUY3ZKD.js} +3 -3
- package/dist/cli/chunks/{chunk-QUORH2MG.js → chunk-XZDPR6I2.js} +8 -8
- package/dist/cli/chunks/{chunk-MZMG6CUJ.js → chunk-Y63DADOR.js} +2 -2
- package/dist/cli/chunks/{chunk-CQNMGK6Y.js → chunk-YFRZVNE4.js} +2 -2
- package/dist/cli/chunks/{chunk-3QJU4Q4R.js → chunk-YIDZ3TEN.js} +2 -2
- package/dist/cli/chunks/{chunk-4EKV7PHB.js → chunk-Z6CRROLU.js} +2 -2
- package/dist/cli/chunks/{chunk-IWFFO6VT.js → chunk-ZPH2YT3J.js} +2 -2
- package/dist/cli/chunks/{chunk-PYKY22GC.js → chunk-ZV7LJPSI.js} +5 -5
- package/dist/cli/chunks/chunk-ZXIIB3QE.js +2 -0
- package/dist/cli/chunks/ci-63JINRNB.js +82 -0
- package/dist/cli/chunks/{ci-output-RLS32FUY.js → ci-output-CRFWLUAA.js} +2 -2
- package/dist/cli/chunks/{circuit-breaker-MRCC7WCM.js → circuit-breaker-PJLG3WYL.js} +2 -2
- package/dist/cli/chunks/{claude-flow-setup-LIZCEKDF.js → claude-flow-setup-UKHSQMJU.js} +2 -2
- package/dist/cli/chunks/client-A4FTITK3.js +2 -0
- package/dist/cli/chunks/{cline-installer-T7H6R2RC.js → cline-installer-PYQ27AS3.js} +2 -2
- package/dist/cli/chunks/{code-XMBLI7OF.js → code-K7VGLZ3W.js} +3 -3
- package/dist/cli/chunks/{code-index-extractor-QS7BYLEX.js → code-index-extractor-NNWAVWSL.js} +2 -2
- package/dist/cli/chunks/{codex-installer-6PGT5FM6.js → codex-installer-U4VJIKRN.js} +2 -2
- package/dist/cli/chunks/{completions-2A3WRXY2.js → completions-DOCI3P4W.js} +2 -2
- package/dist/cli/chunks/{complexity-analyzer-23HOOGJ7.js → complexity-analyzer-RFW2QRFR.js} +2 -2
- package/dist/cli/chunks/{continuedev-installer-4FSF7B3N.js → continuedev-installer-S5WXXOBU.js} +2 -2
- package/dist/cli/chunks/{copilot-installer-A5GRQQUU.js → copilot-installer-AAQ6YLVJ.js} +2 -2
- package/dist/cli/chunks/core-handlers-FO3QTNWI.js +2 -0
- package/dist/cli/chunks/{cost-tracker-Z4STQ5VB.js → cost-tracker-R4VOHTWQ.js} +2 -2
- package/dist/cli/chunks/{coverage-NUPP6KZZ.js → coverage-P54HPCLV.js} +3 -3
- package/dist/cli/chunks/cross-domain-router-LIV6SRWF.js +2 -0
- package/dist/cli/chunks/{cursor-installer-FVJ7ROPJ.js → cursor-installer-VHBWZE5A.js} +2 -2
- package/dist/cli/chunks/{daemon-D662EX5N.js → daemon-BTRSWNB4.js} +4 -4
- package/dist/cli/chunks/{daemon-7ZZA2MMN.js → daemon-JLH5TTWZ.js} +4 -4
- package/dist/cli/chunks/{dag-attention-scheduler-IB4TQ2KA.js → dag-attention-scheduler-5Z6DCRFK.js} +2 -2
- package/dist/cli/chunks/{detect-LGLBZN4I.js → detect-NWGASRJJ.js} +2 -2
- package/dist/cli/chunks/{dist-node-Z3OL42YE.js → dist-node-XMNNSEFJ.js} +2 -2
- package/dist/cli/chunks/{domain-handler-L3CLNL7U.js → domain-handler-BWVBZTNR.js} +2 -2
- package/dist/cli/chunks/{domain-plugins-GQ3V5X6L.js → domain-plugins-YAD4USA4.js} +2 -2
- package/dist/cli/chunks/domain-transfer-Z3MRPZEZ.js +2 -0
- package/dist/cli/chunks/dream-DNLGHYXY.js +2 -0
- package/dist/cli/chunks/{embed-and-insert-pattern-UGD6USYH.js → embed-and-insert-pattern-5CCO45WC.js} +2 -2
- package/dist/cli/chunks/{eval-3B7UIYGY.js → eval-JEMLTGY4.js} +2 -2
- package/dist/cli/chunks/{experience-capture-middleware-3RQ4NYY3.js → experience-capture-middleware-FKVYBBAN.js} +4 -4
- package/dist/cli/chunks/{fast-paths-QOSAEPYD.js → fast-paths-TFL32H3C.js} +2 -2
- package/dist/cli/chunks/{feature-flags-3S5TH6P4.js → feature-flags-CNGAUUMT.js} +2 -2
- package/dist/cli/chunks/{feature-flags-TLF4NKOH.js → feature-flags-OHGD2NCW.js} +2 -2
- package/dist/cli/chunks/{file-discovery-AEVMJRNB.js → file-discovery-IHGDYW34.js} +2 -2
- package/dist/cli/chunks/{fleet-E6WTXWFL.js → fleet-OGTSDGJ2.js} +4 -4
- package/dist/cli/chunks/{gnn-wrapper-MCKH3AUU.js → gnn-wrapper-QYTTKNCE.js} +2 -2
- package/dist/cli/chunks/{heartbeat-handler-U7XENHRR.js → heartbeat-handler-R5OD2SKN.js} +4 -4
- package/dist/cli/chunks/heartbeat-scheduler-DL4LXXJF.js +2 -0
- package/dist/cli/chunks/hnsw-adapter-Y64M43J4.js +2 -0
- package/dist/cli/chunks/hnsw-index-5V6DDMTA.js +2 -0
- package/dist/cli/chunks/{hnsw-legacy-bridge-5GW4SAEI.js → hnsw-legacy-bridge-ULJWYXBQ.js} +2 -2
- package/dist/cli/chunks/{hnswlib-node-7BLZBK5T.js → hnswlib-node-SYKJXGE2.js} +2 -2
- package/dist/cli/chunks/{hooks-F3O2SB6H.js → hooks-XAJXPXTU.js} +10 -10
- package/dist/cli/chunks/hybrid-backend-JWT2V4FQ.js +2 -0
- package/dist/cli/chunks/{hypergraph-engine-PV4EKXHB.js → hypergraph-engine-GIBPGW4N.js} +2 -2
- package/dist/cli/chunks/{hypergraph-handler-VOWO5ZTW.js → hypergraph-handler-ENFK6IDN.js} +3 -3
- package/dist/cli/chunks/impact-analyzer-XUZQSZZC.js +2 -0
- package/dist/cli/chunks/{init-handler-ENJ5ONJX.js → init-handler-CSA62LGT.js} +6 -6
- package/dist/cli/chunks/init-wizard-KDJKHEPN.js +2 -0
- package/dist/cli/chunks/kernel-MUDYPGFR.js +2 -0
- package/dist/cli/chunks/{kilocode-installer-HNNJOOPE.js → kilocode-installer-YXFIRTSA.js} +2 -2
- package/dist/cli/chunks/{kiro-installer-UZBIQ3IC.js → kiro-installer-JW3BG2MQ.js} +2 -2
- package/dist/cli/chunks/knowledge-graph-GR52N7PU.js +2 -0
- package/dist/cli/chunks/{learning-YMLCVFUT.js → learning-BDBZ7ZVG.js} +4 -4
- package/dist/cli/chunks/{llm-router-YWTARCCT.js → llm-router-CCX2DYTC.js} +4 -4
- package/dist/cli/chunks/llm-router-service-QL6LVKZ4.js +2 -0
- package/dist/cli/chunks/{load-DKE3F3IP.js → load-UJTTEOOK.js} +2 -2
- package/dist/cli/chunks/load-test-76V75WZ5.js +2 -0
- package/dist/cli/chunks/{mcp-5PSGIUCW.js → mcp-2NAJYREC.js} +2 -2
- package/dist/cli/chunks/{memory-3L3O6JMM.js → memory-C3UQSN5F.js} +5 -5
- package/dist/cli/chunks/memory-backend-SMQRS5QN.js +2 -0
- package/dist/cli/chunks/memory-handlers-ESFIJENU.js +2 -0
- package/dist/cli/chunks/{multi-model-executor-AEEO7IA4.js → multi-model-executor-SIHSHAD7.js} +2 -2
- package/dist/cli/chunks/{opencode-installer-ABBO355U.js → opencode-installer-KDYHUGPG.js} +2 -2
- package/dist/cli/chunks/{orchestrator-E36Q7MKE.js → orchestrator-MJHIQEHD.js} +6 -6
- package/dist/cli/chunks/pattern-null-store-MWAJMOYU.js +2 -0
- package/dist/cli/chunks/{pattern-usage-recorder-H4XKSID4.js → pattern-usage-recorder-OLBE4UIF.js} +2 -2
- package/dist/cli/chunks/{pipeline-BGFEHXIN.js → pipeline-IOK2CV3U.js} +2 -2
- package/dist/cli/chunks/{platform-GK7ZVDJI.js → platform-53JQ7JXN.js} +2 -2
- package/dist/cli/chunks/{plugin-CAH2CKI6.js → plugin-L5SDIWDI.js} +2 -2
- package/dist/cli/chunks/{prime-radiant-advanced-wasm-M5EYRONA.js → prime-radiant-advanced-wasm-2DS67JFS.js} +2 -2
- package/dist/cli/chunks/{project-root-BSNZC243.js → project-root-LQMOFO2Z.js} +2 -2
- package/dist/cli/chunks/protocol-executor-32X3GAJT.js +2 -0
- package/dist/cli/chunks/{protocol-handler-JDSSC2SF.js → protocol-handler-NXG2M43B.js} +2 -2
- package/dist/cli/chunks/{prove-ANPTOZJE.js → prove-7K7PFSSX.js} +2 -2
- package/dist/cli/chunks/qe-reasoning-bank-KAFV3TGI.js +2 -0
- package/dist/cli/chunks/{quality-SXWGYRQR.js → quality-ATILUGMJ.js} +2 -2
- package/dist/cli/chunks/quality-gate-MPZMDPIZ.js +7 -0
- package/dist/cli/chunks/queen-coordinator-L3SODGRX.js +2 -0
- package/dist/cli/chunks/{real-embeddings-WSRYAOZM.js → real-embeddings-VZN3KIAI.js} +2 -2
- package/dist/cli/chunks/{ref-validation-AZ3LRWEK.js → ref-validation-EUATPVXX.js} +2 -2
- package/dist/cli/chunks/{roocode-installer-2QKGFIEU.js → roocode-installer-7M2GOUNZ.js} +2 -2
- package/dist/cli/chunks/router-DDCSSXYQ.js +2 -0
- package/dist/cli/chunks/routing-feedback-RFASKYCD.js +2 -0
- package/dist/cli/chunks/{routing-handler-UYDC5MMD.js → routing-handler-VWANE652.js} +2 -2
- package/dist/cli/chunks/{ruvector-commands-QXADPVEY.js → ruvector-commands-B2YIPGOV.js} +2 -2
- package/dist/cli/chunks/rvf-dual-writer-HCIF2G56.js +2 -0
- package/dist/cli/chunks/rvf-migration-adapter-UVAHQ7SV.js +2 -0
- package/dist/cli/chunks/{rvf-migration-coordinator-GD4NBFKT.js → rvf-migration-coordinator-RQXOQJ5T.js} +2 -2
- package/dist/cli/chunks/rvf-native-adapter-F2I5FFHK.js +2 -0
- package/dist/cli/chunks/{rvf-store-integrity-7SXG66IL.js → rvf-store-integrity-7P5YDXRH.js} +2 -2
- package/dist/cli/chunks/safe-db-6ZAA4S23.js +2 -0
- package/dist/cli/chunks/schedule-SM5Q6UVP.js +2 -0
- package/dist/cli/chunks/scheduler-4EYP4EZ6.js +2 -0
- package/dist/cli/chunks/{security-YKB622PK.js → security-VJ7TVSQF.js} +3 -3
- package/dist/cli/chunks/{shared-rvf-adapter-KMLAV7JK.js → shared-rvf-adapter-63NXQFBX.js} +2 -2
- package/dist/cli/chunks/{shared-rvf-dual-writer-OYY27DFV.js → shared-rvf-dual-writer-JQRP7P5A.js} +2 -2
- package/dist/cli/chunks/sqlite-persistence-KLN2K266.js +2 -0
- package/dist/cli/chunks/{standalone-memory-2DOABVLC.js → standalone-memory-WJ72PH5P.js} +2 -2
- package/dist/cli/chunks/{status-handler-EXRKETV7.js → status-handler-G72ZSLAX.js} +2 -2
- package/dist/cli/chunks/{structural-health-2SKK6DU6.js → structural-health-HYBGP4BD.js} +2 -2
- package/dist/cli/chunks/{sync-DQ2YUNI6.js → sync-5YMZZIF4.js} +2 -2
- package/dist/cli/chunks/{sync-UW7SX7GO.js → sync-O5FQAHT7.js} +2 -2
- package/dist/cli/chunks/{task-handler-LYQ6WYUY.js → task-handler-E6IFNHZG.js} +2 -2
- package/dist/cli/chunks/{task-handlers-DIJO232S.js → task-handlers-P3GC2L5L.js} +3 -3
- package/dist/cli/chunks/{test-WRHZMUCW.js → test-OU6ERW67.js} +6 -6
- package/dist/cli/chunks/{test-scheduling-HI23RXFK.js → test-scheduling-3HY4I3HY.js} +7 -7
- package/dist/cli/chunks/{token-bootstrap-23SA6SWZ.js → token-bootstrap-A5QA4CWK.js} +2 -2
- package/dist/cli/chunks/{token-usage-M7RRDPXO.js → token-usage-MUNQVPFT.js} +2 -2
- package/dist/cli/chunks/{transformers-4TC35KKS.js → transformers-IEO25W5V.js} +2 -2
- package/dist/cli/chunks/{tree-sitter-wasm-parser-F4LTKAWD.js → tree-sitter-wasm-parser-T2EQHEAY.js} +2 -2
- package/dist/cli/chunks/{types-NBXV6LXQ.js → types-ODCPGCID.js} +2 -2
- package/dist/cli/chunks/unified-memory-B5IA2KKQ.js +2 -0
- package/dist/cli/chunks/unified-memory-hnsw-YF74LL3Z.js +2 -0
- package/dist/cli/chunks/unified-persistence-VZMGNGWY.js +2 -0
- package/dist/cli/chunks/{upgrade-4BGOU5RM.js → upgrade-4DN6EIW2.js} +2 -2
- package/dist/cli/chunks/{validate-EDWAR63H.js → validate-TBNAPDE3.js} +2 -2
- package/dist/cli/chunks/{validate-swarm-VI72CPR7.js → validate-swarm-ZN7XXUY4.js} +2 -2
- package/dist/cli/chunks/visual-security-ZV3BLLSH.js +2 -0
- package/dist/cli/chunks/{web-tree-sitter-Y5XBRQXF.js → web-tree-sitter-DWAWVD2X.js} +2 -2
- package/dist/cli/chunks/{windsurf-installer-VEX23WAF.js → windsurf-installer-U6EROS5S.js} +2 -2
- package/dist/cli/chunks/{witness-chain-3YNL6YGY.js → witness-chain-EQEJS2P4.js} +2 -2
- package/dist/cli/chunks/witness-chain-OA24MQWX.js +2 -0
- package/dist/cli/chunks/{witness-chain-repair-MJZGZRWT.js → witness-chain-repair-KBXDRXS3.js} +2 -2
- package/dist/cli/chunks/{witness-chain-verifier-TTJYXTBE.js → witness-chain-verifier-HSQGZ4R4.js} +2 -2
- package/dist/cli/chunks/{witness-key-manager-EM6YXYOY.js → witness-key-manager-RAODG73T.js} +2 -2
- package/dist/cli/chunks/{workflow-2RBDOM7V.js → workflow-KNFJNNKG.js} +4 -4
- package/dist/cli/chunks/workflow-orchestrator-IMX2LSVE.js +2 -0
- package/dist/cli/chunks/{wrappers-5OTAVVOV.js → wrappers-NIJBA22T.js} +2 -2
- package/dist/cli/commands/ci.js +17 -6
- package/dist/cli/commands/quality-gate.js +6 -1
- package/dist/cli/index.js +7 -2
- package/dist/cli/process-store-cleanup.d.ts +7 -0
- package/dist/cli/process-store-cleanup.js +27 -0
- package/dist/cli/utils/ci-config.d.ts +3 -3
- package/dist/cli/utils/ci-config.js +202 -68
- package/dist/cli/utils/workflow-parser.js +73 -57
- package/dist/domains/code-intelligence/services/metric-collector/test-counter.d.ts +1 -1
- package/dist/domains/code-intelligence/services/metric-collector/test-counter.js +17 -15
- package/dist/domains/quality-assessment/quality-evidence.d.ts +3 -1
- package/dist/domains/quality-assessment/quality-evidence.js +7 -2
- package/dist/domains/test-execution/services/retry-handler.js +38 -16
- package/dist/domains/test-execution/services/test-executor.d.ts +3 -3
- package/dist/domains/test-execution/services/test-executor.js +66 -22
- package/dist/governance/ab-benchmarking.d.ts +5 -1
- package/dist/governance/ab-benchmarking.js +64 -29
- package/dist/init/fleet-integration.js +3 -2
- package/dist/init/init-wizard-steps.js +3 -2
- package/dist/init/phases/06-code-intelligence.js +6 -4
- package/dist/integrations/ruvector/sona-persistence.d.ts +1 -0
- package/dist/integrations/ruvector/sona-persistence.js +74 -20
- package/dist/integrations/ruvector/sona-wrapper.d.ts +2 -0
- package/dist/integrations/ruvector/sona-wrapper.js +13 -0
- package/dist/kernel/memory-backend.js +5 -4
- package/dist/kernel/unified-memory.js +3 -2
- package/dist/learning/aqe-learning-engine.js +3 -2
- package/dist/mcp/bundle.js +474 -471
- package/dist/mcp/connection-pool.d.ts +2 -0
- package/dist/mcp/connection-pool.js +13 -2
- package/dist/mcp/handlers/memory-handlers.d.ts +1 -0
- package/dist/mcp/handlers/memory-handlers.js +16 -6
- package/dist/mcp/protocol-server.js +29 -8
- package/dist/mcp/security/rate-limiter.d.ts +1 -0
- package/dist/mcp/security/rate-limiter.js +22 -5
- package/dist/mcp/services/session-store.js +17 -17
- package/dist/mcp/tools/planning/goap-status.d.ts +2 -0
- package/dist/mcp/tools/planning/goap-status.js +8 -2
- package/dist/mcp/types.d.ts +2 -0
- package/dist/optimization/session-cache.js +13 -11
- package/dist/planning/goap-planner.d.ts +3 -0
- package/dist/planning/goap-planner.js +80 -37
- package/dist/plugins/cache.js +10 -3
- package/dist/shared/embeddings/embedding-cache.js +5 -5
- package/dist/shared/embeddings/nomic-embedder.js +17 -7
- package/dist/shared/embeddings/ollama-client.js +5 -3
- package/dist/shared/git/git-analyzer.js +31 -30
- package/dist/shared/http/http-client.js +20 -13
- package/dist/shared/io/file-reader.js +11 -8
- package/dist/shared/llm/cache.d.ts +8 -29
- package/dist/shared/llm/cache.js +12 -11
- package/dist/shared/llm/cost-tracker.js +2 -1
- package/dist/shared/llm/provider-manager.js +4 -22
- package/dist/shared/llm/providers/gemini.d.ts +1 -0
- package/dist/shared/llm/providers/gemini.js +14 -5
- package/dist/shared/llm/providers/openrouter.js +6 -3
- package/dist/shared/metrics/code-metrics.js +1 -1
- package/dist/shared/metrics/system-metrics.js +8 -2
- package/dist/shared/retry-engine.js +6 -12
- package/dist/shared/test-runner-process.d.ts +10 -0
- package/dist/shared/test-runner-process.js +210 -0
- package/dist/test-scheduling/executors/vitest-executor.js +26 -17
- package/dist/validation/quality-verdict.js +3 -2
- package/dist/workers/quality-daemon/priority-queue.js +4 -1
- package/package.json +6 -4
- package/dist/cli/chunks/adapter-TVQKH65T.js +0 -2
- package/dist/cli/chunks/aqe-learning-engine-ULGTVVWE.js +0 -2
- package/dist/cli/chunks/base-W42BURDL.js +0 -2
- package/dist/cli/chunks/browser-workflow-HKGHFFFT.js +0 -2
- package/dist/cli/chunks/chunk-2IMSJ7IO.js +0 -2
- package/dist/cli/chunks/chunk-FBZC4IGB.js +0 -2
- package/dist/cli/chunks/chunk-LXZMP3VX.js +0 -736
- package/dist/cli/chunks/chunk-MNQN7UZX.js +0 -4
- package/dist/cli/chunks/chunk-OXHF3L2T.js +0 -2
- package/dist/cli/chunks/chunk-PELENDDQ.js +0 -2
- package/dist/cli/chunks/chunk-TW3SR4TS.js +0 -2
- package/dist/cli/chunks/chunk-V6RE4YRQ.js +0 -2
- package/dist/cli/chunks/chunk-ZQZD55MN.js +0 -3
- package/dist/cli/chunks/ci-J3TDK5RA.js +0 -81
- package/dist/cli/chunks/client-3BD2DI4N.js +0 -2
- package/dist/cli/chunks/core-handlers-C3H2ZCS2.js +0 -2
- package/dist/cli/chunks/cross-domain-router-JCQ7SWDP.js +0 -2
- package/dist/cli/chunks/domain-transfer-MFCI76IY.js +0 -2
- package/dist/cli/chunks/dream-FTP33IJB.js +0 -2
- package/dist/cli/chunks/heartbeat-scheduler-HXBJVJL2.js +0 -2
- package/dist/cli/chunks/hnsw-adapter-TU6WG2ME.js +0 -2
- package/dist/cli/chunks/hnsw-index-MS5KODD7.js +0 -2
- package/dist/cli/chunks/hybrid-backend-HT45LBHC.js +0 -2
- package/dist/cli/chunks/impact-analyzer-AP4AGTG5.js +0 -2
- package/dist/cli/chunks/init-wizard-I5DFZUQL.js +0 -2
- package/dist/cli/chunks/kernel-MISPSPPA.js +0 -2
- package/dist/cli/chunks/knowledge-graph-L26JESGE.js +0 -2
- package/dist/cli/chunks/llm-router-service-MWGC43ZA.js +0 -2
- package/dist/cli/chunks/load-test-H5ISNNM5.js +0 -2
- package/dist/cli/chunks/memory-backend-HWDNOBKW.js +0 -2
- package/dist/cli/chunks/memory-handlers-ZFDVQZM5.js +0 -2
- package/dist/cli/chunks/pattern-null-store-GQP6ICWK.js +0 -2
- package/dist/cli/chunks/protocol-executor-AD5A4DAI.js +0 -2
- package/dist/cli/chunks/qe-reasoning-bank-W3Z2PKTR.js +0 -2
- package/dist/cli/chunks/quality-gate-GYNCA4ZY.js +0 -7
- package/dist/cli/chunks/queen-coordinator-HQRHLIJX.js +0 -2
- package/dist/cli/chunks/router-MTP5LH4H.js +0 -2
- package/dist/cli/chunks/routing-feedback-GWETVB4L.js +0 -2
- package/dist/cli/chunks/rvf-dual-writer-4UE5S7WP.js +0 -2
- package/dist/cli/chunks/rvf-migration-adapter-PHH3HF4Q.js +0 -2
- package/dist/cli/chunks/rvf-native-adapter-KTLZBUWV.js +0 -2
- package/dist/cli/chunks/safe-db-FWWGAPVE.js +0 -2
- package/dist/cli/chunks/schedule-TPA4V4D5.js +0 -2
- package/dist/cli/chunks/scheduler-5ZTEPNDD.js +0 -2
- package/dist/cli/chunks/sqlite-persistence-HPTT624C.js +0 -2
- package/dist/cli/chunks/unified-memory-OVFEPRPS.js +0 -2
- package/dist/cli/chunks/unified-memory-hnsw-KKRSCZHR.js +0 -2
- package/dist/cli/chunks/unified-persistence-7GLR4RI3.js +0 -2
- package/dist/cli/chunks/visual-security-2FUM5GLI.js +0 -2
- package/dist/cli/chunks/witness-chain-MH6GA5L6.js +0 -2
- package/dist/cli/chunks/workflow-orchestrator-H6G65YKU.js +0 -2
|
@@ -235,27 +235,30 @@ export class FileReader {
|
|
|
235
235
|
resolvePath(filePath) {
|
|
236
236
|
// Determine if path is absolute
|
|
237
237
|
const isAbsolutePath = path.isAbsolute(filePath);
|
|
238
|
+
const normalizedBase = path.resolve(this.basePath);
|
|
239
|
+
const normalizedPath = path.resolve(normalizedBase, filePath);
|
|
240
|
+
const relativePath = path.relative(normalizedBase, normalizedPath);
|
|
241
|
+
if (this.basePath && (relativePath === '..' || relativePath.startsWith(`..${path.sep}`) || path.isAbsolute(relativePath))) {
|
|
242
|
+
throw new PathTraversalError(filePath, ['Path escapes base directory'], 'critical');
|
|
243
|
+
}
|
|
244
|
+
// Absolute checkout prefixes are not user-controlled depth beneath the root.
|
|
245
|
+
// Keep validating the original spelling so encoded traversal remains blocked.
|
|
246
|
+
const baseDepth = this.basePath ? normalizedBase.split(/[\\/]/).filter(Boolean).length : 0;
|
|
238
247
|
// SEC-004 FIX: Validate path to prevent directory traversal
|
|
239
248
|
// For absolute paths, validate without basePath to avoid incorrect combination
|
|
240
249
|
// For relative paths, validate with basePath for proper containment check
|
|
241
250
|
const validation = validatePath(filePath, {
|
|
242
251
|
basePath: isAbsolutePath ? '' : this.basePath,
|
|
243
252
|
allowAbsolute: true,
|
|
253
|
+
maxDepth: 10 + (isAbsolutePath ? baseDepth : 0),
|
|
244
254
|
// Allow common development file extensions
|
|
245
255
|
deniedExtensions: ['.exe', '.bat', '.cmd', '.ps1', '.dll', '.so'],
|
|
246
256
|
});
|
|
247
257
|
if (!validation.valid) {
|
|
248
258
|
throw new PathTraversalError(filePath, [validation.error || 'Path validation failed'], validation.riskLevel);
|
|
249
259
|
}
|
|
250
|
-
|
|
251
|
-
if (isAbsolutePath && this.basePath) {
|
|
252
|
-
const normalizedBase = path.resolve(this.basePath);
|
|
253
|
-
const normalizedPath = path.resolve(filePath);
|
|
254
|
-
if (!normalizedPath.startsWith(normalizedBase)) {
|
|
255
|
-
throw new PathTraversalError(filePath, ['Path escapes base directory'], 'critical');
|
|
256
|
-
}
|
|
260
|
+
if (isAbsolutePath)
|
|
257
261
|
return normalizedPath;
|
|
258
|
-
}
|
|
259
262
|
// Use the normalized path from validation if available
|
|
260
263
|
if (validation.normalizedPath) {
|
|
261
264
|
return validation.normalizedPath;
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Provides efficient caching of LLM responses to reduce costs and latency
|
|
6
6
|
* for repeated queries. Uses LRU (Least Recently Used) eviction policy.
|
|
7
7
|
*/
|
|
8
|
-
import { CacheEntry, LLMCacheConfig, LLMCacheStats, LLMResponse, EmbeddingResponse, CompletionResponse } from './interfaces';
|
|
8
|
+
import { CacheEntry, LLMCacheConfig, LLMCacheStats, LLMResponse, EmbeddingResponse, CompletionResponse, type GenerateOptions } from './interfaces';
|
|
9
9
|
/**
|
|
10
10
|
* Default cache configuration
|
|
11
11
|
*/
|
|
@@ -14,6 +14,7 @@ export declare const DEFAULT_CACHE_CONFIG: LLMCacheConfig;
|
|
|
14
14
|
* Type for cacheable response types
|
|
15
15
|
*/
|
|
16
16
|
export type CacheableResponse = LLMResponse | EmbeddingResponse | CompletionResponse;
|
|
17
|
+
type CacheKeyOptions = Pick<GenerateOptions, 'model' | 'temperature' | 'maxTokens' | 'systemPrompt' | 'stopSequences' | 'effort' | 'preferredProvider'>;
|
|
17
18
|
/**
|
|
18
19
|
* LRU Cache implementation for LLM responses
|
|
19
20
|
*/
|
|
@@ -28,12 +29,7 @@ export declare class LLMCache<T = CacheableResponse> {
|
|
|
28
29
|
/**
|
|
29
30
|
* Generate a cache key from request parameters
|
|
30
31
|
*/
|
|
31
|
-
static generateKey(type: 'generation' | 'embedding' | 'completion', input: string, options?:
|
|
32
|
-
model?: string;
|
|
33
|
-
temperature?: number;
|
|
34
|
-
maxTokens?: number;
|
|
35
|
-
systemPrompt?: string;
|
|
36
|
-
}): string;
|
|
32
|
+
static generateKey(type: 'generation' | 'embedding' | 'completion', input: string, options?: CacheKeyOptions): string;
|
|
37
33
|
/**
|
|
38
34
|
* Get a cached value
|
|
39
35
|
*/
|
|
@@ -99,21 +95,11 @@ export declare class LLMResponseCache {
|
|
|
99
95
|
/**
|
|
100
96
|
* Get a cached generation response
|
|
101
97
|
*/
|
|
102
|
-
getGeneration(input: string, options?:
|
|
103
|
-
model?: string;
|
|
104
|
-
temperature?: number;
|
|
105
|
-
maxTokens?: number;
|
|
106
|
-
systemPrompt?: string;
|
|
107
|
-
}): LLMResponse | undefined;
|
|
98
|
+
getGeneration(input: string, options?: CacheKeyOptions): LLMResponse | undefined;
|
|
108
99
|
/**
|
|
109
100
|
* Cache a generation response
|
|
110
101
|
*/
|
|
111
|
-
setGeneration(input: string, response: LLMResponse, options?:
|
|
112
|
-
model?: string;
|
|
113
|
-
temperature?: number;
|
|
114
|
-
maxTokens?: number;
|
|
115
|
-
systemPrompt?: string;
|
|
116
|
-
}, ttlMs?: number): void;
|
|
102
|
+
setGeneration(input: string, response: LLMResponse, options?: CacheKeyOptions, ttlMs?: number): void;
|
|
117
103
|
/**
|
|
118
104
|
* Get a cached embedding response
|
|
119
105
|
*/
|
|
@@ -129,19 +115,11 @@ export declare class LLMResponseCache {
|
|
|
129
115
|
/**
|
|
130
116
|
* Get a cached completion response
|
|
131
117
|
*/
|
|
132
|
-
getCompletion(prompt: string, options?:
|
|
133
|
-
model?: string;
|
|
134
|
-
temperature?: number;
|
|
135
|
-
maxTokens?: number;
|
|
136
|
-
}): CompletionResponse | undefined;
|
|
118
|
+
getCompletion(prompt: string, options?: CacheKeyOptions): CompletionResponse | undefined;
|
|
137
119
|
/**
|
|
138
120
|
* Cache a completion response
|
|
139
121
|
*/
|
|
140
|
-
setCompletion(prompt: string, response: CompletionResponse, options?:
|
|
141
|
-
model?: string;
|
|
142
|
-
temperature?: number;
|
|
143
|
-
maxTokens?: number;
|
|
144
|
-
}, ttlMs?: number): void;
|
|
122
|
+
setCompletion(prompt: string, response: CompletionResponse, options?: CacheKeyOptions, ttlMs?: number): void;
|
|
145
123
|
/**
|
|
146
124
|
* Get combined cache statistics
|
|
147
125
|
*/
|
|
@@ -160,4 +138,5 @@ export declare class LLMResponseCache {
|
|
|
160
138
|
*/
|
|
161
139
|
pruneExpired(): number;
|
|
162
140
|
}
|
|
141
|
+
export {};
|
|
163
142
|
//# sourceMappingURL=cache.d.ts.map
|
package/dist/shared/llm/cache.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* Provides efficient caching of LLM responses to reduce costs and latency
|
|
6
6
|
* for repeated queries. Uses LRU (Least Recently Used) eviction policy.
|
|
7
7
|
*/
|
|
8
|
+
import { createHash } from 'node:crypto';
|
|
8
9
|
/**
|
|
9
10
|
* Default cache configuration
|
|
10
11
|
*/
|
|
@@ -41,15 +42,13 @@ export class LLMCache {
|
|
|
41
42
|
options?.systemPrompt ?? '',
|
|
42
43
|
input,
|
|
43
44
|
];
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
for (let i = 0; i < str.length; i++) {
|
|
48
|
-
const char = str.charCodeAt(i);
|
|
49
|
-
hash = ((hash << 5) - hash) + char;
|
|
50
|
-
hash = hash & hash;
|
|
45
|
+
const outputOptions = [options?.stopSequences, options?.effort, options?.preferredProvider];
|
|
46
|
+
if (outputOptions.some(value => value !== undefined)) {
|
|
47
|
+
parts.push(JSON.stringify(outputOptions));
|
|
51
48
|
}
|
|
52
|
-
|
|
49
|
+
// Encode field boundaries before hashing: prompt text may contain delimiters.
|
|
50
|
+
const hash = createHash('sha256').update(JSON.stringify(parts)).digest('hex');
|
|
51
|
+
return `${type}:${hash}`;
|
|
53
52
|
}
|
|
54
53
|
/**
|
|
55
54
|
* Get a cached value
|
|
@@ -182,7 +181,9 @@ export class LLMCache {
|
|
|
182
181
|
entry.createdAt = new Date(entry.createdAt);
|
|
183
182
|
entry.lastAccessedAt = new Date(entry.lastAccessedAt);
|
|
184
183
|
this.cache.set(key, entry);
|
|
185
|
-
this.
|
|
184
|
+
if (this.config.enableLRU) {
|
|
185
|
+
this.updateAccessOrder(key);
|
|
186
|
+
}
|
|
186
187
|
}
|
|
187
188
|
// Evict if over capacity
|
|
188
189
|
while (this.cache.size > this.config.maxSize) {
|
|
@@ -223,14 +224,14 @@ export class LLMCache {
|
|
|
223
224
|
if (this.accessOrder.length === 0) {
|
|
224
225
|
// Fallback: delete first entry
|
|
225
226
|
const firstKey = this.cache.keys().next().value;
|
|
226
|
-
if (firstKey) {
|
|
227
|
+
if (firstKey !== undefined) {
|
|
227
228
|
this.cache.delete(firstKey);
|
|
228
229
|
this.evictions++;
|
|
229
230
|
}
|
|
230
231
|
return;
|
|
231
232
|
}
|
|
232
233
|
const lruKey = this.accessOrder.shift();
|
|
233
|
-
if (lruKey) {
|
|
234
|
+
if (lruKey !== undefined) {
|
|
234
235
|
this.cache.delete(lruKey);
|
|
235
236
|
this.evictions++;
|
|
236
237
|
}
|
|
@@ -244,7 +244,8 @@ export class CostTracker {
|
|
|
244
244
|
for (const record of relevantRecords) {
|
|
245
245
|
totalCost += record.cost.totalCost;
|
|
246
246
|
totalTokens += record.usage.totalTokens;
|
|
247
|
-
byProvider[record.provider]
|
|
247
|
+
const providerCost = Object.hasOwn(byProvider, record.provider) ? byProvider[record.provider] : 0;
|
|
248
|
+
byProvider[record.provider] = providerCost + record.cost.totalCost;
|
|
248
249
|
byModel[record.model] = (byModel[record.model] || 0) + record.cost.totalCost;
|
|
249
250
|
}
|
|
250
251
|
return {
|
|
@@ -207,12 +207,7 @@ export class ProviderManager {
|
|
|
207
207
|
// Check cache first
|
|
208
208
|
if (!options?.skipCache) {
|
|
209
209
|
const inputStr = typeof input === 'string' ? input : JSON.stringify(input);
|
|
210
|
-
const cached = this.cache.getGeneration(inputStr,
|
|
211
|
-
model: options?.model,
|
|
212
|
-
temperature: options?.temperature,
|
|
213
|
-
maxTokens: options?.maxTokens,
|
|
214
|
-
systemPrompt: options?.systemPrompt,
|
|
215
|
-
});
|
|
210
|
+
const cached = this.cache.getGeneration(inputStr, options);
|
|
216
211
|
if (cached) {
|
|
217
212
|
return { ...cached, cached: true };
|
|
218
213
|
}
|
|
@@ -224,12 +219,7 @@ export class ProviderManager {
|
|
|
224
219
|
// Cache the response
|
|
225
220
|
if (!options?.skipCache) {
|
|
226
221
|
const inputStr = typeof input === 'string' ? input : JSON.stringify(input);
|
|
227
|
-
this.cache.setGeneration(inputStr, response,
|
|
228
|
-
model: options?.model,
|
|
229
|
-
temperature: options?.temperature,
|
|
230
|
-
maxTokens: options?.maxTokens,
|
|
231
|
-
systemPrompt: options?.systemPrompt,
|
|
232
|
-
});
|
|
222
|
+
this.cache.setGeneration(inputStr, response, options);
|
|
233
223
|
}
|
|
234
224
|
// Track cost (in-process) and persist to the cross-process ledger.
|
|
235
225
|
this.costTracker.recordUsage(response.provider, response.model, response.usage, response.requestId);
|
|
@@ -265,11 +255,7 @@ export class ProviderManager {
|
|
|
265
255
|
await this.ensureInitialized();
|
|
266
256
|
// Check cache first
|
|
267
257
|
if (!options?.skipCache) {
|
|
268
|
-
const cached = this.cache.getCompletion(prompt,
|
|
269
|
-
model: options?.model,
|
|
270
|
-
temperature: options?.temperature,
|
|
271
|
-
maxTokens: options?.maxTokens,
|
|
272
|
-
});
|
|
258
|
+
const cached = this.cache.getCompletion(prompt, options);
|
|
273
259
|
if (cached) {
|
|
274
260
|
return { ...cached, cached: true };
|
|
275
261
|
}
|
|
@@ -279,11 +265,7 @@ export class ProviderManager {
|
|
|
279
265
|
const response = await this.executeWithFailover('complete', async (provider) => provider.complete(prompt, options));
|
|
280
266
|
// Cache the response
|
|
281
267
|
if (!options?.skipCache) {
|
|
282
|
-
this.cache.setCompletion(prompt, response,
|
|
283
|
-
model: options?.model,
|
|
284
|
-
temperature: options?.temperature,
|
|
285
|
-
maxTokens: options?.maxTokens,
|
|
286
|
-
});
|
|
268
|
+
this.cache.setCompletion(prompt, response, options);
|
|
287
269
|
}
|
|
288
270
|
// ADR-123: persist to the cross-process ledger (completion has usage too).
|
|
289
271
|
this.costTracker.recordUsage(response.provider, response.model, response.usage, `complete-${response.model}-${Date.now()}`);
|
|
@@ -191,7 +191,10 @@ export class GeminiProvider {
|
|
|
191
191
|
totalTokens: usage.totalTokens,
|
|
192
192
|
estimatedCostUsd: cost.totalCost,
|
|
193
193
|
});
|
|
194
|
-
|
|
194
|
+
// A blocked prompt has no candidates; preserve it as a terminal result.
|
|
195
|
+
const blocked = this.isPromptBlocked(data.promptFeedback);
|
|
196
|
+
const candidate = blocked ? undefined : data.candidates[0];
|
|
197
|
+
const content = candidate?.content?.parts
|
|
195
198
|
?.map(p => p.text ?? '')
|
|
196
199
|
.join('') ?? '';
|
|
197
200
|
return {
|
|
@@ -201,7 +204,7 @@ export class GeminiProvider {
|
|
|
201
204
|
usage,
|
|
202
205
|
cost,
|
|
203
206
|
latencyMs,
|
|
204
|
-
finishReason: this.mapFinishReason(
|
|
207
|
+
finishReason: blocked ? 'content_filter' : this.mapFinishReason(candidate?.finishReason),
|
|
205
208
|
cached: false,
|
|
206
209
|
requestId,
|
|
207
210
|
};
|
|
@@ -269,10 +272,10 @@ export class GeminiProvider {
|
|
|
269
272
|
buffer = lines.pop() || '';
|
|
270
273
|
for (const line of lines) {
|
|
271
274
|
const trimmed = line.trim();
|
|
272
|
-
if (!trimmed || !trimmed.startsWith('data:
|
|
275
|
+
if (!trimmed || !trimmed.startsWith('data:'))
|
|
273
276
|
continue;
|
|
274
277
|
try {
|
|
275
|
-
const chunk = safeJsonParse(trimmed.slice(
|
|
278
|
+
const chunk = safeJsonParse(trimmed.slice(5).trimStart());
|
|
276
279
|
const text = chunk.candidates?.[0]?.content?.parts
|
|
277
280
|
?.map(p => p.text ?? '')
|
|
278
281
|
.join('') ?? '';
|
|
@@ -280,7 +283,10 @@ export class GeminiProvider {
|
|
|
280
283
|
fullContent += text;
|
|
281
284
|
yield text;
|
|
282
285
|
}
|
|
283
|
-
if (chunk.
|
|
286
|
+
if (this.isPromptBlocked(chunk.promptFeedback)) {
|
|
287
|
+
finishReason = 'content_filter';
|
|
288
|
+
}
|
|
289
|
+
else if (chunk.candidates?.[0]?.finishReason) {
|
|
284
290
|
finishReason = this.mapFinishReason(chunk.candidates[0].finishReason);
|
|
285
291
|
}
|
|
286
292
|
if (chunk.usageMetadata) {
|
|
@@ -479,6 +485,9 @@ export class GeminiProvider {
|
|
|
479
485
|
parts: [{ text: m.content }],
|
|
480
486
|
}));
|
|
481
487
|
}
|
|
488
|
+
isPromptBlocked(feedback) {
|
|
489
|
+
return !!feedback?.blockReason && feedback.blockReason !== 'BLOCK_REASON_UNSPECIFIED';
|
|
490
|
+
}
|
|
482
491
|
/**
|
|
483
492
|
* Map Gemini finish reason to standard format
|
|
484
493
|
*/
|
|
@@ -299,11 +299,14 @@ export class OpenRouterProvider {
|
|
|
299
299
|
buffer = lines.pop() || '';
|
|
300
300
|
for (const line of lines) {
|
|
301
301
|
const trimmed = line.trim();
|
|
302
|
-
if (!trimmed || trimmed
|
|
302
|
+
if (!trimmed || !trimmed.startsWith('data:'))
|
|
303
303
|
continue;
|
|
304
|
-
|
|
304
|
+
const data = trimmed.slice(5).trimStart();
|
|
305
|
+
if (data === '[DONE]')
|
|
306
|
+
continue;
|
|
307
|
+
if (trimmed.startsWith('data:')) {
|
|
305
308
|
try {
|
|
306
|
-
const chunk = safeJsonParse(
|
|
309
|
+
const chunk = safeJsonParse(data);
|
|
307
310
|
const delta = chunk.choices[0]?.delta;
|
|
308
311
|
if (delta?.content) {
|
|
309
312
|
fullContent += delta.content;
|
|
@@ -76,7 +76,13 @@ export class SystemMetricsCollector {
|
|
|
76
76
|
*/
|
|
77
77
|
collectProcessMetrics() {
|
|
78
78
|
const memUsage = process.memoryUsage();
|
|
79
|
-
const
|
|
79
|
+
const currentCpuUsage = process.cpuUsage();
|
|
80
|
+
const cpuUsage = this.lastCpuUsage
|
|
81
|
+
? {
|
|
82
|
+
user: currentCpuUsage.user - this.lastCpuUsage.user,
|
|
83
|
+
system: currentCpuUsage.system - this.lastCpuUsage.system,
|
|
84
|
+
}
|
|
85
|
+
: currentCpuUsage;
|
|
80
86
|
// Calculate CPU percentage
|
|
81
87
|
const now = Date.now();
|
|
82
88
|
const elapsedMs = this.lastCpuTime > 0 ? now - this.lastCpuTime : 1000;
|
|
@@ -85,7 +91,7 @@ export class SystemMetricsCollector {
|
|
|
85
91
|
const totalCpuUs = cpuUsage.user + cpuUsage.system;
|
|
86
92
|
const cpuPercent = (totalCpuUs / elapsedUs) * 100;
|
|
87
93
|
// Update last values
|
|
88
|
-
this.lastCpuUsage =
|
|
94
|
+
this.lastCpuUsage = currentCpuUsage;
|
|
89
95
|
this.lastCpuTime = now;
|
|
90
96
|
// Calculate memory percentage
|
|
91
97
|
const totalMem = os.totalmem();
|
|
@@ -1,14 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
* Agentic QE v3 - Unified Retry Engine
|
|
3
|
-
* IMP-03: Retry Engine with Exponential Backoff
|
|
4
|
-
*
|
|
5
|
-
* Provides a single, well-tested retry loop with exponential backoff,
|
|
6
|
-
* jitter, abort signal support, and retryable-error classification.
|
|
7
|
-
*
|
|
8
|
-
* The circuit breaker (circuit-breaker.ts) is a separate concern that
|
|
9
|
-
* receives success/failure signals from callers — this engine does NOT
|
|
10
|
-
* import or depend on it. Integration is planned for a later phase.
|
|
11
|
-
*/
|
|
1
|
+
import { isCallerInputError } from './error-utils.js';
|
|
12
2
|
// ---------------------------------------------------------------------------
|
|
13
3
|
// Defaults
|
|
14
4
|
// ---------------------------------------------------------------------------
|
|
@@ -59,7 +49,7 @@ const NON_RETRYABLE_HTTP_STATUSES = new Set([400, 401, 403, 404, 422]);
|
|
|
59
49
|
* Returns `false` for recognised non-retryable client errors (4xx).
|
|
60
50
|
*/
|
|
61
51
|
export function isRetryableError(error) {
|
|
62
|
-
if (error == null)
|
|
52
|
+
if (error == null || isCallerInputError(error))
|
|
63
53
|
return false;
|
|
64
54
|
// --- code property (errno) -------------------------------------------
|
|
65
55
|
const code = error.code;
|
|
@@ -142,6 +132,10 @@ function delay(ms, signal) {
|
|
|
142
132
|
* promise rejects with an `AbortError`.
|
|
143
133
|
*/
|
|
144
134
|
export async function withRetry(fn, options) {
|
|
135
|
+
// Disabling retries must not bypass the caller's cancellation boundary.
|
|
136
|
+
if (options?.abortSignal?.aborted) {
|
|
137
|
+
throw options.abortSignal.reason ?? new DOMException('The operation was aborted.', 'AbortError');
|
|
138
|
+
}
|
|
145
139
|
// Kill switch: bypass retry entirely when disabled
|
|
146
140
|
if (process.env.AQE_RETRY_DISABLED === 'true') {
|
|
147
141
|
const result = await fn();
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type ChildProcess } from 'node:child_process';
|
|
2
|
+
/** Keep detached runners subject to the CLI's synchronous exit handling. */
|
|
3
|
+
export declare function trackTestRunnerExit(proc: ChildProcess): () => void;
|
|
4
|
+
/**
|
|
5
|
+
* Stop a test runner spawned in its own POSIX process group. The returned
|
|
6
|
+
* promise waits for the group to stop before report files may be removed.
|
|
7
|
+
* Windows uses taskkill's tree operation while the root PID still exists.
|
|
8
|
+
*/
|
|
9
|
+
export declare function terminateTestRunner(proc: ChildProcess): Promise<void>;
|
|
10
|
+
//# sourceMappingURL=test-runner-process.d.ts.map
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { execFileSync, spawn } from 'node:child_process';
|
|
2
|
+
import { readdirSync, readFileSync } from 'node:fs';
|
|
3
|
+
/** Linux signal 0 also sees zombies, which can never execute or write files. */
|
|
4
|
+
function hasLiveLinuxGroupMember(group) {
|
|
5
|
+
for (const pid of readdirSync('/proc')) {
|
|
6
|
+
if (!/^\d+$/.test(pid))
|
|
7
|
+
continue;
|
|
8
|
+
let stat;
|
|
9
|
+
try {
|
|
10
|
+
stat = readFileSync(`/proc/${pid}/stat`, 'utf8');
|
|
11
|
+
}
|
|
12
|
+
catch (error) {
|
|
13
|
+
if (['ENOENT', 'ESRCH'].includes(error.code ?? ''))
|
|
14
|
+
continue;
|
|
15
|
+
throw error; // Unknown process state must not be claimed as stopped.
|
|
16
|
+
}
|
|
17
|
+
// The comm field can contain spaces and parentheses; its final ')' is the
|
|
18
|
+
// boundary before state, ppid and pgrp, not the first whitespace token.
|
|
19
|
+
const fields = stat.slice(stat.lastIndexOf(')') + 1).trim().split(/\s+/);
|
|
20
|
+
if (fields.length < 3 || !/^\d+$/.test(fields[2]))
|
|
21
|
+
throw new Error(`Invalid process stat for ${pid}`);
|
|
22
|
+
if (Number(fields[2]) === group && fields[0] !== 'Z' && fields[0] !== 'X')
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
/** Signal probes on Darwin may deny access while dead group members are reaped. */
|
|
28
|
+
function hasLiveDarwinGroupMember(group) {
|
|
29
|
+
const snapshot = execFileSync('ps', ['-axo', 'pgid=,stat='], {
|
|
30
|
+
encoding: 'utf8', timeout: 1000, maxBuffer: 1024 * 1024,
|
|
31
|
+
});
|
|
32
|
+
for (const line of snapshot.split('\n')) {
|
|
33
|
+
if (!line.trim())
|
|
34
|
+
continue;
|
|
35
|
+
const match = /^\s*(\d+)\s+([A-Z?])\S*\s*$/.exec(line);
|
|
36
|
+
if (!match)
|
|
37
|
+
throw new Error('Could not determine Darwin process group state');
|
|
38
|
+
if (Number(match[1]) === group && match[2] !== 'Z')
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
const activeGroups = new Set();
|
|
44
|
+
const stopGroupsOnExit = () => {
|
|
45
|
+
for (const pid of activeGroups) {
|
|
46
|
+
try {
|
|
47
|
+
process.kill(-pid, 'SIGKILL');
|
|
48
|
+
}
|
|
49
|
+
catch { /* Already exited. */ }
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
/** Keep detached runners subject to the CLI's synchronous exit handling. */
|
|
53
|
+
export function trackTestRunnerExit(proc) {
|
|
54
|
+
const pid = proc.pid;
|
|
55
|
+
if (process.platform === 'win32' || pid === undefined)
|
|
56
|
+
return () => { };
|
|
57
|
+
if (activeGroups.size === 0)
|
|
58
|
+
process.once('exit', stopGroupsOnExit);
|
|
59
|
+
activeGroups.add(pid);
|
|
60
|
+
return () => {
|
|
61
|
+
activeGroups.delete(pid);
|
|
62
|
+
if (activeGroups.size === 0)
|
|
63
|
+
process.off('exit', stopGroupsOnExit);
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Stop a test runner spawned in its own POSIX process group. The returned
|
|
68
|
+
* promise waits for the group to stop before report files may be removed.
|
|
69
|
+
* Windows uses taskkill's tree operation while the root PID still exists.
|
|
70
|
+
*/
|
|
71
|
+
export function terminateTestRunner(proc) {
|
|
72
|
+
return new Promise((resolve, reject) => {
|
|
73
|
+
const platform = process.platform;
|
|
74
|
+
const linux = platform === 'linux';
|
|
75
|
+
const grouped = process.platform !== 'win32' && proc.pid !== undefined;
|
|
76
|
+
const windowsTree = process.platform === 'win32' && proc.pid !== undefined;
|
|
77
|
+
let timer;
|
|
78
|
+
let finished = false;
|
|
79
|
+
let forceSent = false;
|
|
80
|
+
let closed = false;
|
|
81
|
+
let treeStopped = false;
|
|
82
|
+
const finish = () => {
|
|
83
|
+
if (finished)
|
|
84
|
+
return;
|
|
85
|
+
finished = true;
|
|
86
|
+
clearTimeout(timer);
|
|
87
|
+
proc.off('close', onClose);
|
|
88
|
+
resolve();
|
|
89
|
+
};
|
|
90
|
+
const fail = (error) => {
|
|
91
|
+
if (finished)
|
|
92
|
+
return;
|
|
93
|
+
finished = true;
|
|
94
|
+
clearTimeout(timer);
|
|
95
|
+
proc.off('close', onClose);
|
|
96
|
+
reject(error);
|
|
97
|
+
};
|
|
98
|
+
const groupExists = () => {
|
|
99
|
+
try {
|
|
100
|
+
process.kill(-proc.pid, 0);
|
|
101
|
+
return forceSent && linux ? hasLiveLinuxGroupMember(proc.pid) : true;
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
if (error.code === 'ESRCH')
|
|
105
|
+
return false;
|
|
106
|
+
// A delivered group signal is not proof every member died. Inspect
|
|
107
|
+
// actual states; failures/malformed snapshots remain unknown and reject.
|
|
108
|
+
if (platform === 'darwin' && error.code === 'EPERM') {
|
|
109
|
+
return hasLiveDarwinGroupMember(proc.pid);
|
|
110
|
+
}
|
|
111
|
+
if (forceSent && linux && error.code === 'EPERM') {
|
|
112
|
+
return hasLiveLinuxGroupMember(proc.pid);
|
|
113
|
+
}
|
|
114
|
+
throw error;
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
const signalGroup = (signal) => {
|
|
118
|
+
try {
|
|
119
|
+
process.kill(-proc.pid, signal);
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
if (error.code === 'ESRCH')
|
|
124
|
+
return false;
|
|
125
|
+
throw error;
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
const onClose = () => {
|
|
129
|
+
closed = true;
|
|
130
|
+
try {
|
|
131
|
+
if (windowsTree) {
|
|
132
|
+
if (treeStopped)
|
|
133
|
+
finish();
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
// A root can exit before a TERM-resistant descendant. Keep escalation
|
|
137
|
+
// active while its owned group exists, even when stdio has closed.
|
|
138
|
+
if (!grouped || !groupExists())
|
|
139
|
+
finish();
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
fail(error);
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
proc.once('close', onClose);
|
|
146
|
+
try {
|
|
147
|
+
if (grouped) {
|
|
148
|
+
if (!signalGroup('SIGTERM')) {
|
|
149
|
+
finish();
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
timer = setTimeout(() => {
|
|
153
|
+
try {
|
|
154
|
+
if (!signalGroup('SIGKILL')) {
|
|
155
|
+
finish();
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
forceSent = true;
|
|
159
|
+
const deadline = Date.now() + 1000;
|
|
160
|
+
const poll = () => {
|
|
161
|
+
try {
|
|
162
|
+
// Do not discard report files while group exit is unknown.
|
|
163
|
+
if (!groupExists())
|
|
164
|
+
finish();
|
|
165
|
+
else if (Date.now() >= deadline)
|
|
166
|
+
fail(new Error(`Test runner group ${proc.pid} survived SIGKILL.`));
|
|
167
|
+
else
|
|
168
|
+
timer = setTimeout(poll, 20);
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
fail(error);
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
poll();
|
|
175
|
+
}
|
|
176
|
+
catch (error) {
|
|
177
|
+
fail(error);
|
|
178
|
+
}
|
|
179
|
+
}, 1000);
|
|
180
|
+
}
|
|
181
|
+
else if (windowsTree) {
|
|
182
|
+
const killer = spawn('taskkill', ['/PID', String(proc.pid), '/T', '/F'], {
|
|
183
|
+
stdio: 'ignore', windowsHide: true, timeout: 2000,
|
|
184
|
+
});
|
|
185
|
+
killer.once('error', fail);
|
|
186
|
+
killer.once('close', code => {
|
|
187
|
+
if (code !== 0) {
|
|
188
|
+
fail(new Error(`Test runner tree termination failed (taskkill exit ${code}).`));
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
treeStopped = true;
|
|
192
|
+
if (closed)
|
|
193
|
+
finish();
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
// No PID is available before spawn failure (and in test doubles).
|
|
199
|
+
proc.kill('SIGTERM');
|
|
200
|
+
if (finished)
|
|
201
|
+
return;
|
|
202
|
+
timer = setTimeout(() => { proc.kill('SIGKILL'); }, 1000);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
catch (error) {
|
|
206
|
+
fail(error);
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
//# sourceMappingURL=test-runner-process.js.map
|