@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.
Files changed (1091) hide show
  1. package/dist/abstraction-nodes.js +2 -2
  2. package/dist/access-cli.d.ts +1 -1
  3. package/dist/access-cli.js +156 -119
  4. package/dist/access-cli.js.map +1 -1
  5. package/dist/access-http.d.ts +9 -5
  6. package/dist/access-http.js +51 -51
  7. package/dist/access-idempotency.d.ts +2 -0
  8. package/dist/access-idempotency.js +1 -1
  9. package/dist/access-mcp.d.ts +16 -9
  10. package/dist/access-mcp.js +44 -44
  11. package/dist/access-schema.d.ts +47 -15
  12. package/dist/access-schema.js +8 -8
  13. package/dist/{access-service-B5hgZPCN.d.ts → access-service-qrrIrC-0.d.ts} +11 -129
  14. package/dist/access-service.d.ts +7 -4
  15. package/dist/access-service.js +40 -40
  16. package/dist/action-confidence.d.ts +1 -0
  17. package/dist/active-memory-bridge.d.ts +1 -0
  18. package/dist/active-memory-bridge.js +3 -2
  19. package/dist/active-recall.d.ts +1 -0
  20. package/dist/active-recall.js +14 -9
  21. package/dist/active-recall.js.map +1 -1
  22. package/dist/adapters/claude-code.d.ts +6 -2
  23. package/dist/adapters/claude-code.js +2 -2
  24. package/dist/adapters/codex.d.ts +5 -1
  25. package/dist/adapters/codex.js +2 -2
  26. package/dist/adapters/hermes.js +2 -2
  27. package/dist/adapters/index.js +6 -6
  28. package/dist/adapters/registry.js +6 -6
  29. package/dist/adapters/replit.d.ts +4 -2
  30. package/dist/adapters/replit.js +2 -2
  31. package/dist/adapters/types.d.ts +4 -0
  32. package/dist/adapters/types.js +1 -1
  33. package/dist/behavior-learner.d.ts +1 -0
  34. package/dist/behavior-signals.d.ts +1 -0
  35. package/dist/behavior-signals.js +1 -1
  36. package/dist/bootstrap.d.ts +5 -3
  37. package/dist/bootstrap.js +2 -2
  38. package/dist/boxes.d.ts +1 -0
  39. package/dist/boxes.js +1 -1
  40. package/dist/briefing.d.ts +1 -0
  41. package/dist/briefing.js +9 -9
  42. package/dist/buffer-surprise-report.d.ts +1 -0
  43. package/dist/buffer.d.ts +1 -0
  44. package/dist/buffer.js +2 -2
  45. package/dist/bulk-import/index.d.ts +28 -0
  46. package/dist/bulk-import/index.js +31 -0
  47. package/dist/calibration.d.ts +2 -0
  48. package/dist/calibration.js +50 -17
  49. package/dist/calibration.js.map +1 -1
  50. package/dist/{capsule-crypto-5CYAGVC5.js → capsule-crypto-7FJQINUR.js} +2 -2
  51. package/dist/{capsule-merge-4MGKE7C5.js → capsule-merge-T2JRE46P.js} +3 -3
  52. package/dist/causal-behavior.d.ts +1 -0
  53. package/dist/causal-behavior.js +4 -4
  54. package/dist/causal-chain.js +4 -4
  55. package/dist/causal-consolidation.d.ts +16 -1
  56. package/dist/causal-consolidation.js +115 -32
  57. package/dist/causal-consolidation.js.map +1 -1
  58. package/dist/causal-retrieval.js +14 -6
  59. package/dist/causal-retrieval.js.map +1 -1
  60. package/dist/causal-trajectory-graph.js +2 -2
  61. package/dist/causal-trajectory.js +2 -2
  62. package/dist/{chunk-SAZS2QZB.js → chunk-23UORJ4S.js} +3 -3
  63. package/dist/{chunk-76FLAAUC.js → chunk-2AN2L4NL.js} +17 -6
  64. package/dist/chunk-2AN2L4NL.js.map +1 -0
  65. package/dist/{chunk-W4L6CZKA.js → chunk-2DL3OFLD.js} +15 -10
  66. package/dist/chunk-2DL3OFLD.js.map +1 -0
  67. package/dist/{chunk-7OZ53EXP.js → chunk-2NLLXCJG.js} +21 -10
  68. package/dist/chunk-2NLLXCJG.js.map +1 -0
  69. package/dist/{chunk-PK7H5L6Y.js → chunk-2NM43EWN.js} +2 -2
  70. package/dist/{chunk-PYXS46O7.js → chunk-3BP57I6J.js} +2 -2
  71. package/dist/{chunk-FBYESMQ2.js → chunk-3C5RPJAX.js} +2 -2
  72. package/dist/{chunk-QKZGQIPJ.js → chunk-3Q4H3OBR.js} +171 -64
  73. package/dist/chunk-3Q4H3OBR.js.map +1 -0
  74. package/dist/{chunk-FKFMOY3N.js → chunk-42NQ7AVG.js} +3 -4
  75. package/dist/{chunk-FKFMOY3N.js.map → chunk-42NQ7AVG.js.map} +1 -1
  76. package/dist/chunk-4426WSWL.js +73 -0
  77. package/dist/chunk-4426WSWL.js.map +1 -0
  78. package/dist/{chunk-LIRZNNUP.js → chunk-44442YCH.js} +5 -2
  79. package/dist/chunk-44442YCH.js.map +1 -0
  80. package/dist/{chunk-H3ME6L6D.js → chunk-46GJIW5M.js} +23 -20
  81. package/dist/chunk-46GJIW5M.js.map +1 -0
  82. package/dist/{chunk-QDZ2RLEC.js → chunk-472U7RDF.js} +3 -3
  83. package/dist/chunk-472U7RDF.js.map +1 -0
  84. package/dist/{chunk-NN2DKE4T.js → chunk-4H5ZJHEN.js} +16 -3
  85. package/dist/{chunk-NN2DKE4T.js.map → chunk-4H5ZJHEN.js.map} +1 -1
  86. package/dist/{chunk-56K5QLHX.js → chunk-4HP7HIE3.js} +56 -13
  87. package/dist/chunk-4HP7HIE3.js.map +1 -0
  88. package/dist/{chunk-RK2Y4XOM.js → chunk-4JRRISLU.js} +9 -6
  89. package/dist/chunk-4JRRISLU.js.map +1 -0
  90. package/dist/{chunk-MG7NA5H3.js → chunk-4Q73JBSM.js} +17 -12
  91. package/dist/chunk-4Q73JBSM.js.map +1 -0
  92. package/dist/{chunk-XKLD5OK4.js → chunk-4RR6ROTB.js} +10 -11
  93. package/dist/chunk-4RR6ROTB.js.map +1 -0
  94. package/dist/{chunk-4KGVTPGD.js → chunk-6F6BXB7A.js} +9 -8
  95. package/dist/chunk-6F6BXB7A.js.map +1 -0
  96. package/dist/{chunk-NMZY542O.js → chunk-6URPAY2D.js} +41 -17
  97. package/dist/chunk-6URPAY2D.js.map +1 -0
  98. package/dist/{chunk-N53K2EXC.js → chunk-6VF75M3X.js} +2 -2
  99. package/dist/{chunk-XSZEP4SF.js → chunk-6XSPNR6L.js} +6 -5
  100. package/dist/chunk-6XSPNR6L.js.map +1 -0
  101. package/dist/{chunk-6H2TESSP.js → chunk-765K3SAT.js} +3 -3
  102. package/dist/{chunk-EDTHC6UD.js → chunk-77NAFXUD.js} +2 -2
  103. package/dist/{chunk-S7KDBTWT.js → chunk-7F7Z6MOS.js} +29 -14
  104. package/dist/chunk-7F7Z6MOS.js.map +1 -0
  105. package/dist/{chunk-MZH6EHNR.js → chunk-7H6CFEBJ.js} +41 -14
  106. package/dist/chunk-7H6CFEBJ.js.map +1 -0
  107. package/dist/{chunk-575RMLWN.js → chunk-7MV5CWTE.js} +26 -20
  108. package/dist/chunk-7MV5CWTE.js.map +1 -0
  109. package/dist/{chunk-MGKYQQYF.js → chunk-7Q3RCKAQ.js} +2 -2
  110. package/dist/chunk-7RXCMVFQ.js +27 -0
  111. package/dist/chunk-7RXCMVFQ.js.map +1 -0
  112. package/dist/{chunk-DGXUHMOV.js → chunk-A2IYSXDQ.js} +25 -6
  113. package/dist/chunk-A2IYSXDQ.js.map +1 -0
  114. package/dist/{chunk-EABGC2TL.js → chunk-A2Z6UCWT.js} +26 -4
  115. package/dist/chunk-A2Z6UCWT.js.map +1 -0
  116. package/dist/{chunk-3VAL7ZL2.js → chunk-A52AKD7C.js} +59 -24
  117. package/dist/chunk-A52AKD7C.js.map +1 -0
  118. package/dist/{chunk-5375UYTQ.js → chunk-A6D7A2FW.js} +4 -4
  119. package/dist/chunk-A6D7A2FW.js.map +1 -0
  120. package/dist/{chunk-FAAFWE4G.js → chunk-ALEPI75L.js} +24 -6
  121. package/dist/chunk-ALEPI75L.js.map +1 -0
  122. package/dist/{chunk-3SLRNYNG.js → chunk-AUDJPF4N.js} +15 -4
  123. package/dist/chunk-AUDJPF4N.js.map +1 -0
  124. package/dist/chunk-B5XMS73R.js +145 -0
  125. package/dist/chunk-B5XMS73R.js.map +1 -0
  126. package/dist/{chunk-HXXBL2KD.js → chunk-BECQDWBA.js} +44 -4
  127. package/dist/chunk-BECQDWBA.js.map +1 -0
  128. package/dist/{chunk-7SEAZFFB.js → chunk-BEUDU7Y4.js} +24 -4
  129. package/dist/chunk-BEUDU7Y4.js.map +1 -0
  130. package/dist/{chunk-XVVIG67A.js → chunk-BLZAVUD2.js} +61 -17
  131. package/dist/chunk-BLZAVUD2.js.map +1 -0
  132. package/dist/chunk-CHBI22MI.js +159 -0
  133. package/dist/chunk-CHBI22MI.js.map +1 -0
  134. package/dist/{chunk-GDFS42HT.js → chunk-CHCA44C3.js} +15 -8
  135. package/dist/chunk-CHCA44C3.js.map +1 -0
  136. package/dist/chunk-CINZGPSJ.js +22 -0
  137. package/dist/chunk-CINZGPSJ.js.map +1 -0
  138. package/dist/chunk-CMTINOFS.js +36 -0
  139. package/dist/chunk-CMTINOFS.js.map +1 -0
  140. package/dist/{chunk-34DQE4KF.js → chunk-CO7ZO4TU.js} +2 -2
  141. package/dist/{chunk-PFV5C235.js → chunk-CPPS65WS.js} +2 -1
  142. package/dist/{chunk-PFV5C235.js.map → chunk-CPPS65WS.js.map} +1 -1
  143. package/dist/{chunk-DINWEURR.js → chunk-CSKLPDN6.js} +20 -6
  144. package/dist/chunk-CSKLPDN6.js.map +1 -0
  145. package/dist/chunk-CWWMTTQE.js +566 -0
  146. package/dist/chunk-CWWMTTQE.js.map +1 -0
  147. package/dist/{chunk-IQT3XTKW.js → chunk-D24OXEPB.js} +13 -7
  148. package/dist/chunk-D24OXEPB.js.map +1 -0
  149. package/dist/{chunk-KRBK4BQH.js → chunk-D6WE5MTW.js} +272 -411
  150. package/dist/chunk-D6WE5MTW.js.map +1 -0
  151. package/dist/{chunk-WIICJPET.js → chunk-DEUNUKTD.js} +6 -4
  152. package/dist/{chunk-WIICJPET.js.map → chunk-DEUNUKTD.js.map} +1 -1
  153. package/dist/{chunk-ZYVPLJ4T.js → chunk-DHGSZ3UD.js} +9 -7
  154. package/dist/chunk-DHGSZ3UD.js.map +1 -0
  155. package/dist/{chunk-JR4ZC3G4.js → chunk-DLJ4IR6M.js} +91 -41
  156. package/dist/chunk-DLJ4IR6M.js.map +1 -0
  157. package/dist/{chunk-U4SCL7B7.js → chunk-DRD2Q7HQ.js} +82 -18
  158. package/dist/chunk-DRD2Q7HQ.js.map +1 -0
  159. package/dist/{chunk-2IWUMAES.js → chunk-E62SBGQ3.js} +28 -13
  160. package/dist/chunk-E62SBGQ3.js.map +1 -0
  161. package/dist/{chunk-C5BCH4ZS.js → chunk-EAZGEEG2.js} +21 -3
  162. package/dist/chunk-EAZGEEG2.js.map +1 -0
  163. package/dist/{chunk-TPB3I2AC.js → chunk-ECZU5BJH.js} +31 -10
  164. package/dist/chunk-ECZU5BJH.js.map +1 -0
  165. package/dist/{chunk-77H5NU3M.js → chunk-EDBEWFJO.js} +82 -18
  166. package/dist/chunk-EDBEWFJO.js.map +1 -0
  167. package/dist/chunk-EDQVAMQI.js +308 -0
  168. package/dist/chunk-EDQVAMQI.js.map +1 -0
  169. package/dist/{chunk-RRF5UOBJ.js → chunk-EI6V5UXY.js} +22 -15
  170. package/dist/chunk-EI6V5UXY.js.map +1 -0
  171. package/dist/{chunk-I5GLV3VE.js → chunk-EIPUHVKE.js} +31 -24
  172. package/dist/{chunk-I5GLV3VE.js.map → chunk-EIPUHVKE.js.map} +1 -1
  173. package/dist/{chunk-ZKSK55RC.js → chunk-ETUPBUHB.js} +2 -2
  174. package/dist/{chunk-25MQ7IHJ.js → chunk-EUML3N6B.js} +17 -6
  175. package/dist/chunk-EUML3N6B.js.map +1 -0
  176. package/dist/{chunk-5RGLBDQF.js → chunk-EVZFIAPG.js} +12 -12
  177. package/dist/chunk-EVZFIAPG.js.map +1 -0
  178. package/dist/{chunk-QRNI5JBH.js → chunk-EYIEWJNI.js} +2 -2
  179. package/dist/{chunk-3OWUCDKH.js → chunk-FER4WARO.js} +176 -42
  180. package/dist/chunk-FER4WARO.js.map +1 -0
  181. package/dist/{chunk-43PJZYGL.js → chunk-FPGE5NVO.js} +45 -10
  182. package/dist/chunk-FPGE5NVO.js.map +1 -0
  183. package/dist/{chunk-C6QPK5GG.js → chunk-FZZ2QTJI.js} +2 -2
  184. package/dist/{chunk-D46YSIYX.js → chunk-G3Z3QEF5.js} +19 -11
  185. package/dist/{chunk-D46YSIYX.js.map → chunk-G3Z3QEF5.js.map} +1 -1
  186. package/dist/{chunk-3JXBXXM2.js → chunk-G4IAEX6D.js} +2 -2
  187. package/dist/{chunk-MSWG7JI6.js → chunk-G56P5RLD.js} +8 -2
  188. package/dist/chunk-G56P5RLD.js.map +1 -0
  189. package/dist/{chunk-AGZQD76C.js → chunk-GCGJW34D.js} +48 -2
  190. package/dist/chunk-GCGJW34D.js.map +1 -0
  191. package/dist/chunk-H2NCNXMS.js +159 -0
  192. package/dist/chunk-H2NCNXMS.js.map +1 -0
  193. package/dist/{chunk-XYIK4LF6.js → chunk-H3FZVNRN.js} +8 -2
  194. package/dist/chunk-H3FZVNRN.js.map +1 -0
  195. package/dist/{chunk-TK4UEOSK.js → chunk-HDDRVXX4.js} +8 -8
  196. package/dist/chunk-HDDRVXX4.js.map +1 -0
  197. package/dist/{chunk-LLQ2LLWF.js → chunk-HENLZHIT.js} +15 -5
  198. package/dist/chunk-HENLZHIT.js.map +1 -0
  199. package/dist/{chunk-N2D6GXBM.js → chunk-HINSGUA7.js} +28 -20
  200. package/dist/chunk-HINSGUA7.js.map +1 -0
  201. package/dist/{chunk-APO3DCMU.js → chunk-HLAVGJ62.js} +30 -8
  202. package/dist/chunk-HLAVGJ62.js.map +1 -0
  203. package/dist/{chunk-TPMQ3G6Z.js → chunk-HOJZMQ4J.js} +2 -2
  204. package/dist/chunk-HOJZMQ4J.js.map +1 -0
  205. package/dist/{chunk-LUDTDZLK.js → chunk-HPWVAEET.js} +33 -7
  206. package/dist/chunk-HPWVAEET.js.map +1 -0
  207. package/dist/{chunk-NZL6GGQE.js → chunk-HQ6NIBL6.js} +92 -30
  208. package/dist/chunk-HQ6NIBL6.js.map +1 -0
  209. package/dist/{chunk-UWVJF25J.js → chunk-HWVTS5NO.js} +20 -6
  210. package/dist/chunk-HWVTS5NO.js.map +1 -0
  211. package/dist/{chunk-2WWLHTZY.js → chunk-IC4GELZE.js} +2 -2
  212. package/dist/{chunk-QA2ZAPBU.js → chunk-IPLYGWQF.js} +28 -20
  213. package/dist/chunk-IPLYGWQF.js.map +1 -0
  214. package/dist/{chunk-A6KTB5R6.js → chunk-IQ3OI2RR.js} +3 -3
  215. package/dist/chunk-IQ3OI2RR.js.map +1 -0
  216. package/dist/{chunk-6LVVDPJ4.js → chunk-J64TK33U.js} +3 -4
  217. package/dist/chunk-J64TK33U.js.map +1 -0
  218. package/dist/{chunk-6FC5EGNV.js → chunk-JBPKEARU.js} +15 -5
  219. package/dist/{chunk-6FC5EGNV.js.map → chunk-JBPKEARU.js.map} +1 -1
  220. package/dist/{chunk-RHY3HH7P.js → chunk-JFEKNTX7.js} +125 -33
  221. package/dist/chunk-JFEKNTX7.js.map +1 -0
  222. package/dist/{chunk-TZOLIGIG.js → chunk-JJEJJ7RK.js} +4 -2
  223. package/dist/chunk-JJEJJ7RK.js.map +1 -0
  224. package/dist/{chunk-PCUKNJAZ.js → chunk-JKV57BTN.js} +2 -2
  225. package/dist/{chunk-EJI5XIBB.js → chunk-JLNBQWZ2.js} +55 -7
  226. package/dist/chunk-JLNBQWZ2.js.map +1 -0
  227. package/dist/{chunk-XIG5PDM7.js → chunk-JUC24CTX.js} +8 -12
  228. package/dist/chunk-JUC24CTX.js.map +1 -0
  229. package/dist/{chunk-UL2NNBUL.js → chunk-JYIKKAK3.js} +106 -44
  230. package/dist/chunk-JYIKKAK3.js.map +1 -0
  231. package/dist/{chunk-OIGNEXKZ.js → chunk-K5O2QY6T.js} +5 -1
  232. package/dist/{chunk-OIGNEXKZ.js.map → chunk-K5O2QY6T.js.map} +1 -1
  233. package/dist/{chunk-ZTFCYYEZ.js → chunk-KCYE2MZM.js} +3 -3
  234. package/dist/chunk-KCYE2MZM.js.map +1 -0
  235. package/dist/{chunk-JWPLJLDU.js → chunk-KD3QD3A5.js} +2 -2
  236. package/dist/{chunk-JWPLJLDU.js.map → chunk-KD3QD3A5.js.map} +1 -1
  237. package/dist/{chunk-YRMVARQP.js → chunk-KFY3SGN7.js} +49 -2
  238. package/dist/chunk-KFY3SGN7.js.map +1 -0
  239. package/dist/{chunk-CYFQJMUV.js → chunk-KIB7SDIJ.js} +15 -10
  240. package/dist/chunk-KIB7SDIJ.js.map +1 -0
  241. package/dist/{chunk-3KW65B36.js → chunk-KILOTVIF.js} +95 -48
  242. package/dist/chunk-KILOTVIF.js.map +1 -0
  243. package/dist/{chunk-MXFBBHJU.js → chunk-KJMYHC7K.js} +10 -5
  244. package/dist/chunk-KJMYHC7K.js.map +1 -0
  245. package/dist/{chunk-W3LR522O.js → chunk-KM2A35EO.js} +36 -34
  246. package/dist/chunk-KM2A35EO.js.map +1 -0
  247. package/dist/{chunk-WELDCG6C.js → chunk-L227SKTB.js} +109 -36
  248. package/dist/chunk-L227SKTB.js.map +1 -0
  249. package/dist/{chunk-W6AQJ2PY.js → chunk-L7S47WZT.js} +35 -16
  250. package/dist/chunk-L7S47WZT.js.map +1 -0
  251. package/dist/{chunk-BVF3AGJP.js → chunk-LJBOVCQG.js} +26 -11
  252. package/dist/chunk-LJBOVCQG.js.map +1 -0
  253. package/dist/{chunk-2KI4QFHU.js → chunk-LMDRGRJ2.js} +2 -2
  254. package/dist/{chunk-MY6TPVXW.js → chunk-LMPHTYJC.js} +2 -2
  255. package/dist/{chunk-EHRTFRWW.js → chunk-LQHDIS7L.js} +10 -5
  256. package/dist/chunk-LQHDIS7L.js.map +1 -0
  257. package/dist/chunk-LUDUFZTV.js +170 -0
  258. package/dist/chunk-LUDUFZTV.js.map +1 -0
  259. package/dist/{chunk-5HRY2WRF.js → chunk-LZ3VEOU5.js} +2 -2
  260. package/dist/{chunk-Q7P4WJDP.js → chunk-M5T4Q2ZU.js} +1 -1
  261. package/dist/chunk-M5T4Q2ZU.js.map +1 -0
  262. package/dist/{chunk-ICRIXAP2.js → chunk-MC4FJXPA.js} +16 -6
  263. package/dist/chunk-MC4FJXPA.js.map +1 -0
  264. package/dist/{chunk-WPGJYVUH.js → chunk-MGVIEM2O.js} +23 -6
  265. package/dist/chunk-MGVIEM2O.js.map +1 -0
  266. package/dist/{chunk-OC7KHOOX.js → chunk-O27WNHTT.js} +22 -6
  267. package/dist/chunk-O27WNHTT.js.map +1 -0
  268. package/dist/{chunk-NGAVDO7E.js → chunk-OADWQ5CR.js} +2 -2
  269. package/dist/{chunk-2NMMFZ5T.js → chunk-OD4FM2U7.js} +6 -3
  270. package/dist/chunk-OD4FM2U7.js.map +1 -0
  271. package/dist/{chunk-OZHRDTDX.js → chunk-OKTXM5H4.js} +11 -1
  272. package/dist/chunk-OKTXM5H4.js.map +1 -0
  273. package/dist/{chunk-RXDLTSWT.js → chunk-ONPLNAPX.js} +16 -7
  274. package/dist/chunk-ONPLNAPX.js.map +1 -0
  275. package/dist/{chunk-FJ43PRLT.js → chunk-ORFGK3XI.js} +20 -14
  276. package/dist/chunk-ORFGK3XI.js.map +1 -0
  277. package/dist/{chunk-DOM4GKSW.js → chunk-OZKVVUJB.js} +3 -3
  278. package/dist/{chunk-MT4HVDUZ.js → chunk-PM3QHTFT.js} +3 -3
  279. package/dist/{chunk-4DWOBS2A.js → chunk-PRQJ5ESM.js} +27 -2
  280. package/dist/{chunk-4DWOBS2A.js.map → chunk-PRQJ5ESM.js.map} +1 -1
  281. package/dist/chunk-PU44GBL4.js +52 -0
  282. package/dist/chunk-PU44GBL4.js.map +1 -0
  283. package/dist/{chunk-MJFNCJXV.js → chunk-Q4CAQGKQ.js} +47 -9
  284. package/dist/chunk-Q4CAQGKQ.js.map +1 -0
  285. package/dist/{chunk-U3WSW6PZ.js → chunk-QMYXNM4P.js} +90 -35
  286. package/dist/chunk-QMYXNM4P.js.map +1 -0
  287. package/dist/{chunk-NBNN5GOB.js → chunk-QY7YA7OL.js} +11 -2
  288. package/dist/chunk-QY7YA7OL.js.map +1 -0
  289. package/dist/{chunk-QLLBRHAT.js → chunk-R26QUUQN.js} +181 -257
  290. package/dist/chunk-R26QUUQN.js.map +1 -0
  291. package/dist/{chunk-ZK7I7JYV.js → chunk-R3PS27B4.js} +7 -7
  292. package/dist/{chunk-TMQLARTH.js → chunk-RCTS5CKK.js} +33 -14
  293. package/dist/chunk-RCTS5CKK.js.map +1 -0
  294. package/dist/{chunk-2PRLKQAH.js → chunk-RLV3PQGH.js} +35 -19
  295. package/dist/chunk-RLV3PQGH.js.map +1 -0
  296. package/dist/{chunk-WW3QQF4H.js → chunk-ROZJACKP.js} +16 -1
  297. package/dist/chunk-ROZJACKP.js.map +1 -0
  298. package/dist/{chunk-7MNMYOFP.js → chunk-RSUYKGGZ.js} +3 -4
  299. package/dist/chunk-RSUYKGGZ.js.map +1 -0
  300. package/dist/{chunk-LT3NLYSI.js → chunk-RUZOJKNF.js} +10 -7
  301. package/dist/chunk-RUZOJKNF.js.map +1 -0
  302. package/dist/{chunk-326G7DJK.js → chunk-RW5DGAGO.js} +67 -13
  303. package/dist/chunk-RW5DGAGO.js.map +1 -0
  304. package/dist/{chunk-KOSORCJG.js → chunk-S53PKKWK.js} +63 -24
  305. package/dist/chunk-S53PKKWK.js.map +1 -0
  306. package/dist/{chunk-65PG43EQ.js → chunk-S7WU3Y3D.js} +21 -4
  307. package/dist/chunk-S7WU3Y3D.js.map +1 -0
  308. package/dist/{chunk-SKE7JYKA.js → chunk-SFXKHM7P.js} +2 -2
  309. package/dist/{chunk-HMDCOMYU.js → chunk-SKGV326D.js} +3 -3
  310. package/dist/chunk-T2PO5MUF.js +62 -0
  311. package/dist/chunk-T2PO5MUF.js.map +1 -0
  312. package/dist/{chunk-C7VW7C3F.js → chunk-TDKQGLJW.js} +3 -3
  313. package/dist/chunk-TDKQGLJW.js.map +1 -0
  314. package/dist/{chunk-3QKK7QOS.js → chunk-TERNBNJB.js} +3 -3
  315. package/dist/chunk-TERNBNJB.js.map +1 -0
  316. package/dist/{chunk-MXC3AP5I.js → chunk-TGQ2NTWH.js} +12 -7
  317. package/dist/chunk-TGQ2NTWH.js.map +1 -0
  318. package/dist/{chunk-3Y4P7RXM.js → chunk-TMSXWOBZ.js} +3 -4
  319. package/dist/chunk-TMSXWOBZ.js.map +1 -0
  320. package/dist/{chunk-3TNBOMQT.js → chunk-TVRN5QKH.js} +11 -11
  321. package/dist/{chunk-3TNBOMQT.js.map → chunk-TVRN5QKH.js.map} +1 -1
  322. package/dist/{chunk-5UM2VJ6D.js → chunk-UEY3VB6W.js} +2 -2
  323. package/dist/{chunk-I6K5FBRQ.js → chunk-UI3NYK34.js} +4 -1
  324. package/dist/{chunk-I6K5FBRQ.js.map → chunk-UI3NYK34.js.map} +1 -1
  325. package/dist/{chunk-VBJ7V5SK.js → chunk-UIPDNLXA.js} +21 -8
  326. package/dist/chunk-UIPDNLXA.js.map +1 -0
  327. package/dist/{chunk-GIF42EW3.js → chunk-UP6MOYCB.js} +3 -3
  328. package/dist/{chunk-K4FLSOR5.js → chunk-USYGGIJZ.js} +44 -15
  329. package/dist/chunk-USYGGIJZ.js.map +1 -0
  330. package/dist/{chunk-FIT6DMX6.js → chunk-UWY7GIVS.js} +152 -54
  331. package/dist/chunk-UWY7GIVS.js.map +1 -0
  332. package/dist/{chunk-MRILGULB.js → chunk-V2RCP53Q.js} +2 -2
  333. package/dist/{chunk-XKECPATV.js → chunk-VFUEZZBS.js} +113 -4
  334. package/dist/chunk-VFUEZZBS.js.map +1 -0
  335. package/dist/{chunk-FSFEQI74.js → chunk-W7L6HXUC.js} +2 -2
  336. package/dist/{chunk-3IQ2TR4N.js → chunk-WLEB7WCG.js} +2 -2
  337. package/dist/{chunk-GL6I6MEQ.js → chunk-WSGF57U2.js} +3 -3
  338. package/dist/{chunk-KNKUID7G.js → chunk-X7Y7WX73.js} +72 -6
  339. package/dist/chunk-X7Y7WX73.js.map +1 -0
  340. package/dist/{chunk-5NPGSAVB.js → chunk-XEKAG3FM.js} +23 -5
  341. package/dist/chunk-XEKAG3FM.js.map +1 -0
  342. package/dist/{chunk-3APJ5EVB.js → chunk-XKIQZXUB.js} +41 -26
  343. package/dist/chunk-XKIQZXUB.js.map +1 -0
  344. package/dist/chunk-XKXKSQU7.js +92 -0
  345. package/dist/chunk-XKXKSQU7.js.map +1 -0
  346. package/dist/{chunk-JA3AK3PT.js → chunk-XNLXAWHX.js} +4 -4
  347. package/dist/{chunk-CULXMQJH.js → chunk-XPXEJRUB.js} +3 -3
  348. package/dist/chunk-XPXEJRUB.js.map +1 -0
  349. package/dist/{chunk-PZIAX57I.js → chunk-XR6DNK4U.js} +7 -4
  350. package/dist/chunk-XR6DNK4U.js.map +1 -0
  351. package/dist/{chunk-47VWKCAF.js → chunk-XSQ4SGM5.js} +33 -4
  352. package/dist/chunk-XSQ4SGM5.js.map +1 -0
  353. package/dist/{chunk-66DHUKLO.js → chunk-XSWKORGM.js} +16 -14
  354. package/dist/chunk-XSWKORGM.js.map +1 -0
  355. package/dist/{chunk-QR3C7BKQ.js → chunk-XZ4WBBB5.js} +7 -8
  356. package/dist/chunk-XZ4WBBB5.js.map +1 -0
  357. package/dist/{chunk-WNARATI3.js → chunk-Y2SXZ5KZ.js} +59 -11
  358. package/dist/chunk-Y2SXZ5KZ.js.map +1 -0
  359. package/dist/{chunk-SIC6U3GZ.js → chunk-YHV3KRKS.js} +3 -3
  360. package/dist/{chunk-ZPKBYX2F.js → chunk-YNDLCWXS.js} +85 -9
  361. package/dist/chunk-YNDLCWXS.js.map +1 -0
  362. package/dist/{chunk-VLXA6PI2.js → chunk-YQMZ7IH2.js} +4 -4
  363. package/dist/{chunk-TMM4S4IJ.js → chunk-YR6GIWWY.js} +58 -8
  364. package/dist/chunk-YR6GIWWY.js.map +1 -0
  365. package/dist/{chunk-DK5LDEQM.js → chunk-YR7XMOWK.js} +39 -23
  366. package/dist/chunk-YR7XMOWK.js.map +1 -0
  367. package/dist/chunk-ZFXCQPNO.js +27 -0
  368. package/dist/chunk-ZFXCQPNO.js.map +1 -0
  369. package/dist/citations.js +1 -1
  370. package/dist/{cli-CJKI2JIe.d.ts → cli-X4NJoqSe.d.ts} +8 -31
  371. package/dist/cli.d.ts +10 -6
  372. package/dist/cli.js +122 -117
  373. package/dist/commitment-ledger.js +2 -2
  374. package/dist/compat/checks.js +1 -2
  375. package/dist/compounding/engine.d.ts +3 -2
  376. package/dist/compounding/engine.js +11 -11
  377. package/dist/compounding/preference-consolidator.d.ts +1 -0
  378. package/dist/compounding/preference-consolidator.js +8 -8
  379. package/dist/compounding/preference-consolidator.js.map +1 -1
  380. package/dist/compression-optimizer.d.ts +1 -0
  381. package/dist/compression-optimizer.js +1 -1
  382. package/dist/config.d.ts +1 -0
  383. package/dist/config.js +3 -2
  384. package/dist/connectors/codex-materialize-runner.d.ts +1 -0
  385. package/dist/connectors/codex-materialize-runner.js +12 -11
  386. package/dist/connectors/codex-materialize.d.ts +1 -0
  387. package/dist/connectors/codex-materialize.js +3 -2
  388. package/dist/connectors/index.d.ts +1 -0
  389. package/dist/connectors/index.js +14 -14
  390. package/dist/{connectors-cli-CwbyjGR7.d.ts → connectors-cli-DbTPNj2H.d.ts} +7 -1
  391. package/dist/connectors-cli.d.ts +1 -1
  392. package/dist/connectors-cli.js +3 -1
  393. package/dist/consolidation-provenance-check.d.ts +1 -0
  394. package/dist/consolidation-provenance-check.js +2 -2
  395. package/dist/consolidation-undo.d.ts +1 -0
  396. package/dist/consolidation-undo.js +1 -1
  397. package/dist/contradiction/index.d.ts +3 -1
  398. package/dist/contradiction/index.js +3 -3
  399. package/dist/{contradiction-review-ATP4S6IC.js → contradiction-review-6V2LXXK6.js} +2 -2
  400. package/dist/{contradiction-scan-5A4IDZV5.js → contradiction-scan-GIRVC4C7.js} +3 -3
  401. package/dist/conversation-index/backend.d.ts +3 -1
  402. package/dist/conversation-index/backend.js +3 -3
  403. package/dist/conversation-index/chunker.d.ts +1 -0
  404. package/dist/conversation-index/cleanup.js +1 -1
  405. package/dist/conversation-index/faiss-adapter.d.ts +2 -1
  406. package/dist/conversation-index/faiss-adapter.js +1 -1
  407. package/dist/conversation-index/indexer.d.ts +5 -2
  408. package/dist/conversation-index/indexer.js +1 -1
  409. package/dist/conversation-index/search.d.ts +2 -1
  410. package/dist/cross-namespace-budget.js +1 -1
  411. package/dist/cue-anchors.js +2 -2
  412. package/dist/dashboard-runtime.d.ts +6 -0
  413. package/dist/dashboard-runtime.js +3 -3
  414. package/dist/day-summary.d.ts +1 -0
  415. package/dist/day-summary.js +2 -2
  416. package/dist/delinearize.d.ts +1 -0
  417. package/dist/direct-answer-wiring.d.ts +1 -0
  418. package/dist/direct-answer.d.ts +1 -0
  419. package/dist/{dreams-ledger-LR2NBAZE.js → dreams-ledger-3WSCI5V4.js} +5 -4
  420. package/dist/{dreams-ledger-LR2NBAZE.js.map → dreams-ledger-3WSCI5V4.js.map} +1 -1
  421. package/dist/embedding-fallback.d.ts +3 -0
  422. package/dist/embedding-fallback.js +2 -2
  423. package/dist/enrichment/index.d.ts +1 -0
  424. package/dist/enrichment/index.js +1 -1
  425. package/dist/entity-retrieval.d.ts +2 -0
  426. package/dist/entity-retrieval.js +9 -9
  427. package/dist/entity-schema.d.ts +1 -0
  428. package/dist/evals.js +1 -1
  429. package/dist/explicit-capture.d.ts +5 -3
  430. package/dist/explicit-capture.js +2 -2
  431. package/dist/extraction-judge-telemetry.d.ts +2 -0
  432. package/dist/extraction-judge-training.d.ts +2 -0
  433. package/dist/extraction-judge.d.ts +2 -0
  434. package/dist/extraction.d.ts +2 -0
  435. package/dist/extraction.js +12 -12
  436. package/dist/{faiss-adapter-CzPghc4C.d.ts → faiss-adapter-BHecI1fF.d.ts} +4 -1
  437. package/dist/fallback-llm.d.ts +11 -1
  438. package/dist/fallback-llm.js +8 -6
  439. package/dist/{first-start-migration-4MHQEOSD.js → first-start-migration-CKTCTCQI.js} +5 -5
  440. package/dist/graph-dashboard-diff.d.ts +4 -0
  441. package/dist/graph-dashboard-diff.js +1 -1
  442. package/dist/graph-dashboard-parser.js +1 -1
  443. package/dist/{graph-edge-decay-5DI5GUNL.js → graph-edge-decay-MUP5J7CC.js} +6 -6
  444. package/dist/graph-events.js +1 -1
  445. package/dist/graph-snapshot.js +3 -3
  446. package/dist/graph.js +2 -2
  447. package/dist/harmonic-retrieval.js +4 -4
  448. package/dist/identity-continuity.d.ts +1 -0
  449. package/dist/importance.d.ts +1 -0
  450. package/dist/importers/index.d.ts +244 -0
  451. package/dist/importers/index.js +20 -0
  452. package/dist/index.d.ts +21 -351
  453. package/dist/index.js +886 -561
  454. package/dist/index.js.map +1 -1
  455. package/dist/intent.d.ts +1 -0
  456. package/dist/lcm/archive.d.ts +2 -2
  457. package/dist/lcm/archive.js +2 -2
  458. package/dist/lcm/engine.d.ts +3 -2
  459. package/dist/lcm/engine.js +6 -6
  460. package/dist/lcm/index.d.ts +1 -0
  461. package/dist/lcm/index.js +8 -8
  462. package/dist/lcm/recall.js +1 -1
  463. package/dist/lcm/summarizer.js +3 -3
  464. package/dist/lcm/tools.d.ts +1 -0
  465. package/dist/lifecycle.d.ts +1 -0
  466. package/dist/live-connectors-runner.d.ts +1 -0
  467. package/dist/live-connectors-runner.js +6 -6
  468. package/dist/local-llm.d.ts +1 -0
  469. package/dist/local-llm.js +2 -2
  470. package/dist/maintenance/archive-observations.js +1 -1
  471. package/dist/maintenance/memory-governance.d.ts +3 -1
  472. package/dist/maintenance/memory-governance.js +10 -8
  473. package/dist/maintenance/migrate-observations.js +3 -2
  474. package/dist/maintenance/observation-ledger-utils.d.ts +3 -0
  475. package/dist/maintenance/observation-ledger-utils.js +2 -1
  476. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -1
  477. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +11 -8
  478. package/dist/maintenance/rebuild-memory-projection.d.ts +2 -1
  479. package/dist/maintenance/rebuild-memory-projection.js +13 -10
  480. package/dist/maintenance/rebuild-observations.d.ts +1 -0
  481. package/dist/maintenance/rebuild-observations.js +3 -2
  482. package/dist/mcp-memory-inspector-app.d.ts +7 -4
  483. package/dist/mcp-memory-inspector-app.js +1 -1
  484. package/dist/memory-action-policy.d.ts +1 -0
  485. package/dist/memory-cache.d.ts +1 -0
  486. package/dist/memory-cache.js +1 -1
  487. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -0
  488. package/dist/memory-projection-store.d.ts +1 -0
  489. package/dist/memory-projection-store.js +1 -1
  490. package/dist/memory-provenance.d.ts +1 -0
  491. package/dist/memory-worth-outcomes.d.ts +1 -0
  492. package/dist/migrate/from-engram.js +2 -2
  493. package/dist/{migrate-from-identity-anchor-G27MCD6A.js → migrate-from-identity-anchor-EB4XI4Q2.js} +2 -2
  494. package/dist/model-registry.js +1 -1
  495. package/dist/models-json.d.ts +1 -0
  496. package/dist/namespaces/migrate.d.ts +3 -0
  497. package/dist/namespaces/migrate.js +24 -22
  498. package/dist/namespaces/principal.d.ts +1 -0
  499. package/dist/namespaces/principal.js +2 -1
  500. package/dist/namespaces/search.d.ts +1 -0
  501. package/dist/namespaces/search.js +15 -13
  502. package/dist/namespaces/storage.d.ts +4 -2
  503. package/dist/namespaces/storage.js +10 -9
  504. package/dist/native-knowledge.d.ts +1 -0
  505. package/dist/native-knowledge.js +1 -1
  506. package/dist/negative.js +1 -1
  507. package/dist/network/webdav.d.ts +16 -1
  508. package/dist/network/webdav.js +5 -3
  509. package/dist/objective-state-writers.js +4 -4
  510. package/dist/objective-state.js +2 -2
  511. package/dist/offline-sync.d.ts +8 -1
  512. package/dist/offline-sync.js +6 -4
  513. package/dist/operator-toolkit.d.ts +1 -0
  514. package/dist/operator-toolkit.js +35 -32
  515. package/dist/opik-exporter.js +1 -1
  516. package/dist/{orchestrator-DuWl9Hwx.d.ts → orchestrator-Co9nxRLF.d.ts} +4 -74
  517. package/dist/orchestrator.d.ts +5 -3
  518. package/dist/orchestrator.js +99 -96
  519. package/dist/page-versioning.js +1 -1
  520. package/dist/path-X2K5XCHL.js +9 -0
  521. package/dist/patterns-cli.d.ts +1 -0
  522. package/dist/peers/index.d.ts +328 -0
  523. package/dist/{peers-HCVGHMAE.js → peers/index.js} +4 -4
  524. package/dist/pipeline-D18UAKlN.d.ts +32 -0
  525. package/dist/plugin-entry-resolver.d.ts +9 -0
  526. package/dist/plugin-entry-resolver.js +8 -0
  527. package/dist/plugin-entry-resolver.js.map +1 -0
  528. package/dist/plugin-id.d.ts +2 -21
  529. package/dist/plugin-id.js +33 -4
  530. package/dist/plugin-id.js.map +1 -1
  531. package/dist/policy-runtime.d.ts +4 -0
  532. package/dist/policy-runtime.js +1 -1
  533. package/dist/profiling.js +1 -1
  534. package/dist/qmd-recall-cache.d.ts +1 -0
  535. package/dist/qmd.d.ts +1 -0
  536. package/dist/qmd.js +3 -3
  537. package/dist/recall-disclosure-escalation.d.ts +1 -0
  538. package/dist/recall-explain-renderer.d.ts +1 -0
  539. package/dist/recall-explain-renderer.js +3 -3
  540. package/dist/recall-state.d.ts +8 -1
  541. package/dist/recall-state.js +2 -1
  542. package/dist/recall-tag-filter.d.ts +1 -0
  543. package/dist/recall-xray-cli.d.ts +1 -0
  544. package/dist/recall-xray-cli.js +4 -4
  545. package/dist/recall-xray-renderer.d.ts +1 -0
  546. package/dist/recall-xray-renderer.js +3 -3
  547. package/dist/recall-xray.d.ts +1 -0
  548. package/dist/recall-xray.js +2 -2
  549. package/dist/relevance.d.ts +7 -1
  550. package/dist/relevance.js +2 -1
  551. package/dist/replay/normalizers/chatgpt.js +2 -2
  552. package/dist/replay/normalizers/claude.js +2 -2
  553. package/dist/replay/normalizers/openclaw.js +2 -2
  554. package/dist/replay/normalizers/shared.js +1 -1
  555. package/dist/replay/runner.js +1 -1
  556. package/dist/rerank.js +1 -1
  557. package/dist/{resolution-B7FNQSSP.js → resolution-ZY7VM6WS.js} +3 -3
  558. package/dist/resolution-ZY7VM6WS.js.map +1 -0
  559. package/dist/resolve-auth-token.d.ts +1 -0
  560. package/dist/resolve-auth-token.js +1 -1
  561. package/dist/resolve-provider-secret.d.ts +19 -29
  562. package/dist/resolve-provider-secret.js +2 -6
  563. package/dist/resume-bundles.js +10 -9
  564. package/dist/retrieval-agents.d.ts +2 -1
  565. package/dist/retrieval-agents.js +2 -1
  566. package/dist/retrieval-tiers.d.ts +1 -0
  567. package/dist/routing/engine.d.ts +1 -0
  568. package/dist/routing/store.d.ts +3 -0
  569. package/dist/routing/store.js +1 -1
  570. package/dist/runtime/env.js +1 -1
  571. package/dist/schemas.d.ts +213 -39
  572. package/dist/schemas.js +1 -1
  573. package/dist/sdk-compat.js +1 -1
  574. package/dist/search/document-scanner.js +1 -1
  575. package/dist/search/embed-helper.d.ts +7 -2
  576. package/dist/search/embed-helper.js +3 -1
  577. package/dist/search/factory.d.ts +2 -1
  578. package/dist/search/factory.js +13 -12
  579. package/dist/search/index.d.ts +2 -1
  580. package/dist/search/index.js +19 -18
  581. package/dist/search/lancedb-backend.d.ts +7 -6
  582. package/dist/search/lancedb-backend.js +4 -2
  583. package/dist/search/meilisearch-backend.d.ts +7 -6
  584. package/dist/search/meilisearch-backend.js +4 -2
  585. package/dist/search/noop-backend.d.ts +1 -0
  586. package/dist/search/orama-backend.d.ts +9 -7
  587. package/dist/search/orama-backend.js +8 -4
  588. package/dist/search/port.d.ts +1 -0
  589. package/dist/search/remote-backend.d.ts +1 -0
  590. package/dist/secure-store/index.d.ts +16 -3
  591. package/dist/secure-store/index.js +2 -2
  592. package/dist/{semantic-VwGI14Ok.d.ts → semantic-SLAa_prH.d.ts} +5 -3
  593. package/dist/semantic-consolidation.d.ts +1 -0
  594. package/dist/semantic-consolidation.js +14 -13
  595. package/dist/semantic-rule-promotion.js +8 -8
  596. package/dist/semantic-rule-verifier.d.ts +1 -0
  597. package/dist/semantic-rule-verifier.js +8 -8
  598. package/dist/session-integrity.d.ts +1 -0
  599. package/dist/session-integrity.js +1 -1
  600. package/dist/session-observer-bands.d.ts +1 -0
  601. package/dist/session-observer-state.d.ts +6 -1
  602. package/dist/session-observer-state.js +1 -1
  603. package/dist/shared-context/manager.d.ts +5 -0
  604. package/dist/shared-context/manager.js +3 -3
  605. package/dist/signal.d.ts +1 -0
  606. package/dist/signal.js +1 -1
  607. package/dist/source-attribution.js +1 -1
  608. package/dist/state-store-4QZISH3J.js +30 -0
  609. package/dist/state-store-4QZISH3J.js.map +1 -0
  610. package/dist/storage-C4DX8CuG.d.ts +157 -0
  611. package/dist/storage.d.ts +2 -0
  612. package/dist/storage.js +7 -7
  613. package/dist/store-contract.js +1 -1
  614. package/dist/summarizer.d.ts +1 -0
  615. package/dist/summarizer.js +7 -7
  616. package/dist/summary-snapshot.d.ts +1 -0
  617. package/dist/surfaces/dreams.js +48 -17
  618. package/dist/surfaces/dreams.js.map +1 -1
  619. package/dist/temporal-supersession.d.ts +1 -0
  620. package/dist/temporal-supersession.js +1 -1
  621. package/dist/temporal-validity.d.ts +1 -0
  622. package/dist/threading.d.ts +1 -0
  623. package/dist/tier-migration.d.ts +1 -0
  624. package/dist/tier-routing.d.ts +1 -0
  625. package/dist/{tier-stats-62ZVDFKS.js → tier-stats-SKML2OSF.js} +5 -5
  626. package/dist/tmt.js +1 -1
  627. package/dist/tokens.js +2 -2
  628. package/dist/topics.d.ts +1 -0
  629. package/dist/{trace-C5ETWBEF.js → trace-WM7V4CKI.js} +31 -1
  630. package/dist/trace-WM7V4CKI.js.map +1 -0
  631. package/dist/transcript.d.ts +1 -0
  632. package/dist/transcript.js +2 -2
  633. package/dist/transfer/autodetect.js +7 -7
  634. package/dist/transfer/backup.js +5 -5
  635. package/dist/transfer/capsule-export.js +5 -5
  636. package/dist/transfer/capsule-import.d.ts +6 -0
  637. package/dist/transfer/capsule-import.js +4 -4
  638. package/dist/transfer/export-json.js +3 -3
  639. package/dist/transfer/export-md.js +3 -3
  640. package/dist/transfer/export-sqlite.js +3 -3
  641. package/dist/transfer/fs-utils.d.ts +2 -1
  642. package/dist/transfer/fs-utils.js +5 -3
  643. package/dist/transfer/import-json.js +3 -3
  644. package/dist/transfer/import-md.js +3 -3
  645. package/dist/transfer/import-sqlite.js +3 -3
  646. package/dist/transfer/types.d.ts +12 -12
  647. package/dist/trust-zones.js +2 -2
  648. package/dist/types-B1VHaf2w.d.ts +126 -0
  649. package/dist/types-BliCnURB.d.ts +83 -0
  650. package/dist/types.d.ts +35 -0
  651. package/dist/types.js +1 -1
  652. package/dist/utility-learner.js +3 -3
  653. package/dist/utility-runtime.d.ts +1 -0
  654. package/dist/utility-runtime.js +4 -4
  655. package/dist/utility-telemetry.js +2 -2
  656. package/dist/verified-recall.js +9 -9
  657. package/dist/work/board.js +2 -2
  658. package/dist/work/boundary.js +1 -1
  659. package/dist/work/storage.d.ts +5 -0
  660. package/dist/work/storage.js +1 -1
  661. package/dist/work-product-ledger.js +2 -2
  662. package/package.json +74 -3
  663. package/scripts/ensure-better-sqlite3.mjs +8 -7
  664. package/scripts/faiss_index.py +141 -29
  665. package/src/access-cli.test.ts +87 -2
  666. package/src/access-cli.ts +59 -5
  667. package/src/access-http.test.ts +321 -0
  668. package/src/access-http.ts +201 -35
  669. package/src/access-idempotency.ts +136 -3
  670. package/src/access-mcp.test.ts +155 -0
  671. package/src/access-mcp.ts +116 -30
  672. package/src/access-schema.ts +22 -4
  673. package/src/access-service-project-tag.test.ts +37 -0
  674. package/src/access-service.ts +42 -10
  675. package/src/active-recall.test.ts +29 -1
  676. package/src/active-recall.ts +11 -7
  677. package/src/adapters/claude-code.ts +7 -8
  678. package/src/adapters/codex.ts +6 -7
  679. package/src/adapters/hermes.ts +1 -5
  680. package/src/adapters/registry.test.ts +63 -0
  681. package/src/adapters/registry.ts +10 -0
  682. package/src/adapters/replit.ts +5 -7
  683. package/src/adapters/types.ts +24 -1
  684. package/src/behavior-signals.ts +1 -1
  685. package/src/binary-lifecycle/backend.ts +16 -4
  686. package/src/binary-lifecycle/pipeline.test.ts +149 -0
  687. package/src/binary-lifecycle/pipeline.ts +49 -7
  688. package/src/binary-lifecycle/scanner.ts +19 -4
  689. package/src/boxes.ts +119 -32
  690. package/src/buffer-session.test.ts +28 -0
  691. package/src/buffer.ts +10 -14
  692. package/src/bulk-import/types.ts +10 -0
  693. package/src/calibration.test.ts +99 -0
  694. package/src/calibration.ts +57 -13
  695. package/src/causal-consolidation.test.ts +214 -0
  696. package/src/causal-consolidation.ts +131 -14
  697. package/src/causal-retrieval.ts +16 -3
  698. package/src/citations.test.ts +75 -0
  699. package/src/citations.ts +19 -6
  700. package/src/cli.ts +134 -109
  701. package/src/coding/coding-namespace.test.ts +7 -0
  702. package/src/coding/coding-namespace.ts +8 -0
  703. package/src/coding/review-context.test.ts +30 -0
  704. package/src/coding/review-context.ts +79 -9
  705. package/src/coding/wire-coding-context.test.ts +16 -0
  706. package/src/compat/checks.test.ts +33 -0
  707. package/src/compat/checks.ts +64 -4
  708. package/src/compounding/engine.ts +2 -2
  709. package/src/compounding/preference-consolidator.test.ts +47 -0
  710. package/src/compounding/preference-consolidator.ts +8 -8
  711. package/src/compression-optimizer.ts +5 -2
  712. package/src/config.test.ts +34 -2
  713. package/src/config.ts +62 -18
  714. package/src/connectors/codex-materialize-runner.ts +4 -3
  715. package/src/connectors/codex-materialize.ts +149 -34
  716. package/src/connectors/index.test.ts +144 -7
  717. package/src/connectors/index.ts +86 -15
  718. package/src/connectors/live/github.test.ts +47 -0
  719. package/src/connectors/live/github.ts +29 -1
  720. package/src/connectors/live/index.ts +2 -0
  721. package/src/connectors/live/live-connectors.test.ts +359 -73
  722. package/src/connectors/live/notion.test.ts +84 -0
  723. package/src/connectors/live/notion.ts +18 -1
  724. package/src/connectors/live/state-store.ts +419 -38
  725. package/src/connectors/weclone-installer.test.ts +16 -18
  726. package/src/connectors-cli.ts +19 -0
  727. package/src/console/trace.test.ts +28 -0
  728. package/src/console/trace.ts +42 -5
  729. package/src/contradiction/contradiction-judge.test.ts +49 -0
  730. package/src/contradiction/contradiction-judge.ts +15 -5
  731. package/src/contradiction/contradiction-review.ts +31 -7
  732. package/src/contradiction/contradiction-scan.ts +28 -18
  733. package/src/contradiction/contradiction.test.ts +237 -1
  734. package/src/contradiction/resolution.ts +43 -4
  735. package/src/conversation-index/backend.ts +13 -5
  736. package/src/conversation-index/cleanup.ts +25 -4
  737. package/src/conversation-index/faiss-adapter.ts +24 -15
  738. package/src/conversation-index/indexer.test.ts +71 -10
  739. package/src/conversation-index/indexer.ts +22 -3
  740. package/src/cross-namespace-budget.test.ts +59 -0
  741. package/src/cross-namespace-budget.ts +15 -7
  742. package/src/curation/index.ts +18 -17
  743. package/src/dashboard-runtime.test.ts +98 -0
  744. package/src/dashboard-runtime.ts +96 -6
  745. package/src/dedup/index.test.ts +133 -0
  746. package/src/dedup/index.ts +73 -10
  747. package/src/dedup/semantic.test.ts +77 -2
  748. package/src/dedup/semantic.ts +26 -6
  749. package/src/embedding-fallback.ts +47 -15
  750. package/src/enrichment/audit.ts +8 -1
  751. package/src/enrichment/pipeline.ts +21 -13
  752. package/src/enrichment/web-search-provider.ts +1 -6
  753. package/src/entity-retrieval.ts +57 -6
  754. package/src/evals.ts +22 -13
  755. package/src/explicit-capture.test.ts +40 -0
  756. package/src/explicit-capture.ts +14 -2
  757. package/src/extraction.ts +42 -30
  758. package/src/fallback-llm.ts +35 -2
  759. package/src/graph-dashboard-diff.test.ts +57 -0
  760. package/src/graph-dashboard-diff.ts +24 -2
  761. package/src/graph-dashboard-parser.test.ts +31 -0
  762. package/src/graph-dashboard-parser.ts +4 -1
  763. package/src/graph-events.ts +6 -4
  764. package/src/graph.test.ts +69 -0
  765. package/src/graph.ts +7 -4
  766. package/src/importers/base.test.ts +70 -0
  767. package/src/importers/base.ts +56 -7
  768. package/src/index.ts +6 -2
  769. package/src/lcm/archive.ts +65 -16
  770. package/src/lcm/engine.ts +27 -8
  771. package/src/lcm/recall.ts +5 -5
  772. package/src/lcm-engine.test.ts +87 -1
  773. package/src/lcm-recall.test.ts +71 -0
  774. package/src/live-connectors-runner.ts +100 -36
  775. package/src/maintenance/archive-observations.ts +24 -3
  776. package/src/maintenance/atomic-file.ts +85 -0
  777. package/src/maintenance/dreams-ledger.ts +15 -8
  778. package/src/maintenance/memory-governance.test.ts +53 -0
  779. package/src/maintenance/memory-governance.ts +15 -5
  780. package/src/maintenance/observation-ledger-utils.ts +6 -5
  781. package/src/maintenance/purge.test.ts +64 -0
  782. package/src/maintenance/rebuild-memory-lifecycle-ledger.ts +22 -9
  783. package/src/maintenance/rebuild-memory-projection.ts +22 -9
  784. package/src/maintenance/rebuild-observations.ts +7 -3
  785. package/src/mcp-memory-inspector-app.ts +26 -3
  786. package/src/memory-cache.test.ts +19 -0
  787. package/src/memory-cache.ts +1 -0
  788. package/src/memory-extension/codex-publisher.ts +25 -4
  789. package/src/memory-extension-host/host-discovery.test.ts +69 -0
  790. package/src/memory-extension-host/host-discovery.ts +63 -6
  791. package/src/memory-projection-store.ts +114 -62
  792. package/src/message-parts/index.ts +46 -31
  793. package/src/message-parts/message-parts.test.ts +77 -0
  794. package/src/migrate/from-engram.ts +68 -14
  795. package/src/model-registry.test.ts +38 -0
  796. package/src/model-registry.ts +12 -7
  797. package/src/namespaces/identity.test.ts +66 -0
  798. package/src/namespaces/identity.ts +23 -0
  799. package/src/namespaces/migrate.test.ts +62 -0
  800. package/src/namespaces/migrate.ts +82 -14
  801. package/src/namespaces/principal.test.ts +37 -1
  802. package/src/namespaces/principal.ts +18 -7
  803. package/src/namespaces/search.test.ts +76 -6
  804. package/src/namespaces/search.ts +22 -21
  805. package/src/namespaces/storage.ts +93 -11
  806. package/src/native-knowledge.ts +23 -3
  807. package/src/negative.ts +50 -5
  808. package/src/network/webdav.ts +177 -58
  809. package/src/offline-sync.ts +22 -11
  810. package/src/onboarding/index.test.ts +105 -0
  811. package/src/onboarding/index.ts +17 -5
  812. package/src/operator-toolkit.ts +39 -4
  813. package/src/orchestrator.ts +52 -17
  814. package/src/page-versioning.ts +31 -5
  815. package/src/peers/peers.test.ts +70 -0
  816. package/src/peers/storage.ts +32 -3
  817. package/src/plugin-entry-resolver.test.ts +60 -0
  818. package/src/plugin-entry-resolver.ts +48 -0
  819. package/src/plugin-id.test.ts +38 -0
  820. package/src/plugin-id.ts +31 -64
  821. package/src/policy-runtime.test.ts +75 -0
  822. package/src/policy-runtime.ts +32 -3
  823. package/src/procedural/procedure-miner.test.ts +152 -0
  824. package/src/procedural/procedure-miner.ts +124 -19
  825. package/src/profiling.test.ts +23 -0
  826. package/src/profiling.ts +10 -1
  827. package/src/projection/index.test.ts +253 -0
  828. package/src/projection/index.ts +159 -18
  829. package/src/qmd-client.test.ts +45 -0
  830. package/src/qmd.ts +8 -8
  831. package/src/recall-disclosure.test.ts +15 -1
  832. package/src/recall-state.ts +24 -5
  833. package/src/relevance.ts +24 -5
  834. package/src/replay/normalizers/chatgpt.ts +14 -4
  835. package/src/replay/normalizers/claude.ts +8 -3
  836. package/src/replay/normalizers/openclaw.ts +35 -12
  837. package/src/replay/normalizers/replay-normalizers.test.ts +65 -0
  838. package/src/replay/normalizers/shared.ts +4 -1
  839. package/src/replay/runner.ts +1 -1
  840. package/src/rerank.test.ts +41 -1
  841. package/src/rerank.ts +2 -2
  842. package/src/resolve-auth-token.test.ts +29 -0
  843. package/src/resolve-auth-token.ts +12 -7
  844. package/src/resolve-provider-secret.test.ts +78 -22
  845. package/src/resolve-provider-secret.ts +55 -223
  846. package/src/retrieval-agents.ts +51 -14
  847. package/src/review/index.test.ts +75 -1
  848. package/src/review/index.ts +88 -30
  849. package/src/routing/store.ts +36 -6
  850. package/src/runtime/env.test.ts +73 -0
  851. package/src/runtime/env.ts +7 -11
  852. package/src/schemas.ts +16 -1
  853. package/src/search/abort.ts +18 -0
  854. package/src/search/document-scanner.test.ts +80 -0
  855. package/src/search/document-scanner.ts +51 -9
  856. package/src/search/embed-helper.ts +19 -6
  857. package/src/search/factory.ts +9 -5
  858. package/src/search/lancedb-backend.ts +62 -22
  859. package/src/search/meilisearch-backend.ts +35 -12
  860. package/src/search/orama-backend.test.ts +27 -0
  861. package/src/search/orama-backend.ts +65 -15
  862. package/src/secure-store/cli-handlers.ts +70 -6
  863. package/src/secure-store/cli-renderer.ts +13 -7
  864. package/src/secure-store/secure-fs.ts +11 -5
  865. package/src/secure-store/secure-store.test.ts +70 -0
  866. package/src/semantic-consolidation.test.ts +45 -0
  867. package/src/semantic-consolidation.ts +3 -3
  868. package/src/session-integrity.test.ts +98 -0
  869. package/src/session-integrity.ts +51 -1
  870. package/src/session-observer-state.ts +108 -41
  871. package/src/shared-context/manager.ts +93 -15
  872. package/src/signal.test.ts +14 -0
  873. package/src/signal.ts +8 -1
  874. package/src/source-attribution.test.ts +8 -0
  875. package/src/source-attribution.ts +24 -2
  876. package/src/spaces/index.test.ts +93 -0
  877. package/src/spaces/index.ts +75 -9
  878. package/src/storage.ts +14 -1
  879. package/src/store-contract.test.ts +35 -0
  880. package/src/store-contract.ts +39 -5
  881. package/src/summarizer.ts +24 -18
  882. package/src/summary-snapshot.test.ts +77 -0
  883. package/src/surfaces/dreams.test.ts +73 -0
  884. package/src/surfaces/dreams.ts +53 -19
  885. package/src/sync/index.ts +42 -17
  886. package/src/taxonomy/taxonomy-loader.ts +43 -4
  887. package/src/temporal-supersession.test.ts +67 -0
  888. package/src/temporal-supersession.ts +8 -0
  889. package/src/tmt.test.ts +50 -0
  890. package/src/tmt.ts +35 -11
  891. package/src/tokens.test.ts +18 -0
  892. package/src/tokens.ts +7 -0
  893. package/src/training-export/converter.test.ts +55 -2
  894. package/src/training-export/converter.ts +36 -10
  895. package/src/training-export/registry.test.ts +17 -0
  896. package/src/training-export/registry.ts +19 -1
  897. package/src/transcript.ts +2 -2
  898. package/src/transfer/backup.ts +18 -7
  899. package/src/transfer/capsule-crypto.ts +105 -21
  900. package/src/transfer/capsule-encrypt.test.ts +106 -7
  901. package/src/transfer/capsule-export.ts +23 -14
  902. package/src/transfer/capsule-import.ts +11 -2
  903. package/src/transfer/exclusions.ts +7 -0
  904. package/src/transfer/export-sqlite.ts +14 -13
  905. package/src/transfer/fs-utils.ts +52 -1
  906. package/src/transfer/import-json.ts +12 -7
  907. package/src/transfer/import-md.ts +5 -5
  908. package/src/transfer/import-sqlite.ts +4 -5
  909. package/src/trust-zones.ts +1 -1
  910. package/src/types.ts +25 -0
  911. package/src/utility-telemetry.ts +1 -1
  912. package/src/utils/category-dir.test.ts +15 -0
  913. package/src/utils/category-dir.ts +3 -1
  914. package/src/work/boundary.ts +30 -18
  915. package/src/work/storage.ts +116 -38
  916. package/src/work-product-ledger.ts +1 -1
  917. package/dist/chunk-25MQ7IHJ.js.map +0 -1
  918. package/dist/chunk-2IWUMAES.js.map +0 -1
  919. package/dist/chunk-2NMMFZ5T.js.map +0 -1
  920. package/dist/chunk-2PRLKQAH.js.map +0 -1
  921. package/dist/chunk-326G7DJK.js.map +0 -1
  922. package/dist/chunk-3APJ5EVB.js.map +0 -1
  923. package/dist/chunk-3KW65B36.js.map +0 -1
  924. package/dist/chunk-3OWUCDKH.js.map +0 -1
  925. package/dist/chunk-3QKK7QOS.js.map +0 -1
  926. package/dist/chunk-3SLRNYNG.js.map +0 -1
  927. package/dist/chunk-3VAL7ZL2.js.map +0 -1
  928. package/dist/chunk-3Y4P7RXM.js.map +0 -1
  929. package/dist/chunk-43PJZYGL.js.map +0 -1
  930. package/dist/chunk-47VWKCAF.js.map +0 -1
  931. package/dist/chunk-4KGVTPGD.js.map +0 -1
  932. package/dist/chunk-5375UYTQ.js.map +0 -1
  933. package/dist/chunk-56K5QLHX.js.map +0 -1
  934. package/dist/chunk-575RMLWN.js.map +0 -1
  935. package/dist/chunk-5NPGSAVB.js.map +0 -1
  936. package/dist/chunk-5RGLBDQF.js.map +0 -1
  937. package/dist/chunk-65PG43EQ.js.map +0 -1
  938. package/dist/chunk-66DHUKLO.js.map +0 -1
  939. package/dist/chunk-6LVVDPJ4.js.map +0 -1
  940. package/dist/chunk-76FLAAUC.js.map +0 -1
  941. package/dist/chunk-77H5NU3M.js.map +0 -1
  942. package/dist/chunk-7MNMYOFP.js.map +0 -1
  943. package/dist/chunk-7OZ53EXP.js.map +0 -1
  944. package/dist/chunk-7SEAZFFB.js.map +0 -1
  945. package/dist/chunk-A6KTB5R6.js.map +0 -1
  946. package/dist/chunk-AGZQD76C.js.map +0 -1
  947. package/dist/chunk-APO3DCMU.js.map +0 -1
  948. package/dist/chunk-BVF3AGJP.js.map +0 -1
  949. package/dist/chunk-C5BCH4ZS.js.map +0 -1
  950. package/dist/chunk-C7VW7C3F.js.map +0 -1
  951. package/dist/chunk-CULXMQJH.js.map +0 -1
  952. package/dist/chunk-CYFQJMUV.js.map +0 -1
  953. package/dist/chunk-D654IBA6.js +0 -61
  954. package/dist/chunk-D654IBA6.js.map +0 -1
  955. package/dist/chunk-DGXUHMOV.js.map +0 -1
  956. package/dist/chunk-DINWEURR.js.map +0 -1
  957. package/dist/chunk-DK5LDEQM.js.map +0 -1
  958. package/dist/chunk-EABGC2TL.js.map +0 -1
  959. package/dist/chunk-EHRTFRWW.js.map +0 -1
  960. package/dist/chunk-EJI5XIBB.js.map +0 -1
  961. package/dist/chunk-FAAFWE4G.js.map +0 -1
  962. package/dist/chunk-FAJ7FZYM.js +0 -11
  963. package/dist/chunk-FAJ7FZYM.js.map +0 -1
  964. package/dist/chunk-FDU6HUUL.js +0 -147
  965. package/dist/chunk-FDU6HUUL.js.map +0 -1
  966. package/dist/chunk-FIT6DMX6.js.map +0 -1
  967. package/dist/chunk-FJ43PRLT.js.map +0 -1
  968. package/dist/chunk-FLTNHQK6.js +0 -262
  969. package/dist/chunk-FLTNHQK6.js.map +0 -1
  970. package/dist/chunk-GDFS42HT.js.map +0 -1
  971. package/dist/chunk-H3ME6L6D.js.map +0 -1
  972. package/dist/chunk-HXXBL2KD.js.map +0 -1
  973. package/dist/chunk-ICRIXAP2.js.map +0 -1
  974. package/dist/chunk-IQT3XTKW.js.map +0 -1
  975. package/dist/chunk-JR4ZC3G4.js.map +0 -1
  976. package/dist/chunk-K4FLSOR5.js.map +0 -1
  977. package/dist/chunk-KNKUID7G.js.map +0 -1
  978. package/dist/chunk-KOSORCJG.js.map +0 -1
  979. package/dist/chunk-KRBK4BQH.js.map +0 -1
  980. package/dist/chunk-LIRZNNUP.js.map +0 -1
  981. package/dist/chunk-LLQ2LLWF.js.map +0 -1
  982. package/dist/chunk-LPMVBPA3.js +0 -236
  983. package/dist/chunk-LPMVBPA3.js.map +0 -1
  984. package/dist/chunk-LT3NLYSI.js.map +0 -1
  985. package/dist/chunk-LUDTDZLK.js.map +0 -1
  986. package/dist/chunk-MG7NA5H3.js.map +0 -1
  987. package/dist/chunk-MJFNCJXV.js.map +0 -1
  988. package/dist/chunk-MSWG7JI6.js.map +0 -1
  989. package/dist/chunk-MXC3AP5I.js.map +0 -1
  990. package/dist/chunk-MXFBBHJU.js.map +0 -1
  991. package/dist/chunk-MZH6EHNR.js.map +0 -1
  992. package/dist/chunk-N2D6GXBM.js.map +0 -1
  993. package/dist/chunk-NBNN5GOB.js.map +0 -1
  994. package/dist/chunk-NMZY542O.js.map +0 -1
  995. package/dist/chunk-NZL6GGQE.js.map +0 -1
  996. package/dist/chunk-OC7KHOOX.js.map +0 -1
  997. package/dist/chunk-OZHRDTDX.js.map +0 -1
  998. package/dist/chunk-PZIAX57I.js.map +0 -1
  999. package/dist/chunk-Q7P4WJDP.js.map +0 -1
  1000. package/dist/chunk-QA2ZAPBU.js.map +0 -1
  1001. package/dist/chunk-QDZ2RLEC.js.map +0 -1
  1002. package/dist/chunk-QKZGQIPJ.js.map +0 -1
  1003. package/dist/chunk-QLLBRHAT.js.map +0 -1
  1004. package/dist/chunk-QR3C7BKQ.js.map +0 -1
  1005. package/dist/chunk-RHY3HH7P.js.map +0 -1
  1006. package/dist/chunk-RK2Y4XOM.js.map +0 -1
  1007. package/dist/chunk-RR2PKP3I.js +0 -63
  1008. package/dist/chunk-RR2PKP3I.js.map +0 -1
  1009. package/dist/chunk-RRF5UOBJ.js.map +0 -1
  1010. package/dist/chunk-RXDLTSWT.js.map +0 -1
  1011. package/dist/chunk-RYED3SPJ.js +0 -42
  1012. package/dist/chunk-RYED3SPJ.js.map +0 -1
  1013. package/dist/chunk-S7KDBTWT.js.map +0 -1
  1014. package/dist/chunk-TK4UEOSK.js.map +0 -1
  1015. package/dist/chunk-TMM4S4IJ.js.map +0 -1
  1016. package/dist/chunk-TMQLARTH.js.map +0 -1
  1017. package/dist/chunk-TPB3I2AC.js.map +0 -1
  1018. package/dist/chunk-TPMQ3G6Z.js.map +0 -1
  1019. package/dist/chunk-TZOLIGIG.js.map +0 -1
  1020. package/dist/chunk-U3WSW6PZ.js.map +0 -1
  1021. package/dist/chunk-U4SCL7B7.js.map +0 -1
  1022. package/dist/chunk-U66YHYC7.js +0 -31
  1023. package/dist/chunk-U66YHYC7.js.map +0 -1
  1024. package/dist/chunk-UL2NNBUL.js.map +0 -1
  1025. package/dist/chunk-UWVJF25J.js.map +0 -1
  1026. package/dist/chunk-VBJ7V5SK.js.map +0 -1
  1027. package/dist/chunk-W3LR522O.js.map +0 -1
  1028. package/dist/chunk-W4L6CZKA.js.map +0 -1
  1029. package/dist/chunk-W6AQJ2PY.js.map +0 -1
  1030. package/dist/chunk-WELDCG6C.js.map +0 -1
  1031. package/dist/chunk-WNARATI3.js.map +0 -1
  1032. package/dist/chunk-WPGJYVUH.js.map +0 -1
  1033. package/dist/chunk-WW3QQF4H.js.map +0 -1
  1034. package/dist/chunk-XIG5PDM7.js.map +0 -1
  1035. package/dist/chunk-XKECPATV.js.map +0 -1
  1036. package/dist/chunk-XKLD5OK4.js.map +0 -1
  1037. package/dist/chunk-XSZEP4SF.js.map +0 -1
  1038. package/dist/chunk-XVVIG67A.js.map +0 -1
  1039. package/dist/chunk-XYIK4LF6.js.map +0 -1
  1040. package/dist/chunk-YRMVARQP.js.map +0 -1
  1041. package/dist/chunk-ZPKBYX2F.js.map +0 -1
  1042. package/dist/chunk-ZTFCYYEZ.js.map +0 -1
  1043. package/dist/chunk-ZYVPLJ4T.js.map +0 -1
  1044. package/dist/path-MR5JPYOP.js +0 -9
  1045. package/dist/state-store-VZU2IA53.js +0 -16
  1046. package/dist/trace-C5ETWBEF.js.map +0 -1
  1047. /package/dist/{capsule-crypto-5CYAGVC5.js.map → bulk-import/index.js.map} +0 -0
  1048. /package/dist/{contradiction-review-ATP4S6IC.js.map → capsule-crypto-7FJQINUR.js.map} +0 -0
  1049. /package/dist/{capsule-merge-4MGKE7C5.js.map → capsule-merge-T2JRE46P.js.map} +0 -0
  1050. /package/dist/{chunk-SAZS2QZB.js.map → chunk-23UORJ4S.js.map} +0 -0
  1051. /package/dist/{chunk-PK7H5L6Y.js.map → chunk-2NM43EWN.js.map} +0 -0
  1052. /package/dist/{chunk-PYXS46O7.js.map → chunk-3BP57I6J.js.map} +0 -0
  1053. /package/dist/{chunk-FBYESMQ2.js.map → chunk-3C5RPJAX.js.map} +0 -0
  1054. /package/dist/{chunk-N53K2EXC.js.map → chunk-6VF75M3X.js.map} +0 -0
  1055. /package/dist/{chunk-6H2TESSP.js.map → chunk-765K3SAT.js.map} +0 -0
  1056. /package/dist/{chunk-EDTHC6UD.js.map → chunk-77NAFXUD.js.map} +0 -0
  1057. /package/dist/{chunk-MGKYQQYF.js.map → chunk-7Q3RCKAQ.js.map} +0 -0
  1058. /package/dist/{chunk-34DQE4KF.js.map → chunk-CO7ZO4TU.js.map} +0 -0
  1059. /package/dist/{chunk-ZKSK55RC.js.map → chunk-ETUPBUHB.js.map} +0 -0
  1060. /package/dist/{chunk-QRNI5JBH.js.map → chunk-EYIEWJNI.js.map} +0 -0
  1061. /package/dist/{chunk-C6QPK5GG.js.map → chunk-FZZ2QTJI.js.map} +0 -0
  1062. /package/dist/{chunk-3JXBXXM2.js.map → chunk-G4IAEX6D.js.map} +0 -0
  1063. /package/dist/{chunk-2WWLHTZY.js.map → chunk-IC4GELZE.js.map} +0 -0
  1064. /package/dist/{chunk-PCUKNJAZ.js.map → chunk-JKV57BTN.js.map} +0 -0
  1065. /package/dist/{chunk-2KI4QFHU.js.map → chunk-LMDRGRJ2.js.map} +0 -0
  1066. /package/dist/{chunk-MY6TPVXW.js.map → chunk-LMPHTYJC.js.map} +0 -0
  1067. /package/dist/{chunk-5HRY2WRF.js.map → chunk-LZ3VEOU5.js.map} +0 -0
  1068. /package/dist/{chunk-NGAVDO7E.js.map → chunk-OADWQ5CR.js.map} +0 -0
  1069. /package/dist/{chunk-DOM4GKSW.js.map → chunk-OZKVVUJB.js.map} +0 -0
  1070. /package/dist/{chunk-MT4HVDUZ.js.map → chunk-PM3QHTFT.js.map} +0 -0
  1071. /package/dist/{chunk-ZK7I7JYV.js.map → chunk-R3PS27B4.js.map} +0 -0
  1072. /package/dist/{chunk-SKE7JYKA.js.map → chunk-SFXKHM7P.js.map} +0 -0
  1073. /package/dist/{chunk-HMDCOMYU.js.map → chunk-SKGV326D.js.map} +0 -0
  1074. /package/dist/{chunk-5UM2VJ6D.js.map → chunk-UEY3VB6W.js.map} +0 -0
  1075. /package/dist/{chunk-GIF42EW3.js.map → chunk-UP6MOYCB.js.map} +0 -0
  1076. /package/dist/{chunk-MRILGULB.js.map → chunk-V2RCP53Q.js.map} +0 -0
  1077. /package/dist/{chunk-FSFEQI74.js.map → chunk-W7L6HXUC.js.map} +0 -0
  1078. /package/dist/{chunk-3IQ2TR4N.js.map → chunk-WLEB7WCG.js.map} +0 -0
  1079. /package/dist/{chunk-GL6I6MEQ.js.map → chunk-WSGF57U2.js.map} +0 -0
  1080. /package/dist/{chunk-JA3AK3PT.js.map → chunk-XNLXAWHX.js.map} +0 -0
  1081. /package/dist/{chunk-SIC6U3GZ.js.map → chunk-YHV3KRKS.js.map} +0 -0
  1082. /package/dist/{chunk-VLXA6PI2.js.map → chunk-YQMZ7IH2.js.map} +0 -0
  1083. /package/dist/{contradiction-scan-5A4IDZV5.js.map → contradiction-review-6V2LXXK6.js.map} +0 -0
  1084. /package/dist/{migrate-from-identity-anchor-G27MCD6A.js.map → contradiction-scan-GIRVC4C7.js.map} +0 -0
  1085. /package/dist/{first-start-migration-4MHQEOSD.js.map → first-start-migration-CKTCTCQI.js.map} +0 -0
  1086. /package/dist/{graph-edge-decay-5DI5GUNL.js.map → graph-edge-decay-MUP5J7CC.js.map} +0 -0
  1087. /package/dist/{path-MR5JPYOP.js.map → importers/index.js.map} +0 -0
  1088. /package/dist/{peers-HCVGHMAE.js.map → migrate-from-identity-anchor-EB4XI4Q2.js.map} +0 -0
  1089. /package/dist/{resolution-B7FNQSSP.js.map → path-X2K5XCHL.js.map} +0 -0
  1090. /package/dist/{state-store-VZU2IA53.js.map → peers/index.js.map} +0 -0
  1091. /package/dist/{tier-stats-62ZVDFKS.js.map → tier-stats-SKML2OSF.js.map} +0 -0
