agentic-qe 3.9.19 → 3.9.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/skills/skills-manifest.json +1 -1
- package/CHANGELOG.md +52 -0
- package/README.md +39 -0
- package/assets/skills/skills-manifest.json +1 -1
- package/dist/adapters/claude-flow/trajectory-bridge.d.ts +12 -1
- package/dist/adapters/claude-flow/trajectory-bridge.js +33 -31
- package/dist/cli/bundle.js +5 -5
- package/dist/cli/chunks/adapter-WOEZOCHJ.js +2 -0
- package/dist/cli/chunks/{agent-booster-wasm-HVBKHNIS.js → agent-booster-wasm-55SQPP6T.js} +2 -2
- package/dist/cli/chunks/{agent-handler-XNBDYRSJ.js → agent-handler-Q2UXL73Y.js} +2 -2
- package/dist/cli/chunks/{agent-memory-branch-YCVTQEMJ.js → agent-memory-branch-56GIYNGH.js} +2 -2
- package/dist/cli/chunks/aqe-learning-engine-5AHKLABJ.js +2 -0
- package/dist/cli/chunks/{audit-6C2PE7OY.js → audit-2JQ3URVN.js} +2 -2
- package/dist/cli/chunks/base-RNCRGTZJ.js +2 -0
- package/dist/cli/chunks/{better-sqlite3-HZPCHUQU.js → better-sqlite3-XGA7Z5YL.js} +2 -2
- package/dist/cli/chunks/{brain-handler-OV75Q2NM.js → brain-handler-TOOZFEK5.js} +3 -3
- package/dist/cli/chunks/{branch-enumerator-QW6D42HJ.js → branch-enumerator-2BLPN73D.js} +2 -2
- package/dist/cli/chunks/{browser-5BA7Q7OR.js → browser-FSVNN36N.js} +2 -2
- package/dist/cli/chunks/browser-workflow-MXHA63OC.js +2 -0
- package/dist/cli/chunks/{chunk-K554X3T4.js → chunk-2AEWOQWU.js} +2 -2
- package/dist/cli/chunks/{chunk-GVDLCJC5.js → chunk-34BTSZ5D.js} +1 -1
- package/dist/cli/chunks/{chunk-CYLQTVIA.js → chunk-3Y7OZ2PC.js} +2 -2
- package/dist/cli/chunks/{chunk-HVNW3TZS.js → chunk-44BAZASI.js} +1 -1
- package/dist/cli/chunks/{chunk-O5ZP3CBF.js → chunk-4O7YJIOS.js} +2 -2
- package/dist/cli/chunks/{chunk-HJ7CRPZY.js → chunk-4XZPDEK5.js} +1 -1
- package/dist/cli/chunks/{chunk-FL2DMHOQ.js → chunk-4Z4C7BXV.js} +1 -1
- package/dist/cli/chunks/{chunk-WULMXLNN.js → chunk-4ZUXTOUG.js} +1 -1
- package/dist/cli/chunks/{chunk-JYHZK44T.js → chunk-56DGV2Q3.js} +1 -1
- package/dist/cli/chunks/{chunk-SKNHAGYP.js → chunk-5EYQP3V3.js} +2 -2
- package/dist/cli/chunks/{chunk-TXCOK5DC.js → chunk-5FNEOJSD.js} +2 -2
- package/dist/cli/chunks/{chunk-FT3MAIRW.js → chunk-5PZG4WUA.js} +3 -3
- package/dist/cli/chunks/{chunk-WZUQT2BE.js → chunk-63PHZGO2.js} +2 -2
- package/dist/cli/chunks/chunk-65U55JIH.js +12 -0
- package/dist/cli/chunks/{chunk-MTHO6A3V.js → chunk-6MGACOLN.js} +1 -1
- package/dist/cli/chunks/{chunk-AOASQYOO.js → chunk-6OYRNNP2.js} +1 -1
- package/dist/cli/chunks/{chunk-XP4T7CZY.js → chunk-7P4IZQVQ.js} +2 -2
- package/dist/cli/chunks/{chunk-PUUTYV32.js → chunk-ACOEV3YB.js} +2 -2
- package/dist/cli/chunks/{chunk-UIASVDYG.js → chunk-ADC73GLJ.js} +2 -2
- package/dist/cli/chunks/{chunk-NMYZSZHW.js → chunk-AEQNCDYD.js} +2 -2
- package/dist/cli/chunks/chunk-AMOCYHP3.js +2 -0
- package/dist/cli/chunks/{chunk-KTDGHN2J.js → chunk-AT25VXEO.js} +1 -1
- package/dist/cli/chunks/{chunk-MN4366PQ.js → chunk-C4CZXAOE.js} +2 -2
- package/dist/cli/chunks/{chunk-GYDE5TCN.js → chunk-CJKR47YY.js} +1 -1
- package/dist/cli/chunks/{chunk-VXUIIZNG.js → chunk-D24HN6BG.js} +1 -1
- package/dist/cli/chunks/{chunk-U2WMCNNR.js → chunk-DBW745QA.js} +2 -2
- package/dist/cli/chunks/{chunk-BOUCIIUI.js → chunk-DQI5ZR34.js} +1 -1
- package/dist/cli/chunks/{chunk-SKDDAPBV.js → chunk-E2XIPBJ7.js} +1 -1
- package/dist/cli/chunks/{chunk-2WJLEZKP.js → chunk-E55MYZGP.js} +2 -2
- package/dist/cli/chunks/{chunk-44SPMVML.js → chunk-E5TGH4V3.js} +2 -2
- package/dist/cli/chunks/{chunk-OEQCZBBM.js → chunk-E7J32PW2.js} +2 -2
- package/dist/cli/chunks/{chunk-VSI45JCP.js → chunk-ETEV7IZI.js} +1 -1
- package/dist/cli/chunks/{chunk-TCUIYIZ4.js → chunk-EVWNZEYV.js} +1 -1
- package/dist/cli/chunks/{chunk-AEET2WOI.js → chunk-F4VJ4PPI.js} +59 -47
- package/dist/cli/chunks/{chunk-GYESQBDU.js → chunk-FBCLQTXO.js} +2 -2
- package/dist/cli/chunks/{chunk-IG2RCBHJ.js → chunk-FZ2SYLSK.js} +1 -1
- package/dist/cli/chunks/{chunk-XXHJKAE6.js → chunk-G276EI3G.js} +2 -2
- package/dist/cli/chunks/{chunk-ALYUJEYA.js → chunk-G7ZYDJZ3.js} +2 -2
- package/dist/cli/chunks/{chunk-I3JRRFVT.js → chunk-GB6ATLR3.js} +2 -2
- package/dist/cli/chunks/{chunk-MIQAFOFO.js → chunk-GDZ6XQRI.js} +1 -1
- package/dist/cli/chunks/{chunk-QOK4TIE4.js → chunk-GJGFPXWG.js} +2 -2
- package/dist/cli/chunks/{chunk-H4QM37XS.js → chunk-GLQ6LLKC.js} +1 -1
- package/dist/cli/chunks/{chunk-BGTYOZRK.js → chunk-GR4RXQXV.js} +2 -2
- package/dist/cli/chunks/{chunk-C5YFCM2H.js → chunk-HC4VOQZJ.js} +2 -2
- package/dist/cli/chunks/{chunk-NBBIA3QA.js → chunk-HIEP3L7H.js} +2 -2
- package/dist/cli/chunks/{chunk-DZS7XQ2Z.js → chunk-HJCJWPN5.js} +2 -2
- package/dist/cli/chunks/{chunk-BFBR2ZZJ.js → chunk-HMMJ6ZI6.js} +2 -2
- package/dist/cli/chunks/{chunk-XKD6AFY5.js → chunk-HRHKLRBB.js} +1 -1
- package/dist/cli/chunks/{chunk-AG7J7DTM.js → chunk-I3HLZASP.js} +2 -2
- package/dist/cli/chunks/{chunk-3HQ4AZDH.js → chunk-ICPQR533.js} +2 -2
- package/dist/cli/chunks/{chunk-AZKVGH5I.js → chunk-IM7X6BDZ.js} +2 -2
- package/dist/cli/chunks/{chunk-XQZ63XSL.js → chunk-IS6IES7Q.js} +1 -1
- package/dist/cli/chunks/{chunk-Y3GX66VZ.js → chunk-ISNDQOXC.js} +2 -2
- package/dist/cli/chunks/{chunk-2SSDY6OE.js → chunk-J3GG3Q4X.js} +2 -2
- package/dist/cli/chunks/{chunk-2XATUQIG.js → chunk-KDOA7YHW.js} +2 -2
- package/dist/cli/chunks/{chunk-U257SS7D.js → chunk-KENZAFI2.js} +2 -2
- package/dist/cli/chunks/{chunk-5LXWEAEJ.js → chunk-KID7PTBZ.js} +2 -2
- package/dist/cli/chunks/{chunk-M6EP724N.js → chunk-KRXJ7LFP.js} +1 -1
- package/dist/cli/chunks/{chunk-IPLQPBJA.js → chunk-KWPPF7O4.js} +2 -2
- package/dist/cli/chunks/{chunk-XF32XZMY.js → chunk-KYPN6G7T.js} +2 -2
- package/dist/cli/chunks/{chunk-B65GTWF3.js → chunk-LHXIAPKR.js} +2 -2
- package/dist/cli/chunks/chunk-LP52AQE2.js +2 -0
- package/dist/cli/chunks/{chunk-5X2AUPK2.js → chunk-LYZUB3NP.js} +1 -1
- package/dist/cli/chunks/{chunk-3X3QQZ7Q.js → chunk-MJGMH7TW.js} +2 -2
- package/dist/cli/chunks/{chunk-5KGFDNYI.js → chunk-MYZ43VKA.js} +2 -2
- package/dist/cli/chunks/{chunk-7WMHLBNZ.js → chunk-ND2TFQF5.js} +1 -1
- package/dist/cli/chunks/{chunk-R5IL3XD5.js → chunk-NGT3VL66.js} +24 -16
- package/dist/cli/chunks/{chunk-YXLQJ226.js → chunk-NJICCYCB.js} +2 -2
- package/dist/cli/chunks/{chunk-DAPBSAVT.js → chunk-NKOGDRZE.js} +2 -2
- package/dist/cli/chunks/{chunk-PS72GF4R.js → chunk-NS2ZWXUK.js} +3 -3
- package/dist/cli/chunks/{chunk-W3IO4FQ5.js → chunk-NV6AUEIH.js} +2 -2
- package/dist/cli/chunks/{chunk-3546SG2L.js → chunk-OEB3V633.js} +2 -2
- package/dist/cli/chunks/chunk-OHR5ILR3.js +2 -0
- package/dist/cli/chunks/{chunk-N2PLNYEV.js → chunk-OK5JHHXK.js} +1 -1
- package/dist/cli/chunks/{chunk-VRGXYOIN.js → chunk-OXXCWRFU.js} +1 -1
- package/dist/cli/chunks/{chunk-GJ5FON37.js → chunk-P4Q5TMDH.js} +2 -2
- package/dist/cli/chunks/{chunk-7IV2RK5M.js → chunk-PAXSPZ3F.js} +2 -2
- package/dist/cli/chunks/{chunk-5R2DUR3A.js → chunk-PEOTZFNZ.js} +2 -2
- package/dist/cli/chunks/{chunk-VHG67L7O.js → chunk-PGHTRQK6.js} +2 -2
- package/dist/cli/chunks/{chunk-HQFREZRX.js → chunk-QERANESS.js} +2 -2
- package/dist/cli/chunks/{chunk-NPSWRGNT.js → chunk-QPSPIESU.js} +2 -2
- package/dist/cli/chunks/{chunk-V7ZPTEP7.js → chunk-QREO5LNR.js} +1 -1
- package/dist/cli/chunks/{chunk-J7F65KKG.js → chunk-QSLXOYPR.js} +6 -6
- package/dist/cli/chunks/{chunk-VWWLJBRA.js → chunk-QU3VFWZZ.js} +14 -14
- package/dist/cli/chunks/{chunk-KU7OXAFY.js → chunk-RDUIN7LO.js} +1 -1
- package/dist/cli/chunks/{chunk-O6UMETOH.js → chunk-RHAUASC6.js} +2 -2
- package/dist/cli/chunks/{chunk-P6EYD4V3.js → chunk-RIVX6YLS.js} +2 -2
- package/dist/cli/chunks/{chunk-FPVXXQVX.js → chunk-ROC2SSV3.js} +3 -3
- package/dist/cli/chunks/{chunk-B2EHSFUW.js → chunk-S3TU7B7D.js} +2 -2
- package/dist/cli/chunks/{chunk-LTE3CDOY.js → chunk-S5RNBBJ6.js} +2 -2
- package/dist/cli/chunks/{chunk-TMAIHTE3.js → chunk-S6FFUCVZ.js} +4 -4
- package/dist/cli/chunks/{chunk-GL742O2V.js → chunk-SIW4N4NE.js} +4 -4
- package/dist/cli/chunks/{chunk-37DTXQ6P.js → chunk-SMAC5IX4.js} +2 -2
- package/dist/cli/chunks/{chunk-5MGRZ4YD.js → chunk-SMBQERK7.js} +2 -2
- package/dist/cli/chunks/{chunk-G2V4GMPR.js → chunk-T5Z5LL5Y.js} +3 -3
- package/dist/cli/chunks/{chunk-NXO7CT5K.js → chunk-TCNJ5NGT.js} +2 -2
- package/dist/cli/chunks/{chunk-JCPJG2KU.js → chunk-TFAS5UND.js} +3 -3
- package/dist/cli/chunks/{chunk-SLDYG7LC.js → chunk-TMKJXKY2.js} +2 -2
- package/dist/cli/chunks/{chunk-D74RGYKI.js → chunk-TOE6DKE4.js} +1 -1
- package/dist/cli/chunks/{chunk-MMVSIESL.js → chunk-UOLIGPDW.js} +2 -2
- package/dist/cli/chunks/{chunk-SRKBR4DU.js → chunk-V5AVC4D4.js} +2 -2
- package/dist/cli/chunks/{chunk-RL5CBCBV.js → chunk-V6GJ3EMZ.js} +1 -1
- package/dist/cli/chunks/{chunk-2SIQ742L.js → chunk-VGAG5TG7.js} +1 -1
- package/dist/cli/chunks/{chunk-255CWHTF.js → chunk-VQLHHNOH.js} +2 -2
- package/dist/cli/chunks/{chunk-LDBHCOM3.js → chunk-VQXHHEPD.js} +2 -2
- package/dist/cli/chunks/{chunk-EZZJ5XD6.js → chunk-WI5HBS3C.js} +2 -2
- package/dist/cli/chunks/{chunk-HCSTXZYE.js → chunk-WL5IRCU4.js} +2 -2
- package/dist/cli/chunks/{chunk-FNVA7U7X.js → chunk-WY3H7VHF.js} +2 -2
- package/dist/cli/chunks/{chunk-FJJLNCSL.js → chunk-XEMVYJ2Z.js} +3 -3
- package/dist/cli/chunks/{chunk-EW5TQQBR.js → chunk-Y36AJ462.js} +2 -2
- package/dist/cli/chunks/{chunk-VLQYU7ZQ.js → chunk-YH7BAX7S.js} +1 -1
- package/dist/cli/chunks/{chunk-BB3KUX6C.js → chunk-YS5WV3CJ.js} +1 -1
- package/dist/cli/chunks/{chunk-6BRUQTC7.js → chunk-YVG4D6P3.js} +1 -1
- package/dist/cli/chunks/{chunk-JLX35EPX.js → chunk-YVPPR33H.js} +2 -2
- package/dist/cli/chunks/{chunk-IV74GAZN.js → chunk-ZUTYZIWQ.js} +2 -2
- package/dist/cli/chunks/{ci-FTZE4PD3.js → ci-GU2HBK5E.js} +2 -2
- package/dist/cli/chunks/{ci-output-C3ORCIHU.js → ci-output-FGZTTY3R.js} +2 -2
- package/dist/cli/chunks/{circuit-breaker-GS5OTOJZ.js → circuit-breaker-6UNLOLMW.js} +2 -2
- package/dist/cli/chunks/{claude-flow-setup-RWOFP5L2.js → claude-flow-setup-SCOCIDBC.js} +2 -2
- package/dist/cli/chunks/client-XU3ZUFMH.js +2 -0
- package/dist/cli/chunks/{cline-installer-D7RGRAUH.js → cline-installer-G6PQERGI.js} +2 -2
- package/dist/cli/chunks/{code-HBDMMYHY.js → code-RNKTYBI4.js} +2 -2
- package/dist/cli/chunks/{code-index-extractor-B2KUPAEH.js → code-index-extractor-A6KAUQOU.js} +2 -2
- package/dist/cli/chunks/{codex-installer-MPXV4AOD.js → codex-installer-ABWDMKEX.js} +2 -2
- package/dist/cli/chunks/{completions-QJS6QOZQ.js → completions-TB4E6O46.js} +2 -2
- package/dist/cli/chunks/{complexity-analyzer-YQQXWZIL.js → complexity-analyzer-XS37O7OR.js} +2 -2
- package/dist/cli/chunks/{continuedev-installer-Z6PBKYMB.js → continuedev-installer-WDY6O2SR.js} +2 -2
- package/dist/cli/chunks/{copilot-installer-RWVD44CV.js → copilot-installer-SDJ3GYLU.js} +2 -2
- package/dist/cli/chunks/{cost-tracker-DFPBFYWL.js → cost-tracker-MWEXRK7F.js} +2 -2
- package/dist/cli/chunks/{coverage-DYST26FK.js → coverage-Y3KDB56G.js} +3 -3
- package/dist/cli/chunks/cross-domain-router-KKYQWQE7.js +2 -0
- package/dist/cli/chunks/{cursor-installer-LL6UWKTZ.js → cursor-installer-4U7XENLX.js} +2 -2
- package/dist/cli/chunks/{daemon-6PIHFZNR.js → daemon-D6R3BPBJ.js} +3 -3
- package/dist/cli/chunks/{dag-attention-scheduler-WS3HJW4F.js → dag-attention-scheduler-EMVUX6ES.js} +2 -2
- package/dist/cli/chunks/{detect-J4OITSUD.js → detect-QIJPCTZO.js} +2 -2
- package/dist/cli/chunks/{dist-node-QSLD5K6K.js → dist-node-4ZYBZKOB.js} +2 -2
- package/dist/cli/chunks/{domain-handler-BD53QZ4Q.js → domain-handler-X6CTXJQF.js} +2 -2
- package/dist/cli/chunks/{domain-transfer-VZBWINQL.js → domain-transfer-HK4ER37F.js} +2 -2
- package/dist/cli/chunks/dream-FBYASIID.js +2 -0
- package/dist/cli/chunks/{embed-and-insert-pattern-5UAFXNDX.js → embed-and-insert-pattern-XKTD5DQ3.js} +2 -2
- package/dist/cli/chunks/{eval-GBKU6VTD.js → eval-WEEB3CHY.js} +2 -2
- package/dist/cli/chunks/{fast-paths-MYZ6GITZ.js → fast-paths-M2ENEKQX.js} +2 -2
- package/dist/cli/chunks/{feature-flags-6ALWBTHS.js → feature-flags-3WIZC67K.js} +2 -2
- package/dist/cli/chunks/{feature-flags-2WVV66AO.js → feature-flags-CZQXGFGX.js} +2 -2
- package/dist/cli/chunks/{file-discovery-FOYCPGD6.js → file-discovery-ERTPM3C4.js} +2 -2
- package/dist/cli/chunks/{fleet-JROEDHAT.js → fleet-WBEPTBQR.js} +3 -3
- package/dist/cli/chunks/{gnn-wrapper-KAXTFFEE.js → gnn-wrapper-GVRS33BK.js} +2 -2
- package/dist/cli/chunks/{heartbeat-handler-PG24CBMQ.js → heartbeat-handler-JQ6NSC6T.js} +4 -4
- package/dist/cli/chunks/{heartbeat-scheduler-LSS3RD6E.js → heartbeat-scheduler-7XHIE6IV.js} +2 -2
- package/dist/cli/chunks/hnsw-adapter-L7QOLNKP.js +2 -0
- package/dist/cli/chunks/hnsw-index-O2YO7WVU.js +2 -0
- package/dist/cli/chunks/{hnsw-legacy-bridge-HYH4AJAO.js → hnsw-legacy-bridge-TYO6GZ6Z.js} +2 -2
- package/dist/cli/chunks/hnswlib-node-UHEP6UZZ.js +2 -0
- package/dist/cli/chunks/{hooks-RDZSAFQG.js → hooks-2GU7LGNL.js} +58 -47
- package/dist/cli/chunks/{hybrid-router-HNPS6EFL.js → hybrid-router-Z5V4E5SJ.js} +2 -2
- package/dist/cli/chunks/{hypergraph-engine-JUFXRXCC.js → hypergraph-engine-F435AM7S.js} +2 -2
- package/dist/cli/chunks/{hypergraph-handler-YFRF53TF.js → hypergraph-handler-DQMYDUQY.js} +3 -3
- package/dist/cli/chunks/impact-analyzer-37TDXM6V.js +2 -0
- package/dist/cli/chunks/{init-handler-P4W5F57S.js → init-handler-Y4NPRT2W.js} +6 -6
- package/dist/cli/chunks/init-wizard-ONNAHU4H.js +2 -0
- package/dist/cli/chunks/kernel-3S7RJ7PT.js +2 -0
- package/dist/cli/chunks/{kilocode-installer-5VWY4DMH.js → kilocode-installer-EUTWNH4I.js} +2 -2
- package/dist/cli/chunks/{kiro-installer-PZC3BQII.js → kiro-installer-I3ECJ37F.js} +2 -2
- package/dist/cli/chunks/knowledge-graph-GNJMYFT2.js +2 -0
- package/dist/cli/chunks/{learning-4OH4ZG25.js → learning-5FW7N6DA.js} +3 -3
- package/dist/cli/chunks/{llm-router-LZBR6SZQ.js → llm-router-ZRYFNNPU.js} +4 -4
- package/dist/cli/chunks/{load-SPWP6VB3.js → load-7BF33NMJ.js} +2 -2
- package/dist/cli/chunks/load-test-ZHTSLJMB.js +2 -0
- package/dist/cli/chunks/{mcp-QYPQMM7L.js → mcp-7K6P7FMG.js} +2 -2
- package/dist/cli/chunks/{memory-54ILJMWQ.js → memory-O2DCN3GS.js} +5 -5
- package/dist/cli/chunks/memory-backend-LN6NWT4F.js +2 -0
- package/dist/cli/chunks/{memory-handlers-YK7H5UCX.js → memory-handlers-WA63DMQ4.js} +2 -2
- package/dist/cli/chunks/{multi-model-executor-XAOAVPPI.js → multi-model-executor-SJXBFOK5.js} +2 -2
- package/dist/cli/chunks/{opencode-installer-CNS4XMUF.js → opencode-installer-PE7ZV6SV.js} +2 -2
- package/dist/cli/chunks/{orchestrator-SSEMSKUI.js → orchestrator-N4GT5IGY.js} +5 -5
- package/dist/cli/chunks/{pipeline-DS3AENTB.js → pipeline-DUTGGNO6.js} +2 -2
- package/dist/cli/chunks/{platform-BL6LH5NF.js → platform-EGUD7X2R.js} +2 -2
- package/dist/cli/chunks/{plugin-FNXPEQ2C.js → plugin-6ZS3HK43.js} +2 -2
- package/dist/cli/chunks/{prime-radiant-advanced-wasm-E6S6BGNA.js → prime-radiant-advanced-wasm-B5S4RUJS.js} +2 -2
- package/dist/cli/chunks/protocol-executor-ED36SYE4.js +2 -0
- package/dist/cli/chunks/{protocol-handler-D4WIUU3W.js → protocol-handler-Z3QDY7O6.js} +2 -2
- package/dist/cli/chunks/{prove-OLB3PKW6.js → prove-TQHP2XVD.js} +2 -2
- package/dist/cli/chunks/{provider-manager-GKTQ75DT.js → provider-manager-2JFXKYMZ.js} +3 -3
- package/dist/cli/chunks/qe-reasoning-bank-AC5ZWDAZ.js +2 -0
- package/dist/cli/chunks/{quality-ZYJVYTUL.js → quality-NXDHVPAS.js} +2 -2
- package/dist/cli/chunks/queen-coordinator-IZ4RQGKV.js +2 -0
- package/dist/cli/chunks/{real-embeddings-SKJRHLCS.js → real-embeddings-P2LYDBVF.js} +2 -2
- package/dist/cli/chunks/{roocode-installer-WZGKOLWE.js → roocode-installer-YSRXO4W4.js} +2 -2
- package/dist/cli/chunks/router-DZVPCD7E.js +2 -0
- package/dist/cli/chunks/routing-feedback-3LUE56G4.js +2 -0
- package/dist/cli/chunks/{routing-handler-4GIMINCI.js → routing-handler-HVDQQF34.js} +2 -2
- package/dist/cli/chunks/{ruvector-commands-YZONXZ2W.js → ruvector-commands-5NJ5FQ3E.js} +2 -2
- package/dist/cli/chunks/{rvf-dual-writer-WSS5GF54.js → rvf-dual-writer-GZ2HIIKX.js} +2 -2
- package/dist/cli/chunks/{rvf-migration-adapter-WS4HHVEU.js → rvf-migration-adapter-QKEYGJFL.js} +2 -2
- package/dist/cli/chunks/{rvf-migration-coordinator-6BY5GI47.js → rvf-migration-coordinator-5RBME46Y.js} +2 -2
- package/dist/cli/chunks/rvf-native-adapter-UTX4WYSI.js +2 -0
- package/dist/cli/chunks/safe-db-PEJN42TX.js +2 -0
- package/dist/cli/chunks/schedule-UULIQP2J.js +2 -0
- package/dist/cli/chunks/scheduler-T57XAXKF.js +2 -0
- package/dist/cli/chunks/{security-HCNOL2K3.js → security-KB4TOOFJ.js} +3 -3
- package/dist/cli/chunks/shared-rvf-adapter-UZVFV2RJ.js +2 -0
- package/dist/cli/chunks/{shared-rvf-dual-writer-QRNLSDS7.js → shared-rvf-dual-writer-UMDFMGVS.js} +2 -2
- package/dist/cli/chunks/sqlite-persistence-W7E26KF3.js +2 -0
- package/dist/cli/chunks/{status-handler-QXZ442MY.js → status-handler-T53CO6SX.js} +2 -2
- package/dist/cli/chunks/{structural-health-OFYZ3Z4A.js → structural-health-AVS2GE7S.js} +2 -2
- package/dist/cli/chunks/{sync-J4BG65NF.js → sync-Q3UHMELK.js} +2 -2
- package/dist/cli/chunks/{task-handler-UBSFCKK3.js → task-handler-UAJWNRMS.js} +2 -2
- package/dist/cli/chunks/task-handlers-HYSHMTJN.js +9 -0
- package/dist/cli/chunks/{test-WTNAHJHH.js → test-GMXM664Y.js} +4 -4
- package/dist/cli/chunks/{test-scheduling-QREBYRGW.js → test-scheduling-PYU4NLDU.js} +3 -3
- package/dist/cli/chunks/{token-bootstrap-HE5H77OL.js → token-bootstrap-5SIETJI6.js} +2 -2
- package/dist/cli/chunks/{token-usage-V5B6K3JL.js → token-usage-3H4KEKTT.js} +2 -2
- package/dist/cli/chunks/{hnswlib-node-WTTST5LC.js → transformers-ZFPUASV4.js} +2 -2
- package/dist/cli/chunks/{tree-sitter-wasm-parser-WP2SF2M5.js → tree-sitter-wasm-parser-X72YXRIP.js} +2 -2
- package/dist/cli/chunks/{types-7ZBTAO5Z.js → types-CB2HAVZ6.js} +2 -2
- package/dist/cli/chunks/unified-memory-SAIRUPOI.js +2 -0
- package/dist/cli/chunks/unified-memory-hnsw-NQALAER6.js +2 -0
- package/dist/cli/chunks/unified-persistence-XNGQFWFS.js +2 -0
- package/dist/cli/chunks/{upgrade-WIFAJDBG.js → upgrade-BWAZTJKE.js} +2 -2
- package/dist/cli/chunks/{validate-W63V36GA.js → validate-3OVVTWN6.js} +2 -2
- package/dist/cli/chunks/{validate-swarm-CK5BM3YY.js → validate-swarm-WJVG4OUQ.js} +2 -2
- package/dist/cli/chunks/{vibium-MJCCO36E.js → vibium-IIU2F5HC.js} +2 -2
- package/dist/cli/chunks/visual-security-CE37LMFR.js +2 -0
- package/dist/cli/chunks/{web-tree-sitter-ESERXLPK.js → web-tree-sitter-RO4TKGTV.js} +2 -2
- package/dist/cli/chunks/{windsurf-installer-FDWQ5BWI.js → windsurf-installer-7N5CZTJS.js} +2 -2
- package/dist/cli/chunks/{witness-chain-L5KSYE2S.js → witness-chain-B4CHDDS5.js} +2 -2
- package/dist/cli/chunks/witness-chain-L2KM336B.js +2 -0
- package/dist/cli/chunks/{workflow-34GYJDFW.js → workflow-FKJKW36Z.js} +4 -4
- package/dist/cli/chunks/workflow-orchestrator-BE5PCEBO.js +2 -0
- package/dist/cli/chunks/{wrappers-VGKEBQLW.js → wrappers-HU3SB4FT.js} +2 -2
- package/dist/cli/commands/hooks-handlers/hooks-dream-learning.js +54 -0
- package/dist/cli/commands/init.js +3 -1
- package/dist/coordination/consensus/providers/claude-provider.js +1 -1
- package/dist/domains/code-intelligence/coordinator.js +20 -0
- package/dist/integrations/agentic-flow/reasoning-bank/experience-replay.js +82 -0
- package/dist/integrations/embeddings/index/HNSWIndex.js +16 -6
- package/dist/integrations/ruvector/hypergraph-engine.d.ts +45 -0
- package/dist/integrations/ruvector/hypergraph-engine.js +102 -0
- package/dist/integrations/ruvector/shared-rvf-adapter.js +110 -2
- package/dist/learning/dream/dream-engine.js +8 -0
- package/dist/learning/pattern-store.js +38 -1
- package/dist/mcp/bundle.js +361 -344
- package/dist/mcp/entry.js +15 -0
- package/dist/mcp/handlers/core-handlers.js +2 -2
- package/dist/mcp/handlers/task-handlers.js +45 -0
- package/dist/mcp/handlers/trajectory-judge.d.ts +13 -0
- package/dist/mcp/handlers/trajectory-judge.js +100 -0
- package/dist/shared/llm/providers/claude.js +1 -1
- package/package.json +2 -2
- package/scripts/preinstall.cjs +54 -0
- package/dist/cli/chunks/adapter-5NI3IO42.js +0 -2
- package/dist/cli/chunks/aqe-learning-engine-JOUK5HMO.js +0 -2
- package/dist/cli/chunks/base-DCAB7AHK.js +0 -2
- package/dist/cli/chunks/browser-workflow-A4UV73SZ.js +0 -2
- package/dist/cli/chunks/chunk-2WM4NYM5.js +0 -2
- package/dist/cli/chunks/chunk-D2EHD2KF.js +0 -2
- package/dist/cli/chunks/chunk-VPDZTMMB.js +0 -24
- package/dist/cli/chunks/chunk-Z2E5DTKX.js +0 -2
- package/dist/cli/chunks/client-UTNF2C5K.js +0 -2
- package/dist/cli/chunks/cross-domain-router-FCM34JOR.js +0 -2
- package/dist/cli/chunks/dream-6KCS7EWS.js +0 -2
- package/dist/cli/chunks/hnsw-adapter-PG6O67CQ.js +0 -2
- package/dist/cli/chunks/hnsw-index-AHYZHLNZ.js +0 -2
- package/dist/cli/chunks/impact-analyzer-USAJVJY5.js +0 -2
- package/dist/cli/chunks/init-wizard-GL7LAZID.js +0 -2
- package/dist/cli/chunks/kernel-2YAIESTR.js +0 -2
- package/dist/cli/chunks/knowledge-graph-QSIYZRAG.js +0 -2
- package/dist/cli/chunks/load-test-UEHSHLVN.js +0 -2
- package/dist/cli/chunks/memory-backend-4NE4ADPG.js +0 -2
- package/dist/cli/chunks/protocol-executor-YI4HNXND.js +0 -2
- package/dist/cli/chunks/qe-reasoning-bank-ANBAXQXC.js +0 -2
- package/dist/cli/chunks/queen-coordinator-MYYUSWVX.js +0 -2
- package/dist/cli/chunks/router-RYCLZ7A4.js +0 -2
- package/dist/cli/chunks/routing-feedback-5KSRG2UI.js +0 -2
- package/dist/cli/chunks/rvf-native-adapter-NEIOLJRF.js +0 -2
- package/dist/cli/chunks/safe-db-3JQP4EPU.js +0 -2
- package/dist/cli/chunks/schedule-2QKCL64E.js +0 -2
- package/dist/cli/chunks/scheduler-FMOP45FC.js +0 -2
- package/dist/cli/chunks/shared-rvf-adapter-BMFIVWMJ.js +0 -2
- package/dist/cli/chunks/sqlite-persistence-I5RYLFOE.js +0 -2
- package/dist/cli/chunks/task-handlers-JFUT2FQ7.js +0 -2
- package/dist/cli/chunks/transformers-HIVMQP4O.js +0 -2
- package/dist/cli/chunks/unified-memory-2ETCY22B.js +0 -2
- package/dist/cli/chunks/unified-memory-hnsw-OALJW537.js +0 -2
- package/dist/cli/chunks/unified-persistence-SQMP7A3O.js +0 -2
- package/dist/cli/chunks/visual-security-JUJPF2QO.js +0 -2
- package/dist/cli/chunks/witness-chain-QJVKAAZT.js +0 -2
- package/dist/cli/chunks/workflow-orchestrator-WXB2RVVW.js +0 -2
|
@@ -308,6 +308,26 @@ export class CodeIntelligenceCoordinator extends BaseDomainCoordinator {
|
|
|
308
308
|
if (codeIndexResult.files.length > 0) {
|
|
309
309
|
await this.hypergraph.buildFromIndexResult(codeIndexResult);
|
|
310
310
|
logger.info(`Hypergraph rebuilt from ${codeIndexResult.files.length} indexed files`);
|
|
311
|
+
// Synthesize test-coverage shape so findUntestedFunctions /
|
|
312
|
+
// findImpactedTests have data to read. buildFromIndexResult
|
|
313
|
+
// only writes file/entity nodes, `contains` edges (Phase 2),
|
|
314
|
+
// and `imports` edges (Phase 3) — none of which match the
|
|
315
|
+
// `type='test'` + `type='covers'` filters those queries
|
|
316
|
+
// require. The synthesizer re-tags test-shaped file nodes
|
|
317
|
+
// and writes covers edges from each test file to the
|
|
318
|
+
// functions in the source files it imports. (Issue #439 /
|
|
319
|
+
// Jordi P220 follow-up.)
|
|
320
|
+
try {
|
|
321
|
+
const synth = await this.hypergraph.synthesizeTestCoverage();
|
|
322
|
+
if (synth.testsTagged > 0 || synth.coversCreated > 0) {
|
|
323
|
+
logger.info(`Test coverage synthesized: tests_tagged=${synth.testsTagged} covers_created=${synth.coversCreated}`);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
catch (synthError) {
|
|
327
|
+
// Non-fatal — hypergraph nodes/edges from buildFromIndexResult
|
|
328
|
+
// remain useful for module-dependency queries.
|
|
329
|
+
logger.warn(`Test coverage synthesis skipped: ${synthError instanceof Error ? synthError.message : synthError}`);
|
|
330
|
+
}
|
|
311
331
|
}
|
|
312
332
|
}
|
|
313
333
|
catch (hgError) {
|
|
@@ -103,6 +103,88 @@ export class ExperienceReplay {
|
|
|
103
103
|
this.prepareStatements();
|
|
104
104
|
// Load embeddings into memory index
|
|
105
105
|
await this.loadEmbeddingIndex();
|
|
106
|
+
// Backfill missing embeddings on captured_experiences. Hook-side INSERT
|
|
107
|
+
// paths (sources: cli-hook-post-command, patch-060-post-task, etc.)
|
|
108
|
+
// bypass storeExperience() and never call computeRealEmbedding(),
|
|
109
|
+
// leaving HNSW C cold. Fire-and-forget so init isn't blocked; cap=200
|
|
110
|
+
// per boot to bound work.
|
|
111
|
+
void (async () => {
|
|
112
|
+
try {
|
|
113
|
+
if (!this.db)
|
|
114
|
+
return;
|
|
115
|
+
const ghosts = this.db.prepare(`
|
|
116
|
+
SELECT id, domain, task FROM captured_experiences
|
|
117
|
+
WHERE embedding IS NULL AND consolidated_into IS NULL
|
|
118
|
+
LIMIT 200
|
|
119
|
+
`).all();
|
|
120
|
+
if (ghosts.length === 0)
|
|
121
|
+
return;
|
|
122
|
+
const updateStmt = this.db.prepare(`
|
|
123
|
+
UPDATE captured_experiences
|
|
124
|
+
SET embedding = ?, embedding_dimension = ?
|
|
125
|
+
WHERE id = ?
|
|
126
|
+
`);
|
|
127
|
+
let written = 0;
|
|
128
|
+
for (const row of ghosts) {
|
|
129
|
+
const text = `${row.domain ?? ''}: ${row.task}`.slice(0, 512);
|
|
130
|
+
const embedding = await computeRealEmbedding(text);
|
|
131
|
+
const buf = Buffer.from(new Float32Array(embedding).buffer);
|
|
132
|
+
updateStmt.run(buf, embedding.length, row.id);
|
|
133
|
+
// Add to live HNSW so freshly-embedded rows are immediately searchable
|
|
134
|
+
const hnswId = this.nextHnswId++;
|
|
135
|
+
this.hnswIndex.addEmbedding({
|
|
136
|
+
vector: embedding,
|
|
137
|
+
dimension: 384,
|
|
138
|
+
namespace: 'experiences',
|
|
139
|
+
text: row.id,
|
|
140
|
+
timestamp: Date.now(),
|
|
141
|
+
quantization: 'none',
|
|
142
|
+
metadata: {},
|
|
143
|
+
}, hnswId);
|
|
144
|
+
this.idToExperienceId.set(hnswId, row.id);
|
|
145
|
+
this.experienceIdToHnswId.set(row.id, hnswId);
|
|
146
|
+
written++;
|
|
147
|
+
}
|
|
148
|
+
console.log(`[ExperienceReplay] Backfilled ${written} captured_experiences embeddings`);
|
|
149
|
+
}
|
|
150
|
+
catch (err) {
|
|
151
|
+
console.warn('[ExperienceReplay] Embedding backfill failed:', err instanceof Error ? err.message : err);
|
|
152
|
+
}
|
|
153
|
+
})();
|
|
154
|
+
// Backfill missing embeddings on qe_trajectories. TrajectoryTracker.endTrajectory()
|
|
155
|
+
// writes embedding=NULL with no follow-up worker; hook-side trajectory inserts
|
|
156
|
+
// (cli-hook-post-task) also leave the column NULL. Without this, kNN over
|
|
157
|
+
// historical trajectories collapses to "no candidates" and ReasoningBank
|
|
158
|
+
// can't surface similar past runs. Fail-soft when embedding column is absent
|
|
159
|
+
// (TrajectoryTracker may not have run its schema migration yet).
|
|
160
|
+
void (async () => {
|
|
161
|
+
try {
|
|
162
|
+
if (!this.db)
|
|
163
|
+
return;
|
|
164
|
+
const cols = this.db.prepare("PRAGMA table_info(qe_trajectories)").all();
|
|
165
|
+
if (!cols.some(c => c.name === 'embedding'))
|
|
166
|
+
return;
|
|
167
|
+
const rows = this.db.prepare(`
|
|
168
|
+
SELECT id, domain, task FROM qe_trajectories
|
|
169
|
+
WHERE embedding IS NULL AND ended_at IS NOT NULL
|
|
170
|
+
LIMIT 200
|
|
171
|
+
`).all();
|
|
172
|
+
if (rows.length === 0)
|
|
173
|
+
return;
|
|
174
|
+
const updateStmt = this.db.prepare(`UPDATE qe_trajectories SET embedding = ? WHERE id = ?`);
|
|
175
|
+
let written = 0;
|
|
176
|
+
for (const row of rows) {
|
|
177
|
+
const text = `${row.domain ?? ''}: ${row.task}`.slice(0, 512);
|
|
178
|
+
const embedding = await computeRealEmbedding(text);
|
|
179
|
+
updateStmt.run(Buffer.from(new Float32Array(embedding).buffer), row.id);
|
|
180
|
+
written++;
|
|
181
|
+
}
|
|
182
|
+
console.log(`[ExperienceReplay] Backfilled ${written} qe_trajectories embeddings`);
|
|
183
|
+
}
|
|
184
|
+
catch (err) {
|
|
185
|
+
console.warn('[ExperienceReplay] Trajectory embedding backfill failed:', err instanceof Error ? err.message : err);
|
|
186
|
+
}
|
|
187
|
+
})();
|
|
106
188
|
// Initialize reservoir buffer if feature flag is enabled (R10, ADR-087)
|
|
107
189
|
if (getRuVectorFeatureFlags().useReservoirReplay) {
|
|
108
190
|
this.reservoirBuffer = new ReservoirReplayBuffer({ capacity: 10_000 });
|
|
@@ -9,10 +9,18 @@
|
|
|
9
9
|
*
|
|
10
10
|
* @module integrations/embeddings/index/HNSWIndex
|
|
11
11
|
*/
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
let cachedHnswlibCtor = null;
|
|
13
|
+
function loadHnswlibConstructor() {
|
|
14
|
+
if (cachedHnswlibCtor)
|
|
15
|
+
return cachedHnswlibCtor;
|
|
16
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
17
|
+
const mod = require('hnswlib-node');
|
|
18
|
+
if (!mod.HierarchicalNSW) {
|
|
19
|
+
throw new Error('hnswlib-node module missing HierarchicalNSW export');
|
|
20
|
+
}
|
|
21
|
+
cachedHnswlibCtor = mod.HierarchicalNSW;
|
|
22
|
+
return cachedHnswlibCtor;
|
|
23
|
+
}
|
|
16
24
|
// ADR-071 Phase 2C: Always use unified HnswAdapter backend.
|
|
17
25
|
// The hnswlib-node legacy path below is retained as dead code for
|
|
18
26
|
// emergency rollback only — production always takes the adapter path.
|
|
@@ -86,7 +94,8 @@ export class HNSWEmbeddingIndex {
|
|
|
86
94
|
'dotproduct': 'ip',
|
|
87
95
|
};
|
|
88
96
|
const space = spaceMap[this.config.metric] || 'cosine';
|
|
89
|
-
const
|
|
97
|
+
const HierarchicalNSWCtor = loadHnswlibConstructor();
|
|
98
|
+
const index = new HierarchicalNSWCtor(space, this.config.dimension);
|
|
90
99
|
index.initIndex({
|
|
91
100
|
maxElements: 10000,
|
|
92
101
|
m: this.config.M,
|
|
@@ -221,7 +230,8 @@ export class HNSWEmbeddingIndex {
|
|
|
221
230
|
'dotproduct': 'ip',
|
|
222
231
|
};
|
|
223
232
|
const space = spaceMap[this.config.metric] || 'cosine';
|
|
224
|
-
const
|
|
233
|
+
const HierarchicalNSWCtor = loadHnswlibConstructor();
|
|
234
|
+
const index = new HierarchicalNSWCtor(space, this.config.dimension);
|
|
225
235
|
await index.readIndex(path);
|
|
226
236
|
this.indexes.set(namespace, index);
|
|
227
237
|
this.initialized.add(namespace);
|
|
@@ -348,6 +348,51 @@ export declare class HypergraphEngine {
|
|
|
348
348
|
getStats(): Promise<HypergraphStats>;
|
|
349
349
|
private ensureInitialized;
|
|
350
350
|
private mapEntityTypeToNodeType;
|
|
351
|
+
/**
|
|
352
|
+
* Synthesize test-coverage edges from existing index state.
|
|
353
|
+
*
|
|
354
|
+
* Closes the gap that left `findUntestedFunctions`/`findImpactedTests`
|
|
355
|
+
* blind on every project (issue #439 / Jordi P220 follow-up). The shape
|
|
356
|
+
* of the gap was: those queries filter on `type='test'` source nodes and
|
|
357
|
+
* `type='covers'` edges, but `buildFromIndexResult` only ever wrote
|
|
358
|
+
* `type='file'` nodes and `imports`/`contains` edges. Result: empty
|
|
359
|
+
* answers regardless of indexing activity.
|
|
360
|
+
*
|
|
361
|
+
* This synthesis runs as a post-step over what `buildFromIndexResult`
|
|
362
|
+
* already produced:
|
|
363
|
+
*
|
|
364
|
+
* 1. **Tag test files.** Re-type any file node whose path matches a
|
|
365
|
+
* test naming pattern (`.test.ts`, `.spec.ts`, `_test.py`, …) from
|
|
366
|
+
* `'file'` to `'test'`. Idempotent — re-tagging a node already
|
|
367
|
+
* typed `'test'` is a no-op. Existing-file UPDATEs in Phase 1 of
|
|
368
|
+
* `buildFromIndexResult` only touch `nodesUpdated++` counter (no
|
|
369
|
+
* column UPDATE), so the `'test'` tag survives subsequent indexes.
|
|
370
|
+
*
|
|
371
|
+
* 2. **Synthesize `covers` edges.** For each test file, walk its
|
|
372
|
+
* `imports` edges to find imported source files; for each source
|
|
373
|
+
* file, walk its `contains` edges to find function entities; write
|
|
374
|
+
* `INSERT OR REPLACE` `covers` edges from the test file to each
|
|
375
|
+
* such function. This is a heuristic — Jest/Vitest projects
|
|
376
|
+
* typically `import { Foo } from '../src/foo'` and exercise `Foo`'s
|
|
377
|
+
* methods in `it(...)` blocks; we treat that import structure as
|
|
378
|
+
* proxy evidence of coverage. A proper coverage harness (Istanbul/
|
|
379
|
+
* c8 lcov ingest) would produce sharper edges, but those would
|
|
380
|
+
* slot in via the same `covers` schema.
|
|
381
|
+
*
|
|
382
|
+
* Idempotent: repeated calls converge — `INSERT OR REPLACE` on the same
|
|
383
|
+
* edge id (`${testId}--covers-->${fnId}`) is a no-op for unchanged
|
|
384
|
+
* topology.
|
|
385
|
+
*
|
|
386
|
+
* @returns Counts: `testsTagged` (file→test re-types this call) and
|
|
387
|
+
* `coversCreated` (covers-edge writes this call, including
|
|
388
|
+
* replacements of existing rows).
|
|
389
|
+
*/
|
|
390
|
+
synthesizeTestCoverage(opts?: {
|
|
391
|
+
testPathPatterns?: RegExp[];
|
|
392
|
+
}): Promise<{
|
|
393
|
+
testsTagged: number;
|
|
394
|
+
coversCreated: number;
|
|
395
|
+
}>;
|
|
351
396
|
}
|
|
352
397
|
/**
|
|
353
398
|
* Create a new HypergraphEngine instance
|
|
@@ -767,7 +767,109 @@ export class HypergraphEngine {
|
|
|
767
767
|
};
|
|
768
768
|
return mapping[entityType] ?? 'function';
|
|
769
769
|
}
|
|
770
|
+
/**
|
|
771
|
+
* Synthesize test-coverage edges from existing index state.
|
|
772
|
+
*
|
|
773
|
+
* Closes the gap that left `findUntestedFunctions`/`findImpactedTests`
|
|
774
|
+
* blind on every project (issue #439 / Jordi P220 follow-up). The shape
|
|
775
|
+
* of the gap was: those queries filter on `type='test'` source nodes and
|
|
776
|
+
* `type='covers'` edges, but `buildFromIndexResult` only ever wrote
|
|
777
|
+
* `type='file'` nodes and `imports`/`contains` edges. Result: empty
|
|
778
|
+
* answers regardless of indexing activity.
|
|
779
|
+
*
|
|
780
|
+
* This synthesis runs as a post-step over what `buildFromIndexResult`
|
|
781
|
+
* already produced:
|
|
782
|
+
*
|
|
783
|
+
* 1. **Tag test files.** Re-type any file node whose path matches a
|
|
784
|
+
* test naming pattern (`.test.ts`, `.spec.ts`, `_test.py`, …) from
|
|
785
|
+
* `'file'` to `'test'`. Idempotent — re-tagging a node already
|
|
786
|
+
* typed `'test'` is a no-op. Existing-file UPDATEs in Phase 1 of
|
|
787
|
+
* `buildFromIndexResult` only touch `nodesUpdated++` counter (no
|
|
788
|
+
* column UPDATE), so the `'test'` tag survives subsequent indexes.
|
|
789
|
+
*
|
|
790
|
+
* 2. **Synthesize `covers` edges.** For each test file, walk its
|
|
791
|
+
* `imports` edges to find imported source files; for each source
|
|
792
|
+
* file, walk its `contains` edges to find function entities; write
|
|
793
|
+
* `INSERT OR REPLACE` `covers` edges from the test file to each
|
|
794
|
+
* such function. This is a heuristic — Jest/Vitest projects
|
|
795
|
+
* typically `import { Foo } from '../src/foo'` and exercise `Foo`'s
|
|
796
|
+
* methods in `it(...)` blocks; we treat that import structure as
|
|
797
|
+
* proxy evidence of coverage. A proper coverage harness (Istanbul/
|
|
798
|
+
* c8 lcov ingest) would produce sharper edges, but those would
|
|
799
|
+
* slot in via the same `covers` schema.
|
|
800
|
+
*
|
|
801
|
+
* Idempotent: repeated calls converge — `INSERT OR REPLACE` on the same
|
|
802
|
+
* edge id (`${testId}--covers-->${fnId}`) is a no-op for unchanged
|
|
803
|
+
* topology.
|
|
804
|
+
*
|
|
805
|
+
* @returns Counts: `testsTagged` (file→test re-types this call) and
|
|
806
|
+
* `coversCreated` (covers-edge writes this call, including
|
|
807
|
+
* replacements of existing rows).
|
|
808
|
+
*/
|
|
809
|
+
async synthesizeTestCoverage(opts) {
|
|
810
|
+
this.ensureInitialized();
|
|
811
|
+
const patterns = opts?.testPathPatterns ?? DEFAULT_TEST_PATH_PATTERNS;
|
|
812
|
+
let testsTagged = 0;
|
|
813
|
+
let coversCreated = 0;
|
|
814
|
+
const fileRows = this.config.db
|
|
815
|
+
.prepare(`SELECT id, file_path FROM hypergraph_nodes
|
|
816
|
+
WHERE type IN ('file', 'test') AND file_path IS NOT NULL`)
|
|
817
|
+
.all();
|
|
818
|
+
const testFileIds = [];
|
|
819
|
+
for (const row of fileRows) {
|
|
820
|
+
if (patterns.some((p) => p.test(row.file_path))) {
|
|
821
|
+
testFileIds.push(row.id);
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
if (testFileIds.length === 0) {
|
|
825
|
+
return { testsTagged: 0, coversCreated: 0 };
|
|
826
|
+
}
|
|
827
|
+
const tagStmt = this.config.db.prepare(`UPDATE hypergraph_nodes SET type = 'test', updated_at = datetime('now')
|
|
828
|
+
WHERE id = ? AND type = 'file'`);
|
|
829
|
+
const findImportsStmt = this.config.db.prepare(`SELECT target_id FROM hypergraph_edges
|
|
830
|
+
WHERE source_id = ? AND type = 'imports'`);
|
|
831
|
+
const findFunctionsStmt = this.config.db.prepare(`SELECT n.id AS id FROM hypergraph_nodes n
|
|
832
|
+
JOIN hypergraph_edges e ON e.target_id = n.id
|
|
833
|
+
WHERE e.source_id = ? AND e.type = 'contains' AND n.type = 'function'`);
|
|
834
|
+
const insertCoversStmt = this.config.db.prepare(`
|
|
835
|
+
INSERT OR REPLACE INTO hypergraph_edges (id, source_id, target_id, type, weight)
|
|
836
|
+
VALUES (?, ?, ?, 'covers', 1.0)
|
|
837
|
+
`);
|
|
838
|
+
const txn = this.config.db.transaction(() => {
|
|
839
|
+
for (const testId of testFileIds) {
|
|
840
|
+
// (1) Re-tag — only counts the first transition file→test.
|
|
841
|
+
const taggedRows = tagStmt.run(testId).changes;
|
|
842
|
+
if (taggedRows > 0)
|
|
843
|
+
testsTagged++;
|
|
844
|
+
// (2) Walk imports → contains → write covers.
|
|
845
|
+
const importedFileIds = findImportsStmt.all(testId).map((r) => r.target_id);
|
|
846
|
+
for (const fileId of importedFileIds) {
|
|
847
|
+
const functionIds = findFunctionsStmt.all(fileId).map((r) => r.id);
|
|
848
|
+
for (const fnId of functionIds) {
|
|
849
|
+
const edgeId = `${testId}--covers-->${fnId}`;
|
|
850
|
+
insertCoversStmt.run(edgeId, testId, fnId);
|
|
851
|
+
coversCreated++;
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
});
|
|
856
|
+
txn();
|
|
857
|
+
return { testsTagged, coversCreated };
|
|
858
|
+
}
|
|
770
859
|
}
|
|
860
|
+
/**
|
|
861
|
+
* Test-file path patterns matched by {@link HypergraphEngine.synthesizeTestCoverage}.
|
|
862
|
+
* Mirrors `KnowledgeGraphService.isTestFile` so the two layers agree on what
|
|
863
|
+
* "looks like a test file" means.
|
|
864
|
+
*/
|
|
865
|
+
const DEFAULT_TEST_PATH_PATTERNS = [
|
|
866
|
+
/\.test\.[tj]sx?$/,
|
|
867
|
+
/\.spec\.[tj]sx?$/,
|
|
868
|
+
/_test\.[tj]sx?$/,
|
|
869
|
+
/test_.*\.py$/,
|
|
870
|
+
/.*_test\.py$/,
|
|
871
|
+
/.*_test\.go$/,
|
|
872
|
+
];
|
|
771
873
|
// ============================================================================
|
|
772
874
|
// Factory Functions
|
|
773
875
|
// ============================================================================
|
|
@@ -26,14 +26,28 @@ export function getSharedRvfAdapter(dataDir = '.agentic-qe', dimensions = 384) {
|
|
|
26
26
|
try {
|
|
27
27
|
// Dynamic require to match the bundled build pattern used elsewhere
|
|
28
28
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
29
|
-
const { isRvfNativeAvailable, createRvfStore } = require('./rvf-native-adapter.js');
|
|
29
|
+
const { isRvfNativeAvailable, createRvfStore, openRvfStore } = require('./rvf-native-adapter.js');
|
|
30
30
|
if (!isRvfNativeAvailable()) {
|
|
31
31
|
console.warn('[RVF] Native bindings unavailable — agent branching and dream COW disabled. ' +
|
|
32
32
|
'Install @ruvector/rvf-node to enable.');
|
|
33
33
|
return null;
|
|
34
34
|
}
|
|
35
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
35
36
|
const path = require('path');
|
|
36
|
-
|
|
37
|
+
const rvfPath = path.join(dataDir, 'patterns.rvf');
|
|
38
|
+
// Open-or-create with a try-ladder rather than `existsSync` gate.
|
|
39
|
+
// Reasons:
|
|
40
|
+
// 1. RVF native's `RvfDatabase.create()` throws `0x0303 FsyncFailed`
|
|
41
|
+
// when the target file already exists (verified against both 0.1.7
|
|
42
|
+
// and 0.1.8 native binaries on linux-arm64). Earlier init phases
|
|
43
|
+
// legitimately produce patterns.rvf, so subsequent CLI / MCP boot
|
|
44
|
+
// would crash without this guard. (Jordi #439 / RUFLO P020.)
|
|
45
|
+
// 2. A bare `existsSync(...) ? open : create` is racy across
|
|
46
|
+
// processes — two parallel `aqe` invocations during init can both
|
|
47
|
+
// observe absent and both call `create`, with the second hitting
|
|
48
|
+
// FsyncFailed regardless. The try-ladder degrades to whichever
|
|
49
|
+
// path the OS actually permits.
|
|
50
|
+
sharedAdapter = openOrCreateRvf(openRvfStore, createRvfStore, rvfPath, dimensions);
|
|
37
51
|
return sharedAdapter;
|
|
38
52
|
}
|
|
39
53
|
catch (error) {
|
|
@@ -41,6 +55,100 @@ export function getSharedRvfAdapter(dataDir = '.agentic-qe', dimensions = 384) {
|
|
|
41
55
|
return null;
|
|
42
56
|
}
|
|
43
57
|
}
|
|
58
|
+
/**
|
|
59
|
+
* Race-tolerant open-or-create.
|
|
60
|
+
* Tries open first (cheap, succeeds for the common case where init has
|
|
61
|
+
* already produced the file). On open failure we attempt create. On the
|
|
62
|
+
* concurrent-create loser, create itself fails with `FsyncFailed`; we
|
|
63
|
+
* retry open once more. Any final exception bubbles up to the caller.
|
|
64
|
+
*
|
|
65
|
+
* Also asserts `dim()` matches the caller-requested `dimensions` after
|
|
66
|
+
* open so silent dimension drift between releases / configs is detected
|
|
67
|
+
* — a bad-dim file is closed and create() is attempted (fail-loud rather
|
|
68
|
+
* than corrupt-silently, which would manifest as wrong vector hits later).
|
|
69
|
+
*/
|
|
70
|
+
function openOrCreateRvf(openFn, createFn, rvfPath, dimensions) {
|
|
71
|
+
const tryOpen = () => {
|
|
72
|
+
try {
|
|
73
|
+
return { adapter: openFn(rvfPath), err: null };
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
return { adapter: null, err };
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
const isLockHeld = (err) => {
|
|
80
|
+
const m = err instanceof Error ? err.message : String(err);
|
|
81
|
+
return m.includes('LockHeld') || m.includes('0x0300');
|
|
82
|
+
};
|
|
83
|
+
// Pass 1: try to open whatever's there.
|
|
84
|
+
let { adapter: opened, err: openErr } = tryOpen();
|
|
85
|
+
// Pass 1.5: stale-lock recovery. The native binding writes a `<rvfPath>.lock`
|
|
86
|
+
// file on open and removes it on close. `aqe init` and short-lived CLI
|
|
87
|
+
// processes routinely exit without an explicit close, leaving a stale
|
|
88
|
+
// .lock that subsequent invocations interpret as `LockHeld`. Since AQE
|
|
89
|
+
// CLI is overwhelmingly single-shot serial, the realistic case is "the
|
|
90
|
+
// prior process is dead and the lock is stale". We unlink the .lock and
|
|
91
|
+
// retry open exactly once. If a genuinely-live peer existed, it still
|
|
92
|
+
// holds the file open — but the binding's lock is content-based (lock
|
|
93
|
+
// file presence), so this is a best-effort cooperative recovery rather
|
|
94
|
+
// than an OS-level lock break.
|
|
95
|
+
if (!opened && isLockHeld(openErr)) {
|
|
96
|
+
try {
|
|
97
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
98
|
+
const fs = require('fs');
|
|
99
|
+
const lockPath = `${rvfPath}.lock`;
|
|
100
|
+
if (fs.existsSync(lockPath)) {
|
|
101
|
+
fs.unlinkSync(lockPath);
|
|
102
|
+
console.warn(`[RVF] Removed stale lock file at ${lockPath} (prior process exited without closing). ` +
|
|
103
|
+
'Retrying open. If you see this repeatedly under live concurrency, file an issue.');
|
|
104
|
+
({ adapter: opened, err: openErr } = tryOpen());
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
catch (recoveryErr) {
|
|
108
|
+
// Lock removal failed (permissions?) — fall through to error path.
|
|
109
|
+
if (process.env.DEBUG) {
|
|
110
|
+
console.debug('[RVF] stale-lock recovery failed:', recoveryErr instanceof Error ? recoveryErr.message : recoveryErr);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (opened) {
|
|
115
|
+
const actualDim = opened.dimension();
|
|
116
|
+
if (actualDim === dimensions)
|
|
117
|
+
return opened;
|
|
118
|
+
console.warn(`[RVF] patterns.rvf dimension mismatch: file=${actualDim} requested=${dimensions} — ` +
|
|
119
|
+
'closing and degrading. Delete the .rvf file to recreate at the requested dim.');
|
|
120
|
+
try {
|
|
121
|
+
opened.close();
|
|
122
|
+
}
|
|
123
|
+
catch { /* best-effort */ }
|
|
124
|
+
// Don't auto-recreate over a dim-mismatched file. Surface to caller via
|
|
125
|
+
// throw so getSharedRvfAdapter logs and returns null (degrade to SQLite).
|
|
126
|
+
throw new Error(`RVF dimension mismatch (file=${actualDim}, requested=${dimensions})`);
|
|
127
|
+
}
|
|
128
|
+
// Pass 2: open failed even after stale-lock recovery → try create.
|
|
129
|
+
try {
|
|
130
|
+
return createFn(rvfPath, dimensions);
|
|
131
|
+
}
|
|
132
|
+
catch (createErr) {
|
|
133
|
+
// Pass 3: create failed (likely FsyncFailed because a peer process won
|
|
134
|
+
// the race). Try open one more time.
|
|
135
|
+
try {
|
|
136
|
+
const reopened = openFn(rvfPath);
|
|
137
|
+
if (reopened.dimension() !== dimensions) {
|
|
138
|
+
try {
|
|
139
|
+
reopened.close();
|
|
140
|
+
}
|
|
141
|
+
catch { /* best-effort */ }
|
|
142
|
+
throw new Error(`RVF dimension mismatch after race (file=${reopened.dimension()}, requested=${dimensions})`);
|
|
143
|
+
}
|
|
144
|
+
return reopened;
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
// Fall through with the more informative original error.
|
|
148
|
+
throw createErr instanceof Error ? createErr : new Error(String(createErr));
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
44
152
|
/** Close the shared adapter and reset the singleton. */
|
|
45
153
|
export function resetSharedRvfAdapter() {
|
|
46
154
|
if (sharedAdapter) {
|
|
@@ -235,6 +235,14 @@ export class DreamEngine {
|
|
|
235
235
|
await this.persistence.initialize();
|
|
236
236
|
}
|
|
237
237
|
this.db = this.persistence.getDatabase();
|
|
238
|
+
// ADR-001 Option C: dynamic-import paths in checkAndTriggerDream() open
|
|
239
|
+
// a fresh handle that the hook/worker busy_timeout pragmas never reach.
|
|
240
|
+
// 60s patient timeout here keeps dream cycles from failing under WAL
|
|
241
|
+
// contention from MCP workers (was 71% failure rate observed).
|
|
242
|
+
try {
|
|
243
|
+
this.db.pragma('busy_timeout = 60000');
|
|
244
|
+
}
|
|
245
|
+
catch { /* fail-soft */ }
|
|
238
246
|
// Migrate legacy schema: rename 'duration' → 'duration_ms' if needed
|
|
239
247
|
this.migrateSchema();
|
|
240
248
|
// Initialize concept graph (shares same unified persistence)
|
|
@@ -1391,7 +1391,44 @@ export function createPatternStore(memory, config) {
|
|
|
1391
1391
|
// Shared adapter unavailable — fall back to direct create
|
|
1392
1392
|
}
|
|
1393
1393
|
if (!useSharedAdapter) {
|
|
1394
|
-
|
|
1394
|
+
// Race-tolerant open-or-create with dim verification, mirroring
|
|
1395
|
+
// shared-rvf-adapter.ts. Bare `existsSync ? open : create` is
|
|
1396
|
+
// racy across processes (two parallel CLI invocations during init
|
|
1397
|
+
// both observe absent, second hits FsyncFailed regardless). Try
|
|
1398
|
+
// open first, fall back to create, retry open on create-race.
|
|
1399
|
+
// (Jordi #439 / RUFLO P020.)
|
|
1400
|
+
const store = new RvfPatternStore((path, dim) => {
|
|
1401
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
1402
|
+
const { openRvfStore } = require('../integrations/ruvector/rvf-native-adapter.js');
|
|
1403
|
+
const tryOpen = () => {
|
|
1404
|
+
try {
|
|
1405
|
+
return openRvfStore(path);
|
|
1406
|
+
}
|
|
1407
|
+
catch {
|
|
1408
|
+
return null;
|
|
1409
|
+
}
|
|
1410
|
+
};
|
|
1411
|
+
let adapter = tryOpen();
|
|
1412
|
+
if (adapter) {
|
|
1413
|
+
if (adapter.dimension() !== dim) {
|
|
1414
|
+
try {
|
|
1415
|
+
adapter.close();
|
|
1416
|
+
}
|
|
1417
|
+
catch { /* best-effort */ }
|
|
1418
|
+
throw new Error(`RVF dimension mismatch (file=${adapter.dimension()}, requested=${dim})`);
|
|
1419
|
+
}
|
|
1420
|
+
return adapter;
|
|
1421
|
+
}
|
|
1422
|
+
try {
|
|
1423
|
+
return _createRvfStore(path, dim);
|
|
1424
|
+
}
|
|
1425
|
+
catch (createErr) {
|
|
1426
|
+
adapter = tryOpen();
|
|
1427
|
+
if (adapter && adapter.dimension() === dim)
|
|
1428
|
+
return adapter;
|
|
1429
|
+
throw createErr;
|
|
1430
|
+
}
|
|
1431
|
+
}, { rvfPath, base: mergedConfig });
|
|
1395
1432
|
console.log('[PatternStore] Using RVF-backed store (ADR-066)');
|
|
1396
1433
|
return store;
|
|
1397
1434
|
}
|