@remnic/core 1.1.30 → 9.3.515
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/abstraction-nodes.js +2 -2
- package/dist/access-cli.d.ts +1 -1
- package/dist/access-cli.js +156 -119
- package/dist/access-cli.js.map +1 -1
- package/dist/access-http.d.ts +9 -5
- package/dist/access-http.js +51 -51
- package/dist/access-idempotency.d.ts +2 -0
- package/dist/access-idempotency.js +1 -1
- package/dist/access-mcp.d.ts +16 -9
- package/dist/access-mcp.js +44 -44
- package/dist/access-schema.d.ts +47 -15
- package/dist/access-schema.js +8 -8
- package/dist/{access-service-B5hgZPCN.d.ts → access-service-qrrIrC-0.d.ts} +11 -129
- package/dist/access-service.d.ts +7 -4
- package/dist/access-service.js +40 -40
- package/dist/action-confidence.d.ts +1 -0
- package/dist/active-memory-bridge.d.ts +1 -0
- package/dist/active-memory-bridge.js +3 -2
- package/dist/active-recall.d.ts +1 -0
- package/dist/active-recall.js +14 -9
- package/dist/active-recall.js.map +1 -1
- package/dist/adapters/claude-code.d.ts +6 -2
- package/dist/adapters/claude-code.js +2 -2
- package/dist/adapters/codex.d.ts +5 -1
- package/dist/adapters/codex.js +2 -2
- package/dist/adapters/hermes.js +2 -2
- package/dist/adapters/index.js +6 -6
- package/dist/adapters/registry.js +6 -6
- package/dist/adapters/replit.d.ts +4 -2
- package/dist/adapters/replit.js +2 -2
- package/dist/adapters/types.d.ts +4 -0
- package/dist/adapters/types.js +1 -1
- package/dist/behavior-learner.d.ts +1 -0
- package/dist/behavior-signals.d.ts +1 -0
- package/dist/behavior-signals.js +1 -1
- package/dist/bootstrap.d.ts +5 -3
- package/dist/bootstrap.js +2 -2
- package/dist/boxes.d.ts +1 -0
- package/dist/boxes.js +1 -1
- package/dist/briefing.d.ts +1 -0
- package/dist/briefing.js +9 -9
- package/dist/buffer-surprise-report.d.ts +1 -0
- package/dist/buffer.d.ts +1 -0
- package/dist/buffer.js +2 -2
- package/dist/bulk-import/index.d.ts +28 -0
- package/dist/bulk-import/index.js +31 -0
- package/dist/calibration.d.ts +2 -0
- package/dist/calibration.js +50 -17
- package/dist/calibration.js.map +1 -1
- package/dist/{capsule-crypto-5CYAGVC5.js → capsule-crypto-7FJQINUR.js} +2 -2
- package/dist/{capsule-merge-4MGKE7C5.js → capsule-merge-T2JRE46P.js} +3 -3
- package/dist/causal-behavior.d.ts +1 -0
- package/dist/causal-behavior.js +4 -4
- package/dist/causal-chain.js +4 -4
- package/dist/causal-consolidation.d.ts +16 -1
- package/dist/causal-consolidation.js +115 -32
- package/dist/causal-consolidation.js.map +1 -1
- package/dist/causal-retrieval.js +14 -6
- package/dist/causal-retrieval.js.map +1 -1
- package/dist/causal-trajectory-graph.js +2 -2
- package/dist/causal-trajectory.js +2 -2
- package/dist/{chunk-SAZS2QZB.js → chunk-23UORJ4S.js} +3 -3
- package/dist/{chunk-76FLAAUC.js → chunk-2AN2L4NL.js} +17 -6
- package/dist/chunk-2AN2L4NL.js.map +1 -0
- package/dist/{chunk-W4L6CZKA.js → chunk-2DL3OFLD.js} +15 -10
- package/dist/chunk-2DL3OFLD.js.map +1 -0
- package/dist/{chunk-7OZ53EXP.js → chunk-2NLLXCJG.js} +21 -10
- package/dist/chunk-2NLLXCJG.js.map +1 -0
- package/dist/{chunk-PK7H5L6Y.js → chunk-2NM43EWN.js} +2 -2
- package/dist/{chunk-PYXS46O7.js → chunk-3BP57I6J.js} +2 -2
- package/dist/{chunk-FBYESMQ2.js → chunk-3C5RPJAX.js} +2 -2
- package/dist/{chunk-QKZGQIPJ.js → chunk-3Q4H3OBR.js} +171 -64
- package/dist/chunk-3Q4H3OBR.js.map +1 -0
- package/dist/{chunk-FKFMOY3N.js → chunk-42NQ7AVG.js} +3 -4
- package/dist/{chunk-FKFMOY3N.js.map → chunk-42NQ7AVG.js.map} +1 -1
- package/dist/chunk-4426WSWL.js +73 -0
- package/dist/chunk-4426WSWL.js.map +1 -0
- package/dist/{chunk-LIRZNNUP.js → chunk-44442YCH.js} +5 -2
- package/dist/chunk-44442YCH.js.map +1 -0
- package/dist/{chunk-H3ME6L6D.js → chunk-46GJIW5M.js} +23 -20
- package/dist/chunk-46GJIW5M.js.map +1 -0
- package/dist/{chunk-QDZ2RLEC.js → chunk-472U7RDF.js} +3 -3
- package/dist/chunk-472U7RDF.js.map +1 -0
- package/dist/{chunk-NN2DKE4T.js → chunk-4H5ZJHEN.js} +16 -3
- package/dist/{chunk-NN2DKE4T.js.map → chunk-4H5ZJHEN.js.map} +1 -1
- package/dist/{chunk-56K5QLHX.js → chunk-4HP7HIE3.js} +56 -13
- package/dist/chunk-4HP7HIE3.js.map +1 -0
- package/dist/{chunk-RK2Y4XOM.js → chunk-4JRRISLU.js} +9 -6
- package/dist/chunk-4JRRISLU.js.map +1 -0
- package/dist/{chunk-MG7NA5H3.js → chunk-4Q73JBSM.js} +17 -12
- package/dist/chunk-4Q73JBSM.js.map +1 -0
- package/dist/{chunk-XKLD5OK4.js → chunk-4RR6ROTB.js} +10 -11
- package/dist/chunk-4RR6ROTB.js.map +1 -0
- package/dist/{chunk-4KGVTPGD.js → chunk-6F6BXB7A.js} +9 -8
- package/dist/chunk-6F6BXB7A.js.map +1 -0
- package/dist/{chunk-NMZY542O.js → chunk-6URPAY2D.js} +41 -17
- package/dist/chunk-6URPAY2D.js.map +1 -0
- package/dist/{chunk-N53K2EXC.js → chunk-6VF75M3X.js} +2 -2
- package/dist/{chunk-XSZEP4SF.js → chunk-6XSPNR6L.js} +6 -5
- package/dist/chunk-6XSPNR6L.js.map +1 -0
- package/dist/{chunk-6H2TESSP.js → chunk-765K3SAT.js} +3 -3
- package/dist/{chunk-EDTHC6UD.js → chunk-77NAFXUD.js} +2 -2
- package/dist/{chunk-S7KDBTWT.js → chunk-7F7Z6MOS.js} +29 -14
- package/dist/chunk-7F7Z6MOS.js.map +1 -0
- package/dist/{chunk-MZH6EHNR.js → chunk-7H6CFEBJ.js} +41 -14
- package/dist/chunk-7H6CFEBJ.js.map +1 -0
- package/dist/{chunk-575RMLWN.js → chunk-7MV5CWTE.js} +26 -20
- package/dist/chunk-7MV5CWTE.js.map +1 -0
- package/dist/{chunk-MGKYQQYF.js → chunk-7Q3RCKAQ.js} +2 -2
- package/dist/chunk-7RXCMVFQ.js +27 -0
- package/dist/chunk-7RXCMVFQ.js.map +1 -0
- package/dist/{chunk-DGXUHMOV.js → chunk-A2IYSXDQ.js} +25 -6
- package/dist/chunk-A2IYSXDQ.js.map +1 -0
- package/dist/{chunk-EABGC2TL.js → chunk-A2Z6UCWT.js} +26 -4
- package/dist/chunk-A2Z6UCWT.js.map +1 -0
- package/dist/{chunk-3VAL7ZL2.js → chunk-A52AKD7C.js} +59 -24
- package/dist/chunk-A52AKD7C.js.map +1 -0
- package/dist/{chunk-5375UYTQ.js → chunk-A6D7A2FW.js} +4 -4
- package/dist/chunk-A6D7A2FW.js.map +1 -0
- package/dist/{chunk-FAAFWE4G.js → chunk-ALEPI75L.js} +24 -6
- package/dist/chunk-ALEPI75L.js.map +1 -0
- package/dist/{chunk-3SLRNYNG.js → chunk-AUDJPF4N.js} +15 -4
- package/dist/chunk-AUDJPF4N.js.map +1 -0
- package/dist/chunk-B5XMS73R.js +145 -0
- package/dist/chunk-B5XMS73R.js.map +1 -0
- package/dist/{chunk-HXXBL2KD.js → chunk-BECQDWBA.js} +44 -4
- package/dist/chunk-BECQDWBA.js.map +1 -0
- package/dist/{chunk-7SEAZFFB.js → chunk-BEUDU7Y4.js} +24 -4
- package/dist/chunk-BEUDU7Y4.js.map +1 -0
- package/dist/{chunk-XVVIG67A.js → chunk-BLZAVUD2.js} +61 -17
- package/dist/chunk-BLZAVUD2.js.map +1 -0
- package/dist/chunk-CHBI22MI.js +159 -0
- package/dist/chunk-CHBI22MI.js.map +1 -0
- package/dist/{chunk-GDFS42HT.js → chunk-CHCA44C3.js} +15 -8
- package/dist/chunk-CHCA44C3.js.map +1 -0
- package/dist/chunk-CINZGPSJ.js +22 -0
- package/dist/chunk-CINZGPSJ.js.map +1 -0
- package/dist/chunk-CMTINOFS.js +36 -0
- package/dist/chunk-CMTINOFS.js.map +1 -0
- package/dist/{chunk-34DQE4KF.js → chunk-CO7ZO4TU.js} +2 -2
- package/dist/{chunk-PFV5C235.js → chunk-CPPS65WS.js} +2 -1
- package/dist/{chunk-PFV5C235.js.map → chunk-CPPS65WS.js.map} +1 -1
- package/dist/{chunk-DINWEURR.js → chunk-CSKLPDN6.js} +20 -6
- package/dist/chunk-CSKLPDN6.js.map +1 -0
- package/dist/chunk-CWWMTTQE.js +566 -0
- package/dist/chunk-CWWMTTQE.js.map +1 -0
- package/dist/{chunk-IQT3XTKW.js → chunk-D24OXEPB.js} +13 -7
- package/dist/chunk-D24OXEPB.js.map +1 -0
- package/dist/{chunk-KRBK4BQH.js → chunk-D6WE5MTW.js} +272 -411
- package/dist/chunk-D6WE5MTW.js.map +1 -0
- package/dist/{chunk-WIICJPET.js → chunk-DEUNUKTD.js} +6 -4
- package/dist/{chunk-WIICJPET.js.map → chunk-DEUNUKTD.js.map} +1 -1
- package/dist/{chunk-ZYVPLJ4T.js → chunk-DHGSZ3UD.js} +9 -7
- package/dist/chunk-DHGSZ3UD.js.map +1 -0
- package/dist/{chunk-JR4ZC3G4.js → chunk-DLJ4IR6M.js} +91 -41
- package/dist/chunk-DLJ4IR6M.js.map +1 -0
- package/dist/{chunk-U4SCL7B7.js → chunk-DRD2Q7HQ.js} +82 -18
- package/dist/chunk-DRD2Q7HQ.js.map +1 -0
- package/dist/{chunk-2IWUMAES.js → chunk-E62SBGQ3.js} +28 -13
- package/dist/chunk-E62SBGQ3.js.map +1 -0
- package/dist/{chunk-C5BCH4ZS.js → chunk-EAZGEEG2.js} +21 -3
- package/dist/chunk-EAZGEEG2.js.map +1 -0
- package/dist/{chunk-TPB3I2AC.js → chunk-ECZU5BJH.js} +31 -10
- package/dist/chunk-ECZU5BJH.js.map +1 -0
- package/dist/{chunk-77H5NU3M.js → chunk-EDBEWFJO.js} +82 -18
- package/dist/chunk-EDBEWFJO.js.map +1 -0
- package/dist/chunk-EDQVAMQI.js +308 -0
- package/dist/chunk-EDQVAMQI.js.map +1 -0
- package/dist/{chunk-RRF5UOBJ.js → chunk-EI6V5UXY.js} +22 -15
- package/dist/chunk-EI6V5UXY.js.map +1 -0
- package/dist/{chunk-I5GLV3VE.js → chunk-EIPUHVKE.js} +31 -24
- package/dist/{chunk-I5GLV3VE.js.map → chunk-EIPUHVKE.js.map} +1 -1
- package/dist/{chunk-ZKSK55RC.js → chunk-ETUPBUHB.js} +2 -2
- package/dist/{chunk-25MQ7IHJ.js → chunk-EUML3N6B.js} +17 -6
- package/dist/chunk-EUML3N6B.js.map +1 -0
- package/dist/{chunk-5RGLBDQF.js → chunk-EVZFIAPG.js} +12 -12
- package/dist/chunk-EVZFIAPG.js.map +1 -0
- package/dist/{chunk-QRNI5JBH.js → chunk-EYIEWJNI.js} +2 -2
- package/dist/{chunk-3OWUCDKH.js → chunk-FER4WARO.js} +176 -42
- package/dist/chunk-FER4WARO.js.map +1 -0
- package/dist/{chunk-43PJZYGL.js → chunk-FPGE5NVO.js} +45 -10
- package/dist/chunk-FPGE5NVO.js.map +1 -0
- package/dist/{chunk-C6QPK5GG.js → chunk-FZZ2QTJI.js} +2 -2
- package/dist/{chunk-D46YSIYX.js → chunk-G3Z3QEF5.js} +19 -11
- package/dist/{chunk-D46YSIYX.js.map → chunk-G3Z3QEF5.js.map} +1 -1
- package/dist/{chunk-3JXBXXM2.js → chunk-G4IAEX6D.js} +2 -2
- package/dist/{chunk-MSWG7JI6.js → chunk-G56P5RLD.js} +8 -2
- package/dist/chunk-G56P5RLD.js.map +1 -0
- package/dist/{chunk-AGZQD76C.js → chunk-GCGJW34D.js} +48 -2
- package/dist/chunk-GCGJW34D.js.map +1 -0
- package/dist/chunk-H2NCNXMS.js +159 -0
- package/dist/chunk-H2NCNXMS.js.map +1 -0
- package/dist/{chunk-XYIK4LF6.js → chunk-H3FZVNRN.js} +8 -2
- package/dist/chunk-H3FZVNRN.js.map +1 -0
- package/dist/{chunk-TK4UEOSK.js → chunk-HDDRVXX4.js} +8 -8
- package/dist/chunk-HDDRVXX4.js.map +1 -0
- package/dist/{chunk-LLQ2LLWF.js → chunk-HENLZHIT.js} +15 -5
- package/dist/chunk-HENLZHIT.js.map +1 -0
- package/dist/{chunk-N2D6GXBM.js → chunk-HINSGUA7.js} +28 -20
- package/dist/chunk-HINSGUA7.js.map +1 -0
- package/dist/{chunk-APO3DCMU.js → chunk-HLAVGJ62.js} +30 -8
- package/dist/chunk-HLAVGJ62.js.map +1 -0
- package/dist/{chunk-TPMQ3G6Z.js → chunk-HOJZMQ4J.js} +2 -2
- package/dist/chunk-HOJZMQ4J.js.map +1 -0
- package/dist/{chunk-LUDTDZLK.js → chunk-HPWVAEET.js} +33 -7
- package/dist/chunk-HPWVAEET.js.map +1 -0
- package/dist/{chunk-NZL6GGQE.js → chunk-HQ6NIBL6.js} +92 -30
- package/dist/chunk-HQ6NIBL6.js.map +1 -0
- package/dist/{chunk-UWVJF25J.js → chunk-HWVTS5NO.js} +20 -6
- package/dist/chunk-HWVTS5NO.js.map +1 -0
- package/dist/{chunk-2WWLHTZY.js → chunk-IC4GELZE.js} +2 -2
- package/dist/{chunk-QA2ZAPBU.js → chunk-IPLYGWQF.js} +28 -20
- package/dist/chunk-IPLYGWQF.js.map +1 -0
- package/dist/{chunk-A6KTB5R6.js → chunk-IQ3OI2RR.js} +3 -3
- package/dist/chunk-IQ3OI2RR.js.map +1 -0
- package/dist/{chunk-6LVVDPJ4.js → chunk-J64TK33U.js} +3 -4
- package/dist/chunk-J64TK33U.js.map +1 -0
- package/dist/{chunk-6FC5EGNV.js → chunk-JBPKEARU.js} +15 -5
- package/dist/{chunk-6FC5EGNV.js.map → chunk-JBPKEARU.js.map} +1 -1
- package/dist/{chunk-RHY3HH7P.js → chunk-JFEKNTX7.js} +125 -33
- package/dist/chunk-JFEKNTX7.js.map +1 -0
- package/dist/{chunk-TZOLIGIG.js → chunk-JJEJJ7RK.js} +4 -2
- package/dist/chunk-JJEJJ7RK.js.map +1 -0
- package/dist/{chunk-PCUKNJAZ.js → chunk-JKV57BTN.js} +2 -2
- package/dist/{chunk-EJI5XIBB.js → chunk-JLNBQWZ2.js} +55 -7
- package/dist/chunk-JLNBQWZ2.js.map +1 -0
- package/dist/{chunk-XIG5PDM7.js → chunk-JUC24CTX.js} +8 -12
- package/dist/chunk-JUC24CTX.js.map +1 -0
- package/dist/{chunk-UL2NNBUL.js → chunk-JYIKKAK3.js} +106 -44
- package/dist/chunk-JYIKKAK3.js.map +1 -0
- package/dist/{chunk-OIGNEXKZ.js → chunk-K5O2QY6T.js} +5 -1
- package/dist/{chunk-OIGNEXKZ.js.map → chunk-K5O2QY6T.js.map} +1 -1
- package/dist/{chunk-ZTFCYYEZ.js → chunk-KCYE2MZM.js} +3 -3
- package/dist/chunk-KCYE2MZM.js.map +1 -0
- package/dist/{chunk-JWPLJLDU.js → chunk-KD3QD3A5.js} +2 -2
- package/dist/{chunk-JWPLJLDU.js.map → chunk-KD3QD3A5.js.map} +1 -1
- package/dist/{chunk-YRMVARQP.js → chunk-KFY3SGN7.js} +49 -2
- package/dist/chunk-KFY3SGN7.js.map +1 -0
- package/dist/{chunk-CYFQJMUV.js → chunk-KIB7SDIJ.js} +15 -10
- package/dist/chunk-KIB7SDIJ.js.map +1 -0
- package/dist/{chunk-3KW65B36.js → chunk-KILOTVIF.js} +95 -48
- package/dist/chunk-KILOTVIF.js.map +1 -0
- package/dist/{chunk-MXFBBHJU.js → chunk-KJMYHC7K.js} +10 -5
- package/dist/chunk-KJMYHC7K.js.map +1 -0
- package/dist/{chunk-W3LR522O.js → chunk-KM2A35EO.js} +36 -34
- package/dist/chunk-KM2A35EO.js.map +1 -0
- package/dist/{chunk-WELDCG6C.js → chunk-L227SKTB.js} +109 -36
- package/dist/chunk-L227SKTB.js.map +1 -0
- package/dist/{chunk-W6AQJ2PY.js → chunk-L7S47WZT.js} +35 -16
- package/dist/chunk-L7S47WZT.js.map +1 -0
- package/dist/{chunk-BVF3AGJP.js → chunk-LJBOVCQG.js} +26 -11
- package/dist/chunk-LJBOVCQG.js.map +1 -0
- package/dist/{chunk-2KI4QFHU.js → chunk-LMDRGRJ2.js} +2 -2
- package/dist/{chunk-MY6TPVXW.js → chunk-LMPHTYJC.js} +2 -2
- package/dist/{chunk-EHRTFRWW.js → chunk-LQHDIS7L.js} +10 -5
- package/dist/chunk-LQHDIS7L.js.map +1 -0
- package/dist/chunk-LUDUFZTV.js +170 -0
- package/dist/chunk-LUDUFZTV.js.map +1 -0
- package/dist/{chunk-5HRY2WRF.js → chunk-LZ3VEOU5.js} +2 -2
- package/dist/{chunk-Q7P4WJDP.js → chunk-M5T4Q2ZU.js} +1 -1
- package/dist/chunk-M5T4Q2ZU.js.map +1 -0
- package/dist/{chunk-ICRIXAP2.js → chunk-MC4FJXPA.js} +16 -6
- package/dist/chunk-MC4FJXPA.js.map +1 -0
- package/dist/{chunk-WPGJYVUH.js → chunk-MGVIEM2O.js} +23 -6
- package/dist/chunk-MGVIEM2O.js.map +1 -0
- package/dist/{chunk-OC7KHOOX.js → chunk-O27WNHTT.js} +22 -6
- package/dist/chunk-O27WNHTT.js.map +1 -0
- package/dist/{chunk-NGAVDO7E.js → chunk-OADWQ5CR.js} +2 -2
- package/dist/{chunk-2NMMFZ5T.js → chunk-OD4FM2U7.js} +6 -3
- package/dist/chunk-OD4FM2U7.js.map +1 -0
- package/dist/{chunk-OZHRDTDX.js → chunk-OKTXM5H4.js} +11 -1
- package/dist/chunk-OKTXM5H4.js.map +1 -0
- package/dist/{chunk-RXDLTSWT.js → chunk-ONPLNAPX.js} +16 -7
- package/dist/chunk-ONPLNAPX.js.map +1 -0
- package/dist/{chunk-FJ43PRLT.js → chunk-ORFGK3XI.js} +20 -14
- package/dist/chunk-ORFGK3XI.js.map +1 -0
- package/dist/{chunk-DOM4GKSW.js → chunk-OZKVVUJB.js} +3 -3
- package/dist/{chunk-MT4HVDUZ.js → chunk-PM3QHTFT.js} +3 -3
- package/dist/{chunk-4DWOBS2A.js → chunk-PRQJ5ESM.js} +27 -2
- package/dist/{chunk-4DWOBS2A.js.map → chunk-PRQJ5ESM.js.map} +1 -1
- package/dist/chunk-PU44GBL4.js +52 -0
- package/dist/chunk-PU44GBL4.js.map +1 -0
- package/dist/{chunk-MJFNCJXV.js → chunk-Q4CAQGKQ.js} +47 -9
- package/dist/chunk-Q4CAQGKQ.js.map +1 -0
- package/dist/{chunk-U3WSW6PZ.js → chunk-QMYXNM4P.js} +90 -35
- package/dist/chunk-QMYXNM4P.js.map +1 -0
- package/dist/{chunk-NBNN5GOB.js → chunk-QY7YA7OL.js} +11 -2
- package/dist/chunk-QY7YA7OL.js.map +1 -0
- package/dist/{chunk-QLLBRHAT.js → chunk-R26QUUQN.js} +181 -257
- package/dist/chunk-R26QUUQN.js.map +1 -0
- package/dist/{chunk-ZK7I7JYV.js → chunk-R3PS27B4.js} +7 -7
- package/dist/{chunk-TMQLARTH.js → chunk-RCTS5CKK.js} +33 -14
- package/dist/chunk-RCTS5CKK.js.map +1 -0
- package/dist/{chunk-2PRLKQAH.js → chunk-RLV3PQGH.js} +35 -19
- package/dist/chunk-RLV3PQGH.js.map +1 -0
- package/dist/{chunk-WW3QQF4H.js → chunk-ROZJACKP.js} +16 -1
- package/dist/chunk-ROZJACKP.js.map +1 -0
- package/dist/{chunk-7MNMYOFP.js → chunk-RSUYKGGZ.js} +3 -4
- package/dist/chunk-RSUYKGGZ.js.map +1 -0
- package/dist/{chunk-LT3NLYSI.js → chunk-RUZOJKNF.js} +10 -7
- package/dist/chunk-RUZOJKNF.js.map +1 -0
- package/dist/{chunk-326G7DJK.js → chunk-RW5DGAGO.js} +67 -13
- package/dist/chunk-RW5DGAGO.js.map +1 -0
- package/dist/{chunk-KOSORCJG.js → chunk-S53PKKWK.js} +63 -24
- package/dist/chunk-S53PKKWK.js.map +1 -0
- package/dist/{chunk-65PG43EQ.js → chunk-S7WU3Y3D.js} +21 -4
- package/dist/chunk-S7WU3Y3D.js.map +1 -0
- package/dist/{chunk-SKE7JYKA.js → chunk-SFXKHM7P.js} +2 -2
- package/dist/{chunk-HMDCOMYU.js → chunk-SKGV326D.js} +3 -3
- package/dist/chunk-T2PO5MUF.js +62 -0
- package/dist/chunk-T2PO5MUF.js.map +1 -0
- package/dist/{chunk-C7VW7C3F.js → chunk-TDKQGLJW.js} +3 -3
- package/dist/chunk-TDKQGLJW.js.map +1 -0
- package/dist/{chunk-3QKK7QOS.js → chunk-TERNBNJB.js} +3 -3
- package/dist/chunk-TERNBNJB.js.map +1 -0
- package/dist/{chunk-MXC3AP5I.js → chunk-TGQ2NTWH.js} +12 -7
- package/dist/chunk-TGQ2NTWH.js.map +1 -0
- package/dist/{chunk-3Y4P7RXM.js → chunk-TMSXWOBZ.js} +3 -4
- package/dist/chunk-TMSXWOBZ.js.map +1 -0
- package/dist/{chunk-3TNBOMQT.js → chunk-TVRN5QKH.js} +11 -11
- package/dist/{chunk-3TNBOMQT.js.map → chunk-TVRN5QKH.js.map} +1 -1
- package/dist/{chunk-5UM2VJ6D.js → chunk-UEY3VB6W.js} +2 -2
- package/dist/{chunk-I6K5FBRQ.js → chunk-UI3NYK34.js} +4 -1
- package/dist/{chunk-I6K5FBRQ.js.map → chunk-UI3NYK34.js.map} +1 -1
- package/dist/{chunk-VBJ7V5SK.js → chunk-UIPDNLXA.js} +21 -8
- package/dist/chunk-UIPDNLXA.js.map +1 -0
- package/dist/{chunk-GIF42EW3.js → chunk-UP6MOYCB.js} +3 -3
- package/dist/{chunk-K4FLSOR5.js → chunk-USYGGIJZ.js} +44 -15
- package/dist/chunk-USYGGIJZ.js.map +1 -0
- package/dist/{chunk-FIT6DMX6.js → chunk-UWY7GIVS.js} +152 -54
- package/dist/chunk-UWY7GIVS.js.map +1 -0
- package/dist/{chunk-MRILGULB.js → chunk-V2RCP53Q.js} +2 -2
- package/dist/{chunk-XKECPATV.js → chunk-VFUEZZBS.js} +113 -4
- package/dist/chunk-VFUEZZBS.js.map +1 -0
- package/dist/{chunk-FSFEQI74.js → chunk-W7L6HXUC.js} +2 -2
- package/dist/{chunk-3IQ2TR4N.js → chunk-WLEB7WCG.js} +2 -2
- package/dist/{chunk-GL6I6MEQ.js → chunk-WSGF57U2.js} +3 -3
- package/dist/{chunk-KNKUID7G.js → chunk-X7Y7WX73.js} +72 -6
- package/dist/chunk-X7Y7WX73.js.map +1 -0
- package/dist/{chunk-5NPGSAVB.js → chunk-XEKAG3FM.js} +23 -5
- package/dist/chunk-XEKAG3FM.js.map +1 -0
- package/dist/{chunk-3APJ5EVB.js → chunk-XKIQZXUB.js} +41 -26
- package/dist/chunk-XKIQZXUB.js.map +1 -0
- package/dist/chunk-XKXKSQU7.js +92 -0
- package/dist/chunk-XKXKSQU7.js.map +1 -0
- package/dist/{chunk-JA3AK3PT.js → chunk-XNLXAWHX.js} +4 -4
- package/dist/{chunk-CULXMQJH.js → chunk-XPXEJRUB.js} +3 -3
- package/dist/chunk-XPXEJRUB.js.map +1 -0
- package/dist/{chunk-PZIAX57I.js → chunk-XR6DNK4U.js} +7 -4
- package/dist/chunk-XR6DNK4U.js.map +1 -0
- package/dist/{chunk-47VWKCAF.js → chunk-XSQ4SGM5.js} +33 -4
- package/dist/chunk-XSQ4SGM5.js.map +1 -0
- package/dist/{chunk-66DHUKLO.js → chunk-XSWKORGM.js} +16 -14
- package/dist/chunk-XSWKORGM.js.map +1 -0
- package/dist/{chunk-QR3C7BKQ.js → chunk-XZ4WBBB5.js} +7 -8
- package/dist/chunk-XZ4WBBB5.js.map +1 -0
- package/dist/{chunk-WNARATI3.js → chunk-Y2SXZ5KZ.js} +59 -11
- package/dist/chunk-Y2SXZ5KZ.js.map +1 -0
- package/dist/{chunk-SIC6U3GZ.js → chunk-YHV3KRKS.js} +3 -3
- package/dist/{chunk-ZPKBYX2F.js → chunk-YNDLCWXS.js} +85 -9
- package/dist/chunk-YNDLCWXS.js.map +1 -0
- package/dist/{chunk-VLXA6PI2.js → chunk-YQMZ7IH2.js} +4 -4
- package/dist/{chunk-TMM4S4IJ.js → chunk-YR6GIWWY.js} +58 -8
- package/dist/chunk-YR6GIWWY.js.map +1 -0
- package/dist/{chunk-DK5LDEQM.js → chunk-YR7XMOWK.js} +39 -23
- package/dist/chunk-YR7XMOWK.js.map +1 -0
- package/dist/chunk-ZFXCQPNO.js +27 -0
- package/dist/chunk-ZFXCQPNO.js.map +1 -0
- package/dist/citations.js +1 -1
- package/dist/{cli-CJKI2JIe.d.ts → cli-X4NJoqSe.d.ts} +8 -31
- package/dist/cli.d.ts +10 -6
- package/dist/cli.js +122 -117
- package/dist/commitment-ledger.js +2 -2
- package/dist/compat/checks.js +1 -2
- package/dist/compounding/engine.d.ts +3 -2
- package/dist/compounding/engine.js +11 -11
- package/dist/compounding/preference-consolidator.d.ts +1 -0
- package/dist/compounding/preference-consolidator.js +8 -8
- package/dist/compounding/preference-consolidator.js.map +1 -1
- package/dist/compression-optimizer.d.ts +1 -0
- package/dist/compression-optimizer.js +1 -1
- package/dist/config.d.ts +1 -0
- package/dist/config.js +3 -2
- package/dist/connectors/codex-materialize-runner.d.ts +1 -0
- package/dist/connectors/codex-materialize-runner.js +12 -11
- package/dist/connectors/codex-materialize.d.ts +1 -0
- package/dist/connectors/codex-materialize.js +3 -2
- package/dist/connectors/index.d.ts +1 -0
- package/dist/connectors/index.js +14 -14
- package/dist/{connectors-cli-CwbyjGR7.d.ts → connectors-cli-DbTPNj2H.d.ts} +7 -1
- package/dist/connectors-cli.d.ts +1 -1
- package/dist/connectors-cli.js +3 -1
- package/dist/consolidation-provenance-check.d.ts +1 -0
- package/dist/consolidation-provenance-check.js +2 -2
- package/dist/consolidation-undo.d.ts +1 -0
- package/dist/consolidation-undo.js +1 -1
- package/dist/contradiction/index.d.ts +3 -1
- package/dist/contradiction/index.js +3 -3
- package/dist/{contradiction-review-ATP4S6IC.js → contradiction-review-6V2LXXK6.js} +2 -2
- package/dist/{contradiction-scan-5A4IDZV5.js → contradiction-scan-GIRVC4C7.js} +3 -3
- package/dist/conversation-index/backend.d.ts +3 -1
- package/dist/conversation-index/backend.js +3 -3
- package/dist/conversation-index/chunker.d.ts +1 -0
- package/dist/conversation-index/cleanup.js +1 -1
- package/dist/conversation-index/faiss-adapter.d.ts +2 -1
- package/dist/conversation-index/faiss-adapter.js +1 -1
- package/dist/conversation-index/indexer.d.ts +5 -2
- package/dist/conversation-index/indexer.js +1 -1
- package/dist/conversation-index/search.d.ts +2 -1
- package/dist/cross-namespace-budget.js +1 -1
- package/dist/cue-anchors.js +2 -2
- package/dist/dashboard-runtime.d.ts +6 -0
- package/dist/dashboard-runtime.js +3 -3
- package/dist/day-summary.d.ts +1 -0
- package/dist/day-summary.js +2 -2
- package/dist/delinearize.d.ts +1 -0
- package/dist/direct-answer-wiring.d.ts +1 -0
- package/dist/direct-answer.d.ts +1 -0
- package/dist/{dreams-ledger-LR2NBAZE.js → dreams-ledger-3WSCI5V4.js} +5 -4
- package/dist/{dreams-ledger-LR2NBAZE.js.map → dreams-ledger-3WSCI5V4.js.map} +1 -1
- package/dist/embedding-fallback.d.ts +3 -0
- package/dist/embedding-fallback.js +2 -2
- package/dist/enrichment/index.d.ts +1 -0
- package/dist/enrichment/index.js +1 -1
- package/dist/entity-retrieval.d.ts +2 -0
- package/dist/entity-retrieval.js +9 -9
- package/dist/entity-schema.d.ts +1 -0
- package/dist/evals.js +1 -1
- package/dist/explicit-capture.d.ts +5 -3
- package/dist/explicit-capture.js +2 -2
- package/dist/extraction-judge-telemetry.d.ts +2 -0
- package/dist/extraction-judge-training.d.ts +2 -0
- package/dist/extraction-judge.d.ts +2 -0
- package/dist/extraction.d.ts +2 -0
- package/dist/extraction.js +12 -12
- package/dist/{faiss-adapter-CzPghc4C.d.ts → faiss-adapter-BHecI1fF.d.ts} +4 -1
- package/dist/fallback-llm.d.ts +11 -1
- package/dist/fallback-llm.js +8 -6
- package/dist/{first-start-migration-4MHQEOSD.js → first-start-migration-CKTCTCQI.js} +5 -5
- package/dist/graph-dashboard-diff.d.ts +4 -0
- package/dist/graph-dashboard-diff.js +1 -1
- package/dist/graph-dashboard-parser.js +1 -1
- package/dist/{graph-edge-decay-5DI5GUNL.js → graph-edge-decay-MUP5J7CC.js} +6 -6
- package/dist/graph-events.js +1 -1
- package/dist/graph-snapshot.js +3 -3
- package/dist/graph.js +2 -2
- package/dist/harmonic-retrieval.js +4 -4
- package/dist/identity-continuity.d.ts +1 -0
- package/dist/importance.d.ts +1 -0
- package/dist/importers/index.d.ts +244 -0
- package/dist/importers/index.js +20 -0
- package/dist/index.d.ts +21 -351
- package/dist/index.js +886 -561
- package/dist/index.js.map +1 -1
- package/dist/intent.d.ts +1 -0
- package/dist/lcm/archive.d.ts +2 -2
- package/dist/lcm/archive.js +2 -2
- package/dist/lcm/engine.d.ts +3 -2
- package/dist/lcm/engine.js +6 -6
- package/dist/lcm/index.d.ts +1 -0
- package/dist/lcm/index.js +8 -8
- package/dist/lcm/recall.js +1 -1
- package/dist/lcm/summarizer.js +3 -3
- package/dist/lcm/tools.d.ts +1 -0
- package/dist/lifecycle.d.ts +1 -0
- package/dist/live-connectors-runner.d.ts +1 -0
- package/dist/live-connectors-runner.js +6 -6
- package/dist/local-llm.d.ts +1 -0
- package/dist/local-llm.js +2 -2
- package/dist/maintenance/archive-observations.js +1 -1
- package/dist/maintenance/memory-governance.d.ts +3 -1
- package/dist/maintenance/memory-governance.js +10 -8
- package/dist/maintenance/migrate-observations.js +3 -2
- package/dist/maintenance/observation-ledger-utils.d.ts +3 -0
- package/dist/maintenance/observation-ledger-utils.js +2 -1
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -1
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +11 -8
- package/dist/maintenance/rebuild-memory-projection.d.ts +2 -1
- package/dist/maintenance/rebuild-memory-projection.js +13 -10
- package/dist/maintenance/rebuild-observations.d.ts +1 -0
- package/dist/maintenance/rebuild-observations.js +3 -2
- package/dist/mcp-memory-inspector-app.d.ts +7 -4
- package/dist/mcp-memory-inspector-app.js +1 -1
- package/dist/memory-action-policy.d.ts +1 -0
- package/dist/memory-cache.d.ts +1 -0
- package/dist/memory-cache.js +1 -1
- package/dist/memory-lifecycle-ledger-utils.d.ts +1 -0
- package/dist/memory-projection-store.d.ts +1 -0
- package/dist/memory-projection-store.js +1 -1
- package/dist/memory-provenance.d.ts +1 -0
- package/dist/memory-worth-outcomes.d.ts +1 -0
- package/dist/migrate/from-engram.js +2 -2
- package/dist/{migrate-from-identity-anchor-G27MCD6A.js → migrate-from-identity-anchor-EB4XI4Q2.js} +2 -2
- package/dist/model-registry.js +1 -1
- package/dist/models-json.d.ts +1 -0
- package/dist/namespaces/migrate.d.ts +3 -0
- package/dist/namespaces/migrate.js +24 -22
- package/dist/namespaces/principal.d.ts +1 -0
- package/dist/namespaces/principal.js +2 -1
- package/dist/namespaces/search.d.ts +1 -0
- package/dist/namespaces/search.js +15 -13
- package/dist/namespaces/storage.d.ts +4 -2
- package/dist/namespaces/storage.js +10 -9
- package/dist/native-knowledge.d.ts +1 -0
- package/dist/native-knowledge.js +1 -1
- package/dist/negative.js +1 -1
- package/dist/network/webdav.d.ts +16 -1
- package/dist/network/webdav.js +5 -3
- package/dist/objective-state-writers.js +4 -4
- package/dist/objective-state.js +2 -2
- package/dist/offline-sync.d.ts +8 -1
- package/dist/offline-sync.js +6 -4
- package/dist/operator-toolkit.d.ts +1 -0
- package/dist/operator-toolkit.js +35 -32
- package/dist/opik-exporter.js +1 -1
- package/dist/{orchestrator-DuWl9Hwx.d.ts → orchestrator-Co9nxRLF.d.ts} +4 -74
- package/dist/orchestrator.d.ts +5 -3
- package/dist/orchestrator.js +99 -96
- package/dist/page-versioning.js +1 -1
- package/dist/path-X2K5XCHL.js +9 -0
- package/dist/patterns-cli.d.ts +1 -0
- package/dist/peers/index.d.ts +328 -0
- package/dist/{peers-HCVGHMAE.js → peers/index.js} +4 -4
- package/dist/pipeline-D18UAKlN.d.ts +32 -0
- package/dist/plugin-entry-resolver.d.ts +9 -0
- package/dist/plugin-entry-resolver.js +8 -0
- package/dist/plugin-entry-resolver.js.map +1 -0
- package/dist/plugin-id.d.ts +2 -21
- package/dist/plugin-id.js +33 -4
- package/dist/plugin-id.js.map +1 -1
- package/dist/policy-runtime.d.ts +4 -0
- package/dist/policy-runtime.js +1 -1
- package/dist/profiling.js +1 -1
- package/dist/qmd-recall-cache.d.ts +1 -0
- package/dist/qmd.d.ts +1 -0
- package/dist/qmd.js +3 -3
- package/dist/recall-disclosure-escalation.d.ts +1 -0
- package/dist/recall-explain-renderer.d.ts +1 -0
- package/dist/recall-explain-renderer.js +3 -3
- package/dist/recall-state.d.ts +8 -1
- package/dist/recall-state.js +2 -1
- package/dist/recall-tag-filter.d.ts +1 -0
- package/dist/recall-xray-cli.d.ts +1 -0
- package/dist/recall-xray-cli.js +4 -4
- package/dist/recall-xray-renderer.d.ts +1 -0
- package/dist/recall-xray-renderer.js +3 -3
- package/dist/recall-xray.d.ts +1 -0
- package/dist/recall-xray.js +2 -2
- package/dist/relevance.d.ts +7 -1
- package/dist/relevance.js +2 -1
- package/dist/replay/normalizers/chatgpt.js +2 -2
- package/dist/replay/normalizers/claude.js +2 -2
- package/dist/replay/normalizers/openclaw.js +2 -2
- package/dist/replay/normalizers/shared.js +1 -1
- package/dist/replay/runner.js +1 -1
- package/dist/rerank.js +1 -1
- package/dist/{resolution-B7FNQSSP.js → resolution-ZY7VM6WS.js} +3 -3
- package/dist/resolution-ZY7VM6WS.js.map +1 -0
- package/dist/resolve-auth-token.d.ts +1 -0
- package/dist/resolve-auth-token.js +1 -1
- package/dist/resolve-provider-secret.d.ts +19 -29
- package/dist/resolve-provider-secret.js +2 -6
- package/dist/resume-bundles.js +10 -9
- package/dist/retrieval-agents.d.ts +2 -1
- package/dist/retrieval-agents.js +2 -1
- package/dist/retrieval-tiers.d.ts +1 -0
- package/dist/routing/engine.d.ts +1 -0
- package/dist/routing/store.d.ts +3 -0
- package/dist/routing/store.js +1 -1
- package/dist/runtime/env.js +1 -1
- package/dist/schemas.d.ts +213 -39
- package/dist/schemas.js +1 -1
- package/dist/sdk-compat.js +1 -1
- package/dist/search/document-scanner.js +1 -1
- package/dist/search/embed-helper.d.ts +7 -2
- package/dist/search/embed-helper.js +3 -1
- package/dist/search/factory.d.ts +2 -1
- package/dist/search/factory.js +13 -12
- package/dist/search/index.d.ts +2 -1
- package/dist/search/index.js +19 -18
- package/dist/search/lancedb-backend.d.ts +7 -6
- package/dist/search/lancedb-backend.js +4 -2
- package/dist/search/meilisearch-backend.d.ts +7 -6
- package/dist/search/meilisearch-backend.js +4 -2
- package/dist/search/noop-backend.d.ts +1 -0
- package/dist/search/orama-backend.d.ts +9 -7
- package/dist/search/orama-backend.js +8 -4
- package/dist/search/port.d.ts +1 -0
- package/dist/search/remote-backend.d.ts +1 -0
- package/dist/secure-store/index.d.ts +16 -3
- package/dist/secure-store/index.js +2 -2
- package/dist/{semantic-VwGI14Ok.d.ts → semantic-SLAa_prH.d.ts} +5 -3
- package/dist/semantic-consolidation.d.ts +1 -0
- package/dist/semantic-consolidation.js +14 -13
- package/dist/semantic-rule-promotion.js +8 -8
- package/dist/semantic-rule-verifier.d.ts +1 -0
- package/dist/semantic-rule-verifier.js +8 -8
- package/dist/session-integrity.d.ts +1 -0
- package/dist/session-integrity.js +1 -1
- package/dist/session-observer-bands.d.ts +1 -0
- package/dist/session-observer-state.d.ts +6 -1
- package/dist/session-observer-state.js +1 -1
- package/dist/shared-context/manager.d.ts +5 -0
- package/dist/shared-context/manager.js +3 -3
- package/dist/signal.d.ts +1 -0
- package/dist/signal.js +1 -1
- package/dist/source-attribution.js +1 -1
- package/dist/state-store-4QZISH3J.js +30 -0
- package/dist/state-store-4QZISH3J.js.map +1 -0
- package/dist/storage-C4DX8CuG.d.ts +157 -0
- package/dist/storage.d.ts +2 -0
- package/dist/storage.js +7 -7
- package/dist/store-contract.js +1 -1
- package/dist/summarizer.d.ts +1 -0
- package/dist/summarizer.js +7 -7
- package/dist/summary-snapshot.d.ts +1 -0
- package/dist/surfaces/dreams.js +48 -17
- package/dist/surfaces/dreams.js.map +1 -1
- package/dist/temporal-supersession.d.ts +1 -0
- package/dist/temporal-supersession.js +1 -1
- package/dist/temporal-validity.d.ts +1 -0
- package/dist/threading.d.ts +1 -0
- package/dist/tier-migration.d.ts +1 -0
- package/dist/tier-routing.d.ts +1 -0
- package/dist/{tier-stats-62ZVDFKS.js → tier-stats-SKML2OSF.js} +5 -5
- package/dist/tmt.js +1 -1
- package/dist/tokens.js +2 -2
- package/dist/topics.d.ts +1 -0
- package/dist/{trace-C5ETWBEF.js → trace-WM7V4CKI.js} +31 -1
- package/dist/trace-WM7V4CKI.js.map +1 -0
- package/dist/transcript.d.ts +1 -0
- package/dist/transcript.js +2 -2
- package/dist/transfer/autodetect.js +7 -7
- package/dist/transfer/backup.js +5 -5
- package/dist/transfer/capsule-export.js +5 -5
- package/dist/transfer/capsule-import.d.ts +6 -0
- package/dist/transfer/capsule-import.js +4 -4
- package/dist/transfer/export-json.js +3 -3
- package/dist/transfer/export-md.js +3 -3
- package/dist/transfer/export-sqlite.js +3 -3
- package/dist/transfer/fs-utils.d.ts +2 -1
- package/dist/transfer/fs-utils.js +5 -3
- package/dist/transfer/import-json.js +3 -3
- package/dist/transfer/import-md.js +3 -3
- package/dist/transfer/import-sqlite.js +3 -3
- package/dist/transfer/types.d.ts +12 -12
- package/dist/trust-zones.js +2 -2
- package/dist/types-B1VHaf2w.d.ts +126 -0
- package/dist/types-BliCnURB.d.ts +83 -0
- package/dist/types.d.ts +35 -0
- package/dist/types.js +1 -1
- package/dist/utility-learner.js +3 -3
- package/dist/utility-runtime.d.ts +1 -0
- package/dist/utility-runtime.js +4 -4
- package/dist/utility-telemetry.js +2 -2
- package/dist/verified-recall.js +9 -9
- package/dist/work/board.js +2 -2
- package/dist/work/boundary.js +1 -1
- package/dist/work/storage.d.ts +5 -0
- package/dist/work/storage.js +1 -1
- package/dist/work-product-ledger.js +2 -2
- package/package.json +74 -3
- package/scripts/ensure-better-sqlite3.mjs +8 -7
- package/scripts/faiss_index.py +141 -29
- package/src/access-cli.test.ts +87 -2
- package/src/access-cli.ts +59 -5
- package/src/access-http.test.ts +321 -0
- package/src/access-http.ts +201 -35
- package/src/access-idempotency.ts +136 -3
- package/src/access-mcp.test.ts +155 -0
- package/src/access-mcp.ts +116 -30
- package/src/access-schema.ts +22 -4
- package/src/access-service-project-tag.test.ts +37 -0
- package/src/access-service.ts +42 -10
- package/src/active-recall.test.ts +29 -1
- package/src/active-recall.ts +11 -7
- package/src/adapters/claude-code.ts +7 -8
- package/src/adapters/codex.ts +6 -7
- package/src/adapters/hermes.ts +1 -5
- package/src/adapters/registry.test.ts +63 -0
- package/src/adapters/registry.ts +10 -0
- package/src/adapters/replit.ts +5 -7
- package/src/adapters/types.ts +24 -1
- package/src/behavior-signals.ts +1 -1
- package/src/binary-lifecycle/backend.ts +16 -4
- package/src/binary-lifecycle/pipeline.test.ts +149 -0
- package/src/binary-lifecycle/pipeline.ts +49 -7
- package/src/binary-lifecycle/scanner.ts +19 -4
- package/src/boxes.ts +119 -32
- package/src/buffer-session.test.ts +28 -0
- package/src/buffer.ts +10 -14
- package/src/bulk-import/types.ts +10 -0
- package/src/calibration.test.ts +99 -0
- package/src/calibration.ts +57 -13
- package/src/causal-consolidation.test.ts +214 -0
- package/src/causal-consolidation.ts +131 -14
- package/src/causal-retrieval.ts +16 -3
- package/src/citations.test.ts +75 -0
- package/src/citations.ts +19 -6
- package/src/cli.ts +134 -109
- package/src/coding/coding-namespace.test.ts +7 -0
- package/src/coding/coding-namespace.ts +8 -0
- package/src/coding/review-context.test.ts +30 -0
- package/src/coding/review-context.ts +79 -9
- package/src/coding/wire-coding-context.test.ts +16 -0
- package/src/compat/checks.test.ts +33 -0
- package/src/compat/checks.ts +64 -4
- package/src/compounding/engine.ts +2 -2
- package/src/compounding/preference-consolidator.test.ts +47 -0
- package/src/compounding/preference-consolidator.ts +8 -8
- package/src/compression-optimizer.ts +5 -2
- package/src/config.test.ts +34 -2
- package/src/config.ts +62 -18
- package/src/connectors/codex-materialize-runner.ts +4 -3
- package/src/connectors/codex-materialize.ts +149 -34
- package/src/connectors/index.test.ts +144 -7
- package/src/connectors/index.ts +86 -15
- package/src/connectors/live/github.test.ts +47 -0
- package/src/connectors/live/github.ts +29 -1
- package/src/connectors/live/index.ts +2 -0
- package/src/connectors/live/live-connectors.test.ts +359 -73
- package/src/connectors/live/notion.test.ts +84 -0
- package/src/connectors/live/notion.ts +18 -1
- package/src/connectors/live/state-store.ts +419 -38
- package/src/connectors/weclone-installer.test.ts +16 -18
- package/src/connectors-cli.ts +19 -0
- package/src/console/trace.test.ts +28 -0
- package/src/console/trace.ts +42 -5
- package/src/contradiction/contradiction-judge.test.ts +49 -0
- package/src/contradiction/contradiction-judge.ts +15 -5
- package/src/contradiction/contradiction-review.ts +31 -7
- package/src/contradiction/contradiction-scan.ts +28 -18
- package/src/contradiction/contradiction.test.ts +237 -1
- package/src/contradiction/resolution.ts +43 -4
- package/src/conversation-index/backend.ts +13 -5
- package/src/conversation-index/cleanup.ts +25 -4
- package/src/conversation-index/faiss-adapter.ts +24 -15
- package/src/conversation-index/indexer.test.ts +71 -10
- package/src/conversation-index/indexer.ts +22 -3
- package/src/cross-namespace-budget.test.ts +59 -0
- package/src/cross-namespace-budget.ts +15 -7
- package/src/curation/index.ts +18 -17
- package/src/dashboard-runtime.test.ts +98 -0
- package/src/dashboard-runtime.ts +96 -6
- package/src/dedup/index.test.ts +133 -0
- package/src/dedup/index.ts +73 -10
- package/src/dedup/semantic.test.ts +77 -2
- package/src/dedup/semantic.ts +26 -6
- package/src/embedding-fallback.ts +47 -15
- package/src/enrichment/audit.ts +8 -1
- package/src/enrichment/pipeline.ts +21 -13
- package/src/enrichment/web-search-provider.ts +1 -6
- package/src/entity-retrieval.ts +57 -6
- package/src/evals.ts +22 -13
- package/src/explicit-capture.test.ts +40 -0
- package/src/explicit-capture.ts +14 -2
- package/src/extraction.ts +42 -30
- package/src/fallback-llm.ts +35 -2
- package/src/graph-dashboard-diff.test.ts +57 -0
- package/src/graph-dashboard-diff.ts +24 -2
- package/src/graph-dashboard-parser.test.ts +31 -0
- package/src/graph-dashboard-parser.ts +4 -1
- package/src/graph-events.ts +6 -4
- package/src/graph.test.ts +69 -0
- package/src/graph.ts +7 -4
- package/src/importers/base.test.ts +70 -0
- package/src/importers/base.ts +56 -7
- package/src/index.ts +6 -2
- package/src/lcm/archive.ts +65 -16
- package/src/lcm/engine.ts +27 -8
- package/src/lcm/recall.ts +5 -5
- package/src/lcm-engine.test.ts +87 -1
- package/src/lcm-recall.test.ts +71 -0
- package/src/live-connectors-runner.ts +100 -36
- package/src/maintenance/archive-observations.ts +24 -3
- package/src/maintenance/atomic-file.ts +85 -0
- package/src/maintenance/dreams-ledger.ts +15 -8
- package/src/maintenance/memory-governance.test.ts +53 -0
- package/src/maintenance/memory-governance.ts +15 -5
- package/src/maintenance/observation-ledger-utils.ts +6 -5
- package/src/maintenance/purge.test.ts +64 -0
- package/src/maintenance/rebuild-memory-lifecycle-ledger.ts +22 -9
- package/src/maintenance/rebuild-memory-projection.ts +22 -9
- package/src/maintenance/rebuild-observations.ts +7 -3
- package/src/mcp-memory-inspector-app.ts +26 -3
- package/src/memory-cache.test.ts +19 -0
- package/src/memory-cache.ts +1 -0
- package/src/memory-extension/codex-publisher.ts +25 -4
- package/src/memory-extension-host/host-discovery.test.ts +69 -0
- package/src/memory-extension-host/host-discovery.ts +63 -6
- package/src/memory-projection-store.ts +114 -62
- package/src/message-parts/index.ts +46 -31
- package/src/message-parts/message-parts.test.ts +77 -0
- package/src/migrate/from-engram.ts +68 -14
- package/src/model-registry.test.ts +38 -0
- package/src/model-registry.ts +12 -7
- package/src/namespaces/identity.test.ts +66 -0
- package/src/namespaces/identity.ts +23 -0
- package/src/namespaces/migrate.test.ts +62 -0
- package/src/namespaces/migrate.ts +82 -14
- package/src/namespaces/principal.test.ts +37 -1
- package/src/namespaces/principal.ts +18 -7
- package/src/namespaces/search.test.ts +76 -6
- package/src/namespaces/search.ts +22 -21
- package/src/namespaces/storage.ts +93 -11
- package/src/native-knowledge.ts +23 -3
- package/src/negative.ts +50 -5
- package/src/network/webdav.ts +177 -58
- package/src/offline-sync.ts +22 -11
- package/src/onboarding/index.test.ts +105 -0
- package/src/onboarding/index.ts +17 -5
- package/src/operator-toolkit.ts +39 -4
- package/src/orchestrator.ts +52 -17
- package/src/page-versioning.ts +31 -5
- package/src/peers/peers.test.ts +70 -0
- package/src/peers/storage.ts +32 -3
- package/src/plugin-entry-resolver.test.ts +60 -0
- package/src/plugin-entry-resolver.ts +48 -0
- package/src/plugin-id.test.ts +38 -0
- package/src/plugin-id.ts +31 -64
- package/src/policy-runtime.test.ts +75 -0
- package/src/policy-runtime.ts +32 -3
- package/src/procedural/procedure-miner.test.ts +152 -0
- package/src/procedural/procedure-miner.ts +124 -19
- package/src/profiling.test.ts +23 -0
- package/src/profiling.ts +10 -1
- package/src/projection/index.test.ts +253 -0
- package/src/projection/index.ts +159 -18
- package/src/qmd-client.test.ts +45 -0
- package/src/qmd.ts +8 -8
- package/src/recall-disclosure.test.ts +15 -1
- package/src/recall-state.ts +24 -5
- package/src/relevance.ts +24 -5
- package/src/replay/normalizers/chatgpt.ts +14 -4
- package/src/replay/normalizers/claude.ts +8 -3
- package/src/replay/normalizers/openclaw.ts +35 -12
- package/src/replay/normalizers/replay-normalizers.test.ts +65 -0
- package/src/replay/normalizers/shared.ts +4 -1
- package/src/replay/runner.ts +1 -1
- package/src/rerank.test.ts +41 -1
- package/src/rerank.ts +2 -2
- package/src/resolve-auth-token.test.ts +29 -0
- package/src/resolve-auth-token.ts +12 -7
- package/src/resolve-provider-secret.test.ts +78 -22
- package/src/resolve-provider-secret.ts +55 -223
- package/src/retrieval-agents.ts +51 -14
- package/src/review/index.test.ts +75 -1
- package/src/review/index.ts +88 -30
- package/src/routing/store.ts +36 -6
- package/src/runtime/env.test.ts +73 -0
- package/src/runtime/env.ts +7 -11
- package/src/schemas.ts +16 -1
- package/src/search/abort.ts +18 -0
- package/src/search/document-scanner.test.ts +80 -0
- package/src/search/document-scanner.ts +51 -9
- package/src/search/embed-helper.ts +19 -6
- package/src/search/factory.ts +9 -5
- package/src/search/lancedb-backend.ts +62 -22
- package/src/search/meilisearch-backend.ts +35 -12
- package/src/search/orama-backend.test.ts +27 -0
- package/src/search/orama-backend.ts +65 -15
- package/src/secure-store/cli-handlers.ts +70 -6
- package/src/secure-store/cli-renderer.ts +13 -7
- package/src/secure-store/secure-fs.ts +11 -5
- package/src/secure-store/secure-store.test.ts +70 -0
- package/src/semantic-consolidation.test.ts +45 -0
- package/src/semantic-consolidation.ts +3 -3
- package/src/session-integrity.test.ts +98 -0
- package/src/session-integrity.ts +51 -1
- package/src/session-observer-state.ts +108 -41
- package/src/shared-context/manager.ts +93 -15
- package/src/signal.test.ts +14 -0
- package/src/signal.ts +8 -1
- package/src/source-attribution.test.ts +8 -0
- package/src/source-attribution.ts +24 -2
- package/src/spaces/index.test.ts +93 -0
- package/src/spaces/index.ts +75 -9
- package/src/storage.ts +14 -1
- package/src/store-contract.test.ts +35 -0
- package/src/store-contract.ts +39 -5
- package/src/summarizer.ts +24 -18
- package/src/summary-snapshot.test.ts +77 -0
- package/src/surfaces/dreams.test.ts +73 -0
- package/src/surfaces/dreams.ts +53 -19
- package/src/sync/index.ts +42 -17
- package/src/taxonomy/taxonomy-loader.ts +43 -4
- package/src/temporal-supersession.test.ts +67 -0
- package/src/temporal-supersession.ts +8 -0
- package/src/tmt.test.ts +50 -0
- package/src/tmt.ts +35 -11
- package/src/tokens.test.ts +18 -0
- package/src/tokens.ts +7 -0
- package/src/training-export/converter.test.ts +55 -2
- package/src/training-export/converter.ts +36 -10
- package/src/training-export/registry.test.ts +17 -0
- package/src/training-export/registry.ts +19 -1
- package/src/transcript.ts +2 -2
- package/src/transfer/backup.ts +18 -7
- package/src/transfer/capsule-crypto.ts +105 -21
- package/src/transfer/capsule-encrypt.test.ts +106 -7
- package/src/transfer/capsule-export.ts +23 -14
- package/src/transfer/capsule-import.ts +11 -2
- package/src/transfer/exclusions.ts +7 -0
- package/src/transfer/export-sqlite.ts +14 -13
- package/src/transfer/fs-utils.ts +52 -1
- package/src/transfer/import-json.ts +12 -7
- package/src/transfer/import-md.ts +5 -5
- package/src/transfer/import-sqlite.ts +4 -5
- package/src/trust-zones.ts +1 -1
- package/src/types.ts +25 -0
- package/src/utility-telemetry.ts +1 -1
- package/src/utils/category-dir.test.ts +15 -0
- package/src/utils/category-dir.ts +3 -1
- package/src/work/boundary.ts +30 -18
- package/src/work/storage.ts +116 -38
- package/src/work-product-ledger.ts +1 -1
- package/dist/chunk-25MQ7IHJ.js.map +0 -1
- package/dist/chunk-2IWUMAES.js.map +0 -1
- package/dist/chunk-2NMMFZ5T.js.map +0 -1
- package/dist/chunk-2PRLKQAH.js.map +0 -1
- package/dist/chunk-326G7DJK.js.map +0 -1
- package/dist/chunk-3APJ5EVB.js.map +0 -1
- package/dist/chunk-3KW65B36.js.map +0 -1
- package/dist/chunk-3OWUCDKH.js.map +0 -1
- package/dist/chunk-3QKK7QOS.js.map +0 -1
- package/dist/chunk-3SLRNYNG.js.map +0 -1
- package/dist/chunk-3VAL7ZL2.js.map +0 -1
- package/dist/chunk-3Y4P7RXM.js.map +0 -1
- package/dist/chunk-43PJZYGL.js.map +0 -1
- package/dist/chunk-47VWKCAF.js.map +0 -1
- package/dist/chunk-4KGVTPGD.js.map +0 -1
- package/dist/chunk-5375UYTQ.js.map +0 -1
- package/dist/chunk-56K5QLHX.js.map +0 -1
- package/dist/chunk-575RMLWN.js.map +0 -1
- package/dist/chunk-5NPGSAVB.js.map +0 -1
- package/dist/chunk-5RGLBDQF.js.map +0 -1
- package/dist/chunk-65PG43EQ.js.map +0 -1
- package/dist/chunk-66DHUKLO.js.map +0 -1
- package/dist/chunk-6LVVDPJ4.js.map +0 -1
- package/dist/chunk-76FLAAUC.js.map +0 -1
- package/dist/chunk-77H5NU3M.js.map +0 -1
- package/dist/chunk-7MNMYOFP.js.map +0 -1
- package/dist/chunk-7OZ53EXP.js.map +0 -1
- package/dist/chunk-7SEAZFFB.js.map +0 -1
- package/dist/chunk-A6KTB5R6.js.map +0 -1
- package/dist/chunk-AGZQD76C.js.map +0 -1
- package/dist/chunk-APO3DCMU.js.map +0 -1
- package/dist/chunk-BVF3AGJP.js.map +0 -1
- package/dist/chunk-C5BCH4ZS.js.map +0 -1
- package/dist/chunk-C7VW7C3F.js.map +0 -1
- package/dist/chunk-CULXMQJH.js.map +0 -1
- package/dist/chunk-CYFQJMUV.js.map +0 -1
- package/dist/chunk-D654IBA6.js +0 -61
- package/dist/chunk-D654IBA6.js.map +0 -1
- package/dist/chunk-DGXUHMOV.js.map +0 -1
- package/dist/chunk-DINWEURR.js.map +0 -1
- package/dist/chunk-DK5LDEQM.js.map +0 -1
- package/dist/chunk-EABGC2TL.js.map +0 -1
- package/dist/chunk-EHRTFRWW.js.map +0 -1
- package/dist/chunk-EJI5XIBB.js.map +0 -1
- package/dist/chunk-FAAFWE4G.js.map +0 -1
- package/dist/chunk-FAJ7FZYM.js +0 -11
- package/dist/chunk-FAJ7FZYM.js.map +0 -1
- package/dist/chunk-FDU6HUUL.js +0 -147
- package/dist/chunk-FDU6HUUL.js.map +0 -1
- package/dist/chunk-FIT6DMX6.js.map +0 -1
- package/dist/chunk-FJ43PRLT.js.map +0 -1
- package/dist/chunk-FLTNHQK6.js +0 -262
- package/dist/chunk-FLTNHQK6.js.map +0 -1
- package/dist/chunk-GDFS42HT.js.map +0 -1
- package/dist/chunk-H3ME6L6D.js.map +0 -1
- package/dist/chunk-HXXBL2KD.js.map +0 -1
- package/dist/chunk-ICRIXAP2.js.map +0 -1
- package/dist/chunk-IQT3XTKW.js.map +0 -1
- package/dist/chunk-JR4ZC3G4.js.map +0 -1
- package/dist/chunk-K4FLSOR5.js.map +0 -1
- package/dist/chunk-KNKUID7G.js.map +0 -1
- package/dist/chunk-KOSORCJG.js.map +0 -1
- package/dist/chunk-KRBK4BQH.js.map +0 -1
- package/dist/chunk-LIRZNNUP.js.map +0 -1
- package/dist/chunk-LLQ2LLWF.js.map +0 -1
- package/dist/chunk-LPMVBPA3.js +0 -236
- package/dist/chunk-LPMVBPA3.js.map +0 -1
- package/dist/chunk-LT3NLYSI.js.map +0 -1
- package/dist/chunk-LUDTDZLK.js.map +0 -1
- package/dist/chunk-MG7NA5H3.js.map +0 -1
- package/dist/chunk-MJFNCJXV.js.map +0 -1
- package/dist/chunk-MSWG7JI6.js.map +0 -1
- package/dist/chunk-MXC3AP5I.js.map +0 -1
- package/dist/chunk-MXFBBHJU.js.map +0 -1
- package/dist/chunk-MZH6EHNR.js.map +0 -1
- package/dist/chunk-N2D6GXBM.js.map +0 -1
- package/dist/chunk-NBNN5GOB.js.map +0 -1
- package/dist/chunk-NMZY542O.js.map +0 -1
- package/dist/chunk-NZL6GGQE.js.map +0 -1
- package/dist/chunk-OC7KHOOX.js.map +0 -1
- package/dist/chunk-OZHRDTDX.js.map +0 -1
- package/dist/chunk-PZIAX57I.js.map +0 -1
- package/dist/chunk-Q7P4WJDP.js.map +0 -1
- package/dist/chunk-QA2ZAPBU.js.map +0 -1
- package/dist/chunk-QDZ2RLEC.js.map +0 -1
- package/dist/chunk-QKZGQIPJ.js.map +0 -1
- package/dist/chunk-QLLBRHAT.js.map +0 -1
- package/dist/chunk-QR3C7BKQ.js.map +0 -1
- package/dist/chunk-RHY3HH7P.js.map +0 -1
- package/dist/chunk-RK2Y4XOM.js.map +0 -1
- package/dist/chunk-RR2PKP3I.js +0 -63
- package/dist/chunk-RR2PKP3I.js.map +0 -1
- package/dist/chunk-RRF5UOBJ.js.map +0 -1
- package/dist/chunk-RXDLTSWT.js.map +0 -1
- package/dist/chunk-RYED3SPJ.js +0 -42
- package/dist/chunk-RYED3SPJ.js.map +0 -1
- package/dist/chunk-S7KDBTWT.js.map +0 -1
- package/dist/chunk-TK4UEOSK.js.map +0 -1
- package/dist/chunk-TMM4S4IJ.js.map +0 -1
- package/dist/chunk-TMQLARTH.js.map +0 -1
- package/dist/chunk-TPB3I2AC.js.map +0 -1
- package/dist/chunk-TPMQ3G6Z.js.map +0 -1
- package/dist/chunk-TZOLIGIG.js.map +0 -1
- package/dist/chunk-U3WSW6PZ.js.map +0 -1
- package/dist/chunk-U4SCL7B7.js.map +0 -1
- package/dist/chunk-U66YHYC7.js +0 -31
- package/dist/chunk-U66YHYC7.js.map +0 -1
- package/dist/chunk-UL2NNBUL.js.map +0 -1
- package/dist/chunk-UWVJF25J.js.map +0 -1
- package/dist/chunk-VBJ7V5SK.js.map +0 -1
- package/dist/chunk-W3LR522O.js.map +0 -1
- package/dist/chunk-W4L6CZKA.js.map +0 -1
- package/dist/chunk-W6AQJ2PY.js.map +0 -1
- package/dist/chunk-WELDCG6C.js.map +0 -1
- package/dist/chunk-WNARATI3.js.map +0 -1
- package/dist/chunk-WPGJYVUH.js.map +0 -1
- package/dist/chunk-WW3QQF4H.js.map +0 -1
- package/dist/chunk-XIG5PDM7.js.map +0 -1
- package/dist/chunk-XKECPATV.js.map +0 -1
- package/dist/chunk-XKLD5OK4.js.map +0 -1
- package/dist/chunk-XSZEP4SF.js.map +0 -1
- package/dist/chunk-XVVIG67A.js.map +0 -1
- package/dist/chunk-XYIK4LF6.js.map +0 -1
- package/dist/chunk-YRMVARQP.js.map +0 -1
- package/dist/chunk-ZPKBYX2F.js.map +0 -1
- package/dist/chunk-ZTFCYYEZ.js.map +0 -1
- package/dist/chunk-ZYVPLJ4T.js.map +0 -1
- package/dist/path-MR5JPYOP.js +0 -9
- package/dist/state-store-VZU2IA53.js +0 -16
- package/dist/trace-C5ETWBEF.js.map +0 -1
- /package/dist/{capsule-crypto-5CYAGVC5.js.map → bulk-import/index.js.map} +0 -0
- /package/dist/{contradiction-review-ATP4S6IC.js.map → capsule-crypto-7FJQINUR.js.map} +0 -0
- /package/dist/{capsule-merge-4MGKE7C5.js.map → capsule-merge-T2JRE46P.js.map} +0 -0
- /package/dist/{chunk-SAZS2QZB.js.map → chunk-23UORJ4S.js.map} +0 -0
- /package/dist/{chunk-PK7H5L6Y.js.map → chunk-2NM43EWN.js.map} +0 -0
- /package/dist/{chunk-PYXS46O7.js.map → chunk-3BP57I6J.js.map} +0 -0
- /package/dist/{chunk-FBYESMQ2.js.map → chunk-3C5RPJAX.js.map} +0 -0
- /package/dist/{chunk-N53K2EXC.js.map → chunk-6VF75M3X.js.map} +0 -0
- /package/dist/{chunk-6H2TESSP.js.map → chunk-765K3SAT.js.map} +0 -0
- /package/dist/{chunk-EDTHC6UD.js.map → chunk-77NAFXUD.js.map} +0 -0
- /package/dist/{chunk-MGKYQQYF.js.map → chunk-7Q3RCKAQ.js.map} +0 -0
- /package/dist/{chunk-34DQE4KF.js.map → chunk-CO7ZO4TU.js.map} +0 -0
- /package/dist/{chunk-ZKSK55RC.js.map → chunk-ETUPBUHB.js.map} +0 -0
- /package/dist/{chunk-QRNI5JBH.js.map → chunk-EYIEWJNI.js.map} +0 -0
- /package/dist/{chunk-C6QPK5GG.js.map → chunk-FZZ2QTJI.js.map} +0 -0
- /package/dist/{chunk-3JXBXXM2.js.map → chunk-G4IAEX6D.js.map} +0 -0
- /package/dist/{chunk-2WWLHTZY.js.map → chunk-IC4GELZE.js.map} +0 -0
- /package/dist/{chunk-PCUKNJAZ.js.map → chunk-JKV57BTN.js.map} +0 -0
- /package/dist/{chunk-2KI4QFHU.js.map → chunk-LMDRGRJ2.js.map} +0 -0
- /package/dist/{chunk-MY6TPVXW.js.map → chunk-LMPHTYJC.js.map} +0 -0
- /package/dist/{chunk-5HRY2WRF.js.map → chunk-LZ3VEOU5.js.map} +0 -0
- /package/dist/{chunk-NGAVDO7E.js.map → chunk-OADWQ5CR.js.map} +0 -0
- /package/dist/{chunk-DOM4GKSW.js.map → chunk-OZKVVUJB.js.map} +0 -0
- /package/dist/{chunk-MT4HVDUZ.js.map → chunk-PM3QHTFT.js.map} +0 -0
- /package/dist/{chunk-ZK7I7JYV.js.map → chunk-R3PS27B4.js.map} +0 -0
- /package/dist/{chunk-SKE7JYKA.js.map → chunk-SFXKHM7P.js.map} +0 -0
- /package/dist/{chunk-HMDCOMYU.js.map → chunk-SKGV326D.js.map} +0 -0
- /package/dist/{chunk-5UM2VJ6D.js.map → chunk-UEY3VB6W.js.map} +0 -0
- /package/dist/{chunk-GIF42EW3.js.map → chunk-UP6MOYCB.js.map} +0 -0
- /package/dist/{chunk-MRILGULB.js.map → chunk-V2RCP53Q.js.map} +0 -0
- /package/dist/{chunk-FSFEQI74.js.map → chunk-W7L6HXUC.js.map} +0 -0
- /package/dist/{chunk-3IQ2TR4N.js.map → chunk-WLEB7WCG.js.map} +0 -0
- /package/dist/{chunk-GL6I6MEQ.js.map → chunk-WSGF57U2.js.map} +0 -0
- /package/dist/{chunk-JA3AK3PT.js.map → chunk-XNLXAWHX.js.map} +0 -0
- /package/dist/{chunk-SIC6U3GZ.js.map → chunk-YHV3KRKS.js.map} +0 -0
- /package/dist/{chunk-VLXA6PI2.js.map → chunk-YQMZ7IH2.js.map} +0 -0
- /package/dist/{contradiction-scan-5A4IDZV5.js.map → contradiction-review-6V2LXXK6.js.map} +0 -0
- /package/dist/{migrate-from-identity-anchor-G27MCD6A.js.map → contradiction-scan-GIRVC4C7.js.map} +0 -0
- /package/dist/{first-start-migration-4MHQEOSD.js.map → first-start-migration-CKTCTCQI.js.map} +0 -0
- /package/dist/{graph-edge-decay-5DI5GUNL.js.map → graph-edge-decay-MUP5J7CC.js.map} +0 -0
- /package/dist/{path-MR5JPYOP.js.map → importers/index.js.map} +0 -0
- /package/dist/{peers-HCVGHMAE.js.map → migrate-from-identity-anchor-EB4XI4Q2.js.map} +0 -0
- /package/dist/{resolution-B7FNQSSP.js.map → path-X2K5XCHL.js.map} +0 -0
- /package/dist/{state-store-VZU2IA53.js.map → peers/index.js.map} +0 -0
- /package/dist/{tier-stats-62ZVDFKS.js.map → tier-stats-SKML2OSF.js.map} +0 -0
|
@@ -5,14 +5,14 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
computeTransferOutputRel,
|
|
7
7
|
isTransferPathExcluded
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-UI3NYK34.js";
|
|
9
9
|
import {
|
|
10
10
|
listFilesRecursive,
|
|
11
11
|
readUtf8FileStrict,
|
|
12
12
|
sha256String,
|
|
13
13
|
toPosixRelPath,
|
|
14
14
|
writeJsonFile
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-GCGJW34D.js";
|
|
16
16
|
|
|
17
17
|
// src/transfer/export-json.ts
|
|
18
18
|
import path from "path";
|
|
@@ -60,4 +60,4 @@ async function exportJsonBundle(opts) {
|
|
|
60
60
|
export {
|
|
61
61
|
exportJsonBundle
|
|
62
62
|
};
|
|
63
|
-
//# sourceMappingURL=chunk-
|
|
63
|
+
//# sourceMappingURL=chunk-UP6MOYCB.js.map
|
|
@@ -2,13 +2,16 @@ import {
|
|
|
2
2
|
isTemporalQuery,
|
|
3
3
|
recencyWindowBoundsFromPrompt
|
|
4
4
|
} from "./chunk-V3RXWQIE.js";
|
|
5
|
+
import {
|
|
6
|
+
isAbortError
|
|
7
|
+
} from "./chunk-PVGDJXVK.js";
|
|
5
8
|
import {
|
|
6
9
|
log
|
|
7
10
|
} from "./chunk-2ODBA7MQ.js";
|
|
8
11
|
|
|
9
12
|
// src/retrieval-agents.ts
|
|
10
13
|
import path from "path";
|
|
11
|
-
import { readdir, readFile, stat } from "fs/promises";
|
|
14
|
+
import { lstat, readdir, readFile, realpath, stat } from "fs/promises";
|
|
12
15
|
var PARALLEL_AGENT_WEIGHTS = {
|
|
13
16
|
direct: 1,
|
|
14
17
|
// entity-first: high precision
|
|
@@ -38,8 +41,24 @@ function overlapScore(queryTokens, candidateTokens) {
|
|
|
38
41
|
const hits = queryTokens.filter((t) => candidateSet.has(t)).length;
|
|
39
42
|
return hits / Math.max(queryTokens.length, candidateTokens.length);
|
|
40
43
|
}
|
|
44
|
+
async function resolveContainedRegularFile(memoryDir, candidatePath, canonicalRoot) {
|
|
45
|
+
try {
|
|
46
|
+
const root = canonicalRoot ?? await realpath(memoryDir);
|
|
47
|
+
const absolute = path.isAbsolute(candidatePath) ? path.resolve(candidatePath) : path.resolve(memoryDir, candidatePath);
|
|
48
|
+
const entryStat = await lstat(absolute);
|
|
49
|
+
if (entryStat.isSymbolicLink()) return null;
|
|
50
|
+
const fileStat = await stat(absolute);
|
|
51
|
+
if (!fileStat.isFile()) return null;
|
|
52
|
+
const canonical = await realpath(absolute);
|
|
53
|
+
if (canonical !== root && !canonical.startsWith(root + path.sep)) return null;
|
|
54
|
+
return absolute;
|
|
55
|
+
} catch {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
41
59
|
async function runDirectAgent(query, memoryDir, maxResults = 10) {
|
|
42
60
|
try {
|
|
61
|
+
const canonicalRoot = await realpath(memoryDir);
|
|
43
62
|
const entitiesDir = path.join(memoryDir, "entities");
|
|
44
63
|
let entries;
|
|
45
64
|
try {
|
|
@@ -56,9 +75,12 @@ async function runDirectAgent(query, memoryDir, maxResults = 10) {
|
|
|
56
75
|
const entityTokens = nameWithoutExt.split("-").filter((t) => t.length >= 2).map((t) => t.toLowerCase());
|
|
57
76
|
const score = overlapScore(queryTokens, entityTokens);
|
|
58
77
|
if (score <= 0) continue;
|
|
78
|
+
const fullPath = path.join(entitiesDir, entry);
|
|
79
|
+
const safePath = await resolveContainedRegularFile(memoryDir, fullPath, canonicalRoot);
|
|
80
|
+
if (!safePath) continue;
|
|
59
81
|
results.push({
|
|
60
82
|
docid: nameWithoutExt,
|
|
61
|
-
path:
|
|
83
|
+
path: safePath,
|
|
62
84
|
snippet: "",
|
|
63
85
|
// populated by augmentWithDirectAndTemporal after merge
|
|
64
86
|
score,
|
|
@@ -74,6 +96,7 @@ async function runDirectAgent(query, memoryDir, maxResults = 10) {
|
|
|
74
96
|
}
|
|
75
97
|
async function runTemporalAgent(query, memoryDir, maxResults = 20, candidatePaths) {
|
|
76
98
|
try {
|
|
99
|
+
const canonicalRoot = await realpath(memoryDir);
|
|
77
100
|
let dateIndex = {};
|
|
78
101
|
try {
|
|
79
102
|
const indexPath = path.join(memoryDir, "state", "index_time.json");
|
|
@@ -185,20 +208,21 @@ async function runTemporalAgent(query, memoryDir, maxResults = 20, candidatePath
|
|
|
185
208
|
}
|
|
186
209
|
return result;
|
|
187
210
|
}).catch(() => /* @__PURE__ */ new Map()) : Promise.resolve(/* @__PURE__ */ new Map());
|
|
188
|
-
const [
|
|
189
|
-
Promise.all(entries.map(([p]) =>
|
|
211
|
+
const [safePathResults, pathToTags] = await Promise.all([
|
|
212
|
+
Promise.all(entries.map(([p]) => resolveContainedRegularFile(memoryDir, p, canonicalRoot))),
|
|
190
213
|
tagIndexPromise
|
|
191
214
|
]);
|
|
192
215
|
const results = [];
|
|
193
216
|
for (let i = 0; i < entries.length; i++) {
|
|
194
|
-
if (!existenceResults[i]) continue;
|
|
195
217
|
const [p, dateStr] = entries[i];
|
|
218
|
+
const safePath = safePathResults[i];
|
|
219
|
+
if (!safePath) continue;
|
|
196
220
|
const ageMs = todayMs - new Date(dateStr).getTime();
|
|
197
221
|
const ageDays = ageMs / 864e5;
|
|
198
222
|
const recencyScore = Math.exp(-ageDays / 30);
|
|
199
223
|
let topicBoost = 0;
|
|
200
224
|
if (topicTokens.length > 0) {
|
|
201
|
-
const tags = pathToTags.get(p);
|
|
225
|
+
const tags = pathToTags.get(p) ?? pathToTags.get(safePath);
|
|
202
226
|
if (tags && tags.length > 0) {
|
|
203
227
|
const tagSet = new Set(tags.flatMap((t) => tokenize(t)));
|
|
204
228
|
const hits = topicTokens.filter((t) => tagSet.has(t)).length;
|
|
@@ -206,10 +230,10 @@ async function runTemporalAgent(query, memoryDir, maxResults = 20, candidatePath
|
|
|
206
230
|
}
|
|
207
231
|
}
|
|
208
232
|
const score = recencyScore * (1 + topicBoost * 0.3);
|
|
209
|
-
const baseName = path.basename(
|
|
233
|
+
const baseName = path.basename(safePath, ".md");
|
|
210
234
|
results.push({
|
|
211
235
|
docid: baseName,
|
|
212
|
-
path:
|
|
236
|
+
path: safePath,
|
|
213
237
|
snippet: "",
|
|
214
238
|
// populated by augmentWithDirectAndTemporal after merge
|
|
215
239
|
score,
|
|
@@ -233,6 +257,7 @@ async function runContextualAgent(query, qmd, collection, maxResults, signal) {
|
|
|
233
257
|
);
|
|
234
258
|
return results.map((r) => ({ ...r, agentSource: "contextual" }));
|
|
235
259
|
} catch (err) {
|
|
260
|
+
if (isAbortError(err)) throw err;
|
|
236
261
|
log.debug(`ContextualAgent error: ${err}`);
|
|
237
262
|
return [];
|
|
238
263
|
}
|
|
@@ -264,15 +289,18 @@ function stripFrontmatter(raw) {
|
|
|
264
289
|
if (end === -1) return raw;
|
|
265
290
|
return raw.slice(end + 4).replace(/^\n+/, "");
|
|
266
291
|
}
|
|
267
|
-
async function populateEmptySnippets(results) {
|
|
292
|
+
async function populateEmptySnippets(results, memoryDir) {
|
|
268
293
|
const needsSnippet = results.filter((r) => !r.snippet && r.path);
|
|
269
294
|
if (needsSnippet.length === 0) return results;
|
|
295
|
+
const canonicalRoot = memoryDir ? await realpath(memoryDir).catch(() => null) : null;
|
|
270
296
|
const toRead = needsSnippet.slice(0, MAX_SNIPPET_READS);
|
|
271
297
|
const snippetMap = /* @__PURE__ */ new Map();
|
|
272
298
|
await Promise.all(
|
|
273
299
|
toRead.map(async (r) => {
|
|
274
300
|
try {
|
|
275
|
-
const
|
|
301
|
+
const safePath = canonicalRoot && r.path ? await resolveContainedRegularFile(memoryDir, r.path, canonicalRoot) : null;
|
|
302
|
+
if (!safePath) return;
|
|
303
|
+
const raw = await readFile(safePath, "utf-8");
|
|
276
304
|
const body = stripFrontmatter(raw);
|
|
277
305
|
const preview = body.slice(0, SNIPPET_PREVIEW_CHARS).replace(/\s+/g, " ").trim();
|
|
278
306
|
if (preview) snippetMap.set(r.path, preview);
|
|
@@ -283,7 +311,7 @@ async function populateEmptySnippets(results) {
|
|
|
283
311
|
if (snippetMap.size === 0) return results;
|
|
284
312
|
return results.map((r) => r.path && snippetMap.has(r.path) ? { ...r, snippet: snippetMap.get(r.path) } : r);
|
|
285
313
|
}
|
|
286
|
-
async function mergeWithAgentResults(contextualResults, directResults, temporalResults, weights, maxResults) {
|
|
314
|
+
async function mergeWithAgentResults(contextualResults, directResults, temporalResults, weights, maxResults, memoryDir) {
|
|
287
315
|
if (directResults.length === 0 && temporalResults.length === 0) {
|
|
288
316
|
return contextualResults.slice(0, maxResults);
|
|
289
317
|
}
|
|
@@ -296,7 +324,7 @@ async function mergeWithAgentResults(contextualResults, directResults, temporalR
|
|
|
296
324
|
weights,
|
|
297
325
|
maxResults
|
|
298
326
|
);
|
|
299
|
-
return populateEmptySnippets(merged);
|
|
327
|
+
return populateEmptySnippets(merged, memoryDir);
|
|
300
328
|
}
|
|
301
329
|
async function augmentWithDirectAndTemporal(query, memoryDir, contextualResults, weights, maxPerAgent, maxResults, candidatePaths) {
|
|
302
330
|
if (maxPerAgent === 0) return contextualResults;
|
|
@@ -331,7 +359,7 @@ async function augmentWithDirectAndTemporal(query, memoryDir, contextualResults,
|
|
|
331
359
|
weights,
|
|
332
360
|
maxResults
|
|
333
361
|
);
|
|
334
|
-
return populateEmptySnippets(merged);
|
|
362
|
+
return populateEmptySnippets(merged, memoryDir);
|
|
335
363
|
}
|
|
336
364
|
async function parallelRetrieval(query, qmd, memoryDir, options = {}) {
|
|
337
365
|
const maxResults = options.maxResults ?? 20;
|
|
@@ -351,6 +379,7 @@ async function parallelRetrieval(query, qmd, memoryDir, options = {}) {
|
|
|
351
379
|
return [];
|
|
352
380
|
}) : Promise.resolve([]),
|
|
353
381
|
runContextual ? runContextualAgent(query, qmd, options.collection, maxPerAgent, options.signal).catch((err) => {
|
|
382
|
+
if (isAbortError(err)) throw err;
|
|
354
383
|
log.debug(`parallelRetrieval: ContextualAgent failed \u2014 ${err}`);
|
|
355
384
|
return [];
|
|
356
385
|
}) : Promise.resolve([])
|
|
@@ -364,7 +393,7 @@ async function parallelRetrieval(query, qmd, memoryDir, options = {}) {
|
|
|
364
393
|
options.agentWeights ?? PARALLEL_AGENT_WEIGHTS,
|
|
365
394
|
maxResults
|
|
366
395
|
);
|
|
367
|
-
return populateEmptySnippets(merged);
|
|
396
|
+
return populateEmptySnippets(merged, memoryDir);
|
|
368
397
|
}
|
|
369
398
|
|
|
370
399
|
export {
|
|
@@ -377,4 +406,4 @@ export {
|
|
|
377
406
|
augmentWithDirectAndTemporal,
|
|
378
407
|
parallelRetrieval
|
|
379
408
|
};
|
|
380
|
-
//# sourceMappingURL=chunk-
|
|
409
|
+
//# sourceMappingURL=chunk-USYGGIJZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/retrieval-agents.ts"],"sourcesContent":["/**\n * Parallel Specialized Retrieval (v9.1 — ASMR-inspired)\n *\n * Replaces single-pass hybrid search with three parallel specialized agents:\n *\n * 1. DirectFactAgent — entity-first lookup via entity filename index (<5ms)\n * 2. ContextualAgent — existing hybridSearch (same cost as current single-pass)\n * 3. TemporalAgent — temporal index prefilter + recency scoring (<10ms)\n *\n * All agents run via Promise.all(), so total latency = max(agents), not sum.\n * No new LLM inference is introduced — agents reuse existing search primitives.\n *\n * Graceful degradation: any agent error/timeout does not block the others.\n *\n * References:\n * - Supermemory ASMR: https://blog.supermemory.ai/...\n * - Spec: docs/ideas/parallel-specialized-retrieval.md\n */\n\nimport path from \"node:path\";\nimport { lstat, readdir, readFile, realpath, stat } from \"node:fs/promises\";\nimport { log } from \"./logger.js\";\nimport type { QmdSearchResult } from \"./types.js\";\nimport type { QmdClient } from \"./qmd.js\";\nimport { isTemporalQuery, recencyWindowBoundsFromPrompt } from \"./temporal-index.js\";\nimport { isAbortError } from \"./abort-error.js\";\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\nexport type SearchAgentSource = \"direct\" | \"contextual\" | \"temporal\";\n\nexport interface ParallelSearchResult extends QmdSearchResult {\n /** Which retrieval agent produced this result. */\n agentSource: SearchAgentSource;\n}\n\n/** Source-based weights applied during merge. Higher = higher confidence/precision. */\nexport const PARALLEL_AGENT_WEIGHTS: Record<SearchAgentSource, number> = {\n direct: 1.0, // entity-first: high precision\n temporal: 0.85, // recency-boosted: relevant but broader\n contextual: 0.7, // semantic: broadest, lower precision\n};\n\n// ─── Query classification ────────────────────────────────────────────────────\n\n/**\n * Decide whether a given agent should run for this query.\n * Agent 1 (direct) is the only one that may be skipped — when the query\n * contains no proper-noun-like tokens, entity lookups will return nothing.\n * Agents 2 (contextual) and 3 (temporal) always run.\n */\nexport function shouldRunAgent(\n agent: SearchAgentSource,\n query: string,\n knownEntityCount: number,\n): boolean {\n switch (agent) {\n case \"direct\":\n // Skip only if query has no word-like tokens at all. Both capitalized and\n // lowercase entity names are stored (normalizeEntityName lowercases them),\n // so gating on capitalization would silently skip most real entity lookups.\n return knownEntityCount > 0 || /\\b\\w{2,}/.test(query);\n case \"temporal\":\n // Only run temporal agent when the query actually asks about a time window.\n // Running it for every query injects recency bias into semantic searches.\n return isTemporalQuery(query);\n case \"contextual\":\n return true;\n default:\n return true;\n }\n}\n\n// ─── Helpers ─────────────────────────────────────────────────────────────────\n\nfunction tokenize(value: string): string[] {\n return value\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \" \")\n .trim()\n .split(/\\s+/)\n .filter((t) => t.length >= 2);\n}\n\nfunction overlapScore(queryTokens: string[], candidateTokens: string[]): number {\n if (queryTokens.length === 0 || candidateTokens.length === 0) return 0;\n const candidateSet = new Set(candidateTokens);\n const hits = queryTokens.filter((t) => candidateSet.has(t)).length;\n return hits / Math.max(queryTokens.length, candidateTokens.length);\n}\n\nasync function resolveContainedRegularFile(\n memoryDir: string,\n candidatePath: string,\n canonicalRoot?: string,\n): Promise<string | null> {\n try {\n const root = canonicalRoot ?? await realpath(memoryDir);\n const absolute = path.isAbsolute(candidatePath)\n ? path.resolve(candidatePath)\n : path.resolve(memoryDir, candidatePath);\n const entryStat = await lstat(absolute);\n if (entryStat.isSymbolicLink()) return null;\n const fileStat = await stat(absolute);\n if (!fileStat.isFile()) return null;\n const canonical = await realpath(absolute);\n if (canonical !== root && !canonical.startsWith(root + path.sep)) return null;\n return absolute;\n } catch {\n return null;\n }\n}\n\n// ─── Agent 1: Direct Facts ───────────────────────────────────────────────────\n\n/**\n * Direct Facts Agent — entity-first retrieval.\n *\n * Reads entity filenames from the entities directory and scores them by\n * keyword overlap with the query. Returns matching entity file paths as\n * QmdSearchResult[]. Zero LLM inference; pure file I/O.\n *\n * Cost: readdir on entities/ + filename scoring. Typically <5ms.\n *\n */\nexport async function runDirectAgent(\n query: string,\n memoryDir: string,\n maxResults = 10,\n): Promise<ParallelSearchResult[]> {\n try {\n const canonicalRoot = await realpath(memoryDir);\n const entitiesDir = path.join(memoryDir, \"entities\");\n let entries: string[];\n try {\n entries = await readdir(entitiesDir);\n } catch {\n return []; // entities dir missing or unreadable — not an error\n }\n\n const queryTokens = tokenize(query);\n if (queryTokens.length === 0) return [];\n\n const results: ParallelSearchResult[] = [];\n for (const entry of entries) {\n if (!entry.endsWith(\".md\")) continue;\n\n // Filename tokens: split on hyphens (normalizeEntityName uses hyphens)\n const nameWithoutExt = entry.slice(0, -3);\n const entityTokens = nameWithoutExt.split(\"-\").filter((t) => t.length >= 2).map((t) => t.toLowerCase());\n\n const score = overlapScore(queryTokens, entityTokens);\n if (score <= 0) continue;\n\n const fullPath = path.join(entitiesDir, entry);\n const safePath = await resolveContainedRegularFile(memoryDir, fullPath, canonicalRoot);\n if (!safePath) continue;\n\n results.push({\n docid: nameWithoutExt,\n path: safePath,\n snippet: \"\", // populated by augmentWithDirectAndTemporal after merge\n score,\n transport: \"scoped_prefilter\",\n agentSource: \"direct\",\n });\n }\n\n return results\n .sort((a, b) => b.score - a.score)\n .slice(0, maxResults);\n } catch (err) {\n log.debug(`DirectFactAgent error: ${err}`);\n return [];\n }\n}\n\n// ─── Agent 3: Temporal ───────────────────────────────────────────────────────\n\n/**\n * Temporal Agent — recency-focused retrieval.\n *\n * Uses the temporal index (index_time.json) to find memories from the\n * recent time window derived from the query (default: last 7 days).\n * Combines recency decay with query-filename token overlap so results stay\n * relevant to the query content, not just recency. Zero LLM inference; File I/O + math.\n *\n * Cost: read index_time.json + date range scan. Typically <10ms.\n */\nexport async function runTemporalAgent(\n query: string,\n memoryDir: string,\n maxResults = 20,\n /** Optional candidate set from query-aware prefilter. Applied BEFORE the top-K cap so\n * in-scope entries are not displaced by newer out-of-scope entries. */\n candidatePaths?: Set<string> | null,\n): Promise<ParallelSearchResult[]> {\n try {\n const canonicalRoot = await realpath(memoryDir);\n // Read index_time.json once — used for both date-range filtering and recency scoring.\n let dateIndex: Record<string, string[]> = {};\n try {\n const indexPath = path.join(memoryDir, \"state\", \"index_time.json\");\n const raw = await readFile(indexPath, \"utf-8\");\n const parsed = JSON.parse(raw) as { dates?: Record<string, string[]> };\n dateIndex = parsed.dates ?? {};\n } catch {\n return []; // Index missing or unreadable — nothing to return\n }\n\n // Derive both window edges from the same function so fromDate/toDate always use\n // consistent pattern-matching and priority ordering.\n const { fromDate, toDate } = recencyWindowBoundsFromPrompt(query);\n\n // Build path → date map, filtering to the recency window in one pass.\n // Apply candidatePaths here (before scoring + top-K) so in-scope entries are\n // not displaced by newer out-of-scope entries at the slice boundary.\n const pathToDate = new Map<string, string>();\n for (const [date, datePaths] of Object.entries(dateIndex)) {\n // toDate is an exclusive upper bound (the first day NOT included in the window).\n // e.g. \"3 days ago\" → fromDate=\"2026-03-12\", toDate=\"2026-03-13\" → only includes 2026-03-12.\n if (date >= fromDate && date < toDate) {\n for (const p of datePaths) {\n // Skip paths excluded by the query-aware prefilter scope\n if (candidatePaths && !candidatePaths.has(p)) continue;\n if (!pathToDate.has(p)) pathToDate.set(p, date);\n }\n }\n }\n\n if (pathToDate.size === 0) return [];\n\n const todayMs = Date.now();\n\n // Extract non-temporal topic tokens for tag-based relevance boost.\n // Purely temporal words (dates, relative time) and common stopwords are stripped\n // so the signal reflects the subject the user is asking about (e.g. \"auth\" in\n // \"what changed in auth last week\"), not the time window itself.\n const TEMPORAL_STOPWORDS = new Set([\n \"today\", \"yesterday\", \"this\", \"last\", \"week\", \"month\", \"year\",\n \"morning\", \"night\", \"now\", \"earlier\", \"since\", \"after\", \"before\",\n \"ago\", \"hours\", \"days\", \"weeks\", \"months\",\n \"january\", \"february\", \"march\", \"april\", \"may\", \"june\",\n \"july\", \"august\", \"september\", \"october\", \"november\", \"december\",\n \"monday\", \"tuesday\", \"wednesday\", \"thursday\", \"friday\", \"saturday\", \"sunday\",\n \"what\", \"when\", \"where\", \"who\", \"why\", \"how\", \"the\", \"a\", \"an\",\n \"and\", \"or\", \"in\", \"on\", \"at\", \"to\", \"of\", \"for\", \"with\", \"by\",\n \"from\", \"changed\", \"happened\", \"was\", \"were\", \"is\", \"are\", \"did\",\n \"about\", \"that\", \"have\", \"had\", \"has\", \"been\", \"any\", \"all\",\n ]);\n const topicTokens = tokenize(query).filter((t) => !TEMPORAL_STOPWORDS.has(t));\n\n // Load tag index for topical scoring, in parallel with existence checks.\n // Fail-open: if the tag index is unavailable, topicBoost = 0 and scores\n // degrade gracefully to recency-only ordering (existing behaviour).\n const entries = [...pathToDate.entries()];\n const tagIndexPromise: Promise<Map<string, string[]>> = topicTokens.length > 0\n ? readFile(path.join(memoryDir, \"state\", \"index_tags.json\"), \"utf-8\")\n .then((raw) => {\n const parsed = JSON.parse(raw) as { tags?: Record<string, { paths?: string[] } | string[]> };\n const result = new Map<string, string[]>();\n for (const [tag, node] of Object.entries(parsed.tags ?? {})) {\n const tagPaths = Array.isArray(node) ? node : (node.paths ?? []);\n for (const tp of tagPaths) {\n const existing = result.get(tp);\n if (existing) existing.push(tag);\n else result.set(tp, [tag]);\n }\n }\n return result;\n })\n .catch(() => new Map<string, string[]>())\n : Promise.resolve(new Map<string, string[]>());\n\n // Parallel: existence checks + tag index read.\n const [safePathResults, pathToTags] = await Promise.all([\n Promise.all(entries.map(([p]) => resolveContainedRegularFile(memoryDir, p, canonicalRoot))),\n tagIndexPromise,\n ]);\n\n const results: ParallelSearchResult[] = [];\n\n for (let i = 0; i < entries.length; i++) {\n const [p, dateStr] = entries[i];\n const safePath = safePathResults[i];\n if (!safePath) continue; // skip stale or out-of-root index entry\n const ageMs = todayMs - new Date(dateStr).getTime();\n const ageDays = ageMs / 86_400_000;\n // Exponential recency decay with half-life of ~30 days.\n // score ≈ 1.0 at day 0, ≈ 0.79 at 7 days, ≈ 0.36 at 30 days, ≈ 0.13 at 60 days.\n const recencyScore = Math.exp(-ageDays / 30);\n\n // Topical boost: fraction of non-temporal query tokens matched by this file's tags.\n // Adds up to +30% on recency score for a perfect tag match; zero when query is\n // purely temporal (no topic tokens) or the tag index doesn't cover the file.\n let topicBoost = 0;\n if (topicTokens.length > 0) {\n const tags = pathToTags.get(p) ?? pathToTags.get(safePath);\n if (tags && tags.length > 0) {\n const tagSet = new Set(tags.flatMap((t) => tokenize(t)));\n const hits = topicTokens.filter((t) => tagSet.has(t)).length;\n topicBoost = hits / topicTokens.length;\n }\n }\n const score = recencyScore * (1 + topicBoost * 0.3);\n\n const baseName = path.basename(safePath, \".md\");\n\n results.push({\n docid: baseName,\n path: safePath,\n snippet: \"\", // populated by augmentWithDirectAndTemporal after merge\n score,\n transport: \"scoped_prefilter\",\n agentSource: \"temporal\",\n });\n }\n\n return results\n .sort((a, b) => b.score - a.score)\n .slice(0, maxResults);\n } catch (err) {\n log.debug(`TemporalAgent error: ${err}`);\n return [];\n }\n}\n\n// ─── Agent 2: Contextual ─────────────────────────────────────────────────────\n\n/**\n * Contextual Agent — broad semantic/hybrid search.\n *\n * Delegates to the existing hybridSearch (BM25 + vector). Same cost as the\n * current single-pass retrieval — this agent introduces no additional LLM calls.\n */\nexport async function runContextualAgent(\n query: string,\n qmd: QmdClient,\n collection: string | undefined,\n maxResults: number,\n signal?: AbortSignal,\n): Promise<ParallelSearchResult[]> {\n try {\n const results = await qmd.hybridSearch(\n query,\n collection,\n maxResults,\n signal ? { signal } : undefined,\n );\n return results.map((r: QmdSearchResult) => ({ ...r, agentSource: \"contextual\" as const }));\n } catch (err) {\n if (isAbortError(err)) throw err;\n log.debug(`ContextualAgent error: ${err}`);\n return [];\n }\n}\n\n// ─── Merge helper ─────────────────────────────────────────────────────────────\n\n/**\n * Merge results from multiple agents into a single deduplicated, weighted list.\n * Preserves snippets: if a higher-scoring result lacks a snippet, the existing\n * snippet from a lower-scoring source is retained.\n */\nfunction mergeAgentResults(\n allResults: ParallelSearchResult[],\n weights: Record<SearchAgentSource, number>,\n maxResults: number,\n): QmdSearchResult[] {\n const merged = new Map<string, QmdSearchResult>();\n for (const result of allResults) {\n const key = result.path || result.docid;\n const weightedScore = result.score * weights[result.agentSource];\n const existing = merged.get(key);\n if (!existing || weightedScore > existing.score) {\n merged.set(key, {\n docid: result.docid,\n path: result.path,\n // Preserve any snippet from the existing entry when the new one has none\n snippet: result.snippet || existing?.snippet || \"\",\n score: weightedScore,\n transport: \"hybrid\",\n });\n }\n }\n return [...merged.values()]\n .sort((a, b) => b.score - a.score)\n .slice(0, maxResults);\n}\n\n/**\n * For merged results that have an empty snippet, attempt to read the first\n * 200 characters of the file as a fallback preview. Bounded to MAX_SNIPPET_READS\n * to cap I/O when many specialized-agent results are present.\n */\nconst SNIPPET_PREVIEW_CHARS = 200;\nconst MAX_SNIPPET_READS = 8;\n\n/** Strip YAML frontmatter (---...---) and return the document body. */\nfunction stripFrontmatter(raw: string): string {\n if (!raw.startsWith(\"---\")) return raw;\n const end = raw.indexOf(\"\\n---\", 3);\n if (end === -1) return raw;\n // Skip the closing \"---\" line and any leading blank lines\n return raw.slice(end + 4).replace(/^\\n+/, \"\");\n}\n\nasync function populateEmptySnippets(results: QmdSearchResult[], memoryDir?: string): Promise<QmdSearchResult[]> {\n const needsSnippet = results.filter((r) => !r.snippet && r.path);\n if (needsSnippet.length === 0) return results;\n const canonicalRoot = memoryDir ? await realpath(memoryDir).catch(() => null) : null;\n\n const toRead = needsSnippet.slice(0, MAX_SNIPPET_READS);\n const snippetMap = new Map<string, string>();\n\n await Promise.all(\n toRead.map(async (r) => {\n try {\n const safePath = canonicalRoot && r.path\n ? await resolveContainedRegularFile(memoryDir!, r.path, canonicalRoot)\n : null;\n if (!safePath) return;\n const raw = await readFile(safePath, \"utf-8\");\n // Memory files start with YAML frontmatter — skip it so the snippet\n // contains actual memory content, not metadata fields.\n const body = stripFrontmatter(raw);\n const preview = body.slice(0, SNIPPET_PREVIEW_CHARS).replace(/\\s+/g, \" \").trim();\n if (preview) snippetMap.set(r.path, preview);\n } catch {\n // File unreadable — leave snippet empty\n }\n }),\n );\n\n if (snippetMap.size === 0) return results;\n return results.map((r) => (r.path && snippetMap.has(r.path) ? { ...r, snippet: snippetMap.get(r.path)! } : r));\n}\n\n/**\n * Merge pre-computed direct and temporal agent results with contextual results.\n *\n * This is the merge half of augmentWithDirectAndTemporal. Expose it separately so\n * callers that started agents concurrently with the contextual search (for true\n * parallel latency) can merge after all three complete, without re-running agents.\n *\n * Handles the same cases as augmentWithDirectAndTemporal:\n * - Returns contextual unchanged (no reweighting) when both agents return nothing\n * - Applies maxResults cap in all paths\n * - Populates snippets for results discovered only by specialized agents\n */\nexport async function mergeWithAgentResults(\n contextualResults: QmdSearchResult[],\n directResults: ParallelSearchResult[],\n temporalResults: ParallelSearchResult[],\n weights: Record<SearchAgentSource, number>,\n maxResults: number,\n memoryDir?: string,\n): Promise<QmdSearchResult[]> {\n if (directResults.length === 0 && temporalResults.length === 0) {\n return contextualResults.slice(0, maxResults);\n }\n\n const contextualTagged: ParallelSearchResult[] = contextualResults.map((r) => ({\n ...r,\n agentSource: \"contextual\" as const,\n }));\n\n const merged = mergeAgentResults(\n [...contextualTagged, ...directResults, ...temporalResults],\n weights,\n maxResults,\n );\n return populateEmptySnippets(merged, memoryDir);\n}\n\n// ─── Augmentation helper (used by tests; orchestrator uses inline logic) ─────\n//\n// NOTE: This function passes the same `memoryDir` to both direct and temporal\n// agents. The orchestrator's inline implementation differs: it passes a\n// namespace-specific storage dir to runDirectAgent and the shared root to\n// runTemporalAgent. augmentWithDirectAndTemporal is intentionally simpler\n// (single-dir assumption) and is exercised by unit tests where both agents\n// operate on the same temporary directory.\n\n/**\n * Augment a set of contextual (hybridSearch) results with direct and temporal\n * agent results, returning a merged, deduplicated list.\n *\n * **Test helper** — production recall uses the inline orchestrator path which\n * passes namespace-specific directories to each agent. This function uses a\n * simplified single-directory contract suitable for unit tests.\n *\n * Direct and temporal agents run in parallel, then all three are merged with\n * configurable weights.\n *\n * Contextual weight is always applied to `contextualResults` so scoring is\n * consistent regardless of whether direct/temporal agents return anything.\n *\n * Snippets: snippets from contextual results are preserved during merge. For\n * results discovered only by direct/temporal agents (no contextual match),\n * the first ~200 chars of the file are read as a fallback preview so downstream\n * formatters and rerankers have content to work with, not just a path.\n */\nexport async function augmentWithDirectAndTemporal(\n query: string,\n memoryDir: string,\n contextualResults: QmdSearchResult[],\n weights: Record<SearchAgentSource, number>,\n maxPerAgent: number,\n maxResults: number,\n /** Optional candidate set from query-aware prefilter (time/tag scoped). Agents' results are\n * filtered to this set when provided so recall stays within the operator-specified scope. */\n candidatePaths?: Set<string> | null,\n): Promise<QmdSearchResult[]> {\n // maxPerAgent=0 is a hard disable: skip agents entirely and return contextual unchanged\n if (maxPerAgent === 0) return contextualResults;\n\n const knownEntityCount = (query.match(/\\b[A-Z][a-z]{1,}/g) ?? []).length;\n const runDirect = shouldRunAgent(\"direct\", query, knownEntityCount);\n const runTemporal = shouldRunAgent(\"temporal\", query, knownEntityCount);\n\n const startMs = Date.now();\n const [directResults, temporalResults] = await Promise.all([\n runDirect\n ? runDirectAgent(query, memoryDir, maxPerAgent).catch((err) => {\n log.debug(`augmentWithDirectAndTemporal: DirectAgent failed — ${err}`);\n return [] as ParallelSearchResult[];\n })\n : Promise.resolve([] as ParallelSearchResult[]),\n runTemporal\n // Pass candidatePaths so scope-filtering happens before the top-K cap inside runTemporalAgent,\n // preventing out-of-scope newer entries from displacing in-scope ones at the slice boundary.\n ? runTemporalAgent(query, memoryDir, maxPerAgent, candidatePaths).catch((err) => {\n log.debug(`augmentWithDirectAndTemporal: TemporalAgent failed — ${err}`);\n return [] as ParallelSearchResult[];\n })\n : Promise.resolve([] as ParallelSearchResult[]),\n ]);\n const durationMs = Date.now() - startMs;\n\n // Direct agent results (entities/) intentionally bypass candidatePaths.\n //\n // Why: candidatePaths is built from temporal + tag indexes, which never include\n // entity files (entities/*.md). Applying the filter here would silently drop ALL\n // direct-agent results for any scoped query, making the direct agent a no-op.\n // Entity files are identified by filename matching (query tokens vs. entity name),\n // so they are already query-scoped independently of the time/tag prefilter.\n // Temporal results are scoped inside runTemporalAgent() before the top-K cap.\n const scopedDirect = directResults;\n\n // Tag contextual results with their source so they can participate in weighted merge.\n // We do NOT cap contextual here: contextualResults comes from fetchQmdMemoryResultsWithArtifactTopUp\n // which intentionally over-fetches so downstream phases (graph expansion, lifecycle filtering,\n // reranking) can drop candidates. Capping before the merge would remove that headroom.\n const contextualTagged: ParallelSearchResult[] = contextualResults.map((r) => ({\n ...r,\n agentSource: \"contextual\" as const,\n }));\n\n log.debug(\n `augmentWithDirectAndTemporal: direct=${scopedDirect.length} temporal=${temporalResults.length} contextual=${contextualTagged.length} agentMs=${durationMs}ms`,\n );\n\n // If no specialized agents contributed anything (e.g. fresh setup without entities/ or temporal\n // index), skip reweighting entirely — applying the contextual weight penalty with zero benefit\n // would silently reduce every result score by ~30% compared to the non-augmented path.\n if (scopedDirect.length === 0 && temporalResults.length === 0) {\n return (contextualResults as QmdSearchResult[]).slice(0, maxResults);\n }\n\n // Merge all three; contextual first so its snippets are preserved when a higher-scoring\n // direct/temporal result overrides the same path (see mergeAgentResults snippet logic).\n // Note: maxPerAgent=0 is handled by the early-return guard above; we never reach here with 0.\n const merged = mergeAgentResults(\n [...contextualTagged, ...scopedDirect, ...temporalResults],\n weights,\n maxResults,\n );\n\n // Populate snippets for results discovered only by direct/temporal (no contextual preview)\n return populateEmptySnippets(merged, memoryDir);\n}\n\n// ─── Orchestrator ─────────────────────────────────────────────────────────────\n\nexport interface ParallelRetrievalOptions {\n collection?: string;\n maxResults?: number;\n signal?: AbortSignal;\n /** If true, skip the contextual agent (hybridSearch is already running externally). */\n skipContextual?: boolean;\n /** Max results per agent (capped before merge). */\n maxResultsPerAgent?: number;\n /** Override default agent weights. Falls back to PARALLEL_AGENT_WEIGHTS when absent. */\n agentWeights?: Record<SearchAgentSource, number>;\n}\n\n/**\n * Run parallel specialized retrieval agents and merge results.\n *\n * When `skipContextual` is true, only the direct and temporal agents run.\n * This is the intended usage inside the orchestrator, where hybridSearch\n * already runs as the primary search — we augment with the cheap extra agents.\n *\n * Total latency = max(agent_latencies), not sum.\n * Agent errors are isolated — others still return results.\n */\nexport async function parallelRetrieval(\n query: string,\n qmd: QmdClient,\n memoryDir: string,\n options: ParallelRetrievalOptions = {},\n): Promise<QmdSearchResult[]> {\n const maxResults = options.maxResults ?? 20;\n const maxPerAgent = options.maxResultsPerAgent ?? maxResults;\n const startMs = Date.now();\n\n // Rough entity detection: count proper-noun-like tokens in query\n const knownEntityCount = (query.match(/\\b[A-Z][a-z]{1,}/g) ?? []).length;\n\n const runDirect = shouldRunAgent(\"direct\", query, knownEntityCount);\n const runTemporal = shouldRunAgent(\"temporal\", query, knownEntityCount);\n const runContextual = !options.skipContextual && shouldRunAgent(\"contextual\", query, knownEntityCount);\n\n const [directResults, temporalResults, contextualResults] = await Promise.all([\n runDirect\n ? runDirectAgent(query, memoryDir, maxPerAgent).catch((err) => {\n log.debug(`parallelRetrieval: DirectAgent failed — ${err}`);\n return [] as ParallelSearchResult[];\n })\n : Promise.resolve([] as ParallelSearchResult[]),\n runTemporal\n ? runTemporalAgent(query, memoryDir, maxPerAgent).catch((err) => {\n log.debug(`parallelRetrieval: TemporalAgent failed — ${err}`);\n return [] as ParallelSearchResult[];\n })\n : Promise.resolve([] as ParallelSearchResult[]),\n runContextual\n ? runContextualAgent(query, qmd, options.collection, maxPerAgent, options.signal).catch((err) => {\n if (isAbortError(err)) throw err;\n log.debug(`parallelRetrieval: ContextualAgent failed — ${err}`);\n return [] as ParallelSearchResult[];\n })\n : Promise.resolve([] as ParallelSearchResult[]),\n ]);\n\n const durationMs = Date.now() - startMs;\n log.debug(\n `parallelRetrieval: direct=${directResults.length} temporal=${temporalResults.length} contextual=${contextualResults.length} durationMs=${durationMs}ms`,\n );\n\n // Contextual results go first so their snippets are preserved when a higher-scoring\n // direct/temporal result overrides the same path in mergeAgentResults.\n const merged = mergeAgentResults(\n [...contextualResults, ...directResults, ...temporalResults],\n options.agentWeights ?? PARALLEL_AGENT_WEIGHTS,\n maxResults,\n );\n return populateEmptySnippets(merged, memoryDir);\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/network/webdav.ts
|
|
2
|
-
import {
|
|
3
|
-
import { mkdir, readdir, realpath, stat } from "fs/promises";
|
|
2
|
+
import { constants } from "fs";
|
|
3
|
+
import { mkdir, open, readdir, realpath, stat } from "fs/promises";
|
|
4
4
|
import { createServer } from "http";
|
|
5
5
|
import { timingSafeEqual } from "crypto";
|
|
6
6
|
import path from "path";
|
|
@@ -12,10 +12,45 @@ function hostToUrlAuthority(host) {
|
|
|
12
12
|
}
|
|
13
13
|
return host;
|
|
14
14
|
}
|
|
15
|
+
function validateWebDavAuth(auth) {
|
|
16
|
+
if (typeof auth.username !== "string" || auth.username.trim().length === 0) {
|
|
17
|
+
throw new Error("webdav auth.username must be a non-empty string");
|
|
18
|
+
}
|
|
19
|
+
if (typeof auth.password !== "string" || auth.password.trim().length === 0) {
|
|
20
|
+
throw new Error("webdav auth.password must be a non-empty string");
|
|
21
|
+
}
|
|
22
|
+
return auth;
|
|
23
|
+
}
|
|
24
|
+
async function openWebDavFileForRead(absolutePath) {
|
|
25
|
+
let handle = null;
|
|
26
|
+
try {
|
|
27
|
+
handle = await open(absolutePath, constants.O_RDONLY | constants.O_NOFOLLOW);
|
|
28
|
+
const info = await handle.stat();
|
|
29
|
+
if (!info.isFile()) {
|
|
30
|
+
await handle.close().catch(() => {
|
|
31
|
+
});
|
|
32
|
+
return { ok: false, code: 403, message: "path is not a file" };
|
|
33
|
+
}
|
|
34
|
+
return { ok: true, handle, size: info.size };
|
|
35
|
+
} catch (err) {
|
|
36
|
+
await handle?.close().catch(() => {
|
|
37
|
+
});
|
|
38
|
+
const code = err.code;
|
|
39
|
+
if (code === "ELOOP") {
|
|
40
|
+
return { ok: false, code: 403, message: "path escaped allowlist via symlink" };
|
|
41
|
+
}
|
|
42
|
+
if (code === "ENOENT" || code === "ENOTDIR") {
|
|
43
|
+
return { ok: false, code: 404, message: "not found" };
|
|
44
|
+
}
|
|
45
|
+
return { ok: false, code: 404, message: "not found" };
|
|
46
|
+
}
|
|
47
|
+
}
|
|
15
48
|
var WebDavServer = class _WebDavServer {
|
|
16
49
|
options;
|
|
17
50
|
allowedRoots;
|
|
18
51
|
server = null;
|
|
52
|
+
startPromise = null;
|
|
53
|
+
listening = false;
|
|
19
54
|
boundPort;
|
|
20
55
|
constructor(options, allowedRoots) {
|
|
21
56
|
this.options = options;
|
|
@@ -28,7 +63,7 @@ var WebDavServer = class _WebDavServer {
|
|
|
28
63
|
host: input.host ?? "127.0.0.1",
|
|
29
64
|
port: input.port,
|
|
30
65
|
allowlistDirs: input.allowlistDirs,
|
|
31
|
-
auth: input.auth
|
|
66
|
+
auth: input.auth ? validateWebDavAuth(input.auth) : void 0
|
|
32
67
|
};
|
|
33
68
|
if (!Array.isArray(options.allowlistDirs) || options.allowlistDirs.length === 0) {
|
|
34
69
|
throw new Error("webdav allowlistDirs must include at least one directory");
|
|
@@ -55,9 +90,10 @@ var WebDavServer = class _WebDavServer {
|
|
|
55
90
|
if (!this.options.enabled) {
|
|
56
91
|
throw new Error("webdav server is disabled; set enabled=true to start");
|
|
57
92
|
}
|
|
58
|
-
if (this.server) {
|
|
93
|
+
if (this.server && this.listening) {
|
|
59
94
|
return this.status();
|
|
60
95
|
}
|
|
96
|
+
if (this.startPromise) return this.startPromise;
|
|
61
97
|
const server = createServer((req, res) => {
|
|
62
98
|
this.handle(req, res).catch((err) => {
|
|
63
99
|
if (res.headersSent) {
|
|
@@ -69,43 +105,74 @@ var WebDavServer = class _WebDavServer {
|
|
|
69
105
|
});
|
|
70
106
|
});
|
|
71
107
|
this.server = server;
|
|
108
|
+
this.listening = false;
|
|
109
|
+
this.startPromise = (async () => {
|
|
110
|
+
try {
|
|
111
|
+
await new Promise((resolve, reject) => {
|
|
112
|
+
const onError = (err) => {
|
|
113
|
+
server.removeListener("listening", onListening);
|
|
114
|
+
server.removeListener("close", onClose);
|
|
115
|
+
reject(err);
|
|
116
|
+
};
|
|
117
|
+
const onListening = () => {
|
|
118
|
+
server.removeListener("error", onError);
|
|
119
|
+
server.removeListener("close", onClose);
|
|
120
|
+
resolve();
|
|
121
|
+
};
|
|
122
|
+
const onClose = () => {
|
|
123
|
+
server.removeListener("error", onError);
|
|
124
|
+
server.removeListener("listening", onListening);
|
|
125
|
+
reject(new Error("webdav server closed before listening"));
|
|
126
|
+
};
|
|
127
|
+
server.once("error", onError);
|
|
128
|
+
server.once("listening", onListening);
|
|
129
|
+
server.once("close", onClose);
|
|
130
|
+
server.listen(this.options.port, this.options.host);
|
|
131
|
+
});
|
|
132
|
+
} catch (err) {
|
|
133
|
+
if (this.server === server) {
|
|
134
|
+
this.server = null;
|
|
135
|
+
}
|
|
136
|
+
this.listening = false;
|
|
137
|
+
server.close();
|
|
138
|
+
throw err;
|
|
139
|
+
}
|
|
140
|
+
const address = server.address();
|
|
141
|
+
if (address && typeof address !== "string") {
|
|
142
|
+
this.boundPort = address.port;
|
|
143
|
+
}
|
|
144
|
+
this.listening = true;
|
|
145
|
+
return this.status();
|
|
146
|
+
})();
|
|
72
147
|
try {
|
|
73
|
-
await
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
reject(err);
|
|
77
|
-
};
|
|
78
|
-
const onListening = () => {
|
|
79
|
-
server.removeListener("error", onError);
|
|
80
|
-
resolve();
|
|
81
|
-
};
|
|
82
|
-
server.once("error", onError);
|
|
83
|
-
server.once("listening", onListening);
|
|
84
|
-
server.listen(this.options.port, this.options.host);
|
|
85
|
-
});
|
|
86
|
-
} catch (err) {
|
|
87
|
-
this.server = null;
|
|
88
|
-
server.close();
|
|
89
|
-
throw err;
|
|
90
|
-
}
|
|
91
|
-
const address = server.address();
|
|
92
|
-
if (address && typeof address !== "string") {
|
|
93
|
-
this.boundPort = address.port;
|
|
148
|
+
return await this.startPromise;
|
|
149
|
+
} finally {
|
|
150
|
+
this.startPromise = null;
|
|
94
151
|
}
|
|
95
|
-
return this.status();
|
|
96
152
|
}
|
|
97
153
|
async stop() {
|
|
98
154
|
if (!this.server) return;
|
|
99
155
|
const server = this.server;
|
|
100
|
-
|
|
101
|
-
this.boundPort = this.options.port;
|
|
156
|
+
const pendingStart = this.startPromise;
|
|
102
157
|
await new Promise((resolve, reject) => {
|
|
103
|
-
server.close((err) =>
|
|
158
|
+
server.close((err) => {
|
|
159
|
+
if (err && err.code !== "ERR_SERVER_NOT_RUNNING") {
|
|
160
|
+
reject(err);
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
resolve();
|
|
164
|
+
});
|
|
104
165
|
});
|
|
166
|
+
await pendingStart?.catch(() => void 0);
|
|
167
|
+
if (this.server === server) {
|
|
168
|
+
this.server = null;
|
|
169
|
+
}
|
|
170
|
+
this.listening = false;
|
|
171
|
+
this.boundPort = this.options.port;
|
|
105
172
|
}
|
|
106
173
|
status() {
|
|
107
174
|
return {
|
|
108
|
-
running: this.server !== null,
|
|
175
|
+
running: this.server !== null && this.listening,
|
|
109
176
|
host: this.options.host,
|
|
110
177
|
port: this.boundPort,
|
|
111
178
|
rootCount: this.allowedRoots.length
|
|
@@ -137,11 +204,11 @@ var WebDavServer = class _WebDavServer {
|
|
|
137
204
|
return;
|
|
138
205
|
}
|
|
139
206
|
if (method === "PROPFIND") {
|
|
140
|
-
await this.handlePropfind(resolved.absolutePath, resolved.displayPath, res);
|
|
207
|
+
await this.handlePropfind(resolved.absolutePath, resolved.rootAbsolute, resolved.displayPath, res);
|
|
141
208
|
return;
|
|
142
209
|
}
|
|
143
210
|
if (method === "GET" || method === "HEAD") {
|
|
144
|
-
await this.handleRead(method, resolved.absolutePath, res);
|
|
211
|
+
await this.handleRead(method, resolved.absolutePath, resolved.rootAbsolute, res);
|
|
145
212
|
return;
|
|
146
213
|
}
|
|
147
214
|
res.writeHead(405, {
|
|
@@ -221,11 +288,11 @@ var WebDavServer = class _WebDavServer {
|
|
|
221
288
|
if (!this.isPathInside(root.absolute, canonicalCandidate)) {
|
|
222
289
|
return { ok: false, code: 403, message: "path escaped allowlist via symlink" };
|
|
223
290
|
}
|
|
224
|
-
return { ok: true, absolutePath: canonicalCandidate, displayPath: `/${segments.join("/")}
|
|
291
|
+
return { ok: true, absolutePath: canonicalCandidate, displayPath: `/${segments.join("/")}`, rootAbsolute: root.absolute };
|
|
225
292
|
} catch (err) {
|
|
226
293
|
const code = err.code;
|
|
227
294
|
if (code === "ENOENT") {
|
|
228
|
-
return { ok: true, absolutePath: candidate, displayPath: `/${segments.join("/")}
|
|
295
|
+
return { ok: true, absolutePath: candidate, displayPath: `/${segments.join("/")}`, rootAbsolute: root.absolute };
|
|
229
296
|
}
|
|
230
297
|
if (code === "ENOTDIR" || code === "ELOOP") {
|
|
231
298
|
return { ok: false, code: 400, message: "invalid path" };
|
|
@@ -233,31 +300,43 @@ var WebDavServer = class _WebDavServer {
|
|
|
233
300
|
throw err;
|
|
234
301
|
}
|
|
235
302
|
}
|
|
236
|
-
async handleRead(method, absolutePath, res) {
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
res.writeHead(404, { "Content-Type": "text/plain; charset=utf-8" });
|
|
242
|
-
res.end("not found");
|
|
303
|
+
async handleRead(method, absolutePath, rootAbsolute, res) {
|
|
304
|
+
const revalidated = await this.revalidatePathInsideRoot(absolutePath, rootAbsolute);
|
|
305
|
+
if (!revalidated.ok) {
|
|
306
|
+
res.writeHead(revalidated.code, { "Content-Type": "text/plain; charset=utf-8" });
|
|
307
|
+
res.end(revalidated.message);
|
|
243
308
|
return;
|
|
244
309
|
}
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
res.
|
|
310
|
+
const opened = await openWebDavFileForRead(revalidated.absolutePath);
|
|
311
|
+
if (!opened.ok) {
|
|
312
|
+
res.writeHead(opened.code, { "Content-Type": "text/plain; charset=utf-8" });
|
|
313
|
+
res.end(opened.message);
|
|
248
314
|
return;
|
|
249
315
|
}
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
316
|
+
const { handle, size } = opened;
|
|
317
|
+
try {
|
|
318
|
+
res.writeHead(200, {
|
|
319
|
+
"Content-Length": String(size),
|
|
320
|
+
"Content-Type": "application/octet-stream"
|
|
321
|
+
});
|
|
322
|
+
if (method === "HEAD") {
|
|
323
|
+
res.end();
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
await pipeline(handle.createReadStream({ autoClose: false }), res);
|
|
327
|
+
} finally {
|
|
328
|
+
await handle.close().catch(() => {
|
|
329
|
+
});
|
|
257
330
|
}
|
|
258
|
-
await pipeline(createReadStream(absolutePath), res);
|
|
259
331
|
}
|
|
260
|
-
async handlePropfind(absolutePath, displayPath, res) {
|
|
332
|
+
async handlePropfind(absolutePath, rootAbsolute, displayPath, res) {
|
|
333
|
+
const revalidated = await this.revalidatePathInsideRoot(absolutePath, rootAbsolute);
|
|
334
|
+
if (!revalidated.ok) {
|
|
335
|
+
res.writeHead(revalidated.code, { "Content-Type": "text/plain; charset=utf-8" });
|
|
336
|
+
res.end(revalidated.message);
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
absolutePath = revalidated.absolutePath;
|
|
261
340
|
let info;
|
|
262
341
|
try {
|
|
263
342
|
info = await stat(absolutePath);
|
|
@@ -295,6 +374,24 @@ var WebDavServer = class _WebDavServer {
|
|
|
295
374
|
}
|
|
296
375
|
return target.startsWith(`${root}${path.sep}`);
|
|
297
376
|
}
|
|
377
|
+
async revalidatePathInsideRoot(absolutePath, rootAbsolute) {
|
|
378
|
+
try {
|
|
379
|
+
const canonical = await realpath(absolutePath);
|
|
380
|
+
if (!this.isPathInside(rootAbsolute, canonical)) {
|
|
381
|
+
return { ok: false, code: 403, message: "path escaped allowlist via symlink" };
|
|
382
|
+
}
|
|
383
|
+
return { ok: true, absolutePath: canonical };
|
|
384
|
+
} catch (err) {
|
|
385
|
+
const code = err.code;
|
|
386
|
+
if (code === "ENOENT" || code === "ENOTDIR") {
|
|
387
|
+
return { ok: false, code: 404, message: "not found" };
|
|
388
|
+
}
|
|
389
|
+
if (code === "ELOOP") {
|
|
390
|
+
return { ok: false, code: 403, message: "path escaped allowlist via symlink" };
|
|
391
|
+
}
|
|
392
|
+
throw err;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
298
395
|
};
|
|
299
396
|
function xmlEscape(value) {
|
|
300
397
|
return value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
@@ -305,6 +402,7 @@ function toEncodedHref(pathname) {
|
|
|
305
402
|
|
|
306
403
|
export {
|
|
307
404
|
hostToUrlAuthority,
|
|
405
|
+
openWebDavFileForRead,
|
|
308
406
|
WebDavServer
|
|
309
407
|
};
|
|
310
|
-
//# sourceMappingURL=chunk-
|
|
408
|
+
//# sourceMappingURL=chunk-UWY7GIVS.js.map
|