@@ -18,9 +18,11 @@ function emitGraphEvent(memoryDir, type, payload) {
18
18
  payload
19
19
  };
20
20
  const bus = getGraphEventBus(memoryDir);
21
- try {
22
- bus.emit("graph-event", event);
23
- } catch {
21
+ for (const listener of bus.listeners("graph-event")) {
22
+ try {
23
+ listener(event);
24
+ } catch {
25
+ }
24
26
  }
25
27
  }
26
28
  function subscribeGraphEvents(memoryDir, listener) {
@@ -42,4 +44,4 @@ export {
42
44
  subscribeGraphEvents,
43
45
  destroyGraphEventBus
44
46
  };
45
- //# sourceMappingURL=chunk-WIICJPET.js.map
47
+ //# sourceMappingURL=chunk-DEUNUKTD.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/graph-events.ts"],"sourcesContent":["/**\n * In-process EventEmitter for graph mutation events (issue #691 PR 5/5).\n *\n * The singleton is keyed by memoryDir so multiple orchestrator instances in\n * the same process get distinct event buses (CLAUDE.md rule 11: scope globals\n * per service). The SSE handler in access-http.ts subscribes to the bus for\n * the resolved namespace and fans out to connected clients.\n *\n * Event types mirror the five mutations the graph layer can produce:\n * node-added — a memory file was referenced for the first time\n * node-updated — a memory file's metadata changed\n * edge-added — a new edge was appended\n * edge-updated — an existing edge's confidence/weight was modified\n * edge-removed — an edge was pruned (e.g. by decay maintenance)\n *\n * The `GraphEventBus` interface is intentionally narrow so nothing outside\n * this module needs to import Node.js EventEmitter directly.\n */\n\nimport { EventEmitter } from \"node:events\";\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport type GraphEventType =\n | \"node-added\"\n | \"node-updated\"\n | \"edge-added\"\n | \"edge-updated\"\n | \"edge-removed\";\n\nexport interface GraphEvent {\n type: GraphEventType;\n /** Memory dir that owns this event (absolute path). */\n memoryDir: string;\n /** ISO timestamp of the event. */\n ts: string;\n /** Payload depends on event type — always serialisable to JSON. */\n payload: Record<string, unknown>;\n}\n\nexport interface NodeAddedPayload {\n nodeId: string; // relative memory path\n kind: string;\n label: string;\n lastUpdated: string;\n}\n\nexport interface NodeUpdatedPayload {\n nodeId: string;\n kind: string;\n label: string;\n lastUpdated: string;\n}\n\nexport interface EdgeAddedPayload {\n source: string;\n target: string;\n kind: string;\n weight: number;\n label: string;\n confidence: number;\n}\n\nexport interface EdgeUpdatedPayload {\n source: string;\n target: string;\n kind: string;\n weight: number;\n confidence: number;\n}\n\nexport interface EdgeRemovedPayload {\n source: string;\n target: string;\n kind: string;\n}\n\n// ---------------------------------------------------------------------------\n// Per-memoryDir singleton bus\n// ---------------------------------------------------------------------------\n\nconst buses = new Map<string, EventEmitter>();\n\n/**\n * Return (or lazily create) the event bus for the given memoryDir.\n * The same bus is shared by the write side (graph.ts → appendEdge hooks) and\n * the read side (EngramAccessHttpServer SSE handler).\n */\nexport function getGraphEventBus(memoryDir: string): EventEmitter {\n let bus = buses.get(memoryDir);\n if (!bus) {\n bus = new EventEmitter();\n // Remove the default listener-count warning — SSE clients may hold many\n // concurrent connections. Each SSE client registers one \"graph-event\"\n // listener; warn only when an unreasonably high count suggests a leak.\n bus.setMaxListeners(200);\n buses.set(memoryDir, bus);\n }\n return bus;\n}\n\n/**\n * Emit a single graph event onto the bus for memoryDir.\n * Fails open: any listener that throws is caught so one bad client can't\n * crash the extraction pipeline.\n */\nexport function emitGraphEvent(\n memoryDir: string,\n type: GraphEventType,\n payload: Record<string, unknown>,\n): void {\n const event: GraphEvent = {\n type,\n memoryDir,\n ts: new Date().toISOString(),\n payload,\n };\n const bus = getGraphEventBus(memoryDir);\n try {\n bus.emit(\"graph-event\", event);\n } catch {\n // fail-open: never propagate listener errors to the write path\n }\n}\n\n/**\n * Subscribe to graph events for a given memoryDir.\n * Returns an unsubscribe function.\n */\nexport function subscribeGraphEvents(\n memoryDir: string,\n listener: (event: GraphEvent) => void,\n): () => void {\n const bus = getGraphEventBus(memoryDir);\n bus.on(\"graph-event\", listener);\n return () => bus.off(\"graph-event\", listener);\n}\n\n/**\n * Remove all listeners and the bus entry for a memoryDir.\n * Useful for tests that spin up isolated memory dirs.\n */\nexport function destroyGraphEventBus(memoryDir: string): void {\n const bus = buses.get(memoryDir);\n if (bus) {\n bus.removeAllListeners();\n buses.delete(memoryDir);\n }\n}\n"],"mappings":";AAmBA,SAAS,oBAAoB;AAgE7B,IAAM,QAAQ,oBAAI,IAA0B;AAOrC,SAAS,iBAAiB,WAAiC;AAChE,MAAI,MAAM,MAAM,IAAI,SAAS;AAC7B,MAAI,CAAC,KAAK;AACR,UAAM,IAAI,aAAa;AAIvB,QAAI,gBAAgB,GAAG;AACvB,UAAM,IAAI,WAAW,GAAG;AAAA,EAC1B;AACA,SAAO;AACT;AAOO,SAAS,eACd,WACA,MACA,SACM;AACN,QAAM,QAAoB;AAAA,IACxB;AAAA,IACA;AAAA,IACA,KAAI,oBAAI,KAAK,GAAE,YAAY;AAAA,IAC3B;AAAA,EACF;AACA,QAAM,MAAM,iBAAiB,SAAS;AACtC,MAAI;AACF,QAAI,KAAK,eAAe,KAAK;AAAA,EAC/B,QAAQ;AAAA,EAER;AACF;AAMO,SAAS,qBACd,WACA,UACY;AACZ,QAAM,MAAM,iBAAiB,SAAS;AACtC,MAAI,GAAG,eAAe,QAAQ;AAC9B,SAAO,MAAM,IAAI,IAAI,eAAe,QAAQ;AAC9C;AAMO,SAAS,qBAAqB,WAAyB;AAC5D,QAAM,MAAM,MAAM,IAAI,SAAS;AAC/B,MAAI,KAAK;AACP,QAAI,mBAAmB;AACvB,UAAM,OAAO,SAAS;AAAA,EACxB;AACF;","names":[]}
1
+ {"version":3,"sources":["../src/graph-events.ts"],"sourcesContent":["/**\n * In-process EventEmitter for graph mutation events (issue #691 PR 5/5).\n *\n * The singleton is keyed by memoryDir so multiple orchestrator instances in\n * the same process get distinct event buses (CLAUDE.md rule 11: scope globals\n * per service). The SSE handler in access-http.ts subscribes to the bus for\n * the resolved namespace and fans out to connected clients.\n *\n * Event types mirror the five mutations the graph layer can produce:\n * node-added — a memory file was referenced for the first time\n * node-updated — a memory file's metadata changed\n * edge-added — a new edge was appended\n * edge-updated — an existing edge's confidence/weight was modified\n * edge-removed — an edge was pruned (e.g. by decay maintenance)\n *\n * The `GraphEventBus` interface is intentionally narrow so nothing outside\n * this module needs to import Node.js EventEmitter directly.\n */\n\nimport { EventEmitter } from \"node:events\";\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport type GraphEventType =\n | \"node-added\"\n | \"node-updated\"\n | \"edge-added\"\n | \"edge-updated\"\n | \"edge-removed\";\n\nexport interface GraphEvent {\n type: GraphEventType;\n /** Memory dir that owns this event (absolute path). */\n memoryDir: string;\n /** ISO timestamp of the event. */\n ts: string;\n /** Payload depends on event type — always serialisable to JSON. */\n payload: Record<string, unknown>;\n}\n\nexport interface NodeAddedPayload {\n nodeId: string; // relative memory path\n kind: string;\n label: string;\n lastUpdated: string;\n}\n\nexport interface NodeUpdatedPayload {\n nodeId: string;\n kind: string;\n label: string;\n lastUpdated: string;\n}\n\nexport interface EdgeAddedPayload {\n source: string;\n target: string;\n kind: string;\n weight: number;\n label: string;\n confidence: number;\n}\n\nexport interface EdgeUpdatedPayload {\n source: string;\n target: string;\n kind: string;\n weight: number;\n confidence: number;\n}\n\nexport interface EdgeRemovedPayload {\n source: string;\n target: string;\n kind: string;\n}\n\n// ---------------------------------------------------------------------------\n// Per-memoryDir singleton bus\n// ---------------------------------------------------------------------------\n\nconst buses = new Map<string, EventEmitter>();\n\n/**\n * Return (or lazily create) the event bus for the given memoryDir.\n * The same bus is shared by the write side (graph.ts → appendEdge hooks) and\n * the read side (EngramAccessHttpServer SSE handler).\n */\nexport function getGraphEventBus(memoryDir: string): EventEmitter {\n let bus = buses.get(memoryDir);\n if (!bus) {\n bus = new EventEmitter();\n // Remove the default listener-count warning — SSE clients may hold many\n // concurrent connections. Each SSE client registers one \"graph-event\"\n // listener; warn only when an unreasonably high count suggests a leak.\n bus.setMaxListeners(200);\n buses.set(memoryDir, bus);\n }\n return bus;\n}\n\n/**\n * Emit a single graph event onto the bus for memoryDir.\n * Fails open: any listener that throws is caught so one bad client can't\n * crash the extraction pipeline.\n */\nexport function emitGraphEvent(\n memoryDir: string,\n type: GraphEventType,\n payload: Record<string, unknown>,\n): void {\n const event: GraphEvent = {\n type,\n memoryDir,\n ts: new Date().toISOString(),\n payload,\n };\n const bus = getGraphEventBus(memoryDir);\n for (const listener of bus.listeners(\"graph-event\")) {\n try {\n (listener as (event: GraphEvent) => void)(event);\n } catch {\n // fail-open: never let one subscriber block later listeners or writes\n }\n }\n}\n\n/**\n * Subscribe to graph events for a given memoryDir.\n * Returns an unsubscribe function.\n */\nexport function subscribeGraphEvents(\n memoryDir: string,\n listener: (event: GraphEvent) => void,\n): () => void {\n const bus = getGraphEventBus(memoryDir);\n bus.on(\"graph-event\", listener);\n return () => bus.off(\"graph-event\", listener);\n}\n\n/**\n * Remove all listeners and the bus entry for a memoryDir.\n * Useful for tests that spin up isolated memory dirs.\n */\nexport function destroyGraphEventBus(memoryDir: string): void {\n const bus = buses.get(memoryDir);\n if (bus) {\n bus.removeAllListeners();\n buses.delete(memoryDir);\n }\n}\n"],"mappings":";AAmBA,SAAS,oBAAoB;AAgE7B,IAAM,QAAQ,oBAAI,IAA0B;AAOrC,SAAS,iBAAiB,WAAiC;AAChE,MAAI,MAAM,MAAM,IAAI,SAAS;AAC7B,MAAI,CAAC,KAAK;AACR,UAAM,IAAI,aAAa;AAIvB,QAAI,gBAAgB,GAAG;AACvB,UAAM,IAAI,WAAW,GAAG;AAAA,EAC1B;AACA,SAAO;AACT;AAOO,SAAS,eACd,WACA,MACA,SACM;AACN,QAAM,QAAoB;AAAA,IACxB;AAAA,IACA;AAAA,IACA,KAAI,oBAAI,KAAK,GAAE,YAAY;AAAA,IAC3B;AAAA,EACF;AACA,QAAM,MAAM,iBAAiB,SAAS;AACtC,aAAW,YAAY,IAAI,UAAU,aAAa,GAAG;AACnD,QAAI;AACF,MAAC,SAAyC,KAAK;AAAA,IACjD,QAAQ;AAAA,IAER;AAAA,EACF;AACF;AAMO,SAAS,qBACd,WACA,UACY;AACZ,QAAM,MAAM,iBAAiB,SAAS;AACtC,MAAI,GAAG,eAAe,QAAQ;AAC9B,SAAO,MAAM,IAAI,IAAI,eAAe,QAAQ;AAC9C;AAMO,SAAS,qBAAqB,WAAyB;AAC5D,QAAM,MAAM,MAAM,IAAI,SAAS;AAC/B,MAAI,KAAK;AACP,QAAI,mBAAmB;AACvB,UAAM,OAAO,SAAS;AAAA,EACxB;AACF;","names":[]}
@@ -1,20 +1,20 @@
1
1
  import {
2
2
  createVersion
3
- } from "./chunk-FAAFWE4G.js";
3
+ } from "./chunk-ALEPI75L.js";
4
4
  import {
5
5
  parseExportBundle
6
6
  } from "./chunk-WEHSQBFR.js";
