agentic-qe 3.9.15 → 3.9.16
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 +25 -0
- package/assets/skills/skills-manifest.json +1 -1
- package/dist/cli/brain-commands.d.ts +14 -0
- package/dist/cli/brain-commands.js +24 -0
- package/dist/cli/bundle.js +7 -7
- package/dist/cli/chunks/adapter-XFJIW42U.js +2 -0
- package/dist/cli/chunks/{agent-booster-wasm-NA2VN5U2.js → agent-booster-wasm-IECTFMRK.js} +2 -2
- package/dist/cli/chunks/{agent-handler-NRIF5IOC.js → agent-handler-HLLTKZ5G.js} +2 -2
- package/dist/cli/chunks/{agent-memory-branch-NW3UB2UW.js → agent-memory-branch-WJUD3DS4.js} +2 -2
- package/dist/cli/chunks/aqe-learning-engine-UD4SXENM.js +2 -0
- package/dist/cli/chunks/{audit-5CSEDVJR.js → audit-3DLZNWHO.js} +2 -2
- package/dist/cli/chunks/base-ETEN7L2V.js +2 -0
- package/dist/cli/chunks/{better-sqlite3-FZ32SHZ6.js → better-sqlite3-Q356NEQ6.js} +2 -2
- package/dist/cli/chunks/brain-handler-MX2HP7LO.js +89 -0
- package/dist/cli/chunks/{branch-enumerator-IUHWHIMV.js → branch-enumerator-Z3TF3HVO.js} +2 -2
- package/dist/cli/chunks/{browser-D4F3327X.js → browser-Z6PQ7FTO.js} +2 -2
- package/dist/cli/chunks/browser-workflow-KVHPOIBA.js +2 -0
- package/dist/cli/chunks/{chunk-ELLNKP3I.js → chunk-2KCMS4UW.js} +3 -3
- package/dist/cli/chunks/{chunk-IMLH32AG.js → chunk-2MJEAEOW.js} +2 -2
- package/dist/cli/chunks/{chunk-ISNXE6TP.js → chunk-3ADFXSO2.js} +2 -2
- package/dist/cli/chunks/{chunk-WI6UA5HV.js → chunk-3CAPNE2H.js} +2 -2
- package/dist/cli/chunks/{chunk-65QA7MYW.js → chunk-3EUA73H6.js} +2 -2
- package/dist/cli/chunks/{chunk-D3FV5NNA.js → chunk-3H657FNU.js} +2 -2
- package/dist/cli/chunks/{chunk-OMTYOIOS.js → chunk-3K4IX7L4.js} +2 -2
- package/dist/cli/chunks/{chunk-DYQ7HTEU.js → chunk-3SLFWPRE.js} +3 -3
- package/dist/cli/chunks/{chunk-MHL6CPGY.js → chunk-3ZGYB23S.js} +1 -1
- package/dist/cli/chunks/{chunk-IHDW4HW7.js → chunk-46K7ALFU.js} +2 -2
- package/dist/cli/chunks/{chunk-HNAQNAGI.js → chunk-4CFQZHUC.js} +3 -3
- package/dist/cli/chunks/{chunk-2XW36KDQ.js → chunk-4PFHQH4B.js} +2 -2
- package/dist/cli/chunks/{chunk-C5BRTU4V.js → chunk-4ZN4GM7W.js} +1 -1
- package/dist/cli/chunks/{chunk-3FUKJT4S.js → chunk-5A5XANSD.js} +2 -2
- package/dist/cli/chunks/{chunk-OUP2X3LT.js → chunk-5E7FVOOG.js} +1 -1
- package/dist/cli/chunks/chunk-5LDXAVDC.js +2 -0
- package/dist/cli/chunks/{chunk-6Z7LYE2B.js → chunk-666L7MC2.js} +2 -2
- package/dist/cli/chunks/{chunk-DPEG44BS.js → chunk-66BUIFFH.js} +2 -2
- package/dist/cli/chunks/{chunk-HJNFBJT5.js → chunk-6V5P2VMQ.js} +8 -8
- package/dist/cli/chunks/{chunk-3NIHJIWP.js → chunk-6XKZ62O7.js} +2 -2
- package/dist/cli/chunks/{chunk-D3ZUSXFY.js → chunk-77OVXVN2.js} +2 -2
- package/dist/cli/chunks/{chunk-WCOJGDGO.js → chunk-7DP2IQ6F.js} +2 -2
- package/dist/cli/chunks/{chunk-Q3GDSFGA.js → chunk-7IF4LRX2.js} +2 -2
- package/dist/cli/chunks/{chunk-ZOAPOVYW.js → chunk-7JFSMXIA.js} +2 -2
- package/dist/cli/chunks/{chunk-O6J7MKRV.js → chunk-7MF6LVLH.js} +2 -2
- package/dist/cli/chunks/{chunk-REUGPZIA.js → chunk-7NMLIJHL.js} +1 -1
- package/dist/cli/chunks/{chunk-DATFN5DG.js → chunk-7PHYOV2X.js} +2 -2
- package/dist/cli/chunks/{chunk-RSOOENGE.js → chunk-7V2Z3PUJ.js} +2 -2
- package/dist/cli/chunks/{chunk-UZOFXYNC.js → chunk-AA6IUBCM.js} +2 -2
- package/dist/cli/chunks/{chunk-QNLZKD7E.js → chunk-AFLQFUXA.js} +2 -2
- package/dist/cli/chunks/{chunk-7J5KWUC2.js → chunk-BCT26J7X.js} +1 -1
- package/dist/cli/chunks/{chunk-RODJK6G6.js → chunk-BEE5KXQT.js} +1 -1
- package/dist/cli/chunks/{chunk-BGUCXJEJ.js → chunk-BNDK7JRW.js} +2 -2
- package/dist/cli/chunks/{chunk-6AMD4PZB.js → chunk-CR7LLS26.js} +2 -2
- package/dist/cli/chunks/{chunk-62MVVEGH.js → chunk-DBCN7R63.js} +1 -1
- package/dist/cli/chunks/{chunk-AVKUFN3C.js → chunk-DF3DZP7H.js} +2 -2
- package/dist/cli/chunks/{chunk-HWK27KJK.js → chunk-DJPS7H2M.js} +1 -1
- package/dist/cli/chunks/{chunk-MBDX4OHD.js → chunk-ED5OUSYZ.js} +1 -1
- package/dist/cli/chunks/{chunk-FW6QBTPE.js → chunk-EFTK4ZVP.js} +1 -1
- package/dist/cli/chunks/{chunk-N2RPLPVG.js → chunk-FEQ5RDQL.js} +2 -2
- package/dist/cli/chunks/{chunk-JQRR37YY.js → chunk-FKQV52TC.js} +2 -2
- package/dist/cli/chunks/{chunk-KJTXY3DW.js → chunk-FLWIEPAT.js} +1 -1
- package/dist/cli/chunks/{chunk-ORKGVVXK.js → chunk-FQTUUZVK.js} +1 -1
- package/dist/cli/chunks/{chunk-RTVD7SZQ.js → chunk-G5DMEEQQ.js} +1 -1
- package/dist/cli/chunks/{chunk-IPVKVPAF.js → chunk-GB6D3SSY.js} +2 -2
- package/dist/cli/chunks/{chunk-37ZSWRRP.js → chunk-GP7IXB3E.js} +2 -2
- package/dist/cli/chunks/{chunk-LNUWNRRJ.js → chunk-H3JEGAFC.js} +9 -9
- package/dist/cli/chunks/{chunk-LLVS3UYZ.js → chunk-H4BZJVKU.js} +2 -2
- package/dist/cli/chunks/{chunk-RPOW5LWO.js → chunk-HFGCLV56.js} +1 -1
- package/dist/cli/chunks/{chunk-MS6T4VCU.js → chunk-HJUC2DE6.js} +2 -2
- package/dist/cli/chunks/{chunk-II5KTTIS.js → chunk-HN6GVQ4Q.js} +4 -4
- package/dist/cli/chunks/{chunk-CSB2M7IX.js → chunk-HON4X4Z3.js} +2 -2
- package/dist/cli/chunks/{chunk-NL2PQLRD.js → chunk-HVAW64YW.js} +2 -2
- package/dist/cli/chunks/{chunk-6TOUMCSE.js → chunk-HXF4FUPY.js} +2 -2
- package/dist/cli/chunks/{chunk-TJDAXI6E.js → chunk-IUQ6HE2J.js} +2 -2
- package/dist/cli/chunks/{chunk-7ZPNQ3T6.js → chunk-J2ERTUDX.js} +1 -1
- package/dist/cli/chunks/{chunk-2CN2NPJQ.js → chunk-JCQ5PXVM.js} +2 -2
- package/dist/cli/chunks/{chunk-WAQ3U4FC.js → chunk-JNXIYHLI.js} +1 -1
- package/dist/cli/chunks/{chunk-EY2DGYQX.js → chunk-JUKCBZCZ.js} +1 -1
- package/dist/cli/chunks/{chunk-TZWCVGG2.js → chunk-JZOMOYHZ.js} +1 -1
- package/dist/cli/chunks/{chunk-ZSC7NHK3.js → chunk-KLVS6FT2.js} +2 -2
- package/dist/cli/chunks/{chunk-XALB3KRR.js → chunk-KR7S4IZZ.js} +2 -2
- package/dist/cli/chunks/{chunk-MO4Q5ZGE.js → chunk-L2GANTQN.js} +2 -2
- package/dist/cli/chunks/{chunk-ESQSX37W.js → chunk-LJINNQNN.js} +2 -2
- package/dist/cli/chunks/{chunk-OBZMQFWG.js → chunk-LSA4XGSE.js} +2 -2
- package/dist/cli/chunks/{chunk-3Y4YZDHJ.js → chunk-LVA53A5R.js} +4 -4
- package/dist/cli/chunks/{chunk-V775NJOM.js → chunk-LVK2PDUW.js} +1 -1
- package/dist/cli/chunks/{chunk-B4BOOOYM.js → chunk-LWG7LKOK.js} +1 -1
- package/dist/cli/chunks/{chunk-NWMYV7KG.js → chunk-MECDNFOJ.js} +2 -2
- package/dist/cli/chunks/{chunk-Q3E6Z2RQ.js → chunk-MFRC267A.js} +1 -1
- package/dist/cli/chunks/{chunk-2BBKAX7X.js → chunk-MJKFU6A6.js} +2 -2
- package/dist/cli/chunks/{chunk-4T36OQUK.js → chunk-MQHP65QB.js} +3 -3
- package/dist/cli/chunks/{chunk-GLJ6CJNY.js → chunk-MTF6ABUH.js} +2 -2
- package/dist/cli/chunks/{chunk-56YHSI6R.js → chunk-N5ZTPAX7.js} +2 -2
- package/dist/cli/chunks/{chunk-V65DK6ZZ.js → chunk-NCXXXZGL.js} +1 -1
- package/dist/cli/chunks/{chunk-YCYFUYCE.js → chunk-NIXMFJJC.js} +2 -2
- package/dist/cli/chunks/{chunk-GHEO5YVA.js → chunk-NLU4XJBN.js} +1 -1
- package/dist/cli/chunks/{chunk-CUQBOVRP.js → chunk-NOJVROCD.js} +1 -1
- package/dist/cli/chunks/{chunk-HPY7HGVQ.js → chunk-OE7SGIX2.js} +2 -2
- package/dist/cli/chunks/{chunk-AE65B2ZE.js → chunk-OP7X434R.js} +2 -2
- package/dist/cli/chunks/{chunk-E3EDVRB5.js → chunk-P4IYRPCB.js} +1 -1
- package/dist/cli/chunks/{chunk-PSOIVDD2.js → chunk-PNZADZSI.js} +3 -3
- package/dist/cli/chunks/{chunk-FSOY2XB4.js → chunk-PPUEXTH2.js} +3 -3
- package/dist/cli/chunks/{chunk-6F3H2C5H.js → chunk-PQLT3X6X.js} +3 -3
- package/dist/cli/chunks/{chunk-W4PUKTBF.js → chunk-QEKZA2NJ.js} +1 -1
- package/dist/cli/chunks/{chunk-IPTGPCEL.js → chunk-QKQAQPXY.js} +2 -2
- package/dist/cli/chunks/{chunk-JAIIPEE6.js → chunk-RFLSJ7OL.js} +2 -2
- package/dist/cli/chunks/{chunk-U4WDJPRL.js → chunk-RVQXMMRO.js} +2 -2
- package/dist/cli/chunks/{chunk-EORSYD66.js → chunk-RYCAVZSD.js} +2 -2
- package/dist/cli/chunks/{chunk-D32YCVCA.js → chunk-SMNOZEM7.js} +2 -2
- package/dist/cli/chunks/{chunk-ZHTCZGML.js → chunk-T36IXY5W.js} +2 -2
- package/dist/cli/chunks/{chunk-6OEGZSRK.js → chunk-T7VIUEKI.js} +2 -2
- package/dist/cli/chunks/{chunk-6BHAGCZD.js → chunk-TFBEX7ED.js} +1 -1
- package/dist/cli/chunks/{chunk-V6QARSVQ.js → chunk-TPRYLARW.js} +2 -2
- package/dist/cli/chunks/{chunk-3BA2FGSA.js → chunk-TR4NPMRW.js} +2 -2
- package/dist/cli/chunks/{chunk-R4G64UH3.js → chunk-TUPFBZKO.js} +1 -1
- package/dist/cli/chunks/{chunk-KKBSX43Q.js → chunk-TWEBJWJI.js} +2 -2
- package/dist/cli/chunks/{chunk-RWVFOXYM.js → chunk-UH7TV6BY.js} +1 -1
- package/dist/cli/chunks/{chunk-2L5ZFBHP.js → chunk-UT4CXF6C.js} +2 -2
- package/dist/cli/chunks/{chunk-JJDHD7SC.js → chunk-V2ELGHLG.js} +2 -2
- package/dist/cli/chunks/{chunk-G3FUOFXA.js → chunk-VK2GKQYI.js} +2 -2
- package/dist/cli/chunks/{chunk-VBEVZUQW.js → chunk-VNAAXZGF.js} +1 -1
- package/dist/cli/chunks/{chunk-O6CHLZYT.js → chunk-VOAECU7B.js} +2 -2
- package/dist/cli/chunks/{chunk-3RSPEFU3.js → chunk-W4ZV6LAJ.js} +2 -2
- package/dist/cli/chunks/{chunk-XXRDI53H.js → chunk-W6TMZY5R.js} +2 -2
- package/dist/cli/chunks/{chunk-CWWUBZNX.js → chunk-WKLSXJD4.js} +2 -2
- package/dist/cli/chunks/{chunk-H6DAP4KS.js → chunk-WSKASZYC.js} +2 -2
- package/dist/cli/chunks/{chunk-VDDQSW4L.js → chunk-WVFLNGOK.js} +2 -2
- package/dist/cli/chunks/{chunk-SSQ42GI7.js → chunk-WVHH3OQ4.js} +2 -2
- package/dist/cli/chunks/{chunk-OHESV6I3.js → chunk-XAULPLOC.js} +4 -4
- package/dist/cli/chunks/{chunk-GWUO3RY5.js → chunk-XKMMFQSJ.js} +1 -1
- package/dist/cli/chunks/{chunk-SXUX6PTE.js → chunk-XQ6WIPDC.js} +1 -1
- package/dist/cli/chunks/{chunk-4M7RBSW6.js → chunk-ZCE6JNRI.js} +2 -2
- package/dist/cli/chunks/{chunk-CF3W34BA.js → chunk-ZCZJYM42.js} +1 -1
- package/dist/cli/chunks/{chunk-ICXWXO5P.js → chunk-ZXLF3IKT.js} +1 -1
- package/dist/cli/chunks/{ci-BGUUHDUS.js → ci-TTP5HJSW.js} +2 -2
- package/dist/cli/chunks/{ci-output-CDFRGBNU.js → ci-output-TKESU45X.js} +2 -2
- package/dist/cli/chunks/{circuit-breaker-S3NFX6RQ.js → circuit-breaker-GFRV5R7E.js} +2 -2
- package/dist/cli/chunks/{claude-flow-setup-AJIPJFMC.js → claude-flow-setup-LY6MADFA.js} +2 -2
- package/dist/cli/chunks/client-ZDVM5WFL.js +2 -0
- package/dist/cli/chunks/{cline-installer-6O4KZ5UH.js → cline-installer-OSAILLDH.js} +2 -2
- package/dist/cli/chunks/{code-IZALXUL5.js → code-ASRSOGYH.js} +2 -2
- package/dist/cli/chunks/{code-index-extractor-N7VDH4XF.js → code-index-extractor-AMLGVHB7.js} +2 -2
- package/dist/cli/chunks/{codex-installer-35GTWCFJ.js → codex-installer-3CKH3WV4.js} +2 -2
- package/dist/cli/chunks/{completions-XPJFHGG2.js → completions-MXNPWLOE.js} +91 -10
- package/dist/cli/chunks/{complexity-analyzer-DNLCJGUJ.js → complexity-analyzer-2Z347PXF.js} +2 -2
- package/dist/cli/chunks/{continuedev-installer-PXAIKNYO.js → continuedev-installer-LE7K745N.js} +2 -2
- package/dist/cli/chunks/{copilot-installer-2TQ5IZNY.js → copilot-installer-CHJL3275.js} +2 -2
- package/dist/cli/chunks/{cost-tracker-A5XH4W6S.js → cost-tracker-C3ZWNNSV.js} +2 -2
- package/dist/cli/chunks/{coverage-EPIMXTLW.js → coverage-6JOXBVDL.js} +3 -3
- package/dist/cli/chunks/cross-domain-router-J5VK276J.js +2 -0
- package/dist/cli/chunks/{cursor-installer-WMMRPW44.js → cursor-installer-RKCNWO42.js} +2 -2
- package/dist/cli/chunks/{daemon-55DSODOH.js → daemon-XXWOT6TM.js} +3 -3
- package/dist/cli/chunks/{dag-attention-scheduler-5DSWXMMK.js → dag-attention-scheduler-37MG6XR4.js} +2 -2
- package/dist/cli/chunks/{detect-NOS46AWN.js → detect-QOTL36CE.js} +2 -2
- package/dist/cli/chunks/{domain-handler-BFRNU6S3.js → domain-handler-TJNLNJ7Z.js} +2 -2
- package/dist/cli/chunks/{domain-transfer-BPSA4HFR.js → domain-transfer-FDHC2MGH.js} +2 -2
- package/dist/cli/chunks/dream-VCLN6RM4.js +2 -0
- package/dist/cli/chunks/esm-node-YZSRCH6T.js +2 -0
- package/dist/cli/chunks/{eval-YDLM23FB.js → eval-JP7CLUTD.js} +2 -2
- package/dist/cli/chunks/{fast-paths-GISZ7HBO.js → fast-paths-CWTVLIIC.js} +2 -2
- package/dist/cli/chunks/{feature-flags-5WGZLUPQ.js → feature-flags-H2UU53L4.js} +2 -2
- package/dist/cli/chunks/{feature-flags-3FLJF6CQ.js → feature-flags-SKFBAHR3.js} +2 -2
- package/dist/cli/chunks/{file-discovery-PPHUMFSI.js → file-discovery-RWVGKIDB.js} +2 -2
- package/dist/cli/chunks/{fleet-LHFZ53FS.js → fleet-JOSUYRTZ.js} +3 -3
- package/dist/cli/chunks/{gnn-wrapper-Z45DRWGI.js → gnn-wrapper-WNOZFTDD.js} +2 -2
- package/dist/cli/chunks/{heartbeat-handler-VMLJ5PDH.js → heartbeat-handler-73YSR6K7.js} +4 -4
- package/dist/cli/chunks/{heartbeat-scheduler-GUWYDHEY.js → heartbeat-scheduler-EN52JZUX.js} +2 -2
- package/dist/cli/chunks/hnsw-adapter-Y5HVTNJW.js +2 -0
- package/dist/cli/chunks/hnsw-index-NZTCPZA5.js +2 -0
- package/dist/cli/chunks/{hnsw-legacy-bridge-S7UZWDUP.js → hnsw-legacy-bridge-PWD6DXS4.js} +2 -2
- package/dist/cli/chunks/{hnswlib-node-MIAAS7OI.js → hnswlib-node-VAZOCNY7.js} +2 -2
- package/dist/cli/chunks/{hooks-ZN4FV5XS.js → hooks-K7XGDF2Y.js} +6 -6
- package/dist/cli/chunks/{hybrid-router-Y6LBFPL7.js → hybrid-router-6W323WKW.js} +2 -2
- package/dist/cli/chunks/{hypergraph-engine-KK73LZYZ.js → hypergraph-engine-R2N4C24I.js} +2 -2
- package/dist/cli/chunks/{hypergraph-handler-OBGDPIWG.js → hypergraph-handler-AY4YZDOG.js} +3 -3
- package/dist/cli/chunks/impact-analyzer-ROWLIS6H.js +2 -0
- package/dist/cli/chunks/{init-handler-JJJ7VHM4.js → init-handler-UDBW4P3Z.js} +6 -6
- package/dist/cli/chunks/init-wizard-MI76CUL5.js +2 -0
- package/dist/cli/chunks/kernel-5WVAV5RX.js +2 -0
- package/dist/cli/chunks/{kilocode-installer-EF6DPX2D.js → kilocode-installer-J2NZUDEQ.js} +2 -2
- package/dist/cli/chunks/{kiro-installer-SG74CEVO.js → kiro-installer-AHOOKFQH.js} +2 -2
- package/dist/cli/chunks/knowledge-graph-QXL3AWPV.js +2 -0
- package/dist/cli/chunks/{learning-LVWYMHF6.js → learning-VC7X2HKA.js} +3 -3
- package/dist/cli/chunks/{llm-router-QFK7MNPY.js → llm-router-3PU7CH5P.js} +4 -4
- package/dist/cli/chunks/{load-6XPV4WA2.js → load-WB4JD6X7.js} +2 -2
- package/dist/cli/chunks/load-test-2JOY7YH6.js +2 -0
- package/dist/cli/chunks/{mcp-GZXOPYMH.js → mcp-QUU2DYYK.js} +2 -2
- package/dist/cli/chunks/{memory-QTE2Z5HU.js → memory-UAEWPG34.js} +5 -5
- package/dist/cli/chunks/memory-backend-ZKGLAWQZ.js +2 -0
- package/dist/cli/chunks/{memory-handlers-PC4P4YEF.js → memory-handlers-3FBXIZG4.js} +2 -2
- package/dist/cli/chunks/{multi-model-executor-FZOPSUOT.js → multi-model-executor-CIUHXR43.js} +2 -2
- package/dist/cli/chunks/{opencode-installer-CITDTCUQ.js → opencode-installer-VV6RIHNR.js} +2 -2
- package/dist/cli/chunks/{orchestrator-ZTG7MFHQ.js → orchestrator-WV27PZZM.js} +5 -5
- package/dist/cli/chunks/{pipeline-QXO4EJP4.js → pipeline-JRBCX2U3.js} +2 -2
- package/dist/cli/chunks/{platform-JJEDYCAK.js → platform-TUPMH4ND.js} +2 -2
- package/dist/cli/chunks/{plugin-ZEKRM6F7.js → plugin-H757CYQK.js} +2 -2
- package/dist/cli/chunks/{prime-radiant-advanced-wasm-GRS4T6LR.js → prime-radiant-advanced-wasm-5BWO25RA.js} +2 -2
- package/dist/cli/chunks/protocol-executor-3Q4QY7G6.js +2 -0
- package/dist/cli/chunks/{protocol-handler-KWI2T6OR.js → protocol-handler-Z6DCNTUU.js} +2 -2
- package/dist/cli/chunks/{prove-7FJN2HEH.js → prove-4OGWFOUM.js} +2 -2
- package/dist/cli/chunks/{provider-manager-QYYZZLLO.js → provider-manager-K736L6LN.js} +2 -2
- package/dist/cli/chunks/qe-reasoning-bank-SAMJF3NF.js +2 -0
- package/dist/cli/chunks/{quality-4NHO2NY5.js → quality-YFLEATGZ.js} +2 -2
- package/dist/cli/chunks/queen-coordinator-OFRH67Y2.js +2 -0
- package/dist/cli/chunks/{real-embeddings-SIELAOWX.js → real-embeddings-5QUSL7J4.js} +2 -2
- package/dist/cli/chunks/{roocode-installer-ANYXH3NR.js → roocode-installer-HDWE5XW3.js} +2 -2
- package/dist/cli/chunks/router-UDHEENEY.js +2 -0
- package/dist/cli/chunks/routing-feedback-PBZRVFVL.js +2 -0
- package/dist/cli/chunks/{routing-handler-6QQHK4KV.js → routing-handler-P6PP3FYW.js} +2 -2
- package/dist/cli/chunks/{ruvector-commands-YEUA3MZB.js → ruvector-commands-VNMTRQML.js} +2 -2
- package/dist/cli/chunks/{rvf-dual-writer-UJFRHPVE.js → rvf-dual-writer-A7VW5CAT.js} +2 -2
- package/dist/cli/chunks/{rvf-migration-adapter-CSDFG7UA.js → rvf-migration-adapter-QIPSNASM.js} +2 -2
- package/dist/cli/chunks/{rvf-migration-coordinator-QO7OENQF.js → rvf-migration-coordinator-XT4XDLRZ.js} +2 -2
- package/dist/cli/chunks/rvf-native-adapter-CJFEDG74.js +2 -0
- package/dist/cli/chunks/safe-db-YMSZFHWP.js +2 -0
- package/dist/cli/chunks/schedule-B43N6CVB.js +2 -0
- package/dist/cli/chunks/scheduler-ITZH5YQM.js +2 -0
- package/dist/cli/chunks/{security-QCIUC5FX.js → security-E2XCP5CG.js} +3 -3
- package/dist/cli/chunks/shared-rvf-adapter-PV5ZBJ25.js +2 -0
- package/dist/cli/chunks/{shared-rvf-dual-writer-LVJJS3PD.js → shared-rvf-dual-writer-NPWTXHUI.js} +2 -2
- package/dist/cli/chunks/sqlite-persistence-RK5CKPHB.js +2 -0
- package/dist/cli/chunks/{status-handler-O77A4JWM.js → status-handler-MWVNDZSZ.js} +2 -2
- package/dist/cli/chunks/{structural-health-WIIBIIQI.js → structural-health-2KZO43IF.js} +2 -2
- package/dist/cli/chunks/{sync-UN6D6OF2.js → sync-C5BOK3WU.js} +2 -2
- package/dist/cli/chunks/{task-handler-RBOSMJCK.js → task-handler-KRVSHJGJ.js} +2 -2
- package/dist/cli/chunks/{task-handlers-VWMXQKAT.js → task-handlers-CKOHD633.js} +2 -2
- package/dist/cli/chunks/{test-XK5M3PGT.js → test-3B7FK6MJ.js} +4 -4
- package/dist/cli/chunks/{test-scheduling-CTQ3JJ7G.js → test-scheduling-HZIMSTAX.js} +3 -3
- package/dist/cli/chunks/{token-bootstrap-D5CQ3I5M.js → token-bootstrap-JJCANIHJ.js} +2 -2
- package/dist/cli/chunks/{token-usage-L4QSLWQ5.js → token-usage-5VCMBZU7.js} +2 -2
- package/dist/cli/chunks/{transformers-SRPJDBKA.js → transformers-ETUTMOTF.js} +2 -2
- package/dist/cli/chunks/{tree-sitter-wasm-parser-DOU5ITWB.js → tree-sitter-wasm-parser-TMR44BKP.js} +2 -2
- package/dist/cli/chunks/{types-LECYZUBN.js → types-GYT6373C.js} +2 -2
- package/dist/cli/chunks/unified-memory-LIKELZVA.js +2 -0
- package/dist/cli/chunks/unified-memory-hnsw-VTN3MUB4.js +2 -0
- package/dist/cli/chunks/unified-persistence-MQVUY5WN.js +2 -0
- package/dist/cli/chunks/upgrade-534QLY7P.js +5 -0
- package/dist/cli/chunks/{validate-SIKNIS6B.js → validate-UBVF3CSS.js} +2 -2
- package/dist/cli/chunks/{validate-swarm-EHAMMILJ.js → validate-swarm-2XD45EVM.js} +2 -2
- package/dist/cli/chunks/{vibium-LJ4NYXMZ.js → vibium-NMT6AQ4S.js} +2 -2
- package/dist/cli/chunks/visual-security-HVJWGY7T.js +2 -0
- package/dist/cli/chunks/{web-tree-sitter-DZQ3T4JD.js → web-tree-sitter-RNG6NRDD.js} +2 -2
- package/dist/cli/chunks/{windsurf-installer-U6Z73O6J.js → windsurf-installer-RVCDSJT3.js} +2 -2
- package/dist/cli/chunks/witness-chain-5R322YYF.js +2 -0
- package/dist/cli/chunks/{witness-chain-JE3QU4YP.js → witness-chain-YDFB22MT.js} +2 -2
- package/dist/cli/chunks/{workflow-62QXGZQO.js → workflow-MHW4KHNK.js} +4 -4
- package/dist/cli/chunks/workflow-orchestrator-637BCZI4.js +2 -0
- package/dist/cli/chunks/{wrappers-CAX5EZSH.js → wrappers-SAZY3C2S.js} +2 -2
- package/dist/cli/commands/upgrade.d.ts +96 -0
- package/dist/cli/commands/upgrade.js +342 -0
- package/dist/cli/completions/index.d.ts +27 -0
- package/dist/cli/completions/index.js +112 -14
- package/dist/cli/handlers/brain-handler.d.ts +2 -0
- package/dist/cli/handlers/brain-handler.js +221 -1
- package/dist/cli/index.js +5 -1
- package/dist/integrations/ruvector/brain-diff.d.ts +93 -0
- package/dist/integrations/ruvector/brain-diff.js +281 -0
- package/dist/integrations/ruvector/brain-search.d.ts +78 -0
- package/dist/integrations/ruvector/brain-search.js +154 -0
- package/dist/mcp/bundle.js +1 -1
- package/package.json +1 -1
- package/dist/cli/chunks/adapter-P2EPBJLF.js +0 -2
- package/dist/cli/chunks/aqe-learning-engine-6UITO3NJ.js +0 -2
- package/dist/cli/chunks/base-JHBJXVGP.js +0 -2
- package/dist/cli/chunks/brain-handler-ISVST4MR.js +0 -68
- package/dist/cli/chunks/browser-workflow-U4OON5DZ.js +0 -2
- package/dist/cli/chunks/chunk-FEVTMHO6.js +0 -2
- package/dist/cli/chunks/client-UHHMKUPF.js +0 -2
- package/dist/cli/chunks/cross-domain-router-GEBXTPZW.js +0 -2
- package/dist/cli/chunks/dream-XBRGYPBC.js +0 -2
- package/dist/cli/chunks/esm-node-EV4HOHTZ.js +0 -2
- package/dist/cli/chunks/hnsw-adapter-BG73YVXI.js +0 -2
- package/dist/cli/chunks/hnsw-index-K73ZTLJN.js +0 -2
- package/dist/cli/chunks/impact-analyzer-GWIUYYCQ.js +0 -2
- package/dist/cli/chunks/init-wizard-RIJJAKE3.js +0 -2
- package/dist/cli/chunks/kernel-SIPBCRGL.js +0 -2
- package/dist/cli/chunks/knowledge-graph-NOYZXHIG.js +0 -2
- package/dist/cli/chunks/load-test-DIMUH75F.js +0 -2
- package/dist/cli/chunks/memory-backend-IWOGO4BV.js +0 -2
- package/dist/cli/chunks/protocol-executor-NT4TILJW.js +0 -2
- package/dist/cli/chunks/qe-reasoning-bank-VDROHXFS.js +0 -2
- package/dist/cli/chunks/queen-coordinator-7LO73IV3.js +0 -2
- package/dist/cli/chunks/router-SFVOLN2W.js +0 -2
- package/dist/cli/chunks/routing-feedback-MRFV7WUZ.js +0 -2
- package/dist/cli/chunks/rvf-native-adapter-6L7FZZC7.js +0 -2
- package/dist/cli/chunks/safe-db-PYWBVGOV.js +0 -2
- package/dist/cli/chunks/schedule-BUQU75HY.js +0 -2
- package/dist/cli/chunks/scheduler-XOSKWZO2.js +0 -2
- package/dist/cli/chunks/shared-rvf-adapter-OZ7S4ZQL.js +0 -2
- package/dist/cli/chunks/sqlite-persistence-7UXQZ5Y6.js +0 -2
- package/dist/cli/chunks/unified-memory-L6735TFM.js +0 -2
- package/dist/cli/chunks/unified-memory-hnsw-7TZNEDGY.js +0 -2
- package/dist/cli/chunks/unified-persistence-FNYZ3C2B.js +0 -2
- package/dist/cli/chunks/visual-security-SMPZPDY4.js +0 -2
- package/dist/cli/chunks/witness-chain-FNCOTWFA.js +0 -2
- package/dist/cli/chunks/workflow-orchestrator-RCR4N7OA.js +0 -2
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import path from 'path';
|
|
8
8
|
import chalk from 'chalk';
|
|
9
|
-
import { exportBrain, importBrain, brainInfo, witnessBackfill, } from '../brain-commands.js';
|
|
9
|
+
import { exportBrain, importBrain, brainInfo, brainDiff, brainSearch, witnessBackfill, } from '../brain-commands.js';
|
|
10
10
|
// ============================================================================
|
|
11
11
|
// Brain Handler
|
|
12
12
|
// ============================================================================
|
|
@@ -56,6 +56,32 @@ export class BrainHandler {
|
|
|
56
56
|
.action(async (options) => {
|
|
57
57
|
await this.executeWitnessBackfill(options);
|
|
58
58
|
});
|
|
59
|
+
brain
|
|
60
|
+
.command('diff')
|
|
61
|
+
.description('Compare two brain exports (JSONL directory or .rvf file)')
|
|
62
|
+
.argument('<a>', 'Path to first brain export')
|
|
63
|
+
.argument('<b>', 'Path to second brain export')
|
|
64
|
+
.option('--table <name>', 'Restrict comparison to a single table')
|
|
65
|
+
.option('--verbose', 'Show the IDs of added/removed/changed records', false)
|
|
66
|
+
.option('--json', 'Emit the diff as JSON to stdout', false)
|
|
67
|
+
.action(async (a, b, options) => {
|
|
68
|
+
await this.executeDiff(a, b, options);
|
|
69
|
+
});
|
|
70
|
+
brain
|
|
71
|
+
.command('search')
|
|
72
|
+
.description('Search a JSONL brain export with filters')
|
|
73
|
+
.requiredOption('-i, --input <path>', 'Path to brain export directory (JSONL)')
|
|
74
|
+
.option('--table <name>', 'Table to search (default: qe_patterns)')
|
|
75
|
+
.option('--domain <name...>', 'Restrict to one or more domains')
|
|
76
|
+
.option('--pattern-type <type>', 'Restrict to a specific pattern_type (qe_patterns only)')
|
|
77
|
+
.option('--since <iso>', 'Include rows with timestamp ≥ <iso>')
|
|
78
|
+
.option('--until <iso>', 'Include rows with timestamp ≤ <iso>')
|
|
79
|
+
.option('-q, --query <text>', 'Substring match across name + description (case-insensitive)')
|
|
80
|
+
.option('-l, --limit <n>', 'Maximum results to return', '20')
|
|
81
|
+
.option('--json', 'Emit results as JSON to stdout', false)
|
|
82
|
+
.action(async (options) => {
|
|
83
|
+
await this.executeSearch(options);
|
|
84
|
+
});
|
|
59
85
|
}
|
|
60
86
|
async executeExport(options) {
|
|
61
87
|
try {
|
|
@@ -224,6 +250,51 @@ export class BrainHandler {
|
|
|
224
250
|
await this.cleanupAndExit(1);
|
|
225
251
|
}
|
|
226
252
|
}
|
|
253
|
+
async executeDiff(a, b, options) {
|
|
254
|
+
try {
|
|
255
|
+
const result = await brainDiff(path.resolve(a), path.resolve(b), {
|
|
256
|
+
tableFilter: options.table,
|
|
257
|
+
});
|
|
258
|
+
if (options.json) {
|
|
259
|
+
process.stdout.write(JSON.stringify(result, null, 2) + '\n');
|
|
260
|
+
await this.cleanupAndExit(result.identical ? 0 : 1);
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
renderDiff(result, options.verbose);
|
|
264
|
+
// Exit code convention: 0 when identical, 1 when differences exist.
|
|
265
|
+
await this.cleanupAndExit(result.identical ? 0 : 1);
|
|
266
|
+
}
|
|
267
|
+
catch (error) {
|
|
268
|
+
console.error(chalk.red('\n Brain diff failed:'), error);
|
|
269
|
+
await this.cleanupAndExit(2);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
async executeSearch(options) {
|
|
273
|
+
try {
|
|
274
|
+
const limit = parseLimit(options.limit);
|
|
275
|
+
const domains = normalizeDomainOption(options.domain);
|
|
276
|
+
const result = await brainSearch(path.resolve(options.input), {
|
|
277
|
+
table: options.table,
|
|
278
|
+
domains,
|
|
279
|
+
patternType: options.patternType,
|
|
280
|
+
since: options.since,
|
|
281
|
+
until: options.until,
|
|
282
|
+
query: options.query,
|
|
283
|
+
limit,
|
|
284
|
+
});
|
|
285
|
+
if (options.json) {
|
|
286
|
+
process.stdout.write(JSON.stringify(result, null, 2) + '\n');
|
|
287
|
+
await this.cleanupAndExit(result.totalMatched > 0 ? 0 : 3);
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
renderSearch(result);
|
|
291
|
+
await this.cleanupAndExit(result.totalMatched > 0 ? 0 : 3);
|
|
292
|
+
}
|
|
293
|
+
catch (error) {
|
|
294
|
+
console.error(chalk.red('\n Brain search failed:'), error);
|
|
295
|
+
await this.cleanupAndExit(2);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
227
298
|
async executeWitnessBackfill(options) {
|
|
228
299
|
try {
|
|
229
300
|
console.log(chalk.blue('\n Running witness chain backfill...\n'));
|
|
@@ -258,6 +329,8 @@ Subcommands:
|
|
|
258
329
|
export Export brain state to a portable .rvf file or JSONL directory
|
|
259
330
|
import Import a brain export into the local database
|
|
260
331
|
info Show manifest metadata for an existing brain export
|
|
332
|
+
diff Compare two brain exports (manifest always; record-level for JSONL)
|
|
333
|
+
search Filtered search over a JSONL brain export
|
|
261
334
|
|
|
262
335
|
Examples:
|
|
263
336
|
aqe brain export -o .agentic-qe/brain.rvf
|
|
@@ -266,6 +339,9 @@ Examples:
|
|
|
266
339
|
aqe brain import -i .agentic-qe/brain.rvf --strategy latest-wins
|
|
267
340
|
aqe brain import -i .agentic-qe/brain.rvf --dry-run
|
|
268
341
|
aqe brain info -i .agentic-qe/brain.rvf
|
|
342
|
+
aqe brain diff ./brain-a ./brain-b --verbose
|
|
343
|
+
aqe brain search -i ./brain-export --query oauth --domain test-generation
|
|
344
|
+
aqe brain search -i ./brain-export --since 2026-03-01 --limit 50 --json
|
|
269
345
|
`;
|
|
270
346
|
}
|
|
271
347
|
}
|
|
@@ -285,6 +361,150 @@ function formatBytes(bytes) {
|
|
|
285
361
|
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
286
362
|
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
287
363
|
}
|
|
364
|
+
function parseLimit(raw) {
|
|
365
|
+
const n = Number.parseInt(raw, 10);
|
|
366
|
+
if (!Number.isFinite(n) || n < 1)
|
|
367
|
+
return 20;
|
|
368
|
+
return n;
|
|
369
|
+
}
|
|
370
|
+
function normalizeDomainOption(value) {
|
|
371
|
+
if (value === undefined)
|
|
372
|
+
return undefined;
|
|
373
|
+
const arr = Array.isArray(value) ? value : [value];
|
|
374
|
+
const out = [];
|
|
375
|
+
for (const raw of arr) {
|
|
376
|
+
for (const part of raw.split(',')) {
|
|
377
|
+
const trimmed = part.trim();
|
|
378
|
+
if (trimmed)
|
|
379
|
+
out.push(trimmed);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
return out.length > 0 ? out : undefined;
|
|
383
|
+
}
|
|
384
|
+
function renderDiff(result, verbose) {
|
|
385
|
+
console.log(chalk.blue('\n Brain Diff\n'));
|
|
386
|
+
console.log(` A: ${chalk.cyan(result.pathA)} (${result.formatA})`);
|
|
387
|
+
console.log(` B: ${chalk.cyan(result.pathB)} (${result.formatB})`);
|
|
388
|
+
console.log(` Versions: ${chalk.cyan(result.manifestA.version)} → ${chalk.cyan(result.manifestB.version)}` +
|
|
389
|
+
(result.versionMatch ? chalk.gray(' (match)') : chalk.yellow(' (differ)')));
|
|
390
|
+
console.log(` Checksums: ${chalk.gray(result.manifestA.checksum.slice(0, 12))}… → ` +
|
|
391
|
+
`${chalk.gray(result.manifestB.checksum.slice(0, 12))}…` +
|
|
392
|
+
(result.checksumMatch ? chalk.gray(' (match)') : chalk.yellow(' (differ)')));
|
|
393
|
+
console.log(` Exported: ${chalk.gray(result.manifestA.exportedAt)} → ${chalk.gray(result.manifestB.exportedAt)}`);
|
|
394
|
+
console.log(` Records: ${chalk.cyan(result.manifestA.totalRecords)} → ${chalk.cyan(result.manifestB.totalRecords)} ` +
|
|
395
|
+
formatDelta(result.manifestB.totalRecords - result.manifestA.totalRecords));
|
|
396
|
+
if (result.domainsOnlyInA.length > 0 || result.domainsOnlyInB.length > 0) {
|
|
397
|
+
console.log(chalk.blue('\n Domains:'));
|
|
398
|
+
if (result.domainsOnlyInA.length > 0) {
|
|
399
|
+
console.log(` Only in A: ${chalk.yellow(result.domainsOnlyInA.join(', '))}`);
|
|
400
|
+
}
|
|
401
|
+
if (result.domainsOnlyInB.length > 0) {
|
|
402
|
+
console.log(` Only in B: ${chalk.yellow(result.domainsOnlyInB.join(', '))}`);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
if (!result.recordLevel) {
|
|
406
|
+
console.log(chalk.gray('\n Note: record-level diff is only available when both sides are JSONL exports.\n' +
|
|
407
|
+
' Per-table counts shown below; re-export with --format jsonl for added/removed/changed IDs.'));
|
|
408
|
+
}
|
|
409
|
+
console.log(chalk.blue('\n Tables:'));
|
|
410
|
+
const changed = result.tableDiffs.filter(tableHasChange);
|
|
411
|
+
if (changed.length === 0) {
|
|
412
|
+
console.log(chalk.gray(' (no differences)'));
|
|
413
|
+
}
|
|
414
|
+
else {
|
|
415
|
+
for (const t of changed) {
|
|
416
|
+
console.log(` ${t.tableName.padEnd(28)} ${chalk.cyan(String(t.countA).padStart(7))} → ` +
|
|
417
|
+
`${chalk.cyan(String(t.countB).padStart(7))} ${formatDelta(t.delta)}` +
|
|
418
|
+
formatRecordBuckets(t, verbose));
|
|
419
|
+
if (verbose) {
|
|
420
|
+
if (t.added && t.added.length > 0)
|
|
421
|
+
printIdBucket('added', t.added);
|
|
422
|
+
if (t.removed && t.removed.length > 0)
|
|
423
|
+
printIdBucket('removed', t.removed);
|
|
424
|
+
if (t.changed && t.changed.length > 0)
|
|
425
|
+
printIdBucket('changed', t.changed);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
console.log('');
|
|
430
|
+
if (result.identical) {
|
|
431
|
+
console.log(chalk.green(' Result: identical\n'));
|
|
432
|
+
}
|
|
433
|
+
else {
|
|
434
|
+
console.log(chalk.yellow(' Result: differences found\n'));
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
function tableHasChange(t) {
|
|
438
|
+
if (t.delta !== 0)
|
|
439
|
+
return true;
|
|
440
|
+
if (t.added && t.added.length > 0)
|
|
441
|
+
return true;
|
|
442
|
+
if (t.removed && t.removed.length > 0)
|
|
443
|
+
return true;
|
|
444
|
+
if (t.changed && t.changed.length > 0)
|
|
445
|
+
return true;
|
|
446
|
+
return false;
|
|
447
|
+
}
|
|
448
|
+
function formatDelta(delta) {
|
|
449
|
+
if (delta === 0)
|
|
450
|
+
return chalk.gray('(±0)');
|
|
451
|
+
if (delta > 0)
|
|
452
|
+
return chalk.green(`(+${delta})`);
|
|
453
|
+
return chalk.red(`(${delta})`);
|
|
454
|
+
}
|
|
455
|
+
function formatRecordBuckets(t, verbose) {
|
|
456
|
+
const parts = [];
|
|
457
|
+
if (t.added && t.added.length > 0)
|
|
458
|
+
parts.push(chalk.green(`+${t.added.length}`));
|
|
459
|
+
if (t.removed && t.removed.length > 0)
|
|
460
|
+
parts.push(chalk.red(`-${t.removed.length}`));
|
|
461
|
+
if (t.changed && t.changed.length > 0)
|
|
462
|
+
parts.push(chalk.yellow(`~${t.changed.length}`));
|
|
463
|
+
if (parts.length === 0)
|
|
464
|
+
return '';
|
|
465
|
+
if (verbose)
|
|
466
|
+
return ' ' + parts.join(' ');
|
|
467
|
+
return ' ' + chalk.gray('[') + parts.join(' ') + chalk.gray(']');
|
|
468
|
+
}
|
|
469
|
+
function printIdBucket(label, ids) {
|
|
470
|
+
const preview = ids.slice(0, 10).join(', ');
|
|
471
|
+
const suffix = ids.length > 10 ? chalk.gray(` …(+${ids.length - 10} more)`) : '';
|
|
472
|
+
console.log(` ${chalk.gray(label + ':')} ${preview}${suffix}`);
|
|
473
|
+
}
|
|
474
|
+
function renderSearch(result) {
|
|
475
|
+
console.log(chalk.blue('\n Brain Search\n'));
|
|
476
|
+
console.log(` Input: ${chalk.cyan(result.inputPath)}`);
|
|
477
|
+
console.log(` Table: ${chalk.cyan(result.table)}`);
|
|
478
|
+
console.log(` Scanned: ${chalk.cyan(result.totalScanned)} ` +
|
|
479
|
+
`Matched: ${chalk.cyan(result.totalMatched)} ` +
|
|
480
|
+
`Shown: ${chalk.cyan(result.hits.length)}` +
|
|
481
|
+
(result.truncated ? chalk.yellow(` (truncated to limit ${result.limit})`) : ''));
|
|
482
|
+
if (result.hits.length === 0) {
|
|
483
|
+
console.log(chalk.yellow('\n No matching rows.\n'));
|
|
484
|
+
return;
|
|
485
|
+
}
|
|
486
|
+
console.log('');
|
|
487
|
+
for (const hit of result.hits) {
|
|
488
|
+
const header = chalk.cyan(hit.id) +
|
|
489
|
+
(hit.display.patternType ? chalk.gray(` ${hit.display.patternType}`) : '') +
|
|
490
|
+
(hit.display.domain ? chalk.gray(` [${hit.display.domain}]`) : '') +
|
|
491
|
+
(hit.display.confidence !== undefined
|
|
492
|
+
? chalk.gray(` conf=${hit.display.confidence.toFixed(2)}`)
|
|
493
|
+
: '');
|
|
494
|
+
console.log(` ${header}`);
|
|
495
|
+
if (hit.display.name)
|
|
496
|
+
console.log(` ${chalk.bold(hit.display.name)}`);
|
|
497
|
+
if (hit.display.description) {
|
|
498
|
+
const desc = hit.display.description.length > 200
|
|
499
|
+
? hit.display.description.slice(0, 200) + '…'
|
|
500
|
+
: hit.display.description;
|
|
501
|
+
console.log(` ${chalk.gray(desc)}`);
|
|
502
|
+
}
|
|
503
|
+
if (hit.display.updatedAt)
|
|
504
|
+
console.log(` ${chalk.gray(hit.display.updatedAt)}`);
|
|
505
|
+
console.log('');
|
|
506
|
+
}
|
|
507
|
+
}
|
|
288
508
|
// ============================================================================
|
|
289
509
|
// Factory
|
|
290
510
|
// ============================================================================
|
package/dist/cli/index.js
CHANGED
|
@@ -47,7 +47,6 @@ console.log = (...args) => {
|
|
|
47
47
|
originalConsoleLog(...args);
|
|
48
48
|
};
|
|
49
49
|
// Also redirect timestamped INFO/WARN/ERROR log lines (e.g. "[07:12:24.372] [INFO ]")
|
|
50
|
-
const originalConsoleInfo = console.info.bind(console);
|
|
51
50
|
console.info = (...args) => {
|
|
52
51
|
process.stderr.write(args.map(String).join(' ') + '\n');
|
|
53
52
|
};
|
|
@@ -249,6 +248,11 @@ registerLazyCommand(program, {
|
|
|
249
248
|
description: 'Generate shell completions for aqe',
|
|
250
249
|
factory: () => import('./commands/completions.js').then(m => m.createCompletionsCommand(cleanupAndExit)),
|
|
251
250
|
});
|
|
251
|
+
registerLazyCommand(program, {
|
|
252
|
+
name: 'upgrade',
|
|
253
|
+
description: 'Detect optional native bindings and recommend install / flag changes',
|
|
254
|
+
factory: () => import('./commands/upgrade.js').then(m => m.createUpgradeCommand(cleanupAndExit)),
|
|
255
|
+
});
|
|
252
256
|
registerLazyCommand(program, {
|
|
253
257
|
name: 'fleet',
|
|
254
258
|
description: 'Fleet operations with multi-agent progress tracking',
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Brain Export Diff
|
|
3
|
+
*
|
|
4
|
+
* Compares two brain exports (JSONL directory or RVF file) and returns a
|
|
5
|
+
* structured diff.
|
|
6
|
+
*
|
|
7
|
+
* Two levels of comparison:
|
|
8
|
+
* - Manifest-level (always available): version, checksum, per-table record
|
|
9
|
+
* counts, exported_at, domain list delta.
|
|
10
|
+
* - Record-level (JSONL exports only): for each table with a PK, the set of
|
|
11
|
+
* added / removed / changed record IDs. For append-only tables only counts
|
|
12
|
+
* are reported.
|
|
13
|
+
*
|
|
14
|
+
* For RVF exports, record-level diff is not supported by this module (the
|
|
15
|
+
* kernel is opaque without @ruvector/rvf-node). Export as JSONL for full diff.
|
|
16
|
+
*/
|
|
17
|
+
import { type TableExportConfig } from './brain-shared.js';
|
|
18
|
+
export type ExportFormat = 'rvf' | 'jsonl';
|
|
19
|
+
export interface ManifestSummary {
|
|
20
|
+
readonly format: ExportFormat;
|
|
21
|
+
readonly version: string;
|
|
22
|
+
readonly exportedAt: string;
|
|
23
|
+
readonly sourceDb: string;
|
|
24
|
+
readonly checksum: string;
|
|
25
|
+
readonly totalRecords: number;
|
|
26
|
+
readonly domains: readonly string[];
|
|
27
|
+
readonly tableRecordCounts: Record<string, number>;
|
|
28
|
+
}
|
|
29
|
+
export interface TableDiff {
|
|
30
|
+
readonly tableName: string;
|
|
31
|
+
readonly countA: number;
|
|
32
|
+
readonly countB: number;
|
|
33
|
+
readonly delta: number;
|
|
34
|
+
/** Only populated for JSONL↔JSONL record-level diffs on PK tables. */
|
|
35
|
+
readonly added?: readonly string[];
|
|
36
|
+
readonly removed?: readonly string[];
|
|
37
|
+
readonly changed?: readonly string[];
|
|
38
|
+
}
|
|
39
|
+
export interface BrainDiffResult {
|
|
40
|
+
readonly pathA: string;
|
|
41
|
+
readonly pathB: string;
|
|
42
|
+
readonly formatA: ExportFormat;
|
|
43
|
+
readonly formatB: ExportFormat;
|
|
44
|
+
readonly manifestA: ManifestSummary;
|
|
45
|
+
readonly manifestB: ManifestSummary;
|
|
46
|
+
readonly checksumMatch: boolean;
|
|
47
|
+
readonly versionMatch: boolean;
|
|
48
|
+
readonly identical: boolean;
|
|
49
|
+
readonly recordLevel: boolean;
|
|
50
|
+
readonly tableDiffs: readonly TableDiff[];
|
|
51
|
+
readonly domainsOnlyInA: readonly string[];
|
|
52
|
+
readonly domainsOnlyInB: readonly string[];
|
|
53
|
+
}
|
|
54
|
+
export interface BrainDiffOptions {
|
|
55
|
+
/** Restrict comparison to a single table (by table name). */
|
|
56
|
+
readonly tableFilter?: string;
|
|
57
|
+
/** Cap on the number of IDs retained per added/removed/changed list. */
|
|
58
|
+
readonly maxIdsPerBucket?: number;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Compute the diff between two brain exports.
|
|
62
|
+
*
|
|
63
|
+
* Both paths may be JSONL directories or `.rvf` files. Record-level diff is
|
|
64
|
+
* only available when both sides are JSONL.
|
|
65
|
+
*/
|
|
66
|
+
export declare function diffBrains(pathA: string, pathB: string, options?: BrainDiffOptions): BrainDiffResult;
|
|
67
|
+
declare function pkFor(config: TableExportConfig): string;
|
|
68
|
+
/**
|
|
69
|
+
* Read a JSONL file and build a Map<identity, contentHash>.
|
|
70
|
+
*
|
|
71
|
+
* For PK tables the identity is the PK column value. For append-only tables
|
|
72
|
+
* the identity is a concatenation of the dedup columns (collisions are
|
|
73
|
+
* treated as "same record").
|
|
74
|
+
*/
|
|
75
|
+
declare function buildIdentityMap(filePath: string, config: TableExportConfig): Map<string, string>;
|
|
76
|
+
declare function identityOf(row: Record<string, unknown>, config: TableExportConfig): string | undefined;
|
|
77
|
+
declare function stableStringify(obj: Record<string, unknown>): string;
|
|
78
|
+
export interface DiffSummary {
|
|
79
|
+
readonly tablesChanged: number;
|
|
80
|
+
readonly totalAdded: number;
|
|
81
|
+
readonly totalRemoved: number;
|
|
82
|
+
readonly totalChanged: number;
|
|
83
|
+
readonly recordCountDelta: number;
|
|
84
|
+
}
|
|
85
|
+
export declare function summarizeDiff(result: BrainDiffResult): DiffSummary;
|
|
86
|
+
export declare const __test__: {
|
|
87
|
+
stableStringify: typeof stableStringify;
|
|
88
|
+
identityOf: typeof identityOf;
|
|
89
|
+
buildIdentityMap: typeof buildIdentityMap;
|
|
90
|
+
pkFor: typeof pkFor;
|
|
91
|
+
};
|
|
92
|
+
export {};
|
|
93
|
+
//# sourceMappingURL=brain-diff.d.ts.map
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Brain Export Diff
|
|
3
|
+
*
|
|
4
|
+
* Compares two brain exports (JSONL directory or RVF file) and returns a
|
|
5
|
+
* structured diff.
|
|
6
|
+
*
|
|
7
|
+
* Two levels of comparison:
|
|
8
|
+
* - Manifest-level (always available): version, checksum, per-table record
|
|
9
|
+
* counts, exported_at, domain list delta.
|
|
10
|
+
* - Record-level (JSONL exports only): for each table with a PK, the set of
|
|
11
|
+
* added / removed / changed record IDs. For append-only tables only counts
|
|
12
|
+
* are reported.
|
|
13
|
+
*
|
|
14
|
+
* For RVF exports, record-level diff is not supported by this module (the
|
|
15
|
+
* kernel is opaque without @ruvector/rvf-node). Export as JSONL for full diff.
|
|
16
|
+
*/
|
|
17
|
+
import { existsSync, readFileSync, statSync } from 'fs';
|
|
18
|
+
import { join, resolve } from 'path';
|
|
19
|
+
import { safeJsonParse } from '../../shared/safe-json.js';
|
|
20
|
+
import { brainInfoFromRvf } from './brain-rvf-exporter.js';
|
|
21
|
+
import { readJsonl, sha256, TABLE_CONFIGS, PK_COLUMNS, } from './brain-shared.js';
|
|
22
|
+
// ============================================================================
|
|
23
|
+
// Public API
|
|
24
|
+
// ============================================================================
|
|
25
|
+
/**
|
|
26
|
+
* Compute the diff between two brain exports.
|
|
27
|
+
*
|
|
28
|
+
* Both paths may be JSONL directories or `.rvf` files. Record-level diff is
|
|
29
|
+
* only available when both sides are JSONL.
|
|
30
|
+
*/
|
|
31
|
+
export function diffBrains(pathA, pathB, options = {}) {
|
|
32
|
+
const resolvedA = resolve(pathA);
|
|
33
|
+
const resolvedB = resolve(pathB);
|
|
34
|
+
const formatA = detectFormat(resolvedA);
|
|
35
|
+
const formatB = detectFormat(resolvedB);
|
|
36
|
+
const manifestA = readManifestSummary(resolvedA, formatA);
|
|
37
|
+
const manifestB = readManifestSummary(resolvedB, formatB);
|
|
38
|
+
const recordLevel = formatA === 'jsonl' && formatB === 'jsonl';
|
|
39
|
+
const tableDiffs = computeTableDiffs({
|
|
40
|
+
pathA: resolvedA,
|
|
41
|
+
pathB: resolvedB,
|
|
42
|
+
manifestA,
|
|
43
|
+
manifestB,
|
|
44
|
+
recordLevel,
|
|
45
|
+
tableFilter: options.tableFilter,
|
|
46
|
+
maxIdsPerBucket: options.maxIdsPerBucket ?? 500,
|
|
47
|
+
});
|
|
48
|
+
const domainsA = new Set(manifestA.domains);
|
|
49
|
+
const domainsB = new Set(manifestB.domains);
|
|
50
|
+
const domainsOnlyInA = manifestA.domains.filter((d) => !domainsB.has(d));
|
|
51
|
+
const domainsOnlyInB = manifestB.domains.filter((d) => !domainsA.has(d));
|
|
52
|
+
const checksumMatch = manifestA.checksum === manifestB.checksum;
|
|
53
|
+
const versionMatch = manifestA.version === manifestB.version;
|
|
54
|
+
const identical = checksumMatch &&
|
|
55
|
+
versionMatch &&
|
|
56
|
+
tableDiffs.every((t) => t.delta === 0 &&
|
|
57
|
+
(t.added?.length ?? 0) === 0 &&
|
|
58
|
+
(t.removed?.length ?? 0) === 0 &&
|
|
59
|
+
(t.changed?.length ?? 0) === 0);
|
|
60
|
+
return {
|
|
61
|
+
pathA: resolvedA,
|
|
62
|
+
pathB: resolvedB,
|
|
63
|
+
formatA,
|
|
64
|
+
formatB,
|
|
65
|
+
manifestA,
|
|
66
|
+
manifestB,
|
|
67
|
+
checksumMatch,
|
|
68
|
+
versionMatch,
|
|
69
|
+
identical,
|
|
70
|
+
recordLevel,
|
|
71
|
+
tableDiffs,
|
|
72
|
+
domainsOnlyInA,
|
|
73
|
+
domainsOnlyInB,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
// ============================================================================
|
|
77
|
+
// Format detection + manifest reading
|
|
78
|
+
// ============================================================================
|
|
79
|
+
function detectFormat(path) {
|
|
80
|
+
if (!existsSync(path)) {
|
|
81
|
+
throw new Error(`Path not found: ${path}`);
|
|
82
|
+
}
|
|
83
|
+
if (path.endsWith('.rvf'))
|
|
84
|
+
return 'rvf';
|
|
85
|
+
const s = statSync(path);
|
|
86
|
+
if (s.isFile()) {
|
|
87
|
+
// Any single file that isn't .rvf is treated as an error — JSONL exports
|
|
88
|
+
// are directories.
|
|
89
|
+
throw new Error(`Unsupported brain export: ${path} (expected a .rvf file or a JSONL directory)`);
|
|
90
|
+
}
|
|
91
|
+
// Directory: assume JSONL
|
|
92
|
+
return 'jsonl';
|
|
93
|
+
}
|
|
94
|
+
function readManifestSummary(path, format) {
|
|
95
|
+
if (format === 'rvf') {
|
|
96
|
+
return readRvfManifestSummary(path);
|
|
97
|
+
}
|
|
98
|
+
return readJsonlManifestSummary(path);
|
|
99
|
+
}
|
|
100
|
+
function readJsonlManifestSummary(dir) {
|
|
101
|
+
const manifestPath = join(dir, 'manifest.json');
|
|
102
|
+
if (!existsSync(manifestPath)) {
|
|
103
|
+
throw new Error(`Manifest not found at ${manifestPath}`);
|
|
104
|
+
}
|
|
105
|
+
const raw = safeJsonParse(readFileSync(manifestPath, 'utf-8'));
|
|
106
|
+
return toManifestSummary(raw, 'jsonl');
|
|
107
|
+
}
|
|
108
|
+
function readRvfManifestSummary(rvfPath) {
|
|
109
|
+
// Delegate to the RVF exporter's info path so we honour its format handling.
|
|
110
|
+
const raw = brainInfoFromRvf(rvfPath);
|
|
111
|
+
return toManifestSummary(raw, 'rvf');
|
|
112
|
+
}
|
|
113
|
+
function toManifestSummary(raw, format) {
|
|
114
|
+
return {
|
|
115
|
+
format,
|
|
116
|
+
version: raw.version ?? 'unknown',
|
|
117
|
+
exportedAt: raw.exportedAt ?? 'unknown',
|
|
118
|
+
sourceDb: raw.sourceDb ?? 'unknown',
|
|
119
|
+
checksum: raw.checksum ?? '',
|
|
120
|
+
totalRecords: raw.stats?.totalRecords ?? 0,
|
|
121
|
+
domains: raw.domains ?? [],
|
|
122
|
+
tableRecordCounts: raw.tableRecordCounts ?? {},
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
function computeTableDiffs(input) {
|
|
126
|
+
const configs = input.tableFilter
|
|
127
|
+
? TABLE_CONFIGS.filter((c) => c.tableName === input.tableFilter)
|
|
128
|
+
: TABLE_CONFIGS;
|
|
129
|
+
if (input.tableFilter && configs.length === 0) {
|
|
130
|
+
throw new Error(`Unknown table: ${input.tableFilter}`);
|
|
131
|
+
}
|
|
132
|
+
const diffs = [];
|
|
133
|
+
for (const config of configs) {
|
|
134
|
+
const countA = input.manifestA.tableRecordCounts[config.tableName] ?? 0;
|
|
135
|
+
const countB = input.manifestB.tableRecordCounts[config.tableName] ?? 0;
|
|
136
|
+
const delta = countB - countA;
|
|
137
|
+
let added;
|
|
138
|
+
let removed;
|
|
139
|
+
let changed;
|
|
140
|
+
if (input.recordLevel && hasIdentity(config)) {
|
|
141
|
+
const recordDiff = recordLevelDiff(join(input.pathA, config.fileName), join(input.pathB, config.fileName), config, input.maxIdsPerBucket);
|
|
142
|
+
added = recordDiff.added;
|
|
143
|
+
removed = recordDiff.removed;
|
|
144
|
+
changed = recordDiff.changed;
|
|
145
|
+
}
|
|
146
|
+
diffs.push({
|
|
147
|
+
tableName: config.tableName,
|
|
148
|
+
countA,
|
|
149
|
+
countB,
|
|
150
|
+
delta,
|
|
151
|
+
...(added !== undefined ? { added } : {}),
|
|
152
|
+
...(removed !== undefined ? { removed } : {}),
|
|
153
|
+
...(changed !== undefined ? { changed } : {}),
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
return diffs;
|
|
157
|
+
}
|
|
158
|
+
function hasIdentity(_config) {
|
|
159
|
+
// PK tables always have identity; append-only tables can be deduped via
|
|
160
|
+
// their dedup columns, which is good enough to compute added/removed.
|
|
161
|
+
return true;
|
|
162
|
+
}
|
|
163
|
+
function pkFor(config) {
|
|
164
|
+
if (config.dedupColumns && config.dedupColumns.length > 0) {
|
|
165
|
+
// Composite identity — joined with a separator unlikely to occur in values.
|
|
166
|
+
return config.dedupColumns.join('');
|
|
167
|
+
}
|
|
168
|
+
return PK_COLUMNS[config.tableName] ?? 'id';
|
|
169
|
+
}
|
|
170
|
+
function recordLevelDiff(fileA, fileB, config, maxIdsPerBucket) {
|
|
171
|
+
const mapA = buildIdentityMap(fileA, config);
|
|
172
|
+
const mapB = buildIdentityMap(fileB, config);
|
|
173
|
+
const added = [];
|
|
174
|
+
const removed = [];
|
|
175
|
+
const changed = [];
|
|
176
|
+
// In A but not in B → removed.
|
|
177
|
+
for (const [id, hashA] of mapA) {
|
|
178
|
+
const hashB = mapB.get(id);
|
|
179
|
+
if (hashB === undefined) {
|
|
180
|
+
if (removed.length < maxIdsPerBucket)
|
|
181
|
+
removed.push(id);
|
|
182
|
+
}
|
|
183
|
+
else if (hashB !== hashA) {
|
|
184
|
+
// Append-only tables use dedup columns as identity, so if the identity
|
|
185
|
+
// matches the record IS the same — guard via dedup flag.
|
|
186
|
+
if (config.dedupColumns && config.dedupColumns.length > 0)
|
|
187
|
+
continue;
|
|
188
|
+
if (changed.length < maxIdsPerBucket)
|
|
189
|
+
changed.push(id);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
// In B but not in A → added.
|
|
193
|
+
for (const id of mapB.keys()) {
|
|
194
|
+
if (!mapA.has(id)) {
|
|
195
|
+
if (added.length < maxIdsPerBucket)
|
|
196
|
+
added.push(id);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
added.sort();
|
|
200
|
+
removed.sort();
|
|
201
|
+
changed.sort();
|
|
202
|
+
return { added, removed, changed };
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Read a JSONL file and build a Map<identity, contentHash>.
|
|
206
|
+
*
|
|
207
|
+
* For PK tables the identity is the PK column value. For append-only tables
|
|
208
|
+
* the identity is a concatenation of the dedup columns (collisions are
|
|
209
|
+
* treated as "same record").
|
|
210
|
+
*/
|
|
211
|
+
function buildIdentityMap(filePath, config) {
|
|
212
|
+
const map = new Map();
|
|
213
|
+
if (!existsSync(filePath))
|
|
214
|
+
return map;
|
|
215
|
+
const rows = readJsonl(filePath, safeJsonParse);
|
|
216
|
+
for (const row of rows) {
|
|
217
|
+
const id = identityOf(row, config);
|
|
218
|
+
if (id === undefined)
|
|
219
|
+
continue;
|
|
220
|
+
// Stable content hash: JSON-stringify with sorted keys.
|
|
221
|
+
const content = stableStringify(row);
|
|
222
|
+
map.set(id, sha256Hex(content));
|
|
223
|
+
}
|
|
224
|
+
return map;
|
|
225
|
+
}
|
|
226
|
+
function identityOf(row, config) {
|
|
227
|
+
if (config.dedupColumns && config.dedupColumns.length > 0) {
|
|
228
|
+
const parts = [];
|
|
229
|
+
for (const col of config.dedupColumns) {
|
|
230
|
+
const v = row[col];
|
|
231
|
+
if (v === undefined || v === null)
|
|
232
|
+
return undefined;
|
|
233
|
+
parts.push(String(v));
|
|
234
|
+
}
|
|
235
|
+
return parts.join('');
|
|
236
|
+
}
|
|
237
|
+
const pk = PK_COLUMNS[config.tableName] ?? 'id';
|
|
238
|
+
const v = row[pk];
|
|
239
|
+
if (v === undefined || v === null)
|
|
240
|
+
return undefined;
|
|
241
|
+
return String(v);
|
|
242
|
+
}
|
|
243
|
+
function stableStringify(obj) {
|
|
244
|
+
const keys = Object.keys(obj).sort();
|
|
245
|
+
const ordered = {};
|
|
246
|
+
for (const k of keys)
|
|
247
|
+
ordered[k] = obj[k];
|
|
248
|
+
return JSON.stringify(ordered);
|
|
249
|
+
}
|
|
250
|
+
function sha256Hex(s) {
|
|
251
|
+
// sha256() from brain-shared operates on utf-8 strings; both paths yield the
|
|
252
|
+
// same hash for the same input. Kept as a thin wrapper for readability.
|
|
253
|
+
return sha256(s);
|
|
254
|
+
}
|
|
255
|
+
export function summarizeDiff(result) {
|
|
256
|
+
let tablesChanged = 0;
|
|
257
|
+
let totalAdded = 0;
|
|
258
|
+
let totalRemoved = 0;
|
|
259
|
+
let totalChanged = 0;
|
|
260
|
+
for (const t of result.tableDiffs) {
|
|
261
|
+
const hasChange = t.delta !== 0 ||
|
|
262
|
+
(t.added && t.added.length > 0) ||
|
|
263
|
+
(t.removed && t.removed.length > 0) ||
|
|
264
|
+
(t.changed && t.changed.length > 0);
|
|
265
|
+
if (hasChange)
|
|
266
|
+
tablesChanged++;
|
|
267
|
+
totalAdded += t.added?.length ?? 0;
|
|
268
|
+
totalRemoved += t.removed?.length ?? 0;
|
|
269
|
+
totalChanged += t.changed?.length ?? 0;
|
|
270
|
+
}
|
|
271
|
+
return {
|
|
272
|
+
tablesChanged,
|
|
273
|
+
totalAdded,
|
|
274
|
+
totalRemoved,
|
|
275
|
+
totalChanged,
|
|
276
|
+
recordCountDelta: result.manifestB.totalRecords - result.manifestA.totalRecords,
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
// Export internal helpers for test access without widening the public API.
|
|
280
|
+
export const __test__ = { stableStringify, identityOf, buildIdentityMap, pkFor };
|
|
281
|
+
//# sourceMappingURL=brain-diff.js.map
|