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
|
@@ -157,6 +157,7 @@ export class GOAPPlanner {
|
|
|
157
157
|
// for databases seeded before this feature existed, or before a given
|
|
158
158
|
// action's binding was added to the library.
|
|
159
159
|
this.backfillActionMethodBindings();
|
|
160
|
+
this.backfillActionDurationEstimates();
|
|
160
161
|
await this.loadActions();
|
|
161
162
|
this.initialized = true;
|
|
162
163
|
console.log(`[GOAPPlanner] Initialized: ${this.persistence.getDbPath()}`);
|
|
@@ -170,12 +171,12 @@ export class GOAPPlanner {
|
|
|
170
171
|
const allActions = getAllQEActions();
|
|
171
172
|
const db = this.ensureDb();
|
|
172
173
|
const insertAction = db.prepare(`
|
|
173
|
-
INSERT INTO goap_actions (id, name, description, category, preconditions, effects, cost, qe_domain, agent_type, method, params, implemented)
|
|
174
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
174
|
+
INSERT INTO goap_actions (id, name, description, category, preconditions, effects, cost, qe_domain, agent_type, method, params, implemented, estimated_duration_ms)
|
|
175
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
175
176
|
`);
|
|
176
177
|
for (const action of allActions) {
|
|
177
178
|
const id = `action-${Date.now()}-${randomUUID().slice(0, 8)}`;
|
|
178
|
-
insertAction.run(id, action.name, action.description, action.category, JSON.stringify(action.preconditions), JSON.stringify(action.effects), action.cost, action.qeDomain ?? null, action.agentType ?? null, action.method ?? null, action.params ? JSON.stringify(action.params) : null, action.implemented ? 1 : 0);
|
|
179
|
+
insertAction.run(id, action.name, action.description, action.category, JSON.stringify(action.preconditions), JSON.stringify(action.effects), action.cost, action.qeDomain ?? null, action.agentType ?? null, action.method ?? null, action.params ? JSON.stringify(action.params) : null, action.implemented ? 1 : 0, action.estimatedDurationMs ?? null);
|
|
179
180
|
}
|
|
180
181
|
// Seed QE goals using direct insertion
|
|
181
182
|
const insertGoal = db.prepare(`
|
|
@@ -212,6 +213,21 @@ export class GOAPPlanner {
|
|
|
212
213
|
update.run(action.method, action.params ? JSON.stringify(action.params) : '{}', action.name);
|
|
213
214
|
}
|
|
214
215
|
}
|
|
216
|
+
/** Restore missing estimates only for unchanged legacy library definitions. */
|
|
217
|
+
backfillActionDurationEstimates() {
|
|
218
|
+
const update = this.ensureDb().prepare(`
|
|
219
|
+
UPDATE goap_actions SET estimated_duration_ms = ?
|
|
220
|
+
WHERE estimated_duration_ms IS NULL AND name = ?
|
|
221
|
+
AND agent_type IS ? AND category = ? AND qe_domain IS ?
|
|
222
|
+
AND preconditions = ? AND effects = ?
|
|
223
|
+
AND method IS ? AND params IS ? AND implemented = ?
|
|
224
|
+
`);
|
|
225
|
+
for (const action of getAllQEActions()) {
|
|
226
|
+
if (action.estimatedDurationMs === undefined)
|
|
227
|
+
continue;
|
|
228
|
+
update.run(action.estimatedDurationMs, action.name, action.agentType ?? null, action.category, action.qeDomain ?? null, JSON.stringify(action.preconditions), JSON.stringify(action.effects), action.method ?? null, action.params ? JSON.stringify(action.params) : null, action.implemented ? 1 : 0);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
215
231
|
// ==========================================================================
|
|
216
232
|
// Core Planning - A* Search
|
|
217
233
|
// ==========================================================================
|
|
@@ -242,6 +258,7 @@ export class GOAPPlanner {
|
|
|
242
258
|
this.recordPlanReuse(reusedPlan.id, true);
|
|
243
259
|
const clonedPlan = {
|
|
244
260
|
...reusedPlan,
|
|
261
|
+
estimatedDurationMs: reusedPlan.actions.reduce((sum, action) => sum + (action.estimatedDurationMs ?? 0), 0),
|
|
245
262
|
id: `plan-${Date.now()}-${randomUUID().slice(0, 8)}`,
|
|
246
263
|
initialState: this.cloneState(currentState),
|
|
247
264
|
reusedFrom: reusedPlan.id,
|
|
@@ -306,6 +323,9 @@ export class GOAPPlanner {
|
|
|
306
323
|
// Entries are added on insert, updated when a better path is found, and
|
|
307
324
|
// removed when the node is popped (moved to the closed set).
|
|
308
325
|
const openSetCosts = new Map();
|
|
326
|
+
// Under a duration budget, cheaper paths can be slower or deeper. Keep
|
|
327
|
+
// nondominated labels rather than closing the entire state at its first cost.
|
|
328
|
+
const durationLabels = new Map();
|
|
309
329
|
// Issue #535: cost-unit heuristic built once per search from the
|
|
310
330
|
// actions that can actually move each goal key (see buildHeuristic).
|
|
311
331
|
const heuristic = this.buildHeuristic(goal, availableActions);
|
|
@@ -322,34 +342,39 @@ export class GOAPPlanner {
|
|
|
322
342
|
h: startH,
|
|
323
343
|
f: 0,
|
|
324
344
|
depth: 0,
|
|
345
|
+
estimatedDurationMs: 0,
|
|
325
346
|
};
|
|
326
347
|
startNode.f = startNode.g + startNode.h;
|
|
327
348
|
openHeap.push(startNode);
|
|
328
349
|
openSetCosts.set(this.hashState(start), 0);
|
|
350
|
+
durationLabels.set(this.hashState(start), [startNode]);
|
|
329
351
|
// Constraint defaults
|
|
330
352
|
const maxIterations = 10000;
|
|
331
353
|
// Issue #535: constraints.maxSteps caps the search depth (= plan length).
|
|
332
354
|
const maxPlanLength = constraints?.maxSteps ?? DEFAULT_MAX_PLAN_STEPS;
|
|
333
355
|
const maxCost = constraints?.maxCost ?? Infinity;
|
|
334
356
|
const maxDuration = constraints?.maxDurationMs ?? Infinity;
|
|
357
|
+
const boundedDuration = Number.isFinite(maxDuration);
|
|
335
358
|
let iterations = 0;
|
|
336
359
|
while (openHeap.length > 0 && iterations < maxIterations) {
|
|
337
360
|
iterations++;
|
|
338
361
|
// Get node with lowest f score — O(log n)
|
|
339
362
|
const current = openHeap.pop();
|
|
363
|
+
const stateKey = this.hashState(current.state);
|
|
364
|
+
if (boundedDuration && !durationLabels.get(stateKey)?.includes(current)) {
|
|
365
|
+
continue; // a later label dominates this queued path
|
|
366
|
+
}
|
|
340
367
|
// Check if goal reached
|
|
341
368
|
if (this.meetsConditions(current.state, goal)) {
|
|
342
369
|
return this.reconstructPlan(current);
|
|
343
370
|
}
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
371
|
+
if (!boundedDuration) {
|
|
372
|
+
if (closedSet.has(stateKey)) {
|
|
373
|
+
continue; // lazy deletion for the existing cost-only search
|
|
374
|
+
}
|
|
375
|
+
closedSet.add(stateKey);
|
|
376
|
+
openSetCosts.delete(stateKey);
|
|
349
377
|
}
|
|
350
|
-
closedSet.add(stateKey);
|
|
351
|
-
// Node is now closed — remove from open set cost tracker
|
|
352
|
-
openSetCosts.delete(stateKey);
|
|
353
378
|
// Check depth limit
|
|
354
379
|
if (current.depth >= maxPlanLength) {
|
|
355
380
|
continue;
|
|
@@ -364,7 +389,7 @@ export class GOAPPlanner {
|
|
|
364
389
|
const newState = this.applyAction(current.state, action);
|
|
365
390
|
const newStateKey = this.hashState(newState);
|
|
366
391
|
// Skip if already visited
|
|
367
|
-
if (closedSet.has(newStateKey)) {
|
|
392
|
+
if (!boundedDuration && closedSet.has(newStateKey)) {
|
|
368
393
|
continue;
|
|
369
394
|
}
|
|
370
395
|
// Calculate costs
|
|
@@ -379,26 +404,33 @@ export class GOAPPlanner {
|
|
|
379
404
|
continue;
|
|
380
405
|
}
|
|
381
406
|
// Check duration constraints
|
|
382
|
-
const estimatedDuration = current.
|
|
407
|
+
const estimatedDuration = current.estimatedDurationMs + (action.estimatedDurationMs ?? 0);
|
|
383
408
|
if (estimatedDuration > maxDuration) {
|
|
384
409
|
continue;
|
|
385
410
|
}
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
411
|
+
const next = {
|
|
412
|
+
state: newState, action, parent: current, g, h, f,
|
|
413
|
+
depth: current.depth + 1, estimatedDurationMs: estimatedDuration,
|
|
414
|
+
};
|
|
415
|
+
if (boundedDuration) {
|
|
416
|
+
const labels = durationLabels.get(newStateKey) ?? [];
|
|
417
|
+
if (labels.some((label) => label.g <= g &&
|
|
418
|
+
label.estimatedDurationMs <= estimatedDuration && label.depth <= next.depth)) {
|
|
419
|
+
continue;
|
|
420
|
+
}
|
|
421
|
+
durationLabels.set(newStateKey, [
|
|
422
|
+
...labels.filter((label) => !(g <= label.g &&
|
|
423
|
+
estimatedDuration <= label.estimatedDurationMs && next.depth <= label.depth)),
|
|
424
|
+
next,
|
|
425
|
+
]);
|
|
426
|
+
}
|
|
427
|
+
else {
|
|
428
|
+
const prevG = openSetCosts.get(newStateKey);
|
|
429
|
+
if (prevG !== undefined && g >= prevG)
|
|
430
|
+
continue;
|
|
431
|
+
openSetCosts.set(newStateKey, g);
|
|
390
432
|
}
|
|
391
|
-
|
|
392
|
-
// Add new node — O(log n)
|
|
393
|
-
openHeap.push({
|
|
394
|
-
state: newState,
|
|
395
|
-
action,
|
|
396
|
-
parent: current,
|
|
397
|
-
g,
|
|
398
|
-
h,
|
|
399
|
-
f,
|
|
400
|
-
depth: current.depth + 1,
|
|
401
|
-
});
|
|
433
|
+
openHeap.push(next);
|
|
402
434
|
}
|
|
403
435
|
}
|
|
404
436
|
// No plan found
|
|
@@ -896,20 +928,30 @@ export class GOAPPlanner {
|
|
|
896
928
|
ORDER BY created_at DESC, id DESC
|
|
897
929
|
LIMIT ?
|
|
898
930
|
`).all(...args, boundedLimit);
|
|
899
|
-
const plans =
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
931
|
+
const plans = [];
|
|
932
|
+
const invalidPlanIds = [];
|
|
933
|
+
for (const row of rows) {
|
|
934
|
+
let actionIds;
|
|
935
|
+
try {
|
|
936
|
+
actionIds = safeJsonParse(row.action_sequence);
|
|
937
|
+
}
|
|
938
|
+
catch {
|
|
939
|
+
invalidPlanIds.push(row.id);
|
|
940
|
+
continue;
|
|
941
|
+
}
|
|
942
|
+
if (!Array.isArray(actionIds) || !actionIds.every((id) => typeof id === 'string')) {
|
|
943
|
+
invalidPlanIds.push(row.id);
|
|
944
|
+
continue;
|
|
903
945
|
}
|
|
904
|
-
|
|
946
|
+
plans.push({
|
|
905
947
|
id: row.id,
|
|
906
948
|
status: row.status,
|
|
907
949
|
stepCount: actionIds.length,
|
|
908
950
|
totalCost: row.total_cost,
|
|
909
951
|
createdAt: row.created_at,
|
|
910
|
-
};
|
|
911
|
-
}
|
|
912
|
-
return { plans, count };
|
|
952
|
+
});
|
|
953
|
+
}
|
|
954
|
+
return { plans, count, ...(invalidPlanIds.length ? { invalidPlanIds } : {}) };
|
|
913
955
|
}
|
|
914
956
|
/**
|
|
915
957
|
* Find a similar plan by goal conditions
|
|
@@ -998,7 +1040,8 @@ export class GOAPPlanner {
|
|
|
998
1040
|
if (plan.actions.length > maxSteps)
|
|
999
1041
|
return false;
|
|
1000
1042
|
if (constraints?.maxDurationMs !== undefined &&
|
|
1001
|
-
plan.estimatedDurationMs
|
|
1043
|
+
plan.actions.reduce((sum, action) => sum + (action.estimatedDurationMs ?? 0), 0)
|
|
1044
|
+
> constraints.maxDurationMs) {
|
|
1002
1045
|
return false;
|
|
1003
1046
|
}
|
|
1004
1047
|
const allowed = new Set(this.getAvailableActions(constraints).map((a) => a.id));
|
package/dist/plugins/cache.js
CHANGED
|
@@ -51,9 +51,16 @@ export class PluginCache {
|
|
|
51
51
|
}
|
|
52
52
|
// Copy source to cache
|
|
53
53
|
fs.mkdirSync(dir, { recursive: true });
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
try {
|
|
55
|
+
this.copyDir(sourceDir, dir);
|
|
56
|
+
// Write the manifest (ensure it's present even if source didn't have it at root)
|
|
57
|
+
fs.writeFileSync(path.join(dir, 'qe-plugin.json'), JSON.stringify(manifest, null, 2));
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
// A partial directory must not satisfy the immutable-cache fast path on retry.
|
|
61
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
62
|
+
throw error;
|
|
63
|
+
}
|
|
57
64
|
// Cleanup old versions
|
|
58
65
|
this.pruneOldVersions(manifest.name);
|
|
59
66
|
return dir;
|
|
@@ -22,7 +22,7 @@ export class EmbeddingCache {
|
|
|
22
22
|
*/
|
|
23
23
|
hashContent(content, model) {
|
|
24
24
|
return createHash('sha256')
|
|
25
|
-
.update(
|
|
25
|
+
.update(JSON.stringify([model, content]))
|
|
26
26
|
.digest('hex');
|
|
27
27
|
}
|
|
28
28
|
/**
|
|
@@ -36,7 +36,7 @@ export class EmbeddingCache {
|
|
|
36
36
|
// Move to end (LRU update)
|
|
37
37
|
this.cache.delete(key);
|
|
38
38
|
this.cache.set(key, entry);
|
|
39
|
-
return entry.embedding;
|
|
39
|
+
return [...entry.embedding];
|
|
40
40
|
}
|
|
41
41
|
this.misses++;
|
|
42
42
|
return null;
|
|
@@ -54,7 +54,7 @@ export class EmbeddingCache {
|
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
const entry = {
|
|
57
|
-
embedding,
|
|
57
|
+
embedding: [...embedding],
|
|
58
58
|
timestamp: Date.now(),
|
|
59
59
|
model,
|
|
60
60
|
};
|
|
@@ -118,7 +118,7 @@ export class EmbeddingCache {
|
|
|
118
118
|
export() {
|
|
119
119
|
return Array.from(this.cache.entries()).map(([key, entry]) => ({
|
|
120
120
|
key,
|
|
121
|
-
entry,
|
|
121
|
+
entry: { ...entry, embedding: [...entry.embedding] },
|
|
122
122
|
}));
|
|
123
123
|
}
|
|
124
124
|
/**
|
|
@@ -128,7 +128,7 @@ export class EmbeddingCache {
|
|
|
128
128
|
this.cache.clear();
|
|
129
129
|
for (const { key, entry } of data) {
|
|
130
130
|
if (this.cache.size < this.maxSize) {
|
|
131
|
-
this.cache.set(key, entry);
|
|
131
|
+
this.cache.set(key, { ...entry, embedding: [...entry.embedding] });
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
134
|
}
|
|
@@ -14,6 +14,7 @@ import { OllamaClient } from './ollama-client.js';
|
|
|
14
14
|
import { EmbeddingCache } from './embedding-cache.js';
|
|
15
15
|
import { toErrorMessage } from '../error-utils.js';
|
|
16
16
|
import { EMBEDDING_CONFIG, } from './types.js';
|
|
17
|
+
const PSEUDO_EMBEDDING_MODEL = 'pseudo-embedding';
|
|
17
18
|
/**
|
|
18
19
|
* Nomic Embedder for generating code embeddings via Ollama
|
|
19
20
|
*/
|
|
@@ -50,17 +51,23 @@ export class NomicEmbedder {
|
|
|
50
51
|
* Generate embedding for a single text string
|
|
51
52
|
*/
|
|
52
53
|
async embed(text) {
|
|
53
|
-
//
|
|
54
|
-
|
|
54
|
+
// Prefer genuine cached vectors, then select the active backend before a
|
|
55
|
+
// single counted lookup so alternate namespaces do not inflate misses.
|
|
56
|
+
let model = this.cache.has(text, EMBEDDING_CONFIG.MODEL) ||
|
|
57
|
+
await this.isOllamaAvailable() || !this.enableFallback
|
|
58
|
+
? EMBEDDING_CONFIG.MODEL : PSEUDO_EMBEDDING_MODEL;
|
|
59
|
+
const cached = this.cache.get(text, model);
|
|
55
60
|
if (cached) {
|
|
56
61
|
return cached;
|
|
57
62
|
}
|
|
58
63
|
// Try Ollama first, fall back to pseudo-embedding if unavailable
|
|
59
64
|
let embedding;
|
|
60
65
|
if (await this.isOllamaAvailable()) {
|
|
66
|
+
model = EMBEDDING_CONFIG.MODEL;
|
|
61
67
|
embedding = await this.client.generateEmbedding(text);
|
|
62
68
|
}
|
|
63
69
|
else if (this.enableFallback) {
|
|
70
|
+
model = PSEUDO_EMBEDDING_MODEL;
|
|
64
71
|
embedding = this.generatePseudoEmbedding(text);
|
|
65
72
|
}
|
|
66
73
|
else {
|
|
@@ -68,7 +75,7 @@ export class NomicEmbedder {
|
|
|
68
75
|
`Please run: ollama pull ${EMBEDDING_CONFIG.MODEL}`);
|
|
69
76
|
}
|
|
70
77
|
// Cache result
|
|
71
|
-
this.cache.set(text,
|
|
78
|
+
this.cache.set(text, model, embedding);
|
|
72
79
|
return embedding;
|
|
73
80
|
}
|
|
74
81
|
/**
|
|
@@ -181,12 +188,14 @@ export class NomicEmbedder {
|
|
|
181
188
|
const formattedText = this.formatForEmbedding(chunk);
|
|
182
189
|
const chunkStartTime = Date.now();
|
|
183
190
|
// Check cache
|
|
184
|
-
const
|
|
191
|
+
const cachedModel = useOllama || this.cache.has(formattedText, EMBEDDING_CONFIG.MODEL)
|
|
192
|
+
? EMBEDDING_CONFIG.MODEL : PSEUDO_EMBEDDING_MODEL;
|
|
193
|
+
const cachedEmbedding = this.cache.get(formattedText, cachedModel);
|
|
185
194
|
if (cachedEmbedding) {
|
|
186
195
|
return {
|
|
187
196
|
chunkId: chunk.id,
|
|
188
197
|
embedding: cachedEmbedding,
|
|
189
|
-
model:
|
|
198
|
+
model: cachedModel,
|
|
190
199
|
cached: true,
|
|
191
200
|
computeTimeMs: Date.now() - chunkStartTime,
|
|
192
201
|
};
|
|
@@ -201,11 +210,12 @@ export class NomicEmbedder {
|
|
|
201
210
|
embedding = this.generatePseudoEmbedding(formattedText);
|
|
202
211
|
}
|
|
203
212
|
// Cache the result
|
|
204
|
-
|
|
213
|
+
const model = useOllama ? EMBEDDING_CONFIG.MODEL : PSEUDO_EMBEDDING_MODEL;
|
|
214
|
+
this.cache.set(formattedText, model, embedding);
|
|
205
215
|
return {
|
|
206
216
|
chunkId: chunk.id,
|
|
207
217
|
embedding,
|
|
208
|
-
model
|
|
218
|
+
model,
|
|
209
219
|
cached: false,
|
|
210
220
|
computeTimeMs: Date.now() - chunkStartTime,
|
|
211
221
|
};
|
|
@@ -34,10 +34,12 @@ export class OllamaClient {
|
|
|
34
34
|
}
|
|
35
35
|
const data = await response.json();
|
|
36
36
|
// Check if configured embedding model is available
|
|
37
|
-
//
|
|
37
|
+
// Match the configured model exactly, allowing its existing tag suffix.
|
|
38
38
|
if (data.models) {
|
|
39
|
-
return data.models.some((model) => model.name
|
|
40
|
-
model.
|
|
39
|
+
return data.models.some((model) => model.name === EMBEDDING_CONFIG.MODEL ||
|
|
40
|
+
model.name?.startsWith(`${EMBEDDING_CONFIG.MODEL}:`) ||
|
|
41
|
+
model.model === EMBEDDING_CONFIG.MODEL ||
|
|
42
|
+
model.model?.startsWith(`${EMBEDDING_CONFIG.MODEL}:`));
|
|
41
43
|
}
|
|
42
44
|
return false;
|
|
43
45
|
}
|
|
@@ -66,10 +66,11 @@ export class GitAnalyzer {
|
|
|
66
66
|
return 0.4; // Default when not in git repo
|
|
67
67
|
}
|
|
68
68
|
try {
|
|
69
|
-
const relativePath =
|
|
70
|
-
//
|
|
69
|
+
const relativePath = this.getRelativePath(filePath);
|
|
70
|
+
// Literal pathspecs preserve route filenames such as app/[id].tsx.
|
|
71
|
+
// execFileSync passes arguments directly without shell interpretation.
|
|
71
72
|
const output = execFileSync('git', [
|
|
72
|
-
'log', '--oneline', '--since=90 days ago', '--', relativePath
|
|
73
|
+
'--literal-pathspecs', 'log', '--oneline', '--since=90 days ago', '--', relativePath
|
|
73
74
|
], {
|
|
74
75
|
cwd: this.config.repoRoot,
|
|
75
76
|
encoding: 'utf-8',
|
|
@@ -97,10 +98,10 @@ export class GitAnalyzer {
|
|
|
97
98
|
return 0.5; // Default when not in git repo
|
|
98
99
|
}
|
|
99
100
|
try {
|
|
100
|
-
const relativePath =
|
|
101
|
+
const relativePath = this.getRelativePath(filePath);
|
|
101
102
|
// Get blame info using execFileSync with argument array
|
|
102
103
|
const blameOutput = execFileSync('git', [
|
|
103
|
-
'blame', '--line-porcelain', '--', relativePath
|
|
104
|
+
'--literal-pathspecs', 'blame', '--line-porcelain', '--', relativePath
|
|
104
105
|
], {
|
|
105
106
|
cwd: this.config.repoRoot,
|
|
106
107
|
encoding: 'utf-8',
|
|
@@ -143,12 +144,12 @@ export class GitAnalyzer {
|
|
|
143
144
|
return 0.4; // Default when not in git repo
|
|
144
145
|
}
|
|
145
146
|
try {
|
|
146
|
-
const relativePath =
|
|
147
|
+
const relativePath = this.getRelativePath(filePath);
|
|
147
148
|
// Get first commit date using execFileSync with argument array
|
|
148
149
|
let firstCommitTimestamp = NaN;
|
|
149
150
|
try {
|
|
150
151
|
const firstCommitOutput = execFileSync('git', [
|
|
151
|
-
'log', '--format=%at', '--follow', '--diff-filter=A', '--', relativePath
|
|
152
|
+
'--literal-pathspecs', 'log', '--format=%at', '--follow', '--diff-filter=A', '--', relativePath
|
|
152
153
|
], {
|
|
153
154
|
cwd: this.config.repoRoot,
|
|
154
155
|
encoding: 'utf-8',
|
|
@@ -167,7 +168,7 @@ export class GitAnalyzer {
|
|
|
167
168
|
let lastCommitTimestamp = NaN;
|
|
168
169
|
try {
|
|
169
170
|
const lastCommitOutput = execFileSync('git', [
|
|
170
|
-
'log', '-1', '--format=%at', '--', relativePath
|
|
171
|
+
'--literal-pathspecs', 'log', '-1', '--format=%at', '--', relativePath
|
|
171
172
|
], {
|
|
172
173
|
cwd: this.config.repoRoot,
|
|
173
174
|
encoding: 'utf-8',
|
|
@@ -216,7 +217,7 @@ export class GitAnalyzer {
|
|
|
216
217
|
return 0.2; // Default when not in git repo
|
|
217
218
|
}
|
|
218
219
|
try {
|
|
219
|
-
const relativePath =
|
|
220
|
+
const relativePath = this.getRelativePath(filePath);
|
|
220
221
|
// Search for each keyword separately and count unique commits
|
|
221
222
|
// This avoids shell injection from keywords config
|
|
222
223
|
let bugCommits = 0;
|
|
@@ -225,7 +226,7 @@ export class GitAnalyzer {
|
|
|
225
226
|
const sanitizedKeyword = sanitizeGitArg(keyword);
|
|
226
227
|
try {
|
|
227
228
|
const output = execFileSync('git', [
|
|
228
|
-
'log', '--oneline', '--grep', sanitizedKeyword, '-i', '--', relativePath
|
|
229
|
+
'--literal-pathspecs', 'log', '--oneline', '--grep', sanitizedKeyword, '-i', '--', relativePath
|
|
229
230
|
], {
|
|
230
231
|
cwd: this.config.repoRoot,
|
|
231
232
|
encoding: 'utf-8',
|
|
@@ -267,12 +268,12 @@ export class GitAnalyzer {
|
|
|
267
268
|
return this.getDefaultFileHistory(filePath);
|
|
268
269
|
}
|
|
269
270
|
try {
|
|
270
|
-
const relativePath =
|
|
271
|
+
const relativePath = this.getRelativePath(filePath);
|
|
271
272
|
// Get commit count using execFileSync with argument array
|
|
272
273
|
let totalCommits = 0;
|
|
273
274
|
try {
|
|
274
275
|
const commitCountOutput = execFileSync('git', [
|
|
275
|
-
'log', '--oneline', '--', relativePath
|
|
276
|
+
'--literal-pathspecs', 'log', '--oneline', '--', relativePath
|
|
276
277
|
], {
|
|
277
278
|
cwd: this.config.repoRoot,
|
|
278
279
|
encoding: 'utf-8',
|
|
@@ -287,7 +288,7 @@ export class GitAnalyzer {
|
|
|
287
288
|
let uniqueAuthors = 0;
|
|
288
289
|
try {
|
|
289
290
|
const authorsOutput = execFileSync('git', [
|
|
290
|
-
'log', '--format=%ae', '--', relativePath
|
|
291
|
+
'--literal-pathspecs', 'log', '--format=%ae', '--', relativePath
|
|
291
292
|
], {
|
|
292
293
|
cwd: this.config.repoRoot,
|
|
293
294
|
encoding: 'utf-8',
|
|
@@ -305,7 +306,7 @@ export class GitAnalyzer {
|
|
|
305
306
|
let firstCommit = null;
|
|
306
307
|
try {
|
|
307
308
|
const firstCommitOutput = execFileSync('git', [
|
|
308
|
-
'log', '--format=%at', '--follow', '--', relativePath
|
|
309
|
+
'--literal-pathspecs', 'log', '--format=%at', '--follow', '--', relativePath
|
|
309
310
|
], {
|
|
310
311
|
cwd: this.config.repoRoot,
|
|
311
312
|
encoding: 'utf-8',
|
|
@@ -328,7 +329,7 @@ export class GitAnalyzer {
|
|
|
328
329
|
let lastCommit = null;
|
|
329
330
|
try {
|
|
330
331
|
const lastCommitOutput = execFileSync('git', [
|
|
331
|
-
'log', '-1', '--format=%at', '--', relativePath
|
|
332
|
+
'--literal-pathspecs', 'log', '-1', '--format=%at', '--', relativePath
|
|
332
333
|
], {
|
|
333
334
|
cwd: this.config.repoRoot,
|
|
334
335
|
encoding: 'utf-8',
|
|
@@ -361,7 +362,7 @@ export class GitAnalyzer {
|
|
|
361
362
|
const sanitizedKeyword = sanitizeGitArg(keyword);
|
|
362
363
|
try {
|
|
363
364
|
const bugFixOutput = execFileSync('git', [
|
|
364
|
-
'log', '--oneline', '--grep', sanitizedKeyword, '-i', '--', relativePath
|
|
365
|
+
'--literal-pathspecs', 'log', '--oneline', '--grep', sanitizedKeyword, '-i', '--', relativePath
|
|
365
366
|
], {
|
|
366
367
|
cwd: this.config.repoRoot,
|
|
367
368
|
encoding: 'utf-8',
|
|
@@ -410,19 +411,19 @@ export class GitAnalyzer {
|
|
|
410
411
|
}
|
|
411
412
|
try {
|
|
412
413
|
const sinceDate = since || new Date(Date.now() - 24 * 60 * 60 * 1000);
|
|
413
|
-
const sinceStr = sinceDate.toISOString()
|
|
414
|
+
const sinceStr = sinceDate.toISOString();
|
|
414
415
|
// Get files changed since the date using execFileSync with argument array
|
|
415
416
|
const output = execFileSync('git', [
|
|
416
|
-
'log', `--since=${sinceStr}`, '--name-only', '--
|
|
417
|
+
'log', `--since=${sinceStr}`, '--name-only', '-z', '--format='
|
|
417
418
|
], {
|
|
418
419
|
cwd: this.config.repoRoot,
|
|
419
420
|
encoding: 'utf-8',
|
|
420
421
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
421
|
-
})
|
|
422
|
+
});
|
|
422
423
|
if (!output)
|
|
423
424
|
return [];
|
|
424
|
-
//
|
|
425
|
-
const files = output.split('\
|
|
425
|
+
// NUL records preserve whitespace, newlines and Git-quoted Unicode paths.
|
|
426
|
+
const files = output.split('\0').filter(Boolean);
|
|
426
427
|
return Array.from(new Set(files));
|
|
427
428
|
}
|
|
428
429
|
catch {
|
|
@@ -442,15 +443,15 @@ export class GitAnalyzer {
|
|
|
442
443
|
// Sanitize commit hash to prevent injection
|
|
443
444
|
const sanitizedHash = sanitizeGitArg(commitHash);
|
|
444
445
|
const output = execFileSync('git', [
|
|
445
|
-
'diff-tree', '--no-commit-id', '--name-only', '-r', sanitizedHash
|
|
446
|
+
'diff-tree', '--no-commit-id', '--name-only', '-z', '-r', sanitizedHash
|
|
446
447
|
], {
|
|
447
448
|
cwd: this.config.repoRoot,
|
|
448
449
|
encoding: 'utf-8',
|
|
449
450
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
450
|
-
})
|
|
451
|
+
});
|
|
451
452
|
if (!output)
|
|
452
453
|
return [];
|
|
453
|
-
return output.split('\
|
|
454
|
+
return output.split('\0').filter(Boolean);
|
|
454
455
|
}
|
|
455
456
|
catch {
|
|
456
457
|
return [];
|
|
@@ -469,14 +470,14 @@ export class GitAnalyzer {
|
|
|
469
470
|
// Get unstaged changes using execFileSync with argument array
|
|
470
471
|
try {
|
|
471
472
|
const unstagedOutput = execFileSync('git', [
|
|
472
|
-
'diff', '--name-only', 'HEAD'
|
|
473
|
+
'diff', '--name-only', '-z', 'HEAD'
|
|
473
474
|
], {
|
|
474
475
|
cwd: this.config.repoRoot,
|
|
475
476
|
encoding: 'utf-8',
|
|
476
477
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
477
|
-
})
|
|
478
|
+
});
|
|
478
479
|
if (unstagedOutput) {
|
|
479
|
-
files.push(...unstagedOutput.split('\
|
|
480
|
+
files.push(...unstagedOutput.split('\0').filter(Boolean));
|
|
480
481
|
}
|
|
481
482
|
}
|
|
482
483
|
catch {
|
|
@@ -485,14 +486,14 @@ export class GitAnalyzer {
|
|
|
485
486
|
// Get staged changes using execFileSync with argument array
|
|
486
487
|
try {
|
|
487
488
|
const stagedOutput = execFileSync('git', [
|
|
488
|
-
'diff', '--name-only', '--cached'
|
|
489
|
+
'diff', '--name-only', '-z', '--cached'
|
|
489
490
|
], {
|
|
490
491
|
cwd: this.config.repoRoot,
|
|
491
492
|
encoding: 'utf-8',
|
|
492
493
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
493
|
-
})
|
|
494
|
+
});
|
|
494
495
|
if (stagedOutput) {
|
|
495
|
-
files.push(...stagedOutput.split('\
|
|
496
|
+
files.push(...stagedOutput.split('\0').filter(Boolean));
|
|
496
497
|
}
|
|
497
498
|
}
|
|
498
499
|
catch {
|
|
@@ -74,8 +74,9 @@ class CircuitBreaker {
|
|
|
74
74
|
}
|
|
75
75
|
return false;
|
|
76
76
|
}
|
|
77
|
-
// half-open
|
|
78
|
-
|
|
77
|
+
// The open -> half-open transition already admitted the recovery probe.
|
|
78
|
+
// Keep further requests out until that probe records success or failure.
|
|
79
|
+
return false;
|
|
79
80
|
}
|
|
80
81
|
reset(url) {
|
|
81
82
|
if (url) {
|
|
@@ -253,17 +254,23 @@ export class HttpClient {
|
|
|
253
254
|
if (!error) {
|
|
254
255
|
return 'UNKNOWN_ERROR';
|
|
255
256
|
}
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
257
|
+
// Native fetch wraps transport errors in a TypeError whose cause carries
|
|
258
|
+
// the socket/DNS code. Retain message-based handling for existing callers.
|
|
259
|
+
const visited = new Set();
|
|
260
|
+
let current = error;
|
|
261
|
+
while (typeof current === 'object' && current !== null && !visited.has(current)) {
|
|
262
|
+
visited.add(current);
|
|
263
|
+
const detail = current;
|
|
264
|
+
if (detail.name === 'AbortError')
|
|
265
|
+
return 'TIMEOUT';
|
|
266
|
+
const message = typeof detail.message === 'string' ? detail.message : '';
|
|
267
|
+
if (detail.code === 'ECONNREFUSED' || message.includes('ECONNREFUSED'))
|
|
268
|
+
return 'CONNECTION_REFUSED';
|
|
269
|
+
if (detail.code === 'ENOTFOUND' || message.includes('ENOTFOUND'))
|
|
270
|
+
return 'DNS_ERROR';
|
|
271
|
+
if (detail.code === 'ETIMEDOUT' || message.includes('ETIMEDOUT'))
|
|
272
|
+
return 'NETWORK_TIMEOUT';
|
|
273
|
+
current = detail.cause;
|
|
267
274
|
}
|
|
268
275
|
return 'REQUEST_FAILED';
|
|
269
276
|
}
|