@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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/contradiction/contradiction-review.ts"],"sourcesContent":["/**\n * Contradiction Review Queue — storage for detected contradiction pairs (issue #520).\n *\n * Stores candidate pairs as JSON files under `memoryDir/.review/contradictions/`.\n * Pair IDs are deterministic (sha256 of sorted memory IDs plus namespace when scoped) so reruns are idempotent.\n *\n * Lifecycle:\n * - `contradicts` → awaiting user review\n * - `duplicates` → auto-flagged for dedup (still needs user approval)\n * - `independent` / `both-valid` → dormant with cooldown\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { createHash, randomUUID } from \"node:crypto\";\nimport type { ContradictionVerdict } from \"./contradiction-judge.js\";\n\n// ── Types ──────────────────────────────────────────────────────────────────────\n\nexport type ResolutionVerb = \"keep-a\" | \"keep-b\" | \"merge\" | \"both-valid\" | \"needs-more-context\";\n\nconst VALID_RESOLUTION_VERBS: readonly ResolutionVerb[] = [\n \"keep-a\",\n \"keep-b\",\n \"merge\",\n \"both-valid\",\n \"needs-more-context\",\n];\n\nexport interface ContradictionPair {\n /** Deterministic pair ID: sha256(sorted(memoryIdA, memoryIdB) plus namespace when scoped). */\n pairId: string;\n /** Memory IDs (sorted). */\n memoryIds: [string, string];\n /** Judge verdict. */\n verdict: ContradictionVerdict;\n /** Judge rationale. */\n rationale: string;\n /** Judge confidence in [0, 1]. */\n confidence: number;\n /** ISO timestamp when detected. */\n detectedAt: string;\n /** ISO timestamp when last reviewed by user. */\n lastReviewedAt?: string;\n /** Resolution verb applied by user. */\n resolution?: ResolutionVerb;\n /** ISO timestamp until which a non-terminal deferral remains hidden from review. */\n deferredUntil?: string;\n /** Content hashes captured for each referenced memory when this pair was judged. */\n memoryContentHashes?: Record<string, string>;\n /** Namespace scope. */\n namespace?: string;\n}\n\nexport interface ContradictionListResult {\n pairs: ContradictionPair[];\n total: number;\n durationMs: number;\n}\n\nexport type ContradictionFilter = ContradictionVerdict | \"all\" | \"unresolved\";\nexport interface WritePairOptions {\n /** Cooldown used by scan callers to preserve still-dormant reviewed pairs. */\n cooldownDays?: number;\n}\nconst NEEDS_MORE_CONTEXT_COOLDOWN_MS = 24 * 60 * 60 * 1000;\nconst UNSCOPED_MIGRATION_MARKER_PREFIX = \".unscoped-migrated-\";\nconst UNSCOPED_MIGRATION_MARKER_SUFFIX = \".done\";\n\n// ── Helpers ────────────────────────────────────────────────────────────────────\n\nexport function computePairId(memoryIdA: string, memoryIdB: string, namespace?: string): string {\n const sorted = [memoryIdA, memoryIdB].sort();\n const normalizedNamespace = namespace?.trim();\n const scope = normalizedNamespace ? `ns:${normalizedNamespace}::` : \"\";\n return createHash(\"sha256\").update(`${scope}${sorted.join(\"::\")}`).digest(\"hex\").slice(0, 24);\n}\n\nexport function isDefaultReviewNamespace(\n defaultNamespace: string,\n requestedNamespace: string | undefined,\n resolvedNamespace: string,\n): boolean {\n const requested = requestedNamespace?.trim();\n return !requested || requested === defaultNamespace || resolvedNamespace === defaultNamespace;\n}\n\nfunction isTerminalResolution(resolution: ResolutionVerb | undefined): boolean {\n return resolution === \"keep-a\" || resolution === \"keep-b\" || resolution === \"merge\";\n}\n\nfunction preservesDirectResolution(resolution: ResolutionVerb | undefined): boolean {\n return isTerminalResolution(resolution) || resolution === \"both-valid\";\n}\n\nfunction isDormantReviewedPair(pair: ContradictionPair): boolean {\n return pair.verdict === \"independent\" || pair.resolution === \"both-valid\";\n}\n\nfunction reviewStateRank(pair: ContradictionPair, cooldownDays?: number): number {\n if (isTerminalResolution(pair.resolution)) return 5;\n if (pair.resolution === \"both-valid\") return 4;\n if (isDeferralActive(pair)) return 3;\n if (isDormantReviewedPair(pair)) {\n if (cooldownDays === undefined) return 2;\n return isCoolingDown(pair, cooldownDays) ? 2 : 0;\n }\n return 1;\n}\n\nfunction parseIsoMillis(value: string | undefined): number | null {\n if (!value) return null;\n const millis = new Date(value).getTime();\n return Number.isFinite(millis) ? millis : null;\n}\n\nfunction isDeferred(pair: Pick<ContradictionPair, \"resolution\" | \"deferredUntil\">): boolean {\n return pair.resolution === \"needs-more-context\" || Boolean(pair.deferredUntil);\n}\n\nfunction deferralUntilMillis(pair: ContradictionPair): number | null {\n const deferredUntil = parseIsoMillis(pair.deferredUntil);\n if (deferredUntil !== null) return deferredUntil;\n\n if (pair.resolution === \"needs-more-context\") {\n const lastReviewed = parseIsoMillis(pair.lastReviewedAt);\n return lastReviewed === null ? null : lastReviewed + NEEDS_MORE_CONTEXT_COOLDOWN_MS;\n }\n\n return null;\n}\n\nfunction isDeferralActive(pair: ContradictionPair): boolean {\n const deferredUntil = deferralUntilMillis(pair);\n return deferredUntil !== null && Date.now() < deferredUntil;\n}\n\nfunction reviewStateMillis(pair: ContradictionPair): number {\n return Math.max(\n parseIsoMillis(pair.deferredUntil) ?? Number.NEGATIVE_INFINITY,\n parseIsoMillis(pair.lastReviewedAt) ?? Number.NEGATIVE_INFINITY,\n parseIsoMillis(pair.detectedAt) ?? Number.NEGATIVE_INFINITY,\n );\n}\n\nfunction mergeMigratedPair(existing: ContradictionPair, migrated: ContradictionPair, options: WritePairOptions): ContradictionPair {\n const existingRank = reviewStateRank(existing, options.cooldownDays);\n const migratedRank = reviewStateRank(migrated, options.cooldownDays);\n const selected = migratedRank > existingRank\n ? migrated\n : migratedRank < existingRank\n ? existing\n : reviewStateMillis(migrated) > reviewStateMillis(existing)\n ? migrated\n : existing;\n\n return {\n ...selected,\n pairId: migrated.pairId,\n namespace: migrated.namespace,\n };\n}\n\nfunction reviewDir(memoryDir: string): string {\n return path.join(memoryDir, \".review\", \"contradictions\");\n}\n\nfunction migrationMarkerPath(memoryDir: string, namespace: string): string {\n const namespaceKey = createHash(\"sha256\").update(namespace).digest(\"hex\").slice(0, 16);\n return path.join(reviewDir(memoryDir), `${UNSCOPED_MIGRATION_MARKER_PREFIX}${namespaceKey}${UNSCOPED_MIGRATION_MARKER_SUFFIX}`);\n}\n\nfunction clearUnscopedMigrationMarkers(memoryDir: string): void {\n const dir = reviewDir(memoryDir);\n if (!fs.existsSync(dir)) return;\n\n try {\n for (const entry of fs.readdirSync(dir)) {\n if (entry.startsWith(UNSCOPED_MIGRATION_MARKER_PREFIX) && entry.endsWith(UNSCOPED_MIGRATION_MARKER_SUFFIX)) {\n fs.rmSync(path.join(dir, entry), { force: true });\n }\n }\n } catch {\n // Marker cleanup is best-effort. The next migration/list call can recover.\n }\n}\n\nfunction pairPath(memoryDir: string, pairId: string): string {\n if (pairId.includes(\"/\") || pairId.includes(\"\\\\\") || pairId.includes(\"..\")) {\n throw new Error(`Invalid pairId: ${pairId}`);\n }\n return path.join(reviewDir(memoryDir), `${pairId}.json`);\n}\n\nfunction isSafeReviewJsonFile(memoryDir: string, filePath: string): boolean {\n const root = path.resolve(reviewDir(memoryDir));\n const resolved = path.resolve(filePath);\n const relative = path.relative(root, resolved);\n if (relative === \"\" || relative.startsWith(\"..\") || path.isAbsolute(relative)) {\n return false;\n }\n\n try {\n return fs.lstatSync(resolved).isFile();\n } catch {\n return false;\n }\n}\n\nfunction ensureDir(memoryDir: string): void {\n const dir = reviewDir(memoryDir);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n}\n\nfunction uniqueTempPath(filePath: string): string {\n return `${filePath}.${process.pid}.${Date.now()}.${randomUUID()}.tmp`;\n}\n\nfunction writePairFile(filePath: string, pair: ContradictionPair): void {\n const tmpPath = uniqueTempPath(filePath);\n try {\n fs.writeFileSync(tmpPath, JSON.stringify(pair, null, 2), \"utf-8\");\n fs.renameSync(tmpPath, filePath);\n } catch (error) {\n try {\n fs.rmSync(tmpPath, { force: true });\n } catch {\n // Best-effort cleanup only; preserve the original write failure.\n }\n throw error;\n }\n}\n\nexport function computeMemoryContentHash(content: string, category?: string): string {\n const normalized = JSON.stringify({\n content: content.trim(),\n category: (category ?? \"\").trim(),\n });\n return createHash(\"sha256\").update(normalized).digest(\"hex\").slice(0, 16);\n}\n\nfunction suppliedMemoryHashesChanged(\n existing: ContradictionPair,\n pair: Omit<ContradictionPair, \"pairId\"> & { memoryIds: [string, string] },\n): boolean {\n if (!existing.memoryContentHashes || !pair.memoryContentHashes) return false;\n return pair.memoryIds.some((memoryId) => {\n const current = pair.memoryContentHashes?.[memoryId];\n return typeof current === \"string\" && existing.memoryContentHashes?.[memoryId] !== current;\n });\n}\n\n// ── Write ──────────────────────────────────────────────────────────────────────\n\n/**\n * Write a contradiction pair to the review queue.\n * Idempotent: if the pair already exists with a higher or equal confidence,\n * the existing entry is preserved.\n */\nexport function writePair(\n memoryDir: string,\n pair: Omit<ContradictionPair, \"pairId\"> & { memoryIds: [string, string] },\n options: WritePairOptions = {},\n): ContradictionPair {\n ensureDir(memoryDir);\n if (pair.namespace === undefined) {\n clearUnscopedMigrationMarkers(memoryDir);\n }\n const pairId = computePairId(pair.memoryIds[0], pair.memoryIds[1], pair.namespace);\n const existing = readPair(memoryDir, pairId);\n\n // Preserve terminal user resolutions if already reviewed.\n if (isTerminalResolution(existing?.resolution)) {\n return existing!;\n }\n const contentChanged = Boolean(existing && suppliedMemoryHashesChanged(existing, pair));\n if (existing?.resolution === \"both-valid\" && options.cooldownDays === undefined && !contentChanged) {\n return existing;\n }\n\n // Preserve active deferrals, but allow expired deferrals to be refreshed.\n const existingDeferralExpired = Boolean(existing && isDeferred(existing) && !isDeferralActive(existing));\n if (existing && isDeferralActive(existing) && !contentChanged) {\n return existing;\n }\n\n // Preserve same-verdict or still-cooling entries, but let expired dormant\n // verdicts refresh when the judge now finds an actionable conflict.\n const existingDormantCooldownActive = Boolean(\n existing\n && isDormantReviewedPair(existing)\n && options.cooldownDays !== undefined\n && isCoolingDown(existing, options.cooldownDays),\n );\n const dormantContentChanged = Boolean(\n existing\n && existingDormantCooldownActive\n && contentChanged,\n );\n const existingDormantExpired = Boolean(\n existing\n && isDormantReviewedPair(existing)\n && options.cooldownDays !== undefined\n && !existingDormantCooldownActive,\n );\n if (\n existing\n && !existingDeferralExpired\n && (\n (existingDormantCooldownActive && !dormantContentChanged)\n || (!existingDormantExpired && !contentChanged && existing.confidence >= pair.confidence)\n )\n ) {\n return existing;\n }\n\n const full: ContradictionPair = {\n ...pair,\n pairId,\n lastReviewedAt: (existingDeferralExpired || existingDormantExpired || contentChanged)\n ? pair.lastReviewedAt\n : (existing?.lastReviewedAt ?? pair.lastReviewedAt),\n resolution: undefined,\n deferredUntil: (existingDeferralExpired || existingDormantExpired || contentChanged)\n ? undefined\n : existing?.deferredUntil,\n };\n\n const filePath = pairPath(memoryDir, pairId);\n writePairFile(filePath, full);\n\n return full;\n}\n\n/**\n * Write multiple pairs, deduplicating inputs first (rule 49).\n */\nexport function writePairs(\n memoryDir: string,\n pairs: Array<Omit<ContradictionPair, \"pairId\"> & { memoryIds: [string, string] }>,\n options: WritePairOptions = {},\n): ContradictionPair[] {\n const seen = new Set<string>();\n const results: ContradictionPair[] = [];\n\n for (const pair of pairs) {\n const key = computePairId(pair.memoryIds[0], pair.memoryIds[1], pair.namespace);\n if (seen.has(key)) continue;\n seen.add(key);\n results.push(writePair(memoryDir, pair, options));\n }\n\n return results;\n}\n\n// ── Read ───────────────────────────────────────────────────────────────────────\n\n/**\n * Read a single pair by ID. Returns null if not found.\n */\nexport function readPair(memoryDir: string, pairId: string): ContradictionPair | null {\n const filePath = pairPath(memoryDir, pairId);\n try {\n if (!isSafeReviewJsonFile(memoryDir, filePath)) return null;\n const raw = fs.readFileSync(filePath, \"utf-8\");\n const parsed = JSON.parse(raw);\n if (typeof parsed === \"object\" && parsed !== null && Array.isArray(parsed.memoryIds)) {\n return parsed as ContradictionPair;\n }\n return null;\n } catch {\n return null;\n }\n}\n\n/**\n * List pairs in the review queue, optionally filtered by verdict.\n */\nexport function listPairs(\n memoryDir: string,\n options?: {\n filter?: ContradictionFilter;\n namespace?: string;\n includeUnscopedForNamespace?: boolean;\n limit?: number;\n },\n): ContradictionListResult {\n const startTime = Date.now();\n const dir = reviewDir(memoryDir);\n const { filter = \"all\", namespace, includeUnscopedForNamespace = false, limit = 50 } = options ?? {};\n const pairs: ContradictionPair[] = [];\n let total = 0;\n\n if (!fs.existsSync(dir)) {\n return { pairs: [], total: 0, durationMs: Date.now() - startTime };\n }\n\n for (const entry of fs.readdirSync(dir)) {\n if (!entry.endsWith(\".json\")) continue;\n\n try {\n const filePath = path.join(dir, entry);\n if (!isSafeReviewJsonFile(memoryDir, filePath)) continue;\n const raw = fs.readFileSync(filePath, \"utf-8\");\n const pair = JSON.parse(raw) as ContradictionPair;\n\n if (typeof pair !== \"object\" || pair === null) continue;\n if (!Array.isArray(pair.memoryIds)) continue;\n\n // Namespace filter\n if (namespace && pair.namespace !== namespace && !(includeUnscopedForNamespace && pair.namespace === undefined)) continue;\n\n // Verdict filter\n if (filter === \"unresolved\") {\n if (isTerminalResolution(pair.resolution)) continue;\n if (isDeferralActive(pair)) continue;\n if (pair.resolution === \"both-valid\") continue;\n if (pair.verdict === \"independent\") continue;\n } else if (filter !== \"all\" && pair.verdict !== filter) {\n continue;\n }\n\n total++;\n if (pairs.length < limit) pairs.push(pair);\n } catch {\n continue;\n }\n }\n\n return { pairs, total, durationMs: Date.now() - startTime };\n}\n\nexport function migrateUnscopedPairsToNamespace(memoryDir: string, namespace: string, options: WritePairOptions = {}): number {\n const resolvedNamespace = namespace.trim();\n if (!resolvedNamespace) return 0;\n\n const dir = reviewDir(memoryDir);\n if (!fs.existsSync(dir)) return 0;\n const markerPath = migrationMarkerPath(memoryDir, resolvedNamespace);\n if (fs.existsSync(markerPath)) return 0;\n\n let migrated = 0;\n let hadMigrationFailure = false;\n for (const entry of fs.readdirSync(dir)) {\n if (!entry.endsWith(\".json\")) continue;\n const filePath = path.join(dir, entry);\n\n try {\n if (!isSafeReviewJsonFile(memoryDir, filePath)) continue;\n const raw = fs.readFileSync(filePath, \"utf-8\");\n const pair = JSON.parse(raw) as ContradictionPair;\n if (typeof pair !== \"object\" || pair === null) continue;\n if (!Array.isArray(pair.memoryIds)) continue;\n if (pair.namespace !== undefined) continue;\n\n const pairId = computePairId(pair.memoryIds[0], pair.memoryIds[1], resolvedNamespace);\n const migratedPair = { ...pair, namespace: resolvedNamespace, pairId };\n const targetPath = pairPath(memoryDir, pairId);\n try {\n if (targetPath === filePath) {\n writePairFile(filePath, migratedPair);\n } else if (!fs.existsSync(targetPath)) {\n writePairFile(targetPath, migratedPair);\n fs.rmSync(filePath, { force: true });\n } else {\n if (!isSafeReviewJsonFile(memoryDir, targetPath)) {\n hadMigrationFailure = true;\n continue;\n }\n const existing = readPair(memoryDir, pairId);\n writePairFile(targetPath, existing ? mergeMigratedPair(existing, migratedPair, options) : migratedPair);\n fs.rmSync(filePath, { force: true });\n }\n migrated += 1;\n } catch {\n hadMigrationFailure = true;\n continue;\n }\n } catch {\n continue;\n }\n }\n\n if (!hadMigrationFailure) {\n try {\n fs.writeFileSync(markerPath, `${new Date().toISOString()}\\n`, { encoding: \"utf-8\", flag: \"wx\" });\n } catch {\n // Another caller may have completed the same one-shot migration first.\n }\n }\n\n return migrated;\n}\n\n// ── Cooldown ───────────────────────────────────────────────────────────────────\n\n/**\n * Check if a pair is within its cooldown window.\n * Returns true if the pair should be SKIPPED (still cooling down).\n */\nexport function isCoolingDown(pair: ContradictionPair, cooldownDays: number): boolean {\n if (cooldownDays <= 0) return false; // rule 27: guard against 0\n\n const deferredUntil = deferralUntilMillis(pair);\n if (deferredUntil !== null) {\n return Date.now() < deferredUntil;\n }\n\n if (!pair.lastReviewedAt) return false;\n\n const lastReviewed = parseIsoMillis(pair.lastReviewedAt);\n if (lastReviewed === null) return false;\n\n const cooldownMs = cooldownDays * 24 * 60 * 60 * 1000;\n return Date.now() < lastReviewed + cooldownMs;\n}\n\n/**\n * Mark a pair as reviewed (sets lastReviewedAt and, for terminal verbs, resolution).\n */\nexport function resolvePair(\n memoryDir: string,\n pairId: string,\n verb: ResolutionVerb,\n): ContradictionPair | null {\n if (typeof verb !== \"string\" || !VALID_RESOLUTION_VERBS.includes(verb)) {\n throw new Error(`Invalid contradiction resolution verb: ${String(verb)}`);\n }\n\n if (verb === \"needs-more-context\") {\n return deferPair(memoryDir, pairId);\n }\n\n const existing = readPair(memoryDir, pairId);\n if (!existing) return null;\n if (preservesDirectResolution(existing.resolution)) return existing;\n\n const updated: ContradictionPair = {\n ...existing,\n lastReviewedAt: new Date().toISOString(),\n resolution: verb,\n deferredUntil: undefined,\n };\n\n const filePath = pairPath(memoryDir, pairId);\n writePairFile(filePath, updated);\n\n return updated;\n}\n\n/**\n * Defer a pair without terminally resolving it.\n */\nexport function deferPair(\n memoryDir: string,\n pairId: string,\n deferredUntil = new Date(Date.now() + NEEDS_MORE_CONTEXT_COOLDOWN_MS).toISOString(),\n): ContradictionPair | null {\n const existing = readPair(memoryDir, pairId);\n if (!existing) return null;\n if (preservesDirectResolution(existing.resolution)) return existing;\n\n const updated: ContradictionPair = {\n ...existing,\n lastReviewedAt: new Date().toISOString(),\n resolution: undefined,\n deferredUntil,\n };\n\n const filePath = pairPath(memoryDir, pairId);\n writePairFile(filePath, updated);\n\n return updated;\n}\n\n/**\n * Check whether a pair's referenced memories have changed since detection,\n * which should override cooldown.\n */\nexport function memoryHashesChanged(\n _memoryDir: string,\n pair: ContradictionPair,\n getCurrentHash: (memoryId: string) => string | null,\n): boolean {\n if (!pair.memoryContentHashes) return false;\n\n for (const memoryId of pair.memoryIds) {\n const previousHash = pair.memoryContentHashes[memoryId];\n if (typeof previousHash !== \"string\") continue;\n\n const currentHash = getCurrentHash(memoryId);\n if (currentHash !== null && currentHash !== previousHash) return true;\n }\n\n return false;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -24,7 +24,7 @@ function inDateRange(turn, fromTs, toTs) {
|
|
|
24
24
|
const turnTs = parseIsoTimestamp(turn.timestamp);
|
|
25
25
|
if (turnTs === null) return false;
|
|
26
26
|
if (fromTs !== null && turnTs < fromTs) return false;
|
|
27
|
-
if (toTs !== null && turnTs
|
|
27
|
+
if (toTs !== null && turnTs >= toTs) return false;
|
|
28
28
|
return true;
|
|
29
29
|
}
|
|
30
30
|
function buildReplayNormalizerRegistry(normalizers) {
|
|
@@ -142,4 +142,4 @@ export {
|
|
|
142
142
|
runReplay,
|
|
143
143
|
runReplayWithNormalizer
|
|
144
144
|
};
|
|
145
|
-
//# sourceMappingURL=chunk-
|
|
145
|
+
//# sourceMappingURL=chunk-HOJZMQ4J.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/replay/runner.ts"],"sourcesContent":["import {\n parseIsoTimestamp,\n type ReplayNormalizer,\n type ReplayParseOptions,\n type ReplaySource,\n type ReplayTurn,\n type ReplayWarning,\n type ReplayValidationIssue,\n validateReplayTurn,\n} from \"./types.js\";\n\nexport interface ReplayRunOptions extends ReplayParseOptions {\n dryRun?: boolean;\n startOffset?: number;\n maxTurns?: number;\n batchSize?: number;\n}\n\nexport interface ReplayRunHandlers {\n onTurn?: (turn: ReplayTurn) => Promise<void> | void;\n onBatch?: (turns: ReplayTurn[]) => Promise<void> | void;\n}\n\nexport interface ReplayRunSummary {\n source: ReplaySource;\n parsedTurns: number;\n validTurns: number;\n invalidTurns: number;\n filteredByDate: number;\n skippedByOffset: number;\n processedTurns: number;\n batchCount: number;\n dryRun: boolean;\n nextOffset: number;\n firstTimestamp?: string;\n lastTimestamp?: string;\n warnings: ReplayWarning[];\n}\n\nexport type ReplayNormalizerRegistry = Record<ReplaySource, ReplayNormalizer>;\n\nfunction clampNonNegativeInt(value: number | undefined, defaultValue: number): number {\n if (!Number.isFinite(value as number)) return defaultValue;\n return Math.max(0, Math.floor(value as number));\n}\n\nexport function clampBatchSize(value: number | undefined): number {\n const parsed = clampNonNegativeInt(value, 100);\n if (parsed < 1) return 1;\n return Math.min(parsed, 1000);\n}\n\nfunction toWarning(issue: ReplayValidationIssue): ReplayWarning {\n return {\n code: issue.code,\n message: issue.message,\n index: issue.index,\n };\n}\n\nfunction inDateRange(turn: ReplayTurn, fromTs: number | null, toTs: number | null): boolean {\n const turnTs = parseIsoTimestamp(turn.timestamp);\n if (turnTs === null) return false;\n if (fromTs !== null && turnTs < fromTs) return false;\n if (toTs !== null && turnTs >= toTs) return false;\n return true;\n}\n\nexport function buildReplayNormalizerRegistry(normalizers: ReplayNormalizer[]): ReplayNormalizerRegistry {\n const registry = {} as ReplayNormalizerRegistry;\n for (const normalizer of normalizers) {\n if (!normalizer?.source) {\n throw new Error(\"replay normalizer source is required\");\n }\n if (registry[normalizer.source]) {\n throw new Error(`duplicate replay normalizer for source '${normalizer.source}'`);\n }\n registry[normalizer.source] = normalizer;\n }\n return registry;\n}\n\nexport async function runReplay(\n source: ReplaySource,\n input: unknown,\n registry: ReplayNormalizerRegistry,\n handlers: ReplayRunHandlers = {},\n options: ReplayRunOptions = {},\n): Promise<ReplayRunSummary> {\n const normalizer = registry[source];\n if (!normalizer) {\n throw new Error(`missing replay normalizer for source '${source}'`);\n }\n return runReplayWithNormalizer(normalizer, input, handlers, options);\n}\n\nexport async function runReplayWithNormalizer(\n normalizer: ReplayNormalizer,\n input: unknown,\n handlers: ReplayRunHandlers = {},\n options: ReplayRunOptions = {},\n): Promise<ReplayRunSummary> {\n const parseResult = await normalizer.parse(input, options);\n if (!parseResult || typeof parseResult !== \"object\") {\n throw new Error(`replay normalizer '${normalizer.source}' returned invalid parse result object`);\n }\n if (!Array.isArray(parseResult.turns)) {\n throw new Error(`replay normalizer '${normalizer.source}' returned invalid parse result: turns must be an array`);\n }\n if (parseResult.warnings != null && !Array.isArray(parseResult.warnings)) {\n throw new Error(`replay normalizer '${normalizer.source}' returned invalid parse result: warnings must be an array`);\n }\n const warnings: ReplayWarning[] = [...(parseResult.warnings ?? [])];\n const parsedTurns = parseResult.turns;\n\n const validTurns: ReplayTurn[] = [];\n let invalidTurns = 0;\n for (let i = 0; i < parsedTurns.length; i += 1) {\n const turn = parsedTurns[i];\n const issues = validateReplayTurn(turn, i);\n if (issues.length === 0 && turn.source !== normalizer.source) {\n issues.push({\n code: \"turn.source.mismatch\",\n message: `Replay turn source '${turn.source}' does not match normalizer source '${normalizer.source}'.`,\n index: i,\n });\n }\n if (issues.length > 0) {\n invalidTurns += 1;\n for (const issue of issues) warnings.push(toWarning(issue));\n continue;\n }\n validTurns.push(turn);\n }\n\n const sorted = [...validTurns].sort((a, b) => {\n const left = parseIsoTimestamp(a.timestamp) ?? 0;\n const right = parseIsoTimestamp(b.timestamp) ?? 0;\n return left - right;\n });\n\n const fromTs = options.from ? parseIsoTimestamp(options.from) : null;\n const toTs = options.to ? parseIsoTimestamp(options.to) : null;\n if (options.from && fromTs === null) {\n throw new Error(`invalid replay --from timestamp '${options.from}'`);\n }\n if (options.to && toTs === null) {\n throw new Error(`invalid replay --to timestamp '${options.to}'`);\n }\n if (fromTs !== null && toTs !== null && fromTs > toTs) {\n throw new Error(\"invalid replay date range: --from is after --to\");\n }\n\n const ranged = sorted.filter((turn) => inDateRange(turn, fromTs, toTs));\n const filteredByDate = sorted.length - ranged.length;\n\n const startOffset = clampNonNegativeInt(options.startOffset, 0);\n const skippedByOffset = Math.min(startOffset, ranged.length);\n const offsetApplied = ranged.slice(startOffset);\n\n const maxTurns = clampNonNegativeInt(options.maxTurns, offsetApplied.length);\n const selected = offsetApplied.slice(0, maxTurns);\n const dryRun = options.dryRun === true;\n const batchSize = clampBatchSize(options.batchSize);\n\n let batchCount = 0;\n if (!dryRun) {\n for (let i = 0; i < selected.length; i += batchSize) {\n const batch = selected.slice(i, i + batchSize);\n batchCount += 1;\n if (handlers.onBatch) await handlers.onBatch(batch);\n if (handlers.onTurn) {\n for (const turn of batch) {\n await handlers.onTurn(turn);\n }\n }\n }\n } else if (selected.length > 0) {\n batchCount = Math.ceil(selected.length / batchSize);\n }\n\n return {\n source: normalizer.source,\n parsedTurns: parsedTurns.length,\n validTurns: sorted.length,\n invalidTurns,\n filteredByDate,\n skippedByOffset,\n processedTurns: selected.length,\n batchCount,\n dryRun,\n nextOffset: startOffset + selected.length,\n firstTimestamp: selected[0]?.timestamp,\n lastTimestamp: selected[selected.length - 1]?.timestamp,\n warnings,\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -6,9 +6,9 @@ import {
|
|
|
6
6
|
} from "./chunk-2ODBA7MQ.js";
|
|
7
7
|
|
|
8
8
|
// src/routing/store.ts
|
|
9
|
-
import { lstat, mkdir, readFile, realpath, rename, rm, stat, writeFile } from "fs/promises";
|
|
9
|
+
import { lstat, mkdir, readFile, realpath, rename, rm, rmdir, stat, writeFile } from "fs/promises";
|
|
10
10
|
import path from "path";
|
|
11
|
-
import { createHash } from "crypto";
|
|
11
|
+
import { createHash, randomUUID } from "crypto";
|
|
12
12
|
function defaultState() {
|
|
13
13
|
return {
|
|
14
14
|
version: 1,
|
|
@@ -37,7 +37,6 @@ function resolveStatePath(memoryDir, stateFile) {
|
|
|
37
37
|
}
|
|
38
38
|
function normalizeRule(rule, options) {
|
|
39
39
|
if (!rule || typeof rule !== "object") return null;
|
|
40
|
-
if (rule.enabled === false) return null;
|
|
41
40
|
if (rule.patternType !== "keyword" && rule.patternType !== "regex") return null;
|
|
42
41
|
if (typeof rule.pattern !== "string" || rule.pattern.trim().length === 0) return null;
|
|
43
42
|
if (typeof rule.priority !== "number" || !Number.isFinite(rule.priority)) return null;
|
|
@@ -57,7 +56,7 @@ function normalizeRule(rule, options) {
|
|
|
57
56
|
pattern: rule.pattern.trim(),
|
|
58
57
|
priority: normalizedPriority,
|
|
59
58
|
target: normalizedTarget,
|
|
60
|
-
enabled: true
|
|
59
|
+
enabled: rule.enabled === false ? false : true
|
|
61
60
|
};
|
|
62
61
|
}
|
|
63
62
|
function isEnoent(err) {
|
|
@@ -200,9 +199,15 @@ var RoutingRulesStore = class {
|
|
|
200
199
|
while (Date.now() - start < timeoutMs) {
|
|
201
200
|
try {
|
|
202
201
|
await mkdir(this.lockPath);
|
|
202
|
+
const ownerPath = path.join(this.lockPath, "owner");
|
|
203
|
+
const ownerToken = `${process.pid}:${randomUUID()}`;
|
|
204
|
+
await writeFile(ownerPath, ownerToken, "utf-8");
|
|
203
205
|
return async () => {
|
|
204
206
|
try {
|
|
205
|
-
|
|
207
|
+
const currentOwner = await readFile(ownerPath, "utf-8").catch(() => "");
|
|
208
|
+
if (currentOwner === ownerToken) {
|
|
209
|
+
await rm(this.lockPath, { recursive: true, force: true });
|
|
210
|
+
}
|
|
206
211
|
} catch {
|
|
207
212
|
}
|
|
208
213
|
};
|
|
@@ -215,7 +220,7 @@ var RoutingRulesStore = class {
|
|
|
215
220
|
try {
|
|
216
221
|
const lockStat = await stat(this.lockPath);
|
|
217
222
|
if (Date.now() - lockStat.mtimeMs > staleMs) {
|
|
218
|
-
await
|
|
223
|
+
await this.removeStaleLock(lockStat);
|
|
219
224
|
continue;
|
|
220
225
|
}
|
|
221
226
|
} catch {
|
|
@@ -228,6 +233,27 @@ var RoutingRulesStore = class {
|
|
|
228
233
|
}
|
|
229
234
|
throw new Error(`routing rules lock acquisition timed out after ${timeoutMs}ms`);
|
|
230
235
|
}
|
|
236
|
+
async removeStaleLock(observedStat) {
|
|
237
|
+
const currentStat = await stat(this.lockPath);
|
|
238
|
+
if (!this.sameLockStat(observedStat, currentStat)) return;
|
|
239
|
+
try {
|
|
240
|
+
await rmdir(this.lockPath);
|
|
241
|
+
return;
|
|
242
|
+
} catch (err) {
|
|
243
|
+
const code = err.code;
|
|
244
|
+
if (code !== "ENOTEMPTY" && code !== "EEXIST") {
|
|
245
|
+
throw err;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
const quarantinePath = `${this.lockPath}.stale-${process.pid}-${Date.now()}-${randomUUID()}`;
|
|
249
|
+
await rename(this.lockPath, quarantinePath);
|
|
250
|
+
await rm(quarantinePath, { recursive: true, force: true });
|
|
251
|
+
}
|
|
252
|
+
sameLockStat(left, right) {
|
|
253
|
+
if (left.mtimeMs !== right.mtimeMs || left.size !== right.size) return false;
|
|
254
|
+
if (left.ino && right.ino && left.ino !== right.ino) return false;
|
|
255
|
+
return true;
|
|
256
|
+
}
|
|
231
257
|
async assertStatePathScoped() {
|
|
232
258
|
await mkdir(this.memoryRoot, { recursive: true });
|
|
233
259
|
const canonicalRoot = await realpath(this.memoryRoot);
|
|
@@ -284,4 +310,4 @@ var RoutingRulesStore = class {
|
|
|
284
310
|
export {
|
|
285
311
|
RoutingRulesStore
|
|
286
312
|
};
|
|
287
|
-
//# sourceMappingURL=chunk-
|
|
313
|
+
//# sourceMappingURL=chunk-HPWVAEET.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/routing/store.ts"],"sourcesContent":["import { lstat, mkdir, readFile, realpath, rename, rm, rmdir, stat, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { createHash, randomUUID } from \"node:crypto\";\nimport { log } from \"../logger.js\";\nimport { validateRouteTarget, type RouteRule, type RoutingEngineOptions } from \"./engine.js\";\n\ntype RoutingRulesState = {\n version: 1;\n updatedAt: string;\n rules: RouteRule[];\n};\n\nfunction defaultState(): RoutingRulesState {\n return {\n version: 1,\n updatedAt: new Date(0).toISOString(),\n rules: [],\n };\n}\n\nfunction stableRuleId(rule: Pick<RouteRule, \"patternType\" | \"pattern\" | \"priority\" | \"target\">): string {\n const seed = JSON.stringify({\n patternType: rule.patternType,\n pattern: rule.pattern.trim(),\n priority: rule.priority,\n target: rule.target,\n });\n return `route-${createHash(\"sha256\").update(seed).digest(\"hex\").slice(0, 12)}`;\n}\n\nfunction resolveStatePath(memoryDir: string, stateFile: string): string {\n const root = path.resolve(memoryDir);\n const defaultPath = path.join(root, \"state\", \"routing-rules.json\");\n if (path.isAbsolute(stateFile)) {\n const absolute = path.resolve(stateFile);\n return absolute.startsWith(root + path.sep) ? absolute : defaultPath;\n }\n const resolved = path.resolve(root, stateFile);\n return resolved.startsWith(root + path.sep) ? resolved : defaultPath;\n}\n\nfunction normalizeRule(rule: RouteRule, options?: RoutingEngineOptions): RouteRule | null {\n if (!rule || typeof rule !== \"object\") return null;\n if (rule.patternType !== \"keyword\" && rule.patternType !== \"regex\") return null;\n if (typeof rule.pattern !== \"string\" || rule.pattern.trim().length === 0) return null;\n if (typeof rule.priority !== \"number\" || !Number.isFinite(rule.priority)) return null;\n\n const targetValidation = validateRouteTarget(rule.target, options);\n if (!targetValidation.ok || !targetValidation.target) return null;\n\n const normalizedPriority = Math.trunc(rule.priority);\n const normalizedTarget = targetValidation.target;\n const id = typeof rule.id === \"string\" && rule.id.trim().length > 0\n ? rule.id.trim()\n : stableRuleId({\n patternType: rule.patternType,\n pattern: rule.pattern.trim(),\n priority: normalizedPriority,\n target: normalizedTarget,\n });\n return {\n id,\n patternType: rule.patternType,\n pattern: rule.pattern.trim(),\n priority: normalizedPriority,\n target: normalizedTarget,\n enabled: rule.enabled === false ? false : true,\n };\n}\n\nfunction isEnoent(err: unknown): boolean {\n return err instanceof Error && \"code\" in err && (err as NodeJS.ErrnoException).code === \"ENOENT\";\n}\n\nexport class RoutingRulesStore {\n private readonly memoryRoot: string;\n private readonly statePath: string;\n private readonly lockPath: string;\n private writeQueue: Promise<void> = Promise.resolve();\n\n constructor(memoryDir: string, stateFile = \"state/routing-rules.json\") {\n this.memoryRoot = path.resolve(memoryDir);\n this.statePath = resolveStatePath(memoryDir, stateFile);\n this.lockPath = `${this.statePath}.lock`;\n }\n\n async read(options?: RoutingEngineOptions): Promise<RouteRule[]> {\n try {\n const persisted = await this.readPersistedRules();\n return persisted\n .map((rule) => normalizeRule(rule, options))\n .filter((rule): rule is RouteRule => rule !== null);\n } catch {\n return [];\n }\n }\n\n async write(rules: RouteRule[], options?: RoutingEngineOptions): Promise<RouteRule[]> {\n return this.withWriteLock(async () => {\n await this.readPersistedRules();\n return this.writeNormalized(rules, options);\n });\n }\n\n async upsert(rule: RouteRule, options?: RoutingEngineOptions): Promise<RouteRule[]> {\n return this.withWriteLock(async () => {\n const existing = await this.readPersistedRules();\n const normalized = normalizeRule(rule, options);\n if (!normalized) return existing;\n\n const next = existing.filter((entry) => entry.id !== normalized.id);\n next.push(normalized);\n return this.writeNormalized(next);\n });\n }\n\n async removeByPattern(pattern: string): Promise<RouteRule[]> {\n return this.withWriteLock(async () => {\n const trimmed = pattern.trim();\n const existing = await this.readPersistedRules();\n const next = existing.filter((entry) => entry.pattern !== trimmed);\n if (next.length === existing.length) return existing;\n return this.writeNormalized(next);\n });\n }\n\n async reset(): Promise<void> {\n await this.withWriteLock(async () => {\n await this.writeState(defaultState());\n });\n }\n\n private dedupeById(rules: RouteRule[]): RouteRule[] {\n const byId = new Map<string, RouteRule>();\n for (const rule of rules) {\n byId.set(rule.id, rule);\n }\n return Array.from(byId.values());\n }\n\n private async readPersistedRules(): Promise<RouteRule[]> {\n await this.assertStatePathScoped();\n let raw: string;\n try {\n raw = await readFile(this.statePath, \"utf-8\");\n } catch (err) {\n if (isEnoent(err)) {\n return [];\n }\n throw err;\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (err) {\n throw new Error(\n `failed to parse routing rules state at ${this.statePath}: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n throw new Error(`invalid routing rules state at ${this.statePath}: expected object`);\n }\n const state = parsed as Partial<RoutingRulesState>;\n if (!Array.isArray(state.rules)) {\n throw new Error(`invalid routing rules state at ${this.statePath}: rules must be an array`);\n }\n const normalized = state.rules\n .map((rule) => normalizeRule(rule))\n .filter((rule): rule is RouteRule => rule !== null);\n return this.dedupeById(normalized);\n }\n\n private async writeNormalized(rules: RouteRule[], options?: RoutingEngineOptions): Promise<RouteRule[]> {\n const normalized = this.dedupeById(\n rules\n .map((rule) => normalizeRule(rule, options))\n .filter((rule): rule is RouteRule => rule !== null),\n );\n\n const payload: RoutingRulesState = {\n version: 1,\n updatedAt: new Date().toISOString(),\n rules: normalized,\n };\n\n await this.writeState(payload);\n\n return normalized;\n }\n\n private async writeState(payload: RoutingRulesState): Promise<void> {\n const tmpPath = `${this.statePath}.tmp-${process.pid}-${Date.now()}`;\n try {\n await this.assertStatePathScoped();\n await writeFile(tmpPath, JSON.stringify(payload, null, 2), \"utf-8\");\n await rename(tmpPath, this.statePath);\n } catch (err) {\n log.debug(`routing rules write failed: ${err}`);\n throw err;\n } finally {\n await rm(tmpPath, { force: true }).catch(() => {});\n }\n }\n\n private async withWriteLock<T>(op: () => Promise<T>): Promise<T> {\n const previous = this.writeQueue;\n let release: () => void = () => {};\n this.writeQueue = new Promise<void>((resolve) => {\n release = resolve;\n });\n await previous;\n let unlock: (() => Promise<void>) | null = null;\n try {\n unlock = await this.acquireFileLock();\n return await op();\n } finally {\n if (unlock) await unlock();\n release();\n }\n }\n\n private async acquireFileLock(): Promise<() => Promise<void>> {\n const start = Date.now();\n const staleMs = 30_000;\n const timeoutMs = 5_000;\n let unexpectedLockError: unknown = null;\n await this.assertStatePathScoped();\n await mkdir(path.dirname(this.lockPath), { recursive: true });\n\n while (Date.now() - start < timeoutMs) {\n try {\n await mkdir(this.lockPath);\n const ownerPath = path.join(this.lockPath, \"owner\");\n const ownerToken = `${process.pid}:${randomUUID()}`;\n await writeFile(ownerPath, ownerToken, \"utf-8\");\n return async () => {\n try {\n const currentOwner = await readFile(ownerPath, \"utf-8\").catch(() => \"\");\n if (currentOwner === ownerToken) {\n await rm(this.lockPath, { recursive: true, force: true });\n }\n } catch {\n // Fail-open: lock cleanup should not fail writes.\n }\n };\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code !== \"EEXIST\") {\n unexpectedLockError = err;\n break;\n }\n try {\n const lockStat = await stat(this.lockPath);\n if (Date.now() - lockStat.mtimeMs > staleMs) {\n await this.removeStaleLock(lockStat);\n continue;\n }\n } catch {\n // Lock may have been released between stat/rm attempts.\n }\n await new Promise((resolve) => setTimeout(resolve, 25));\n }\n }\n\n if (unexpectedLockError) {\n throw unexpectedLockError;\n }\n throw new Error(`routing rules lock acquisition timed out after ${timeoutMs}ms`);\n }\n\n private async removeStaleLock(observedStat: Awaited<ReturnType<typeof stat>>): Promise<void> {\n const currentStat = await stat(this.lockPath);\n if (!this.sameLockStat(observedStat, currentStat)) return;\n\n try {\n await rmdir(this.lockPath);\n return;\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code !== \"ENOTEMPTY\" && code !== \"EEXIST\") {\n throw err;\n }\n }\n\n const quarantinePath = `${this.lockPath}.stale-${process.pid}-${Date.now()}-${randomUUID()}`;\n await rename(this.lockPath, quarantinePath);\n await rm(quarantinePath, { recursive: true, force: true });\n }\n\n private sameLockStat(left: Awaited<ReturnType<typeof stat>>, right: Awaited<ReturnType<typeof stat>>): boolean {\n if (left.mtimeMs !== right.mtimeMs || left.size !== right.size) return false;\n if (left.ino && right.ino && left.ino !== right.ino) return false;\n return true;\n }\n\n private async assertStatePathScoped(): Promise<void> {\n await mkdir(this.memoryRoot, { recursive: true });\n const canonicalRoot = await realpath(this.memoryRoot);\n const canonicalParent = await this.canonicalizePathWithoutCreating(path.dirname(this.statePath));\n const canonicalStatePath = path.join(canonicalParent, path.basename(this.statePath));\n if (!this.isPathInside(canonicalRoot, canonicalStatePath)) {\n throw new Error(`routing rules state path escaped memoryDir: ${canonicalStatePath}`);\n }\n await mkdir(path.dirname(this.statePath), { recursive: true });\n try {\n const stateStats = await lstat(this.statePath);\n if (stateStats.isSymbolicLink()) {\n throw new Error(`routing rules state path must not be a symlink: ${this.statePath}`);\n }\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code !== \"ENOENT\") {\n throw err;\n }\n }\n }\n\n private isPathInside(root: string, candidate: string): boolean {\n const normalizedRoot = path.resolve(root);\n const normalizedCandidate = path.resolve(candidate);\n if (normalizedCandidate === normalizedRoot) return true;\n if (normalizedRoot === path.parse(normalizedRoot).root) {\n return normalizedCandidate.startsWith(normalizedRoot);\n }\n return normalizedCandidate.startsWith(`${normalizedRoot}${path.sep}`);\n }\n\n private async canonicalizePathWithoutCreating(targetPath: string): Promise<string> {\n const absoluteTarget = path.resolve(targetPath);\n let probe = absoluteTarget;\n while (true) {\n try {\n const canonicalProbe = await realpath(probe);\n const remainder = path.relative(probe, absoluteTarget);\n return path.resolve(canonicalProbe, remainder);\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code !== \"ENOENT\") {\n throw err;\n }\n const parent = path.dirname(probe);\n if (parent === probe) {\n return absoluteTarget;\n }\n probe = parent;\n }\n }\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -25,6 +25,73 @@ function makeTraceId(topics) {
|
|
|
25
25
|
const key = topics.slice().sort().join(",");
|
|
26
26
|
return `trace-${createHash("sha256").update(key).digest("hex").slice(0, 8)}`;
|
|
27
27
|
}
|
|
28
|
+
function isRecord(value) {
|
|
29
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
30
|
+
}
|
|
31
|
+
function isStringArray(value) {
|
|
32
|
+
return Array.isArray(value) && value.every((entry) => typeof entry === "string");
|
|
33
|
+
}
|
|
34
|
+
function isStringRecord(value) {
|
|
35
|
+
return isRecord(value) && Object.values(value).every((entry) => typeof entry === "string");
|
|
36
|
+
}
|
|
37
|
+
function isStringArrayRecord(value) {
|
|
38
|
+
return isRecord(value) && Object.values(value).every(isStringArray);
|
|
39
|
+
}
|
|
40
|
+
function parseOpenBoxState(value) {
|
|
41
|
+
if (value === null) return null;
|
|
42
|
+
if (!isRecord(value)) return null;
|
|
43
|
+
if (typeof value.id !== "string" || typeof value.createdAt !== "string" || typeof value.lastActivityAt !== "string" || !isStringArray(value.topics) || !isStringArray(value.memoryIds)) {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
if (value.goal !== void 0 && typeof value.goal !== "string") return null;
|
|
47
|
+
if (value.toolsUsed !== void 0 && !isStringArray(value.toolsUsed)) return null;
|
|
48
|
+
return {
|
|
49
|
+
id: value.id,
|
|
50
|
+
createdAt: value.createdAt,
|
|
51
|
+
lastActivityAt: value.lastActivityAt,
|
|
52
|
+
topics: value.topics,
|
|
53
|
+
memoryIds: value.memoryIds,
|
|
54
|
+
goal: value.goal,
|
|
55
|
+
toolsUsed: value.toolsUsed
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
function parseTraceIndex(value) {
|
|
59
|
+
if (!isRecord(value)) return null;
|
|
60
|
+
if (!isStringArrayRecord(value.traces) || !isStringRecord(value.boxToTrace) || !isStringArrayRecord(value.traceTopics)) {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
const traceLastSeen = value.traceLastSeen ?? {};
|
|
64
|
+
if (!isStringRecord(traceLastSeen)) return null;
|
|
65
|
+
return {
|
|
66
|
+
traces: value.traces,
|
|
67
|
+
boxToTrace: value.boxToTrace,
|
|
68
|
+
traceTopics: value.traceTopics,
|
|
69
|
+
traceLastSeen
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function serializeStringArray(values) {
|
|
73
|
+
return JSON.stringify(values);
|
|
74
|
+
}
|
|
75
|
+
function parseStringArray(val) {
|
|
76
|
+
if (!val) return [];
|
|
77
|
+
try {
|
|
78
|
+
const parsed = JSON.parse(val);
|
|
79
|
+
if (Array.isArray(parsed)) {
|
|
80
|
+
return parsed.filter((entry) => typeof entry === "string");
|
|
81
|
+
}
|
|
82
|
+
} catch {
|
|
83
|
+
}
|
|
84
|
+
const start = val.indexOf("[");
|
|
85
|
+
const end = val.lastIndexOf("]");
|
|
86
|
+
if (start === -1 || end <= start) return [];
|
|
87
|
+
return val.slice(start + 1, end).split(",").map((s) => stripLegacyQuotes(s.trim())).filter(Boolean);
|
|
88
|
+
}
|
|
89
|
+
function stripLegacyQuotes(value) {
|
|
90
|
+
if (value.length >= 2 && value.startsWith('"') && value.endsWith('"')) {
|
|
91
|
+
return value.slice(1, -1);
|
|
92
|
+
}
|
|
93
|
+
return value;
|
|
94
|
+
}
|
|
28
95
|
function serializeBoxFrontmatter(fm) {
|
|
29
96
|
const lines = [
|
|
30
97
|
"---",
|
|
@@ -33,13 +100,13 @@ function serializeBoxFrontmatter(fm) {
|
|
|
33
100
|
`createdAt: ${fm.createdAt}`,
|
|
34
101
|
`sealedAt: ${fm.sealedAt}`,
|
|
35
102
|
`sealReason: ${fm.sealReason}`,
|
|
36
|
-
`topics:
|
|
37
|
-
`memoryIds:
|
|
103
|
+
`topics: ${serializeStringArray(fm.topics)}`,
|
|
104
|
+
`memoryIds: ${serializeStringArray(fm.memoryIds)}`
|
|
38
105
|
];
|
|
39
106
|
if (fm.sessionKey) lines.push(`sessionKey: ${fm.sessionKey}`);
|
|
40
107
|
if (fm.traceId) lines.push(`traceId: ${fm.traceId}`);
|
|
41
108
|
if (fm.goal) lines.push(`goal: ${fm.goal.replace(/[\r\n]+/g, " ")}`);
|
|
42
|
-
if (fm.toolsUsed?.length) lines.push(`toolsUsed:
|
|
109
|
+
if (fm.toolsUsed?.length) lines.push(`toolsUsed: ${serializeStringArray(fm.toolsUsed)}`);
|
|
43
110
|
if (fm.outcome) lines.push(`outcome: ${fm.outcome}`);
|
|
44
111
|
lines.push("---");
|
|
45
112
|
return lines.join("\n");
|
|
@@ -54,12 +121,6 @@ function parseBoxFrontmatter(raw) {
|
|
|
54
121
|
if (colonIdx === -1) continue;
|
|
55
122
|
fm[line.slice(0, colonIdx).trim()] = line.slice(colonIdx + 1).trim();
|
|
56
123
|
}
|
|
57
|
-
const parseArray = (val) => {
|
|
58
|
-
if (!val) return [];
|
|
59
|
-
const m = val.match(/\[(.*)]/);
|
|
60
|
-
if (!m) return [];
|
|
61
|
-
return m[1].split(",").map((s) => s.trim().replace(/^"|"$/g, "")).filter(Boolean);
|
|
62
|
-
};
|
|
63
124
|
const outcome = fm.outcome;
|
|
64
125
|
return {
|
|
65
126
|
id: fm.id ?? "",
|
|
@@ -68,11 +129,11 @@ function parseBoxFrontmatter(raw) {
|
|
|
68
129
|
sealedAt: fm.sealedAt ?? "",
|
|
69
130
|
sealReason: fm.sealReason ?? "forced",
|
|
70
131
|
sessionKey: fm.sessionKey,
|
|
71
|
-
topics:
|
|
72
|
-
memoryIds:
|
|
132
|
+
topics: parseStringArray(fm.topics),
|
|
133
|
+
memoryIds: parseStringArray(fm.memoryIds),
|
|
73
134
|
traceId: fm.traceId,
|
|
74
135
|
goal: fm.goal || void 0,
|
|
75
|
-
toolsUsed: fm.toolsUsed ?
|
|
136
|
+
toolsUsed: fm.toolsUsed ? parseStringArray(fm.toolsUsed) : void 0,
|
|
76
137
|
outcome: outcome && ["success", "failure", "partial", "unknown"].includes(outcome) ? outcome : void 0
|
|
77
138
|
};
|
|
78
139
|
}
|
|
@@ -119,27 +180,26 @@ var BoxBuilder = class {
|
|
|
119
180
|
this.stateLoaded = true;
|
|
120
181
|
try {
|
|
121
182
|
const raw = await readFile(this.openBoxStatePath, "utf-8");
|
|
122
|
-
this.openBox = JSON.parse(raw);
|
|
183
|
+
this.openBox = parseOpenBoxState(JSON.parse(raw));
|
|
123
184
|
} catch {
|
|
124
185
|
this.openBox = null;
|
|
125
186
|
}
|
|
126
187
|
}
|
|
127
|
-
async
|
|
188
|
+
async writeOpenBoxState(state) {
|
|
128
189
|
await mkdir(this.stateDir, { recursive: true });
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
await writeFile(this.openBoxStatePath, "null", "utf-8");
|
|
134
|
-
} catch {
|
|
135
|
-
}
|
|
136
|
-
}
|
|
190
|
+
await writeFile(this.openBoxStatePath, JSON.stringify(state, null, 2), "utf-8");
|
|
191
|
+
}
|
|
192
|
+
async saveOpenBox() {
|
|
193
|
+
await this.writeOpenBoxState(this.openBox);
|
|
137
194
|
}
|
|
138
195
|
async loadTraceIndex() {
|
|
139
196
|
try {
|
|
140
197
|
const raw = await readFile(this.tracesPath, "utf-8");
|
|
141
|
-
const parsed = JSON.parse(raw);
|
|
142
|
-
parsed
|
|
198
|
+
const parsed = parseTraceIndex(JSON.parse(raw));
|
|
199
|
+
if (!parsed) {
|
|
200
|
+
log.warn("[engram/boxes] Ignoring invalid trace index state");
|
|
201
|
+
return { traces: {}, boxToTrace: {}, traceTopics: {}, traceLastSeen: {} };
|
|
202
|
+
}
|
|
143
203
|
return parsed;
|
|
144
204
|
} catch {
|
|
145
205
|
return { traces: {}, boxToTrace: {}, traceTopics: {}, traceLastSeen: {} };
|
|
@@ -149,8 +209,10 @@ var BoxBuilder = class {
|
|
|
149
209
|
try {
|
|
150
210
|
await mkdir(this.stateDir, { recursive: true });
|
|
151
211
|
await writeFile(this.tracesPath, JSON.stringify(idx, null, 2), "utf-8");
|
|
212
|
+
return true;
|
|
152
213
|
} catch (err) {
|
|
153
214
|
log.warn(`[engram/boxes] Failed to save trace index: ${err.message}`);
|
|
215
|
+
return false;
|
|
154
216
|
}
|
|
155
217
|
}
|
|
156
218
|
// ── Core logic ────────────────────────────────────────────────────────────
|
|
@@ -233,9 +295,9 @@ var BoxBuilder = class {
|
|
|
233
295
|
await this.loadOpenBox();
|
|
234
296
|
if (!this.openBox) return null;
|
|
235
297
|
const box = this.openBox;
|
|
236
|
-
this.openBox = null;
|
|
237
298
|
if (box.memoryIds.length === 0 && box.topics.length === 0) {
|
|
238
|
-
await this.
|
|
299
|
+
await this.writeOpenBoxState(null);
|
|
300
|
+
this.openBox = null;
|
|
239
301
|
return null;
|
|
240
302
|
}
|
|
241
303
|
const sealedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -266,7 +328,8 @@ var BoxBuilder = class {
|
|
|
266
328
|
const filePath = path.join(dir, `${box.id}.md`);
|
|
267
329
|
await writeFile(filePath, content, "utf-8");
|
|
268
330
|
log.debug(`[boxes] sealed box ${box.id} (${reason}): ${box.memoryIds.length} memories, topics=[${box.topics.join(",")}]`);
|
|
269
|
-
await this.
|
|
331
|
+
await this.writeOpenBoxState(null);
|
|
332
|
+
this.openBox = null;
|
|
270
333
|
return box.id;
|
|
271
334
|
}
|
|
272
335
|
// ── Trace Weaving ─────────────────────────────────────────────────────────
|
|
@@ -304,8 +367,7 @@ var BoxBuilder = class {
|
|
|
304
367
|
} else {
|
|
305
368
|
idx.traceTopics[traceId] = [...topics];
|
|
306
369
|
}
|
|
307
|
-
await this.saveTraceIndex(idx);
|
|
308
|
-
return traceId;
|
|
370
|
+
return await this.saveTraceIndex(idx) ? traceId : void 0;
|
|
309
371
|
}
|
|
310
372
|
// ── Recall ────────────────────────────────────────────────────────────────
|
|
311
373
|
/**
|
|
@@ -372,4 +434,4 @@ export {
|
|
|
372
434
|
parseBoxFrontmatter,
|
|
373
435
|
BoxBuilder
|
|
374
436
|
};
|
|
375
|
-
//# sourceMappingURL=chunk-
|
|
437
|
+
//# sourceMappingURL=chunk-HQ6NIBL6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/boxes.ts"],"sourcesContent":["/**\n * Memory Boxes + Trace Weaving (v8.0 Phase 2A)\n *\n * Implements the Membox concept: a sliding topic window that forms an \"open box\"\n * accumulating related memories. The box is sealed on topic shift or time gap,\n * then written to memory/boxes/YYYY-MM-DD/box-<id>.md.\n *\n * Trace Weaving links recurring topic boxes with a shared traceId so that\n * cross-session continuity on the same topics is preserved and discoverable.\n */\n\nimport { mkdir, writeFile, readFile, readdir } from \"node:fs/promises\";\nimport type { Dirent } from \"node:fs\";\nimport path from \"node:path\";\nimport { createHash } from \"node:crypto\";\nimport { log } from \"./logger.js\";\n\nexport const BOX_DIR = \"boxes\";\nconst STATE_DIR = \"state\";\nconst TRACES_FILE = \"traces.json\";\nconst OPEN_BOX_STATE_FILE = \"open-box.json\";\n\n// ── Types ─────────────────────────────────────────────────────────────────\n\nexport interface BoxFrontmatter {\n id: string;\n memoryKind: \"box\";\n createdAt: string;\n sealedAt: string;\n sealReason: SealReason;\n sessionKey?: string;\n topics: string[];\n memoryIds: string[];\n traceId?: string;\n /** High-level task goal for this episode (REMem-inspired). */\n goal?: string;\n /** Tools invoked during this episode. */\n toolsUsed?: string[];\n /** Episode outcome: success, failure, partial, or unknown. */\n outcome?: \"success\" | \"failure\" | \"partial\" | \"unknown\";\n}\n\nexport type SealReason = \"topic_shift\" | \"time_gap\" | \"max_memories\" | \"forced\" | \"flush\";\n\ninterface OpenBoxState {\n id: string;\n createdAt: string;\n lastActivityAt: string;\n topics: string[];\n memoryIds: string[];\n goal?: string;\n toolsUsed?: string[];\n}\n\ninterface TraceIndex {\n /** traceId → list of box IDs */\n traces: Record<string, string[]>;\n /** boxId → traceId */\n boxToTrace: Record<string, string>;\n /** traceId → canonical topic fingerprint for matching */\n traceTopics: Record<string, string[]>;\n /** traceId → ISO timestamp of last box added (for lookback filtering) */\n traceLastSeen: Record<string, string>;\n}\n\nexport interface BoxBuilderConfig {\n memoryBoxesEnabled: boolean;\n traceWeaverEnabled: boolean;\n /** Jaccard threshold below which topic shift triggers seal (0-1, default 0.35) */\n boxTopicShiftThreshold: number;\n /** Time gap in ms before sealing an open box (default 30 min) */\n boxTimeGapMs: number;\n /** Max memories in one box before forced seal */\n boxMaxMemories: number;\n /** Days back to look for trace links */\n traceWeaverLookbackDays: number;\n /** Minimum topic overlap to assign same traceId (0-1, default 0.4) */\n traceWeaverOverlapThreshold: number;\n}\n\ninterface ExtractionEvent {\n topics: string[];\n memoryIds: string[];\n timestamp: string;\n goal?: string;\n toolsUsed?: string[];\n}\n\n// ── Utility ───────────────────────────────────────────────────────────────\n\n/**\n * Jaccard similarity between two topic arrays.\n * Returns 0.0 for empty inputs.\n */\nexport function topicOverlapScore(a: string[], b: string[]): number {\n if (a.length === 0 || b.length === 0) return 0.0;\n const setA = new Set(a.map((t) => t.toLowerCase()));\n const setB = new Set(b.map((t) => t.toLowerCase()));\n const intersection = [...setA].filter((t) => setB.has(t)).length;\n const union = new Set([...setA, ...setB]).size;\n return union === 0 ? 0.0 : intersection / union;\n}\n\nfunction makeBoxId(): string {\n return `box-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;\n}\n\nfunction makeTraceId(topics: string[]): string {\n const key = topics.slice().sort().join(\",\");\n return `trace-${createHash(\"sha256\").update(key).digest(\"hex\").slice(0, 8)}`;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction isStringArray(value: unknown): value is string[] {\n return Array.isArray(value) && value.every((entry) => typeof entry === \"string\");\n}\n\nfunction isStringRecord(value: unknown): value is Record<string, string> {\n return isRecord(value) && Object.values(value).every((entry) => typeof entry === \"string\");\n}\n\nfunction isStringArrayRecord(value: unknown): value is Record<string, string[]> {\n return isRecord(value) && Object.values(value).every(isStringArray);\n}\n\nfunction parseOpenBoxState(value: unknown): OpenBoxState | null {\n if (value === null) return null;\n if (!isRecord(value)) return null;\n if (\n typeof value.id !== \"string\" ||\n typeof value.createdAt !== \"string\" ||\n typeof value.lastActivityAt !== \"string\" ||\n !isStringArray(value.topics) ||\n !isStringArray(value.memoryIds)\n ) {\n return null;\n }\n if (value.goal !== undefined && typeof value.goal !== \"string\") return null;\n if (value.toolsUsed !== undefined && !isStringArray(value.toolsUsed)) return null;\n return {\n id: value.id,\n createdAt: value.createdAt,\n lastActivityAt: value.lastActivityAt,\n topics: value.topics,\n memoryIds: value.memoryIds,\n goal: value.goal,\n toolsUsed: value.toolsUsed,\n };\n}\n\nfunction parseTraceIndex(value: unknown): TraceIndex | null {\n if (!isRecord(value)) return null;\n if (\n !isStringArrayRecord(value.traces) ||\n !isStringRecord(value.boxToTrace) ||\n !isStringArrayRecord(value.traceTopics)\n ) {\n return null;\n }\n const traceLastSeen = value.traceLastSeen ?? {};\n if (!isStringRecord(traceLastSeen)) return null;\n return {\n traces: value.traces,\n boxToTrace: value.boxToTrace,\n traceTopics: value.traceTopics,\n traceLastSeen,\n };\n}\n\n// ── Frontmatter serialization ──────────────────────────────────────────────\n\nfunction serializeStringArray(values: string[]): string {\n return JSON.stringify(values);\n}\n\nfunction parseStringArray(val: string | undefined): string[] {\n if (!val) return [];\n try {\n const parsed = JSON.parse(val);\n if (Array.isArray(parsed)) {\n return parsed.filter((entry): entry is string => typeof entry === \"string\");\n }\n } catch {\n // Fall back to the legacy comma-split parser below.\n }\n const start = val.indexOf(\"[\");\n const end = val.lastIndexOf(\"]\");\n if (start === -1 || end <= start) return [];\n return val\n .slice(start + 1, end)\n .split(\",\")\n .map((s) => stripLegacyQuotes(s.trim()))\n .filter(Boolean);\n}\n\nfunction stripLegacyQuotes(value: string): string {\n if (value.length >= 2 && value.startsWith(\"\\\"\") && value.endsWith(\"\\\"\")) {\n return value.slice(1, -1);\n }\n return value;\n}\n\nfunction serializeBoxFrontmatter(fm: BoxFrontmatter): string {\n const lines = [\n \"---\",\n `id: ${fm.id}`,\n `memoryKind: ${fm.memoryKind}`,\n `createdAt: ${fm.createdAt}`,\n `sealedAt: ${fm.sealedAt}`,\n `sealReason: ${fm.sealReason}`,\n `topics: ${serializeStringArray(fm.topics)}`,\n `memoryIds: ${serializeStringArray(fm.memoryIds)}`,\n ];\n if (fm.sessionKey) lines.push(`sessionKey: ${fm.sessionKey}`);\n if (fm.traceId) lines.push(`traceId: ${fm.traceId}`);\n if (fm.goal) lines.push(`goal: ${fm.goal.replace(/[\\r\\n]+/g, \" \")}`);\n if (fm.toolsUsed?.length) lines.push(`toolsUsed: ${serializeStringArray(fm.toolsUsed)}`);\n if (fm.outcome) lines.push(`outcome: ${fm.outcome}`);\n lines.push(\"---\");\n return lines.join(\"\\n\");\n}\n\nexport function parseBoxFrontmatter(raw: string): BoxFrontmatter | null {\n const match = raw.match(/^---\\n([\\s\\S]*?)\\n---/);\n if (!match) return null;\n\n const fmBlock = match[1];\n const fm: Record<string, string> = {};\n for (const line of fmBlock.split(\"\\n\")) {\n const colonIdx = line.indexOf(\":\");\n if (colonIdx === -1) continue;\n fm[line.slice(0, colonIdx).trim()] = line.slice(colonIdx + 1).trim();\n }\n\n const outcome = fm.outcome as BoxFrontmatter[\"outcome\"];\n return {\n id: fm.id ?? \"\",\n memoryKind: \"box\",\n createdAt: fm.createdAt ?? \"\",\n sealedAt: fm.sealedAt ?? \"\",\n sealReason: (fm.sealReason ?? \"forced\") as SealReason,\n sessionKey: fm.sessionKey,\n topics: parseStringArray(fm.topics),\n memoryIds: parseStringArray(fm.memoryIds),\n traceId: fm.traceId,\n goal: fm.goal || undefined,\n toolsUsed: fm.toolsUsed ? parseStringArray(fm.toolsUsed) : undefined,\n outcome: outcome && [\"success\", \"failure\", \"partial\", \"unknown\"].includes(outcome) ? outcome : undefined,\n };\n}\n\n// ── BoxBuilder ────────────────────────────────────────────────────────────\n\nexport class BoxBuilder {\n private baseDir: string;\n private cfg: BoxBuilderConfig;\n private openBox: OpenBoxState | null = null;\n private stateLoaded = false;\n private openBoxMutationChain: Promise<unknown> = Promise.resolve();\n private traceMutationChain: Promise<unknown> = Promise.resolve();\n\n constructor(baseDir: string, cfg: BoxBuilderConfig) {\n this.baseDir = baseDir;\n this.cfg = cfg;\n }\n\n private enqueueOpenBoxMutation<T>(op: () => Promise<T>): Promise<T> {\n const run = this.openBoxMutationChain.catch(() => {}).then(op);\n this.openBoxMutationChain = run.catch(() => {});\n return run;\n }\n\n private enqueueTraceMutation<T>(op: () => Promise<T>): Promise<T> {\n const run = this.traceMutationChain.catch(() => {}).then(op);\n this.traceMutationChain = run.catch(() => {});\n return run;\n }\n\n private get boxBaseDir(): string {\n return path.join(this.baseDir, BOX_DIR);\n }\n\n private get stateDir(): string {\n return path.join(this.baseDir, STATE_DIR);\n }\n\n private get openBoxStatePath(): string {\n return path.join(this.stateDir, OPEN_BOX_STATE_FILE);\n }\n\n private get tracesPath(): string {\n return path.join(this.stateDir, TRACES_FILE);\n }\n\n // ── State persistence ────────────────────────────────────────────────────\n\n private async loadOpenBox(): Promise<void> {\n if (this.stateLoaded) return;\n this.stateLoaded = true;\n try {\n const raw = await readFile(this.openBoxStatePath, \"utf-8\");\n this.openBox = parseOpenBoxState(JSON.parse(raw));\n } catch {\n this.openBox = null;\n }\n }\n\n private async writeOpenBoxState(state: OpenBoxState | null): Promise<void> {\n await mkdir(this.stateDir, { recursive: true });\n await writeFile(this.openBoxStatePath, JSON.stringify(state, null, 2), \"utf-8\");\n }\n\n private async saveOpenBox(): Promise<void> {\n await this.writeOpenBoxState(this.openBox);\n }\n\n private async loadTraceIndex(): Promise<TraceIndex> {\n try {\n const raw = await readFile(this.tracesPath, \"utf-8\");\n const parsed = parseTraceIndex(JSON.parse(raw));\n if (!parsed) {\n log.warn(\"[engram/boxes] Ignoring invalid trace index state\");\n return { traces: {}, boxToTrace: {}, traceTopics: {}, traceLastSeen: {} };\n }\n return parsed;\n } catch {\n return { traces: {}, boxToTrace: {}, traceTopics: {}, traceLastSeen: {} };\n }\n }\n\n private async saveTraceIndex(idx: TraceIndex): Promise<boolean> {\n try {\n await mkdir(this.stateDir, { recursive: true });\n await writeFile(this.tracesPath, JSON.stringify(idx, null, 2), \"utf-8\");\n return true;\n } catch (err) {\n log.warn(`[engram/boxes] Failed to save trace index: ${(err as Error).message}`);\n return false;\n }\n }\n\n // ── Core logic ────────────────────────────────────────────────────────────\n\n /**\n * Called after each extraction run.\n * Decides whether to seal the current open box and/or start a new one.\n */\n async onExtraction(event: ExtractionEvent): Promise<void> {\n await this.enqueueOpenBoxMutation(async () => this.onExtractionUnlocked(event));\n }\n\n private async onExtractionUnlocked(event: ExtractionEvent): Promise<void> {\n if (!this.cfg.memoryBoxesEnabled) return;\n\n await this.loadOpenBox();\n\n const newTopics = event.topics.filter(Boolean);\n const now = new Date(event.timestamp);\n const nowMs = now.getTime();\n\n if (this.openBox) {\n // Check seal conditions\n const lastActivity = new Date(this.openBox.lastActivityAt).getTime();\n const timeGapMs = nowMs - lastActivity;\n const overlap = topicOverlapScore(this.openBox.topics, newTopics);\n const topicShifted = newTopics.length > 0 && overlap < this.cfg.boxTopicShiftThreshold;\n const timeExpired = timeGapMs >= this.cfg.boxTimeGapMs;\n const tooManyMemories =\n this.openBox.memoryIds.length + event.memoryIds.length > this.cfg.boxMaxMemories;\n\n if (tooManyMemories) {\n // Merge topics and add current batch then seal\n const topicSet = new Set([...this.openBox.topics, ...newTopics]);\n this.openBox.topics = [...topicSet];\n this.openBox.memoryIds.push(...event.memoryIds);\n if (event.toolsUsed?.length) {\n const toolSet = new Set([...(this.openBox.toolsUsed ?? []), ...event.toolsUsed]);\n this.openBox.toolsUsed = [...toolSet];\n }\n await this.sealCurrentUnlocked(\"max_memories\");\n } else if (topicShifted) {\n await this.sealCurrentUnlocked(\"topic_shift\");\n this.openBox = this.newBox(event, now.toISOString());\n await this.saveOpenBox();\n } else if (timeExpired) {\n await this.sealCurrentUnlocked(\"time_gap\");\n this.openBox = this.newBox(event, now.toISOString());\n await this.saveOpenBox();\n } else {\n // Accumulate\n this.openBox.memoryIds.push(...event.memoryIds);\n // Merge new topics (union)\n const topicSet = new Set([...this.openBox.topics, ...newTopics]);\n this.openBox.topics = [...topicSet];\n this.openBox.lastActivityAt = now.toISOString();\n // Merge toolsUsed (union)\n if (event.toolsUsed?.length) {\n const toolSet = new Set([...(this.openBox.toolsUsed ?? []), ...event.toolsUsed]);\n this.openBox.toolsUsed = [...toolSet];\n }\n await this.saveOpenBox();\n }\n } else {\n // No open box — start one\n this.openBox = this.newBox(event, now.toISOString());\n // If this initial batch already exceeds max, seal immediately\n if (this.openBox.memoryIds.length > this.cfg.boxMaxMemories) {\n await this.sealCurrentUnlocked(\"max_memories\");\n } else {\n await this.saveOpenBox();\n }\n }\n }\n\n private newBox(event: ExtractionEvent, ts: string): OpenBoxState {\n return {\n id: makeBoxId(),\n createdAt: ts,\n lastActivityAt: ts,\n topics: event.topics.filter(Boolean),\n memoryIds: [...event.memoryIds],\n goal: event.goal,\n toolsUsed: event.toolsUsed?.length ? [...event.toolsUsed] : undefined,\n };\n }\n\n /**\n * Seal the current open box and write it to disk.\n * Also runs trace weaving if enabled.\n */\n async sealCurrent(reason: SealReason): Promise<string | null> {\n return this.enqueueOpenBoxMutation(async () => this.sealCurrentUnlocked(reason));\n }\n\n private async sealCurrentUnlocked(reason: SealReason): Promise<string | null> {\n await this.loadOpenBox();\n if (!this.openBox) return null;\n\n const box = this.openBox;\n\n if (box.memoryIds.length === 0 && box.topics.length === 0) {\n await this.writeOpenBoxState(null);\n this.openBox = null;\n return null;\n }\n\n const sealedAt = new Date().toISOString();\n const day = sealedAt.slice(0, 10);\n const dir = path.join(this.boxBaseDir, day);\n await mkdir(dir, { recursive: true });\n\n let traceId: string | undefined;\n if (this.cfg.traceWeaverEnabled && box.topics.length > 0) {\n traceId = await this.resolveTrace(box.id, box.topics);\n }\n\n const fm: BoxFrontmatter = {\n id: box.id,\n memoryKind: \"box\",\n createdAt: box.createdAt,\n sealedAt,\n sealReason: reason,\n topics: box.topics,\n memoryIds: box.memoryIds,\n traceId,\n goal: box.goal,\n toolsUsed: box.toolsUsed?.length ? box.toolsUsed : undefined,\n outcome: \"unknown\",\n };\n\n const content = `${serializeBoxFrontmatter(fm)}\\n\\n<!-- Topics: ${box.topics.join(\", \")} | Memories: ${box.memoryIds.length} -->\\n`;\n const filePath = path.join(dir, `${box.id}.md`);\n await writeFile(filePath, content, \"utf-8\");\n log.debug(`[boxes] sealed box ${box.id} (${reason}): ${box.memoryIds.length} memories, topics=[${box.topics.join(\",\")}]`);\n\n await this.writeOpenBoxState(null);\n this.openBox = null;\n return box.id;\n }\n\n // ── Trace Weaving ─────────────────────────────────────────────────────────\n\n /**\n * Find an existing trace that matches box topics, or create a new trace.\n * Returns the traceId to assign to this box.\n */\n private async resolveTrace(boxId: string, topics: string[]): Promise<string | undefined> {\n return this.enqueueTraceMutation(async () => this.resolveTraceUnlocked(boxId, topics));\n }\n\n private async resolveTraceUnlocked(boxId: string, topics: string[]): Promise<string | undefined> {\n const idx = await this.loadTraceIndex();\n\n // Filter to traces active within the lookback window\n const lookbackMs = this.cfg.traceWeaverLookbackDays * 24 * 60 * 60 * 1000;\n const cutoff = new Date(Date.now() - lookbackMs);\n\n let bestTraceId: string | undefined;\n let bestScore = 0;\n\n for (const [tid, traceTopics] of Object.entries(idx.traceTopics)) {\n const lastSeen = idx.traceLastSeen[tid];\n if (lastSeen && new Date(lastSeen) < cutoff) continue; // outside lookback window\n const score = topicOverlapScore(topics, traceTopics);\n if (score >= this.cfg.traceWeaverOverlapThreshold && score > bestScore) {\n bestScore = score;\n bestTraceId = tid;\n }\n }\n\n const traceId = bestTraceId ?? makeTraceId(topics);\n const now = new Date().toISOString();\n\n // Update trace index\n if (!idx.traces[traceId]) idx.traces[traceId] = [];\n idx.traces[traceId].push(boxId);\n idx.boxToTrace[boxId] = traceId;\n idx.traceLastSeen[traceId] = now;\n\n // Update canonical topics for this trace (merge)\n if (idx.traceTopics[traceId]) {\n const merged = new Set([...idx.traceTopics[traceId], ...topics]);\n idx.traceTopics[traceId] = [...merged];\n } else {\n idx.traceTopics[traceId] = [...topics];\n }\n\n return (await this.saveTraceIndex(idx)) ? traceId : undefined;\n }\n\n // ── Recall ────────────────────────────────────────────────────────────────\n\n /**\n * Read all sealed boxes from the last N days for recall injection.\n */\n async readRecentBoxes(days: number): Promise<BoxFrontmatter[]> {\n const cutoff = new Date(Date.now() - days * 24 * 60 * 60 * 1000);\n const cutoffDateStr = cutoff.toISOString().slice(0, 10); // \"YYYY-MM-DD\"\n\n let topEntries: Dirent<string>[];\n try {\n topEntries = await readdir(this.boxBaseDir, { withFileTypes: true, encoding: \"utf-8\" });\n } catch {\n return [];\n }\n\n // Filter day directories by name (YYYY-MM-DD) — skip dirs older than cutoff\n // without reading a single file from them.\n const recentDirs = topEntries\n .filter((e) => e.isDirectory() && /^\\d{4}-\\d{2}-\\d{2}$/.test(e.name) && e.name >= cutoffDateStr)\n .map((e) => path.join(this.boxBaseDir, e.name));\n\n // Also include legacy flat entries at the root level (non-date dirs and .md files)\n const legacyEntries = topEntries.filter(\n (e) => !e.isDirectory() || !/^\\d{4}-\\d{2}-\\d{2}$/.test(e.name),\n );\n\n // Read all files in each recent day directory in parallel (per dir)\n const boxes: BoxFrontmatter[] = [];\n\n const readDir = async (dir: string) => {\n let files: string[];\n try {\n files = (await readdir(dir)).filter((f) => f.endsWith(\".md\"));\n } catch {\n return;\n }\n const results = await Promise.all(\n files.map(async (f) => {\n try {\n const raw = await readFile(path.join(dir, f), \"utf-8\");\n const parsed = parseBoxFrontmatter(raw);\n return parsed && new Date(parsed.sealedAt) >= cutoff ? parsed : null;\n } catch {\n return null;\n }\n }),\n );\n for (const r of results) {\n if (r !== null) boxes.push(r);\n }\n };\n\n // Day dirs in parallel\n await Promise.all(recentDirs.map(readDir));\n\n // Legacy non-date entries (walk sub-dirs sequentially but read files in parallel)\n for (const e of legacyEntries) {\n const full = path.join(this.boxBaseDir, e.name);\n if (e.isDirectory()) {\n await readDir(full);\n } else if (e.name.endsWith(\".md\")) {\n try {\n const raw = await readFile(full, \"utf-8\");\n const parsed = parseBoxFrontmatter(raw);\n if (parsed && new Date(parsed.sealedAt) >= cutoff) boxes.push(parsed);\n } catch { /* corrupt file — skip */ }\n }\n }\n\n // Sort newest-first so slice(0, N) gives the most recent boxes\n boxes.sort((a, b) => new Date(b.sealedAt).getTime() - new Date(a.sealedAt).getTime());\n return boxes;\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,4 +1,17 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isLikelyUnsafeRegex
|
|
3
|
+
} from "./chunk-U3PN77QT.js";
|
|
4
|
+
|
|
1
5
|
// src/namespaces/principal.ts
|
|
6
|
+
var MAX_REGEX_SESSION_KEY_LENGTH = 512;
|
|
7
|
+
function compileSafePrincipalRegex(pattern) {
|
|
8
|
+
if (isLikelyUnsafeRegex(pattern)) return null;
|
|
9
|
+
try {
|
|
10
|
+
return new RegExp(pattern);
|
|
11
|
+
} catch {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
2
15
|
function resolvePrincipal(sessionKey, config) {
|
|
3
16
|
if (!config.namespacesEnabled) return "default";
|
|
4
17
|
const sk = sessionKey ?? "";
|
|
@@ -14,11 +27,12 @@ function resolvePrincipal(sessionKey, config) {
|
|
|
14
27
|
if (sk === r.match) return r.principal;
|
|
15
28
|
}
|
|
16
29
|
} else if (mode === "regex") {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const re =
|
|
20
|
-
if (re
|
|
21
|
-
|
|
30
|
+
if (sk.length <= MAX_REGEX_SESSION_KEY_LENGTH) {
|
|
31
|
+
for (const r of rules) {
|
|
32
|
+
const re = compileSafePrincipalRegex(r.match);
|
|
33
|
+
if (re?.test(sk)) {
|
|
34
|
+
return r.principal;
|
|
35
|
+
}
|
|
22
36
|
}
|
|
23
37
|
}
|
|
24
38
|
}
|
|
@@ -71,4 +85,4 @@ export {
|
|
|
71
85
|
defaultNamespaceForPrincipal,
|
|
72
86
|
recallNamespacesForPrincipal
|
|
73
87
|
};
|
|
74
|
-
//# sourceMappingURL=chunk-
|
|
88
|
+
//# sourceMappingURL=chunk-HWVTS5NO.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/namespaces/principal.ts"],"sourcesContent":["import type { PluginConfig } from \"../types.js\";\nimport { isLikelyUnsafeRegex } from \"../routing/engine.js\";\n\nconst MAX_REGEX_SESSION_KEY_LENGTH = 512;\n\nfunction compileSafePrincipalRegex(pattern: string): RegExp | null {\n if (isLikelyUnsafeRegex(pattern)) return null;\n try {\n return new RegExp(pattern);\n } catch {\n return null;\n }\n}\n\nexport function resolvePrincipal(sessionKey: string | undefined, config: PluginConfig): string {\n if (!config.namespacesEnabled) return \"default\";\n const sk = sessionKey ?? \"\";\n const mode = config.principalFromSessionKeyMode;\n const rules = config.principalFromSessionKeyRules ?? [];\n\n if (!sk) return \"default\";\n\n if (mode === \"prefix\") {\n for (const r of rules) {\n if (sk.startsWith(r.match)) return r.principal;\n }\n } else if (mode === \"map\") {\n for (const r of rules) {\n if (sk === r.match) return r.principal;\n }\n } else if (mode === \"regex\") {\n if (sk.length <= MAX_REGEX_SESSION_KEY_LENGTH) {\n for (const r of rules) {\n const re = compileSafePrincipalRegex(r.match);\n if (re?.test(sk)) {\n return r.principal;\n }\n }\n }\n }\n\n // Fallback heuristic: \"agent:<agentId>:<channelType>:...\"\n const parts = sk.split(\":\");\n if (parts.length >= 2 && parts[0] === \"agent\") {\n const agentId = parts[1];\n if (agentId && agentId.length > 0) return agentId;\n }\n return \"default\";\n}\n\nexport function canReadNamespace(principal: string, namespace: string, config: PluginConfig): boolean {\n if (!config.namespacesEnabled) return true;\n const policy = config.namespacePolicies.find((p) => p.name === namespace);\n if (!policy) return namespace === config.defaultNamespace || namespace === config.sharedNamespace;\n return policy.readPrincipals.includes(principal) || policy.readPrincipals.includes(\"*\");\n}\n\nexport function canWriteNamespace(principal: string, namespace: string, config: PluginConfig): boolean {\n if (!config.namespacesEnabled) return true;\n const policy = config.namespacePolicies.find((p) => p.name === namespace);\n if (!policy) return namespace === config.defaultNamespace;\n return policy.writePrincipals.includes(principal) || policy.writePrincipals.includes(\"*\");\n}\n\n/**\n * Default \"self\" namespace for a principal.\n *\n * Heuristic:\n * - If there's a namespace policy with the same name as the principal, use it.\n * - Otherwise use config.defaultNamespace.\n */\nexport function defaultNamespaceForPrincipal(principal: string, config: PluginConfig): string {\n if (!config.namespacesEnabled) return config.defaultNamespace;\n const exists = config.namespacePolicies.some((p) => p.name === principal);\n return exists ? principal : config.defaultNamespace;\n}\n\nexport function recallNamespacesForPrincipal(principal: string, config: PluginConfig): string[] {\n const out: string[] = [];\n if (!config.namespacesEnabled) return [config.defaultNamespace];\n\n const selfNs = defaultNamespaceForPrincipal(principal, config);\n if (config.defaultRecallNamespaces.includes(\"self\") && canReadNamespace(principal, selfNs, config)) {\n out.push(selfNs);\n }\n if (config.defaultRecallNamespaces.includes(\"shared\") && canReadNamespace(principal, config.sharedNamespace, config)) {\n out.push(config.sharedNamespace);\n }\n\n for (const p of config.namespacePolicies) {\n if (p.includeInRecallByDefault && canReadNamespace(principal, p.name, config)) {\n if (!out.includes(p.name)) out.push(p.name);\n }\n }\n\n return out;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
canReadNamespace,
|
|
7
7
|
defaultNamespaceForPrincipal,
|
|
8
8
|
resolvePrincipal
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-HWVTS5NO.js";
|
|
10
10
|
|
|
11
11
|
// src/active-memory-bridge.ts
|
|
12
12
|
function isArtifactPath(value) {
|
|
@@ -118,4 +118,4 @@ export {
|
|
|
118
118
|
recallForActiveMemory,
|
|
119
119
|
getMemoryForActiveMemory
|
|
120
120
|
};
|
|
121
|
-
//# sourceMappingURL=chunk-
|
|
121
|
+
//# sourceMappingURL=chunk-IC4GELZE.js.map
|