7
7
  import {
8
8
  decryptCapsuleFileInMemory,
9
9
  isEncryptedCapsuleFile
10
- } from "./chunk-KNKUID7G.js";
10
+ } from "./chunk-X7Y7WX73.js";
11
11
  import {
12
12
  assertIsDirectoryNotSymlink,
13
13
  assertRealpathInsideRoot,
14
14
  fromPosixRelPath,
15
15
  isPathInsideRoot,
16
16
  sha256String
17
- } from "./chunk-AGZQD76C.js";
17
+ } from "./chunk-GCGJW34D.js";
18
18
 
19
19
  // src/transfer/capsule-import.ts
20
20
  import { lstat, mkdir, readFile, realpath, stat, writeFile } from "fs/promises";
@@ -34,12 +34,14 @@ async function importCapsule(opts) {
34
34
  const encrypted = await isEncryptedCapsuleFile(archiveAbs);
35
35
  let raw;
36
36
  if (encrypted) {
37
- if (!opts.memoryDir) {
37
+ if (!opts.memoryDir && !opts.passphrase) {
38
38
  throw new Error(
39
- `importCapsule: archive is encrypted but 'memoryDir' was not provided. Pass the memory directory so the secure-store key can be retrieved, or run \`remnic secure-store unlock\` before importing.`
39
+ `importCapsule: archive is encrypted but 'memoryDir' was not provided. Pass the memory directory so the secure-store key can be retrieved, provide the original passphrase for a format-v2 archive restore, or run \`remnic secure-store unlock\` before importing.`
40
40
  );
41
41
  }
42
- raw = await decryptCapsuleFileInMemory(archiveAbs, opts.memoryDir);
42
+ raw = await decryptCapsuleFileInMemory(archiveAbs, opts.memoryDir, {
43
+ passphrase: opts.passphrase
44
+ });
43
45
  } else {
44
46
  raw = await readFile(archiveAbs);
45
47
  }
@@ -225,4 +227,4 @@ function mintForkId(capsuleId, originalId, now) {
225
227
  export {
226
228
  importCapsule
227
229
  };
228
- //# sourceMappingURL=chunk-ZYVPLJ4T.js.map
230
+ //# sourceMappingURL=chunk-DHGSZ3UD.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/transfer/capsule-import.ts"],"sourcesContent":["import { lstat, mkdir, readFile, realpath, stat, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { createHash, randomUUID } from \"node:crypto\";\nimport { gunzipSync } from \"node:zlib\";\nimport {\n createVersion,\n type VersioningConfig,\n type VersioningLogger,\n} from \"../page-versioning.js\";\nimport {\n assertIsDirectoryNotSymlink,\n assertRealpathInsideRoot,\n fromPosixRelPath,\n isPathInsideRoot,\n sha256String,\n} from \"./fs-utils.js\";\nimport {\n parseExportBundle,\n type CapsuleBlock,\n type ExportManifestV2,\n type ExportMemoryRecordV1,\n} from \"./types.js\";\nimport { isEncryptedCapsuleFile, decryptCapsuleFileInMemory } from \"./capsule-crypto.js\";\n\n/**\n * Conflict-resolution mode for {@link importCapsule}. Inverse of the\n * `mode` selector in PR 4/6's CLI surface.\n *\n * - `\"skip\"` (default) — when a target file already exists at the same\n * relative path, leave it untouched. The corresponding record is reported\n * via {@link ImportCapsuleResult.skipped}.\n * - `\"overwrite\"` — when a target file exists, snapshot the prior content\n * via {@link createVersion} (gotcha #54: write-before-delete; gotcha #25:\n * don't destroy old state until new state is confirmed), then write the\n * incoming content. The snapshot's `note` includes the source capsule id.\n * - `\"fork\"` — never overwrite. Every record is rebased under\n * `forks/<capsule-id>/<original-path>` and any YAML-frontmatter `id:`\n * field is rewritten to a new fork-scoped value. The original tree is\n * not touched.\n *\n * The mode is selected once per call and applied uniformly to every record\n * in the bundle. Mixed-mode imports are not supported by design — that\n * would let a single corrupted manifest silently land partial state.\n */\nexport type ImportCapsuleMode = \"skip\" | \"overwrite\" | \"fork\";\n\n/**\n * Options accepted by {@link importCapsule}.\n *\n * `archivePath` — absolute or cwd-relative path to a `.capsule.json.gz`\n * archive produced by `exportCapsule`. The archive must contain a V2\n * bundle (`schemaVersion: 2`); V1 archives are rejected.\n *\n * `root` — absolute or cwd-relative path to the memory directory that\n * will receive the records. Must be an existing directory.\n *\n * `mode` — see {@link ImportCapsuleMode}. Defaults to `\"skip\"`.\n *\n * `versioning` — optional page-versioning config used by `mode: \"overwrite\"`\n * to snapshot prior content before replacing it. Snapshots are skipped when\n * not provided or when `enabled === false`. Tests pass an enabled config\n * to assert snapshot creation; production callers thread the\n * orchestrator's resolved versioning config.\n *\n * `log` — optional logger forwarded to {@link createVersion}.\n *\n * `now` — optional clock override (ms epoch) used to derive deterministic\n * fork ids in tests. Production callers omit this.\n */\nexport interface ImportCapsuleOptions {\n archivePath: string;\n root: string;\n mode?: ImportCapsuleMode;\n versioning?: VersioningConfig;\n log?: VersioningLogger;\n now?: number;\n /**\n * Memory directory whose secure-store keyring is used when the archive is\n * encrypted. Required when `archivePath` ends with `.enc` or when the file\n * starts with the REMNIC-ENC magic header. If `memoryDir` is omitted and the\n * archive turns out to be encrypted, `importCapsule` throws a clear error\n * rather than silently failing.\n *\n * When provided and the archive is NOT encrypted, the value is ignored.\n */\n memoryDir?: string;\n /**\n * Original secure-store passphrase for encrypted format-v2 archives. When\n * supplied, the importer derives the archive key from the embedded KDF\n * header, enabling restore without the source machine's unlocked keyring.\n */\n passphrase?: string;\n}\n\nexport interface ImportCapsuleSkippedRecord {\n /** Original record path (capsule-relative, posix). */\n path: string;\n /**\n * Why this record was not written.\n *\n * `\"exists\"` — the target path already existed and the mode was `\"skip\"`,\n * OR the computed fork path already existed in fork mode.\n *\n * `\"checksum_mismatch\"` is intentionally absent: a checksum failure aborts\n * the import entirely (fail-closed) rather than skipping the offending\n * record, so no `ImportCapsuleSkippedRecord` is ever produced for it.\n */\n reason: \"exists\";\n}\n\nexport interface ImportCapsuleImportedRecord {\n /** Capsule-relative posix path the record carried. */\n sourcePath: string;\n /** Memory-dir-relative posix path the file was written to. */\n targetPath: string;\n /** Whether a prior version snapshot was taken (overwrite-mode only). */\n snapshotted: boolean;\n /** Whether the frontmatter `id:` field was rewritten (fork-mode only). */\n rewroteId: boolean;\n}\n\nexport interface ImportCapsuleResult {\n /** Records that landed on disk. */\n imported: ImportCapsuleImportedRecord[];\n /** Records that were not written. */\n skipped: ImportCapsuleSkippedRecord[];\n /** The manifest decoded from the archive. */\n manifest: ExportManifestV2;\n}\n\n/**\n * Pure async function that imports a capsule archive into a memory\n * directory. Inverse of {@link import(\"./capsule-export.js\").exportCapsule}.\n *\n * Sequence:\n * 1. Read + gunzip + JSON.parse the archive.\n * 2. Validate the bundle through `parseExportBundle` (V1 rejected).\n * 3. Verify each record's content sha256 against the manifest entry.\n * Any mismatch aborts the import BEFORE any file is written —\n * partial-write recovery would require a full rollback we cannot\n * offer cheaply, so we fail closed (gotcha #25).\n * 4. Apply the selected {@link ImportCapsuleMode} to every record.\n *\n * Determinism guarantees:\n * - Imported records are returned sorted by `sourcePath`.\n * - Skipped records are returned sorted by `path`.\n * - Fork-mode rebases under a stable `forks/<capsule-id>/` prefix so\n * repeated fork imports of the same capsule shape land in predictable\n * locations (subsequent fork imports still skip-on-exist because the\n * target tree is computed from the source path).\n */\nexport async function importCapsule(\n opts: ImportCapsuleOptions,\n): Promise<ImportCapsuleResult> {\n const archiveAbs = path.resolve(opts.archivePath);\n const rootAbs = path.resolve(opts.root);\n await assertIsDirectoryNotSymlink(rootAbs, \"importCapsule\", \"root\");\n\n const mode: ImportCapsuleMode = opts.mode ?? \"skip\";\n // Reject unknown mode values up-front (rule 51). TypeScript callers get a\n // compile-time check via the union type; JS/CLI callers get a runtime error\n // here before any write begins — not a silent destructive fallback.\n if (mode !== \"skip\" && mode !== \"overwrite\" && mode !== \"fork\") {\n throw new Error(\n `importCapsule: unknown mode ${JSON.stringify(mode)}; expected \"skip\", \"overwrite\", or \"fork\"`,\n );\n }\n\n // Auto-detect encrypted archives. If the file ends with `.enc` or starts\n // with the REMNIC-ENC magic header, decrypt it first before gunzip+parse.\n // Rule 48: default is \"not encrypted\"; we only attempt decryption when the\n // header is definitively present, never on ambiguous content.\n const encrypted = await isEncryptedCapsuleFile(archiveAbs);\n let raw: Buffer;\n if (encrypted) {\n if (!opts.memoryDir && !opts.passphrase) {\n throw new Error(\n `importCapsule: archive is encrypted but 'memoryDir' was not provided. ` +\n `Pass the memory directory so the secure-store key can be retrieved, ` +\n `provide the original passphrase for a format-v2 archive restore, ` +\n `or run \\`remnic secure-store unlock\\` before importing.`,\n );\n }\n raw = await decryptCapsuleFileInMemory(archiveAbs, opts.memoryDir, {\n passphrase: opts.passphrase,\n });\n } else {\n raw = await readFile(archiveAbs);\n }\n const json = gunzipSync(raw).toString(\"utf-8\");\n let parsedJson: unknown;\n try {\n parsedJson = JSON.parse(json);\n } catch (cause) {\n throw new Error(\n `importCapsule: archive is not valid JSON after gunzip: ${archiveAbs}`,\n { cause: cause as Error },\n );\n }\n\n const parsed = parseExportBundle(parsedJson);\n if (parsed.capsuleVersion !== 2) {\n // PR 1/6 ships a V1 reader; capsule import is V2-only by design. A V1\n // bundle does not carry a capsule block, so fork-mode (which depends on\n // `capsule.id` for the rebase prefix) cannot work. Reject up-front per\n // gotcha #51 instead of silently routing to a different code path.\n throw new Error(\n \"importCapsule: archive is V1; only V2 capsule archives are supported\",\n );\n }\n const bundle = parsed.bundle as { manifest: ExportManifestV2; records: ExportMemoryRecordV1[] };\n const manifest = bundle.manifest;\n const capsule = manifest.capsule;\n\n // Build a path → manifest-entry index for O(1) checksum lookup. The\n // manifest is the source of truth; records-without-manifest-entries and\n // manifest-entries-without-records are both treated as corruption.\n const manifestIndex = new Map<string, ExportManifestV2[\"files\"][number]>();\n for (const f of manifest.files) {\n manifestIndex.set(f.path, f);\n }\n if (manifestIndex.size !== manifest.files.length) {\n throw new Error(\n \"importCapsule: manifest contains duplicate file paths\",\n );\n }\n const recordPaths = new Set<string>();\n for (const rec of bundle.records) {\n if (recordPaths.has(rec.path)) {\n throw new Error(\n `importCapsule: bundle contains duplicate record path: ${rec.path}`,\n );\n }\n recordPaths.add(rec.path);\n }\n\n // Phase 1: verify every record matches its manifest entry AND validate all\n // target paths before any filesystem mutation. We do both in a single pass\n // so a corrupted or malicious archive cannot leave the memory dir partially\n // written (fail-closed per gotcha #25).\n //\n // The real root is resolved once via realpath so the subsequent per-record\n // inside-root checks are symlink-aware: a record path like `facts/a.md`\n // cannot write outside the intended sandbox via a symlinked subdirectory\n // (Codex P1 feedback). If realpath fails (root does not exist) the earlier\n // assertIsDirectoryNotSymlink call already threw, so this should always succeed.\n const rootReal = await realpath(rootAbs).catch(() => rootAbs);\n\n // Tracks normalized, case-folded target paths seen so far in phase 1. Maps\n // targetAbs.toLowerCase() → first source path so the collision error can name\n // both offending entries. Two manifest entries whose computed target paths\n // normalize to the same absolute path (e.g. `subdir/file.md` and\n // `subdir/./file.md`, or differing case on case-insensitive filesystems such\n // as macOS and Windows) would both try to write the same inode — the second\n // would silently overwrite the first. We reject the import up-front before\n // any write (Codex P2 thread on PR #741, line 283).\n const seenTargetPaths = new Map<string, string>();\n\n for (const rec of bundle.records) {\n // Checksum validation.\n const entry = manifestIndex.get(rec.path);\n if (!entry) {\n throw new Error(\n `importCapsule: archive checksum mismatch (record without manifest entry: ${rec.path})`,\n );\n }\n const { sha256, bytes } = sha256String(rec.content);\n if (sha256 !== entry.sha256 || bytes !== entry.bytes) {\n throw new Error(\n `importCapsule: archive checksum mismatch for ${rec.path}: ` +\n `expected sha256=${entry.sha256} bytes=${entry.bytes}, ` +\n `got sha256=${sha256} bytes=${bytes}`,\n );\n }\n\n // Source path validation: reject any record whose posix source path\n // contains a `..` segment, an absolute prefix, or any component that would\n // let fork-mode bypass its isolation invariant. This check runs before\n // `computeTargetPath` so that fork mode's `forks/<id>/` rebase cannot be\n // bypassed by a path like `../../profile.md` (which `path.join` would\n // silently collapse, landing the file inside root but outside the fork\n // prefix — Cursor medium thread #741). Rejecting `..` up-front is simpler\n // and more robust than normalising after the fact.\n //\n // Extended guard (Codex P1 #741 round 5): also reject paths containing\n // backslash separators (`\\`), which are Windows path separators. On Windows\n // a path like `..\\\\escape.md` or `subdir\\\\..\\\\..\\\\escape.md` would resolve\n // to a parent traversal but would bypass a purely posix-split check.\n // Additionally, after posix-normalizing the path we re-check for a leading\n // `..` or `/` — this catches edge-cases such as `subdir/../..` where the\n // individual split segments are not `..` but the normalized result is.\n if (rec.path.includes(\"\\\\\")) {\n throw new Error(\n `importCapsule: record path contains backslash separators (Windows-style paths are not allowed): ${rec.path}`,\n );\n }\n const posixNormalized = path.posix.normalize(rec.path);\n if (\n rec.path.startsWith(\"/\") ||\n rec.path.split(\"/\").some((seg) => seg === \"..\") ||\n posixNormalized.startsWith(\"..\") ||\n posixNormalized.startsWith(\"/\")\n ) {\n throw new Error(\n `importCapsule: record path escapes target root: ${rec.path}`,\n );\n }\n\n // Path-traversal validation (moved here from phase 2 per Cursor feedback:\n // the traversal check must run before ANY write so a malicious archive\n // with an escaping path that sorts last cannot land partial writes).\n //\n // We build targetAbs relative to the real-resolved root (rootReal) so\n // that the inside-root check is symlink-aware: if `rootReal !== rootAbs`\n // (the import root is itself behind a symlink), we still compare against\n // the canonical path (Codex P1).\n const targetRel = computeTargetPath(rec.path, mode, capsule.id);\n const targetAbs = path.join(rootReal, fromPosixRelPath(targetRel));\n if (!isPathInsideRoot(rootReal, targetAbs)) {\n throw new Error(\n `importCapsule: record path escapes target root: ${rec.path}`,\n );\n }\n\n // Symlink-aware containment check (Cursor thread #741 line 247/264).\n // The lexical check above handles `..`-traversal but cannot detect\n // symlinked subdirectories that point outside the root. We resolve the\n // nearest existing ancestor of the target via realpath to catch symlinks\n // anywhere in the path components. If any resolved prefix escapes rootReal,\n // the import is rejected before any write. This applies to ALL modes,\n // including fork mode whose rebase prefix may itself traverse a symlink.\n await assertRealpathInsideRoot(rootReal, targetAbs, rec.path, \"importCapsule\");\n\n // Target-file symlink check (Codex P1 #741 round 4, line 260).\n // `assertRealpathInsideRoot` resolves the nearest existing *ancestor* to\n // catch symlinked parent directories, but if the TARGET FILE itself already\n // exists and is a symlink, that check passes (the parent is real) while the\n // write would silently follow the symlink to a path outside root. We\n // therefore lstat the target directly: if it exists and is a symlink we\n // reject the record up-front. For new files the parent-canonicalization\n // performed above is sufficient; no realpath of a non-existent file is\n // needed.\n const targetLstat = await lstat(targetAbs).catch(() => null);\n if (targetLstat !== null && targetLstat.isSymbolicLink()) {\n throw new Error(\n `importCapsule: record target is a symlink and cannot be written to safely: ${rec.path}`,\n );\n }\n\n // Duplicate normalized target path detection (Codex P2 #741, line 283).\n // `path.join` already normalises `.` segments (e.g. `subdir/./file.md` →\n // `subdir/file.md`). On case-insensitive filesystems (macOS default,\n // Windows), two paths that differ only in case would resolve to the same\n // inode. We fold the dedup key to lowercase so that `subdir/File.md` and\n // `subdir/file.md` are detected as duplicates before any write occurs.\n // This is intentionally unconditional: the cost of an extra `.toLowerCase()`\n // on case-sensitive filesystems is negligible, and a defensive lowercase\n // is far simpler than probing filesystem case-sensitivity at runtime.\n const dedupKey = targetAbs.toLowerCase();\n const firstSourcePath = seenTargetPaths.get(dedupKey);\n if (firstSourcePath !== undefined) {\n throw new Error(\n `importCapsule: manifest contains two entries that resolve to the same target path: ` +\n `\"${firstSourcePath}\" and \"${rec.path}\" both map to \"${targetRel}\"`,\n );\n }\n seenTargetPaths.set(dedupKey, rec.path);\n }\n // Detect manifest-only entries (missing record). Treat as corruption.\n for (const f of manifest.files) {\n if (!recordPaths.has(f.path)) {\n throw new Error(\n `importCapsule: archive checksum mismatch (manifest entry without record: ${f.path})`,\n );\n }\n }\n\n // Phase 2: apply the mode. All records were validated in phase 1; we now\n // write to disk. Per-record errors propagate; each individual write is\n // atomic (mkdir + writeFile pair).\n const imported: ImportCapsuleImportedRecord[] = [];\n const skipped: ImportCapsuleSkippedRecord[] = [];\n\n // Sort by source path so the imported/skipped lists are deterministic\n // regardless of bundle order. (`exportCapsule` already sorts; we re-sort\n // defensively in case a hand-edited archive ships records in another order.)\n const sortedRecords = [...bundle.records].sort((a, b) =>\n a.path.localeCompare(b.path),\n );\n\n for (const rec of sortedRecords) {\n const targetRel = computeTargetPath(rec.path, mode, capsule.id);\n // Use rootReal (realpath-resolved) to stay consistent with phase 1's\n // traversal validation and avoid writing through stale symlinks.\n const targetAbs = path.join(rootReal, fromPosixRelPath(targetRel));\n\n const exists = await fileExistsAt(targetAbs);\n\n // Skip logic applies to both `skip` mode (explicit) and `fork` mode\n // (Cursor medium: fork mode must also be skip-on-exist for the computed\n // fork path, because production imports generate non-deterministic IDs —\n // so re-importing the same capsule should not overwrite user edits in the\n // fork tree or silently change file identities by generating new IDs).\n if ((mode === \"skip\" || mode === \"fork\") && exists) {\n skipped.push({ path: rec.path, reason: \"exists\" });\n continue;\n }\n\n let snapshotted = false;\n if (mode === \"overwrite\" && exists) {\n // Gotcha #54: snapshot BEFORE overwriting. If snapshot creation fails\n // we abort this record's import rather than silently destroying\n // history. The page-versioning module is responsible for atomic\n // sidecar writes; we just call it.\n if (opts.versioning && opts.versioning.enabled) {\n const prior = await readFile(targetAbs, \"utf-8\").catch(() => \"\");\n await createVersion(\n targetAbs,\n prior,\n \"manual\",\n opts.versioning,\n opts.log,\n `capsule-import: ${capsule.id}`,\n rootReal,\n );\n snapshotted = true;\n }\n }\n\n let contentToWrite = rec.content;\n let rewroteId = false;\n if (mode === \"fork\") {\n const forked = rewriteFrontmatterIdForFork(rec.content, capsule.id, opts.now);\n contentToWrite = forked.content;\n rewroteId = forked.rewrote;\n }\n\n await mkdir(path.dirname(targetAbs), { recursive: true });\n await writeFile(targetAbs, contentToWrite, \"utf-8\");\n imported.push({\n sourcePath: rec.path,\n targetPath: targetRel,\n snapshotted,\n rewroteId,\n });\n }\n\n // Sort skipped for stable output (see comment above).\n skipped.sort((a, b) => a.path.localeCompare(b.path));\n\n return { imported, skipped, manifest };\n}\n\n// ---------------------------------------------------------------------------\n// Path helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Compute the destination relative path for a record under the chosen\n * mode.\n *\n * - `skip` / `overwrite` — identity: the record's posix path is used as-is.\n * - `fork` — rebased under `forks/<capsule-id>/<original-path>` so the\n * original tree is never modified.\n */\nfunction computeTargetPath(\n sourcePosix: string,\n mode: ImportCapsuleMode,\n capsuleId: string,\n): string {\n if (mode === \"fork\") return `forks/${capsuleId}/${sourcePosix}`;\n return sourcePosix;\n}\n\nasync function fileExistsAt(absPath: string): Promise<boolean> {\n const st = await stat(absPath).catch(() => null);\n return st !== null && st.isFile();\n}\n\n// ---------------------------------------------------------------------------\n// Fork-mode id rewriting\n// ---------------------------------------------------------------------------\n\n/**\n * Rewrite a YAML-frontmatter `id:` field to a fork-scoped value.\n *\n * Strategy: we deliberately do NOT parse the entire YAML — memory files\n * use a deterministic top-of-file frontmatter delimited by `---` lines,\n * and the orchestrator's `parseFrontmatter` reads `id` as a top-level\n * key with a single-line scalar value. We mirror that contract:\n *\n * - Detect a leading `---\\n` … `\\n---` block at the top of the file.\n * - Within that block, locate the first `id:` line that is not nested\n * under another key (cheap heuristic: line starts at column 0).\n * - Replace its value with a new fork-id derived from `capsuleId` and\n * a short random suffix (or {@link opts.now} when provided for tests).\n *\n * Files without a frontmatter block, or without an `id:` key inside one,\n * are returned unchanged with `rewrote: false`. This keeps non-memory\n * artifacts (READMEs, transcripts) byte-identical to the source.\n */\nfunction rewriteFrontmatterIdForFork(\n content: string,\n capsuleId: string,\n now: number | undefined,\n): { content: string; rewrote: boolean } {\n // Detect the dominant line ending in the file so we can preserve it when\n // rebuilding the frontmatter delimiters. Splitting/joining on `\\n` silently\n // drops `\\r` from CRLF files, changing the byte content (Cursor thread #741\n // line 467). We detect the ending of the very first line (the opening `---`)\n // and use that as the canonical separator for the reconstructed delimiters.\n // All three cases are covered: CRLF (\\r\\n), LF (\\n), and bare CR (\\r).\n const crlfMatch = /^---(\\r\\n|\\r|\\n)/.exec(content);\n // Fall back to LF if the file starts with `---` but has no newline (EOF).\n const eol = crlfMatch ? crlfMatch[1] : \"\\n\";\n\n // Frontmatter block detection: `---` on its own line at the very start,\n // followed by content, followed by `---` on its own line. The closing\n // delimiter must be at column 0. We capture the trailing terminator\n // (`\\r?\\n` or end-of-string) as a separate group so we can re-emit it\n // verbatim, preserving CRLF/LF/EOF shape from the original file.\n const fmMatch = /^---\\r?\\n([\\s\\S]*?)\\r?\\n---(\\r?\\n|$)/.exec(content);\n if (!fmMatch) return { content, rewrote: false };\n const fmBody = fmMatch[1];\n const fmTrailer = fmMatch[2];\n const fmStart = fmMatch.index;\n const fmEnd = fmStart + fmMatch[0].length;\n\n // Find a top-level `id:` line. Top-level means the line begins at\n // column 0 inside the frontmatter body (no leading whitespace) and the\n // key is exactly `id`. We deliberately accept `id:` and `id : ` shapes\n // but reject `nested_id:` to avoid touching unrelated keys.\n const idLineRe = /^id:[ \\t]*([^\\r\\n]*)$/m;\n const idMatch = idLineRe.exec(fmBody);\n if (!idMatch) return { content, rewrote: false };\n\n const newId = mintForkId(capsuleId, idMatch[1]?.trim() ?? \"\", now);\n const replacedBody = fmBody.replace(idLineRe, `id: ${newId}`);\n // Reconstruct the file: original prefix (always empty here, fmStart === 0\n // by the `^` anchor) + frontmatter delimiters around the rewritten body.\n // Use the detected `eol` for the opening/closing `---` lines so that CRLF\n // files remain CRLF and LF files remain LF, preserving byte-content fidelity\n // (Cursor thread #741 line 467). The captured `fmTrailer` (the newline\n // immediately after the closing `---`, or end-of-string) is re-emitted\n // verbatim so the byte immediately after the closing fence is unchanged.\n const prefix = content.slice(0, fmStart);\n const tail = content.slice(fmEnd);\n const rebuilt = `${prefix}---${eol}${replacedBody}${eol}---${fmTrailer}${tail}`;\n return { content: rebuilt, rewrote: true };\n}\n\n/**\n * Derive a deterministic-when-`now`-is-set fork id from the capsule id and\n * the original record id. Production callers omit `now` and get a UUID\n * suffix; tests pass `now` for byte-stable assertions.\n */\nfunction mintForkId(capsuleId: string, originalId: string, now: number | undefined): string {\n const base = originalId.length > 0 ? originalId : \"fork\";\n if (now === undefined) {\n const suffix = randomUUID().slice(0, 8);\n return `${base}-fork-${capsuleId}-${suffix}`;\n }\n // Deterministic suffix: short hash of (capsuleId, originalId, now). Using\n // sha256 over a sorted-key serialization (gotcha #38) so the suffix does\n // not depend on Object.entries order.\n const payload = JSON.stringify({ c: capsuleId, i: originalId, n: now });\n const suffix = createHash(\"sha256\").update(payload, \"utf-8\").digest(\"hex\").slice(0, 8);\n return `${base}-fork-${capsuleId}-${suffix}`;\n}\n\n// Note: `CapsuleBlock` is re-exported here purely so callers that want to\n// inspect the manifest block don't have to deep-import from `./types.js`.\nexport type { CapsuleBlock };\n"],"mappings":"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","names":["suffix"]}
@@ -155,34 +155,45 @@ var SessionObserverState = class {
155
155
  }
156
156
  async save() {
157
157
  await this.withSaveLock(async () => {
158
- const merged = /* @__PURE__ */ new Map();
159
- const persisted = await this.readPersistedState();
160
- if (persisted) {
161
- for (const [key, value] of this.normalizePersistedSessions(persisted.sessions).entries()) {
162
- merged.set(key, value);
163
- }
164
- }
165
- for (const [key, current] of this.sessions.entries()) {
166
- const existing = merged.get(key);
167
- if (!existing) {
168
- merged.set(key, current);
169
- continue;
170
- }
171
- merged.set(key, mergeSessionCursor(existing, current));
172
- }
158
+ const merged = await this.readMergedSessions();
173
159
  this.sessions = merged;
174
- const sessions = {};
175
- for (const [key, value] of merged.entries()) {
176
- sessions[key] = value;
177
- }
178
- const payload = { version: 1, sessions };
179
- await mkdir(path.dirname(this.statePath), { recursive: true });
180
- await writeFile(this.statePath, JSON.stringify(payload, null, 2), "utf-8");
160
+ await this.writeSessions(merged);
181
161
  });
182
162
  }
183
- enqueueSave() {
184
- this.saveQueue = this.saveQueue.catch(() => void 0).then(() => this.save());
185
- return this.saveQueue;
163
+ async readMergedSessions() {
164
+ const merged = /* @__PURE__ */ new Map();
165
+ const persisted = await this.readPersistedState();
166
+ if (persisted) {
167
+ for (const [key, value] of this.normalizePersistedSessions(persisted.sessions).entries()) {
168
+ merged.set(key, value);
169
+ }
170
+ }
171
+ for (const [key, current] of this.sessions.entries()) {
172
+ const existing = merged.get(key);
173
+ if (!existing) {
174
+ merged.set(key, current);
175
+ continue;
176
+ }
177
+ merged.set(key, mergeSessionCursor(existing, current));
178
+ }
179
+ return merged;
180
+ }
181
+ async writeSessions(sessionsMap) {
182
+ const sessions = {};
183
+ for (const [key, value] of sessionsMap.entries()) {
184
+ sessions[key] = value;
185
+ }
186
+ const payload = { version: 1, sessions };
187
+ await mkdir(path.dirname(this.statePath), { recursive: true });
188
+ await writeFile(this.statePath, JSON.stringify(payload, null, 2), "utf-8");
189
+ }
190
+ enqueueObservation(input) {
191
+ const operation = this.saveQueue.catch(() => void 0).then(() => this.observeWithSaveLock(input));
192
+ this.saveQueue = operation.then(
193
+ () => void 0,
194
+ () => void 0
195
+ );
196
+ return operation;
186
197
  }
187
198
  bandForTotalBytes(totalBytes) {
188
199
  const bytes = sanitizeNonNegativeInt(totalBytes);
@@ -192,19 +203,39 @@ var SessionObserverState = class {
192
203
  return this.bands[this.bands.length - 1];
193
204
  }
194
205
  async observe(input) {
206
+ return this.enqueueObservation(input);
207
+ }
208
+ async observeWithSaveLock(input) {
209
+ let decision;
210
+ await this.withSaveLock(async () => {
211
+ const localExisting = this.sessions.get(input.sessionKey);
212
+ const sessions = await this.readMergedSessions();
213
+ decision = await this.observeMerged(
214
+ input,
215
+ sessions,
216
+ localExisting ? { ...localExisting } : void 0
217
+ );
218
+ });
219
+ if (!decision) {
220
+ throw new Error("session observer decision was not computed");
221
+ }
222
+ return decision;
223
+ }
224
+ async observeMerged(input, sessions, localExisting) {
195
225
  const nowIso = input.observedAt ?? (/* @__PURE__ */ new Date()).toISOString();
196
226
  const totalBytes = sanitizeNonNegativeInt(input.totalBytes);
197
227
  const totalTokens = sanitizeNonNegativeInt(input.totalTokens);
198
228
  const band = this.bandForTotalBytes(totalBytes);
199
- const existing = this.sessions.get(input.sessionKey);
229
+ const existing = sessions.get(input.sessionKey);
200
230
  if (!existing) {
201
- this.sessions.set(input.sessionKey, {
231
+ sessions.set(input.sessionKey, {
202
232
  sessionKey: input.sessionKey,
203
233
  cursorBytes: totalBytes,
204
234
  cursorTokens: totalTokens,
205
235
  lastObservedAt: nowIso
206
236
  });
207
- await this.enqueueSave();
237
+ this.sessions = sessions;
238
+ await this.writeSessions(sessions);
208
239
  return {
209
240
  triggered: false,
210
241
  deltaBytes: 0,
@@ -214,13 +245,27 @@ var SessionObserverState = class {
214
245
  };
215
246
  }
216
247
  const session = { ...existing };
248
+ const observedMs = parseIsoMs(nowIso);
249
+ const existingObservedMs = parseIsoMs(session.lastObservedAt);
250
+ const existingResetMs = parseIsoMs(session.lastResetAt);
251
+ if (existingResetMs > 0 && observedMs < existingResetMs) {
252
+ this.sessions = sessions;
253
+ return { triggered: false, deltaBytes: 0, deltaTokens: 0, band, reason: "baseline" };
254
+ }
217
255
  if (totalBytes < session.cursorBytes || totalTokens < session.cursorTokens) {
218
- session.cursorBytes = totalBytes;
219
- session.cursorTokens = totalTokens;
220
- session.lastObservedAt = nowIso;
221
- session.lastResetAt = nowIso;
222
- this.sessions.set(input.sessionKey, session);
223
- await this.enqueueSave();
256
+ const localSawReset = localExisting !== void 0 && (totalBytes < sanitizeNonNegativeInt(localExisting.cursorBytes) || totalTokens < sanitizeNonNegativeInt(localExisting.cursorTokens));
257
+ const canApplyReset = localSawReset && observedMs >= existingObservedMs;
258
+ if (canApplyReset) {
259
+ session.cursorBytes = totalBytes;
260
+ session.cursorTokens = totalTokens;
261
+ session.lastObservedAt = nowIso;
262
+ session.lastResetAt = nowIso;
263
+ } else if (observedMs >= existingObservedMs) {
264
+ session.lastObservedAt = nowIso;
265
+ }
266
+ sessions.set(input.sessionKey, session);
267
+ this.sessions = sessions;
268
+ await this.writeSessions(sessions);
224
269
  return { triggered: false, deltaBytes: 0, deltaTokens: 0, band, reason: "baseline" };
225
270
  }
226
271
  const deltaBytes = totalBytes - session.cursorBytes;
@@ -230,8 +275,11 @@ var SessionObserverState = class {
230
275
  if (!crossedThreshold) {
231
276
  const unchanged = deltaBytes === 0 && deltaTokens === 0;
232
277
  if (!unchanged) {
233
- this.sessions.set(input.sessionKey, session);
234
- await this.enqueueSave();
278
+ sessions.set(input.sessionKey, session);
279
+ this.sessions = sessions;
280
+ await this.writeSessions(sessions);
281
+ } else {
282
+ this.sessions = sessions;
235
283
  }
236
284
  return {
237
285
  triggered: false,
@@ -244,8 +292,9 @@ var SessionObserverState = class {
244
292
  const lastTriggeredMs = session.lastTriggeredAt ? Date.parse(session.lastTriggeredAt) : NaN;
245
293
  const withinDebounce = Number.isFinite(lastTriggeredMs) && nowMs - lastTriggeredMs < this.debounceMs;
246
294
  if (withinDebounce) {
247
- this.sessions.set(input.sessionKey, session);
248
- await this.enqueueSave();
295
+ sessions.set(input.sessionKey, session);
296
+ this.sessions = sessions;
297
+ await this.writeSessions(sessions);
249
298
  return {
250
299
  triggered: false,
251
300
  deltaBytes,
@@ -257,8 +306,9 @@ var SessionObserverState = class {
257
306
  session.lastTriggeredAt = nowIso;
258
307
  session.cursorBytes = totalBytes;
259
308
  session.cursorTokens = totalTokens;
260
- this.sessions.set(input.sessionKey, session);
261
- await this.enqueueSave();
309
+ sessions.set(input.sessionKey, session);
310
+ this.sessions = sessions;
311
+ await this.writeSessions(sessions);
262
312
  return {
263
313
  triggered: true,
264
314
  deltaBytes,
@@ -273,4 +323,4 @@ export {
273
323
  normalizeObserverBands,
274
324
  SessionObserverState
275
325
  };
276
- //# sourceMappingURL=chunk-JR4ZC3G4.js.map
326
+ //# sourceMappingURL=chunk-DLJ4IR6M.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/session-observer-state.ts"],"sourcesContent":["import path from \"node:path\";\nimport { mkdir, open, readFile, stat, unlink, writeFile } from \"node:fs/promises\";\nimport { log } from \"./logger.js\";\nimport type { SessionObserverBandConfig } from \"./types.js\";\nimport { cloneDefaultSessionObserverBands } from \"./session-observer-bands.js\";\n\ninterface SessionObserverCursor {\n sessionKey: string;\n cursorBytes: number;\n cursorTokens: number;\n lastObservedAt: string;\n lastTriggeredAt?: string;\n lastResetAt?: string;\n}\n\ninterface SessionObserverPersistedState {\n version: 1;\n sessions: Record<string, SessionObserverCursor>;\n}\n\nexport interface SessionObservationInput {\n sessionKey: string;\n totalBytes: number;\n totalTokens: number;\n observedAt?: string;\n}\n\nexport interface SessionObservationDecision {\n triggered: boolean;\n deltaBytes: number;\n deltaTokens: number;\n band: SessionObserverBandConfig;\n reason?: \"threshold\" | \"debounced\" | \"baseline\";\n}\n\nfunction sanitizeNonNegativeInt(value: number): number {\n if (!Number.isFinite(value)) return 0;\n return Math.max(0, Math.floor(value));\n}\n\nfunction parseIsoMs(value?: string): number {\n if (!value) return 0;\n const ms = Date.parse(value);\n return Number.isFinite(ms) ? ms : 0;\n}\n\nfunction mergeSessionCursor(\n existing: SessionObserverCursor,\n incoming: SessionObserverCursor,\n): SessionObserverCursor {\n const existingObservedMs = parseIsoMs(existing.lastObservedAt);\n const incomingObservedMs = parseIsoMs(incoming.lastObservedAt);\n const existingTriggeredMs = parseIsoMs(existing.lastTriggeredAt);\n const incomingTriggeredMs = parseIsoMs(incoming.lastTriggeredAt);\n const existingResetMs = parseIsoMs(existing.lastResetAt);\n const incomingResetMs = parseIsoMs(incoming.lastResetAt);\n\n const observedAt =\n incomingObservedMs >= existingObservedMs ? incoming.lastObservedAt : existing.lastObservedAt;\n const triggeredAt =\n incomingTriggeredMs >= existingTriggeredMs ? incoming.lastTriggeredAt : existing.lastTriggeredAt;\n\n // Preserve monotonic cursor progression except for explicit reset observations.\n const incomingIsNewer = incomingObservedMs >= existingObservedMs;\n const incomingHasNewerReset = incomingResetMs > existingResetMs;\n const allowIncomingReset = incomingIsNewer && incomingHasNewerReset;\n const keepExistingReset =\n existingResetMs > incomingResetMs && existingObservedMs >= incomingObservedMs;\n\n let cursorBytes = Math.max(\n sanitizeNonNegativeInt(existing.cursorBytes),\n sanitizeNonNegativeInt(incoming.cursorBytes),\n );\n let cursorTokens = Math.max(\n sanitizeNonNegativeInt(existing.cursorTokens),\n sanitizeNonNegativeInt(incoming.cursorTokens),\n );\n if (keepExistingReset) {\n cursorBytes = sanitizeNonNegativeInt(existing.cursorBytes);\n cursorTokens = sanitizeNonNegativeInt(existing.cursorTokens);\n } else if (allowIncomingReset) {\n cursorBytes = sanitizeNonNegativeInt(incoming.cursorBytes);\n cursorTokens = sanitizeNonNegativeInt(incoming.cursorTokens);\n }\n\n return {\n sessionKey: existing.sessionKey,\n cursorBytes,\n cursorTokens,\n lastObservedAt: observedAt,\n lastTriggeredAt: triggeredAt,\n lastResetAt:\n incomingResetMs >= existingResetMs ? incoming.lastResetAt : existing.lastResetAt,\n };\n}\n\nexport function normalizeObserverBands(\n bands: SessionObserverBandConfig[],\n): SessionObserverBandConfig[] {\n const normalized = bands\n .map((band) => ({\n maxBytes: sanitizeNonNegativeInt(band.maxBytes),\n triggerDeltaBytes: sanitizeNonNegativeInt(band.triggerDeltaBytes),\n triggerDeltaTokens: sanitizeNonNegativeInt(band.triggerDeltaTokens),\n }))\n .filter((band) => band.maxBytes > 0)\n .sort((a, b) => a.maxBytes - b.maxBytes);\n\n if (normalized.length === 0) {\n return cloneDefaultSessionObserverBands();\n }\n\n const last = normalized[normalized.length - 1];\n if (last && last.maxBytes < 1_000_000_000) {\n normalized.push({\n maxBytes: 1_000_000_000,\n triggerDeltaBytes: last.triggerDeltaBytes,\n triggerDeltaTokens: last.triggerDeltaTokens,\n });\n }\n return normalized;\n}\n\nexport class SessionObserverState {\n private readonly statePath: string;\n private readonly lockPath: string;\n private readonly lockStaleMs = 120_000;\n private readonly debounceMs: number;\n private readonly bands: SessionObserverBandConfig[];\n private sessions = new Map<string, SessionObserverCursor>();\n private saveQueue: Promise<void> = Promise.resolve();\n\n private async readPersistedState(): Promise<SessionObserverPersistedState | null> {\n try {\n const raw = await readFile(this.statePath, \"utf-8\");\n const parsed = JSON.parse(raw) as SessionObserverPersistedState;\n if (parsed?.version !== 1 || !parsed.sessions || typeof parsed.sessions !== \"object\") {\n return null;\n }\n return parsed;\n } catch {\n return null;\n }\n }\n\n private normalizePersistedSessions(\n sessions: Record<string, SessionObserverCursor>,\n ): Map<string, SessionObserverCursor> {\n const next = new Map<string, SessionObserverCursor>();\n for (const [sessionKey, value] of Object.entries(sessions)) {\n if (!value || typeof value !== \"object\") continue;\n next.set(sessionKey, {\n sessionKey,\n cursorBytes: sanitizeNonNegativeInt(value.cursorBytes),\n cursorTokens: sanitizeNonNegativeInt(value.cursorTokens),\n lastObservedAt:\n typeof value.lastObservedAt === \"string\" ? value.lastObservedAt : new Date(0).toISOString(),\n lastTriggeredAt: typeof value.lastTriggeredAt === \"string\" ? value.lastTriggeredAt : undefined,\n lastResetAt: typeof value.lastResetAt === \"string\" ? value.lastResetAt : undefined,\n });\n }\n return next;\n }\n\n constructor(opts: {\n memoryDir: string;\n debounceMs: number;\n bands: SessionObserverBandConfig[];\n }) {\n this.statePath = path.join(opts.memoryDir, \"state\", \"session-observer-state.json\");\n this.lockPath = path.join(opts.memoryDir, \"state\", \"session-observer-state.lock\");\n this.debounceMs = Math.max(0, Math.floor(opts.debounceMs));\n this.bands = normalizeObserverBands(opts.bands);\n }\n\n private async withSaveLock(fn: () => Promise<void>): Promise<void> {\n await mkdir(path.dirname(this.lockPath), { recursive: true });\n for (let attempt = 0; attempt < 80; attempt++) {\n try {\n const handle = await open(this.lockPath, \"wx\");\n try {\n await fn();\n } finally {\n await handle.close();\n await unlink(this.lockPath).catch(() => {});\n }\n return;\n } catch (err: any) {\n if (err?.code !== \"EEXIST\") throw err;\n try {\n const lockInfo = await stat(this.lockPath);\n if (Date.now() - lockInfo.mtimeMs > this.lockStaleMs) {\n await unlink(this.lockPath).catch(() => {});\n continue;\n }\n } catch {\n // Lock might have been released between EEXIST and stat/read.\n }\n await new Promise((resolve) => setTimeout(resolve, 25));\n }\n }\n const error = new Error(\"session observer save lock timeout\");\n log.debug(error.message);\n throw error;\n }\n\n async load(): Promise<void> {\n const parsed = await this.readPersistedState();\n if (!parsed) {\n this.sessions.clear();\n return;\n }\n this.sessions = this.normalizePersistedSessions(parsed.sessions);\n }\n\n async save(): Promise<void> {\n await this.withSaveLock(async () => {\n const merged = await this.readMergedSessions();\n this.sessions = merged;\n\n await this.writeSessions(merged);\n });\n }\n\n private async readMergedSessions(): Promise<Map<string, SessionObserverCursor>> {\n const merged = new Map<string, SessionObserverCursor>();\n const persisted = await this.readPersistedState();\n if (persisted) {\n for (const [key, value] of this.normalizePersistedSessions(persisted.sessions).entries()) {\n merged.set(key, value);\n }\n }\n for (const [key, current] of this.sessions.entries()) {\n const existing = merged.get(key);\n if (!existing) {\n merged.set(key, current);\n continue;\n }\n merged.set(key, mergeSessionCursor(existing, current));\n }\n return merged;\n }\n\n private async writeSessions(sessionsMap: Map<string, SessionObserverCursor>): Promise<void> {\n const sessions: Record<string, SessionObserverCursor> = {};\n for (const [key, value] of sessionsMap.entries()) {\n sessions[key] = value;\n }\n const payload: SessionObserverPersistedState = { version: 1, sessions };\n await mkdir(path.dirname(this.statePath), { recursive: true });\n await writeFile(this.statePath, JSON.stringify(payload, null, 2), \"utf-8\");\n }\n\n private enqueueObservation(\n input: SessionObservationInput,\n ): Promise<SessionObservationDecision> {\n const operation = this.saveQueue\n .catch(() => undefined)\n .then(() => this.observeWithSaveLock(input));\n this.saveQueue = operation.then(\n () => undefined,\n () => undefined,\n );\n return operation;\n }\n\n private bandForTotalBytes(totalBytes: number): SessionObserverBandConfig {\n const bytes = sanitizeNonNegativeInt(totalBytes);\n for (const band of this.bands) {\n if (bytes <= band.maxBytes) return band;\n }\n return this.bands[this.bands.length - 1];\n }\n\n async observe(input: SessionObservationInput): Promise<SessionObservationDecision> {\n return this.enqueueObservation(input);\n }\n\n private async observeWithSaveLock(\n input: SessionObservationInput,\n ): Promise<SessionObservationDecision> {\n let decision: SessionObservationDecision | undefined;\n await this.withSaveLock(async () => {\n const localExisting = this.sessions.get(input.sessionKey);\n const sessions = await this.readMergedSessions();\n decision = await this.observeMerged(\n input,\n sessions,\n localExisting ? { ...localExisting } : undefined,\n );\n });\n if (!decision) {\n throw new Error(\"session observer decision was not computed\");\n }\n return decision;\n }\n\n private async observeMerged(\n input: SessionObservationInput,\n sessions: Map<string, SessionObserverCursor>,\n localExisting?: SessionObserverCursor,\n ): Promise<SessionObservationDecision> {\n const nowIso = input.observedAt ?? new Date().toISOString();\n const totalBytes = sanitizeNonNegativeInt(input.totalBytes);\n const totalTokens = sanitizeNonNegativeInt(input.totalTokens);\n const band = this.bandForTotalBytes(totalBytes);\n\n const existing = sessions.get(input.sessionKey);\n if (!existing) {\n sessions.set(input.sessionKey, {\n sessionKey: input.sessionKey,\n cursorBytes: totalBytes,\n cursorTokens: totalTokens,\n lastObservedAt: nowIso,\n });\n this.sessions = sessions;\n await this.writeSessions(sessions);\n return {\n triggered: false,\n deltaBytes: 0,\n deltaTokens: 0,\n band,\n reason: \"baseline\",\n };\n }\n\n const session = { ...existing };\n const observedMs = parseIsoMs(nowIso);\n const existingObservedMs = parseIsoMs(session.lastObservedAt);\n const existingResetMs = parseIsoMs(session.lastResetAt);\n if (existingResetMs > 0 && observedMs < existingResetMs) {\n this.sessions = sessions;\n return { triggered: false, deltaBytes: 0, deltaTokens: 0, band, reason: \"baseline\" };\n }\n\n if (totalBytes < session.cursorBytes || totalTokens < session.cursorTokens) {\n const localSawReset =\n localExisting !== undefined\n && (totalBytes < sanitizeNonNegativeInt(localExisting.cursorBytes)\n || totalTokens < sanitizeNonNegativeInt(localExisting.cursorTokens));\n const canApplyReset = localSawReset && observedMs >= existingObservedMs;\n\n if (canApplyReset) {\n session.cursorBytes = totalBytes;\n session.cursorTokens = totalTokens;\n session.lastObservedAt = nowIso;\n session.lastResetAt = nowIso;\n } else if (observedMs >= existingObservedMs) {\n session.lastObservedAt = nowIso;\n }\n sessions.set(input.sessionKey, session);\n this.sessions = sessions;\n await this.writeSessions(sessions);\n return { triggered: false, deltaBytes: 0, deltaTokens: 0, band, reason: \"baseline\" };\n }\n\n const deltaBytes = totalBytes - session.cursorBytes;\n const deltaTokens = totalTokens - session.cursorTokens;\n const crossedThreshold =\n (band.triggerDeltaBytes > 0 && deltaBytes >= band.triggerDeltaBytes)\n || (band.triggerDeltaTokens > 0 && deltaTokens >= band.triggerDeltaTokens);\n session.lastObservedAt = nowIso;\n\n if (!crossedThreshold) {\n const unchanged = deltaBytes === 0 && deltaTokens === 0;\n if (!unchanged) {\n sessions.set(input.sessionKey, session);\n this.sessions = sessions;\n await this.writeSessions(sessions);\n } else {\n this.sessions = sessions;\n }\n return {\n triggered: false,\n deltaBytes,\n deltaTokens,\n band,\n };\n }\n\n const nowMs = Date.parse(nowIso);\n const lastTriggeredMs = session.lastTriggeredAt ? Date.parse(session.lastTriggeredAt) : NaN;\n const withinDebounce =\n Number.isFinite(lastTriggeredMs) && nowMs - lastTriggeredMs < this.debounceMs;\n\n if (withinDebounce) {\n sessions.set(input.sessionKey, session);\n this.sessions = sessions;\n await this.writeSessions(sessions);\n return {\n triggered: false,\n deltaBytes,\n deltaTokens,\n band,\n reason: \"debounced\",\n };\n }\n\n session.lastTriggeredAt = nowIso;\n session.cursorBytes = totalBytes;\n session.cursorTokens = totalTokens;\n sessions.set(input.sessionKey, session);\n this.sessions = sessions;\n await this.writeSessions(sessions);\n return {\n triggered: true,\n deltaBytes,\n deltaTokens,\n band,\n reason: \"threshold\",\n };\n }\n}\n"],"mappings":"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","names":[]}
@@ -1,12 +1,13 @@
1
1
  import {
2
2
  expandTildePath
3
- } from "./chunk-QRNI5JBH.js";
3
+ } from "./chunk-EYIEWJNI.js";
4
4
  import {
5
5
  log
6
6
  } from "./chunk-2ODBA7MQ.js";
7
7
 
8
8
  // src/shared-context/manager.ts
9
- import { mkdir, readFile, readdir, appendFile, writeFile, stat } from "fs/promises";
9
+ import { randomUUID } from "crypto";
10
+ import { mkdir, readFile, readdir, appendFile, writeFile, stat, rename, rm } from "fs/promises";
10
11
  import path from "path";
11
12
  import { z } from "zod";
12
13
  var SharedFeedbackEntrySchema = z.object({
@@ -79,6 +80,16 @@ function readFrontmatterScalar(raw, key) {
79
80
  function ymd(d) {
80
81
  return d.toISOString().slice(0, 10);
81
82
  }
83
+ function safeDateSegment(date) {
84
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
85
+ throw new Error(`Invalid shared-context date: ${JSON.stringify(date)}; expected YYYY-MM-DD`);
86
+ }
87
+ const parsed = /* @__PURE__ */ new Date(`${date}T00:00:00.000Z`);
88
+ if (!Number.isFinite(parsed.getTime()) || parsed.toISOString().slice(0, 10) !== date) {
89
+ throw new Error(`Invalid shared-context date: ${JSON.stringify(date)}; expected a real calendar date`);
90
+ }
91
+ return date;
92
+ }
82
93
  var CROSS_SIGNAL_STOPWORDS = /* @__PURE__ */ new Set([
83
94
  "a",
84
95
  "an",
@@ -278,14 +289,34 @@ function feedbackSeverityPriority(severity) {
278
289
  function compareFeedbackPriority(a, b) {
279
290
  return feedbackDecisionPriority(b.decision) - feedbackDecisionPriority(a.decision) || feedbackSeverityPriority(b.severity) - feedbackSeverityPriority(a.severity) || a.date.localeCompare(b.date);
280
291
  }
292
+ function markdownLineText(value) {
293
+ return value.replace(/[\r\n]+/g, " ").replace(/\s+/g, " ").trim();
294
+ }
295
+ function markdownLineList(values) {
296
+ return values.map(markdownLineText).filter(Boolean).join(", ");
297
+ }
281
298
  function formatFeedbackLine(entry) {
282
- const extras = [`feedback: ${entry.date}`];
283
- if (entry.severity) extras.push(`severity: ${entry.severity}`);
284
- if (entry.refs?.length) extras.push(`refs: ${entry.refs.join(", ")}`);
285
- return `- [${entry.agent}] ${entry.decision}: ${entry.reason} [${extras.join("; ")}]`;
299
+ const extras = [`feedback: ${markdownLineText(entry.date)}`];
300
+ if (entry.severity) extras.push(`severity: ${markdownLineText(entry.severity)}`);
301
+ if (entry.refs?.length) extras.push(`refs: ${markdownLineList(entry.refs)}`);
302
+ return `- [${markdownLineText(entry.agent)}] ${entry.decision}: ${markdownLineText(entry.reason)} [${extras.join("; ")}]`;
286
303
  }
287
304
  function formatOverlapLine(entry) {
288
- return `- \`${entry.token}\` (${entry.agentCount} agents: ${entry.agents.join(", ")}) [sources: ${entry.sourcePaths.join(", ")}]`;
305
+ return `- \`${entry.token}\` (${entry.agentCount} agents: ${markdownLineList(entry.agents)}) [sources: ${markdownLineList(entry.sourcePaths)}]`;
306
+ }
307
+ async function writeFileAtomic(filePath, content) {
308
+ await mkdir(path.dirname(filePath), { recursive: true });
309
+ const tempPath = path.join(
310
+ path.dirname(filePath),
311
+ `.${path.basename(filePath)}.${process.pid}.${randomUUID()}.tmp`
312
+ );
313
+ try {
314
+ await writeFile(tempPath, content, { encoding: "utf-8", flag: "wx" });
315
+ await rename(tempPath, filePath);
316
+ } catch (error) {
317
+ await rm(tempPath, { force: true }).catch(() => void 0);
318
+ throw error;
319
+ }
289
320
  }
290
321
  function resolveSharedContextDir(config) {
291
322
  return typeof config.sharedContextDir === "string" && config.sharedContextDir.length > 0 ? expandTildePath(config.sharedContextDir) : path.join(expandTildePath(config.workspaceDir), "shared-context");
@@ -312,6 +343,7 @@ var SharedContextManager = class {
312
343
  feedbackDir;
313
344
  feedbackInboxPath;
314
345
  crossSignalsDir;
346
+ dailySynthesisChains = /* @__PURE__ */ new Map();
315
347
  async ensureStructure() {
316
348
  await mkdir(this.dir, { recursive: true });
317
349
  await mkdir(this.outputsDir, { recursive: true });
@@ -426,12 +458,37 @@ title: ${formatFrontmatterScalar(opts.title.replace(/\n/g, " ").slice(0, 200))}
426
458
  ].join("\n");
427
459
  await appendFile(this.prioritiesInboxPath, lines, "utf-8");
428
460
  }
461
+ async withDailySynthesisLock(date, fn) {
462
+ const previous = this.dailySynthesisChains.get(date) ?? Promise.resolve();
463
+ let releaseCurrent;
464
+ const current = new Promise((resolve) => {
465
+ releaseCurrent = resolve;
466
+ });
467
+ const queued = previous.catch(() => void 0).then(() => current);
468
+ this.dailySynthesisChains.set(date, queued);
469
+ await previous.catch(() => void 0);
470
+ try {
471
+ return await fn();
472
+ } finally {
473
+ releaseCurrent();
474
+ if (this.dailySynthesisChains.get(date) === queued) {
475
+ this.dailySynthesisChains.delete(date);
476
+ }
477
+ }
478
+ }
429
479
  async synthesizeCrossSignals(opts) {
430
- const date = opts.date ?? ymd(/* @__PURE__ */ new Date());
480
+ const date = safeDateSegment(opts.date ?? ymd(/* @__PURE__ */ new Date()));
481
+ return this.withDailySynthesisLock(date, () => this.synthesizeCrossSignalsUnlocked({
482
+ date,
483
+ maxSummaryItems: opts.maxSummaryItems
484
+ }));
485
+ }
486
+ async synthesizeCrossSignalsUnlocked(opts) {
487
+ const date = opts.date;
431
488
  const maxSummaryItems = Math.max(1, opts.maxSummaryItems ?? 8);
432
489
  const outputs = [];
433
490
  try {
434
- const agents = await readdir(this.outputsDir, { withFileTypes: true });
491
+ const agents = (await readdir(this.outputsDir, { withFileTypes: true })).sort((a, b) => a.name.localeCompare(b.name));
435
492
  for (const a of agents) {
436
493
  if (!a.isDirectory()) continue;
437
494
  const dayDir = path.join(this.outputsDir, a.name, date);
@@ -449,6 +506,9 @@ title: ${formatFrontmatterScalar(opts.title.replace(/\n/g, " ").slice(0, 200))}
449
506
  }
450
507
  } catch {
451
508
  }
509
+ outputs.sort(
510
+ (a, b) => a.agent.localeCompare(b.agent) || a.path.localeCompare(b.path) || a.title.localeCompare(b.title)
511
+ );
452
512
  const feedback = [];
453
513
  try {
454
514
  const raw = await readFile(this.feedbackInboxPath, "utf-8");
@@ -548,14 +608,14 @@ ${body}`)
548
608
  }
549
609
  };
550
610
  const crossSignalsPath = path.join(this.crossSignalsDir, `${date}.json`);
551
- await writeFile(crossSignalsPath, `${JSON.stringify(report, null, 2)}
552
- `, "utf-8");
611
+ await writeFileAtomic(crossSignalsPath, `${JSON.stringify(report, null, 2)}
612
+ `);
553
613
  const recurringThemeLines = mergedOverlaps.length === 0 ? ["- No multi-agent topic overlap detected."] : mergedOverlaps.slice(0, maxSummaryItems).map((entry) => formatOverlapLine(entry));
554
614
  const riskSignals = [...feedback].filter((entry) => entry.decision !== "approved" || entry.severity === "high" || entry.severity === "medium").sort(compareFeedbackPriority).slice(0, maxSummaryItems);
555
615
  const riskLines = riskSignals.length === 0 ? ["- No explicit blockers or elevated review risks recorded."] : riskSignals.map((entry) => formatFeedbackLine(entry));
556
616
  const promotionCandidates = mergedOverlaps.filter((entry) => entry.agentCount >= 3).slice(0, maxSummaryItems);
557
617
  const promotionLines = promotionCandidates.length === 0 ? ["- No promotion candidates yet."] : promotionCandidates.map(
558
- (entry) => `- Consider promoting \`${entry.token}\` into priorities or operating rules [sources: ${entry.sourcePaths.join(", ")}]`
618
+ (entry) => `- Consider promoting \`${entry.token}\` into priorities or operating rules [sources: ${markdownLineList(entry.sourcePaths)}]`
559
619
  );
560
620
  const crossSignalsMarkdown = [
561
621
  `# Cross-Signals \u2014 ${date}`,
@@ -578,12 +638,12 @@ ${body}`)
578
638
  "",
579
639
  "## Sources",
580
640
  ...sources.length === 0 ? ["- (none)"] : sources.map(
581
- (source) => `- [${source.agent}] ${source.title} (${source.path})`
641
+ (source) => `- [${markdownLineText(source.agent)}] ${markdownLineText(source.title)} (${markdownLineText(source.path)})`
582
642
  ),
583
643
  ""
584
644
  ].join("\n");
585
645
  const crossSignalsMarkdownPath = path.join(this.crossSignalsDir, `${date}.md`);
586
- await writeFile(crossSignalsMarkdownPath, crossSignalsMarkdown, "utf-8");
646
+ await writeFileAtomic(crossSignalsMarkdownPath, crossSignalsMarkdown);
587
647
  return {
588
648
  date,
589
649
  crossSignalsPath,
@@ -593,9 +653,13 @@ ${body}`)
593
653
  };
594
654
  }
595
655
  async curateDaily(opts) {
596
- const date = opts.date ?? ymd(/* @__PURE__ */ new Date());
656
+ const date = safeDateSegment(opts.date ?? ymd(/* @__PURE__ */ new Date()));
657
+ return this.withDailySynthesisLock(date, () => this.curateDailyUnlocked({ ...opts, date }));
658
+ }
659
+ async curateDailyUnlocked(opts) {
660
+ const date = opts.date;
597
661
  const maxChars = Math.max(2e3, opts.maxChars ?? 2e4);
598
- const crossSignals = await this.synthesizeCrossSignals({ date });
662
+ const crossSignals = await this.synthesizeCrossSignalsUnlocked({ date });
599
663
  const feedbackLines = crossSignals.report.feedbackEntries.length === 0 ? ["- (none)"] : crossSignals.report.feedbackEntries.map((entry) => formatFeedbackLine(entry));
600
664
  const overlapBullets = crossSignals.report.overlaps.length === 0 ? ["- No multi-agent topic overlap detected."] : crossSignals.report.overlaps.slice(0, 8).map((entry) => formatOverlapLine(entry));
601
665
  const md = [
@@ -620,7 +684,7 @@ ${body}`)
620
684
  const out = md.join("\n");
621
685
  const trimmed = out.length > maxChars ? out.slice(0, maxChars) + "\n\n...(trimmed)\n" : out;
622
686
  const roundtablePath = path.join(this.roundtableDir, `${date}.md`);
623
- await writeFile(roundtablePath, trimmed, "utf-8");
687
+ await writeFileAtomic(roundtablePath, trimmed);
624
688
  log.info(`shared-context curated daily roundtable: ${roundtablePath}`);
625
689
  return {
626
690
  date,
@@ -637,4 +701,4 @@ export {
637
701
  resolveSharedContextDir,
638
702
  SharedContextManager
639
703
  };
640
- //# sourceMappingURL=chunk-U4SCL7B7.js.map
704
+ //# sourceMappingURL=chunk-DRD2Q7HQ.js.map