@remnic/core 1.1.12 → 1.1.14
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/dist/access-cli.d.ts +2 -1
- package/dist/access-cli.js +263 -82
- package/dist/access-cli.js.map +1 -1
- package/dist/access-http.d.ts +26 -60
- package/dist/access-http.js +43 -29
- package/dist/access-mcp.d.ts +24 -6
- package/dist/access-mcp.js +35 -28
- package/dist/access-schema.d.ts +9 -6
- package/dist/access-schema.js +7 -5
- package/dist/access-service-DcCDmNYC.d.ts +1542 -0
- package/dist/access-service.d.ts +25 -7
- package/dist/access-service.js +33 -26
- package/dist/active-memory-bridge.js +2 -2
- package/dist/active-recall.js +11 -3
- package/dist/active-recall.js.map +1 -1
- package/dist/adapters/claude-code.d.ts +24 -0
- package/dist/adapters/claude-code.js +9 -0
- package/dist/adapters/codex.d.ts +25 -0
- package/dist/adapters/codex.js +9 -0
- package/dist/adapters/hermes.d.ts +35 -0
- package/dist/adapters/hermes.js +9 -0
- package/dist/adapters/index.d.ts +6 -0
- package/dist/adapters/index.js +26 -0
- package/dist/adapters/registry.d.ts +20 -0
- package/dist/adapters/registry.js +13 -0
- package/dist/adapters/replit.d.ts +28 -0
- package/dist/adapters/replit.js +9 -0
- package/dist/adapters/types.d.ts +43 -0
- package/dist/adapters/types.js +8 -0
- package/dist/bootstrap.d.ts +20 -5
- package/dist/boxes.d.ts +7 -0
- package/dist/boxes.js +1 -1
- package/dist/briefing.d.ts +5 -3
- package/dist/briefing.js +9 -6
- package/dist/buffer-surprise-report.js +1 -1
- package/dist/buffer.d.ts +18 -4
- package/dist/buffer.js +1 -1
- package/dist/calibration.js +4 -4
- package/dist/capsule-cli.d.ts +4 -4
- package/dist/capsule-cli.js +1 -1
- package/dist/capsule-crypto-5CYAGVC5.js +18 -0
- package/dist/capsule-merge-4MGKE7C5.js +189 -0
- package/dist/causal-behavior.d.ts +8 -28
- package/dist/causal-behavior.js +6 -3
- package/dist/causal-behavior.js.map +1 -1
- package/dist/causal-chain.js +3 -2
- package/dist/causal-consolidation.d.ts +1 -1
- package/dist/causal-consolidation.js +24 -13
- package/dist/causal-consolidation.js.map +1 -1
- package/dist/causal-retrieval.js +3 -3
- package/dist/causal-trajectory.js +1 -1
- package/dist/chunk-25MQ7IHJ.js +427 -0
- package/dist/chunk-25MQ7IHJ.js.map +1 -0
- package/dist/chunk-2F2W355T.js +256 -0
- package/dist/chunk-2F2W355T.js.map +1 -0
- package/dist/chunk-2KI4QFHU.js +228 -0
- package/dist/chunk-2KI4QFHU.js.map +1 -0
- package/dist/chunk-2PRQG7PV.js +86 -0
- package/dist/chunk-2PRQG7PV.js.map +1 -0
- package/dist/chunk-2QR3XXIC.js +2272 -0
- package/dist/chunk-2QR3XXIC.js.map +1 -0
- package/dist/chunk-2WWLHTZY.js +121 -0
- package/dist/chunk-326G7DJK.js +2185 -0
- package/dist/chunk-326G7DJK.js.map +1 -0
- package/dist/chunk-34DQE4KF.js +174 -0
- package/dist/chunk-34DQE4KF.js.map +1 -0
- package/dist/chunk-3APJ5EVB.js +601 -0
- package/dist/chunk-3APJ5EVB.js.map +1 -0
- package/dist/chunk-3HPAPHUK.js +51 -0
- package/dist/chunk-3HPAPHUK.js.map +1 -0
- package/dist/chunk-3JXBXXM2.js +69 -0
- package/dist/chunk-3JXBXXM2.js.map +1 -0
- package/dist/chunk-3KW65B36.js +681 -0
- package/dist/chunk-3KW65B36.js.map +1 -0
- package/dist/chunk-3UXOZBHV.js +20 -0
- package/dist/chunk-3UXOZBHV.js.map +1 -0
- package/dist/chunk-3VAL7ZL2.js +266 -0
- package/dist/chunk-3VAL7ZL2.js.map +1 -0
- package/dist/chunk-3Y4P7RXM.js +31 -0
- package/dist/chunk-3Y4P7RXM.js.map +1 -0
- package/dist/chunk-47VWKCAF.js +273 -0
- package/dist/chunk-47VWKCAF.js.map +1 -0
- package/dist/chunk-4CRG46BG.js +271 -0
- package/dist/chunk-5375UYTQ.js +914 -0
- package/dist/chunk-5375UYTQ.js.map +1 -0
- package/dist/chunk-56K5QLHX.js +506 -0
- package/dist/chunk-56K5QLHX.js.map +1 -0
- package/dist/chunk-5RGLBDQF.js +596 -0
- package/dist/chunk-5RGLBDQF.js.map +1 -0
- package/dist/chunk-5UZXUTVO.js +9 -0
- package/dist/chunk-5UZXUTVO.js.map +1 -0
- package/dist/chunk-65PG43EQ.js +105 -0
- package/dist/chunk-65PG43EQ.js.map +1 -0
- package/dist/chunk-66DHUKLO.js +57 -0
- package/dist/chunk-66DHUKLO.js.map +1 -0
- package/dist/chunk-6FC5EGNV.js +46 -0
- package/dist/chunk-6FC5EGNV.js.map +1 -0
- package/dist/chunk-6H2TESSP.js +62 -0
- package/dist/chunk-6H2TESSP.js.map +1 -0
- package/dist/chunk-6LVVDPJ4.js +32 -0
- package/dist/chunk-6LVVDPJ4.js.map +1 -0
- package/dist/chunk-6RVI47ZR.js +159 -0
- package/dist/chunk-6RVI47ZR.js.map +1 -0
- package/dist/chunk-7AAT6G4Q.js +5117 -0
- package/dist/chunk-7AAT6G4Q.js.map +1 -0
- package/dist/chunk-7DTASS5T.js +29 -0
- package/dist/chunk-7DTASS5T.js.map +1 -0
- package/dist/chunk-7IASACLB.js +596 -0
- package/dist/chunk-7MNMYOFP.js +32 -0
- package/dist/chunk-7MNMYOFP.js.map +1 -0
- package/dist/chunk-7N4KAIGN.js +133 -0
- package/dist/chunk-7N4KAIGN.js.map +1 -0
- package/dist/chunk-7OZ53EXP.js +101 -0
- package/dist/chunk-7OZ53EXP.js.map +1 -0
- package/dist/chunk-7XYTQGCC.js +134 -0
- package/dist/chunk-7XYTQGCC.js.map +1 -0
- package/dist/chunk-A2XUIMJ3.js +341 -0
- package/dist/chunk-A2XUIMJ3.js.map +1 -0
- package/dist/chunk-AGZQD76C.js +201 -0
- package/dist/chunk-AGZQD76C.js.map +1 -0
- package/dist/chunk-APO3DCMU.js +361 -0
- package/dist/chunk-APO3DCMU.js.map +1 -0
- package/dist/chunk-BFBF3XEF.js +283 -0
- package/dist/chunk-BFBF3XEF.js.map +1 -0
- package/dist/chunk-BJ3KMYTB.js +1974 -0
- package/dist/chunk-BJ3KMYTB.js.map +1 -0
- package/dist/chunk-CHEL3SKB.js +6758 -0
- package/dist/chunk-CHEL3SKB.js.map +1 -0
- package/dist/chunk-CQZRLNMV.js +1491 -0
- package/dist/chunk-CQZRLNMV.js.map +1 -0
- package/dist/chunk-D46YSIYX.js +892 -0
- package/dist/chunk-D46YSIYX.js.map +1 -0
- package/dist/chunk-DINWEURR.js +648 -0
- package/dist/chunk-DINWEURR.js.map +1 -0
- package/dist/chunk-DK5LDEQM.js +530 -0
- package/dist/chunk-DK5LDEQM.js.map +1 -0
- package/dist/chunk-DOM4GKSW.js +34 -0
- package/dist/chunk-DOM4GKSW.js.map +1 -0
- package/dist/chunk-EDTHC6UD.js +1075 -0
- package/dist/chunk-EFJ3MQ4V.js +721 -0
- package/dist/chunk-EHRTFRWW.js +89 -0
- package/dist/chunk-EHRTFRWW.js.map +1 -0
- package/dist/chunk-FAJ7FZYM.js +11 -0
- package/dist/chunk-FAJ7FZYM.js.map +1 -0
- package/dist/chunk-FBYESMQ2.js +570 -0
- package/dist/chunk-FDU6HUUL.js +147 -0
- package/dist/chunk-FF4KLI5W.js +99 -0
- package/dist/chunk-FF4KLI5W.js.map +1 -0
- package/dist/chunk-FIT6DMX6.js +310 -0
- package/dist/chunk-FIT6DMX6.js.map +1 -0
- package/dist/chunk-FJ43PRLT.js +272 -0
- package/dist/chunk-FJ43PRLT.js.map +1 -0
- package/dist/chunk-FKFMOY3N.js +32 -0
- package/dist/chunk-FKFMOY3N.js.map +1 -0
- package/dist/chunk-FLTNHQK6.js +262 -0
- package/dist/chunk-FLTNHQK6.js.map +1 -0
- package/dist/chunk-GA454ALV.js +12436 -0
- package/dist/chunk-GA454ALV.js.map +1 -0
- package/dist/chunk-GGKRUQOO.js +228 -0
- package/dist/chunk-GIF42EW3.js +63 -0
- package/dist/chunk-GIF42EW3.js.map +1 -0
- package/dist/chunk-GL6I6MEQ.js +647 -0
- package/dist/chunk-H3ME6L6D.js +709 -0
- package/dist/chunk-H3ME6L6D.js.map +1 -0
- package/dist/chunk-HHLLAQGZ.js +1 -0
- package/dist/chunk-HXXBL2KD.js +2040 -0
- package/dist/chunk-I5V2VDIW.js +219 -0
- package/dist/chunk-I5V2VDIW.js.map +1 -0
- package/dist/chunk-I6K5FBRQ.js +35 -0
- package/dist/chunk-I6K5FBRQ.js.map +1 -0
- package/dist/chunk-ICRIXAP2.js +121 -0
- package/dist/chunk-ICRIXAP2.js.map +1 -0
- package/dist/chunk-J4EB7DNW.js +11 -0
- package/dist/chunk-J4EB7DNW.js.map +1 -0
- package/dist/chunk-JLFA7DQG.js +62 -0
- package/dist/chunk-JLFA7DQG.js.map +1 -0
- package/dist/chunk-KJTKLXTH.js +9 -0
- package/dist/chunk-KJTKLXTH.js.map +1 -0
- package/dist/chunk-KLAO5DGL.js +917 -0
- package/dist/chunk-KLAO5DGL.js.map +1 -0
- package/dist/chunk-KNKUID7G.js +183 -0
- package/dist/chunk-KOSORCJG.js +624 -0
- package/dist/chunk-KOSORCJG.js.map +1 -0
- package/dist/chunk-KUJVMMZQ.js +1262 -0
- package/dist/chunk-KUJVMMZQ.js.map +1 -0
- package/dist/chunk-LCR46JY5.js +123 -0
- package/dist/chunk-LCR46JY5.js.map +1 -0
- package/dist/chunk-LLQ2LLWF.js +148 -0
- package/dist/chunk-LLQ2LLWF.js.map +1 -0
- package/dist/chunk-LPMVBPA3.js +236 -0
- package/dist/chunk-LT3NLYSI.js +50 -0
- package/dist/chunk-LT3NLYSI.js.map +1 -0
- package/dist/chunk-LUDTDZLK.js +287 -0
- package/dist/chunk-LUDTDZLK.js.map +1 -0
- package/dist/chunk-M23FSH32.js +3963 -0
- package/dist/chunk-M23FSH32.js.map +1 -0
- package/dist/chunk-MC26UJIM.js +118 -0
- package/dist/chunk-ME6ESPZU.js +119 -0
- package/dist/chunk-ME6ESPZU.js.map +1 -0
- package/dist/chunk-MGKYQQYF.js +272 -0
- package/dist/chunk-MJFNCJXV.js +66 -0
- package/dist/chunk-MJFNCJXV.js.map +1 -0
- package/dist/chunk-MSWG7JI6.js +237 -0
- package/dist/chunk-MSWG7JI6.js.map +1 -0
- package/dist/chunk-MT25YHYH.js +141 -0
- package/dist/chunk-MT25YHYH.js.map +1 -0
- package/dist/chunk-MT4HVDUZ.js +53 -0
- package/dist/chunk-MY6TPVXW.js +219 -0
- package/dist/chunk-N2D6GXBM.js +267 -0
- package/dist/chunk-N2D6GXBM.js.map +1 -0
- package/dist/chunk-NJ3MJQZX.js +46 -0
- package/dist/chunk-NJ3MJQZX.js.map +1 -0
- package/dist/chunk-NMZY542O.js +335 -0
- package/dist/chunk-NMZY542O.js.map +1 -0
- package/dist/chunk-NNVTUXEB.js +23 -0
- package/dist/chunk-NZL6GGQE.js +375 -0
- package/dist/chunk-NZL6GGQE.js.map +1 -0
- package/dist/chunk-P4NEIHUT.js +108 -0
- package/dist/chunk-P7FMDTKL.js +103 -0
- package/dist/chunk-P7FMDTKL.js.map +1 -0
- package/dist/chunk-PHK3HARR.js +32 -0
- package/dist/chunk-PHK3HARR.js.map +1 -0
- package/dist/chunk-PIRJPV5T.js +98 -0
- package/dist/chunk-PIRJPV5T.js.map +1 -0
- package/dist/chunk-PK7H5L6Y.js +159 -0
- package/dist/chunk-PK7H5L6Y.js.map +1 -0
- package/dist/chunk-PR5FBTFU.js +233 -0
- package/dist/chunk-PR5FBTFU.js.map +1 -0
- package/dist/chunk-PU63GXWS.js +174 -0
- package/dist/chunk-PU63GXWS.js.map +1 -0
- package/dist/chunk-PZIAX57I.js +124 -0
- package/dist/chunk-PZIAX57I.js.map +1 -0
- package/dist/chunk-Q7P4WJDP.js +26 -0
- package/dist/chunk-Q7P4WJDP.js.map +1 -0
- package/dist/chunk-QQUAB63I.js +63 -0
- package/dist/chunk-QQUAB63I.js.map +1 -0
- package/dist/chunk-QRNI5JBH.js +18 -0
- package/dist/chunk-RHY3HH7P.js +601 -0
- package/dist/chunk-RHY3HH7P.js.map +1 -0
- package/dist/chunk-RRF5UOBJ.js +91 -0
- package/dist/chunk-RXDLTSWT.js +124 -0
- package/dist/chunk-RXDLTSWT.js.map +1 -0
- package/dist/chunk-RYED3SPJ.js +42 -0
- package/dist/chunk-RYED3SPJ.js.map +1 -0
- package/dist/chunk-S7KDBTWT.js +106 -0
- package/dist/chunk-S7KDBTWT.js.map +1 -0
- package/dist/chunk-SEDEKFYQ.js +1 -0
- package/dist/chunk-TECVW3JP.js +36 -0
- package/dist/chunk-TECVW3JP.js.map +1 -0
- package/dist/chunk-TFO23QT4.js +88 -0
- package/dist/chunk-TFO23QT4.js.map +1 -0
- package/dist/chunk-TK4UEOSK.js +76 -0
- package/dist/chunk-TK4UEOSK.js.map +1 -0
- package/dist/chunk-TKWGAOLV.js +122 -0
- package/dist/chunk-TKWGAOLV.js.map +1 -0
- package/dist/chunk-TMM4S4IJ.js +597 -0
- package/dist/chunk-TMM4S4IJ.js.map +1 -0
- package/dist/chunk-TMQLARTH.js +188 -0
- package/dist/chunk-TMQLARTH.js.map +1 -0
- package/dist/chunk-TPDBFYEG.js +130 -0
- package/dist/chunk-TPDBFYEG.js.map +1 -0
- package/dist/chunk-TPMQ3G6Z.js +145 -0
- package/dist/chunk-TPMQ3G6Z.js.map +1 -0
- package/dist/chunk-TZOLIGIG.js +61 -0
- package/dist/chunk-TZOLIGIG.js.map +1 -0
- package/dist/chunk-U3PN77QT.js +113 -0
- package/dist/chunk-U3WSW6PZ.js +277 -0
- package/dist/chunk-U4SCL7B7.js +640 -0
- package/dist/chunk-U4SCL7B7.js.map +1 -0
- package/dist/chunk-UWK5OXUJ.js +156 -0
- package/dist/chunk-UWK5OXUJ.js.map +1 -0
- package/dist/chunk-UWVJF25J.js +74 -0
- package/dist/chunk-UXHQAFNA.js +1317 -0
- package/dist/chunk-UXHQAFNA.js.map +1 -0
- package/dist/chunk-V5OCT34X.js +1 -0
- package/dist/chunk-VLXA6PI2.js +304 -0
- package/dist/chunk-VLXA6PI2.js.map +1 -0
- package/dist/chunk-VNO6ZJ35.js +500 -0
- package/dist/chunk-VNO6ZJ35.js.map +1 -0
- package/dist/chunk-VW676BEI.js +827 -0
- package/dist/chunk-VW676BEI.js.map +1 -0
- package/dist/chunk-W3LR522O.js +2296 -0
- package/dist/chunk-W4L6CZKA.js +96 -0
- package/dist/chunk-W4L6CZKA.js.map +1 -0
- package/dist/chunk-W4RVMTHR.js +372 -0
- package/dist/chunk-W4RVMTHR.js.map +1 -0
- package/dist/chunk-WEHSQBFR.js +188 -0
- package/dist/chunk-WEHSQBFR.js.map +1 -0
- package/dist/chunk-WELDCG6C.js +380 -0
- package/dist/chunk-WELDCG6C.js.map +1 -0
- package/dist/chunk-WZYKANL3.js +2800 -0
- package/dist/chunk-WZYKANL3.js.map +1 -0
- package/dist/chunk-XIG5PDM7.js +48 -0
- package/dist/chunk-XJNBEDFE.js +193 -0
- package/dist/chunk-XJNBEDFE.js.map +1 -0
- package/dist/chunk-XVVIG67A.js +291 -0
- package/dist/chunk-XVVIG67A.js.map +1 -0
- package/dist/chunk-XVZ7B3HG.js +135 -0
- package/dist/chunk-YBPYIAA5.js +73 -0
- package/dist/chunk-YBPYIAA5.js.map +1 -0
- package/dist/chunk-Z734BLO3.js +21 -0
- package/dist/chunk-Z734BLO3.js.map +1 -0
- package/dist/chunk-ZKSK55RC.js +269 -0
- package/dist/chunk-ZKSK55RC.js.map +1 -0
- package/dist/chunk-ZTFCYYEZ.js +69 -0
- package/dist/chunk-ZTFCYYEZ.js.map +1 -0
- package/dist/chunk-ZY2MNJR6.js +329 -0
- package/dist/chunk-ZY2MNJR6.js.map +1 -0
- package/dist/cli-D3VpkVwB.d.ts +1136 -0
- package/dist/cli.d.ts +39 -10
- package/dist/cli.js +108 -49
- package/dist/commitment-ledger.js +1 -1
- package/dist/compat/checks.d.ts +5 -0
- package/dist/compat/checks.js +11 -0
- package/dist/compat/checks.js.map +1 -0
- package/dist/compat/types.d.ts +30 -0
- package/dist/compat/types.js +1 -0
- package/dist/compat/types.js.map +1 -0
- package/dist/compounding/engine.d.ts +221 -0
- package/dist/compounding/engine.js +32 -0
- package/dist/compounding/engine.js.map +1 -0
- package/dist/compounding/preference-consolidator.d.ts +92 -0
- package/dist/compounding/preference-consolidator.js +553 -0
- package/dist/compounding/preference-consolidator.js.map +1 -0
- package/dist/config.d.ts +4 -2
- package/dist/config.js +9 -4
- package/dist/conflict-policy-DyJ2wd-h.d.ts +4 -0
- package/dist/connectors/codex-materialize-runner.d.ts +64 -0
- package/dist/connectors/codex-materialize-runner.js +33 -0
- package/dist/connectors/codex-materialize-runner.js.map +1 -0
- package/dist/connectors/codex-materialize.d.ts +195 -0
- package/dist/connectors/codex-materialize.js +38 -0
- package/dist/connectors/codex-materialize.js.map +1 -0
- package/dist/connectors/index.d.ts +444 -0
- package/dist/connectors/index.js +115 -0
- package/dist/connectors/index.js.map +1 -0
- package/dist/connectors-cli-CwbyjGR7.d.ts +257 -0
- package/dist/connectors-cli.d.ts +1 -1
- package/dist/consolidation-provenance-check.d.ts +3 -1
- package/dist/consolidation-undo.d.ts +3 -1
- package/dist/contradiction/index.d.ts +258 -0
- package/dist/contradiction/index.js +43 -0
- package/dist/contradiction/index.js.map +1 -0
- package/dist/contradiction-review-ATP4S6IC.js +30 -0
- package/dist/contradiction-review-ATP4S6IC.js.map +1 -0
- package/dist/contradiction-scan-5A4IDZV5.js +13 -0
- package/dist/contradiction-scan-5A4IDZV5.js.map +1 -0
- package/dist/conversation-index/backend.d.ts +97 -0
- package/dist/conversation-index/backend.js +13 -0
- package/dist/conversation-index/backend.js.map +1 -0
- package/dist/conversation-index/chunker.d.ts +16 -0
- package/dist/conversation-index/chunker.js +8 -0
- package/dist/conversation-index/chunker.js.map +1 -0
- package/dist/conversation-index/cleanup.d.ts +11 -0
- package/dist/conversation-index/cleanup.js +9 -0
- package/dist/conversation-index/cleanup.js.map +1 -0
- package/dist/conversation-index/faiss-adapter.d.ts +6 -0
- package/dist/conversation-index/faiss-adapter.js +16 -0
- package/dist/conversation-index/faiss-adapter.js.map +1 -0
- package/dist/conversation-index/indexer.d.ts +23 -0
- package/dist/conversation-index/indexer.js +15 -0
- package/dist/conversation-index/indexer.js.map +1 -0
- package/dist/conversation-index/search.d.ts +6 -0
- package/dist/conversation-index/search.js +11 -0
- package/dist/conversation-index/search.js.map +1 -0
- package/dist/embedding-fallback.js +2 -2
- package/dist/enrichment/index.d.ts +163 -0
- package/dist/enrichment/index.js +18 -0
- package/dist/enrichment/index.js.map +1 -0
- package/dist/entity-retrieval.d.ts +4 -2
- package/dist/entity-retrieval.js +8 -5
- package/dist/evals.js +1 -1
- package/dist/explicit-capture.d.ts +20 -5
- package/dist/explicit-capture.js +2 -2
- package/dist/extraction-judge-training.js +1 -1
- package/dist/extraction.js +8 -8
- package/dist/faiss-adapter-CzPghc4C.d.ts +70 -0
- package/dist/fallback-llm.d.ts +2 -0
- package/dist/fallback-llm.js +4 -4
- package/dist/graph-edge-decay-5DI5GUNL.js +207 -0
- package/dist/index.d.ts +66 -711
- package/dist/index.js +556 -2680
- package/dist/index.js.map +1 -1
- package/dist/lcm/archive.d.ts +89 -0
- package/dist/lcm/archive.js +12 -0
- package/dist/lcm/archive.js.map +1 -0
- package/dist/lcm/dag.d.ts +48 -0
- package/dist/lcm/dag.js +8 -0
- package/dist/lcm/dag.js.map +1 -0
- package/dist/lcm/engine.d.ts +116 -0
- package/dist/lcm/engine.js +20 -0
- package/dist/lcm/engine.js.map +1 -0
- package/dist/lcm/index.d.ts +12 -0
- package/dist/lcm/index.js +44 -0
- package/dist/lcm/index.js.map +1 -0
- package/dist/lcm/queue.d.ts +62 -0
- package/dist/lcm/queue.js +8 -0
- package/dist/lcm/queue.js.map +1 -0
- package/dist/lcm/recall.d.ts +20 -0
- package/dist/lcm/recall.js +8 -0
- package/dist/lcm/recall.js.map +1 -0
- package/dist/lcm/schema.d.ts +16 -0
- package/dist/lcm/schema.js +14 -0
- package/dist/lcm/schema.js.map +1 -0
- package/dist/lcm/summarizer.d.ts +38 -0
- package/dist/lcm/summarizer.js +12 -0
- package/dist/lcm/summarizer.js.map +1 -0
- package/dist/lcm/tools.d.ts +29 -0
- package/dist/lcm/tools.js +8 -0
- package/dist/lcm/tools.js.map +1 -0
- package/dist/live-connectors-runner.js +5 -5
- package/dist/local-llm.js +3 -3
- package/dist/maintenance/archive-observations.d.ts +18 -0
- package/dist/maintenance/archive-observations.js +8 -0
- package/dist/maintenance/archive-observations.js.map +1 -0
- package/dist/maintenance/backup-stamp.d.ts +3 -0
- package/dist/maintenance/backup-stamp.js +8 -0
- package/dist/maintenance/backup-stamp.js.map +1 -0
- package/dist/maintenance/memory-governance-cron.d.ts +85 -0
- package/dist/maintenance/memory-governance-cron.js +22 -0
- package/dist/maintenance/memory-governance-cron.js.map +1 -0
- package/dist/maintenance/memory-governance.d.ts +137 -0
- package/dist/maintenance/memory-governance.js +40 -0
- package/dist/maintenance/memory-governance.js.map +1 -0
- package/dist/maintenance/migrate-observations.d.ts +18 -0
- package/dist/maintenance/migrate-observations.js +9 -0
- package/dist/maintenance/migrate-observations.js.map +1 -0
- package/dist/maintenance/observation-ledger-utils.d.ts +10 -0
- package/dist/maintenance/observation-ledger-utils.js +10 -0
- package/dist/maintenance/observation-ledger-utils.js.map +1 -0
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +15 -0
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +28 -0
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js.map +1 -0
- package/dist/maintenance/rebuild-memory-projection.d.ts +77 -0
- package/dist/maintenance/rebuild-memory-projection.js +35 -0
- package/dist/maintenance/rebuild-memory-projection.js.map +1 -0
- package/dist/maintenance/rebuild-observations.d.ts +17 -0
- package/dist/maintenance/rebuild-observations.js +9 -0
- package/dist/maintenance/rebuild-observations.js.map +1 -0
- package/dist/mcp-memory-inspector-app.d.ts +24 -6
- package/dist/memory-projection-store.d.ts +108 -3
- package/dist/memory-projection-store.js +2 -1
- package/dist/memory-worth-outcomes.d.ts +4 -2
- package/dist/migrate/from-engram.d.ts +24 -0
- package/dist/migrate/from-engram.js +12 -0
- package/dist/migrate/from-engram.js.map +1 -0
- package/dist/namespaces/migrate.d.ts +50 -0
- package/dist/namespaces/migrate.js +50 -0
- package/dist/namespaces/migrate.js.map +1 -0
- package/dist/namespaces/principal.d.ts +17 -0
- package/dist/namespaces/principal.js +16 -0
- package/dist/namespaces/principal.js.map +1 -0
- package/dist/namespaces/search.d.ts +46 -0
- package/dist/namespaces/search.js +28 -0
- package/dist/namespaces/search.js.map +1 -0
- package/dist/namespaces/storage.d.ts +32 -0
- package/dist/namespaces/storage.js +28 -0
- package/dist/namespaces/storage.js.map +1 -0
- package/dist/network/tailscale.d.ts +41 -0
- package/dist/network/tailscale.js +9 -0
- package/dist/network/tailscale.js.map +1 -0
- package/dist/network/webdav.d.ts +39 -0
- package/dist/network/webdav.js +10 -0
- package/dist/network/webdav.js.map +1 -0
- package/dist/objective-state-writers.js +2 -2
- package/dist/operator-toolkit.d.ts +4 -2
- package/dist/operator-toolkit.js +32 -14
- package/dist/opik-exporter.js +2 -2
- package/dist/opik-exporter.js.map +1 -1
- package/dist/orchestrator-DuWl9Hwx.d.ts +1244 -0
- package/dist/orchestrator.d.ts +22 -7
- package/dist/orchestrator.js +79 -44
- package/dist/path-MR5JPYOP.js +9 -0
- package/dist/path-MR5JPYOP.js.map +1 -0
- package/dist/qmd-recall-cache.d.ts +1 -1
- package/dist/qmd.d.ts +102 -3
- package/dist/qmd.js +23 -5
- package/dist/recall-explain-renderer.js +3 -3
- package/dist/recall-xray-cli.js +4 -4
- package/dist/recall-xray-renderer.js +3 -3
- package/dist/recall-xray.js +2 -2
- package/dist/replay/normalizers/chatgpt.d.ts +6 -0
- package/dist/replay/normalizers/chatgpt.js +11 -0
- package/dist/replay/normalizers/chatgpt.js.map +1 -0
- package/dist/replay/normalizers/claude.d.ts +6 -0
- package/dist/replay/normalizers/claude.js +11 -0
- package/dist/replay/normalizers/claude.js.map +1 -0
- package/dist/replay/normalizers/openclaw.d.ts +6 -0
- package/dist/replay/normalizers/openclaw.js +11 -0
- package/dist/replay/normalizers/openclaw.js.map +1 -0
- package/dist/replay/normalizers/shared.d.ts +16 -0
- package/dist/replay/normalizers/shared.js +14 -0
- package/dist/replay/normalizers/shared.js.map +1 -0
- package/dist/replay/runner.d.ts +35 -0
- package/dist/replay/runner.js +16 -0
- package/dist/replay/runner.js.map +1 -0
- package/dist/replay/types.d.ts +57 -0
- package/dist/replay/types.js +19 -0
- package/dist/replay/types.js.map +1 -0
- package/dist/resolution-B7FNQSSP.js +12 -0
- package/dist/resolution-B7FNQSSP.js.map +1 -0
- package/dist/resolve-provider-secret.js +2 -2
- package/dist/resume-bundles.js +8 -6
- package/dist/retrieval-agents.d.ts +1 -1
- package/dist/routing/engine.d.ts +35 -0
- package/dist/routing/engine.js +16 -0
- package/dist/routing/engine.js.map +1 -0
- package/dist/routing/store.d.ts +27 -0
- package/dist/routing/store.js +10 -0
- package/dist/routing/store.js.map +1 -0
- package/dist/runtime/better-sqlite.d.ts +8 -0
- package/dist/runtime/better-sqlite.js +10 -0
- package/dist/runtime/better-sqlite.js.map +1 -0
- package/dist/runtime/child-process.d.ts +32 -0
- package/dist/runtime/child-process.js +10 -0
- package/dist/runtime/child-process.js.map +1 -0
- package/dist/runtime/env.d.ts +5 -0
- package/dist/runtime/env.js +12 -0
- package/dist/runtime/env.js.map +1 -0
- package/dist/schemas.d.ts +22 -22
- package/dist/sdk-compat.js +1 -1
- package/dist/search/document-scanner.d.ts +22 -0
- package/dist/search/document-scanner.js +8 -0
- package/dist/search/document-scanner.js.map +1 -0
- package/dist/search/embed-helper.d.ts +35 -0
- package/dist/search/embed-helper.js +9 -0
- package/dist/search/embed-helper.js.map +1 -0
- package/dist/search/factory.d.ts +32 -0
- package/dist/search/factory.js +29 -0
- package/dist/search/factory.js.map +1 -0
- package/dist/search/index.d.ts +15 -0
- package/dist/search/index.js +50 -0
- package/dist/search/index.js.map +1 -0
- package/dist/search/lancedb-backend.d.ts +51 -0
- package/dist/search/lancedb-backend.js +10 -0
- package/dist/search/lancedb-backend.js.map +1 -0
- package/dist/search/meilisearch-backend.d.ts +48 -0
- package/dist/search/meilisearch-backend.js +10 -0
- package/dist/search/meilisearch-backend.js.map +1 -0
- package/dist/search/noop-backend.d.ts +26 -0
- package/dist/search/noop-backend.js +8 -0
- package/dist/search/noop-backend.js.map +1 -0
- package/dist/search/orama-backend.d.ts +53 -0
- package/dist/search/orama-backend.js +10 -0
- package/dist/search/orama-backend.js.map +1 -0
- package/dist/search/port.d.ts +61 -0
- package/dist/search/port.js +1 -0
- package/dist/search/port.js.map +1 -0
- package/dist/search/remote-backend.d.ts +39 -0
- package/dist/search/remote-backend.js +9 -0
- package/dist/search/remote-backend.js.map +1 -0
- package/dist/secure-store/index.d.ts +890 -0
- package/dist/secure-store/index.js +156 -0
- package/dist/secure-store/index.js.map +1 -0
- package/dist/semantic-VwGI14Ok.d.ts +69 -0
- package/dist/semantic-consolidation-4HkHWgeI.d.ts +180 -0
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +13 -6
- package/dist/semantic-rule-promotion.js +8 -5
- package/dist/semantic-rule-verifier.js +8 -5
- package/dist/shared-context/manager.d.ts +131 -0
- package/dist/shared-context/manager.js +15 -0
- package/dist/shared-context/manager.js.map +1 -0
- package/dist/skills-registry.js +13 -1
- package/dist/skills-registry.js.map +1 -1
- package/dist/state-store-VZU2IA53.js +16 -0
- package/dist/state-store-VZU2IA53.js.map +1 -0
- package/dist/storage-paths.d.ts +9 -0
- package/dist/storage-paths.js +20 -0
- package/dist/storage-paths.js.map +1 -0
- package/dist/storage.d.ts +3 -1
- package/dist/storage.js +7 -4
- package/dist/summarizer.d.ts +5 -0
- package/dist/summarizer.js +9 -8
- package/dist/summary-snapshot.js +2 -1
- package/dist/surfaces/dreams.d.ts +16 -0
- package/dist/surfaces/dreams.js +282 -0
- package/dist/surfaces/dreams.js.map +1 -0
- package/dist/surfaces/heartbeat.d.ts +17 -0
- package/dist/surfaces/heartbeat.js +265 -0
- package/dist/surfaces/heartbeat.js.map +1 -0
- package/dist/temporal-supersession.d.ts +3 -1
- package/dist/threading.d.ts +5 -0
- package/dist/threading.js +2 -1
- package/dist/tier-migration.d.ts +4 -2
- package/dist/tokens.js +2 -2
- package/dist/transcript.d.ts +15 -1
- package/dist/transcript.js +2 -1
- package/dist/transfer/autodetect.d.ts +4 -0
- package/dist/transfer/autodetect.js +15 -0
- package/dist/transfer/autodetect.js.map +1 -0
- package/dist/transfer/backup.d.ts +21 -0
- package/dist/transfer/backup.js +17 -0
- package/dist/transfer/backup.js.map +1 -0
- package/dist/transfer/capsule-export.d.ts +113 -0
- package/dist/transfer/capsule-export.js +19 -0
- package/dist/transfer/capsule-export.js.map +1 -0
- package/dist/transfer/capsule-import.d.ts +124 -0
- package/dist/transfer/capsule-import.js +16 -0
- package/dist/transfer/capsule-import.js.map +1 -0
- package/dist/transfer/constants.d.ts +13 -0
- package/dist/transfer/constants.js +12 -0
- package/dist/transfer/constants.js.map +1 -0
- package/dist/transfer/export-json.d.ts +11 -0
- package/dist/transfer/export-json.js +11 -0
- package/dist/transfer/export-json.js.map +1 -0
- package/dist/transfer/export-md.d.ts +10 -0
- package/dist/transfer/export-md.js +13 -0
- package/dist/transfer/export-md.js.map +1 -0
- package/dist/transfer/export-sqlite.d.ts +9 -0
- package/dist/transfer/export-sqlite.js +12 -0
- package/dist/transfer/export-sqlite.js.map +1 -0
- package/dist/transfer/fs-utils.d.ts +61 -0
- package/dist/transfer/fs-utils.js +40 -0
- package/dist/transfer/fs-utils.js.map +1 -0
- package/dist/transfer/import-json.d.ts +16 -0
- package/dist/transfer/import-json.js +13 -0
- package/dist/transfer/import-json.js.map +1 -0
- package/dist/transfer/import-md.d.ts +14 -0
- package/dist/transfer/import-md.js +11 -0
- package/dist/transfer/import-md.js.map +1 -0
- package/dist/transfer/import-sqlite.d.ts +14 -0
- package/dist/transfer/import-sqlite.js +12 -0
- package/dist/transfer/import-sqlite.js.map +1 -0
- package/dist/transfer/sqlite-schema.d.ts +4 -0
- package/dist/transfer/sqlite-schema.js +10 -0
- package/dist/transfer/sqlite-schema.js.map +1 -0
- package/dist/transfer/types.d.ts +916 -0
- package/dist/transfer/types.js +30 -0
- package/dist/transfer/types.js.map +1 -0
- package/dist/types.d.ts +28 -1
- package/dist/types.js +1 -1
- package/dist/verified-recall.js +9 -6
- package/dist/work/board.d.ts +43 -0
- package/dist/work/board.js +14 -0
- package/dist/work/board.js.map +1 -0
- package/dist/work/boundary.d.ts +8 -0
- package/dist/work/boundary.js +14 -0
- package/dist/work/boundary.js.map +1 -0
- package/dist/work/storage.d.ts +39 -0
- package/dist/work/storage.js +11 -0
- package/dist/work/storage.js.map +1 -0
- package/dist/work/types.d.ts +75 -0
- package/dist/work/types.js +1 -0
- package/dist/work/types.js.map +1 -0
- package/package.json +2767 -6
- package/scripts/faiss_index.py +816 -0
- package/scripts/faiss_requirements.txt +3 -0
- package/skills/remnic-entities/SKILL.md +51 -0
- package/skills/remnic-memory-workflow/SKILL.md +61 -0
- package/skills/remnic-recall/SKILL.md +51 -0
- package/skills/remnic-remember/SKILL.md +56 -0
- package/skills/remnic-search/SKILL.md +51 -0
- package/skills/remnic-status/SKILL.md +51 -0
- package/src/abort-error.test.ts +49 -0
- package/src/abort-error.ts +46 -0
- package/src/abstraction-nodes.ts +162 -0
- package/src/access-audit.test.ts +178 -0
- package/src/access-audit.ts +125 -0
- package/src/access-cli.test.ts +439 -0
- package/src/access-cli.ts +438 -0
- package/src/access-http.test.ts +225 -0
- package/src/access-http.ts +1899 -0
- package/src/access-idempotency.ts +232 -0
- package/src/access-mcp.test.ts +568 -0
- package/src/access-mcp.ts +3056 -0
- package/src/access-schema-pi.test.ts +60 -0
- package/src/access-schema.ts +522 -0
- package/src/access-service-namespace.test.ts +123 -0
- package/src/access-service.ts +5629 -0
- package/src/action-confidence.test.ts +206 -0
- package/src/action-confidence.ts +466 -0
- package/src/active-memory-bridge.test.ts +285 -0
- package/src/active-memory-bridge.ts +217 -0
- package/src/active-recall.test.ts +484 -0
- package/src/active-recall.ts +459 -0
- package/src/adapters/claude-code.ts +56 -0
- package/src/adapters/codex.ts +57 -0
- package/src/adapters/hermes.ts +64 -0
- package/src/adapters/index.ts +6 -0
- package/src/adapters/registry.ts +41 -0
- package/src/adapters/replit.ts +55 -0
- package/src/adapters/types.ts +51 -0
- package/src/behavior-learner.ts +144 -0
- package/src/behavior-signals.ts +73 -0
- package/src/binary-lifecycle/backend.ts +117 -0
- package/src/binary-lifecycle/index.ts +35 -0
- package/src/binary-lifecycle/manifest.ts +79 -0
- package/src/binary-lifecycle/pipeline.ts +352 -0
- package/src/binary-lifecycle/scanner.ts +89 -0
- package/src/binary-lifecycle/types.ts +89 -0
- package/src/bootstrap.ts +178 -0
- package/src/boxes.ts +521 -0
- package/src/briefing.test.ts +1535 -0
- package/src/briefing.ts +1382 -0
- package/src/buffer-session.test.ts +443 -0
- package/src/buffer-surprise-report.ts +176 -0
- package/src/buffer-surprise-telemetry.test.ts +606 -0
- package/src/buffer-surprise-trigger.test.ts +766 -0
- package/src/buffer-surprise.test.ts +339 -0
- package/src/buffer-surprise.ts +203 -0
- package/src/buffer.ts +900 -0
- package/src/bulk-import/cli-command.test.ts +204 -0
- package/src/bulk-import/index.ts +34 -0
- package/src/bulk-import/pipeline.test.ts +445 -0
- package/src/bulk-import/pipeline.ts +178 -0
- package/src/bulk-import/registry.test.ts +151 -0
- package/src/bulk-import/registry.ts +72 -0
- package/src/bulk-import/types.test.ts +272 -0
- package/src/bulk-import/types.ts +145 -0
- package/src/calibration.ts +394 -0
- package/src/capsule-cli.test.ts +398 -0
- package/src/capsule-cli.ts +565 -0
- package/src/causal-behavior.ts +308 -0
- package/src/causal-chain.ts +419 -0
- package/src/causal-consolidation.ts +370 -0
- package/src/causal-retrieval.ts +286 -0
- package/src/causal-trajectory-graph.ts +60 -0
- package/src/causal-trajectory.ts +303 -0
- package/src/chunking.ts +220 -0
- package/src/citations.ts +232 -0
- package/src/cli.ts +9403 -0
- package/src/codex-cli-fallback.ts +162 -0
- package/src/codex-thread-key.ts +1 -0
- package/src/coding/access-coding-context.test.ts +197 -0
- package/src/coding/coding-branch-scope.test.ts +281 -0
- package/src/coding/coding-namespace.test.ts +360 -0
- package/src/coding/coding-namespace.ts +412 -0
- package/src/coding/coding-orchestrator.test.ts +249 -0
- package/src/coding/git-context.test.ts +507 -0
- package/src/coding/git-context.ts +336 -0
- package/src/coding/mcp-set-coding-context.test.ts +174 -0
- package/src/coding/review-context.test.ts +316 -0
- package/src/coding/review-context.ts +349 -0
- package/src/coding/wire-coding-context.test.ts +468 -0
- package/src/commitment-ledger.test.ts +78 -0
- package/src/commitment-ledger.ts +337 -0
- package/src/compat/checks.test.ts +206 -0
- package/src/compat/checks.ts +716 -0
- package/src/compat/types.ts +33 -0
- package/src/compounding/engine.ts +1686 -0
- package/src/compounding/preference-consolidator.ts +778 -0
- package/src/compression-optimizer.ts +312 -0
- package/src/config.test.ts +930 -0
- package/src/config.ts +3807 -0
- package/src/connectors/codex/instructions.md +160 -0
- package/src/connectors/codex/resources/namespace-cheatsheet.md +48 -0
- package/src/connectors/codex-marketplace.ts +500 -0
- package/src/connectors/codex-materialize-runner.ts +212 -0
- package/src/connectors/codex-materialize.ts +983 -0
- package/src/connectors/coerce.ts +62 -0
- package/src/connectors/index.test.ts +1570 -0
- package/src/connectors/index.ts +3222 -0
- package/src/connectors/live/framework.ts +164 -0
- package/src/connectors/live/github.test.ts +1218 -0
- package/src/connectors/live/github.ts +1068 -0
- package/src/connectors/live/gmail.test.ts +1706 -0
- package/src/connectors/live/gmail.ts +1293 -0
- package/src/connectors/live/google-drive.test.ts +696 -0
- package/src/connectors/live/google-drive.ts +724 -0
- package/src/connectors/live/index.ts +101 -0
- package/src/connectors/live/live-connectors.test.ts +689 -0
- package/src/connectors/live/notion.test.ts +1109 -0
- package/src/connectors/live/notion.ts +978 -0
- package/src/connectors/live/registry.ts +103 -0
- package/src/connectors/live/state-store.ts +399 -0
- package/src/connectors/live/transient-errors.ts +150 -0
- package/src/connectors/weclone-installer.test.ts +850 -0
- package/src/connectors-cli.ts +513 -0
- package/src/console/state.test.ts +224 -0
- package/src/console/state.ts +514 -0
- package/src/console/trace.test.ts +813 -0
- package/src/console/trace.ts +603 -0
- package/src/console/tui.test.ts +582 -0
- package/src/console/tui.ts +508 -0
- package/src/consolidation-operator.ts +182 -0
- package/src/consolidation-provenance-check.ts +551 -0
- package/src/consolidation-undo.ts +718 -0
- package/src/contradiction/contradiction-judge.test.ts +189 -0
- package/src/contradiction/contradiction-judge.ts +333 -0
- package/src/contradiction/contradiction-review.ts +574 -0
- package/src/contradiction/contradiction-scan.ts +504 -0
- package/src/contradiction/contradiction.test.ts +2230 -0
- package/src/contradiction/index.ts +37 -0
- package/src/contradiction/resolution.ts +383 -0
- package/src/conversation-index/backend.ts +323 -0
- package/src/conversation-index/chunker.ts +47 -0
- package/src/conversation-index/cleanup.ts +53 -0
- package/src/conversation-index/faiss-adapter.ts +384 -0
- package/src/conversation-index/indexer.test.ts +164 -0
- package/src/conversation-index/indexer.ts +192 -0
- package/src/conversation-index/search.ts +37 -0
- package/src/cross-namespace-budget.test.ts +275 -0
- package/src/cross-namespace-budget.ts +365 -0
- package/src/cue-anchors.ts +163 -0
- package/src/curation/index.ts +544 -0
- package/src/dashboard-runtime.ts +337 -0
- package/src/day-summary.ts +122 -0
- package/src/dedup/index.ts +330 -0
- package/src/dedup/semantic.test.ts +1577 -0
- package/src/dedup/semantic.ts +148 -0
- package/src/delinearize.ts +193 -0
- package/src/direct-answer-wiring.test.ts +473 -0
- package/src/direct-answer-wiring.ts +180 -0
- package/src/direct-answer.test.ts +484 -0
- package/src/direct-answer.ts +273 -0
- package/src/embedding-fallback.ts +565 -0
- package/src/enrichment/audit.ts +89 -0
- package/src/enrichment/index.ts +27 -0
- package/src/enrichment/pipeline.ts +197 -0
- package/src/enrichment/provider-registry.ts +85 -0
- package/src/enrichment/types.ts +100 -0
- package/src/enrichment/web-search-provider.ts +63 -0
- package/src/entity-retrieval.ts +774 -0
- package/src/entity-schema.ts +239 -0
- package/src/evals.ts +1312 -0
- package/src/event-order-recall.test.ts +4164 -0
- package/src/event-order-recall.ts +2802 -0
- package/src/evidence-pack.test.ts +89 -0
- package/src/evidence-pack.ts +388 -0
- package/src/explicit-capture.ts +530 -0
- package/src/explicit-cue-recall.test.ts +3019 -0
- package/src/explicit-cue-recall.ts +5545 -0
- package/src/extraction-judge-telemetry.ts +234 -0
- package/src/extraction-judge-training.ts +221 -0
- package/src/extraction-judge.ts +846 -0
- package/src/extraction-timeout.test.ts +265 -0
- package/src/extraction.ts +2719 -0
- package/src/fallback-llm.test.ts +1060 -0
- package/src/fallback-llm.ts +918 -0
- package/src/focused-list-recall.test.ts +734 -0
- package/src/focused-list-recall.ts +1160 -0
- package/src/graph-dashboard-diff.ts +35 -0
- package/src/graph-dashboard-key.ts +5 -0
- package/src/graph-dashboard-parser.ts +104 -0
- package/src/graph-edge-reinforcement.ts +192 -0
- package/src/graph-events.ts +151 -0
- package/src/graph-recall.test.ts +164 -0
- package/src/graph-recall.ts +189 -0
- package/src/graph-retrieval.test.ts +809 -0
- package/src/graph-retrieval.ts +823 -0
- package/src/graph-snapshot.ts +329 -0
- package/src/graph.ts +813 -0
- package/src/harmonic-retrieval.ts +223 -0
- package/src/himem.ts +154 -0
- package/src/hygiene.ts +87 -0
- package/src/identity-continuity.ts +333 -0
- package/src/importance.ts +328 -0
- package/src/importers/base.test.ts +294 -0
- package/src/importers/base.ts +436 -0
- package/src/importers/index.ts +21 -0
- package/src/index.ts +1204 -0
- package/src/intent.ts +154 -0
- package/src/json-extract.ts +85 -0
- package/src/json-store.ts +42 -0
- package/src/lcm/archive.ts +617 -0
- package/src/lcm/dag.ts +199 -0
- package/src/lcm/engine.ts +645 -0
- package/src/lcm/index.ts +7 -0
- package/src/lcm/queue.test.ts +178 -0
- package/src/lcm/queue.ts +200 -0
- package/src/lcm/recall.ts +117 -0
- package/src/lcm/schema.ts +154 -0
- package/src/lcm/summarizer.ts +235 -0
- package/src/lcm/tools.ts +191 -0
- package/src/lcm-engine.test.ts +660 -0
- package/src/legacy-hook-compat.test.ts +20 -0
- package/src/legacy-hook-compat.ts +45 -0
- package/src/lifecycle.ts +289 -0
- package/src/live-connectors-runner.ts +385 -0
- package/src/local-llm-qos.test.ts +303 -0
- package/src/local-llm-thinking.test.ts +292 -0
- package/src/local-llm.ts +1464 -0
- package/src/logger.ts +49 -0
- package/src/maintenance/archive-observations.ts +147 -0
- package/src/maintenance/backup-stamp.ts +3 -0
- package/src/maintenance/dreams-ledger.ts +516 -0
- package/src/maintenance/first-start-migration.ts +362 -0
- package/src/maintenance/forget.test.ts +206 -0
- package/src/maintenance/forget.ts +126 -0
- package/src/maintenance/graph-edge-decay.test.ts +409 -0
- package/src/maintenance/graph-edge-decay.ts +394 -0
- package/src/maintenance/memory-governance-cron.ts +447 -0
- package/src/maintenance/memory-governance.ts +1039 -0
- package/src/maintenance/migrate-observations.ts +216 -0
- package/src/maintenance/observation-ledger-utils.ts +54 -0
- package/src/maintenance/pattern-reinforcement.test.ts +875 -0
- package/src/maintenance/pattern-reinforcement.ts +369 -0
- package/src/maintenance/purge.ts +334 -0
- package/src/maintenance/rebuild-memory-lifecycle-ledger.ts +78 -0
- package/src/maintenance/rebuild-memory-projection.ts +1234 -0
- package/src/maintenance/rebuild-observations.ts +178 -0
- package/src/maintenance/tier-stats.test.ts +378 -0
- package/src/maintenance/tier-stats.ts +222 -0
- package/src/mcp-memory-inspector-app.ts +421 -0
- package/src/memory-action-policy.ts +80 -0
- package/src/memory-cache.ts +208 -0
- package/src/memory-extension/claude-code-publisher.ts +51 -0
- package/src/memory-extension/codex-publisher.ts +149 -0
- package/src/memory-extension/hermes-publisher.ts +51 -0
- package/src/memory-extension/index.ts +100 -0
- package/src/memory-extension/shared-instructions.ts +133 -0
- package/src/memory-extension/types.ts +86 -0
- package/src/memory-extension-host/host-discovery.ts +276 -0
- package/src/memory-extension-host/index.ts +14 -0
- package/src/memory-extension-host/render-extensions-block.ts +73 -0
- package/src/memory-extension-host/types.ts +21 -0
- package/src/memory-lifecycle-ledger-utils.ts +116 -0
- package/src/memory-projection-format.ts +11 -0
- package/src/memory-projection-store.ts +951 -0
- package/src/memory-provenance.test.ts +196 -0
- package/src/memory-provenance.ts +484 -0
- package/src/memory-worth-bench.test.ts +71 -0
- package/src/memory-worth-bench.ts +265 -0
- package/src/memory-worth-filter.test.ts +209 -0
- package/src/memory-worth-filter.ts +204 -0
- package/src/memory-worth-frontmatter.test.ts +311 -0
- package/src/memory-worth-outcomes.test.ts +316 -0
- package/src/memory-worth-outcomes.ts +286 -0
- package/src/memory-worth.test.ts +317 -0
- package/src/memory-worth.ts +215 -0
- package/src/message-parts/index.ts +806 -0
- package/src/message-parts/message-parts.test.ts +421 -0
- package/src/migrate/from-engram.ts +789 -0
- package/src/model-registry.ts +313 -0
- package/src/models-json.ts +76 -0
- package/src/namespaces/migrate.ts +187 -0
- package/src/namespaces/path.ts +25 -0
- package/src/namespaces/principal.test.ts +195 -0
- package/src/namespaces/principal.ts +86 -0
- package/src/namespaces/search.test.ts +105 -0
- package/src/namespaces/search.ts +233 -0
- package/src/namespaces/storage.ts +74 -0
- package/src/native-knowledge.ts +1823 -0
- package/src/negative.ts +72 -0
- package/src/network/tailscale.ts +179 -0
- package/src/network/webdav.ts +385 -0
- package/src/objective-state-writers.ts +951 -0
- package/src/objective-state.ts +320 -0
- package/src/onboarding/index.ts +529 -0
- package/src/openai-chat-compat.ts +56 -0
- package/src/operator-toolkit.ts +2132 -0
- package/src/opik-exporter.test.ts +72 -0
- package/src/opik-exporter.ts +587 -0
- package/src/orchestrator-extraction-queue.test.ts +197 -0
- package/src/orchestrator-flush.test.ts +1171 -0
- package/src/orchestrator-pattern-reinforcement.test.ts +128 -0
- package/src/orchestrator-source-attribution.test.ts +701 -0
- package/src/orchestrator.ts +16368 -0
- package/src/page-versioning.ts +450 -0
- package/src/patterns-cli.ts +574 -0
- package/src/peers/index.ts +54 -0
- package/src/peers/migrate-from-identity-anchor.test.ts +291 -0
- package/src/peers/migrate-from-identity-anchor.ts +350 -0
- package/src/peers/peers.test.ts +419 -0
- package/src/peers/profile-reasoner.ts +694 -0
- package/src/peers/storage.ts +1350 -0
- package/src/peers/types.ts +138 -0
- package/src/plugin-id.ts +84 -0
- package/src/policy-runtime.ts +209 -0
- package/src/procedural/procedure-miner.ts +150 -0
- package/src/procedural/procedure-recall.ts +93 -0
- package/src/procedural/procedure-stats.ts +213 -0
- package/src/procedural/procedure-types.ts +132 -0
- package/src/procedural/reinforcement-core.test.ts +132 -0
- package/src/procedural/reinforcement-core.ts +73 -0
- package/src/profiling.test.ts +263 -0
- package/src/profiling.ts +435 -0
- package/src/projection/index.ts +398 -0
- package/src/qmd-recall-cache.test.ts +138 -0
- package/src/qmd-recall-cache.ts +111 -0
- package/src/qmd.test.ts +258 -0
- package/src/qmd.ts +2614 -0
- package/src/reasoning-trace-recall.ts +201 -0
- package/src/reasoning-trace-types.ts +235 -0
- package/src/recall-audit-anomaly.test.ts +246 -0
- package/src/recall-audit-anomaly.ts +297 -0
- package/src/recall-audit.test.ts +51 -0
- package/src/recall-audit.ts +72 -0
- package/src/recall-budget-config.test.ts +87 -0
- package/src/recall-disclosure-escalation.test.ts +196 -0
- package/src/recall-disclosure-escalation.ts +158 -0
- package/src/recall-disclosure-shaping.test.ts +146 -0
- package/src/recall-disclosure.test.ts +214 -0
- package/src/recall-explain-renderer.test.ts +140 -0
- package/src/recall-explain-renderer.ts +356 -0
- package/src/recall-mmr.test.ts +808 -0
- package/src/recall-mmr.ts +607 -0
- package/src/recall-qos.test.ts +85 -0
- package/src/recall-qos.ts +82 -0
- package/src/recall-query-policy.ts +221 -0
- package/src/recall-state.test.ts +233 -0
- package/src/recall-state.ts +456 -0
- package/src/recall-tag-filter.ts +143 -0
- package/src/recall-tokenization.ts +35 -0
- package/src/recall-xray-cli.test.ts +118 -0
- package/src/recall-xray-cli.ts +100 -0
- package/src/recall-xray-disclosure-telemetry.test.ts +183 -0
- package/src/recall-xray-renderer.test.ts +539 -0
- package/src/recall-xray-renderer.ts +487 -0
- package/src/recall-xray.test.ts +503 -0
- package/src/recall-xray.ts +621 -0
- package/src/reconstruct.ts +41 -0
- package/src/release-changelog.ts +35 -0
- package/src/relevance.ts +67 -0
- package/src/replay/normalizers/chatgpt.ts +133 -0
- package/src/replay/normalizers/claude.ts +102 -0
- package/src/replay/normalizers/openclaw.ts +119 -0
- package/src/replay/normalizers/shared.ts +69 -0
- package/src/replay/runner.ts +197 -0
- package/src/replay/types.ts +143 -0
- package/src/rerank.test.ts +48 -0
- package/src/rerank.ts +176 -0
- package/src/resolve-auth-token.test.ts +226 -0
- package/src/resolve-auth-token.ts +151 -0
- package/src/resolve-provider-secret.test.ts +187 -0
- package/src/resolve-provider-secret.ts +410 -0
- package/src/response-guidance-recall.test.ts +3952 -0
- package/src/response-guidance-recall.ts +4431 -0
- package/src/resume-bundles.ts +415 -0
- package/src/retrieval-agents.ts +623 -0
- package/src/retrieval-tiers.ts +25 -0
- package/src/retrieval.ts +104 -0
- package/src/review/index.test.ts +201 -0
- package/src/review/index.ts +536 -0
- package/src/routing/engine.ts +162 -0
- package/src/routing/store.ts +321 -0
- package/src/runtime/better-sqlite.test.ts +32 -0
- package/src/runtime/better-sqlite.ts +76 -0
- package/src/runtime/child-process.ts +67 -0
- package/src/runtime/env.ts +48 -0
- package/src/sanitize.ts +58 -0
- package/src/schemas.ts +449 -0
- package/src/sdk-compat.ts +87 -0
- package/src/search/document-scanner.ts +96 -0
- package/src/search/embed-helper.ts +142 -0
- package/src/search/factory.ts +189 -0
- package/src/search/index.ts +10 -0
- package/src/search/lancedb-backend.ts +342 -0
- package/src/search/meilisearch-backend.ts +232 -0
- package/src/search/noop-backend.ts +57 -0
- package/src/search/orama-backend.ts +358 -0
- package/src/search/port.ts +86 -0
- package/src/search/remote-backend.ts +124 -0
- package/src/secure-store/cipher.ts +271 -0
- package/src/secure-store/cli-handlers.ts +355 -0
- package/src/secure-store/cli-renderer.ts +131 -0
- package/src/secure-store/header.ts +373 -0
- package/src/secure-store/index.ts +137 -0
- package/src/secure-store/kdf.ts +263 -0
- package/src/secure-store/keyring.ts +106 -0
- package/src/secure-store/metadata.ts +394 -0
- package/src/secure-store/passphrase-reader.ts +252 -0
- package/src/secure-store/secure-fs.ts +571 -0
- package/src/secure-store/secure-store.test.ts +755 -0
- package/src/semantic-chunking.ts +545 -0
- package/src/semantic-consolidation.test.ts +182 -0
- package/src/semantic-consolidation.ts +432 -0
- package/src/semantic-rule-promotion.ts +183 -0
- package/src/semantic-rule-verifier.ts +160 -0
- package/src/session-integrity.ts +569 -0
- package/src/session-observer-bands.ts +11 -0
- package/src/session-observer-state.ts +346 -0
- package/src/session-toggles.test.ts +96 -0
- package/src/session-toggles.ts +159 -0
- package/src/shared-context/manager.ts +810 -0
- package/src/signal.ts +84 -0
- package/src/skills-registry.test.ts +277 -0
- package/src/skills-registry.ts +120 -0
- package/src/source-attribution-roundtrip.test.ts +215 -0
- package/src/source-attribution.test.ts +1425 -0
- package/src/source-attribution.ts +639 -0
- package/src/spaces/index.ts +627 -0
- package/src/storage-paths.ts +117 -0
- package/src/storage.ts +6657 -0
- package/src/store-contract.ts +55 -0
- package/src/summarizer.ts +844 -0
- package/src/summary-snapshot.test.ts +681 -0
- package/src/summary-snapshot.ts +238 -0
- package/src/surfaces/dreams.test.ts +394 -0
- package/src/surfaces/dreams.ts +346 -0
- package/src/surfaces/heartbeat.test.ts +415 -0
- package/src/surfaces/heartbeat.ts +325 -0
- package/src/sync/index.ts +308 -0
- package/src/targeted-fact-recall.test.ts +1694 -0
- package/src/targeted-fact-recall.ts +2905 -0
- package/src/taxonomy/default-taxonomy.ts +87 -0
- package/src/taxonomy/index.ts +26 -0
- package/src/taxonomy/resolver-doc-generator.ts +57 -0
- package/src/taxonomy/resolver.ts +184 -0
- package/src/taxonomy/taxonomy-loader.ts +186 -0
- package/src/taxonomy/types.ts +48 -0
- package/src/telemetry-transcript.ts +70 -0
- package/src/temporal-index.ts +890 -0
- package/src/temporal-supersession.test.ts +2703 -0
- package/src/temporal-supersession.ts +493 -0
- package/src/temporal-validity.test.ts +448 -0
- package/src/temporal-validity.ts +123 -0
- package/src/threading.ts +395 -0
- package/src/tier-migration.ts +124 -0
- package/src/tier-routing.ts +102 -0
- package/src/tmt.ts +462 -0
- package/src/tokens.test.ts +178 -0
- package/src/tokens.ts +279 -0
- package/src/topics.ts +147 -0
- package/src/training-export/cli-date-validation.test.ts +258 -0
- package/src/training-export/converter.test.ts +452 -0
- package/src/training-export/converter.ts +319 -0
- package/src/training-export/date-parse.ts +117 -0
- package/src/training-export/index.ts +26 -0
- package/src/training-export/registry.test.ts +85 -0
- package/src/training-export/registry.ts +57 -0
- package/src/training-export/types.ts +31 -0
- package/src/transcript.ts +1179 -0
- package/src/transfer/autodetect.ts +30 -0
- package/src/transfer/backup.ts +138 -0
- package/src/transfer/capsule-crypto.ts +485 -0
- package/src/transfer/capsule-encrypt.test.ts +690 -0
- package/src/transfer/capsule-export.ts +543 -0
- package/src/transfer/capsule-fork.ts +375 -0
- package/src/transfer/capsule-import.ts +564 -0
- package/src/transfer/capsule-merge.ts +433 -0
- package/src/transfer/conflict-policy.ts +16 -0
- package/src/transfer/constants.ts +13 -0
- package/src/transfer/exclusions.ts +37 -0
- package/src/transfer/export-json.ts +65 -0
- package/src/transfer/export-md.ts +59 -0
- package/src/transfer/export-sqlite.ts +52 -0
- package/src/transfer/fs-utils.ts +269 -0
- package/src/transfer/import-json.ts +108 -0
- package/src/transfer/import-md.ts +84 -0
- package/src/transfer/import-sqlite.ts +100 -0
- package/src/transfer/integrity.ts +71 -0
- package/src/transfer/sqlite-schema.ts +16 -0
- package/src/transfer/types.ts +297 -0
- package/src/trust-zones.ts +1186 -0
- package/src/types.ts +3074 -0
- package/src/user-model.test.ts +124 -0
- package/src/user-model.ts +162 -0
- package/src/utility-learner.ts +353 -0
- package/src/utility-runtime.ts +88 -0
- package/src/utility-telemetry.ts +215 -0
- package/src/utils/category-dir.ts +44 -0
- package/src/utils/errno.ts +6 -0
- package/src/utils/iso-timestamp.test.ts +37 -0
- package/src/utils/iso-timestamp.ts +164 -0
- package/src/utils/path.ts +26 -0
- package/src/verified-recall.ts +138 -0
- package/src/version-utils.test.ts +10 -0
- package/src/version-utils.ts +9 -0
- package/src/whitespace.ts +10 -0
- package/src/work/board.ts +359 -0
- package/src/work/boundary.ts +107 -0
- package/src/work/storage.ts +436 -0
- package/src/work/types.ts +82 -0
- package/src/work-product-ledger.ts +265 -0
- package/dist/access-service-DDjzFALq.d.ts +0 -2088
- package/dist/capsule-crypto-SJS5VVAP.js +0 -18
- package/dist/capsule-export-7QNCBZOQ.js +0 -17
- package/dist/capsule-import-EPBHD2EN.js +0 -16
- package/dist/capsule-merge-DI7PNQ2H.js +0 -189
- package/dist/chunk-23ZZK64Y.js +0 -26
- package/dist/chunk-23ZZK64Y.js.map +0 -1
- package/dist/chunk-242S3I2A.js +0 -647
- package/dist/chunk-2LGMW3DJ.js +0 -111
- package/dist/chunk-3B6KIRBH.js +0 -5213
- package/dist/chunk-3B6KIRBH.js.map +0 -1
- package/dist/chunk-457A4P3L.js +0 -119
- package/dist/chunk-457A4P3L.js.map +0 -1
- package/dist/chunk-4IS4SXIQ.js +0 -2040
- package/dist/chunk-4YM32CRU.js +0 -721
- package/dist/chunk-6TBWYBJ3.js +0 -236
- package/dist/chunk-74EMIVE4.js +0 -329
- package/dist/chunk-74EMIVE4.js.map +0 -1
- package/dist/chunk-767ODGE6.js +0 -183
- package/dist/chunk-7V22HTMD.js +0 -623
- package/dist/chunk-7V22HTMD.js.map +0 -1
- package/dist/chunk-7ZM3BFKK.js +0 -9705
- package/dist/chunk-7ZM3BFKK.js.map +0 -1
- package/dist/chunk-AQJNPMOA.js +0 -643
- package/dist/chunk-AQJNPMOA.js.map +0 -1
- package/dist/chunk-ASAITVLA.js +0 -64
- package/dist/chunk-ASAITVLA.js.map +0 -1
- package/dist/chunk-BBE34QBJ.js +0 -275
- package/dist/chunk-BBE34QBJ.js.map +0 -1
- package/dist/chunk-BZSQEPRW.js +0 -14710
- package/dist/chunk-BZSQEPRW.js.map +0 -1
- package/dist/chunk-CPKTBRS2.js +0 -891
- package/dist/chunk-CPKTBRS2.js.map +0 -1
- package/dist/chunk-D4GAOFF6.js +0 -562
- package/dist/chunk-D4GAOFF6.js.map +0 -1
- package/dist/chunk-D54LZC5L.js +0 -147
- package/dist/chunk-DF3RVK3X.js +0 -119
- package/dist/chunk-DF3RVK3X.js.map +0 -1
- package/dist/chunk-DZZPC36E.js +0 -1451
- package/dist/chunk-DZZPC36E.js.map +0 -1
- package/dist/chunk-E2UCDP5S.js +0 -570
- package/dist/chunk-E6K4NIEU.js +0 -747
- package/dist/chunk-E6K4NIEU.js.map +0 -1
- package/dist/chunk-EEQLFRUM.js +0 -89
- package/dist/chunk-ETOW6ACV.js +0 -158
- package/dist/chunk-ETOW6ACV.js.map +0 -1
- package/dist/chunk-FMEBPEAO.js +0 -347
- package/dist/chunk-FMEBPEAO.js.map +0 -1
- package/dist/chunk-FQDPCE3I.js +0 -1837
- package/dist/chunk-FQDPCE3I.js.map +0 -1
- package/dist/chunk-FYIYMQ5N.js +0 -221
- package/dist/chunk-FYIYMQ5N.js.map +0 -1
- package/dist/chunk-G2WADRQ3.js +0 -219
- package/dist/chunk-G4SK7DSQ.js +0 -121
- package/dist/chunk-GVPWB7EY.js +0 -390
- package/dist/chunk-GVPWB7EY.js.map +0 -1
- package/dist/chunk-HELQZFZO.js +0 -1075
- package/dist/chunk-HL5LRPNA.js +0 -1914
- package/dist/chunk-HL5LRPNA.js.map +0 -1
- package/dist/chunk-HQZVVSVB.js +0 -147
- package/dist/chunk-HQZVVSVB.js.map +0 -1
- package/dist/chunk-HY3L4WKC.js +0 -2195
- package/dist/chunk-HY3L4WKC.js.map +0 -1
- package/dist/chunk-IB3BFHGN.js +0 -228
- package/dist/chunk-IXEJRKCZ.js +0 -18
- package/dist/chunk-JBMSGZEQ.js +0 -441
- package/dist/chunk-JBMSGZEQ.js.map +0 -1
- package/dist/chunk-JESOB2HO.js +0 -108
- package/dist/chunk-JKDVIE52.js +0 -272
- package/dist/chunk-JRNQ3RNA.js +0 -284
- package/dist/chunk-JRNQ3RNA.js.map +0 -1
- package/dist/chunk-K6WK37A6.js +0 -865
- package/dist/chunk-K6WK37A6.js.map +0 -1
- package/dist/chunk-MARWOCVP.js +0 -48
- package/dist/chunk-MNU6ZBWT.js +0 -4454
- package/dist/chunk-MNU6ZBWT.js.map +0 -1
- package/dist/chunk-N5AKDXAI.js +0 -74
- package/dist/chunk-OA3L7BFR.js +0 -183
- package/dist/chunk-OA3L7BFR.js.map +0 -1
- package/dist/chunk-OR64ZGRZ.js +0 -23
- package/dist/chunk-P77UEOU2.js +0 -1521
- package/dist/chunk-P77UEOU2.js.map +0 -1
- package/dist/chunk-PH4C2U43.js +0 -239
- package/dist/chunk-PH4C2U43.js.map +0 -1
- package/dist/chunk-RVPLBATS.js +0 -1586
- package/dist/chunk-RVPLBATS.js.map +0 -1
- package/dist/chunk-U5JMRGKX.js +0 -340
- package/dist/chunk-U5JMRGKX.js.map +0 -1
- package/dist/chunk-URB2WSKZ.js +0 -350
- package/dist/chunk-URB2WSKZ.js.map +0 -1
- package/dist/chunk-UVMUAWVT.js +0 -596
- package/dist/chunk-WEJG4TB5.js +0 -118
- package/dist/chunk-X7HPGUVG.js +0 -271
- package/dist/chunk-XAMBKFQS.js +0 -2777
- package/dist/chunk-XAMBKFQS.js.map +0 -1
- package/dist/chunk-XJKFSSDW.js +0 -726
- package/dist/chunk-XJKFSSDW.js.map +0 -1
- package/dist/chunk-XMHBH5H6.js +0 -283
- package/dist/chunk-XMHBH5H6.js.map +0 -1
- package/dist/chunk-XMVFHBHT.js +0 -277
- package/dist/chunk-Y3VMVTYX.js +0 -53
- package/dist/chunk-YNB73F22.js +0 -137
- package/dist/chunk-YNB73F22.js.map +0 -1
- package/dist/chunk-Z2E7VW55.js +0 -335
- package/dist/chunk-Z2E7VW55.js.map +0 -1
- package/dist/chunk-ZG7PTKBK.js +0 -2296
- package/dist/chunk-ZNQN6ZTA.js +0 -135
- package/dist/chunk-ZVTKDVVM.js +0 -827
- package/dist/chunk-ZVTKDVVM.js.map +0 -1
- package/dist/cli-BR8KpIU0.d.ts +0 -1259
- package/dist/codex-materialize-CQlLTzke.d.ts +0 -139
- package/dist/connectors-cli-DFGtY2DB.d.ts +0 -257
- package/dist/contradiction-review-5LTTVDQV.js +0 -22
- package/dist/contradiction-scan-QTXAMBUA.js +0 -414
- package/dist/contradiction-scan-QTXAMBUA.js.map +0 -1
- package/dist/engine-35M5BKQ7.js +0 -28
- package/dist/fs-utils-IRVUFB6G.js +0 -30
- package/dist/graph-edge-decay-PWB63GRE.js +0 -207
- package/dist/memory-governance-IMPQZXFC.js +0 -37
- package/dist/memory-projection-store-CY8TU40w.d.ts +0 -222
- package/dist/orchestrator-DDMPqU6R.d.ts +0 -1792
- package/dist/path-RMTY5Y5A.js +0 -9
- package/dist/port-B6VEDIkC.d.ts +0 -53
- package/dist/resolution-YGIBORXI.js +0 -101
- package/dist/resolution-YGIBORXI.js.map +0 -1
- package/dist/secure-store-4R2GSO7S.js +0 -156
- package/dist/semantic-consolidation-ByBXb-sf.d.ts +0 -180
- package/dist/state-store-3EH7HYIN.js +0 -16
- package/dist/types-V3FJ26TF.js +0 -30
- /package/dist/{capsule-crypto-SJS5VVAP.js.map → adapters/claude-code.js.map} +0 -0
- /package/dist/{capsule-export-7QNCBZOQ.js.map → adapters/codex.js.map} +0 -0
- /package/dist/{capsule-import-EPBHD2EN.js.map → adapters/hermes.js.map} +0 -0
- /package/dist/{contradiction-review-5LTTVDQV.js.map → adapters/index.js.map} +0 -0
- /package/dist/{engine-35M5BKQ7.js.map → adapters/registry.js.map} +0 -0
- /package/dist/{fs-utils-IRVUFB6G.js.map → adapters/replit.js.map} +0 -0
- /package/dist/{memory-governance-IMPQZXFC.js.map → adapters/types.js.map} +0 -0
- /package/dist/{path-RMTY5Y5A.js.map → capsule-crypto-5CYAGVC5.js.map} +0 -0
- /package/dist/{capsule-merge-DI7PNQ2H.js.map → capsule-merge-4MGKE7C5.js.map} +0 -0
- /package/dist/{chunk-G4SK7DSQ.js.map → chunk-2WWLHTZY.js.map} +0 -0
- /package/dist/{chunk-X7HPGUVG.js.map → chunk-4CRG46BG.js.map} +0 -0
- /package/dist/{chunk-UVMUAWVT.js.map → chunk-7IASACLB.js.map} +0 -0
- /package/dist/{chunk-HELQZFZO.js.map → chunk-EDTHC6UD.js.map} +0 -0
- /package/dist/{chunk-4YM32CRU.js.map → chunk-EFJ3MQ4V.js.map} +0 -0
- /package/dist/{chunk-E2UCDP5S.js.map → chunk-FBYESMQ2.js.map} +0 -0
- /package/dist/{chunk-D54LZC5L.js.map → chunk-FDU6HUUL.js.map} +0 -0
- /package/dist/{chunk-IB3BFHGN.js.map → chunk-GGKRUQOO.js.map} +0 -0
- /package/dist/{chunk-242S3I2A.js.map → chunk-GL6I6MEQ.js.map} +0 -0
- /package/dist/{secure-store-4R2GSO7S.js.map → chunk-HHLLAQGZ.js.map} +0 -0
- /package/dist/{chunk-4IS4SXIQ.js.map → chunk-HXXBL2KD.js.map} +0 -0
- /package/dist/{chunk-767ODGE6.js.map → chunk-KNKUID7G.js.map} +0 -0
- /package/dist/{chunk-6TBWYBJ3.js.map → chunk-LPMVBPA3.js.map} +0 -0
- /package/dist/{chunk-WEJG4TB5.js.map → chunk-MC26UJIM.js.map} +0 -0
- /package/dist/{chunk-JKDVIE52.js.map → chunk-MGKYQQYF.js.map} +0 -0
- /package/dist/{chunk-Y3VMVTYX.js.map → chunk-MT4HVDUZ.js.map} +0 -0
- /package/dist/{chunk-G2WADRQ3.js.map → chunk-MY6TPVXW.js.map} +0 -0
- /package/dist/{chunk-OR64ZGRZ.js.map → chunk-NNVTUXEB.js.map} +0 -0
- /package/dist/{chunk-JESOB2HO.js.map → chunk-P4NEIHUT.js.map} +0 -0
- /package/dist/{chunk-IXEJRKCZ.js.map → chunk-QRNI5JBH.js.map} +0 -0
- /package/dist/{chunk-EEQLFRUM.js.map → chunk-RRF5UOBJ.js.map} +0 -0
- /package/dist/{state-store-3EH7HYIN.js.map → chunk-SEDEKFYQ.js.map} +0 -0
- /package/dist/{chunk-2LGMW3DJ.js.map → chunk-U3PN77QT.js.map} +0 -0
- /package/dist/{chunk-XMVFHBHT.js.map → chunk-U3WSW6PZ.js.map} +0 -0
- /package/dist/{chunk-N5AKDXAI.js.map → chunk-UWVJF25J.js.map} +0 -0
- /package/dist/{types-V3FJ26TF.js.map → chunk-V5OCT34X.js.map} +0 -0
- /package/dist/{chunk-ZG7PTKBK.js.map → chunk-W3LR522O.js.map} +0 -0
- /package/dist/{chunk-MARWOCVP.js.map → chunk-XIG5PDM7.js.map} +0 -0
- /package/dist/{chunk-ZNQN6ZTA.js.map → chunk-XVZ7B3HG.js.map} +0 -0
- /package/dist/{graph-edge-decay-PWB63GRE.js.map → graph-edge-decay-5DI5GUNL.js.map} +0 -0
|
@@ -0,0 +1,1974 @@
|
|
|
1
|
+
import {
|
|
2
|
+
abortError,
|
|
3
|
+
isAbortError,
|
|
4
|
+
throwIfAborted
|
|
5
|
+
} from "./chunk-PVGDJXVK.js";
|
|
6
|
+
import {
|
|
7
|
+
launchProcess
|
|
8
|
+
} from "./chunk-NNVTUXEB.js";
|
|
9
|
+
import {
|
|
10
|
+
getCachedQmdSearch,
|
|
11
|
+
setCachedQmdSearch
|
|
12
|
+
} from "./chunk-PFV5C235.js";
|
|
13
|
+
import {
|
|
14
|
+
mergeEnv
|
|
15
|
+
} from "./chunk-XIG5PDM7.js";
|
|
16
|
+
import {
|
|
17
|
+
log
|
|
18
|
+
} from "./chunk-2ODBA7MQ.js";
|
|
19
|
+
|
|
20
|
+
// src/qmd.ts
|
|
21
|
+
import { createHash } from "crypto";
|
|
22
|
+
import os from "os";
|
|
23
|
+
import path from "path";
|
|
24
|
+
var QMD_TIMEOUT_MS = 3e4;
|
|
25
|
+
var QMD_DAEMON_TIMEOUT_MS = 8e3;
|
|
26
|
+
var QMD_PROBE_TIMEOUT_MS = 8e3;
|
|
27
|
+
var QMD_UPDATE_BACKOFF_MS = 15 * 60 * 1e3;
|
|
28
|
+
var QMD_EMBED_BACKOFF_MS = 60 * 60 * 1e3;
|
|
29
|
+
var QMD_CLI_WARN_THROTTLE_MS = 15 * 60 * 1e3;
|
|
30
|
+
var QMD_SUPPORTED_VERSION = "2.5.1";
|
|
31
|
+
var QMD_PACKAGE_NAME = "@tobilu/qmd";
|
|
32
|
+
var QMD_AUTO_UPGRADE_TIMEOUT_MS = 12e4;
|
|
33
|
+
var QMD_AUTO_UPGRADE_CHECK_INTERVAL_MS = 24 * 60 * 6e4;
|
|
34
|
+
var QMD_STRUCTURED_HYDE_MAX_CHARS = 320;
|
|
35
|
+
var QMD_FALLBACK_PATHS = [
|
|
36
|
+
path.join(os.homedir(), ".bun", "bin", "qmd"),
|
|
37
|
+
"/usr/local/bin/qmd",
|
|
38
|
+
"/opt/homebrew/bin/qmd"
|
|
39
|
+
];
|
|
40
|
+
var QMD_GLOBAL_STATE_KEY = "__openclawEngramQmdGlobalState";
|
|
41
|
+
function getGlobalQmdState() {
|
|
42
|
+
const g = globalThis;
|
|
43
|
+
if (!g[QMD_GLOBAL_STATE_KEY]) {
|
|
44
|
+
g[QMD_GLOBAL_STATE_KEY] = {
|
|
45
|
+
warnedGlobalUpdateBehavior: false,
|
|
46
|
+
lastGlobalUpdateRunAtMs: null,
|
|
47
|
+
lastGlobalUpdateFailAtMs: null,
|
|
48
|
+
lastGlobalEmbedRunAtMs: null,
|
|
49
|
+
lastGlobalEmbedFailAtMs: null,
|
|
50
|
+
lastCliWarnAtMs: null,
|
|
51
|
+
lastUpdateByCollectionMs: {},
|
|
52
|
+
lastUpdateFailByCollectionMs: {},
|
|
53
|
+
lastEmbedByCollectionMs: {},
|
|
54
|
+
lastEmbedFailByCollectionMs: {},
|
|
55
|
+
lastAutoUpgradeCheckAtMs: null,
|
|
56
|
+
lastAutoUpgradeStatus: null,
|
|
57
|
+
lastAutoUpgradeCheckByTargetMs: {},
|
|
58
|
+
lastAutoUpgradeStatusByTarget: {}
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
const state = g[QMD_GLOBAL_STATE_KEY];
|
|
62
|
+
state.lastAutoUpgradeCheckByTargetMs ??= {};
|
|
63
|
+
state.lastAutoUpgradeStatusByTarget ??= {};
|
|
64
|
+
return state;
|
|
65
|
+
}
|
|
66
|
+
function sleep(ms) {
|
|
67
|
+
return new Promise((r) => setTimeout(r, ms));
|
|
68
|
+
}
|
|
69
|
+
function errorMessage(err) {
|
|
70
|
+
if (typeof err === "string") return err;
|
|
71
|
+
if (err instanceof Error) return err.message;
|
|
72
|
+
if (err && typeof err === "object" && "message" in err && typeof err.message === "string") {
|
|
73
|
+
return err.message;
|
|
74
|
+
}
|
|
75
|
+
return String(err);
|
|
76
|
+
}
|
|
77
|
+
function isCallerCancellation(err, signal) {
|
|
78
|
+
if (signal?.aborted) return true;
|
|
79
|
+
if (isAbortError(err)) return true;
|
|
80
|
+
if (err && typeof err === "object") {
|
|
81
|
+
const code = "code" in err ? err.code : void 0;
|
|
82
|
+
if (code === "ABORT_ERR" || code === "ERR_CANCELED") return true;
|
|
83
|
+
}
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
function isDaemonTimeoutError(err) {
|
|
87
|
+
return /timed out/i.test(errorMessage(err));
|
|
88
|
+
}
|
|
89
|
+
function sleepWithSignal(ms, signal) {
|
|
90
|
+
return new Promise((resolve, reject) => {
|
|
91
|
+
throwIfAborted(signal);
|
|
92
|
+
const timer = setTimeout(() => {
|
|
93
|
+
cleanup();
|
|
94
|
+
resolve();
|
|
95
|
+
}, ms);
|
|
96
|
+
const onAbort = () => {
|
|
97
|
+
clearTimeout(timer);
|
|
98
|
+
cleanup();
|
|
99
|
+
reject(abortError("operation aborted while waiting"));
|
|
100
|
+
};
|
|
101
|
+
const cleanup = () => {
|
|
102
|
+
signal?.removeEventListener("abort", onAbort);
|
|
103
|
+
};
|
|
104
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
function isSqliteBusyError(msg) {
|
|
108
|
+
const lower = msg.toLowerCase();
|
|
109
|
+
return lower.includes("database is locked") || lower.includes("sqlite_busy") || lower.includes("sqlite_busy_recovery") || lower.includes("sqliterror: database is locked");
|
|
110
|
+
}
|
|
111
|
+
function stripControlChars(s) {
|
|
112
|
+
return s.replace(/\x1b\[[0-9;]*[A-Za-z]/g, "").replace(/[\u0000-\u001f\u007f]/g, "");
|
|
113
|
+
}
|
|
114
|
+
function truncateForLog(s, max = 2e3) {
|
|
115
|
+
const cleaned = stripControlChars(s);
|
|
116
|
+
return cleaned.length > max ? cleaned.slice(0, max) + "\u2026(truncated)" : cleaned;
|
|
117
|
+
}
|
|
118
|
+
function isVectorDimensionMismatchError(err) {
|
|
119
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
120
|
+
return /dimension mismatch/i.test(msg) || /vectors?_vec/i.test(msg) && /float\[\d+\]/i.test(msg) || /embedding/i.test(msg) && /dimensions?/i.test(msg);
|
|
121
|
+
}
|
|
122
|
+
function parseQmdVersion(version) {
|
|
123
|
+
if (!version) return null;
|
|
124
|
+
const match = version.match(/v?(\d{1,10})\.(\d{1,10})\.(\d{1,10})/i);
|
|
125
|
+
if (!match) return null;
|
|
126
|
+
return [
|
|
127
|
+
Number.parseInt(match[1] ?? "0", 10),
|
|
128
|
+
Number.parseInt(match[2] ?? "0", 10),
|
|
129
|
+
Number.parseInt(match[3] ?? "0", 10)
|
|
130
|
+
];
|
|
131
|
+
}
|
|
132
|
+
function parseQmdVersionOutput(stdout, stderr) {
|
|
133
|
+
const lines = `${stdout}
|
|
134
|
+
${stderr}`.split("\n").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
135
|
+
if (lines.length === 0) return null;
|
|
136
|
+
const semanticLines = lines.filter((line) => parseQmdVersion(line) !== null);
|
|
137
|
+
if (semanticLines.length === 0) return lines[0] ?? null;
|
|
138
|
+
return semanticLines.find((line) => /\bqmd\b/i.test(line)) ?? semanticLines[0] ?? null;
|
|
139
|
+
}
|
|
140
|
+
function compareQmdVersions(left, right) {
|
|
141
|
+
if (!left && !right) return 0;
|
|
142
|
+
if (!left) return -1;
|
|
143
|
+
if (!right) return 1;
|
|
144
|
+
for (let i = 0; i < 3; i += 1) {
|
|
145
|
+
if ((left[i] ?? 0) > (right[i] ?? 0)) return 1;
|
|
146
|
+
if ((left[i] ?? 0) < (right[i] ?? 0)) return -1;
|
|
147
|
+
}
|
|
148
|
+
return 0;
|
|
149
|
+
}
|
|
150
|
+
function versionAtLeast(current, target) {
|
|
151
|
+
return compareQmdVersions(current, target) >= 0;
|
|
152
|
+
}
|
|
153
|
+
function resolveQmdCapabilities(version) {
|
|
154
|
+
const parsedVersion = parseQmdVersion(version);
|
|
155
|
+
const atLeast = (target) => versionAtLeast(parsedVersion, target);
|
|
156
|
+
return {
|
|
157
|
+
version,
|
|
158
|
+
parsedVersion,
|
|
159
|
+
stableSdk: atLeast([2, 0, 0]),
|
|
160
|
+
unifiedSearch: atLeast([2, 0, 0]),
|
|
161
|
+
getDocumentBody: atLeast([2, 0, 0]),
|
|
162
|
+
maintenanceApi: atLeast([2, 0, 0]),
|
|
163
|
+
legacySkillInstall: atLeast([2, 0, 1]),
|
|
164
|
+
intentHints: atLeast([1, 1, 5]),
|
|
165
|
+
explainTraces: atLeast([1, 1, 2]),
|
|
166
|
+
candidateLimit: atLeast([1, 1, 2]),
|
|
167
|
+
v2McpQueryTool: atLeast([2, 0, 0]),
|
|
168
|
+
structuredSearches: atLeast([2, 0, 0]),
|
|
169
|
+
queryRerankToggle: atLeast([2, 1, 0]),
|
|
170
|
+
chunkStrategy: atLeast([2, 1, 0]),
|
|
171
|
+
qmdBench: atLeast([2, 1, 0]),
|
|
172
|
+
perCollectionModels: atLeast([2, 1, 0]),
|
|
173
|
+
jsonLineNumbers: atLeast([2, 1, 0]),
|
|
174
|
+
editorLinks: atLeast([2, 1, 0]),
|
|
175
|
+
doctor: atLeast([2, 5, 0]),
|
|
176
|
+
versionedSkills: atLeast([2, 5, 0]),
|
|
177
|
+
absoluteSnippetLines: atLeast([2, 5, 0]),
|
|
178
|
+
fullQueryOutput: atLeast([2, 5, 0]),
|
|
179
|
+
forceCpu: atLeast([2, 5, 0]),
|
|
180
|
+
gpuBackendOverride: atLeast([2, 5, 0]),
|
|
181
|
+
embedParallelism: atLeast([2, 5, 0]),
|
|
182
|
+
modelEnvConsistency: atLeast([2, 5, 0]),
|
|
183
|
+
scopedEmbed: atLeast([2, 5, 0]),
|
|
184
|
+
safeStatusDeviceProbe: atLeast([2, 5, 0]),
|
|
185
|
+
mcpIndexSelection: atLeast([2, 5, 0])
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
function shouldAutoUpgradeQmd(installedVersion, supportedVersion = QMD_SUPPORTED_VERSION) {
|
|
189
|
+
const installed = parseQmdVersion(installedVersion);
|
|
190
|
+
const supported = parseQmdVersion(supportedVersion);
|
|
191
|
+
if (!installed || !supported) return false;
|
|
192
|
+
return compareQmdVersions(installed, supported) < 0;
|
|
193
|
+
}
|
|
194
|
+
function getQmdPostInstallProbeTargets(qmdPath, qmdPathSource) {
|
|
195
|
+
const targets = [
|
|
196
|
+
{ qmdPath: "qmd", source: "auto-path" }
|
|
197
|
+
];
|
|
198
|
+
const normalizedPath = qmdPath.trim();
|
|
199
|
+
if (qmdPathSource === "auto-fallback" && normalizedPath.length > 0 && normalizedPath !== "qmd") {
|
|
200
|
+
targets.push({ qmdPath: normalizedPath, source: "auto-fallback" });
|
|
201
|
+
}
|
|
202
|
+
return targets;
|
|
203
|
+
}
|
|
204
|
+
function qmdVersionToString(version) {
|
|
205
|
+
return `${version[0]}.${version[1]}.${version[2]}`;
|
|
206
|
+
}
|
|
207
|
+
function normalizeSearchOptions(options) {
|
|
208
|
+
if (!options) return void 0;
|
|
209
|
+
const intent = typeof options.intent === "string" ? options.intent.trim() : "";
|
|
210
|
+
const normalized = {};
|
|
211
|
+
if (intent.length > 0) {
|
|
212
|
+
normalized.intent = intent;
|
|
213
|
+
}
|
|
214
|
+
if (options.explain === true) {
|
|
215
|
+
normalized.explain = true;
|
|
216
|
+
}
|
|
217
|
+
if (options.rerank === false) {
|
|
218
|
+
normalized.rerank = false;
|
|
219
|
+
}
|
|
220
|
+
if (options.chunkStrategy === "auto" || options.chunkStrategy === "regex") {
|
|
221
|
+
normalized.chunkStrategy = options.chunkStrategy;
|
|
222
|
+
}
|
|
223
|
+
if (typeof options.candidateLimit === "number" && Number.isFinite(options.candidateLimit) && options.candidateLimit > 0) {
|
|
224
|
+
normalized.candidateLimit = Math.floor(options.candidateLimit);
|
|
225
|
+
}
|
|
226
|
+
const structuredSearches = normalizeStructuredSearches(options.structuredSearches);
|
|
227
|
+
if (structuredSearches.length > 0) {
|
|
228
|
+
normalized.structuredSearches = structuredSearches;
|
|
229
|
+
}
|
|
230
|
+
return Object.keys(normalized).length > 0 ? normalized : void 0;
|
|
231
|
+
}
|
|
232
|
+
function normalizeStructuredSearches(value) {
|
|
233
|
+
if (!Array.isArray(value)) return [];
|
|
234
|
+
const normalized = [];
|
|
235
|
+
for (const entry of value) {
|
|
236
|
+
if (!entry || typeof entry !== "object") continue;
|
|
237
|
+
const candidate = entry;
|
|
238
|
+
const type = candidate.type;
|
|
239
|
+
const query = typeof candidate.query === "string" ? candidate.query.trim() : "";
|
|
240
|
+
if ((type === "lex" || type === "vec" || type === "hyde") && query.length > 0) {
|
|
241
|
+
normalized.push({ type, query });
|
|
242
|
+
}
|
|
243
|
+
if (normalized.length >= 10) break;
|
|
244
|
+
}
|
|
245
|
+
return normalized;
|
|
246
|
+
}
|
|
247
|
+
function buildSyntheticHydeQuery(query, intent) {
|
|
248
|
+
const base = intent && intent.trim().length > 0 ? `A relevant Remnic memory for ${intent.trim()} would answer: ${query.trim()}` : `A relevant Remnic memory would answer: ${query.trim()}`;
|
|
249
|
+
return base.length > QMD_STRUCTURED_HYDE_MAX_CHARS ? base.slice(0, QMD_STRUCTURED_HYDE_MAX_CHARS) : base;
|
|
250
|
+
}
|
|
251
|
+
function buildDefaultStructuredSearches(query, options) {
|
|
252
|
+
const explicit = normalizeStructuredSearches(options?.structuredSearches);
|
|
253
|
+
if (explicit.length > 0) return explicit;
|
|
254
|
+
const trimmed = query.trim();
|
|
255
|
+
if (!trimmed) return [];
|
|
256
|
+
return [
|
|
257
|
+
{ type: "lex", query: trimmed },
|
|
258
|
+
{ type: "vec", query: trimmed },
|
|
259
|
+
{ type: "hyde", query: buildSyntheticHydeQuery(trimmed, options?.intent) }
|
|
260
|
+
];
|
|
261
|
+
}
|
|
262
|
+
function parseExplainScores(value) {
|
|
263
|
+
if (!Array.isArray(value)) return void 0;
|
|
264
|
+
const scores = value.filter((entry) => typeof entry === "number");
|
|
265
|
+
return scores.length > 0 ? scores : void 0;
|
|
266
|
+
}
|
|
267
|
+
function parseQmdExplain(value) {
|
|
268
|
+
if (!value || typeof value !== "object") return void 0;
|
|
269
|
+
const candidate = value;
|
|
270
|
+
const rrf = typeof candidate.rrf === "number" ? candidate.rrf : candidate.rrf && typeof candidate.rrf === "object" && typeof candidate.rrf.totalScore === "number" ? candidate.rrf.totalScore : void 0;
|
|
271
|
+
const rrfObj = candidate.rrf && typeof candidate.rrf === "object" ? candidate.rrf : void 0;
|
|
272
|
+
const parsed = {
|
|
273
|
+
ftsScores: parseExplainScores(candidate.ftsScores),
|
|
274
|
+
vectorScores: parseExplainScores(candidate.vectorScores),
|
|
275
|
+
rrf,
|
|
276
|
+
rrfRank: typeof rrfObj?.rank === "number" ? rrfObj.rank : void 0,
|
|
277
|
+
rrfPositionScore: typeof rrfObj?.positionScore === "number" ? rrfObj.positionScore : void 0,
|
|
278
|
+
rrfBaseScore: typeof rrfObj?.baseScore === "number" ? rrfObj.baseScore : void 0,
|
|
279
|
+
rrfTopRankBonus: typeof rrfObj?.topRankBonus === "number" ? rrfObj.topRankBonus : void 0,
|
|
280
|
+
rerankScore: typeof candidate.rerankScore === "number" ? candidate.rerankScore : void 0,
|
|
281
|
+
blendedScore: typeof candidate.blendedScore === "number" ? candidate.blendedScore : void 0
|
|
282
|
+
};
|
|
283
|
+
return Object.values(parsed).some((entry) => entry !== void 0) ? parsed : void 0;
|
|
284
|
+
}
|
|
285
|
+
var AsyncMutex = class {
|
|
286
|
+
locked = false;
|
|
287
|
+
queue = [];
|
|
288
|
+
async runExclusive(fn, signal) {
|
|
289
|
+
const release = await this.acquire(signal);
|
|
290
|
+
try {
|
|
291
|
+
throwIfAborted(signal);
|
|
292
|
+
return await fn();
|
|
293
|
+
} finally {
|
|
294
|
+
release();
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
acquire(signal) {
|
|
298
|
+
throwIfAborted(signal);
|
|
299
|
+
if (!this.locked) {
|
|
300
|
+
this.locked = true;
|
|
301
|
+
return Promise.resolve(() => this.release());
|
|
302
|
+
}
|
|
303
|
+
return new Promise((resolve, reject) => {
|
|
304
|
+
const waiter = {
|
|
305
|
+
resolve: (release) => {
|
|
306
|
+
signal?.removeEventListener("abort", waiter.onAbort);
|
|
307
|
+
resolve(release);
|
|
308
|
+
},
|
|
309
|
+
reject: (reason) => {
|
|
310
|
+
signal?.removeEventListener("abort", waiter.onAbort);
|
|
311
|
+
reject(reason);
|
|
312
|
+
},
|
|
313
|
+
signal,
|
|
314
|
+
onAbort: () => {
|
|
315
|
+
this.queue = this.queue.filter((entry) => entry !== waiter);
|
|
316
|
+
reject(abortError("operation aborted while waiting for qmd mutex"));
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
signal?.addEventListener("abort", waiter.onAbort, { once: true });
|
|
320
|
+
this.queue.push(waiter);
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
release() {
|
|
324
|
+
while (this.queue.length > 0) {
|
|
325
|
+
const next = this.queue.shift();
|
|
326
|
+
if (!next) break;
|
|
327
|
+
if (next.signal?.aborted) {
|
|
328
|
+
next.reject(abortError("operation aborted while waiting for qmd mutex"));
|
|
329
|
+
continue;
|
|
330
|
+
}
|
|
331
|
+
this.locked = true;
|
|
332
|
+
next.resolve(() => this.release());
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
this.locked = false;
|
|
336
|
+
}
|
|
337
|
+
};
|
|
338
|
+
var QMD_MUTEX = new AsyncMutex();
|
|
339
|
+
function runQmd(args, timeoutMs = QMD_TIMEOUT_MS, qmdPath = "qmd", signal, runtimeEnv) {
|
|
340
|
+
return QMD_MUTEX.runExclusive(async () => {
|
|
341
|
+
throwIfAborted(signal, `qmd ${args.join(" ")} aborted before start`);
|
|
342
|
+
const maxAttempts = isLikelyWriteCommand(args) ? 3 : 1;
|
|
343
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
344
|
+
try {
|
|
345
|
+
return await runQmdOnce(args, timeoutMs, qmdPath, signal, runtimeEnv);
|
|
346
|
+
} catch (err) {
|
|
347
|
+
if (isAbortError(err)) throw err;
|
|
348
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
349
|
+
if (attempt < maxAttempts && isSqliteBusyError(msg)) {
|
|
350
|
+
await sleepWithSignal(1500 * attempt, signal);
|
|
351
|
+
continue;
|
|
352
|
+
}
|
|
353
|
+
throw err;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
throw new Error("qmd command failed");
|
|
357
|
+
}, signal);
|
|
358
|
+
}
|
|
359
|
+
function isLikelyWriteCommand(args) {
|
|
360
|
+
const cmd = getQmdCommandName(args);
|
|
361
|
+
return cmd === "update" || cmd === "embed" || cmd === "cleanup" || cmd === "collection";
|
|
362
|
+
}
|
|
363
|
+
function getQmdCommandName(args) {
|
|
364
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
365
|
+
const arg = args[i] ?? "";
|
|
366
|
+
if (arg === "--index") {
|
|
367
|
+
i += 1;
|
|
368
|
+
continue;
|
|
369
|
+
}
|
|
370
|
+
if (arg.startsWith("--index=")) {
|
|
371
|
+
continue;
|
|
372
|
+
}
|
|
373
|
+
if (arg.startsWith("-")) {
|
|
374
|
+
continue;
|
|
375
|
+
}
|
|
376
|
+
return arg;
|
|
377
|
+
}
|
|
378
|
+
return "";
|
|
379
|
+
}
|
|
380
|
+
function runQmdOnce(args, timeoutMs, qmdPath, signal, runtimeEnv) {
|
|
381
|
+
const isVersionCheck = args.length === 1 && args[0] === "--version";
|
|
382
|
+
return runCommandWithTimeout(qmdPath, args, {
|
|
383
|
+
timeoutMs,
|
|
384
|
+
signal,
|
|
385
|
+
env: runtimeEnv,
|
|
386
|
+
label: `qmd ${args.join(" ")}`,
|
|
387
|
+
isSuccessExitCode: (code) => code === 0 || isVersionCheck && code === 1
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
function runCommandWithTimeout(command, args, options) {
|
|
391
|
+
const label = options.label ?? `${command} ${args.join(" ")}`;
|
|
392
|
+
const isSuccessExitCode = options.isSuccessExitCode ?? ((code) => code === 0);
|
|
393
|
+
return new Promise((resolve, reject) => {
|
|
394
|
+
throwIfAborted(options.signal, `${label} aborted before spawn`);
|
|
395
|
+
const child = launchProcess(command, args, {
|
|
396
|
+
env: mergeEnv({ NO_COLOR: "1", ...options.env }),
|
|
397
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
398
|
+
});
|
|
399
|
+
if (!child.stdout || !child.stderr) {
|
|
400
|
+
reject(new Error(`${label} failed to open stdio pipes`));
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
let stdout = "";
|
|
404
|
+
let stderr = "";
|
|
405
|
+
let settled = false;
|
|
406
|
+
const timer = setTimeout(() => {
|
|
407
|
+
settled = true;
|
|
408
|
+
cleanup();
|
|
409
|
+
child.kill("SIGKILL");
|
|
410
|
+
reject(new Error(`${label} timed out after ${options.timeoutMs}ms`));
|
|
411
|
+
}, options.timeoutMs);
|
|
412
|
+
const onAbort = () => {
|
|
413
|
+
if (settled) return;
|
|
414
|
+
settled = true;
|
|
415
|
+
clearTimeout(timer);
|
|
416
|
+
cleanup();
|
|
417
|
+
child.kill("SIGKILL");
|
|
418
|
+
reject(abortError(`${label} aborted`));
|
|
419
|
+
};
|
|
420
|
+
const cleanup = () => {
|
|
421
|
+
options.signal?.removeEventListener("abort", onAbort);
|
|
422
|
+
};
|
|
423
|
+
options.signal?.addEventListener("abort", onAbort, { once: true });
|
|
424
|
+
child.stdout.on("data", (data) => {
|
|
425
|
+
stdout += data.toString();
|
|
426
|
+
});
|
|
427
|
+
child.stderr.on("data", (data) => {
|
|
428
|
+
stderr += data.toString();
|
|
429
|
+
});
|
|
430
|
+
child.on("error", (err) => {
|
|
431
|
+
if (settled) return;
|
|
432
|
+
settled = true;
|
|
433
|
+
clearTimeout(timer);
|
|
434
|
+
cleanup();
|
|
435
|
+
reject(err);
|
|
436
|
+
});
|
|
437
|
+
child.on("close", (code) => {
|
|
438
|
+
if (settled) return;
|
|
439
|
+
settled = true;
|
|
440
|
+
clearTimeout(timer);
|
|
441
|
+
cleanup();
|
|
442
|
+
if (isSuccessExitCode(code)) {
|
|
443
|
+
resolve({ stdout, stderr });
|
|
444
|
+
} else {
|
|
445
|
+
reject(
|
|
446
|
+
new Error(
|
|
447
|
+
`${label} failed (code ${code}): ${truncateForLog(stderr || stdout)}`
|
|
448
|
+
)
|
|
449
|
+
);
|
|
450
|
+
}
|
|
451
|
+
});
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
function runProcessCommand(command, args, timeoutMs, signal) {
|
|
455
|
+
return runCommandWithTimeout(command, args, {
|
|
456
|
+
timeoutMs,
|
|
457
|
+
signal
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
var nextJsonRpcId = 1;
|
|
461
|
+
var QmdDaemonSession = class {
|
|
462
|
+
child = null;
|
|
463
|
+
initialized = false;
|
|
464
|
+
buffer = "";
|
|
465
|
+
startPromise = null;
|
|
466
|
+
pendingRequests = /* @__PURE__ */ new Map();
|
|
467
|
+
qmdPath;
|
|
468
|
+
runtimeEnv;
|
|
469
|
+
indexName;
|
|
470
|
+
constructor(qmdPath, runtimeEnv = {}, indexName) {
|
|
471
|
+
this.qmdPath = qmdPath;
|
|
472
|
+
this.runtimeEnv = runtimeEnv;
|
|
473
|
+
this.indexName = indexName?.trim() || void 0;
|
|
474
|
+
}
|
|
475
|
+
/** Spawn the qmd mcp child process and perform MCP handshake. */
|
|
476
|
+
async start() {
|
|
477
|
+
if (this.child && !this.child.killed && this.initialized) {
|
|
478
|
+
return true;
|
|
479
|
+
}
|
|
480
|
+
if (this.startPromise) {
|
|
481
|
+
return this.startPromise;
|
|
482
|
+
}
|
|
483
|
+
this.startPromise = (async () => {
|
|
484
|
+
const processAlreadyRunning = this.child != null && !this.child.killed;
|
|
485
|
+
if (!processAlreadyRunning) {
|
|
486
|
+
if (this.child) {
|
|
487
|
+
this.cleanup({ killChild: true });
|
|
488
|
+
}
|
|
489
|
+
try {
|
|
490
|
+
const args = this.indexName ? ["--index", this.indexName, "mcp"] : ["mcp"];
|
|
491
|
+
const child = launchProcess(this.qmdPath, args, {
|
|
492
|
+
env: mergeEnv({ NO_COLOR: "1", ...this.runtimeEnv }),
|
|
493
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
494
|
+
});
|
|
495
|
+
this.child = child;
|
|
496
|
+
this.buffer = "";
|
|
497
|
+
child.stdout?.on("data", (data) => {
|
|
498
|
+
if (this.child !== child) return;
|
|
499
|
+
this.handleStdoutData(data);
|
|
500
|
+
});
|
|
501
|
+
child.stderr?.on("data", (data) => {
|
|
502
|
+
if (this.child !== child) return;
|
|
503
|
+
const msg = data.toString().trim();
|
|
504
|
+
if (msg) log.debug(`QMD mcp stderr: ${stripControlChars(msg)}`);
|
|
505
|
+
});
|
|
506
|
+
child.stdin?.on("error", (err) => {
|
|
507
|
+
log.debug(`QMD mcp stdin error (suppressed): ${err.message}`);
|
|
508
|
+
});
|
|
509
|
+
child.on("error", (err) => {
|
|
510
|
+
if (this.child !== child) return;
|
|
511
|
+
log.debug(`QMD mcp process error: ${err.message}`);
|
|
512
|
+
this.cleanup({ child });
|
|
513
|
+
});
|
|
514
|
+
child.on("close", (code) => {
|
|
515
|
+
if (this.child !== child) return;
|
|
516
|
+
log.debug(`QMD mcp process exited (code ${code})`);
|
|
517
|
+
this.cleanup({ child });
|
|
518
|
+
});
|
|
519
|
+
} catch (err) {
|
|
520
|
+
log.debug(`QMD mcp: failed to spawn process: ${err}`);
|
|
521
|
+
this.cleanup({ killChild: true });
|
|
522
|
+
return false;
|
|
523
|
+
}
|
|
524
|
+
} else {
|
|
525
|
+
log.debug("QMD mcp: process already running, retrying handshake");
|
|
526
|
+
}
|
|
527
|
+
try {
|
|
528
|
+
const result = await this.sendRequest(
|
|
529
|
+
"initialize",
|
|
530
|
+
{
|
|
531
|
+
protocolVersion: "2024-11-05",
|
|
532
|
+
capabilities: {},
|
|
533
|
+
clientInfo: { name: "openclaw-remnic", version: "1.0.0" }
|
|
534
|
+
},
|
|
535
|
+
6e4
|
|
536
|
+
);
|
|
537
|
+
if (!result) {
|
|
538
|
+
this.cleanup({ killChild: true });
|
|
539
|
+
return false;
|
|
540
|
+
}
|
|
541
|
+
this.sendNotification("notifications/initialized");
|
|
542
|
+
this.initialized = true;
|
|
543
|
+
log.info("QMD mcp: stdio session initialized");
|
|
544
|
+
return true;
|
|
545
|
+
} catch (err) {
|
|
546
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
547
|
+
if (/timed out/i.test(msg)) {
|
|
548
|
+
log.debug(`QMD mcp: handshake timed out \u2014 process still loading, will retry later`);
|
|
549
|
+
this.initialized = false;
|
|
550
|
+
} else {
|
|
551
|
+
log.debug(`QMD mcp: failed to start stdio session: ${err}`);
|
|
552
|
+
this.cleanup({ killChild: true });
|
|
553
|
+
}
|
|
554
|
+
return false;
|
|
555
|
+
} finally {
|
|
556
|
+
this.startPromise = null;
|
|
557
|
+
}
|
|
558
|
+
})();
|
|
559
|
+
return this.startPromise;
|
|
560
|
+
}
|
|
561
|
+
/** Call an MCP tool and return the parsed result. */
|
|
562
|
+
async callTool(name, args, timeoutMs = 3e4, signal) {
|
|
563
|
+
if (!this.child || this.child.killed || !this.initialized) {
|
|
564
|
+
throw new Error("QMD mcp process not running");
|
|
565
|
+
}
|
|
566
|
+
return this.sendRequest("tools/call", { name, arguments: args }, timeoutMs, signal);
|
|
567
|
+
}
|
|
568
|
+
/** Kill stdio process and clear state so the next probe can restart. */
|
|
569
|
+
invalidate() {
|
|
570
|
+
this.cleanup({ killChild: true });
|
|
571
|
+
}
|
|
572
|
+
/** Kill stdio process and wait briefly for the child handle to close. */
|
|
573
|
+
async close(timeoutMs = 1e3) {
|
|
574
|
+
const target = this.child;
|
|
575
|
+
if (!target) {
|
|
576
|
+
this.cleanup({ killChild: true });
|
|
577
|
+
return;
|
|
578
|
+
}
|
|
579
|
+
let closed = false;
|
|
580
|
+
const closedPromise = new Promise((resolve) => {
|
|
581
|
+
target.once("close", () => {
|
|
582
|
+
closed = true;
|
|
583
|
+
resolve();
|
|
584
|
+
});
|
|
585
|
+
});
|
|
586
|
+
this.cleanup({ killChild: true });
|
|
587
|
+
await Promise.race([closedPromise, sleep(timeoutMs)]);
|
|
588
|
+
if (!closed) {
|
|
589
|
+
try {
|
|
590
|
+
target.kill("SIGKILL");
|
|
591
|
+
} catch {
|
|
592
|
+
}
|
|
593
|
+
await Promise.race([closedPromise, sleep(250)]);
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
isActive() {
|
|
597
|
+
return this.child !== null && !this.child.killed && this.initialized;
|
|
598
|
+
}
|
|
599
|
+
/** True while the process is spawned but the MCP handshake has not yet completed. */
|
|
600
|
+
isLoading() {
|
|
601
|
+
return this.child !== null && !this.child.killed && !this.initialized;
|
|
602
|
+
}
|
|
603
|
+
sendRequest(method, params, timeoutMs, signal) {
|
|
604
|
+
return new Promise((resolve, reject) => {
|
|
605
|
+
throwIfAborted(signal, `QMD mcp ${method} aborted before request`);
|
|
606
|
+
if (!this.child || !this.child.stdin || this.child.killed) {
|
|
607
|
+
reject(new Error("QMD mcp process not available"));
|
|
608
|
+
return;
|
|
609
|
+
}
|
|
610
|
+
const id = nextJsonRpcId++;
|
|
611
|
+
const timer = setTimeout(() => {
|
|
612
|
+
this.pendingRequests.delete(id);
|
|
613
|
+
cleanup();
|
|
614
|
+
reject(new Error(`QMD mcp ${method} timed out after ${timeoutMs}ms`));
|
|
615
|
+
}, timeoutMs);
|
|
616
|
+
const onAbort = () => {
|
|
617
|
+
clearTimeout(timer);
|
|
618
|
+
this.pendingRequests.delete(id);
|
|
619
|
+
cleanup();
|
|
620
|
+
reject(abortError(`QMD mcp ${method} aborted`));
|
|
621
|
+
};
|
|
622
|
+
const cleanup = () => {
|
|
623
|
+
signal?.removeEventListener("abort", onAbort);
|
|
624
|
+
};
|
|
625
|
+
this.pendingRequests.set(id, { resolve, reject, timer, cleanup });
|
|
626
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
627
|
+
const message = JSON.stringify({ jsonrpc: "2.0", id, method, params }) + "\n";
|
|
628
|
+
this.child.stdin.write(message, (err) => {
|
|
629
|
+
if (err) {
|
|
630
|
+
clearTimeout(timer);
|
|
631
|
+
this.pendingRequests.delete(id);
|
|
632
|
+
cleanup();
|
|
633
|
+
reject(new Error(`Failed to write to QMD mcp stdin: ${err.message}`));
|
|
634
|
+
}
|
|
635
|
+
});
|
|
636
|
+
});
|
|
637
|
+
}
|
|
638
|
+
sendNotification(method, params) {
|
|
639
|
+
if (!this.child || !this.child.stdin || this.child.killed) return;
|
|
640
|
+
if (this.child.stdin.destroyed) return;
|
|
641
|
+
const msg = { jsonrpc: "2.0", method };
|
|
642
|
+
if (params) msg.params = params;
|
|
643
|
+
try {
|
|
644
|
+
this.child.stdin.write(JSON.stringify(msg) + "\n");
|
|
645
|
+
} catch {
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
handleStdoutData(data) {
|
|
649
|
+
this.buffer += data.toString();
|
|
650
|
+
let newlineIdx;
|
|
651
|
+
while ((newlineIdx = this.buffer.indexOf("\n")) !== -1) {
|
|
652
|
+
const line = this.buffer.slice(0, newlineIdx).trim();
|
|
653
|
+
this.buffer = this.buffer.slice(newlineIdx + 1);
|
|
654
|
+
if (!line) continue;
|
|
655
|
+
try {
|
|
656
|
+
const msg = JSON.parse(line);
|
|
657
|
+
this.handleMessage(msg);
|
|
658
|
+
} catch {
|
|
659
|
+
log.debug(`QMD mcp: unparseable stdout: ${truncateForLog(line, 200)}`);
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
handleMessage(msg) {
|
|
664
|
+
if (msg.id !== void 0 && msg.id !== null) {
|
|
665
|
+
const pending = this.pendingRequests.get(msg.id);
|
|
666
|
+
if (pending) {
|
|
667
|
+
clearTimeout(pending.timer);
|
|
668
|
+
this.pendingRequests.delete(msg.id);
|
|
669
|
+
pending.cleanup();
|
|
670
|
+
if (msg.error) {
|
|
671
|
+
pending.reject(new Error(JSON.stringify(msg.error)));
|
|
672
|
+
} else {
|
|
673
|
+
pending.resolve(msg.result);
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
return;
|
|
677
|
+
}
|
|
678
|
+
if (msg.method) {
|
|
679
|
+
log.debug(`QMD mcp notification: ${msg.method}`);
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
cleanup(opts) {
|
|
683
|
+
const target = opts?.child ?? this.child;
|
|
684
|
+
if (!target) return;
|
|
685
|
+
if (opts?.child && this.child !== opts.child) {
|
|
686
|
+
return;
|
|
687
|
+
}
|
|
688
|
+
if (opts?.killChild && !target.killed) {
|
|
689
|
+
target.kill("SIGTERM");
|
|
690
|
+
}
|
|
691
|
+
this.initialized = false;
|
|
692
|
+
for (const [, pending] of this.pendingRequests) {
|
|
693
|
+
clearTimeout(pending.timer);
|
|
694
|
+
pending.cleanup();
|
|
695
|
+
pending.reject(new Error("QMD mcp process terminated"));
|
|
696
|
+
}
|
|
697
|
+
this.pendingRequests.clear();
|
|
698
|
+
this.startPromise = null;
|
|
699
|
+
this.child = null;
|
|
700
|
+
this.buffer = "";
|
|
701
|
+
}
|
|
702
|
+
};
|
|
703
|
+
var QMD_RESULT_LINE_RE = /^#([0-9a-fA-F]+)\s+(\d+)%\s+(.+)/;
|
|
704
|
+
var QMD_PATH_TITLE_RE = /^(.+?\.[a-zA-Z]{2,10})\s+-\s+(.*)$/;
|
|
705
|
+
function parseQmdMarkdownResultText(text, transport) {
|
|
706
|
+
const results = [];
|
|
707
|
+
for (const line of text.split("\n")) {
|
|
708
|
+
const m = QMD_RESULT_LINE_RE.exec(line.trim());
|
|
709
|
+
if (!m) continue;
|
|
710
|
+
const rest = m[3];
|
|
711
|
+
const pathTitleSplit = QMD_PATH_TITLE_RE.exec(rest);
|
|
712
|
+
if (!pathTitleSplit) continue;
|
|
713
|
+
results.push({
|
|
714
|
+
docid: m[1],
|
|
715
|
+
path: pathTitleSplit[1] ?? "unknown",
|
|
716
|
+
snippet: "",
|
|
717
|
+
score: parseInt(m[2], 10) / 100,
|
|
718
|
+
transport
|
|
719
|
+
});
|
|
720
|
+
}
|
|
721
|
+
return results;
|
|
722
|
+
}
|
|
723
|
+
function parseMcpSearchResult(result, transport = "daemon") {
|
|
724
|
+
const resultObj = result;
|
|
725
|
+
if (!resultObj) return [];
|
|
726
|
+
const results = [];
|
|
727
|
+
const pushDocs = (docs) => {
|
|
728
|
+
for (const doc of docs) {
|
|
729
|
+
const d = doc;
|
|
730
|
+
results.push({
|
|
731
|
+
docid: typeof d.docid === "string" ? d.docid.replace(/^#/, "") : "",
|
|
732
|
+
path: typeof d.file === "string" ? d.file : typeof d.path === "string" ? d.path : typeof d.docid === "string" ? d.docid.replace(/^#/, "") : "unknown",
|
|
733
|
+
snippet: typeof d.snippet === "string" ? d.snippet : "",
|
|
734
|
+
score: typeof d.score === "number" ? d.score : 0,
|
|
735
|
+
line: typeof d.line === "number" && Number.isFinite(d.line) ? Math.max(1, Math.floor(d.line)) : void 0,
|
|
736
|
+
explain: parseQmdExplain(d.explain),
|
|
737
|
+
transport
|
|
738
|
+
});
|
|
739
|
+
}
|
|
740
|
+
};
|
|
741
|
+
const topStructured = resultObj.structuredContent;
|
|
742
|
+
const topDocs = topStructured?.results ?? topStructured?.documents;
|
|
743
|
+
if (Array.isArray(topDocs)) pushDocs(topDocs);
|
|
744
|
+
const content = resultObj.content;
|
|
745
|
+
if (Array.isArray(content)) {
|
|
746
|
+
for (const item of content) {
|
|
747
|
+
const structured = item?.structuredContent;
|
|
748
|
+
const docResults = structured?.results ?? structured?.documents;
|
|
749
|
+
if (Array.isArray(docResults)) pushDocs(docResults);
|
|
750
|
+
if (typeof item?.text === "string") {
|
|
751
|
+
try {
|
|
752
|
+
const parsed = JSON.parse(item.text);
|
|
753
|
+
const textResults = parsed?.results ?? parsed?.documents;
|
|
754
|
+
if (Array.isArray(textResults)) pushDocs(textResults);
|
|
755
|
+
} catch {
|
|
756
|
+
const existingKeys = new Set(results.map((r) => `${r.docid.toLowerCase()}|${r.path}`));
|
|
757
|
+
const parsed = parseQmdMarkdownResultText(item.text, transport);
|
|
758
|
+
for (const p of parsed) {
|
|
759
|
+
const key = `${p.docid.toLowerCase()}|${p.path}`;
|
|
760
|
+
if (!existingKeys.has(key)) {
|
|
761
|
+
results.push(p);
|
|
762
|
+
existingKeys.add(key);
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
return results;
|
|
770
|
+
}
|
|
771
|
+
function parseQmdSearchStdout(stdout, transport = "subprocess") {
|
|
772
|
+
const trimmedOut = stdout.trim();
|
|
773
|
+
if (!trimmedOut || trimmedOut === "No results found.") return [];
|
|
774
|
+
const parsed = JSON.parse(trimmedOut);
|
|
775
|
+
if (!Array.isArray(parsed)) return [];
|
|
776
|
+
return parsed.map(
|
|
777
|
+
(entry) => ({
|
|
778
|
+
docid: entry.docid ?? "",
|
|
779
|
+
path: entry.file ?? entry.path ?? entry.docid ?? "unknown",
|
|
780
|
+
snippet: entry.snippet ?? "",
|
|
781
|
+
score: typeof entry.score === "number" ? entry.score : 0,
|
|
782
|
+
line: typeof entry.line === "number" && Number.isFinite(entry.line) ? Math.max(1, Math.floor(entry.line)) : void 0,
|
|
783
|
+
explain: parseQmdExplain(entry.explain),
|
|
784
|
+
transport
|
|
785
|
+
})
|
|
786
|
+
);
|
|
787
|
+
}
|
|
788
|
+
var SHARED_DAEMON_SESSIONS = /* @__PURE__ */ new Map();
|
|
789
|
+
function stableRuntimeEnvKey(runtimeEnv) {
|
|
790
|
+
return JSON.stringify(
|
|
791
|
+
Object.keys(runtimeEnv).sort().map((key) => [key, runtimeEnv[key]])
|
|
792
|
+
);
|
|
793
|
+
}
|
|
794
|
+
function recordAutoUpgradeStatus(state, targetKey, status) {
|
|
795
|
+
state.lastAutoUpgradeStatusByTarget[targetKey] = status;
|
|
796
|
+
state.lastAutoUpgradeStatus = status;
|
|
797
|
+
}
|
|
798
|
+
function retainSharedDaemonSession(qmdPath, runtimeEnv = {}, indexName, cliVersion) {
|
|
799
|
+
const normalizedPath = qmdPath.trim() || "qmd";
|
|
800
|
+
const normalizedIndex = indexName?.trim() || "";
|
|
801
|
+
const normalizedVersion = cliVersion?.trim() || "";
|
|
802
|
+
const sessionKey = `${normalizedPath}\0${normalizedIndex}\0${normalizedVersion}\0${stableRuntimeEnvKey(runtimeEnv)}`;
|
|
803
|
+
const existing = SHARED_DAEMON_SESSIONS.get(sessionKey);
|
|
804
|
+
if (existing) {
|
|
805
|
+
existing.refs += 1;
|
|
806
|
+
return existing.session;
|
|
807
|
+
}
|
|
808
|
+
const session = new QmdDaemonSession(normalizedPath, runtimeEnv, normalizedIndex || void 0);
|
|
809
|
+
SHARED_DAEMON_SESSIONS.set(sessionKey, {
|
|
810
|
+
refs: 1,
|
|
811
|
+
session
|
|
812
|
+
});
|
|
813
|
+
return session;
|
|
814
|
+
}
|
|
815
|
+
async function releaseSharedDaemonSession(session) {
|
|
816
|
+
if (!session) return;
|
|
817
|
+
for (const [qmdPath, entry] of SHARED_DAEMON_SESSIONS.entries()) {
|
|
818
|
+
if (entry.session !== session) continue;
|
|
819
|
+
entry.refs = Math.max(0, entry.refs - 1);
|
|
820
|
+
if (entry.refs === 0) {
|
|
821
|
+
SHARED_DAEMON_SESSIONS.delete(qmdPath);
|
|
822
|
+
await entry.session.close();
|
|
823
|
+
}
|
|
824
|
+
return;
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
var QmdClient = class _QmdClient {
|
|
828
|
+
constructor(collection, maxResults, opts) {
|
|
829
|
+
this.collection = collection;
|
|
830
|
+
this.maxResults = maxResults;
|
|
831
|
+
this.slowLog = opts?.slowLog;
|
|
832
|
+
this.updateTimeoutMs = opts?.updateTimeoutMs ?? 12e4;
|
|
833
|
+
this.updateMinIntervalMs = Math.max(0, opts?.updateMinIntervalMs ?? 15 * 6e4);
|
|
834
|
+
this.configuredQmdPath = opts?.qmdPath?.trim() ? opts.qmdPath.trim() : void 0;
|
|
835
|
+
this.qmdSupportedVersion = parseQmdVersion(opts?.qmdSupportedVersion ?? null) !== null ? opts?.qmdSupportedVersion ?? QMD_SUPPORTED_VERSION : QMD_SUPPORTED_VERSION;
|
|
836
|
+
this.qmdAutoUpgradeEnabled = opts?.qmdAutoUpgradeEnabled === true;
|
|
837
|
+
this.qmdAutoUpgradeCheckIntervalMs = Math.max(
|
|
838
|
+
6e4,
|
|
839
|
+
Math.floor(opts?.qmdAutoUpgradeCheckIntervalMs ?? QMD_AUTO_UPGRADE_CHECK_INTERVAL_MS)
|
|
840
|
+
);
|
|
841
|
+
this.qmdChunkStrategy = opts?.qmdChunkStrategy === "auto" || opts?.qmdChunkStrategy === "regex" ? opts.qmdChunkStrategy : void 0;
|
|
842
|
+
this.qmdCandidateLimit = typeof opts?.qmdCandidateLimit === "number" && Number.isFinite(opts.qmdCandidateLimit) && opts.qmdCandidateLimit > 0 ? Math.floor(opts.qmdCandidateLimit) : void 0;
|
|
843
|
+
this.qmdQueryRerankEnabled = opts?.qmdQueryRerankEnabled !== false;
|
|
844
|
+
this.qmdIndexName = opts?.qmdIndexName?.trim() || void 0;
|
|
845
|
+
this.qmdRuntimeEnv = this.buildRuntimeEnv(opts);
|
|
846
|
+
if (this.configuredQmdPath) {
|
|
847
|
+
this.qmdPath = this.configuredQmdPath;
|
|
848
|
+
this.qmdPathSource = "configured";
|
|
849
|
+
}
|
|
850
|
+
this.daemonEnabled = Boolean(opts?.daemonUrl);
|
|
851
|
+
this.daemonRecheckIntervalMs = opts?.daemonRecheckIntervalMs ?? 15e3;
|
|
852
|
+
}
|
|
853
|
+
collection;
|
|
854
|
+
maxResults;
|
|
855
|
+
available = null;
|
|
856
|
+
_lastUpdateFailAtMs = null;
|
|
857
|
+
lastEmbedFailAtMs = null;
|
|
858
|
+
lastUpdateRunAtMs = null;
|
|
859
|
+
get lastUpdateFailedAtMs() {
|
|
860
|
+
return this._lastUpdateFailAtMs;
|
|
861
|
+
}
|
|
862
|
+
get lastUpdateRanAtMs() {
|
|
863
|
+
return this.lastUpdateRunAtMs;
|
|
864
|
+
}
|
|
865
|
+
resetUpdateThrottles() {
|
|
866
|
+
this._lastUpdateFailAtMs = null;
|
|
867
|
+
this.lastUpdateRunAtMs = null;
|
|
868
|
+
const gs = getGlobalQmdState();
|
|
869
|
+
gs.lastGlobalUpdateRunAtMs = null;
|
|
870
|
+
gs.lastGlobalUpdateFailAtMs = null;
|
|
871
|
+
}
|
|
872
|
+
updateTimeoutMs;
|
|
873
|
+
updateMinIntervalMs;
|
|
874
|
+
slowLog;
|
|
875
|
+
configuredQmdPath;
|
|
876
|
+
qmdSupportedVersion;
|
|
877
|
+
qmdAutoUpgradeEnabled;
|
|
878
|
+
qmdAutoUpgradeCheckIntervalMs;
|
|
879
|
+
qmdChunkStrategy;
|
|
880
|
+
qmdCandidateLimit;
|
|
881
|
+
qmdQueryRerankEnabled;
|
|
882
|
+
qmdIndexName;
|
|
883
|
+
qmdRuntimeEnv;
|
|
884
|
+
qmdPathSource = "auto-path";
|
|
885
|
+
cliVersion = null;
|
|
886
|
+
lastCliProbeError = null;
|
|
887
|
+
qmdCapabilities = resolveQmdCapabilities(null);
|
|
888
|
+
// Daemon mode fields
|
|
889
|
+
daemonSession = null;
|
|
890
|
+
daemonAvailable = false;
|
|
891
|
+
daemonSessionPath = null;
|
|
892
|
+
lastDaemonCheckAtMs = 0;
|
|
893
|
+
daemonEnabled;
|
|
894
|
+
daemonRecheckIntervalMs;
|
|
895
|
+
/** Consecutive transient daemon failures before invalidating the session. */
|
|
896
|
+
daemonTransientFailures = 0;
|
|
897
|
+
static DAEMON_MAX_TRANSIENT_FAILURES = 3;
|
|
898
|
+
qmdPath = "qmd";
|
|
899
|
+
buildRuntimeEnv(opts) {
|
|
900
|
+
const env = {};
|
|
901
|
+
if (opts?.qmdForceCpu === true) {
|
|
902
|
+
env.QMD_FORCE_CPU = "1";
|
|
903
|
+
}
|
|
904
|
+
if (opts?.qmdGpuBackend) {
|
|
905
|
+
env.QMD_LLAMA_GPU = opts.qmdGpuBackend;
|
|
906
|
+
}
|
|
907
|
+
if (typeof opts?.qmdEmbedParallelism === "number" && Number.isFinite(opts.qmdEmbedParallelism) && opts.qmdEmbedParallelism > 0) {
|
|
908
|
+
env.QMD_EMBED_PARALLELISM = String(Math.min(8, Math.max(1, Math.floor(opts.qmdEmbedParallelism))));
|
|
909
|
+
}
|
|
910
|
+
if (opts?.qmdEmbedModel?.trim()) {
|
|
911
|
+
env.QMD_EMBED_MODEL = opts.qmdEmbedModel.trim();
|
|
912
|
+
}
|
|
913
|
+
if (opts?.qmdRerankModel?.trim()) {
|
|
914
|
+
env.QMD_RERANK_MODEL = opts.qmdRerankModel.trim();
|
|
915
|
+
}
|
|
916
|
+
if (opts?.qmdGenerateModel?.trim()) {
|
|
917
|
+
env.QMD_GENERATE_MODEL = opts.qmdGenerateModel.trim();
|
|
918
|
+
}
|
|
919
|
+
return env;
|
|
920
|
+
}
|
|
921
|
+
async probe() {
|
|
922
|
+
const cliOk = await this.probeCli();
|
|
923
|
+
if (this.daemonEnabled) {
|
|
924
|
+
await this.probeDaemon();
|
|
925
|
+
}
|
|
926
|
+
return cliOk || this.daemonAvailable;
|
|
927
|
+
}
|
|
928
|
+
async probeDaemon() {
|
|
929
|
+
this.lastDaemonCheckAtMs = Date.now();
|
|
930
|
+
const normalizedPath = this.qmdPath.trim() || "qmd";
|
|
931
|
+
const daemonIndexName = this.qmdIndexName && this.qmdCapabilities.mcpIndexSelection ? this.qmdIndexName : void 0;
|
|
932
|
+
const daemonSessionPath = `${normalizedPath}\0${daemonIndexName ?? ""}\0${this.cliVersion ?? ""}`;
|
|
933
|
+
if (!this.daemonSession || this.daemonSessionPath !== daemonSessionPath) {
|
|
934
|
+
await releaseSharedDaemonSession(this.daemonSession);
|
|
935
|
+
this.daemonSession = retainSharedDaemonSession(
|
|
936
|
+
normalizedPath,
|
|
937
|
+
this.qmdRuntimeEnv,
|
|
938
|
+
daemonIndexName,
|
|
939
|
+
this.cliVersion
|
|
940
|
+
);
|
|
941
|
+
this.daemonSessionPath = daemonSessionPath;
|
|
942
|
+
}
|
|
943
|
+
try {
|
|
944
|
+
const PROBE_QUICK_TIMEOUT_MS = 3e3;
|
|
945
|
+
const ok = await Promise.race([
|
|
946
|
+
this.daemonSession.start(),
|
|
947
|
+
new Promise((resolve) => setTimeout(() => resolve(false), PROBE_QUICK_TIMEOUT_MS))
|
|
948
|
+
]);
|
|
949
|
+
if (!ok) {
|
|
950
|
+
const loading = this.daemonSession.isLoading();
|
|
951
|
+
log.debug(`QMD daemon: stdio session not ready within ${PROBE_QUICK_TIMEOUT_MS}ms probe window${loading ? " (still loading)" : ""}`);
|
|
952
|
+
this.daemonAvailable = false;
|
|
953
|
+
return false;
|
|
954
|
+
}
|
|
955
|
+
log.info(`QMD daemon: stdio session active (collection=${this.collection})`);
|
|
956
|
+
this.daemonAvailable = true;
|
|
957
|
+
this.daemonTransientFailures = 0;
|
|
958
|
+
return true;
|
|
959
|
+
} catch (err) {
|
|
960
|
+
log.debug(`QMD daemon: probe failed: ${err}`);
|
|
961
|
+
this.daemonAvailable = false;
|
|
962
|
+
return false;
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
async probeCli() {
|
|
966
|
+
const markProbeFailure = (err) => {
|
|
967
|
+
this.lastCliProbeError = err instanceof Error ? err.message : String(err);
|
|
968
|
+
};
|
|
969
|
+
const recordProbeSuccess = async (result, qmdPath, source) => {
|
|
970
|
+
this.available = true;
|
|
971
|
+
this.qmdPath = qmdPath;
|
|
972
|
+
this.qmdPathSource = source;
|
|
973
|
+
this.cliVersion = parseQmdVersionOutput(result.stdout, result.stderr);
|
|
974
|
+
this.qmdCapabilities = resolveQmdCapabilities(this.cliVersion);
|
|
975
|
+
this.lastCliProbeError = null;
|
|
976
|
+
await this.maybeAutoUpgradeQmd();
|
|
977
|
+
};
|
|
978
|
+
if (this.configuredQmdPath) {
|
|
979
|
+
try {
|
|
980
|
+
const result = await runQmd(["--version"], QMD_PROBE_TIMEOUT_MS, this.configuredQmdPath, void 0, this.qmdRuntimeEnv);
|
|
981
|
+
await recordProbeSuccess(result, this.configuredQmdPath, "configured");
|
|
982
|
+
return true;
|
|
983
|
+
} catch (err) {
|
|
984
|
+
markProbeFailure(err);
|
|
985
|
+
this.logCliProbeWarning(
|
|
986
|
+
`QMD: configured qmdPath failed (${this.configuredQmdPath}): ${this.lastCliProbeError}`
|
|
987
|
+
);
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
try {
|
|
991
|
+
const result = await runQmd(["--version"], QMD_PROBE_TIMEOUT_MS, "qmd", void 0, this.qmdRuntimeEnv);
|
|
992
|
+
await recordProbeSuccess(result, "qmd", "auto-path");
|
|
993
|
+
return true;
|
|
994
|
+
} catch (err) {
|
|
995
|
+
markProbeFailure(err);
|
|
996
|
+
for (const fallbackPath of QMD_FALLBACK_PATHS) {
|
|
997
|
+
try {
|
|
998
|
+
const result = await runQmd(["--version"], QMD_PROBE_TIMEOUT_MS, fallbackPath, void 0, this.qmdRuntimeEnv);
|
|
999
|
+
await recordProbeSuccess(result, fallbackPath, "auto-fallback");
|
|
1000
|
+
log.info(`QMD: found at ${fallbackPath}`);
|
|
1001
|
+
return true;
|
|
1002
|
+
} catch (fallbackErr) {
|
|
1003
|
+
markProbeFailure(fallbackErr);
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
this.available = false;
|
|
1007
|
+
return false;
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
async maybeAutoUpgradeQmd() {
|
|
1011
|
+
if (!this.qmdAutoUpgradeEnabled) return;
|
|
1012
|
+
const state = getGlobalQmdState();
|
|
1013
|
+
const targetKey = this.autoUpgradeTargetKey();
|
|
1014
|
+
const now = Date.now();
|
|
1015
|
+
const lastCheckAtMs = state.lastAutoUpgradeCheckByTargetMs[targetKey];
|
|
1016
|
+
if (Number.isFinite(lastCheckAtMs) && now - lastCheckAtMs < this.qmdAutoUpgradeCheckIntervalMs) {
|
|
1017
|
+
return;
|
|
1018
|
+
}
|
|
1019
|
+
state.lastAutoUpgradeCheckByTargetMs[targetKey] = now;
|
|
1020
|
+
state.lastAutoUpgradeCheckAtMs = now;
|
|
1021
|
+
const installed = parseQmdVersion(this.cliVersion);
|
|
1022
|
+
const supported = parseQmdVersion(this.qmdSupportedVersion);
|
|
1023
|
+
if (!installed || !supported) {
|
|
1024
|
+
const status = `skipped: unable to parse installed=${this.cliVersion ?? "unknown"} supported=${this.qmdSupportedVersion}`;
|
|
1025
|
+
recordAutoUpgradeStatus(state, targetKey, status);
|
|
1026
|
+
log.warn(`QMD auto-upgrade skipped: ${status}`);
|
|
1027
|
+
return;
|
|
1028
|
+
}
|
|
1029
|
+
if (compareQmdVersions(installed, supported) >= 0) {
|
|
1030
|
+
recordAutoUpgradeStatus(
|
|
1031
|
+
state,
|
|
1032
|
+
targetKey,
|
|
1033
|
+
`current: installed=${qmdVersionToString(installed)} supported=${qmdVersionToString(supported)}`
|
|
1034
|
+
);
|
|
1035
|
+
return;
|
|
1036
|
+
}
|
|
1037
|
+
if (this.qmdPathSource === "configured") {
|
|
1038
|
+
const status = `skipped: configured qmdPath=${this.qmdPath}`;
|
|
1039
|
+
recordAutoUpgradeStatus(state, targetKey, status);
|
|
1040
|
+
log.warn(
|
|
1041
|
+
`QMD auto-upgrade skipped because qmdPath is explicitly configured (${this.qmdPath}); install ${QMD_PACKAGE_NAME}@${this.qmdSupportedVersion} manually for that path.`
|
|
1042
|
+
);
|
|
1043
|
+
return;
|
|
1044
|
+
}
|
|
1045
|
+
const packageSpec = `${QMD_PACKAGE_NAME}@${this.qmdSupportedVersion}`;
|
|
1046
|
+
try {
|
|
1047
|
+
log.warn(
|
|
1048
|
+
`QMD auto-upgrade: installed=${qmdVersionToString(installed)} supported=${qmdVersionToString(supported)}; running npm install -g ${packageSpec}`
|
|
1049
|
+
);
|
|
1050
|
+
await runProcessCommand(
|
|
1051
|
+
"npm",
|
|
1052
|
+
["install", "-g", packageSpec],
|
|
1053
|
+
QMD_AUTO_UPGRADE_TIMEOUT_MS
|
|
1054
|
+
);
|
|
1055
|
+
const postInstall = await this.probePostInstallQmdVersion(supported);
|
|
1056
|
+
this.qmdPath = postInstall.qmdPath;
|
|
1057
|
+
this.qmdPathSource = postInstall.source;
|
|
1058
|
+
this.cliVersion = postInstall.version;
|
|
1059
|
+
this.qmdCapabilities = resolveQmdCapabilities(this.cliVersion);
|
|
1060
|
+
await releaseSharedDaemonSession(this.daemonSession);
|
|
1061
|
+
this.daemonSession = null;
|
|
1062
|
+
this.daemonSessionPath = null;
|
|
1063
|
+
this.daemonAvailable = false;
|
|
1064
|
+
this.daemonTransientFailures = 0;
|
|
1065
|
+
const upgraded = parseQmdVersion(this.cliVersion);
|
|
1066
|
+
if (!upgraded || compareQmdVersions(upgraded, supported) < 0) {
|
|
1067
|
+
const status = `failed: post-install version=${this.cliVersion ?? "unknown"} target=${this.qmdSupportedVersion}`;
|
|
1068
|
+
recordAutoUpgradeStatus(state, targetKey, status);
|
|
1069
|
+
log.warn(`QMD auto-upgrade did not reach supported version: ${status}`);
|
|
1070
|
+
return;
|
|
1071
|
+
}
|
|
1072
|
+
recordAutoUpgradeStatus(
|
|
1073
|
+
state,
|
|
1074
|
+
targetKey,
|
|
1075
|
+
`upgraded: installed=${this.cliVersion ?? "unknown"} target=${this.qmdSupportedVersion}`
|
|
1076
|
+
);
|
|
1077
|
+
} catch (err) {
|
|
1078
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1079
|
+
recordAutoUpgradeStatus(state, targetKey, `failed: ${msg}`);
|
|
1080
|
+
log.warn(`QMD auto-upgrade failed: ${msg}`);
|
|
1081
|
+
}
|
|
1082
|
+
}
|
|
1083
|
+
async probePostInstallQmdVersion(supported) {
|
|
1084
|
+
let lastErr;
|
|
1085
|
+
let lastResult = null;
|
|
1086
|
+
for (const candidate of getQmdPostInstallProbeTargets(this.qmdPath, this.qmdPathSource)) {
|
|
1087
|
+
try {
|
|
1088
|
+
const result = await runQmd(
|
|
1089
|
+
["--version"],
|
|
1090
|
+
QMD_PROBE_TIMEOUT_MS,
|
|
1091
|
+
candidate.qmdPath,
|
|
1092
|
+
void 0,
|
|
1093
|
+
this.qmdRuntimeEnv
|
|
1094
|
+
);
|
|
1095
|
+
const postInstall = {
|
|
1096
|
+
...candidate,
|
|
1097
|
+
version: parseQmdVersionOutput(result.stdout, result.stderr)
|
|
1098
|
+
};
|
|
1099
|
+
lastResult = postInstall;
|
|
1100
|
+
const parsed = parseQmdVersion(postInstall.version);
|
|
1101
|
+
if (parsed && compareQmdVersions(parsed, supported) >= 0) {
|
|
1102
|
+
return postInstall;
|
|
1103
|
+
}
|
|
1104
|
+
} catch (err) {
|
|
1105
|
+
lastErr = err;
|
|
1106
|
+
}
|
|
1107
|
+
}
|
|
1108
|
+
if (lastResult) return lastResult;
|
|
1109
|
+
throw lastErr instanceof Error ? lastErr : new Error(String(lastErr));
|
|
1110
|
+
}
|
|
1111
|
+
autoUpgradeTargetKey() {
|
|
1112
|
+
return JSON.stringify({
|
|
1113
|
+
path: this.qmdPath.trim() || "qmd",
|
|
1114
|
+
source: this.qmdPathSource,
|
|
1115
|
+
index: this.qmdIndexName ?? "",
|
|
1116
|
+
supportedVersion: this.qmdSupportedVersion,
|
|
1117
|
+
runtimeEnv: stableRuntimeEnvKey(this.qmdRuntimeEnv)
|
|
1118
|
+
});
|
|
1119
|
+
}
|
|
1120
|
+
logCliProbeWarning(message) {
|
|
1121
|
+
const state = getGlobalQmdState();
|
|
1122
|
+
const now = Date.now();
|
|
1123
|
+
const canWarn = state.lastCliWarnAtMs === null || now - state.lastCliWarnAtMs >= QMD_CLI_WARN_THROTTLE_MS;
|
|
1124
|
+
if (!canWarn) {
|
|
1125
|
+
log.debug(message);
|
|
1126
|
+
return;
|
|
1127
|
+
}
|
|
1128
|
+
state.lastCliWarnAtMs = now;
|
|
1129
|
+
if (this.daemonAvailable) {
|
|
1130
|
+
log.debug(message);
|
|
1131
|
+
return;
|
|
1132
|
+
}
|
|
1133
|
+
log.warn(message);
|
|
1134
|
+
}
|
|
1135
|
+
/** Re-probe daemon if it was down and recheck interval has elapsed. */
|
|
1136
|
+
async maybeProbeDaemon() {
|
|
1137
|
+
if (!this.daemonEnabled) return;
|
|
1138
|
+
if (this.daemonAvailable && this.daemonSession?.isActive()) return;
|
|
1139
|
+
if (this.daemonAvailable === false) {
|
|
1140
|
+
const elapsed = Date.now() - this.lastDaemonCheckAtMs;
|
|
1141
|
+
if (elapsed < this.daemonRecheckIntervalMs) return;
|
|
1142
|
+
}
|
|
1143
|
+
this.daemonAvailable = false;
|
|
1144
|
+
await this.probeDaemon();
|
|
1145
|
+
}
|
|
1146
|
+
isAvailable() {
|
|
1147
|
+
return this.available === true || this.daemonAvailable;
|
|
1148
|
+
}
|
|
1149
|
+
/** Debug string for troubleshooting availability issues. */
|
|
1150
|
+
debugStatus() {
|
|
1151
|
+
const cliPath = this.available ? this.qmdPath : this.configuredQmdPath ?? "unavailable";
|
|
1152
|
+
const cliVersion = this.cliVersion ?? "unknown";
|
|
1153
|
+
const status = this.getVersionStatus();
|
|
1154
|
+
const enabledFeatures = Object.entries(status.capabilities).filter(([key, value]) => key !== "version" && key !== "parsedVersion" && value === true).map(([key]) => key).join(",");
|
|
1155
|
+
const globalState = getGlobalQmdState();
|
|
1156
|
+
const autoUpgradeStatus = globalState.lastAutoUpgradeStatusByTarget[this.autoUpgradeTargetKey()] ?? globalState.lastAutoUpgradeStatus;
|
|
1157
|
+
const probeError = this.lastCliProbeError ? ` cliProbeError=${this.lastCliProbeError}` : "";
|
|
1158
|
+
return `cli=${this.available} daemon=${this.daemonAvailable} session=${!!this.daemonSession} cliPath=${cliPath} cliPathSource=${this.qmdPathSource} cliVersion=${cliVersion} supportedVersion=${status.supportedVersion} upgradeAvailable=${status.upgradeAvailable} qmdFeatures=${enabledFeatures || "none"}${autoUpgradeStatus ? ` autoUpgrade=${autoUpgradeStatus}` : ""}${probeError}`;
|
|
1159
|
+
}
|
|
1160
|
+
getVersionStatus() {
|
|
1161
|
+
const installed = parseQmdVersion(this.cliVersion);
|
|
1162
|
+
const supported = parseQmdVersion(this.qmdSupportedVersion) ?? parseQmdVersion(QMD_SUPPORTED_VERSION);
|
|
1163
|
+
const cmp = compareQmdVersions(installed, supported);
|
|
1164
|
+
return {
|
|
1165
|
+
installedVersion: this.cliVersion,
|
|
1166
|
+
supportedVersion: qmdVersionToString(supported),
|
|
1167
|
+
supported: installed !== null && cmp >= 0,
|
|
1168
|
+
newerThanSupported: installed !== null && cmp > 0,
|
|
1169
|
+
upgradeAvailable: installed !== null && cmp < 0,
|
|
1170
|
+
capabilities: this.qmdCapabilities
|
|
1171
|
+
};
|
|
1172
|
+
}
|
|
1173
|
+
async doctor() {
|
|
1174
|
+
if (!this.isAvailable()) {
|
|
1175
|
+
return { available: false, skipped: "qmd unavailable" };
|
|
1176
|
+
}
|
|
1177
|
+
if (!this.qmdCapabilities.doctor) {
|
|
1178
|
+
return {
|
|
1179
|
+
available: false,
|
|
1180
|
+
skipped: `qmd doctor requires qmd >=2.5.0; installed ${this.cliVersion ?? "unknown"}`
|
|
1181
|
+
};
|
|
1182
|
+
}
|
|
1183
|
+
try {
|
|
1184
|
+
const { stdout } = await this.runQmdCommand(["doctor", "--json"], QMD_TIMEOUT_MS);
|
|
1185
|
+
const trimmed = stdout.trim();
|
|
1186
|
+
if (!trimmed) return { available: true, report: null };
|
|
1187
|
+
try {
|
|
1188
|
+
return { available: true, report: JSON.parse(trimmed) };
|
|
1189
|
+
} catch {
|
|
1190
|
+
return { available: true, raw: trimmed };
|
|
1191
|
+
}
|
|
1192
|
+
} catch (err) {
|
|
1193
|
+
return {
|
|
1194
|
+
available: false,
|
|
1195
|
+
error: err instanceof Error ? err.message : String(err)
|
|
1196
|
+
};
|
|
1197
|
+
}
|
|
1198
|
+
}
|
|
1199
|
+
isDaemonMode() {
|
|
1200
|
+
return this.daemonAvailable;
|
|
1201
|
+
}
|
|
1202
|
+
async dispose() {
|
|
1203
|
+
await releaseSharedDaemonSession(this.daemonSession);
|
|
1204
|
+
this.daemonSession = null;
|
|
1205
|
+
this.daemonSessionPath = null;
|
|
1206
|
+
this.daemonAvailable = false;
|
|
1207
|
+
this.daemonTransientFailures = 0;
|
|
1208
|
+
}
|
|
1209
|
+
/**
|
|
1210
|
+
* Record a daemon search success — resets the transient failure counter.
|
|
1211
|
+
*/
|
|
1212
|
+
recordDaemonSuccess() {
|
|
1213
|
+
this.daemonTransientFailures = 0;
|
|
1214
|
+
}
|
|
1215
|
+
/**
|
|
1216
|
+
* Handle a non-timeout, non-cancellation daemon error.
|
|
1217
|
+
* Tolerates up to DAEMON_MAX_TRANSIENT_FAILURES consecutive failures
|
|
1218
|
+
* before invalidating the session. This prevents a single transient
|
|
1219
|
+
* error from pushing all concurrent searches through the subprocess
|
|
1220
|
+
* mutex for the full recheck interval.
|
|
1221
|
+
*/
|
|
1222
|
+
handleDaemonTransientError(label, err, durationMs) {
|
|
1223
|
+
if (!this.daemonAvailable) {
|
|
1224
|
+
log.debug(`QMD daemon ${label} failed after ${durationMs}ms (daemon already unavailable, ignoring): ${err}`);
|
|
1225
|
+
return;
|
|
1226
|
+
}
|
|
1227
|
+
this.daemonTransientFailures += 1;
|
|
1228
|
+
if (this.daemonTransientFailures >= _QmdClient.DAEMON_MAX_TRANSIENT_FAILURES) {
|
|
1229
|
+
log.debug(`QMD daemon ${label} failed after ${durationMs}ms (${this.daemonTransientFailures} consecutive failures, invalidating): ${err}`);
|
|
1230
|
+
this.daemonSession?.invalidate();
|
|
1231
|
+
this.daemonAvailable = false;
|
|
1232
|
+
this.daemonTransientFailures = 0;
|
|
1233
|
+
} else {
|
|
1234
|
+
log.debug(`QMD daemon ${label} failed after ${durationMs}ms (transient ${this.daemonTransientFailures}/${_QmdClient.DAEMON_MAX_TRANSIENT_FAILURES}): ${err}`);
|
|
1235
|
+
}
|
|
1236
|
+
}
|
|
1237
|
+
async runQmdCommand(args, timeoutMs, signal) {
|
|
1238
|
+
const commandArgs = this.qmdIndexName && this.qmdCapabilities.mcpIndexSelection ? ["--index", this.qmdIndexName, ...args] : args;
|
|
1239
|
+
return runQmd(commandArgs, timeoutMs, this.qmdPath, signal, this.qmdRuntimeEnv);
|
|
1240
|
+
}
|
|
1241
|
+
supportsIntentHints() {
|
|
1242
|
+
return this.qmdCapabilities.intentHints;
|
|
1243
|
+
}
|
|
1244
|
+
supportsExplainTraces() {
|
|
1245
|
+
return this.qmdCapabilities.explainTraces;
|
|
1246
|
+
}
|
|
1247
|
+
supportsCandidateLimit() {
|
|
1248
|
+
return this.qmdCapabilities.candidateLimit;
|
|
1249
|
+
}
|
|
1250
|
+
supportsRerankToggle() {
|
|
1251
|
+
return this.qmdCapabilities.queryRerankToggle;
|
|
1252
|
+
}
|
|
1253
|
+
supportsChunkStrategy() {
|
|
1254
|
+
return this.qmdCapabilities.chunkStrategy;
|
|
1255
|
+
}
|
|
1256
|
+
/**
|
|
1257
|
+
* QMD v2 (>= 2.0.0) uses a new MCP tool API:
|
|
1258
|
+
* - `search` and `vsearch` tools removed; only `query` tool exists
|
|
1259
|
+
* - `query` accepts `{ searches: [{ type, query }], collections?: string[] }`
|
|
1260
|
+
* instead of `{ query: string, collection?: string }`
|
|
1261
|
+
* - `collection` (singular) → `collections` (plural array)
|
|
1262
|
+
*/
|
|
1263
|
+
isQmdV2() {
|
|
1264
|
+
return this.qmdCapabilities.v2McpQueryTool;
|
|
1265
|
+
}
|
|
1266
|
+
resolveSearchOptions(options) {
|
|
1267
|
+
const normalized = normalizeSearchOptions(options);
|
|
1268
|
+
const withDefaults = { ...normalized ?? {} };
|
|
1269
|
+
if (this.qmdCandidateLimit !== void 0 && withDefaults.candidateLimit === void 0) {
|
|
1270
|
+
withDefaults.candidateLimit = this.qmdCandidateLimit;
|
|
1271
|
+
}
|
|
1272
|
+
if (!this.qmdQueryRerankEnabled && withDefaults.rerank === void 0) {
|
|
1273
|
+
withDefaults.rerank = false;
|
|
1274
|
+
}
|
|
1275
|
+
if (this.qmdChunkStrategy && withDefaults.chunkStrategy === void 0) {
|
|
1276
|
+
withDefaults.chunkStrategy = this.qmdChunkStrategy;
|
|
1277
|
+
}
|
|
1278
|
+
const resolved = {};
|
|
1279
|
+
if (withDefaults.intent && this.supportsIntentHints()) {
|
|
1280
|
+
resolved.intent = withDefaults.intent;
|
|
1281
|
+
}
|
|
1282
|
+
if (withDefaults.explain === true && this.supportsExplainTraces()) {
|
|
1283
|
+
resolved.explain = true;
|
|
1284
|
+
}
|
|
1285
|
+
if (typeof withDefaults.candidateLimit === "number" && withDefaults.candidateLimit > 0 && this.supportsCandidateLimit()) {
|
|
1286
|
+
resolved.candidateLimit = Math.floor(withDefaults.candidateLimit);
|
|
1287
|
+
}
|
|
1288
|
+
if (withDefaults.rerank === false && this.supportsRerankToggle()) {
|
|
1289
|
+
resolved.rerank = false;
|
|
1290
|
+
}
|
|
1291
|
+
if (withDefaults.chunkStrategy && this.supportsChunkStrategy()) {
|
|
1292
|
+
resolved.chunkStrategy = withDefaults.chunkStrategy;
|
|
1293
|
+
}
|
|
1294
|
+
if (this.qmdCapabilities.structuredSearches) {
|
|
1295
|
+
const structuredSearches = normalizeStructuredSearches(withDefaults.structuredSearches);
|
|
1296
|
+
if (structuredSearches.length > 0) {
|
|
1297
|
+
resolved.structuredSearches = structuredSearches;
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1300
|
+
return Object.keys(resolved).length > 0 ? resolved : void 0;
|
|
1301
|
+
}
|
|
1302
|
+
resolveSupportedSearchOptions(options) {
|
|
1303
|
+
return this.resolveSearchOptions(options);
|
|
1304
|
+
}
|
|
1305
|
+
addResolvedSearchOptionsToArgs(args, options) {
|
|
1306
|
+
if (options?.intent) {
|
|
1307
|
+
args.push("--intent", options.intent);
|
|
1308
|
+
}
|
|
1309
|
+
if (options?.explain === true) {
|
|
1310
|
+
args.push("--explain");
|
|
1311
|
+
}
|
|
1312
|
+
if (typeof options?.candidateLimit === "number" && options.candidateLimit > 0) {
|
|
1313
|
+
args.push("--candidate-limit", String(Math.floor(options.candidateLimit)));
|
|
1314
|
+
}
|
|
1315
|
+
if (options?.rerank === false) {
|
|
1316
|
+
args.push("--no-rerank");
|
|
1317
|
+
}
|
|
1318
|
+
if (options?.chunkStrategy) {
|
|
1319
|
+
args.push("--chunk-strategy", options.chunkStrategy);
|
|
1320
|
+
}
|
|
1321
|
+
}
|
|
1322
|
+
addResolvedSearchOptionsToMcpArgs(args, options) {
|
|
1323
|
+
if (options?.intent) {
|
|
1324
|
+
args.intent = options.intent;
|
|
1325
|
+
}
|
|
1326
|
+
if (options?.explain === true) {
|
|
1327
|
+
args.explain = true;
|
|
1328
|
+
}
|
|
1329
|
+
if (typeof options?.candidateLimit === "number" && options.candidateLimit > 0) {
|
|
1330
|
+
args.candidateLimit = Math.floor(options.candidateLimit);
|
|
1331
|
+
}
|
|
1332
|
+
if (options?.rerank === false) {
|
|
1333
|
+
args.rerank = false;
|
|
1334
|
+
}
|
|
1335
|
+
}
|
|
1336
|
+
buildEmbedArgs(collection, force = false) {
|
|
1337
|
+
const args = ["embed"];
|
|
1338
|
+
if (force) args.push("-f");
|
|
1339
|
+
args.push("-c", collection);
|
|
1340
|
+
if (this.qmdChunkStrategy && this.qmdCapabilities.chunkStrategy) {
|
|
1341
|
+
args.push("--chunk-strategy", this.qmdChunkStrategy);
|
|
1342
|
+
}
|
|
1343
|
+
return args;
|
|
1344
|
+
}
|
|
1345
|
+
async search(query, collection, maxResults, options, execution) {
|
|
1346
|
+
if (!this.isAvailable()) return [];
|
|
1347
|
+
const trimmed = query.trim();
|
|
1348
|
+
if (!trimmed) return [];
|
|
1349
|
+
const col = collection ?? this.collection;
|
|
1350
|
+
const n = maxResults ?? this.maxResults;
|
|
1351
|
+
const searchOptions = this.resolveSearchOptions(options);
|
|
1352
|
+
const optionsFingerprint = searchOptions ? JSON.stringify(searchOptions) : "";
|
|
1353
|
+
const cacheKey = createHash("sha256").update(`${col}:${n}:${optionsFingerprint}:${trimmed}`).digest("hex");
|
|
1354
|
+
const cached = getCachedQmdSearch(cacheKey);
|
|
1355
|
+
if (cached) {
|
|
1356
|
+
log.debug(`QMD search cache hit (${cached.length} results)`);
|
|
1357
|
+
return cached;
|
|
1358
|
+
}
|
|
1359
|
+
await this.maybeProbeDaemon();
|
|
1360
|
+
if (this.daemonAvailable) {
|
|
1361
|
+
let results;
|
|
1362
|
+
try {
|
|
1363
|
+
results = await this.searchViaDaemon(trimmed, col, n, searchOptions, execution?.signal);
|
|
1364
|
+
} catch (err) {
|
|
1365
|
+
if (isCallerCancellation(err, execution?.signal)) {
|
|
1366
|
+
throw isAbortError(err) ? err : abortError("QMD daemon search aborted");
|
|
1367
|
+
}
|
|
1368
|
+
throw err;
|
|
1369
|
+
}
|
|
1370
|
+
if (results !== null) {
|
|
1371
|
+
if (results.length === 0) {
|
|
1372
|
+
log.debug("QMD daemon search returned 0 results; skipping subprocess");
|
|
1373
|
+
}
|
|
1374
|
+
setCachedQmdSearch(cacheKey, results);
|
|
1375
|
+
return results;
|
|
1376
|
+
}
|
|
1377
|
+
log.debug("QMD daemon search timed out/failed; skipping subprocess (daemon-only mode)");
|
|
1378
|
+
return [];
|
|
1379
|
+
}
|
|
1380
|
+
if (this.daemonSession?.isLoading()) {
|
|
1381
|
+
log.debug("QMD search: daemon loading, skipping subprocess");
|
|
1382
|
+
return [];
|
|
1383
|
+
}
|
|
1384
|
+
const subprocessResults = await this.searchViaSubprocess(trimmed, col, n, searchOptions, execution?.signal);
|
|
1385
|
+
setCachedQmdSearch(cacheKey, subprocessResults);
|
|
1386
|
+
return subprocessResults;
|
|
1387
|
+
}
|
|
1388
|
+
async searchGlobal(query, maxResults, execution) {
|
|
1389
|
+
if (!this.isAvailable()) return [];
|
|
1390
|
+
const trimmed = query.trim();
|
|
1391
|
+
if (!trimmed) return [];
|
|
1392
|
+
const n = maxResults ?? 6;
|
|
1393
|
+
const searchOptions = this.resolveSearchOptions();
|
|
1394
|
+
await this.maybeProbeDaemon();
|
|
1395
|
+
if (this.daemonAvailable) {
|
|
1396
|
+
let results;
|
|
1397
|
+
try {
|
|
1398
|
+
results = await this.searchViaDaemon(trimmed, void 0, n, searchOptions, execution?.signal);
|
|
1399
|
+
} catch (err) {
|
|
1400
|
+
if (isCallerCancellation(err, execution?.signal)) {
|
|
1401
|
+
throw isAbortError(err) ? err : abortError("QMD daemon global search aborted");
|
|
1402
|
+
}
|
|
1403
|
+
throw err;
|
|
1404
|
+
}
|
|
1405
|
+
if (results !== null) {
|
|
1406
|
+
if (results.length === 0) {
|
|
1407
|
+
log.debug("QMD daemon global search returned 0 results; skipping subprocess");
|
|
1408
|
+
}
|
|
1409
|
+
return results;
|
|
1410
|
+
}
|
|
1411
|
+
log.debug("QMD daemon global search timed out/failed; skipping subprocess (daemon-only mode)");
|
|
1412
|
+
return [];
|
|
1413
|
+
}
|
|
1414
|
+
if (this.daemonSession?.isLoading()) {
|
|
1415
|
+
log.debug("QMD searchGlobal: daemon loading, skipping subprocess");
|
|
1416
|
+
return [];
|
|
1417
|
+
}
|
|
1418
|
+
return this.searchGlobalViaSubprocess(trimmed, n, searchOptions, execution?.signal);
|
|
1419
|
+
}
|
|
1420
|
+
/**
|
|
1421
|
+
* BM25 keyword search (fast, ~0.3s). Uses `qmd search`.
|
|
1422
|
+
*/
|
|
1423
|
+
async bm25Search(query, collection, maxResults, execution) {
|
|
1424
|
+
if (!this.isAvailable()) return [];
|
|
1425
|
+
const trimmed = query.trim();
|
|
1426
|
+
if (!trimmed) return [];
|
|
1427
|
+
const col = collection ?? this.collection;
|
|
1428
|
+
const n = maxResults ?? this.maxResults;
|
|
1429
|
+
await this.maybeProbeDaemon();
|
|
1430
|
+
if (this.daemonAvailable && this.daemonSession) {
|
|
1431
|
+
let results;
|
|
1432
|
+
try {
|
|
1433
|
+
results = await this.bm25SearchViaDaemon(trimmed, col, n, execution?.signal);
|
|
1434
|
+
} catch (err) {
|
|
1435
|
+
if (isCallerCancellation(err, execution?.signal)) {
|
|
1436
|
+
throw isAbortError(err) ? err : abortError("QMD daemon bm25 aborted");
|
|
1437
|
+
}
|
|
1438
|
+
throw err;
|
|
1439
|
+
}
|
|
1440
|
+
if (results !== null) {
|
|
1441
|
+
if (results.length === 0) {
|
|
1442
|
+
log.debug("QMD daemon bm25 returned 0 results; skipping subprocess");
|
|
1443
|
+
}
|
|
1444
|
+
return results;
|
|
1445
|
+
}
|
|
1446
|
+
log.debug("QMD daemon bm25 timed out/failed; skipping subprocess (daemon-only mode)");
|
|
1447
|
+
return [];
|
|
1448
|
+
}
|
|
1449
|
+
if (this.daemonSession?.isLoading()) {
|
|
1450
|
+
log.debug("QMD bm25: daemon loading, skipping subprocess");
|
|
1451
|
+
return [];
|
|
1452
|
+
}
|
|
1453
|
+
return this.bm25SearchViaSubprocess(trimmed, col, n, execution?.signal);
|
|
1454
|
+
}
|
|
1455
|
+
/**
|
|
1456
|
+
* Vector similarity search (~3-4s). Uses `qmd vsearch`.
|
|
1457
|
+
*/
|
|
1458
|
+
async vectorSearch(query, collection, maxResults, execution) {
|
|
1459
|
+
if (!this.isAvailable()) return [];
|
|
1460
|
+
const trimmed = query.trim();
|
|
1461
|
+
if (!trimmed) return [];
|
|
1462
|
+
const col = collection ?? this.collection;
|
|
1463
|
+
const n = maxResults ?? this.maxResults;
|
|
1464
|
+
await this.maybeProbeDaemon();
|
|
1465
|
+
if (this.daemonAvailable && this.daemonSession) {
|
|
1466
|
+
let results;
|
|
1467
|
+
try {
|
|
1468
|
+
results = await this.vsearchViaDaemon(trimmed, col, n, execution?.signal);
|
|
1469
|
+
} catch (err) {
|
|
1470
|
+
if (isCallerCancellation(err, execution?.signal)) {
|
|
1471
|
+
throw isAbortError(err) ? err : abortError("QMD daemon vsearch aborted");
|
|
1472
|
+
}
|
|
1473
|
+
throw err;
|
|
1474
|
+
}
|
|
1475
|
+
if (results !== null) {
|
|
1476
|
+
if (results.length === 0) {
|
|
1477
|
+
log.debug("QMD daemon vsearch returned 0 results; skipping subprocess");
|
|
1478
|
+
}
|
|
1479
|
+
return results;
|
|
1480
|
+
}
|
|
1481
|
+
log.debug("QMD daemon vsearch timed out/failed; skipping subprocess (daemon-only mode)");
|
|
1482
|
+
return [];
|
|
1483
|
+
}
|
|
1484
|
+
if (this.daemonSession?.isLoading()) {
|
|
1485
|
+
log.debug("QMD vsearch: daemon loading, skipping subprocess");
|
|
1486
|
+
return [];
|
|
1487
|
+
}
|
|
1488
|
+
return this.vsearchViaSubprocess(trimmed, col, n, execution?.signal);
|
|
1489
|
+
}
|
|
1490
|
+
/**
|
|
1491
|
+
* Hybrid search: runs BM25 + vector in parallel, merges/dedupes by path
|
|
1492
|
+
* keeping the best score and first non-empty snippet.
|
|
1493
|
+
*/
|
|
1494
|
+
async hybridSearch(query, collection, maxResults, execution) {
|
|
1495
|
+
const n = maxResults ?? this.maxResults;
|
|
1496
|
+
const trimmed = query.trim();
|
|
1497
|
+
if (!trimmed) return [];
|
|
1498
|
+
const [bm25Results, vectorResults] = await Promise.all([
|
|
1499
|
+
this.bm25Search(trimmed, collection, n, execution),
|
|
1500
|
+
this.vectorSearch(trimmed, collection, n, execution)
|
|
1501
|
+
]);
|
|
1502
|
+
const merged = /* @__PURE__ */ new Map();
|
|
1503
|
+
for (const r of [...bm25Results, ...vectorResults]) {
|
|
1504
|
+
const key = r.path || r.docid;
|
|
1505
|
+
const existing = merged.get(key);
|
|
1506
|
+
if (!existing || r.score > existing.score) {
|
|
1507
|
+
merged.set(key, {
|
|
1508
|
+
...r,
|
|
1509
|
+
snippet: r.snippet || existing?.snippet || ""
|
|
1510
|
+
});
|
|
1511
|
+
}
|
|
1512
|
+
}
|
|
1513
|
+
return [...merged.values()].sort((a, b) => b.score - a.score).slice(0, n);
|
|
1514
|
+
}
|
|
1515
|
+
async searchViaDaemon(query, collection, maxResults, options, signal) {
|
|
1516
|
+
if (!this.daemonSession || !this.daemonAvailable) return null;
|
|
1517
|
+
const startedAtMs = Date.now();
|
|
1518
|
+
const v2 = this.isQmdV2();
|
|
1519
|
+
try {
|
|
1520
|
+
let args;
|
|
1521
|
+
if (v2) {
|
|
1522
|
+
const searches = buildDefaultStructuredSearches(query, options);
|
|
1523
|
+
args = { searches, limit: maxResults };
|
|
1524
|
+
if (collection) {
|
|
1525
|
+
args.collections = [collection];
|
|
1526
|
+
}
|
|
1527
|
+
this.addResolvedSearchOptionsToMcpArgs(args, options);
|
|
1528
|
+
} else {
|
|
1529
|
+
args = { query, limit: maxResults };
|
|
1530
|
+
if (collection) {
|
|
1531
|
+
args.collection = collection;
|
|
1532
|
+
}
|
|
1533
|
+
this.addResolvedSearchOptionsToMcpArgs(args, options);
|
|
1534
|
+
}
|
|
1535
|
+
const result = await this.daemonSession.callTool("query", args, QMD_DAEMON_TIMEOUT_MS, signal);
|
|
1536
|
+
const durationMs = Date.now() - startedAtMs;
|
|
1537
|
+
if (this.slowLog?.enabled && durationMs >= this.slowLog.thresholdMs) {
|
|
1538
|
+
log.warn(
|
|
1539
|
+
`SLOW QMD daemon query: durationMs=${durationMs} collection=${collection ?? "global"} maxResults=${maxResults} queryChars=${query.length} v2=${v2}`
|
|
1540
|
+
);
|
|
1541
|
+
}
|
|
1542
|
+
const results = parseMcpSearchResult(result, "daemon");
|
|
1543
|
+
log.debug(`QMD daemon search: ${results.length} results in ${durationMs}ms (v2=${v2})`);
|
|
1544
|
+
this.recordDaemonSuccess();
|
|
1545
|
+
return results;
|
|
1546
|
+
} catch (err) {
|
|
1547
|
+
const durationMs = Date.now() - startedAtMs;
|
|
1548
|
+
if (isCallerCancellation(err, signal)) {
|
|
1549
|
+
log.debug(`QMD daemon search aborted/cancelled after ${durationMs}ms`);
|
|
1550
|
+
throw isAbortError(err) ? err : abortError("QMD daemon search aborted");
|
|
1551
|
+
}
|
|
1552
|
+
if (isDaemonTimeoutError(err)) {
|
|
1553
|
+
log.debug(`QMD daemon search timed out after ${durationMs}ms, falling back to subprocess`);
|
|
1554
|
+
return null;
|
|
1555
|
+
}
|
|
1556
|
+
this.handleDaemonTransientError("search", err, durationMs);
|
|
1557
|
+
return null;
|
|
1558
|
+
}
|
|
1559
|
+
}
|
|
1560
|
+
async bm25SearchViaDaemon(query, collection, maxResults, signal) {
|
|
1561
|
+
if (!this.daemonSession || !this.daemonAvailable) return null;
|
|
1562
|
+
const startedAtMs = Date.now();
|
|
1563
|
+
const v2 = this.isQmdV2();
|
|
1564
|
+
try {
|
|
1565
|
+
let result;
|
|
1566
|
+
if (v2) {
|
|
1567
|
+
result = await this.daemonSession.callTool(
|
|
1568
|
+
"query",
|
|
1569
|
+
{
|
|
1570
|
+
searches: [{ type: "lex", query }],
|
|
1571
|
+
collections: [collection],
|
|
1572
|
+
limit: maxResults
|
|
1573
|
+
},
|
|
1574
|
+
QMD_DAEMON_TIMEOUT_MS,
|
|
1575
|
+
signal
|
|
1576
|
+
);
|
|
1577
|
+
} else {
|
|
1578
|
+
result = await this.daemonSession.callTool(
|
|
1579
|
+
"search",
|
|
1580
|
+
{ query, limit: maxResults, collection },
|
|
1581
|
+
QMD_DAEMON_TIMEOUT_MS,
|
|
1582
|
+
signal
|
|
1583
|
+
);
|
|
1584
|
+
}
|
|
1585
|
+
const durationMs = Date.now() - startedAtMs;
|
|
1586
|
+
const results = parseMcpSearchResult(result);
|
|
1587
|
+
log.debug(`QMD daemon bm25: ${results.length} results in ${durationMs}ms (v2=${v2})`);
|
|
1588
|
+
this.recordDaemonSuccess();
|
|
1589
|
+
return results;
|
|
1590
|
+
} catch (err) {
|
|
1591
|
+
const durationMs = Date.now() - startedAtMs;
|
|
1592
|
+
if (isCallerCancellation(err, signal)) {
|
|
1593
|
+
log.debug(`QMD daemon bm25 aborted/cancelled after ${durationMs}ms`);
|
|
1594
|
+
throw isAbortError(err) ? err : abortError("QMD daemon bm25 aborted");
|
|
1595
|
+
}
|
|
1596
|
+
if (isDaemonTimeoutError(err)) {
|
|
1597
|
+
log.debug(`QMD daemon bm25 timed out after ${durationMs}ms, falling back to subprocess`);
|
|
1598
|
+
return null;
|
|
1599
|
+
}
|
|
1600
|
+
this.handleDaemonTransientError("bm25", err, durationMs);
|
|
1601
|
+
return null;
|
|
1602
|
+
}
|
|
1603
|
+
}
|
|
1604
|
+
async vsearchViaDaemon(query, collection, maxResults, signal) {
|
|
1605
|
+
if (!this.daemonSession || !this.daemonAvailable) return null;
|
|
1606
|
+
const startedAtMs = Date.now();
|
|
1607
|
+
const v2 = this.isQmdV2();
|
|
1608
|
+
try {
|
|
1609
|
+
let result;
|
|
1610
|
+
if (v2) {
|
|
1611
|
+
result = await this.daemonSession.callTool(
|
|
1612
|
+
"query",
|
|
1613
|
+
{
|
|
1614
|
+
searches: [{ type: "vec", query }],
|
|
1615
|
+
collections: [collection],
|
|
1616
|
+
limit: maxResults
|
|
1617
|
+
},
|
|
1618
|
+
QMD_DAEMON_TIMEOUT_MS,
|
|
1619
|
+
signal
|
|
1620
|
+
);
|
|
1621
|
+
} else {
|
|
1622
|
+
result = await this.daemonSession.callTool(
|
|
1623
|
+
"vsearch",
|
|
1624
|
+
{ query, limit: maxResults, collection },
|
|
1625
|
+
QMD_DAEMON_TIMEOUT_MS,
|
|
1626
|
+
signal
|
|
1627
|
+
);
|
|
1628
|
+
}
|
|
1629
|
+
const durationMs = Date.now() - startedAtMs;
|
|
1630
|
+
const results = parseMcpSearchResult(result);
|
|
1631
|
+
log.debug(`QMD daemon vsearch: ${results.length} results in ${durationMs}ms (v2=${v2})`);
|
|
1632
|
+
this.recordDaemonSuccess();
|
|
1633
|
+
return results;
|
|
1634
|
+
} catch (err) {
|
|
1635
|
+
const durationMs = Date.now() - startedAtMs;
|
|
1636
|
+
if (isCallerCancellation(err, signal)) {
|
|
1637
|
+
log.debug(`QMD daemon vsearch aborted/cancelled after ${durationMs}ms`);
|
|
1638
|
+
throw isAbortError(err) ? err : abortError("QMD daemon vsearch aborted");
|
|
1639
|
+
}
|
|
1640
|
+
if (isDaemonTimeoutError(err)) {
|
|
1641
|
+
log.debug(`QMD daemon vsearch timed out after ${durationMs}ms, falling back to subprocess`);
|
|
1642
|
+
return null;
|
|
1643
|
+
}
|
|
1644
|
+
this.handleDaemonTransientError("vsearch", err, durationMs);
|
|
1645
|
+
return null;
|
|
1646
|
+
}
|
|
1647
|
+
}
|
|
1648
|
+
async searchViaSubprocess(query, collection, maxResults, options, signal) {
|
|
1649
|
+
if (this.available === false) return [];
|
|
1650
|
+
const startedAtMs = Date.now();
|
|
1651
|
+
try {
|
|
1652
|
+
const args = ["query", query, "-c", collection, "--json", "-n", String(maxResults)];
|
|
1653
|
+
this.addResolvedSearchOptionsToArgs(args, options);
|
|
1654
|
+
const { stdout } = await this.runQmdCommand(args, QMD_TIMEOUT_MS, signal);
|
|
1655
|
+
const durationMs = Date.now() - startedAtMs;
|
|
1656
|
+
if (this.slowLog?.enabled && durationMs >= this.slowLog.thresholdMs) {
|
|
1657
|
+
log.warn(
|
|
1658
|
+
`SLOW QMD query: durationMs=${durationMs} collection=${collection} maxResults=${maxResults} queryChars=${query.length}`
|
|
1659
|
+
);
|
|
1660
|
+
}
|
|
1661
|
+
return parseQmdSearchStdout(stdout, "subprocess");
|
|
1662
|
+
} catch (err) {
|
|
1663
|
+
if (isCallerCancellation(err, signal)) {
|
|
1664
|
+
throw isAbortError(err) ? err : abortError("QMD subprocess search aborted");
|
|
1665
|
+
}
|
|
1666
|
+
log.debug(`QMD search failed: ${err}`);
|
|
1667
|
+
return [];
|
|
1668
|
+
}
|
|
1669
|
+
}
|
|
1670
|
+
async bm25SearchViaSubprocess(query, collection, maxResults, signal) {
|
|
1671
|
+
if (this.available === false) return [];
|
|
1672
|
+
const startedAtMs = Date.now();
|
|
1673
|
+
try {
|
|
1674
|
+
const { stdout } = await this.runQmdCommand(
|
|
1675
|
+
["search", query, "-c", collection, "--json", "-n", String(maxResults)],
|
|
1676
|
+
QMD_TIMEOUT_MS,
|
|
1677
|
+
signal
|
|
1678
|
+
);
|
|
1679
|
+
log.debug(`QMD bm25: ${Date.now() - startedAtMs}ms`);
|
|
1680
|
+
return parseQmdSearchStdout(stdout);
|
|
1681
|
+
} catch (err) {
|
|
1682
|
+
if (isCallerCancellation(err, signal)) {
|
|
1683
|
+
throw isAbortError(err) ? err : abortError("QMD subprocess bm25 aborted");
|
|
1684
|
+
}
|
|
1685
|
+
log.debug(`QMD bm25 search failed: ${err}`);
|
|
1686
|
+
return [];
|
|
1687
|
+
}
|
|
1688
|
+
}
|
|
1689
|
+
async vsearchViaSubprocess(query, collection, maxResults, signal) {
|
|
1690
|
+
if (this.available === false) return [];
|
|
1691
|
+
const startedAtMs = Date.now();
|
|
1692
|
+
try {
|
|
1693
|
+
const { stdout } = await this.runQmdCommand(
|
|
1694
|
+
["vsearch", query, "-c", collection, "--json", "-n", String(maxResults)],
|
|
1695
|
+
QMD_TIMEOUT_MS,
|
|
1696
|
+
signal
|
|
1697
|
+
);
|
|
1698
|
+
log.debug(`QMD vsearch: ${Date.now() - startedAtMs}ms`);
|
|
1699
|
+
return parseQmdSearchStdout(stdout);
|
|
1700
|
+
} catch (err) {
|
|
1701
|
+
if (isCallerCancellation(err, signal)) {
|
|
1702
|
+
throw isAbortError(err) ? err : abortError("QMD subprocess vsearch aborted");
|
|
1703
|
+
}
|
|
1704
|
+
log.debug(`QMD vsearch failed: ${err}`);
|
|
1705
|
+
return [];
|
|
1706
|
+
}
|
|
1707
|
+
}
|
|
1708
|
+
async searchGlobalViaSubprocess(query, maxResults, options, signal) {
|
|
1709
|
+
if (this.available === false) return [];
|
|
1710
|
+
const startedAtMs = Date.now();
|
|
1711
|
+
try {
|
|
1712
|
+
const args = ["query", query, "--json", "-n", String(maxResults)];
|
|
1713
|
+
this.addResolvedSearchOptionsToArgs(args, options);
|
|
1714
|
+
const { stdout } = await this.runQmdCommand(args, QMD_TIMEOUT_MS, signal);
|
|
1715
|
+
const durationMs = Date.now() - startedAtMs;
|
|
1716
|
+
if (this.slowLog?.enabled && durationMs >= this.slowLog.thresholdMs) {
|
|
1717
|
+
log.warn(
|
|
1718
|
+
`SLOW QMD global query: durationMs=${durationMs} maxResults=${maxResults} queryChars=${query.length}`
|
|
1719
|
+
);
|
|
1720
|
+
}
|
|
1721
|
+
return parseQmdSearchStdout(stdout);
|
|
1722
|
+
} catch (err) {
|
|
1723
|
+
if (isCallerCancellation(err, signal)) {
|
|
1724
|
+
throw isAbortError(err) ? err : abortError("QMD subprocess global search aborted");
|
|
1725
|
+
}
|
|
1726
|
+
log.debug(`QMD global search failed: ${err}`);
|
|
1727
|
+
return [];
|
|
1728
|
+
}
|
|
1729
|
+
}
|
|
1730
|
+
async update(execution) {
|
|
1731
|
+
await this.runUpdateForCollection(
|
|
1732
|
+
this.collection,
|
|
1733
|
+
{ perCollectionThrottle: false },
|
|
1734
|
+
execution?.signal
|
|
1735
|
+
);
|
|
1736
|
+
}
|
|
1737
|
+
async updateCollection(collection, execution) {
|
|
1738
|
+
await this.runUpdateForCollection(
|
|
1739
|
+
collection,
|
|
1740
|
+
{ perCollectionThrottle: true },
|
|
1741
|
+
execution?.signal
|
|
1742
|
+
);
|
|
1743
|
+
}
|
|
1744
|
+
async updateCollectionStrict(collection, execution) {
|
|
1745
|
+
await this.runUpdateForCollection(
|
|
1746
|
+
collection,
|
|
1747
|
+
{ perCollectionThrottle: true, strict: true },
|
|
1748
|
+
execution?.signal
|
|
1749
|
+
);
|
|
1750
|
+
}
|
|
1751
|
+
updatesAllCollections() {
|
|
1752
|
+
return true;
|
|
1753
|
+
}
|
|
1754
|
+
async runUpdateForCollection(collection, options, signal) {
|
|
1755
|
+
if (this.available === false) {
|
|
1756
|
+
if (options.strict) {
|
|
1757
|
+
throw new Error("QMD unavailable");
|
|
1758
|
+
}
|
|
1759
|
+
return;
|
|
1760
|
+
}
|
|
1761
|
+
const name = collection.trim();
|
|
1762
|
+
if (!name) {
|
|
1763
|
+
if (options.strict) {
|
|
1764
|
+
throw new Error("QMD collection name is required");
|
|
1765
|
+
}
|
|
1766
|
+
return;
|
|
1767
|
+
}
|
|
1768
|
+
const globalState = getGlobalQmdState();
|
|
1769
|
+
const now = Date.now();
|
|
1770
|
+
if (!options.strict && options.perCollectionThrottle) {
|
|
1771
|
+
if (globalState.lastGlobalUpdateFailAtMs && now - globalState.lastGlobalUpdateFailAtMs < QMD_UPDATE_BACKOFF_MS) {
|
|
1772
|
+
log.debug("QMD update: suppressed by global failure backoff");
|
|
1773
|
+
return;
|
|
1774
|
+
}
|
|
1775
|
+
const lastCollectionRun = globalState.lastUpdateByCollectionMs[name];
|
|
1776
|
+
if (Number.isFinite(lastCollectionRun) && now - lastCollectionRun < this.updateMinIntervalMs) {
|
|
1777
|
+
log.debug(`QMD update: suppressed by per-collection min-interval gate (${name})`);
|
|
1778
|
+
return;
|
|
1779
|
+
}
|
|
1780
|
+
const lastCollectionFail = globalState.lastUpdateFailByCollectionMs[name];
|
|
1781
|
+
if (Number.isFinite(lastCollectionFail) && now - lastCollectionFail < QMD_UPDATE_BACKOFF_MS) {
|
|
1782
|
+
log.debug(`QMD update: suppressed by per-collection failure backoff (${name})`);
|
|
1783
|
+
return;
|
|
1784
|
+
}
|
|
1785
|
+
} else if (!options.strict) {
|
|
1786
|
+
if (this.lastUpdateRunAtMs && now - this.lastUpdateRunAtMs < this.updateMinIntervalMs) {
|
|
1787
|
+
log.debug("QMD update: suppressed due to min-interval gate");
|
|
1788
|
+
return;
|
|
1789
|
+
}
|
|
1790
|
+
if (this._lastUpdateFailAtMs && now - this._lastUpdateFailAtMs < QMD_UPDATE_BACKOFF_MS) {
|
|
1791
|
+
log.debug("QMD update: suppressed due to recent failures (backoff)");
|
|
1792
|
+
return;
|
|
1793
|
+
}
|
|
1794
|
+
if (globalState.lastGlobalUpdateRunAtMs && now - globalState.lastGlobalUpdateRunAtMs < this.updateMinIntervalMs) {
|
|
1795
|
+
log.debug("QMD update: suppressed by global min-interval gate");
|
|
1796
|
+
return;
|
|
1797
|
+
}
|
|
1798
|
+
if (globalState.lastGlobalUpdateFailAtMs && now - globalState.lastGlobalUpdateFailAtMs < QMD_UPDATE_BACKOFF_MS) {
|
|
1799
|
+
log.debug("QMD update: suppressed by global failure backoff");
|
|
1800
|
+
return;
|
|
1801
|
+
}
|
|
1802
|
+
}
|
|
1803
|
+
try {
|
|
1804
|
+
if (!globalState.warnedGlobalUpdateBehavior) {
|
|
1805
|
+
globalState.warnedGlobalUpdateBehavior = true;
|
|
1806
|
+
log.warn(
|
|
1807
|
+
"QMD update runs globally across collections in current CLI versions; Engram now rate-limits update calls to reduce gateway load."
|
|
1808
|
+
);
|
|
1809
|
+
}
|
|
1810
|
+
const startedAtMs = Date.now();
|
|
1811
|
+
await this.runQmdCommand(["update", "-c", name], this.updateTimeoutMs, signal);
|
|
1812
|
+
const durationMs = Date.now() - startedAtMs;
|
|
1813
|
+
if (this.slowLog?.enabled && durationMs >= this.slowLog.thresholdMs) {
|
|
1814
|
+
log.warn(`SLOW QMD update: durationMs=${durationMs}`);
|
|
1815
|
+
}
|
|
1816
|
+
const at = Date.now();
|
|
1817
|
+
if (options.perCollectionThrottle) {
|
|
1818
|
+
globalState.lastUpdateByCollectionMs[name] = at;
|
|
1819
|
+
globalState.lastGlobalUpdateRunAtMs = at;
|
|
1820
|
+
} else {
|
|
1821
|
+
this.lastUpdateRunAtMs = at;
|
|
1822
|
+
globalState.lastGlobalUpdateRunAtMs = at;
|
|
1823
|
+
}
|
|
1824
|
+
log.debug(`QMD update completed for collection=${name}`);
|
|
1825
|
+
} catch (err) {
|
|
1826
|
+
const at = Date.now();
|
|
1827
|
+
if (options.perCollectionThrottle) {
|
|
1828
|
+
globalState.lastUpdateFailByCollectionMs[name] = at;
|
|
1829
|
+
globalState.lastGlobalUpdateFailAtMs = at;
|
|
1830
|
+
} else {
|
|
1831
|
+
this._lastUpdateFailAtMs = at;
|
|
1832
|
+
globalState.lastGlobalUpdateFailAtMs = at;
|
|
1833
|
+
}
|
|
1834
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1835
|
+
log.warn(`QMD update failed for collection ${name}: ${msg}`);
|
|
1836
|
+
if (options.strict) {
|
|
1837
|
+
throw err;
|
|
1838
|
+
}
|
|
1839
|
+
}
|
|
1840
|
+
}
|
|
1841
|
+
async embed() {
|
|
1842
|
+
if (this.available === false) return;
|
|
1843
|
+
const globalState = getGlobalQmdState();
|
|
1844
|
+
if (this.lastEmbedFailAtMs && Date.now() - this.lastEmbedFailAtMs < QMD_EMBED_BACKOFF_MS) {
|
|
1845
|
+
log.debug("QMD embed: suppressed due to recent failures (backoff)");
|
|
1846
|
+
return;
|
|
1847
|
+
}
|
|
1848
|
+
if (globalState.lastGlobalEmbedRunAtMs && Date.now() - globalState.lastGlobalEmbedRunAtMs < this.updateMinIntervalMs) {
|
|
1849
|
+
log.debug("QMD embed: suppressed by global min-interval gate");
|
|
1850
|
+
return;
|
|
1851
|
+
}
|
|
1852
|
+
if (globalState.lastGlobalEmbedFailAtMs && Date.now() - globalState.lastGlobalEmbedFailAtMs < QMD_EMBED_BACKOFF_MS) {
|
|
1853
|
+
log.debug("QMD embed: suppressed by global failure backoff");
|
|
1854
|
+
return;
|
|
1855
|
+
}
|
|
1856
|
+
try {
|
|
1857
|
+
const startedAtMs = Date.now();
|
|
1858
|
+
await this.runQmdCommand(this.buildEmbedArgs(this.collection), 3e5);
|
|
1859
|
+
const durationMs = Date.now() - startedAtMs;
|
|
1860
|
+
if (this.slowLog?.enabled && durationMs >= this.slowLog.thresholdMs) {
|
|
1861
|
+
log.warn(`SLOW QMD embed: durationMs=${durationMs}`);
|
|
1862
|
+
}
|
|
1863
|
+
globalState.lastGlobalEmbedRunAtMs = Date.now();
|
|
1864
|
+
log.debug("QMD embed completed");
|
|
1865
|
+
} catch (err) {
|
|
1866
|
+
if (isVectorDimensionMismatchError(err)) {
|
|
1867
|
+
try {
|
|
1868
|
+
log.warn("QMD embed hit a vector dimension mismatch; retrying with force re-embed");
|
|
1869
|
+
await this.runQmdCommand(this.buildEmbedArgs(this.collection, true), 3e5);
|
|
1870
|
+
globalState.lastGlobalEmbedRunAtMs = Date.now();
|
|
1871
|
+
this.lastEmbedFailAtMs = null;
|
|
1872
|
+
globalState.lastGlobalEmbedFailAtMs = null;
|
|
1873
|
+
log.warn("QMD embed recovered by forcing a full vector rebuild");
|
|
1874
|
+
return;
|
|
1875
|
+
} catch (retryErr) {
|
|
1876
|
+
const retryMsg = retryErr instanceof Error ? retryErr.message : String(retryErr);
|
|
1877
|
+
log.warn(`QMD force re-embed failed after dimension mismatch: ${retryMsg}`);
|
|
1878
|
+
}
|
|
1879
|
+
}
|
|
1880
|
+
const now = Date.now();
|
|
1881
|
+
this.lastEmbedFailAtMs = now;
|
|
1882
|
+
globalState.lastGlobalEmbedFailAtMs = now;
|
|
1883
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1884
|
+
log.warn(`QMD embed failed: ${msg}`);
|
|
1885
|
+
}
|
|
1886
|
+
}
|
|
1887
|
+
async embedCollection(collection) {
|
|
1888
|
+
if (this.available === false) return;
|
|
1889
|
+
const name = collection.trim();
|
|
1890
|
+
if (!name) return;
|
|
1891
|
+
const globalState = getGlobalQmdState();
|
|
1892
|
+
const now = Date.now();
|
|
1893
|
+
if (globalState.lastGlobalEmbedFailAtMs && now - globalState.lastGlobalEmbedFailAtMs < QMD_EMBED_BACKOFF_MS) {
|
|
1894
|
+
log.debug(`QMD embed: suppressed by global failure backoff (${name})`);
|
|
1895
|
+
return;
|
|
1896
|
+
}
|
|
1897
|
+
const lastCollectionRun = globalState.lastEmbedByCollectionMs[name];
|
|
1898
|
+
if (Number.isFinite(lastCollectionRun) && now - lastCollectionRun < this.updateMinIntervalMs) {
|
|
1899
|
+
log.debug(`QMD embed: suppressed by per-collection min-interval gate (${name})`);
|
|
1900
|
+
return;
|
|
1901
|
+
}
|
|
1902
|
+
const lastCollectionFail = globalState.lastEmbedFailByCollectionMs[name];
|
|
1903
|
+
if (Number.isFinite(lastCollectionFail) && now - lastCollectionFail < QMD_EMBED_BACKOFF_MS) {
|
|
1904
|
+
log.debug(`QMD embed: suppressed by per-collection failure backoff (${name})`);
|
|
1905
|
+
return;
|
|
1906
|
+
}
|
|
1907
|
+
try {
|
|
1908
|
+
await this.runQmdCommand(this.buildEmbedArgs(name), 3e5);
|
|
1909
|
+
const at = Date.now();
|
|
1910
|
+
globalState.lastEmbedByCollectionMs[name] = at;
|
|
1911
|
+
globalState.lastGlobalEmbedRunAtMs = at;
|
|
1912
|
+
} catch (err) {
|
|
1913
|
+
if (isVectorDimensionMismatchError(err)) {
|
|
1914
|
+
try {
|
|
1915
|
+
log.warn(`QMD embed for collection ${name} hit a vector dimension mismatch; retrying with force re-embed`);
|
|
1916
|
+
await this.runQmdCommand(this.buildEmbedArgs(name, true), 3e5);
|
|
1917
|
+
const recoveredAt = Date.now();
|
|
1918
|
+
globalState.lastEmbedByCollectionMs[name] = recoveredAt;
|
|
1919
|
+
globalState.lastGlobalEmbedRunAtMs = recoveredAt;
|
|
1920
|
+
delete globalState.lastEmbedFailByCollectionMs[name];
|
|
1921
|
+
globalState.lastGlobalEmbedFailAtMs = null;
|
|
1922
|
+
log.warn(`QMD embed for collection ${name} recovered by forcing a full vector rebuild`);
|
|
1923
|
+
return;
|
|
1924
|
+
} catch (retryErr) {
|
|
1925
|
+
const retryMsg = retryErr instanceof Error ? retryErr.message : String(retryErr);
|
|
1926
|
+
log.warn(`QMD force re-embed failed for collection ${name}: ${retryMsg}`);
|
|
1927
|
+
}
|
|
1928
|
+
}
|
|
1929
|
+
const at = Date.now();
|
|
1930
|
+
globalState.lastEmbedFailByCollectionMs[name] = at;
|
|
1931
|
+
globalState.lastGlobalEmbedFailAtMs = at;
|
|
1932
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1933
|
+
log.warn(`QMD embed failed for collection ${name}: ${msg}`);
|
|
1934
|
+
}
|
|
1935
|
+
}
|
|
1936
|
+
async ensureCollection(memoryDir) {
|
|
1937
|
+
if (this.available === false && !this.daemonAvailable) return "unknown";
|
|
1938
|
+
if (this.available === false) return "skipped";
|
|
1939
|
+
try {
|
|
1940
|
+
const { stdout } = await this.runQmdCommand(["collection", "list"], QMD_TIMEOUT_MS);
|
|
1941
|
+
const collectionRegex = new RegExp(
|
|
1942
|
+
`^${this.collection}\\s+\\(qmd://`,
|
|
1943
|
+
"m"
|
|
1944
|
+
);
|
|
1945
|
+
if (collectionRegex.test(stdout)) {
|
|
1946
|
+
return "present";
|
|
1947
|
+
}
|
|
1948
|
+
} catch (err) {
|
|
1949
|
+
log.debug(
|
|
1950
|
+
`QMD collection check unavailable for "${this.collection}" (will not disable features): ${err instanceof Error ? err.message : String(err)}`
|
|
1951
|
+
);
|
|
1952
|
+
return "unknown";
|
|
1953
|
+
}
|
|
1954
|
+
log.info(
|
|
1955
|
+
`QMD collection "${this.collection}" not found. Add it to ~/.config/qmd/index.yml pointing at ${memoryDir}`
|
|
1956
|
+
);
|
|
1957
|
+
return "missing";
|
|
1958
|
+
}
|
|
1959
|
+
};
|
|
1960
|
+
|
|
1961
|
+
export {
|
|
1962
|
+
QMD_SUPPORTED_VERSION,
|
|
1963
|
+
parseQmdVersion,
|
|
1964
|
+
parseQmdVersionOutput,
|
|
1965
|
+
compareQmdVersions,
|
|
1966
|
+
versionAtLeast,
|
|
1967
|
+
resolveQmdCapabilities,
|
|
1968
|
+
shouldAutoUpgradeQmd,
|
|
1969
|
+
getQmdPostInstallProbeTargets,
|
|
1970
|
+
parseQmdExplain,
|
|
1971
|
+
getQmdCommandName,
|
|
1972
|
+
QmdClient
|
|
1973
|
+
};
|
|
1974
|
+
//# sourceMappingURL=chunk-BJ3KMYTB.js.map
|