@remnic/core 1.1.31 → 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 (1087) 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 +8 -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 +45 -13
  12. package/dist/access-schema.js +8 -8
  13. package/dist/{access-service-CkZyb35d.d.ts → access-service-qrrIrC-0.d.ts} +5 -128
  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-ZAVUCJ4H.js → chunk-3Q4H3OBR.js} +150 -65
  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-U7EJOMFC.js → chunk-4Q73JBSM.js} +4 -4
  91. package/dist/{chunk-XKLD5OK4.js → chunk-4RR6ROTB.js} +10 -11
  92. package/dist/chunk-4RR6ROTB.js.map +1 -0
  93. package/dist/{chunk-4KGVTPGD.js → chunk-6F6BXB7A.js} +9 -8
  94. package/dist/chunk-6F6BXB7A.js.map +1 -0
  95. package/dist/{chunk-NMZY542O.js → chunk-6URPAY2D.js} +41 -17
  96. package/dist/chunk-6URPAY2D.js.map +1 -0
  97. package/dist/{chunk-N53K2EXC.js → chunk-6VF75M3X.js} +2 -2
  98. package/dist/{chunk-XSZEP4SF.js → chunk-6XSPNR6L.js} +6 -5
  99. package/dist/chunk-6XSPNR6L.js.map +1 -0
  100. package/dist/{chunk-6H2TESSP.js → chunk-765K3SAT.js} +3 -3
  101. package/dist/{chunk-EDTHC6UD.js → chunk-77NAFXUD.js} +2 -2
  102. package/dist/{chunk-S7KDBTWT.js → chunk-7F7Z6MOS.js} +29 -14
  103. package/dist/chunk-7F7Z6MOS.js.map +1 -0
  104. package/dist/{chunk-MZH6EHNR.js → chunk-7H6CFEBJ.js} +41 -14
  105. package/dist/chunk-7H6CFEBJ.js.map +1 -0
  106. package/dist/{chunk-575RMLWN.js → chunk-7MV5CWTE.js} +26 -20
  107. package/dist/chunk-7MV5CWTE.js.map +1 -0
  108. package/dist/{chunk-MGKYQQYF.js → chunk-7Q3RCKAQ.js} +2 -2
  109. package/dist/chunk-7RXCMVFQ.js +27 -0
  110. package/dist/chunk-7RXCMVFQ.js.map +1 -0
  111. package/dist/{chunk-DGXUHMOV.js → chunk-A2IYSXDQ.js} +25 -6
  112. package/dist/chunk-A2IYSXDQ.js.map +1 -0
  113. package/dist/{chunk-EABGC2TL.js → chunk-A2Z6UCWT.js} +26 -4
  114. package/dist/chunk-A2Z6UCWT.js.map +1 -0
  115. package/dist/{chunk-3VAL7ZL2.js → chunk-A52AKD7C.js} +59 -24
  116. package/dist/chunk-A52AKD7C.js.map +1 -0
  117. package/dist/{chunk-5375UYTQ.js → chunk-A6D7A2FW.js} +4 -4
  118. package/dist/chunk-A6D7A2FW.js.map +1 -0
  119. package/dist/{chunk-FAAFWE4G.js → chunk-ALEPI75L.js} +24 -6
  120. package/dist/chunk-ALEPI75L.js.map +1 -0
  121. package/dist/{chunk-3SLRNYNG.js → chunk-AUDJPF4N.js} +15 -4
  122. package/dist/chunk-AUDJPF4N.js.map +1 -0
  123. package/dist/chunk-B5XMS73R.js +145 -0
  124. package/dist/chunk-B5XMS73R.js.map +1 -0
  125. package/dist/{chunk-HXXBL2KD.js → chunk-BECQDWBA.js} +44 -4
  126. package/dist/chunk-BECQDWBA.js.map +1 -0
  127. package/dist/{chunk-7SEAZFFB.js → chunk-BEUDU7Y4.js} +24 -4
  128. package/dist/chunk-BEUDU7Y4.js.map +1 -0
  129. package/dist/{chunk-XVVIG67A.js → chunk-BLZAVUD2.js} +61 -17
  130. package/dist/chunk-BLZAVUD2.js.map +1 -0
  131. package/dist/chunk-CHBI22MI.js +159 -0
  132. package/dist/chunk-CHBI22MI.js.map +1 -0
  133. package/dist/{chunk-GDFS42HT.js → chunk-CHCA44C3.js} +15 -8
  134. package/dist/chunk-CHCA44C3.js.map +1 -0
  135. package/dist/chunk-CINZGPSJ.js +22 -0
  136. package/dist/chunk-CINZGPSJ.js.map +1 -0
  137. package/dist/chunk-CMTINOFS.js +36 -0
  138. package/dist/chunk-CMTINOFS.js.map +1 -0
  139. package/dist/{chunk-34DQE4KF.js → chunk-CO7ZO4TU.js} +2 -2
  140. package/dist/{chunk-PFV5C235.js → chunk-CPPS65WS.js} +2 -1
  141. package/dist/{chunk-PFV5C235.js.map → chunk-CPPS65WS.js.map} +1 -1
  142. package/dist/{chunk-DINWEURR.js → chunk-CSKLPDN6.js} +20 -6
  143. package/dist/chunk-CSKLPDN6.js.map +1 -0
  144. package/dist/chunk-CWWMTTQE.js +566 -0
  145. package/dist/chunk-CWWMTTQE.js.map +1 -0
  146. package/dist/{chunk-IQT3XTKW.js → chunk-D24OXEPB.js} +13 -7
  147. package/dist/chunk-D24OXEPB.js.map +1 -0
  148. package/dist/{chunk-TPU5L5EY.js → chunk-D6WE5MTW.js} +272 -411
  149. package/dist/chunk-D6WE5MTW.js.map +1 -0
  150. package/dist/{chunk-WIICJPET.js → chunk-DEUNUKTD.js} +6 -4
  151. package/dist/{chunk-WIICJPET.js.map → chunk-DEUNUKTD.js.map} +1 -1
  152. package/dist/{chunk-ZYVPLJ4T.js → chunk-DHGSZ3UD.js} +9 -7
  153. package/dist/chunk-DHGSZ3UD.js.map +1 -0
  154. package/dist/{chunk-JR4ZC3G4.js → chunk-DLJ4IR6M.js} +91 -41
  155. package/dist/chunk-DLJ4IR6M.js.map +1 -0
  156. package/dist/{chunk-U4SCL7B7.js → chunk-DRD2Q7HQ.js} +82 -18
  157. package/dist/chunk-DRD2Q7HQ.js.map +1 -0
  158. package/dist/{chunk-2IWUMAES.js → chunk-E62SBGQ3.js} +28 -13
  159. package/dist/chunk-E62SBGQ3.js.map +1 -0
  160. package/dist/{chunk-C5BCH4ZS.js → chunk-EAZGEEG2.js} +21 -3
  161. package/dist/chunk-EAZGEEG2.js.map +1 -0
  162. package/dist/{chunk-TPB3I2AC.js → chunk-ECZU5BJH.js} +31 -10
  163. package/dist/chunk-ECZU5BJH.js.map +1 -0
  164. package/dist/{chunk-77H5NU3M.js → chunk-EDBEWFJO.js} +82 -18
  165. package/dist/chunk-EDBEWFJO.js.map +1 -0
  166. package/dist/chunk-EDQVAMQI.js +308 -0
  167. package/dist/chunk-EDQVAMQI.js.map +1 -0
  168. package/dist/{chunk-RRF5UOBJ.js → chunk-EI6V5UXY.js} +22 -15
  169. package/dist/chunk-EI6V5UXY.js.map +1 -0
  170. package/dist/{chunk-I5GLV3VE.js → chunk-EIPUHVKE.js} +31 -24
  171. package/dist/{chunk-I5GLV3VE.js.map → chunk-EIPUHVKE.js.map} +1 -1
  172. package/dist/{chunk-ZKSK55RC.js → chunk-ETUPBUHB.js} +2 -2
  173. package/dist/{chunk-25MQ7IHJ.js → chunk-EUML3N6B.js} +17 -6
  174. package/dist/chunk-EUML3N6B.js.map +1 -0
  175. package/dist/{chunk-5RGLBDQF.js → chunk-EVZFIAPG.js} +12 -12
  176. package/dist/chunk-EVZFIAPG.js.map +1 -0
  177. package/dist/{chunk-QRNI5JBH.js → chunk-EYIEWJNI.js} +2 -2
  178. package/dist/{chunk-YU5KIWYQ.js → chunk-FER4WARO.js} +79 -41
  179. package/dist/chunk-FER4WARO.js.map +1 -0
  180. package/dist/{chunk-43PJZYGL.js → chunk-FPGE5NVO.js} +45 -10
  181. package/dist/chunk-FPGE5NVO.js.map +1 -0
  182. package/dist/{chunk-C6QPK5GG.js → chunk-FZZ2QTJI.js} +2 -2
  183. package/dist/{chunk-D46YSIYX.js → chunk-G3Z3QEF5.js} +19 -11
  184. package/dist/{chunk-D46YSIYX.js.map → chunk-G3Z3QEF5.js.map} +1 -1
  185. package/dist/{chunk-3JXBXXM2.js → chunk-G4IAEX6D.js} +2 -2
  186. package/dist/{chunk-MSWG7JI6.js → chunk-G56P5RLD.js} +8 -2
  187. package/dist/chunk-G56P5RLD.js.map +1 -0
  188. package/dist/{chunk-AGZQD76C.js → chunk-GCGJW34D.js} +48 -2
  189. package/dist/chunk-GCGJW34D.js.map +1 -0
  190. package/dist/chunk-H2NCNXMS.js +159 -0
  191. package/dist/chunk-H2NCNXMS.js.map +1 -0
  192. package/dist/{chunk-XYIK4LF6.js → chunk-H3FZVNRN.js} +8 -2
  193. package/dist/chunk-H3FZVNRN.js.map +1 -0
  194. package/dist/{chunk-TK4UEOSK.js → chunk-HDDRVXX4.js} +8 -8
  195. package/dist/chunk-HDDRVXX4.js.map +1 -0
  196. package/dist/{chunk-LLQ2LLWF.js → chunk-HENLZHIT.js} +15 -5
  197. package/dist/chunk-HENLZHIT.js.map +1 -0
  198. package/dist/{chunk-N2D6GXBM.js → chunk-HINSGUA7.js} +28 -20
  199. package/dist/chunk-HINSGUA7.js.map +1 -0
  200. package/dist/{chunk-APO3DCMU.js → chunk-HLAVGJ62.js} +30 -8
  201. package/dist/chunk-HLAVGJ62.js.map +1 -0
  202. package/dist/{chunk-TPMQ3G6Z.js → chunk-HOJZMQ4J.js} +2 -2
  203. package/dist/chunk-HOJZMQ4J.js.map +1 -0
  204. package/dist/{chunk-LUDTDZLK.js → chunk-HPWVAEET.js} +33 -7
  205. package/dist/chunk-HPWVAEET.js.map +1 -0
  206. package/dist/{chunk-NZL6GGQE.js → chunk-HQ6NIBL6.js} +92 -30
  207. package/dist/chunk-HQ6NIBL6.js.map +1 -0
  208. package/dist/{chunk-UWVJF25J.js → chunk-HWVTS5NO.js} +20 -6
  209. package/dist/chunk-HWVTS5NO.js.map +1 -0
  210. package/dist/{chunk-2WWLHTZY.js → chunk-IC4GELZE.js} +2 -2
  211. package/dist/{chunk-QA2ZAPBU.js → chunk-IPLYGWQF.js} +28 -20
  212. package/dist/chunk-IPLYGWQF.js.map +1 -0
  213. package/dist/{chunk-A6KTB5R6.js → chunk-IQ3OI2RR.js} +3 -3
  214. package/dist/chunk-IQ3OI2RR.js.map +1 -0
  215. package/dist/{chunk-6LVVDPJ4.js → chunk-J64TK33U.js} +3 -4
  216. package/dist/chunk-J64TK33U.js.map +1 -0
  217. package/dist/{chunk-6FC5EGNV.js → chunk-JBPKEARU.js} +15 -5
  218. package/dist/{chunk-6FC5EGNV.js.map → chunk-JBPKEARU.js.map} +1 -1
  219. package/dist/{chunk-RHY3HH7P.js → chunk-JFEKNTX7.js} +125 -33
  220. package/dist/chunk-JFEKNTX7.js.map +1 -0
  221. package/dist/{chunk-TZOLIGIG.js → chunk-JJEJJ7RK.js} +4 -2
  222. package/dist/chunk-JJEJJ7RK.js.map +1 -0
  223. package/dist/{chunk-PCUKNJAZ.js → chunk-JKV57BTN.js} +2 -2
  224. package/dist/{chunk-EJI5XIBB.js → chunk-JLNBQWZ2.js} +55 -7
  225. package/dist/chunk-JLNBQWZ2.js.map +1 -0
  226. package/dist/{chunk-XIG5PDM7.js → chunk-JUC24CTX.js} +8 -12
  227. package/dist/chunk-JUC24CTX.js.map +1 -0
  228. package/dist/{chunk-3ZLVGM76.js → chunk-JYIKKAK3.js} +106 -44
  229. package/dist/chunk-JYIKKAK3.js.map +1 -0
  230. package/dist/{chunk-OIGNEXKZ.js → chunk-K5O2QY6T.js} +5 -1
  231. package/dist/{chunk-OIGNEXKZ.js.map → chunk-K5O2QY6T.js.map} +1 -1
  232. package/dist/{chunk-ZTFCYYEZ.js → chunk-KCYE2MZM.js} +3 -3
  233. package/dist/chunk-KCYE2MZM.js.map +1 -0
  234. package/dist/{chunk-JWPLJLDU.js → chunk-KD3QD3A5.js} +2 -2
  235. package/dist/{chunk-JWPLJLDU.js.map → chunk-KD3QD3A5.js.map} +1 -1
  236. package/dist/{chunk-YRMVARQP.js → chunk-KFY3SGN7.js} +49 -2
  237. package/dist/chunk-KFY3SGN7.js.map +1 -0
  238. package/dist/{chunk-CYFQJMUV.js → chunk-KIB7SDIJ.js} +15 -10
  239. package/dist/chunk-KIB7SDIJ.js.map +1 -0
  240. package/dist/{chunk-3KW65B36.js → chunk-KILOTVIF.js} +95 -48
  241. package/dist/chunk-KILOTVIF.js.map +1 -0
  242. package/dist/{chunk-MXFBBHJU.js → chunk-KJMYHC7K.js} +10 -5
  243. package/dist/chunk-KJMYHC7K.js.map +1 -0
  244. package/dist/{chunk-W3LR522O.js → chunk-KM2A35EO.js} +36 -34
  245. package/dist/chunk-KM2A35EO.js.map +1 -0
  246. package/dist/{chunk-WELDCG6C.js → chunk-L227SKTB.js} +109 -36
  247. package/dist/chunk-L227SKTB.js.map +1 -0
  248. package/dist/{chunk-W6AQJ2PY.js → chunk-L7S47WZT.js} +35 -16
  249. package/dist/chunk-L7S47WZT.js.map +1 -0
  250. package/dist/{chunk-BVF3AGJP.js → chunk-LJBOVCQG.js} +26 -11
  251. package/dist/chunk-LJBOVCQG.js.map +1 -0
  252. package/dist/{chunk-2KI4QFHU.js → chunk-LMDRGRJ2.js} +2 -2
  253. package/dist/{chunk-MY6TPVXW.js → chunk-LMPHTYJC.js} +2 -2
  254. package/dist/{chunk-EHRTFRWW.js → chunk-LQHDIS7L.js} +10 -5
  255. package/dist/chunk-LQHDIS7L.js.map +1 -0
  256. package/dist/chunk-LUDUFZTV.js +170 -0
  257. package/dist/chunk-LUDUFZTV.js.map +1 -0
  258. package/dist/{chunk-5HRY2WRF.js → chunk-LZ3VEOU5.js} +2 -2
  259. package/dist/{chunk-Q7P4WJDP.js → chunk-M5T4Q2ZU.js} +1 -1
  260. package/dist/chunk-M5T4Q2ZU.js.map +1 -0
  261. package/dist/{chunk-ICRIXAP2.js → chunk-MC4FJXPA.js} +16 -6
  262. package/dist/chunk-MC4FJXPA.js.map +1 -0
  263. package/dist/{chunk-WPGJYVUH.js → chunk-MGVIEM2O.js} +23 -6
  264. package/dist/chunk-MGVIEM2O.js.map +1 -0
  265. package/dist/{chunk-YROHKYBY.js → chunk-O27WNHTT.js} +22 -6
  266. package/dist/chunk-O27WNHTT.js.map +1 -0
  267. package/dist/{chunk-NGAVDO7E.js → chunk-OADWQ5CR.js} +2 -2
  268. package/dist/{chunk-2NMMFZ5T.js → chunk-OD4FM2U7.js} +6 -3
  269. package/dist/chunk-OD4FM2U7.js.map +1 -0
  270. package/dist/{chunk-OZHRDTDX.js → chunk-OKTXM5H4.js} +11 -1
  271. package/dist/chunk-OKTXM5H4.js.map +1 -0
  272. package/dist/{chunk-RXDLTSWT.js → chunk-ONPLNAPX.js} +16 -7
  273. package/dist/chunk-ONPLNAPX.js.map +1 -0
  274. package/dist/{chunk-FJ43PRLT.js → chunk-ORFGK3XI.js} +20 -14
  275. package/dist/chunk-ORFGK3XI.js.map +1 -0
  276. package/dist/{chunk-DOM4GKSW.js → chunk-OZKVVUJB.js} +3 -3
  277. package/dist/{chunk-MT4HVDUZ.js → chunk-PM3QHTFT.js} +3 -3
  278. package/dist/{chunk-4DWOBS2A.js → chunk-PRQJ5ESM.js} +27 -2
  279. package/dist/{chunk-4DWOBS2A.js.map → chunk-PRQJ5ESM.js.map} +1 -1
  280. package/dist/chunk-PU44GBL4.js +52 -0
  281. package/dist/chunk-PU44GBL4.js.map +1 -0
  282. package/dist/{chunk-MJFNCJXV.js → chunk-Q4CAQGKQ.js} +47 -9
  283. package/dist/chunk-Q4CAQGKQ.js.map +1 -0
  284. package/dist/{chunk-U3WSW6PZ.js → chunk-QMYXNM4P.js} +90 -35
  285. package/dist/chunk-QMYXNM4P.js.map +1 -0
  286. package/dist/{chunk-NBNN5GOB.js → chunk-QY7YA7OL.js} +11 -2
  287. package/dist/chunk-QY7YA7OL.js.map +1 -0
  288. package/dist/{chunk-QLLBRHAT.js → chunk-R26QUUQN.js} +181 -257
  289. package/dist/chunk-R26QUUQN.js.map +1 -0
  290. package/dist/{chunk-ZK7I7JYV.js → chunk-R3PS27B4.js} +7 -7
  291. package/dist/{chunk-TMQLARTH.js → chunk-RCTS5CKK.js} +33 -14
  292. package/dist/chunk-RCTS5CKK.js.map +1 -0
  293. package/dist/{chunk-2PRLKQAH.js → chunk-RLV3PQGH.js} +35 -19
  294. package/dist/chunk-RLV3PQGH.js.map +1 -0
  295. package/dist/{chunk-WW3QQF4H.js → chunk-ROZJACKP.js} +16 -1
  296. package/dist/chunk-ROZJACKP.js.map +1 -0
  297. package/dist/{chunk-7MNMYOFP.js → chunk-RSUYKGGZ.js} +3 -4
  298. package/dist/chunk-RSUYKGGZ.js.map +1 -0
  299. package/dist/{chunk-LT3NLYSI.js → chunk-RUZOJKNF.js} +10 -7
  300. package/dist/chunk-RUZOJKNF.js.map +1 -0
  301. package/dist/{chunk-326G7DJK.js → chunk-RW5DGAGO.js} +67 -13
  302. package/dist/chunk-RW5DGAGO.js.map +1 -0
  303. package/dist/{chunk-KOSORCJG.js → chunk-S53PKKWK.js} +63 -24
  304. package/dist/chunk-S53PKKWK.js.map +1 -0
  305. package/dist/{chunk-65PG43EQ.js → chunk-S7WU3Y3D.js} +21 -4
  306. package/dist/chunk-S7WU3Y3D.js.map +1 -0
  307. package/dist/{chunk-SKE7JYKA.js → chunk-SFXKHM7P.js} +2 -2
  308. package/dist/{chunk-HMDCOMYU.js → chunk-SKGV326D.js} +3 -3
  309. package/dist/chunk-T2PO5MUF.js +62 -0
  310. package/dist/chunk-T2PO5MUF.js.map +1 -0
  311. package/dist/{chunk-C7VW7C3F.js → chunk-TDKQGLJW.js} +3 -3
  312. package/dist/chunk-TDKQGLJW.js.map +1 -0
  313. package/dist/{chunk-3QKK7QOS.js → chunk-TERNBNJB.js} +3 -3
  314. package/dist/chunk-TERNBNJB.js.map +1 -0
  315. package/dist/{chunk-MXC3AP5I.js → chunk-TGQ2NTWH.js} +12 -7
  316. package/dist/chunk-TGQ2NTWH.js.map +1 -0
  317. package/dist/{chunk-3Y4P7RXM.js → chunk-TMSXWOBZ.js} +3 -4
  318. package/dist/chunk-TMSXWOBZ.js.map +1 -0
  319. package/dist/{chunk-3TNBOMQT.js → chunk-TVRN5QKH.js} +11 -11
  320. package/dist/{chunk-3TNBOMQT.js.map → chunk-TVRN5QKH.js.map} +1 -1
  321. package/dist/{chunk-5UM2VJ6D.js → chunk-UEY3VB6W.js} +2 -2
  322. package/dist/{chunk-I6K5FBRQ.js → chunk-UI3NYK34.js} +4 -1
  323. package/dist/{chunk-I6K5FBRQ.js.map → chunk-UI3NYK34.js.map} +1 -1
  324. package/dist/{chunk-VBJ7V5SK.js → chunk-UIPDNLXA.js} +21 -8
  325. package/dist/chunk-UIPDNLXA.js.map +1 -0
  326. package/dist/{chunk-GIF42EW3.js → chunk-UP6MOYCB.js} +3 -3
  327. package/dist/{chunk-K4FLSOR5.js → chunk-USYGGIJZ.js} +44 -15
  328. package/dist/chunk-USYGGIJZ.js.map +1 -0
  329. package/dist/{chunk-FIT6DMX6.js → chunk-UWY7GIVS.js} +152 -54
  330. package/dist/chunk-UWY7GIVS.js.map +1 -0
  331. package/dist/{chunk-MRILGULB.js → chunk-V2RCP53Q.js} +2 -2
  332. package/dist/{chunk-XKECPATV.js → chunk-VFUEZZBS.js} +113 -4
  333. package/dist/chunk-VFUEZZBS.js.map +1 -0
  334. package/dist/{chunk-FSFEQI74.js → chunk-W7L6HXUC.js} +2 -2
  335. package/dist/{chunk-3IQ2TR4N.js → chunk-WLEB7WCG.js} +2 -2
  336. package/dist/{chunk-GL6I6MEQ.js → chunk-WSGF57U2.js} +3 -3
  337. package/dist/{chunk-KNKUID7G.js → chunk-X7Y7WX73.js} +72 -6
  338. package/dist/chunk-X7Y7WX73.js.map +1 -0
  339. package/dist/{chunk-5NPGSAVB.js → chunk-XEKAG3FM.js} +23 -5
  340. package/dist/chunk-XEKAG3FM.js.map +1 -0
  341. package/dist/{chunk-3APJ5EVB.js → chunk-XKIQZXUB.js} +41 -26
  342. package/dist/chunk-XKIQZXUB.js.map +1 -0
  343. package/dist/chunk-XKXKSQU7.js +92 -0
  344. package/dist/chunk-XKXKSQU7.js.map +1 -0
  345. package/dist/{chunk-JA3AK3PT.js → chunk-XNLXAWHX.js} +4 -4
  346. package/dist/{chunk-CULXMQJH.js → chunk-XPXEJRUB.js} +3 -3
  347. package/dist/chunk-XPXEJRUB.js.map +1 -0
  348. package/dist/{chunk-PZIAX57I.js → chunk-XR6DNK4U.js} +7 -4
  349. package/dist/chunk-XR6DNK4U.js.map +1 -0
  350. package/dist/{chunk-47VWKCAF.js → chunk-XSQ4SGM5.js} +33 -4
  351. package/dist/chunk-XSQ4SGM5.js.map +1 -0
  352. package/dist/{chunk-66DHUKLO.js → chunk-XSWKORGM.js} +16 -14
  353. package/dist/chunk-XSWKORGM.js.map +1 -0
  354. package/dist/{chunk-QR3C7BKQ.js → chunk-XZ4WBBB5.js} +7 -8
  355. package/dist/chunk-XZ4WBBB5.js.map +1 -0
  356. package/dist/{chunk-WNARATI3.js → chunk-Y2SXZ5KZ.js} +59 -11
  357. package/dist/chunk-Y2SXZ5KZ.js.map +1 -0
  358. package/dist/{chunk-SIC6U3GZ.js → chunk-YHV3KRKS.js} +3 -3
  359. package/dist/{chunk-ZPKBYX2F.js → chunk-YNDLCWXS.js} +85 -9
  360. package/dist/chunk-YNDLCWXS.js.map +1 -0
  361. package/dist/{chunk-VLXA6PI2.js → chunk-YQMZ7IH2.js} +4 -4
  362. package/dist/{chunk-TMM4S4IJ.js → chunk-YR6GIWWY.js} +58 -8
  363. package/dist/chunk-YR6GIWWY.js.map +1 -0
  364. package/dist/{chunk-DK5LDEQM.js → chunk-YR7XMOWK.js} +39 -23
  365. package/dist/chunk-YR7XMOWK.js.map +1 -0
  366. package/dist/chunk-ZFXCQPNO.js +27 -0
  367. package/dist/chunk-ZFXCQPNO.js.map +1 -0
  368. package/dist/citations.js +1 -1
  369. package/dist/{cli-kuh9PwZ5.d.ts → cli-X4NJoqSe.d.ts} +8 -31
  370. package/dist/cli.d.ts +10 -6
  371. package/dist/cli.js +122 -117
  372. package/dist/commitment-ledger.js +2 -2
  373. package/dist/compat/checks.js +1 -2
  374. package/dist/compounding/engine.d.ts +3 -2
  375. package/dist/compounding/engine.js +11 -11
  376. package/dist/compounding/preference-consolidator.d.ts +1 -0
  377. package/dist/compounding/preference-consolidator.js +8 -8
  378. package/dist/compounding/preference-consolidator.js.map +1 -1
  379. package/dist/compression-optimizer.d.ts +1 -0
  380. package/dist/compression-optimizer.js +1 -1
  381. package/dist/config.d.ts +1 -0
  382. package/dist/config.js +3 -2
  383. package/dist/connectors/codex-materialize-runner.d.ts +1 -0
  384. package/dist/connectors/codex-materialize-runner.js +12 -11
  385. package/dist/connectors/codex-materialize.d.ts +1 -0
  386. package/dist/connectors/codex-materialize.js +3 -2
  387. package/dist/connectors/index.d.ts +1 -0
  388. package/dist/connectors/index.js +14 -14
  389. package/dist/{connectors-cli-CwbyjGR7.d.ts → connectors-cli-DbTPNj2H.d.ts} +7 -1
  390. package/dist/connectors-cli.d.ts +1 -1
  391. package/dist/connectors-cli.js +3 -1
  392. package/dist/consolidation-provenance-check.d.ts +1 -0
  393. package/dist/consolidation-provenance-check.js +2 -2
  394. package/dist/consolidation-undo.d.ts +1 -0
  395. package/dist/consolidation-undo.js +1 -1
  396. package/dist/contradiction/index.d.ts +3 -1
  397. package/dist/contradiction/index.js +3 -3
  398. package/dist/{contradiction-review-ATP4S6IC.js → contradiction-review-6V2LXXK6.js} +2 -2
  399. package/dist/{contradiction-scan-5A4IDZV5.js → contradiction-scan-GIRVC4C7.js} +3 -3
  400. package/dist/conversation-index/backend.d.ts +3 -1
  401. package/dist/conversation-index/backend.js +3 -3
  402. package/dist/conversation-index/chunker.d.ts +1 -0
  403. package/dist/conversation-index/cleanup.js +1 -1
  404. package/dist/conversation-index/faiss-adapter.d.ts +2 -1
  405. package/dist/conversation-index/faiss-adapter.js +1 -1
  406. package/dist/conversation-index/indexer.d.ts +5 -2
  407. package/dist/conversation-index/indexer.js +1 -1
  408. package/dist/conversation-index/search.d.ts +2 -1
  409. package/dist/cross-namespace-budget.js +1 -1
  410. package/dist/cue-anchors.js +2 -2
  411. package/dist/dashboard-runtime.d.ts +6 -0
  412. package/dist/dashboard-runtime.js +3 -3
  413. package/dist/day-summary.d.ts +1 -0
  414. package/dist/day-summary.js +2 -2
  415. package/dist/delinearize.d.ts +1 -0
  416. package/dist/direct-answer-wiring.d.ts +1 -0
  417. package/dist/direct-answer.d.ts +1 -0
  418. package/dist/{dreams-ledger-LR2NBAZE.js → dreams-ledger-3WSCI5V4.js} +5 -4
  419. package/dist/{dreams-ledger-LR2NBAZE.js.map → dreams-ledger-3WSCI5V4.js.map} +1 -1
  420. package/dist/embedding-fallback.d.ts +3 -0
  421. package/dist/embedding-fallback.js +2 -2
  422. package/dist/enrichment/index.d.ts +1 -0
  423. package/dist/enrichment/index.js +1 -1
  424. package/dist/entity-retrieval.d.ts +2 -0
  425. package/dist/entity-retrieval.js +9 -9
  426. package/dist/entity-schema.d.ts +1 -0
  427. package/dist/evals.js +1 -1
  428. package/dist/explicit-capture.d.ts +5 -3
  429. package/dist/explicit-capture.js +2 -2
  430. package/dist/extraction-judge-telemetry.d.ts +2 -0
  431. package/dist/extraction-judge-training.d.ts +2 -0
  432. package/dist/extraction-judge.d.ts +2 -0
  433. package/dist/extraction.d.ts +2 -0
  434. package/dist/extraction.js +12 -12
  435. package/dist/{faiss-adapter-CzPghc4C.d.ts → faiss-adapter-BHecI1fF.d.ts} +4 -1
  436. package/dist/fallback-llm.d.ts +11 -1
  437. package/dist/fallback-llm.js +8 -6
  438. package/dist/{first-start-migration-4MHQEOSD.js → first-start-migration-CKTCTCQI.js} +5 -5
  439. package/dist/graph-dashboard-diff.d.ts +4 -0
  440. package/dist/graph-dashboard-diff.js +1 -1
  441. package/dist/graph-dashboard-parser.js +1 -1
  442. package/dist/{graph-edge-decay-5DI5GUNL.js → graph-edge-decay-MUP5J7CC.js} +6 -6
  443. package/dist/graph-events.js +1 -1
  444. package/dist/graph-snapshot.js +3 -3
  445. package/dist/graph.js +2 -2
  446. package/dist/harmonic-retrieval.js +4 -4
  447. package/dist/identity-continuity.d.ts +1 -0
  448. package/dist/importance.d.ts +1 -0
  449. package/dist/importers/index.d.ts +244 -0
  450. package/dist/importers/index.js +20 -0
  451. package/dist/index.d.ts +20 -350
  452. package/dist/index.js +884 -561
  453. package/dist/index.js.map +1 -1
  454. package/dist/intent.d.ts +1 -0
  455. package/dist/lcm/archive.d.ts +2 -2
  456. package/dist/lcm/archive.js +2 -2
  457. package/dist/lcm/engine.d.ts +3 -2
  458. package/dist/lcm/engine.js +6 -6
  459. package/dist/lcm/index.d.ts +1 -0
  460. package/dist/lcm/index.js +8 -8
  461. package/dist/lcm/recall.js +1 -1
  462. package/dist/lcm/summarizer.js +3 -3
  463. package/dist/lcm/tools.d.ts +1 -0
  464. package/dist/lifecycle.d.ts +1 -0
  465. package/dist/live-connectors-runner.d.ts +1 -0
  466. package/dist/live-connectors-runner.js +6 -6
  467. package/dist/local-llm.d.ts +1 -0
  468. package/dist/local-llm.js +2 -2
  469. package/dist/maintenance/archive-observations.js +1 -1
  470. package/dist/maintenance/memory-governance.d.ts +3 -1
  471. package/dist/maintenance/memory-governance.js +10 -8
  472. package/dist/maintenance/migrate-observations.js +3 -2
  473. package/dist/maintenance/observation-ledger-utils.d.ts +3 -0
  474. package/dist/maintenance/observation-ledger-utils.js +2 -1
  475. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -1
  476. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +11 -8
  477. package/dist/maintenance/rebuild-memory-projection.d.ts +2 -1
  478. package/dist/maintenance/rebuild-memory-projection.js +13 -10
  479. package/dist/maintenance/rebuild-observations.d.ts +1 -0
  480. package/dist/maintenance/rebuild-observations.js +3 -2
  481. package/dist/mcp-memory-inspector-app.d.ts +7 -4
  482. package/dist/mcp-memory-inspector-app.js +1 -1
  483. package/dist/memory-action-policy.d.ts +1 -0
  484. package/dist/memory-cache.d.ts +1 -0
  485. package/dist/memory-cache.js +1 -1
  486. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -0
  487. package/dist/memory-projection-store.d.ts +1 -0
  488. package/dist/memory-projection-store.js +1 -1
  489. package/dist/memory-provenance.d.ts +1 -0
  490. package/dist/memory-worth-outcomes.d.ts +1 -0
  491. package/dist/migrate/from-engram.js +2 -2
  492. package/dist/{migrate-from-identity-anchor-G27MCD6A.js → migrate-from-identity-anchor-EB4XI4Q2.js} +2 -2
  493. package/dist/model-registry.js +1 -1
  494. package/dist/models-json.d.ts +1 -0
  495. package/dist/namespaces/migrate.d.ts +3 -0
  496. package/dist/namespaces/migrate.js +24 -22
  497. package/dist/namespaces/principal.d.ts +1 -0
  498. package/dist/namespaces/principal.js +2 -1
  499. package/dist/namespaces/search.d.ts +1 -0
  500. package/dist/namespaces/search.js +15 -13
  501. package/dist/namespaces/storage.d.ts +4 -2
  502. package/dist/namespaces/storage.js +10 -9
  503. package/dist/native-knowledge.d.ts +1 -0
  504. package/dist/native-knowledge.js +1 -1
  505. package/dist/negative.js +1 -1
  506. package/dist/network/webdav.d.ts +16 -1
  507. package/dist/network/webdav.js +5 -3
  508. package/dist/objective-state-writers.js +4 -4
  509. package/dist/objective-state.js +2 -2
  510. package/dist/offline-sync.js +4 -4
  511. package/dist/operator-toolkit.d.ts +1 -0
  512. package/dist/operator-toolkit.js +35 -32
  513. package/dist/opik-exporter.js +1 -1
  514. package/dist/{orchestrator-DuWl9Hwx.d.ts → orchestrator-Co9nxRLF.d.ts} +4 -74
  515. package/dist/orchestrator.d.ts +5 -3
  516. package/dist/orchestrator.js +99 -96
  517. package/dist/page-versioning.js +1 -1
  518. package/dist/path-X2K5XCHL.js +9 -0
  519. package/dist/patterns-cli.d.ts +1 -0
  520. package/dist/peers/index.d.ts +328 -0
  521. package/dist/{peers-HCVGHMAE.js → peers/index.js} +4 -4
  522. package/dist/pipeline-D18UAKlN.d.ts +32 -0
  523. package/dist/plugin-entry-resolver.d.ts +9 -0
  524. package/dist/plugin-entry-resolver.js +8 -0
  525. package/dist/plugin-entry-resolver.js.map +1 -0
  526. package/dist/plugin-id.d.ts +2 -21
  527. package/dist/plugin-id.js +33 -4
  528. package/dist/plugin-id.js.map +1 -1
  529. package/dist/policy-runtime.d.ts +4 -0
  530. package/dist/policy-runtime.js +1 -1
  531. package/dist/profiling.js +1 -1
  532. package/dist/qmd-recall-cache.d.ts +1 -0
  533. package/dist/qmd.d.ts +1 -0
  534. package/dist/qmd.js +3 -3
  535. package/dist/recall-disclosure-escalation.d.ts +1 -0
  536. package/dist/recall-explain-renderer.d.ts +1 -0
  537. package/dist/recall-explain-renderer.js +3 -3
  538. package/dist/recall-state.d.ts +8 -1
  539. package/dist/recall-state.js +2 -1
  540. package/dist/recall-tag-filter.d.ts +1 -0
  541. package/dist/recall-xray-cli.d.ts +1 -0
  542. package/dist/recall-xray-cli.js +4 -4
  543. package/dist/recall-xray-renderer.d.ts +1 -0
  544. package/dist/recall-xray-renderer.js +3 -3
  545. package/dist/recall-xray.d.ts +1 -0
  546. package/dist/recall-xray.js +2 -2
  547. package/dist/relevance.d.ts +7 -1
  548. package/dist/relevance.js +2 -1
  549. package/dist/replay/normalizers/chatgpt.js +2 -2
  550. package/dist/replay/normalizers/claude.js +2 -2
  551. package/dist/replay/normalizers/openclaw.js +2 -2
  552. package/dist/replay/normalizers/shared.js +1 -1
  553. package/dist/replay/runner.js +1 -1
  554. package/dist/rerank.js +1 -1
  555. package/dist/{resolution-B7FNQSSP.js → resolution-ZY7VM6WS.js} +3 -3
  556. package/dist/resolution-ZY7VM6WS.js.map +1 -0
  557. package/dist/resolve-auth-token.d.ts +1 -0
  558. package/dist/resolve-auth-token.js +1 -1
  559. package/dist/resolve-provider-secret.d.ts +19 -29
  560. package/dist/resolve-provider-secret.js +2 -6
  561. package/dist/resume-bundles.js +10 -9
  562. package/dist/retrieval-agents.d.ts +2 -1
  563. package/dist/retrieval-agents.js +2 -1
  564. package/dist/retrieval-tiers.d.ts +1 -0
  565. package/dist/routing/engine.d.ts +1 -0
  566. package/dist/routing/store.d.ts +3 -0
  567. package/dist/routing/store.js +1 -1
  568. package/dist/runtime/env.js +1 -1
  569. package/dist/schemas.d.ts +191 -17
  570. package/dist/schemas.js +1 -1
  571. package/dist/sdk-compat.js +1 -1
  572. package/dist/search/document-scanner.js +1 -1
  573. package/dist/search/embed-helper.d.ts +7 -2
  574. package/dist/search/embed-helper.js +3 -1
  575. package/dist/search/factory.d.ts +2 -1
  576. package/dist/search/factory.js +13 -12
  577. package/dist/search/index.d.ts +2 -1
  578. package/dist/search/index.js +19 -18
  579. package/dist/search/lancedb-backend.d.ts +7 -6
  580. package/dist/search/lancedb-backend.js +4 -2
  581. package/dist/search/meilisearch-backend.d.ts +7 -6
  582. package/dist/search/meilisearch-backend.js +4 -2
  583. package/dist/search/noop-backend.d.ts +1 -0
  584. package/dist/search/orama-backend.d.ts +9 -7
  585. package/dist/search/orama-backend.js +8 -4
  586. package/dist/search/port.d.ts +1 -0
  587. package/dist/search/remote-backend.d.ts +1 -0
  588. package/dist/secure-store/index.d.ts +16 -3
  589. package/dist/secure-store/index.js +2 -2
  590. package/dist/{semantic-VwGI14Ok.d.ts → semantic-SLAa_prH.d.ts} +5 -3
  591. package/dist/semantic-consolidation.d.ts +1 -0
  592. package/dist/semantic-consolidation.js +14 -13
  593. package/dist/semantic-rule-promotion.js +8 -8
  594. package/dist/semantic-rule-verifier.d.ts +1 -0
  595. package/dist/semantic-rule-verifier.js +8 -8
  596. package/dist/session-integrity.d.ts +1 -0
  597. package/dist/session-integrity.js +1 -1
  598. package/dist/session-observer-bands.d.ts +1 -0
  599. package/dist/session-observer-state.d.ts +6 -1
  600. package/dist/session-observer-state.js +1 -1
  601. package/dist/shared-context/manager.d.ts +5 -0
  602. package/dist/shared-context/manager.js +3 -3
  603. package/dist/signal.d.ts +1 -0
  604. package/dist/signal.js +1 -1
  605. package/dist/source-attribution.js +1 -1
  606. package/dist/state-store-4QZISH3J.js +30 -0
  607. package/dist/state-store-4QZISH3J.js.map +1 -0
  608. package/dist/storage-C4DX8CuG.d.ts +157 -0
  609. package/dist/storage.d.ts +2 -0
  610. package/dist/storage.js +7 -7
  611. package/dist/store-contract.js +1 -1
  612. package/dist/summarizer.d.ts +1 -0
  613. package/dist/summarizer.js +7 -7
  614. package/dist/summary-snapshot.d.ts +1 -0
  615. package/dist/surfaces/dreams.js +48 -17
  616. package/dist/surfaces/dreams.js.map +1 -1
  617. package/dist/temporal-supersession.d.ts +1 -0
  618. package/dist/temporal-supersession.js +1 -1
  619. package/dist/temporal-validity.d.ts +1 -0
  620. package/dist/threading.d.ts +1 -0
  621. package/dist/tier-migration.d.ts +1 -0
  622. package/dist/tier-routing.d.ts +1 -0
  623. package/dist/{tier-stats-62ZVDFKS.js → tier-stats-SKML2OSF.js} +5 -5
  624. package/dist/tmt.js +1 -1
  625. package/dist/tokens.js +2 -2
  626. package/dist/topics.d.ts +1 -0
  627. package/dist/{trace-C5ETWBEF.js → trace-WM7V4CKI.js} +31 -1
  628. package/dist/trace-WM7V4CKI.js.map +1 -0
  629. package/dist/transcript.d.ts +1 -0
  630. package/dist/transcript.js +2 -2
  631. package/dist/transfer/autodetect.js +7 -7
  632. package/dist/transfer/backup.js +5 -5
  633. package/dist/transfer/capsule-export.js +5 -5
  634. package/dist/transfer/capsule-import.d.ts +6 -0
  635. package/dist/transfer/capsule-import.js +4 -4
  636. package/dist/transfer/export-json.js +3 -3
  637. package/dist/transfer/export-md.js +3 -3
  638. package/dist/transfer/export-sqlite.js +3 -3
  639. package/dist/transfer/fs-utils.d.ts +2 -1
  640. package/dist/transfer/fs-utils.js +5 -3
  641. package/dist/transfer/import-json.js +3 -3
  642. package/dist/transfer/import-md.js +3 -3
  643. package/dist/transfer/import-sqlite.js +3 -3
  644. package/dist/trust-zones.js +2 -2
  645. package/dist/types-B1VHaf2w.d.ts +126 -0
  646. package/dist/types-BliCnURB.d.ts +83 -0
  647. package/dist/types.d.ts +35 -0
  648. package/dist/types.js +1 -1
  649. package/dist/utility-learner.js +3 -3
  650. package/dist/utility-runtime.d.ts +1 -0
  651. package/dist/utility-runtime.js +4 -4
  652. package/dist/utility-telemetry.js +2 -2
  653. package/dist/verified-recall.js +9 -9
  654. package/dist/work/board.js +2 -2
  655. package/dist/work/boundary.js +1 -1
  656. package/dist/work/storage.d.ts +5 -0
  657. package/dist/work/storage.js +1 -1
  658. package/dist/work-product-ledger.js +2 -2
  659. package/package.json +74 -3
  660. package/scripts/ensure-better-sqlite3.mjs +8 -7
  661. package/scripts/faiss_index.py +141 -29
  662. package/src/access-cli.test.ts +87 -2
  663. package/src/access-cli.ts +59 -5
  664. package/src/access-http.test.ts +150 -0
  665. package/src/access-http.ts +89 -34
  666. package/src/access-idempotency.ts +136 -3
  667. package/src/access-mcp.test.ts +155 -0
  668. package/src/access-mcp.ts +116 -30
  669. package/src/access-schema.ts +22 -4
  670. package/src/access-service-project-tag.test.ts +37 -0
  671. package/src/access-service.ts +11 -10
  672. package/src/active-recall.test.ts +29 -1
  673. package/src/active-recall.ts +11 -7
  674. package/src/adapters/claude-code.ts +7 -8
  675. package/src/adapters/codex.ts +6 -7
  676. package/src/adapters/hermes.ts +1 -5
  677. package/src/adapters/registry.test.ts +63 -0
  678. package/src/adapters/registry.ts +10 -0
  679. package/src/adapters/replit.ts +5 -7
  680. package/src/adapters/types.ts +24 -1
  681. package/src/behavior-signals.ts +1 -1
  682. package/src/binary-lifecycle/backend.ts +16 -4
  683. package/src/binary-lifecycle/pipeline.test.ts +149 -0
  684. package/src/binary-lifecycle/pipeline.ts +49 -7
  685. package/src/binary-lifecycle/scanner.ts +19 -4
  686. package/src/boxes.ts +119 -32
  687. package/src/buffer-session.test.ts +28 -0
  688. package/src/buffer.ts +10 -14
  689. package/src/bulk-import/types.ts +10 -0
  690. package/src/calibration.test.ts +99 -0
  691. package/src/calibration.ts +57 -13
  692. package/src/causal-consolidation.test.ts +214 -0
  693. package/src/causal-consolidation.ts +131 -14
  694. package/src/causal-retrieval.ts +16 -3
  695. package/src/citations.test.ts +75 -0
  696. package/src/citations.ts +19 -6
  697. package/src/cli.ts +134 -109
  698. package/src/coding/coding-namespace.test.ts +7 -0
  699. package/src/coding/coding-namespace.ts +8 -0
  700. package/src/coding/review-context.test.ts +30 -0
  701. package/src/coding/review-context.ts +79 -9
  702. package/src/coding/wire-coding-context.test.ts +16 -0
  703. package/src/compat/checks.test.ts +33 -0
  704. package/src/compat/checks.ts +64 -4
  705. package/src/compounding/engine.ts +2 -2
  706. package/src/compounding/preference-consolidator.test.ts +47 -0
  707. package/src/compounding/preference-consolidator.ts +8 -8
  708. package/src/compression-optimizer.ts +5 -2
  709. package/src/config.test.ts +34 -2
  710. package/src/config.ts +62 -18
  711. package/src/connectors/codex-materialize-runner.ts +4 -3
  712. package/src/connectors/codex-materialize.ts +149 -34
  713. package/src/connectors/index.test.ts +144 -7
  714. package/src/connectors/index.ts +86 -15
  715. package/src/connectors/live/github.test.ts +47 -0
  716. package/src/connectors/live/github.ts +29 -1
  717. package/src/connectors/live/index.ts +2 -0
  718. package/src/connectors/live/live-connectors.test.ts +359 -73
  719. package/src/connectors/live/notion.test.ts +84 -0
  720. package/src/connectors/live/notion.ts +18 -1
  721. package/src/connectors/live/state-store.ts +419 -38
  722. package/src/connectors/weclone-installer.test.ts +16 -18
  723. package/src/connectors-cli.ts +19 -0
  724. package/src/console/trace.test.ts +28 -0
  725. package/src/console/trace.ts +42 -5
  726. package/src/contradiction/contradiction-judge.test.ts +49 -0
  727. package/src/contradiction/contradiction-judge.ts +15 -5
  728. package/src/contradiction/contradiction-review.ts +31 -7
  729. package/src/contradiction/contradiction-scan.ts +28 -18
  730. package/src/contradiction/contradiction.test.ts +237 -1
  731. package/src/contradiction/resolution.ts +43 -4
  732. package/src/conversation-index/backend.ts +13 -5
  733. package/src/conversation-index/cleanup.ts +25 -4
  734. package/src/conversation-index/faiss-adapter.ts +24 -15
  735. package/src/conversation-index/indexer.test.ts +71 -10
  736. package/src/conversation-index/indexer.ts +22 -3
  737. package/src/cross-namespace-budget.test.ts +59 -0
  738. package/src/cross-namespace-budget.ts +15 -7
  739. package/src/curation/index.ts +18 -17
  740. package/src/dashboard-runtime.test.ts +98 -0
  741. package/src/dashboard-runtime.ts +96 -6
  742. package/src/dedup/index.test.ts +133 -0
  743. package/src/dedup/index.ts +73 -10
  744. package/src/dedup/semantic.test.ts +77 -2
  745. package/src/dedup/semantic.ts +26 -6
  746. package/src/embedding-fallback.ts +47 -15
  747. package/src/enrichment/audit.ts +8 -1
  748. package/src/enrichment/pipeline.ts +21 -13
  749. package/src/enrichment/web-search-provider.ts +1 -6
  750. package/src/entity-retrieval.ts +57 -6
  751. package/src/evals.ts +22 -13
  752. package/src/explicit-capture.test.ts +40 -0
  753. package/src/explicit-capture.ts +14 -2
  754. package/src/extraction.ts +42 -30
  755. package/src/fallback-llm.ts +35 -2
  756. package/src/graph-dashboard-diff.test.ts +57 -0
  757. package/src/graph-dashboard-diff.ts +24 -2
  758. package/src/graph-dashboard-parser.test.ts +31 -0
  759. package/src/graph-dashboard-parser.ts +4 -1
  760. package/src/graph-events.ts +6 -4
  761. package/src/graph.test.ts +69 -0
  762. package/src/graph.ts +7 -4
  763. package/src/importers/base.test.ts +70 -0
  764. package/src/importers/base.ts +56 -7
  765. package/src/index.ts +5 -2
  766. package/src/lcm/archive.ts +65 -16
  767. package/src/lcm/engine.ts +27 -8
  768. package/src/lcm/recall.ts +5 -5
  769. package/src/lcm-engine.test.ts +87 -1
  770. package/src/lcm-recall.test.ts +71 -0
  771. package/src/live-connectors-runner.ts +100 -36
  772. package/src/maintenance/archive-observations.ts +24 -3
  773. package/src/maintenance/atomic-file.ts +85 -0
  774. package/src/maintenance/dreams-ledger.ts +15 -8
  775. package/src/maintenance/memory-governance.test.ts +53 -0
  776. package/src/maintenance/memory-governance.ts +15 -5
  777. package/src/maintenance/observation-ledger-utils.ts +6 -5
  778. package/src/maintenance/purge.test.ts +64 -0
  779. package/src/maintenance/rebuild-memory-lifecycle-ledger.ts +22 -9
  780. package/src/maintenance/rebuild-memory-projection.ts +22 -9
  781. package/src/maintenance/rebuild-observations.ts +7 -3
  782. package/src/mcp-memory-inspector-app.ts +26 -3
  783. package/src/memory-cache.test.ts +19 -0
  784. package/src/memory-cache.ts +1 -0
  785. package/src/memory-extension/codex-publisher.ts +25 -4
  786. package/src/memory-extension-host/host-discovery.test.ts +69 -0
  787. package/src/memory-extension-host/host-discovery.ts +63 -6
  788. package/src/memory-projection-store.ts +114 -62
  789. package/src/message-parts/index.ts +46 -31
  790. package/src/message-parts/message-parts.test.ts +77 -0
  791. package/src/migrate/from-engram.ts +68 -14
  792. package/src/model-registry.test.ts +38 -0
  793. package/src/model-registry.ts +12 -7
  794. package/src/namespaces/identity.test.ts +66 -0
  795. package/src/namespaces/identity.ts +23 -0
  796. package/src/namespaces/migrate.test.ts +62 -0
  797. package/src/namespaces/migrate.ts +82 -14
  798. package/src/namespaces/principal.test.ts +37 -1
  799. package/src/namespaces/principal.ts +18 -7
  800. package/src/namespaces/search.test.ts +76 -6
  801. package/src/namespaces/search.ts +22 -21
  802. package/src/namespaces/storage.ts +93 -11
  803. package/src/native-knowledge.ts +23 -3
  804. package/src/negative.ts +50 -5
  805. package/src/network/webdav.ts +177 -58
  806. package/src/onboarding/index.test.ts +105 -0
  807. package/src/onboarding/index.ts +17 -5
  808. package/src/operator-toolkit.ts +39 -4
  809. package/src/orchestrator.ts +52 -17
  810. package/src/page-versioning.ts +31 -5
  811. package/src/peers/peers.test.ts +70 -0
  812. package/src/peers/storage.ts +32 -3
  813. package/src/plugin-entry-resolver.test.ts +60 -0
  814. package/src/plugin-entry-resolver.ts +48 -0
  815. package/src/plugin-id.test.ts +38 -0
  816. package/src/plugin-id.ts +31 -64
  817. package/src/policy-runtime.test.ts +75 -0
  818. package/src/policy-runtime.ts +32 -3
  819. package/src/procedural/procedure-miner.test.ts +152 -0
  820. package/src/procedural/procedure-miner.ts +124 -19
  821. package/src/profiling.test.ts +23 -0
  822. package/src/profiling.ts +10 -1
  823. package/src/projection/index.test.ts +253 -0
  824. package/src/projection/index.ts +159 -18
  825. package/src/qmd-client.test.ts +45 -0
  826. package/src/qmd.ts +8 -8
  827. package/src/recall-disclosure.test.ts +15 -1
  828. package/src/recall-state.ts +24 -5
  829. package/src/relevance.ts +24 -5
  830. package/src/replay/normalizers/chatgpt.ts +14 -4
  831. package/src/replay/normalizers/claude.ts +8 -3
  832. package/src/replay/normalizers/openclaw.ts +35 -12
  833. package/src/replay/normalizers/replay-normalizers.test.ts +65 -0
  834. package/src/replay/normalizers/shared.ts +4 -1
  835. package/src/replay/runner.ts +1 -1
  836. package/src/rerank.test.ts +41 -1
  837. package/src/rerank.ts +2 -2
  838. package/src/resolve-auth-token.test.ts +29 -0
  839. package/src/resolve-auth-token.ts +12 -7
  840. package/src/resolve-provider-secret.test.ts +78 -22
  841. package/src/resolve-provider-secret.ts +55 -223
  842. package/src/retrieval-agents.ts +51 -14
  843. package/src/review/index.test.ts +75 -1
  844. package/src/review/index.ts +88 -30
  845. package/src/routing/store.ts +36 -6
  846. package/src/runtime/env.test.ts +73 -0
  847. package/src/runtime/env.ts +7 -11
  848. package/src/schemas.ts +16 -1
  849. package/src/search/abort.ts +18 -0
  850. package/src/search/document-scanner.test.ts +80 -0
  851. package/src/search/document-scanner.ts +51 -9
  852. package/src/search/embed-helper.ts +19 -6
  853. package/src/search/factory.ts +9 -5
  854. package/src/search/lancedb-backend.ts +62 -22
  855. package/src/search/meilisearch-backend.ts +35 -12
  856. package/src/search/orama-backend.test.ts +27 -0
  857. package/src/search/orama-backend.ts +65 -15
  858. package/src/secure-store/cli-handlers.ts +70 -6
  859. package/src/secure-store/cli-renderer.ts +13 -7
  860. package/src/secure-store/secure-fs.ts +11 -5
  861. package/src/secure-store/secure-store.test.ts +70 -0
  862. package/src/semantic-consolidation.test.ts +45 -0
  863. package/src/semantic-consolidation.ts +3 -3
  864. package/src/session-integrity.test.ts +98 -0
  865. package/src/session-integrity.ts +51 -1
  866. package/src/session-observer-state.ts +108 -41
  867. package/src/shared-context/manager.ts +93 -15
  868. package/src/signal.test.ts +14 -0
  869. package/src/signal.ts +8 -1
  870. package/src/source-attribution.test.ts +8 -0
  871. package/src/source-attribution.ts +24 -2
  872. package/src/spaces/index.test.ts +93 -0
  873. package/src/spaces/index.ts +75 -9
  874. package/src/storage.ts +14 -1
  875. package/src/store-contract.test.ts +35 -0
  876. package/src/store-contract.ts +39 -5
  877. package/src/summarizer.ts +24 -18
  878. package/src/summary-snapshot.test.ts +77 -0
  879. package/src/surfaces/dreams.test.ts +73 -0
  880. package/src/surfaces/dreams.ts +53 -19
  881. package/src/sync/index.ts +42 -17
  882. package/src/taxonomy/taxonomy-loader.ts +43 -4
  883. package/src/temporal-supersession.test.ts +67 -0
  884. package/src/temporal-supersession.ts +8 -0
  885. package/src/tmt.test.ts +50 -0
  886. package/src/tmt.ts +35 -11
  887. package/src/tokens.test.ts +18 -0
  888. package/src/tokens.ts +7 -0
  889. package/src/training-export/converter.test.ts +55 -2
  890. package/src/training-export/converter.ts +36 -10
  891. package/src/training-export/registry.test.ts +17 -0
  892. package/src/training-export/registry.ts +19 -1
  893. package/src/transcript.ts +2 -2
  894. package/src/transfer/backup.ts +18 -7
  895. package/src/transfer/capsule-crypto.ts +105 -21
  896. package/src/transfer/capsule-encrypt.test.ts +106 -7
  897. package/src/transfer/capsule-export.ts +23 -14
  898. package/src/transfer/capsule-import.ts +11 -2
  899. package/src/transfer/exclusions.ts +7 -0
  900. package/src/transfer/export-sqlite.ts +14 -13
  901. package/src/transfer/fs-utils.ts +52 -1
  902. package/src/transfer/import-json.ts +12 -7
  903. package/src/transfer/import-md.ts +5 -5
  904. package/src/transfer/import-sqlite.ts +4 -5
  905. package/src/trust-zones.ts +1 -1
  906. package/src/types.ts +25 -0
  907. package/src/utility-telemetry.ts +1 -1
  908. package/src/utils/category-dir.test.ts +15 -0
  909. package/src/utils/category-dir.ts +3 -1
  910. package/src/work/boundary.ts +30 -18
  911. package/src/work/storage.ts +116 -38
  912. package/src/work-product-ledger.ts +1 -1
  913. package/dist/chunk-25MQ7IHJ.js.map +0 -1
  914. package/dist/chunk-2IWUMAES.js.map +0 -1
  915. package/dist/chunk-2NMMFZ5T.js.map +0 -1
  916. package/dist/chunk-2PRLKQAH.js.map +0 -1
  917. package/dist/chunk-326G7DJK.js.map +0 -1
  918. package/dist/chunk-3APJ5EVB.js.map +0 -1
  919. package/dist/chunk-3KW65B36.js.map +0 -1
  920. package/dist/chunk-3QKK7QOS.js.map +0 -1
  921. package/dist/chunk-3SLRNYNG.js.map +0 -1
  922. package/dist/chunk-3VAL7ZL2.js.map +0 -1
  923. package/dist/chunk-3Y4P7RXM.js.map +0 -1
  924. package/dist/chunk-3ZLVGM76.js.map +0 -1
  925. package/dist/chunk-43PJZYGL.js.map +0 -1
  926. package/dist/chunk-47VWKCAF.js.map +0 -1
  927. package/dist/chunk-4KGVTPGD.js.map +0 -1
  928. package/dist/chunk-5375UYTQ.js.map +0 -1
  929. package/dist/chunk-56K5QLHX.js.map +0 -1
  930. package/dist/chunk-575RMLWN.js.map +0 -1
  931. package/dist/chunk-5NPGSAVB.js.map +0 -1
  932. package/dist/chunk-5RGLBDQF.js.map +0 -1
  933. package/dist/chunk-65PG43EQ.js.map +0 -1
  934. package/dist/chunk-66DHUKLO.js.map +0 -1
  935. package/dist/chunk-6LVVDPJ4.js.map +0 -1
  936. package/dist/chunk-76FLAAUC.js.map +0 -1
  937. package/dist/chunk-77H5NU3M.js.map +0 -1
  938. package/dist/chunk-7MNMYOFP.js.map +0 -1
  939. package/dist/chunk-7OZ53EXP.js.map +0 -1
  940. package/dist/chunk-7SEAZFFB.js.map +0 -1
  941. package/dist/chunk-A6KTB5R6.js.map +0 -1
  942. package/dist/chunk-AGZQD76C.js.map +0 -1
  943. package/dist/chunk-APO3DCMU.js.map +0 -1
  944. package/dist/chunk-BVF3AGJP.js.map +0 -1
  945. package/dist/chunk-C5BCH4ZS.js.map +0 -1
  946. package/dist/chunk-C7VW7C3F.js.map +0 -1
  947. package/dist/chunk-CULXMQJH.js.map +0 -1
  948. package/dist/chunk-CYFQJMUV.js.map +0 -1
  949. package/dist/chunk-D654IBA6.js +0 -61
  950. package/dist/chunk-D654IBA6.js.map +0 -1
  951. package/dist/chunk-DGXUHMOV.js.map +0 -1
  952. package/dist/chunk-DINWEURR.js.map +0 -1
  953. package/dist/chunk-DK5LDEQM.js.map +0 -1
  954. package/dist/chunk-EABGC2TL.js.map +0 -1
  955. package/dist/chunk-EHRTFRWW.js.map +0 -1
  956. package/dist/chunk-EJI5XIBB.js.map +0 -1
  957. package/dist/chunk-FAAFWE4G.js.map +0 -1
  958. package/dist/chunk-FAJ7FZYM.js +0 -11
  959. package/dist/chunk-FAJ7FZYM.js.map +0 -1
  960. package/dist/chunk-FDU6HUUL.js +0 -147
  961. package/dist/chunk-FDU6HUUL.js.map +0 -1
  962. package/dist/chunk-FIT6DMX6.js.map +0 -1
  963. package/dist/chunk-FJ43PRLT.js.map +0 -1
  964. package/dist/chunk-FLTNHQK6.js +0 -262
  965. package/dist/chunk-FLTNHQK6.js.map +0 -1
  966. package/dist/chunk-GDFS42HT.js.map +0 -1
  967. package/dist/chunk-H3ME6L6D.js.map +0 -1
  968. package/dist/chunk-HXXBL2KD.js.map +0 -1
  969. package/dist/chunk-ICRIXAP2.js.map +0 -1
  970. package/dist/chunk-IQT3XTKW.js.map +0 -1
  971. package/dist/chunk-JR4ZC3G4.js.map +0 -1
  972. package/dist/chunk-K4FLSOR5.js.map +0 -1
  973. package/dist/chunk-KNKUID7G.js.map +0 -1
  974. package/dist/chunk-KOSORCJG.js.map +0 -1
  975. package/dist/chunk-LIRZNNUP.js.map +0 -1
  976. package/dist/chunk-LLQ2LLWF.js.map +0 -1
  977. package/dist/chunk-LPMVBPA3.js +0 -236
  978. package/dist/chunk-LPMVBPA3.js.map +0 -1
  979. package/dist/chunk-LT3NLYSI.js.map +0 -1
  980. package/dist/chunk-LUDTDZLK.js.map +0 -1
  981. package/dist/chunk-MJFNCJXV.js.map +0 -1
  982. package/dist/chunk-MSWG7JI6.js.map +0 -1
  983. package/dist/chunk-MXC3AP5I.js.map +0 -1
  984. package/dist/chunk-MXFBBHJU.js.map +0 -1
  985. package/dist/chunk-MZH6EHNR.js.map +0 -1
  986. package/dist/chunk-N2D6GXBM.js.map +0 -1
  987. package/dist/chunk-NBNN5GOB.js.map +0 -1
  988. package/dist/chunk-NMZY542O.js.map +0 -1
  989. package/dist/chunk-NZL6GGQE.js.map +0 -1
  990. package/dist/chunk-OZHRDTDX.js.map +0 -1
  991. package/dist/chunk-PZIAX57I.js.map +0 -1
  992. package/dist/chunk-Q7P4WJDP.js.map +0 -1
  993. package/dist/chunk-QA2ZAPBU.js.map +0 -1
  994. package/dist/chunk-QDZ2RLEC.js.map +0 -1
  995. package/dist/chunk-QLLBRHAT.js.map +0 -1
  996. package/dist/chunk-QR3C7BKQ.js.map +0 -1
  997. package/dist/chunk-RHY3HH7P.js.map +0 -1
  998. package/dist/chunk-RK2Y4XOM.js.map +0 -1
  999. package/dist/chunk-RR2PKP3I.js +0 -63
  1000. package/dist/chunk-RR2PKP3I.js.map +0 -1
  1001. package/dist/chunk-RRF5UOBJ.js.map +0 -1
  1002. package/dist/chunk-RXDLTSWT.js.map +0 -1
  1003. package/dist/chunk-RYED3SPJ.js +0 -42
  1004. package/dist/chunk-RYED3SPJ.js.map +0 -1
  1005. package/dist/chunk-S7KDBTWT.js.map +0 -1
  1006. package/dist/chunk-TK4UEOSK.js.map +0 -1
  1007. package/dist/chunk-TMM4S4IJ.js.map +0 -1
  1008. package/dist/chunk-TMQLARTH.js.map +0 -1
  1009. package/dist/chunk-TPB3I2AC.js.map +0 -1
  1010. package/dist/chunk-TPMQ3G6Z.js.map +0 -1
  1011. package/dist/chunk-TPU5L5EY.js.map +0 -1
  1012. package/dist/chunk-TZOLIGIG.js.map +0 -1
  1013. package/dist/chunk-U3WSW6PZ.js.map +0 -1
  1014. package/dist/chunk-U4SCL7B7.js.map +0 -1
  1015. package/dist/chunk-U66YHYC7.js +0 -31
  1016. package/dist/chunk-U66YHYC7.js.map +0 -1
  1017. package/dist/chunk-UWVJF25J.js.map +0 -1
  1018. package/dist/chunk-VBJ7V5SK.js.map +0 -1
  1019. package/dist/chunk-W3LR522O.js.map +0 -1
  1020. package/dist/chunk-W4L6CZKA.js.map +0 -1
  1021. package/dist/chunk-W6AQJ2PY.js.map +0 -1
  1022. package/dist/chunk-WELDCG6C.js.map +0 -1
  1023. package/dist/chunk-WNARATI3.js.map +0 -1
  1024. package/dist/chunk-WPGJYVUH.js.map +0 -1
  1025. package/dist/chunk-WW3QQF4H.js.map +0 -1
  1026. package/dist/chunk-XIG5PDM7.js.map +0 -1
  1027. package/dist/chunk-XKECPATV.js.map +0 -1
  1028. package/dist/chunk-XKLD5OK4.js.map +0 -1
  1029. package/dist/chunk-XSZEP4SF.js.map +0 -1
  1030. package/dist/chunk-XVVIG67A.js.map +0 -1
  1031. package/dist/chunk-XYIK4LF6.js.map +0 -1
  1032. package/dist/chunk-YRMVARQP.js.map +0 -1
  1033. package/dist/chunk-YROHKYBY.js.map +0 -1
  1034. package/dist/chunk-YU5KIWYQ.js.map +0 -1
  1035. package/dist/chunk-ZAVUCJ4H.js.map +0 -1
  1036. package/dist/chunk-ZPKBYX2F.js.map +0 -1
  1037. package/dist/chunk-ZTFCYYEZ.js.map +0 -1
  1038. package/dist/chunk-ZYVPLJ4T.js.map +0 -1
  1039. package/dist/path-MR5JPYOP.js +0 -9
  1040. package/dist/state-store-VZU2IA53.js +0 -16
  1041. package/dist/trace-C5ETWBEF.js.map +0 -1
  1042. /package/dist/{capsule-crypto-5CYAGVC5.js.map → bulk-import/index.js.map} +0 -0
  1043. /package/dist/{contradiction-review-ATP4S6IC.js.map → capsule-crypto-7FJQINUR.js.map} +0 -0
  1044. /package/dist/{capsule-merge-4MGKE7C5.js.map → capsule-merge-T2JRE46P.js.map} +0 -0
  1045. /package/dist/{chunk-SAZS2QZB.js.map → chunk-23UORJ4S.js.map} +0 -0
  1046. /package/dist/{chunk-PK7H5L6Y.js.map → chunk-2NM43EWN.js.map} +0 -0
  1047. /package/dist/{chunk-PYXS46O7.js.map → chunk-3BP57I6J.js.map} +0 -0
  1048. /package/dist/{chunk-FBYESMQ2.js.map → chunk-3C5RPJAX.js.map} +0 -0
  1049. /package/dist/{chunk-U7EJOMFC.js.map → chunk-4Q73JBSM.js.map} +0 -0
  1050. /package/dist/{chunk-N53K2EXC.js.map → chunk-6VF75M3X.js.map} +0 -0
  1051. /package/dist/{chunk-6H2TESSP.js.map → chunk-765K3SAT.js.map} +0 -0
  1052. /package/dist/{chunk-EDTHC6UD.js.map → chunk-77NAFXUD.js.map} +0 -0
  1053. /package/dist/{chunk-MGKYQQYF.js.map → chunk-7Q3RCKAQ.js.map} +0 -0
  1054. /package/dist/{chunk-34DQE4KF.js.map → chunk-CO7ZO4TU.js.map} +0 -0
  1055. /package/dist/{chunk-ZKSK55RC.js.map → chunk-ETUPBUHB.js.map} +0 -0
  1056. /package/dist/{chunk-QRNI5JBH.js.map → chunk-EYIEWJNI.js.map} +0 -0
  1057. /package/dist/{chunk-C6QPK5GG.js.map → chunk-FZZ2QTJI.js.map} +0 -0
  1058. /package/dist/{chunk-3JXBXXM2.js.map → chunk-G4IAEX6D.js.map} +0 -0
  1059. /package/dist/{chunk-2WWLHTZY.js.map → chunk-IC4GELZE.js.map} +0 -0
  1060. /package/dist/{chunk-PCUKNJAZ.js.map → chunk-JKV57BTN.js.map} +0 -0
  1061. /package/dist/{chunk-2KI4QFHU.js.map → chunk-LMDRGRJ2.js.map} +0 -0
  1062. /package/dist/{chunk-MY6TPVXW.js.map → chunk-LMPHTYJC.js.map} +0 -0
  1063. /package/dist/{chunk-5HRY2WRF.js.map → chunk-LZ3VEOU5.js.map} +0 -0
  1064. /package/dist/{chunk-NGAVDO7E.js.map → chunk-OADWQ5CR.js.map} +0 -0
  1065. /package/dist/{chunk-DOM4GKSW.js.map → chunk-OZKVVUJB.js.map} +0 -0
  1066. /package/dist/{chunk-MT4HVDUZ.js.map → chunk-PM3QHTFT.js.map} +0 -0
  1067. /package/dist/{chunk-ZK7I7JYV.js.map → chunk-R3PS27B4.js.map} +0 -0
  1068. /package/dist/{chunk-SKE7JYKA.js.map → chunk-SFXKHM7P.js.map} +0 -0
  1069. /package/dist/{chunk-HMDCOMYU.js.map → chunk-SKGV326D.js.map} +0 -0
  1070. /package/dist/{chunk-5UM2VJ6D.js.map → chunk-UEY3VB6W.js.map} +0 -0
  1071. /package/dist/{chunk-GIF42EW3.js.map → chunk-UP6MOYCB.js.map} +0 -0
  1072. /package/dist/{chunk-MRILGULB.js.map → chunk-V2RCP53Q.js.map} +0 -0
  1073. /package/dist/{chunk-FSFEQI74.js.map → chunk-W7L6HXUC.js.map} +0 -0
  1074. /package/dist/{chunk-3IQ2TR4N.js.map → chunk-WLEB7WCG.js.map} +0 -0
  1075. /package/dist/{chunk-GL6I6MEQ.js.map → chunk-WSGF57U2.js.map} +0 -0
  1076. /package/dist/{chunk-JA3AK3PT.js.map → chunk-XNLXAWHX.js.map} +0 -0
  1077. /package/dist/{chunk-SIC6U3GZ.js.map → chunk-YHV3KRKS.js.map} +0 -0
  1078. /package/dist/{chunk-VLXA6PI2.js.map → chunk-YQMZ7IH2.js.map} +0 -0
  1079. /package/dist/{contradiction-scan-5A4IDZV5.js.map → contradiction-review-6V2LXXK6.js.map} +0 -0
  1080. /package/dist/{migrate-from-identity-anchor-G27MCD6A.js.map → contradiction-scan-GIRVC4C7.js.map} +0 -0
  1081. /package/dist/{first-start-migration-4MHQEOSD.js.map → first-start-migration-CKTCTCQI.js.map} +0 -0
  1082. /package/dist/{graph-edge-decay-5DI5GUNL.js.map → graph-edge-decay-MUP5J7CC.js.map} +0 -0
  1083. /package/dist/{path-MR5JPYOP.js.map → importers/index.js.map} +0 -0
  1084. /package/dist/{peers-HCVGHMAE.js.map → migrate-from-identity-anchor-EB4XI4Q2.js.map} +0 -0
  1085. /package/dist/{resolution-B7FNQSSP.js.map → path-X2K5XCHL.js.map} +0 -0
  1086. /package/dist/{state-store-VZU2IA53.js.map → peers/index.js.map} +0 -0
  1087. /package/dist/{tier-stats-62ZVDFKS.js.map → tier-stats-SKML2OSF.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/network/webdav.ts"],"sourcesContent":["import { constants } from \"node:fs\";\nimport type { FileHandle } from \"node:fs/promises\";\nimport { mkdir, open, readdir, realpath, stat } from \"node:fs/promises\";\nimport { createServer, type IncomingMessage, type Server, type ServerResponse } from \"node:http\";\nimport { timingSafeEqual } from \"node:crypto\";\nimport path from \"node:path\";\nimport { pipeline } from \"node:stream/promises\";\nimport { URL } from \"node:url\";\n\nexport function hostToUrlAuthority(host: string): string {\n if (host.includes(\":\") && !host.startsWith(\"[\") && !host.endsWith(\"]\")) {\n return `[${host}]`;\n }\n return host;\n}\n\nexport interface WebDavAuth {\n username: string;\n password: string;\n}\n\nexport interface WebDavServerOptions {\n enabled?: boolean;\n host?: string;\n port: number;\n allowlistDirs: string[];\n auth?: WebDavAuth;\n}\n\nexport interface WebDavServerStatus {\n running: boolean;\n host: string;\n port: number;\n rootCount: number;\n}\n\ninterface AllowedRoot {\n absolute: string;\n name: string;\n}\n\ntype WebDavReadOpenResult =\n | { ok: true; handle: FileHandle; size: number }\n | { ok: false; code: number; message: string };\n\nfunction validateWebDavAuth(auth: WebDavAuth): WebDavAuth {\n if (typeof auth.username !== \"string\" || auth.username.trim().length === 0) {\n throw new Error(\"webdav auth.username must be a non-empty string\");\n }\n if (typeof auth.password !== \"string\" || auth.password.trim().length === 0) {\n throw new Error(\"webdav auth.password must be a non-empty string\");\n }\n return auth;\n}\n\nexport async function openWebDavFileForRead(absolutePath: string): Promise<WebDavReadOpenResult> {\n let handle: FileHandle | null = null;\n try {\n handle = await open(absolutePath, constants.O_RDONLY | constants.O_NOFOLLOW);\n const info = await handle.stat();\n if (!info.isFile()) {\n await handle.close().catch(() => {});\n return { ok: false, code: 403, message: \"path is not a file\" };\n }\n return { ok: true, handle, size: info.size };\n } catch (err) {\n await handle?.close().catch(() => {});\n const code = (err as NodeJS.ErrnoException).code;\n if (code === \"ELOOP\") {\n return { ok: false, code: 403, message: \"path escaped allowlist via symlink\" };\n }\n if (code === \"ENOENT\" || code === \"ENOTDIR\") {\n return { ok: false, code: 404, message: \"not found\" };\n }\n return { ok: false, code: 404, message: \"not found\" };\n }\n}\n\nexport class WebDavServer {\n private readonly options: Required<Omit<WebDavServerOptions, \"auth\">> & Pick<WebDavServerOptions, \"auth\">;\n private readonly allowedRoots: AllowedRoot[];\n private server: Server | null = null;\n private startPromise: Promise<WebDavServerStatus> | null = null;\n private listening = false;\n private boundPort: number;\n\n private constructor(\n options: Required<Omit<WebDavServerOptions, \"auth\">> & Pick<WebDavServerOptions, \"auth\">,\n allowedRoots: AllowedRoot[],\n ) {\n this.options = options;\n this.allowedRoots = allowedRoots;\n this.boundPort = options.port;\n }\n\n static async create(input: WebDavServerOptions): Promise<WebDavServer> {\n const options: Required<Omit<WebDavServerOptions, \"auth\">> & Pick<WebDavServerOptions, \"auth\"> = {\n enabled: input.enabled ?? false,\n host: input.host ?? \"127.0.0.1\",\n port: input.port,\n allowlistDirs: input.allowlistDirs,\n auth: input.auth ? validateWebDavAuth(input.auth) : undefined,\n };\n\n if (!Array.isArray(options.allowlistDirs) || options.allowlistDirs.length === 0) {\n throw new Error(\"webdav allowlistDirs must include at least one directory\");\n }\n if (!Number.isInteger(options.port) || options.port < 0 || options.port > 65535) {\n throw new Error(`invalid webdav port: ${options.port}`);\n }\n\n const allowedRoots: AllowedRoot[] = [];\n const aliasSet = new Set<string>();\n for (const dir of options.allowlistDirs) {\n const resolved = path.resolve(dir);\n await mkdir(resolved, { recursive: true });\n const canonical = await realpath(resolved);\n const alias = path.basename(canonical) || \"root\";\n if (aliasSet.has(alias)) {\n throw new Error(`duplicate webdav allowlist alias: ${alias}`);\n }\n aliasSet.add(alias);\n allowedRoots.push({ absolute: canonical, name: alias });\n }\n\n return new WebDavServer(options, allowedRoots);\n }\n\n async start(): Promise<WebDavServerStatus> {\n if (!this.options.enabled) {\n throw new Error(\"webdav server is disabled; set enabled=true to start\");\n }\n if (this.server && this.listening) {\n return this.status();\n }\n if (this.startPromise) return this.startPromise;\n\n const server = createServer((req, res) => {\n this.handle(req, res).catch((err) => {\n if (res.headersSent) {\n res.destroy(err as Error);\n return;\n }\n res.writeHead(500, { \"Content-Type\": \"text/plain; charset=utf-8\" });\n res.end(\"webdav error\");\n });\n });\n this.server = server;\n this.listening = false;\n\n this.startPromise = (async () => {\n try {\n await new Promise<void>((resolve, reject) => {\n const onError = (err: Error) => {\n server.removeListener(\"listening\", onListening);\n server.removeListener(\"close\", onClose);\n reject(err);\n };\n const onListening = () => {\n server.removeListener(\"error\", onError);\n server.removeListener(\"close\", onClose);\n resolve();\n };\n const onClose = () => {\n server.removeListener(\"error\", onError);\n server.removeListener(\"listening\", onListening);\n reject(new Error(\"webdav server closed before listening\"));\n };\n server.once(\"error\", onError);\n server.once(\"listening\", onListening);\n server.once(\"close\", onClose);\n server.listen(this.options.port, this.options.host);\n });\n } catch (err) {\n if (this.server === server) {\n this.server = null;\n }\n this.listening = false;\n server.close();\n throw err;\n }\n\n const address = server.address();\n if (address && typeof address !== \"string\") {\n this.boundPort = address.port;\n }\n this.listening = true;\n\n return this.status();\n })();\n\n try {\n return await this.startPromise;\n } finally {\n this.startPromise = null;\n }\n }\n\n async stop(): Promise<void> {\n if (!this.server) return;\n const server = this.server;\n const pendingStart = this.startPromise;\n await new Promise<void>((resolve, reject) => {\n server.close((err) => {\n if (err && (err as NodeJS.ErrnoException).code !== \"ERR_SERVER_NOT_RUNNING\") {\n reject(err);\n return;\n }\n resolve();\n });\n });\n await pendingStart?.catch(() => undefined);\n if (this.server === server) {\n this.server = null;\n }\n this.listening = false;\n this.boundPort = this.options.port;\n }\n\n status(): WebDavServerStatus {\n return {\n running: this.server !== null && this.listening,\n host: this.options.host,\n port: this.boundPort,\n rootCount: this.allowedRoots.length,\n };\n }\n\n private async handle(req: IncomingMessage, res: ServerResponse): Promise<void> {\n if (!this.isAuthorized(req)) {\n res.writeHead(401, {\n \"WWW-Authenticate\": 'Basic realm=\"Engram WebDAV\"',\n \"Content-Type\": \"text/plain; charset=utf-8\",\n });\n res.end(\"authentication required\");\n return;\n }\n\n const method = (req.method ?? \"GET\").toUpperCase();\n if (method === \"OPTIONS\") {\n res.writeHead(204, {\n Allow: \"OPTIONS, PROPFIND, GET, HEAD\",\n DAV: \"1\",\n });\n res.end();\n return;\n }\n\n const parsed = new URL(req.url ?? \"/\", `http://${hostToUrlAuthority(this.options.host)}`);\n const resolved = await this.resolvePath(parsed.pathname);\n if (!resolved.ok) {\n res.writeHead(resolved.code, { \"Content-Type\": \"text/plain; charset=utf-8\" });\n res.end(resolved.message);\n return;\n }\n\n if (method === \"PROPFIND\") {\n await this.handlePropfind(resolved.absolutePath, resolved.rootAbsolute, resolved.displayPath, res);\n return;\n }\n\n if (method === \"GET\" || method === \"HEAD\") {\n await this.handleRead(method, resolved.absolutePath, resolved.rootAbsolute, res);\n return;\n }\n\n res.writeHead(405, {\n Allow: \"OPTIONS, PROPFIND, GET, HEAD\",\n \"Content-Type\": \"text/plain; charset=utf-8\",\n });\n res.end(\"method not allowed\");\n }\n\n private isAuthorized(req: IncomingMessage): boolean {\n if (!this.options.auth) return true;\n const raw = req.headers.authorization;\n if (!raw) return false;\n const separator = raw.indexOf(\" \");\n if (separator <= 0) return false;\n const scheme = raw.slice(0, separator).toLowerCase();\n if (scheme !== \"basic\") return false;\n const encodedPart = raw.slice(separator + 1).trim();\n if (!encodedPart) return false;\n\n try {\n const decoded = Buffer.from(encodedPart, \"base64\").toString(\"utf-8\");\n const credentialSeparator = decoded.indexOf(\":\");\n if (credentialSeparator < 0) return false;\n const username = decoded.slice(0, credentialSeparator);\n const password = decoded.slice(credentialSeparator + 1);\n const usernameOk = this.timingSafeStringEqual(username, this.options.auth.username);\n const passwordOk = this.timingSafeStringEqual(password, this.options.auth.password);\n return Boolean((usernameOk ? 1 : 0) & (passwordOk ? 1 : 0));\n } catch {\n return false;\n }\n }\n\n private timingSafeStringEqual(a: string, b: string): boolean {\n const left = this.encodeAuthField(a);\n const right = this.encodeAuthField(b);\n if (!left || !right) return false;\n return timingSafeEqual(left, right);\n }\n\n private encodeAuthField(value: string): Buffer | null {\n const maxBytes = 512;\n const encoded = Buffer.from(value, \"utf-8\");\n if (encoded.length > maxBytes) return null;\n const out = Buffer.alloc(2 + maxBytes);\n out.writeUInt16BE(encoded.length, 0);\n encoded.copy(out, 2);\n return out;\n }\n\n private async resolvePath(requestPathname: string): Promise<\n | { ok: true; absolutePath: string; displayPath: string; rootAbsolute: string }\n | { ok: false; code: number; message: string }\n > {\n let decodedPath: string;\n try {\n decodedPath = decodeURIComponent(requestPathname || \"/\");\n } catch {\n return { ok: false, code: 400, message: \"invalid path encoding\" };\n }\n if (decodedPath.includes(\"\\0\")) {\n return { ok: false, code: 400, message: \"invalid path\" };\n }\n\n const normalized = path.posix.normalize(decodedPath);\n const segments = normalized.split(\"/\").filter((segment) => segment.length > 0);\n\n if (segments.length === 0) {\n return { ok: false, code: 403, message: \"root listing is not allowed\" };\n }\n\n const rootName = segments[0];\n const root = this.allowedRoots.find((entry) => entry.name === rootName);\n if (!root) {\n return { ok: false, code: 403, message: \"path is outside allowlist\" };\n }\n\n const relative = segments.slice(1);\n if (relative.some((segment) => segment === \"..\" || segment.includes(\"\\\\\"))) {\n return { ok: false, code: 403, message: \"path traversal is not allowed\" };\n }\n\n const candidate = path.resolve(root.absolute, ...relative);\n if (!this.isPathInside(root.absolute, candidate)) {\n return { ok: false, code: 403, message: \"path escaped allowlist\" };\n }\n\n try {\n const canonicalCandidate = await realpath(candidate);\n if (!this.isPathInside(root.absolute, canonicalCandidate)) {\n return { ok: false, code: 403, message: \"path escaped allowlist via symlink\" };\n }\n return { ok: true, absolutePath: canonicalCandidate, displayPath: `/${segments.join(\"/\")}`, rootAbsolute: root.absolute };\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === \"ENOENT\") {\n return { ok: true, absolutePath: candidate, displayPath: `/${segments.join(\"/\")}`, rootAbsolute: root.absolute };\n }\n if (code === \"ENOTDIR\" || code === \"ELOOP\") {\n return { ok: false, code: 400, message: \"invalid path\" };\n }\n throw err;\n }\n }\n\n private async handleRead(\n method: \"GET\" | \"HEAD\",\n absolutePath: string,\n rootAbsolute: string,\n res: ServerResponse,\n ): Promise<void> {\n const revalidated = await this.revalidatePathInsideRoot(absolutePath, rootAbsolute);\n if (!revalidated.ok) {\n res.writeHead(revalidated.code, { \"Content-Type\": \"text/plain; charset=utf-8\" });\n res.end(revalidated.message);\n return;\n }\n const opened = await openWebDavFileForRead(revalidated.absolutePath);\n if (!opened.ok) {\n res.writeHead(opened.code, { \"Content-Type\": \"text/plain; charset=utf-8\" });\n res.end(opened.message);\n return;\n }\n\n const { handle, size } = opened;\n\n try {\n res.writeHead(200, {\n \"Content-Length\": String(size),\n \"Content-Type\": \"application/octet-stream\",\n });\n\n if (method === \"HEAD\") {\n res.end();\n return;\n }\n\n await pipeline(handle.createReadStream({ autoClose: false }), res);\n } finally {\n await handle.close().catch(() => {});\n }\n }\n\n private async handlePropfind(\n absolutePath: string,\n rootAbsolute: string,\n displayPath: string,\n res: ServerResponse,\n ): Promise<void> {\n const revalidated = await this.revalidatePathInsideRoot(absolutePath, rootAbsolute);\n if (!revalidated.ok) {\n res.writeHead(revalidated.code, { \"Content-Type\": \"text/plain; charset=utf-8\" });\n res.end(revalidated.message);\n return;\n }\n absolutePath = revalidated.absolutePath;\n let info;\n try {\n info = await stat(absolutePath);\n } catch {\n res.writeHead(404, { \"Content-Type\": \"text/plain; charset=utf-8\" });\n res.end(\"not found\");\n return;\n }\n\n const entries: string[] = [];\n if (info.isDirectory()) {\n const children = await readdir(absolutePath, { withFileTypes: true });\n for (const child of children) {\n const childHref = toEncodedHref(`${displayPath.replace(/\\/$/, \"\")}/${child.name}`);\n entries.push(`\n <d:response>\n <d:href>${xmlEscape(childHref)}</d:href>\n <d:propstat><d:prop><d:resourcetype>${child.isDirectory() ? \"<d:collection/>\" : \"\"}</d:resourcetype></d:prop><d:status>HTTP/1.1 200 OK</d:status></d:propstat>\n </d:response>`);\n }\n }\n\n const xml = `<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<d:multistatus xmlns:d=\"DAV:\">\n <d:response>\n <d:href>${xmlEscape(toEncodedHref(displayPath))}</d:href>\n <d:propstat><d:prop><d:resourcetype>${info.isDirectory() ? \"<d:collection/>\" : \"\"}</d:resourcetype></d:prop><d:status>HTTP/1.1 200 OK</d:status></d:propstat>\n </d:response>${entries.join(\"\")}\n</d:multistatus>`;\n\n res.writeHead(207, { \"Content-Type\": \"application/xml; charset=utf-8\" });\n res.end(xml);\n }\n\n private isPathInside(root: string, target: string): boolean {\n if (target === root) return true;\n if (root === path.parse(root).root) {\n return target.startsWith(root);\n }\n return target.startsWith(`${root}${path.sep}`);\n }\n\n private async revalidatePathInsideRoot(\n absolutePath: string,\n rootAbsolute: string,\n ): Promise<\n | { ok: true; absolutePath: string }\n | { ok: false; code: number; message: string }\n > {\n try {\n const canonical = await realpath(absolutePath);\n if (!this.isPathInside(rootAbsolute, canonical)) {\n return { ok: false, code: 403, message: \"path escaped allowlist via symlink\" };\n }\n return { ok: true, absolutePath: canonical };\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === \"ENOENT\" || code === \"ENOTDIR\") {\n return { ok: false, code: 404, message: \"not found\" };\n }\n if (code === \"ELOOP\") {\n return { ok: false, code: 403, message: \"path escaped allowlist via symlink\" };\n }\n throw err;\n }\n }\n}\n\nfunction xmlEscape(value: string): string {\n return value\n .replaceAll(\"&\", \"&amp;\")\n .replaceAll(\"<\", \"&lt;\")\n .replaceAll(\">\", \"&gt;\")\n .replaceAll('\"', \"&quot;\")\n .replaceAll(\"'\", \"&apos;\");\n}\n\nfunction toEncodedHref(pathname: string): string {\n return pathname\n .split(\"/\")\n .map((segment) => encodeURIComponent(segment))\n .join(\"/\");\n}\n"],"mappings":"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","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  StorageManager
3
- } from "./chunk-VBJ7V5SK.js";
3
+ } from "./chunk-UIPDNLXA.js";
4
4
 
5
5
  // src/semantic-rule-promotion.ts
6
6
  function normalizeRuleWhitespace(value) {
@@ -132,4 +132,4 @@ async function promoteSemanticRuleFromMemory(options) {
132
132
  export {
133
133
  promoteSemanticRuleFromMemory
134
134
  };
135
- //# sourceMappingURL=chunk-MRILGULB.js.map
135
+ //# sourceMappingURL=chunk-V2RCP53Q.js.map
@@ -1,7 +1,7 @@
1
1
  // src/access-idempotency.ts
2
2
  import { mkdir, open, readFile, rename, stat, unlink, utimes, writeFile } from "fs/promises";
3
3
  import path from "path";
4
- import { createHash } from "crypto";
4
+ import { createHash, randomUUID } from "crypto";
5
5
  var testHooks = null;
6
6
  function stableStringify(value) {
7
7
  return JSON.stringify(value, (_key, candidate) => {
@@ -136,8 +136,17 @@ var AccessIdempotencyStore = class {
136
136
  const lockHeartbeatMs = testHooks?.lockHeartbeatMs ?? Math.max(1e3, Math.floor(staleLockMs / 3));
137
137
  const startedAt = Date.now();
138
138
  while (true) {
139
+ const ownerToken = `${process.pid}:${randomUUID()}`;
139
140
  try {
140
141
  const handle = await open(lockPath, "wx");
142
+ try {
143
+ await testHooks?.beforeLockOwnerWrite?.(lockPath, ownerToken);
144
+ await handle.writeFile(ownerToken, "utf-8");
145
+ } catch (error) {
146
+ await handle.close().catch(() => void 0);
147
+ await unlink(lockPath).catch(() => void 0);
148
+ throw error;
149
+ }
141
150
  let heartbeat = null;
142
151
  if (lockHeartbeatMs > 0) {
143
152
  heartbeat = setInterval(() => {
@@ -152,14 +161,24 @@ var AccessIdempotencyStore = class {
152
161
  clearInterval(heartbeat);
153
162
  }
154
163
  await handle.close().catch(() => void 0);
155
- await unlink(lockPath).catch(() => void 0);
164
+ await unlinkLockIfOwner(lockPath, ownerToken, staleLockMs);
156
165
  }
157
166
  } catch (error) {
158
167
  if (!isAlreadyExistsError(error)) throw error;
159
168
  try {
160
169
  const lockStat = await stat(lockPath);
170
+ const lockOwner = await readLockOwner(lockPath);
161
171
  if (Date.now() - lockStat.mtimeMs > staleLockMs) {
162
- await unlink(lockPath).catch(() => void 0);
172
+ await testHooks?.beforeStaleLockUnlink?.();
173
+ const removed = await unlinkStaleLockIfUnchanged({
174
+ lockPath,
175
+ observedOwner: lockOwner,
176
+ observedMtimeMs: lockStat.mtimeMs,
177
+ staleLockMs
178
+ });
179
+ if (!removed) {
180
+ await sleep(10);
181
+ }
163
182
  continue;
164
183
  }
165
184
  } catch {
@@ -190,6 +209,96 @@ var AccessIdempotencyStore = class {
190
209
  function isAlreadyExistsError(error) {
191
210
  return typeof error === "object" && error !== null && "code" in error && error.code === "EEXIST";
192
211
  }
212
+ async function readLockOwner(lockPath) {
213
+ try {
214
+ return await readFile(lockPath, "utf-8");
215
+ } catch {
216
+ return null;
217
+ }
218
+ }
219
+ async function unlinkLockIfOwner(lockPath, ownerToken, staleLockMs) {
220
+ const reclaimHandle = await openStaleReclaimLock(`${lockPath}.reclaim`, staleLockMs);
221
+ if (!reclaimHandle) return;
222
+ try {
223
+ await reclaimHandle.writeFile(`${process.pid}:${Date.now()}`, "utf-8");
224
+ await unlinkLockIfOwnerWhileReclaimHeld(lockPath, ownerToken);
225
+ } finally {
226
+ await reclaimHandle.close().catch(() => void 0);
227
+ await unlink(`${lockPath}.reclaim`).catch(() => void 0);
228
+ }
229
+ }
230
+ async function unlinkLockIfOwnerWhileReclaimHeld(lockPath, ownerToken) {
231
+ let handle;
232
+ try {
233
+ handle = await open(lockPath, "r");
234
+ } catch {
235
+ return;
236
+ }
237
+ try {
238
+ const openedStat = await handle.stat();
239
+ const currentOwner = await handle.readFile("utf-8");
240
+ if (currentOwner !== ownerToken) return;
241
+ let currentStat;
242
+ try {
243
+ currentStat = await stat(lockPath);
244
+ } catch {
245
+ return;
246
+ }
247
+ if (!isSameFileIdentity(openedStat, currentStat)) return;
248
+ } finally {
249
+ await handle.close().catch(() => void 0);
250
+ }
251
+ await unlink(lockPath).catch(() => void 0);
252
+ }
253
+ function isSameFileIdentity(left, right) {
254
+ return left.dev === right.dev && left.ino === right.ino;
255
+ }
256
+ async function unlinkStaleLockIfUnchanged(options) {
257
+ const reclaimPath = `${options.lockPath}.reclaim`;
258
+ const reclaimHandle = await openStaleReclaimLock(reclaimPath, options.staleLockMs);
259
+ if (!reclaimHandle) return false;
260
+ try {
261
+ await reclaimHandle.writeFile(`${process.pid}:${Date.now()}`, "utf-8");
262
+ return await unlinkStaleLockIfStillOwned(options);
263
+ } finally {
264
+ await reclaimHandle.close().catch(() => void 0);
265
+ await unlink(reclaimPath).catch(() => void 0);
266
+ }
267
+ }
268
+ async function openStaleReclaimLock(reclaimPath, staleLockMs) {
269
+ try {
270
+ return await open(reclaimPath, "wx");
271
+ } catch (error) {
272
+ if (!isAlreadyExistsError(error)) throw error;
273
+ }
274
+ try {
275
+ const reclaimStat = await stat(reclaimPath);
276
+ if (Date.now() - reclaimStat.mtimeMs <= staleLockMs) return null;
277
+ await unlink(reclaimPath);
278
+ } catch {
279
+ return null;
280
+ }
281
+ try {
282
+ return await open(reclaimPath, "wx");
283
+ } catch (error) {
284
+ if (isAlreadyExistsError(error)) return null;
285
+ throw error;
286
+ }
287
+ }
288
+ async function unlinkStaleLockIfStillOwned(options) {
289
+ let currentStat;
290
+ try {
291
+ currentStat = await stat(options.lockPath);
292
+ } catch {
293
+ return true;
294
+ }
295
+ if (currentStat.mtimeMs !== options.observedMtimeMs) return false;
296
+ if (Date.now() - currentStat.mtimeMs <= options.staleLockMs) return false;
297
+ const currentOwner = await readLockOwner(options.lockPath);
298
+ if (currentOwner !== options.observedOwner) return false;
299
+ await unlink(options.lockPath);
300
+ return true;
301
+ }
193
302
  function sleep(ms) {
194
303
  return new Promise((resolve) => setTimeout(resolve, ms));
195
304
  }
@@ -199,4 +308,4 @@ export {
199
308
  setAccessIdempotencyTestHooks,
200
309
  AccessIdempotencyStore
201
310
  };
202
- //# sourceMappingURL=chunk-XKECPATV.js.map
311
+ //# sourceMappingURL=chunk-VFUEZZBS.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/access-idempotency.ts"],"sourcesContent":["import { mkdir, open, readFile, rename, stat, unlink, utimes, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { createHash, randomUUID } from \"node:crypto\";\n\ntype AccessIdempotencyEntry = {\n recordedAt: string;\n requestHash: string;\n response: unknown;\n};\n\ntype AccessIdempotencyTestHooks = {\n beforeFlushWrite?: () => Promise<void> | void;\n lockTimeoutMs?: number;\n staleLockMs?: number;\n lockHeartbeatMs?: number;\n beforeLockOwnerWrite?: (lockPath: string, ownerToken: string) => Promise<void> | void;\n beforeStaleLockUnlink?: () => Promise<void> | void;\n};\n\nlet testHooks: AccessIdempotencyTestHooks | null = null;\n\nfunction stableStringify(value: unknown): string {\n return JSON.stringify(value, (_key, candidate) => {\n if (!candidate || typeof candidate !== \"object\" || Array.isArray(candidate)) {\n return candidate;\n }\n return Object.keys(candidate)\n .sort()\n .reduce<Record<string, unknown>>((acc, key) => {\n acc[key] = (candidate as Record<string, unknown>)[key];\n return acc;\n }, {});\n });\n}\n\nexport function hashAccessIdempotencyPayload(payload: unknown): string {\n return createHash(\"sha256\").update(stableStringify(payload)).digest(\"hex\");\n}\n\nexport function setAccessIdempotencyTestHooks(hooks: AccessIdempotencyTestHooks | null): void {\n testHooks = hooks;\n}\n\nexport class AccessIdempotencyStore {\n private readonly statePath: string;\n private readonly lockPath: string;\n private readonly keyLockDir: string;\n private loadedMtimeMs = 0;\n private state: Record<string, AccessIdempotencyEntry> = {};\n private writeQueue: Promise<void> = Promise.resolve();\n\n constructor(memoryDir: string) {\n this.statePath = path.join(memoryDir, \"state\", \"access-idempotency.json\");\n this.lockPath = `${this.statePath}.lock`;\n this.keyLockDir = path.join(memoryDir, \"state\", \"access-idempotency-locks\");\n }\n\n async get(key: string, requestHash: string): Promise<{ response?: unknown; conflict: boolean }> {\n await this.writeQueue.catch(() => {});\n await this.reload({ forceRefresh: true });\n const entry = this.state[key];\n if (!entry) return { conflict: false };\n if (entry.requestHash !== requestHash) {\n return { conflict: true };\n }\n return {\n conflict: false,\n response: JSON.parse(JSON.stringify(entry.response)),\n };\n }\n\n async put(key: string, requestHash: string, response: unknown): Promise<void> {\n await this.withWriteQueue(async () => {\n await this.reload({ forceRefresh: true });\n this.state[key] = {\n recordedAt: new Date().toISOString(),\n requestHash,\n response: JSON.parse(JSON.stringify(response)),\n };\n await this.prune();\n await this.flush();\n });\n }\n\n async withKeyLock<T>(key: string, callback: () => Promise<T>): Promise<T> {\n const keyHash = createHash(\"sha256\").update(key).digest(\"hex\");\n const keyLockPath = path.join(this.keyLockDir, `${keyHash}.lock`);\n return this.withExclusiveFileLock(keyLockPath, callback);\n }\n\n private async reload(options: { forceRefresh?: boolean } = {}): Promise<void> {\n if (options.forceRefresh === true) {\n try {\n const fileStat = await stat(this.statePath);\n if (fileStat.mtimeMs < this.loadedMtimeMs) {\n return;\n }\n } catch {\n this.state = {};\n this.loadedMtimeMs = 0;\n return;\n }\n }\n try {\n const raw = await readFile(this.statePath, \"utf-8\");\n const parsed = JSON.parse(raw) as Record<string, AccessIdempotencyEntry>;\n if (parsed && typeof parsed === \"object\") {\n this.state = parsed;\n this.loadedMtimeMs = await this.readMtimeMs();\n return;\n }\n } catch {\n // Missing or malformed state should fail open to an empty store.\n }\n this.state = {};\n this.loadedMtimeMs = 0;\n }\n\n private async prune(): Promise<void> {\n const entries = Object.entries(this.state);\n if (entries.length <= 512) return;\n entries\n .sort((left, right) => right[1].recordedAt.localeCompare(left[1].recordedAt))\n .slice(512)\n .forEach(([key]) => {\n delete this.state[key];\n });\n }\n\n private async flush(): Promise<void> {\n await mkdir(path.dirname(this.statePath), { recursive: true });\n await this.withExclusiveFileLock(this.lockPath, async () => {\n try {\n const raw = await readFile(this.statePath, \"utf-8\");\n const parsed = JSON.parse(raw) as Record<string, AccessIdempotencyEntry>;\n if (parsed && typeof parsed === \"object\") {\n this.state = {\n ...parsed,\n ...this.state,\n };\n await this.prune();\n }\n } catch {\n // Fail open when there is no pre-existing shared state to merge.\n }\n\n await testHooks?.beforeFlushWrite?.();\n\n const tempPath = `${this.statePath}.${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}.tmp`;\n try {\n await writeFile(tempPath, JSON.stringify(this.state, null, 2), \"utf-8\");\n await rename(tempPath, this.statePath);\n } finally {\n await unlink(tempPath).catch(() => undefined);\n }\n this.loadedMtimeMs = await this.readMtimeMs();\n });\n }\n\n private async readMtimeMs(): Promise<number> {\n try {\n return (await stat(this.statePath)).mtimeMs;\n } catch {\n return 0;\n }\n }\n\n private async withExclusiveFileLock<T>(lockPath: string, callback: () => Promise<T>): Promise<T> {\n await mkdir(path.dirname(lockPath), { recursive: true });\n const timeoutMs = testHooks?.lockTimeoutMs ?? 5_000;\n const staleLockMs = testHooks?.staleLockMs ?? 30_000;\n const lockHeartbeatMs = testHooks?.lockHeartbeatMs ?? Math.max(1_000, Math.floor(staleLockMs / 3));\n const startedAt = Date.now();\n\n while (true) {\n const ownerToken = `${process.pid}:${randomUUID()}`;\n try {\n const handle = await open(lockPath, \"wx\");\n try {\n await testHooks?.beforeLockOwnerWrite?.(lockPath, ownerToken);\n await handle.writeFile(ownerToken, \"utf-8\");\n } catch (error) {\n await handle.close().catch(() => undefined);\n await unlink(lockPath).catch(() => undefined);\n throw error;\n }\n let heartbeat: NodeJS.Timeout | null = null;\n if (lockHeartbeatMs > 0) {\n heartbeat = setInterval(() => {\n void utimes(lockPath, new Date(), new Date()).catch(() => undefined);\n }, lockHeartbeatMs);\n heartbeat.unref?.();\n }\n try {\n return await callback();\n } finally {\n if (heartbeat) {\n clearInterval(heartbeat);\n }\n await handle.close().catch(() => undefined);\n await unlinkLockIfOwner(lockPath, ownerToken, staleLockMs);\n }\n } catch (error) {\n if (!isAlreadyExistsError(error)) throw error;\n try {\n const lockStat = await stat(lockPath);\n const lockOwner = await readLockOwner(lockPath);\n if (Date.now() - lockStat.mtimeMs > staleLockMs) {\n await testHooks?.beforeStaleLockUnlink?.();\n const removed = await unlinkStaleLockIfUnchanged({\n lockPath,\n observedOwner: lockOwner,\n observedMtimeMs: lockStat.mtimeMs,\n staleLockMs,\n });\n if (!removed) {\n await sleep(10);\n }\n continue;\n }\n } catch {\n continue;\n }\n if (Date.now() - startedAt > timeoutMs) {\n throw new Error(\"timed out acquiring access idempotency lock\");\n }\n await sleep(10);\n }\n }\n }\n\n private async withWriteQueue<T>(callback: () => Promise<T>): Promise<T> {\n const previous = this.writeQueue;\n let release!: () => void;\n this.writeQueue = new Promise<void>((resolve) => {\n release = resolve;\n });\n await previous.catch(() => {});\n try {\n return await callback();\n } finally {\n release();\n }\n }\n}\n\nfunction isAlreadyExistsError(error: unknown): boolean {\n return typeof error === \"object\" && error !== null && \"code\" in error && error.code === \"EEXIST\";\n}\n\nasync function readLockOwner(lockPath: string): Promise<string | null> {\n try {\n return await readFile(lockPath, \"utf-8\");\n } catch {\n return null;\n }\n}\n\nasync function unlinkLockIfOwner(lockPath: string, ownerToken: string, staleLockMs: number): Promise<void> {\n const reclaimHandle = await openStaleReclaimLock(`${lockPath}.reclaim`, staleLockMs);\n if (!reclaimHandle) return;\n try {\n await reclaimHandle.writeFile(`${process.pid}:${Date.now()}`, \"utf-8\");\n await unlinkLockIfOwnerWhileReclaimHeld(lockPath, ownerToken);\n } finally {\n await reclaimHandle.close().catch(() => undefined);\n await unlink(`${lockPath}.reclaim`).catch(() => undefined);\n }\n}\n\nasync function unlinkLockIfOwnerWhileReclaimHeld(lockPath: string, ownerToken: string): Promise<void> {\n let handle: Awaited<ReturnType<typeof open>>;\n try {\n handle = await open(lockPath, \"r\");\n } catch {\n return;\n }\n try {\n const openedStat = await handle.stat();\n const currentOwner = await handle.readFile(\"utf-8\");\n if (currentOwner !== ownerToken) return;\n let currentStat: Awaited<ReturnType<typeof stat>>;\n try {\n currentStat = await stat(lockPath);\n } catch {\n return;\n }\n if (!isSameFileIdentity(openedStat, currentStat)) return;\n } finally {\n await handle.close().catch(() => undefined);\n }\n await unlink(lockPath).catch(() => undefined);\n}\n\nfunction isSameFileIdentity(left: Awaited<ReturnType<typeof stat>>, right: Awaited<ReturnType<typeof stat>>): boolean {\n return left.dev === right.dev && left.ino === right.ino;\n}\n\nasync function unlinkStaleLockIfUnchanged(options: {\n lockPath: string;\n observedOwner: string | null;\n observedMtimeMs: number;\n staleLockMs: number;\n}): Promise<boolean> {\n const reclaimPath = `${options.lockPath}.reclaim`;\n const reclaimHandle = await openStaleReclaimLock(reclaimPath, options.staleLockMs);\n if (!reclaimHandle) return false;\n try {\n await reclaimHandle.writeFile(`${process.pid}:${Date.now()}`, \"utf-8\");\n return await unlinkStaleLockIfStillOwned(options);\n } finally {\n await reclaimHandle.close().catch(() => undefined);\n await unlink(reclaimPath).catch(() => undefined);\n }\n}\n\nasync function openStaleReclaimLock(\n reclaimPath: string,\n staleLockMs: number,\n): Promise<Awaited<ReturnType<typeof open>> | null> {\n try {\n return await open(reclaimPath, \"wx\");\n } catch (error) {\n if (!isAlreadyExistsError(error)) throw error;\n }\n\n try {\n const reclaimStat = await stat(reclaimPath);\n if (Date.now() - reclaimStat.mtimeMs <= staleLockMs) return null;\n await unlink(reclaimPath);\n } catch {\n return null;\n }\n\n try {\n return await open(reclaimPath, \"wx\");\n } catch (error) {\n if (isAlreadyExistsError(error)) return null;\n throw error;\n }\n}\n\nasync function unlinkStaleLockIfStillOwned(options: {\n lockPath: string;\n observedOwner: string | null;\n observedMtimeMs: number;\n staleLockMs: number;\n}): Promise<boolean> {\n let currentStat: Awaited<ReturnType<typeof stat>>;\n try {\n currentStat = await stat(options.lockPath);\n } catch {\n return true;\n }\n if (currentStat.mtimeMs !== options.observedMtimeMs) return false;\n if (Date.now() - currentStat.mtimeMs <= options.staleLockMs) return false;\n const currentOwner = await readLockOwner(options.lockPath);\n if (currentOwner !== options.observedOwner) return false;\n await unlink(options.lockPath);\n return true;\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n"],"mappings":"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","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  readUtilityLearningSnapshot
3
- } from "./chunk-PYXS46O7.js";
3
+ } from "./chunk-3BP57I6J.js";
4
4
  import {
5
5
  clamp01
6
6
  } from "./chunk-TBBDFYXW.js";
@@ -65,4 +65,4 @@ export {
65
65
  applyUtilityRankingRuntimeDelta,
66
66
  applyUtilityPromotionRuntimePolicy
67
67
  };
68
- //# sourceMappingURL=chunk-FSFEQI74.js.map
68
+ //# sourceMappingURL=chunk-W7L6HXUC.js.map
@@ -2,7 +2,7 @@ import {
2
2
  discoverMemoryExtensions,
3
3
  renderExtensionsFooter,
4
4
  resolveExtensionsRoot
5
- } from "./chunk-EJI5XIBB.js";
5
+ } from "./chunk-JLNBQWZ2.js";
6
6
  import {
7
7
  log
8
8
  } from "./chunk-2ODBA7MQ.js";
@@ -113,4 +113,4 @@ export {
113
113
  formatDaySummaryMemories,
114
114
  buildExtensionsFooterForSummary
115
115
  };
116
- //# sourceMappingURL=chunk-3IQ2TR4N.js.map
116
+ //# sourceMappingURL=chunk-WLEB7WCG.js.map
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  parseMessageParts
3
- } from "./chunk-3APJ5EVB.js";
3
+ } from "./chunk-XKIQZXUB.js";
4
4
  import {
5
5
  recordObjectiveStateSnapshot
6
- } from "./chunk-5UM2VJ6D.js";
6
+ } from "./chunk-UEY3VB6W.js";
7
7
 
8
8
  // src/objective-state-writers.ts
9
9
  import crypto from "crypto";
@@ -644,4 +644,4 @@ export {
644
644
  recordObjectiveStateSnapshotsFromAgentMessages,
645
645
  recordObjectiveStateSnapshotsFromObservedMessages
646
646
  };
647
- //# sourceMappingURL=chunk-GL6I6MEQ.js.map
647
+ //# sourceMappingURL=chunk-WSGF57U2.js.map
@@ -3,6 +3,10 @@ import {
3
3
  readHeader,
4
4
  secureStoreDir
5
5
  } from "./chunk-BJMBJZ2Y.js";
6
+ import {
7
+ KDF_SALT_LENGTH,
8
+ deriveKey
9
+ } from "./chunk-FP2373TW.js";
6
10
  import {
7
11
  open,
8
12
  seal
@@ -68,7 +72,14 @@ async function decryptCapsuleFile(opts) {
68
72
  `decryptCapsuleFile: unsupported encrypted-capsule format version ${version} (this build supports versions 1 and 2): ${opts.encPath}`
69
73
  );
70
74
  }
71
- const { key, envelopeOffset } = resolveKeyAndOffset(buf, version, opts.memoryDir, "decryptCapsuleFile", opts.encPath);
75
+ const { key, envelopeOffset } = resolveKeyAndOffset(
76
+ buf,
77
+ version,
78
+ opts.memoryDir,
79
+ "decryptCapsuleFile",
80
+ opts.encPath,
81
+ opts.passphrase
82
+ );
72
83
  const envelope = buf.subarray(envelopeOffset);
73
84
  const basename = path.basename(opts.encPath);
74
85
  const aad = Buffer.from(basename, "utf-8");
@@ -84,7 +95,7 @@ async function decryptCapsuleFile(opts) {
84
95
  await writeFile(gzPath, plaintext);
85
96
  return { gzPath };
86
97
  }
87
- async function decryptCapsuleFileInMemory(encPath, memoryDir) {
98
+ async function decryptCapsuleFileInMemory(encPath, memoryDir, options = {}) {
88
99
  const buf = await readFile(encPath);
89
100
  if (buf.length < MIN_ENC_SIZE_V1) {
90
101
  throw new Error(
@@ -102,7 +113,14 @@ async function decryptCapsuleFileInMemory(encPath, memoryDir) {
102
113
  `decryptCapsuleFileInMemory: unsupported encrypted-capsule format version ${version} (this build supports versions 1 and 2): ${encPath}`
103
114
  );
104
115
  }
105
- const { key, envelopeOffset } = resolveKeyAndOffset(buf, version, memoryDir, "decryptCapsuleFileInMemory", encPath);
116
+ const { key, envelopeOffset } = resolveKeyAndOffset(
117
+ buf,
118
+ version,
119
+ memoryDir,
120
+ "decryptCapsuleFileInMemory",
121
+ encPath,
122
+ options.passphrase
123
+ );
106
124
  const envelope = buf.subarray(envelopeOffset);
107
125
  const basename = path.basename(encPath);
108
126
  const aad = Buffer.from(basename, "utf-8");
@@ -142,16 +160,21 @@ async function loadKdfSection(memoryDir) {
142
160
  return { json, salt };
143
161
  }
144
162
  function getKeyOrThrow(memoryDir, action) {
163
+ if (!memoryDir) {
164
+ throw new Error(
165
+ `Secure-store memoryDir is required \u2014 cannot ${action} without either an unlocked keyring or a format-v2 passphrase.`
166
+ );
167
+ }
145
168
  const storeId = secureStoreDir(memoryDir);
146
169
  const key = getKey(storeId);
147
170
  if (key === null) {
148
171
  throw new Error(
149
- `Secure-store is locked or not initialized \u2014 cannot ${action}. Run \`remnic secure-store unlock\` first, or \`remnic secure-store init\` if the store has never been initialized.`
172
+ `Secure-store is locked or not initialized \u2014 cannot ${action}. Run \`remnic secure-store unlock\` first, provide the original passphrase for a format-v2 archive restore, or run \`remnic secure-store init\` if the store has never been initialized.`
150
173
  );
151
174
  }
152
175
  return key;
153
176
  }
154
- function resolveKeyAndOffset(buf, version, memoryDir, caller, encPath) {
177
+ function resolveKeyAndOffset(buf, version, memoryDir, caller, encPath, passphrase) {
155
178
  if (version === 1) {
156
179
  const key2 = getKeyOrThrow(memoryDir, "decrypt capsule");
157
180
  return { key: key2, envelopeOffset: MAGIC.length + 1 };
@@ -169,10 +192,53 @@ function resolveKeyAndOffset(buf, version, memoryDir, caller, encPath) {
169
192
  `${caller}: file too short for format v2 KDF params section (expected ${kdfLen} bytes): ${encPath}`
170
193
  );
171
194
  }
195
+ if (kdfLen <= 0) {
196
+ throw new Error(`${caller}: format v2 KDF params section is empty: ${encPath}`);
197
+ }
198
+ const kdfJson = buf.subarray(kdfJsonOffset, kdfJsonOffset + kdfLen).toString("utf-8");
199
+ const kdf = parseEmbeddedKdfSection(kdfJson, caller, encPath);
172
200
  const envelopeOffset = kdfJsonOffset + kdfLen;
201
+ if (passphrase !== void 0) {
202
+ if (passphrase.length === 0) {
203
+ throw new Error(`${caller}: passphrase must not be empty for format v2 archive restore`);
204
+ }
205
+ const key2 = deriveKey(kdf.algorithm, passphrase, kdf.salt, kdf.params);
206
+ return { key: key2, envelopeOffset };
207
+ }
173
208
  const key = getKeyOrThrow(memoryDir, "decrypt capsule");
174
209
  return { key, envelopeOffset };
175
210
  }
211
+ function parseEmbeddedKdfSection(json, caller, encPath) {
212
+ let parsed;
213
+ try {
214
+ parsed = JSON.parse(json);
215
+ } catch (cause) {
216
+ throw new Error(`${caller}: format v2 KDF params are not valid JSON: ${encPath}`, { cause });
217
+ }
218
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
219
+ throw new Error(`${caller}: format v2 KDF params must be a JSON object: ${encPath}`);
220
+ }
221
+ const obj = parsed;
222
+ const algorithm = obj.algorithm;
223
+ if (algorithm !== "scrypt" && algorithm !== "argon2id") {
224
+ throw new Error(`${caller}: unsupported format v2 KDF algorithm ${String(algorithm)}: ${encPath}`);
225
+ }
226
+ if (typeof obj.params !== "object" || obj.params === null || Array.isArray(obj.params)) {
227
+ throw new Error(`${caller}: format v2 KDF params.params must be an object: ${encPath}`);
228
+ }
229
+ if (typeof obj.salt !== "string" || !/^[0-9a-fA-F]+$/.test(obj.salt) || obj.salt.length % 2 !== 0) {
230
+ throw new Error(`${caller}: format v2 KDF salt must be an even-length hex string: ${encPath}`);
231
+ }
232
+ const salt = Buffer.from(obj.salt, "hex");
233
+ if (salt.length !== KDF_SALT_LENGTH) {
234
+ throw new Error(`${caller}: format v2 KDF salt decoded to ${salt.length} bytes, expected ${KDF_SALT_LENGTH}: ${encPath}`);
235
+ }
236
+ return {
237
+ algorithm,
238
+ params: obj.params,
239
+ salt
240
+ };
241
+ }
176
242
 
177
243
  export {
178
244
  isEncryptedCapsuleFile,
@@ -180,4 +246,4 @@ export {
180
246
  decryptCapsuleFile,
181
247
  decryptCapsuleFileInMemory
182
248
  };
183
- //# sourceMappingURL=chunk-KNKUID7G.js.map
249
+ //# sourceMappingURL=chunk-X7Y7WX73.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/transfer/capsule-crypto.ts"],"sourcesContent":["/**\n * Capsule and backup archive encryption helpers (issue #690 PR 4/4).\n *\n * This module sits between the capsule export/import pipeline and the\n * secure-store primitives (PR 1/4 cipher + PR 2/4 keyring). It handles:\n *\n * - Wrapping a raw `.capsule.json.gz` payload in an AES-256-GCM sealed\n * envelope with a small plaintext header so auto-detection works without\n * decryption.\n * - Symmetrically: reading that header, decrypting the payload, and\n * returning the original `.capsule.json.gz` bytes.\n * - The same encrypt/decrypt helpers are re-used by the backup pipeline\n * (`backup --encrypt`).\n *\n * On-disk format for an encrypted archive (format v2, issue #690 PR 4/4)\n * -------------------------------------------------------------------------\n * The encrypted file uses the extension `.capsule.json.gz.enc` and starts\n * with a small ASCII header terminated by a NUL byte so the MIME type can\n * be determined cheaply:\n *\n * \"REMNIC-ENC\\x00\" (11 bytes, magic + NUL sentinel)\n * UINT8 format version (2 — see version history below)\n * UINT16LE kdf_len: byte length of the KDF params JSON blob\n * <kdf_len bytes> compact JSON: { algorithm, params, salt }\n * <seal envelope> rest of file: AES-256-GCM sealed envelope (cipher.ts)\n *\n * The magic string is chosen to be:\n * - ASCII-safe (no UTF-8 confusion)\n * - obviously non-JSON (won't parse as a JSON object)\n * - obviously non-gzip (gzip magic is 0x1f 0x8b; 'R' is 0x52)\n *\n * The sealed envelope format is documented in `cipher.ts`:\n * [VERSION:1][SALT:16][IV:12][AUTHTAG:16][CIPHERTEXT:...]\n *\n * The original gzip bytes are the ciphertext. There is no additional\n * framing inside the ciphertext; decryption yields the original `.gz`\n * bytes verbatim.\n *\n * AAD\n * ---\n * The file's basename (without the `.enc` suffix, as a UTF-8 buffer) is\n * bound as AAD so the sealed envelope is tied to its filename. Renaming an\n * encrypted capsule file causes auth-tag failure on open. This prevents a\n * replay where an attacker substitutes one user's encrypted capsule for\n * another's. Callers MUST supply the same basename on encrypt and decrypt.\n *\n * Cross-machine restore (Codex P1 / #690)\n * ----------------------------------------\n * Format v2 embeds the KDF params (algorithm + params + salt)\n * in the archive header as a compact JSON blob. Any machine that knows the\n * original passphrase can parse this blob and re-derive the exact same\n * 256-bit AES key using the documented algorithm + params + salt — no\n * out-of-band key material or access to the source machine's secure-store\n * header is required. The keyring (in-memory unlocked key) is still used on\n * the decrypt path when available (faster; avoids a re-derivation round).\n */\n\nimport { open as openFileHandle, readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport { open, seal } from \"../secure-store/cipher.js\";\nimport * as keyring from \"../secure-store/keyring.js\";\nimport { readHeader, secureStoreDir } from \"../secure-store/header.js\";\nimport {\n deriveKey,\n KDF_SALT_LENGTH,\n type Argon2idParams,\n type KdfAlgorithm,\n type ScryptParams,\n} from \"../secure-store/kdf.js\";\n\n// ---------------------------------------------------------------------------\n// On-disk magic\n// ---------------------------------------------------------------------------\n\n/** ASCII magic + NUL sentinel — 11 bytes total. */\nconst MAGIC = Buffer.from(\"REMNIC-ENC\\x00\", \"ascii\");\n\n/**\n * Current format version byte.\n *\n * Version history:\n * 1 — original format: MAGIC(11) + VERSION(1) + ENVELOPE(...)\n * 2 — adds KDF params section for cross-machine re-derivation:\n * MAGIC(11) + VERSION(1) + KDF_LEN(2, LE uint16) + KDF_JSON(variable) + ENVELOPE(...)\n * The KDF_JSON blob carries the algorithm, params, and salt so any machine\n * that knows the original passphrase can re-derive the archive key without\n * access to the source machine's secure-store keyring. (Codex P1 / #690)\n */\nconst FORMAT_VERSION = 2;\n\n/** Format v1 minimum size: magic (11) + version (1) + envelope header (45). */\nconst MIN_ENC_SIZE_V1 = MAGIC.length + 1 + 45; // 45 = cipher.ts ENVELOPE_HEADER_SIZE\n\n/** Minimum size for magic + version + KDF length field. */\nconst MIN_ENC_SIZE = MAGIC.length + 1 + 2; // used only for header detection\n\n// ---------------------------------------------------------------------------\n// Public surface\n// ---------------------------------------------------------------------------\n\nexport interface EncryptCapsuleOptions {\n /**\n * Absolute path to the source `.capsule.json.gz` (or `.backup.tar.gz`)\n * payload to encrypt.\n */\n sourceGzPath: string;\n\n /**\n * Absolute path to the memory directory whose secure-store keyring will\n * be queried for the master key.\n */\n memoryDir: string;\n\n /**\n * Destination path for the encrypted output. If omitted, defaults to\n * `sourceGzPath + \".enc\"`.\n */\n outPath?: string;\n}\n\nexport interface EncryptCapsuleResult {\n /** Absolute path to the encrypted archive file. */\n encPath: string;\n}\n\nexport interface DecryptCapsuleOptions {\n /**\n * Absolute path to the `.enc` encrypted archive to decrypt.\n */\n encPath: string;\n\n /**\n * Absolute path to the memory directory whose secure-store keyring will\n * be queried for the master key when no passphrase is supplied. Required\n * for v1 archives, optional for v2 passphrase-based restores.\n */\n memoryDir?: string;\n\n /**\n * Original secure-store passphrase. For format-v2 archives this is used\n * with the embedded KDF params to restore on a machine that does not have\n * the source memory directory's unlocked keyring entry.\n */\n passphrase?: string;\n\n /**\n * Destination path for the decrypted output. If omitted, defaults to\n * `encPath` with the `.enc` suffix removed.\n */\n outPath?: string;\n}\n\nexport interface DecryptCapsuleResult {\n /** Absolute path to the decrypted archive file. */\n gzPath: string;\n}\n\n/**\n * Return `true` iff the given file path ends with `.enc` AND its first bytes\n * match the REMNIC-ENC magic header.\n *\n * Reads only the first `MAGIC.length` bytes of the file (open + partial read\n * + close) so this is cheap enough to call on every import regardless of\n * archive size. (Codex P2 / Cursor — previously read the entire file.)\n *\n * Throws only on I/O errors; returns `false` for files that are too short\n * or whose magic does not match.\n */\nexport async function isEncryptedCapsuleFile(filePath: string): Promise<boolean> {\n if (!filePath.endsWith(\".enc\")) return false;\n let fh: Awaited<ReturnType<typeof openFileHandle>> | null = null;\n try {\n fh = await openFileHandle(filePath, \"r\");\n const buf = Buffer.allocUnsafe(MAGIC.length);\n const { bytesRead } = await fh.read(buf, 0, MAGIC.length, 0);\n if (bytesRead < MAGIC.length) return false;\n return buf.equals(MAGIC);\n } catch {\n return false;\n } finally {\n if (fh !== null) {\n await fh.close().catch(() => undefined);\n }\n }\n}\n\n/**\n * Encrypt a `.capsule.json.gz` (or `.backup.tar.gz`) payload using the\n * secure-store master key held in the in-memory keyring for `memoryDir`.\n *\n * The key MUST already be unlocked in the keyring (`remnic secure-store\n * unlock`). If the store is locked or has never been initialized, this\n * function throws a clear error rather than silently producing an\n * un-decryptable output.\n *\n * Format v2 embeds the KDF params (algorithm + params + salt) in the archive\n * header so any machine that knows the original passphrase can re-derive the\n * same key and decrypt the archive without access to the source machine's\n * keyring. (Codex P1 — cross-machine restore.)\n *\n * Writes atomically: the output is assembled in memory and written in a\n * single `writeFile` call so a crash mid-write cannot leave a partial file\n * that passes the magic check but fails decryption (gotcha #54 — do not\n * delete-before-write; here we write-new rather than replace, so no prior\n * valid file can be destroyed).\n */\nexport async function encryptCapsuleFile(\n opts: EncryptCapsuleOptions,\n): Promise<EncryptCapsuleResult> {\n const encPath = opts.outPath ?? `${opts.sourceGzPath}.enc`;\n const key = getKeyOrThrow(opts.memoryDir, \"encrypt capsule\");\n\n // Read the source payload.\n const plaintext = await readFile(opts.sourceGzPath);\n\n // Bind the output filename (without .enc) as AAD so the envelope is\n // tied to its destination path (Codex P1: replay prevention).\n const basename = path.basename(encPath);\n const aad = Buffer.from(basename, \"utf-8\");\n\n // Load the secure-store header to extract KDF params + canonical salt.\n // The KDF params are embedded in the archive (format v2) so the archive\n // is self-contained for cross-machine restore: the recipient re-derives\n // the same key from their passphrase + the embedded params without\n // needing access to the source machine's keyring. (Codex P1 / #690)\n const kdfSection = await loadKdfSection(opts.memoryDir);\n\n const envelope = seal(key, kdfSection.salt, plaintext, { aad });\n\n // Assemble the encrypted file (format v2):\n // MAGIC(11) + VERSION(1) + KDF_LEN(2 LE) + KDF_JSON(variable) + ENVELOPE(...)\n const versionBuf = Buffer.alloc(1);\n versionBuf.writeUInt8(FORMAT_VERSION, 0);\n\n const kdfJsonBuf = Buffer.from(kdfSection.json, \"utf-8\");\n const kdfLenBuf = Buffer.alloc(2);\n kdfLenBuf.writeUInt16LE(kdfJsonBuf.length, 0);\n\n const output = Buffer.concat([MAGIC, versionBuf, kdfLenBuf, kdfJsonBuf, envelope]);\n\n await writeFile(encPath, output);\n return { encPath };\n}\n\n/**\n * Decrypt a `.enc` encrypted capsule or backup archive.\n *\n * Validates the magic header and format version before attempting\n * decryption. Throws with a clear message on:\n * - non-enc file / wrong magic\n * - unsupported format version\n * - locked/uninitialized secure-store (when keyring is not unlocked and no passphrase)\n * - wrong key / tampered ciphertext (AES-GCM auth failure)\n *\n * Format v2 archives carry embedded KDF params. If a `passphrase` is\n * provided, the key is re-derived from the passphrase + embedded KDF params\n * for cross-machine restore. Without a passphrase, an unlocked keyring key\n * from `memoryDir` is used directly.\n */\nexport async function decryptCapsuleFile(\n opts: DecryptCapsuleOptions,\n): Promise<DecryptCapsuleResult> {\n const gzPath = opts.outPath ?? opts.encPath.replace(/\\.enc$/, \"\");\n\n const buf = await readFile(opts.encPath);\n\n // Magic check.\n if (buf.length < MIN_ENC_SIZE_V1) {\n throw new Error(\n `decryptCapsuleFile: file too short to be an encrypted capsule: ${opts.encPath}`,\n );\n }\n if (!buf.subarray(0, MAGIC.length).equals(MAGIC)) {\n throw new Error(\n `decryptCapsuleFile: file does not start with REMNIC-ENC magic: ${opts.encPath}`,\n );\n }\n\n // Version check.\n const version = buf.readUInt8(MAGIC.length);\n if (version !== 1 && version !== 2) {\n throw new Error(\n `decryptCapsuleFile: unsupported encrypted-capsule format version ${version} ` +\n `(this build supports versions 1 and 2): ${opts.encPath}`,\n );\n }\n\n // Resolve the decryption key and the envelope offset.\n const { key, envelopeOffset } = resolveKeyAndOffset(\n buf,\n version,\n opts.memoryDir,\n \"decryptCapsuleFile\",\n opts.encPath,\n opts.passphrase,\n );\n\n // The sealed envelope starts at `envelopeOffset`.\n const envelope = buf.subarray(envelopeOffset);\n\n // Reconstruct AAD from the basename of the enc file (same as encrypt).\n const basename = path.basename(opts.encPath);\n const aad = Buffer.from(basename, \"utf-8\");\n\n let plaintext: Buffer;\n try {\n plaintext = open(key, envelope, { aad });\n } catch (cause) {\n throw new Error(\n `decryptCapsuleFile: authentication failed — wrong passphrase, ` +\n `tampered archive, or key mismatch. ` +\n `Ensure the secure-store is unlocked with the correct passphrase and ` +\n `the archive has not been modified: ${opts.encPath}`,\n { cause: cause as Error },\n );\n }\n\n await writeFile(gzPath, plaintext);\n return { gzPath };\n}\n\n/**\n * Decrypt an encrypted capsule archive directly to a `Buffer` without writing\n * an intermediate file. Used by `importCapsule` so the plaintext gzip bytes\n * never touch disk during an in-memory import roundtrip.\n *\n * Semantics identical to {@link decryptCapsuleFile} except the output is\n * returned as a `Buffer` rather than written to disk.\n *\n * Supports both format v1 (keyring-only) and format v2 (keyring preferred,\n * passphrase re-derivation available for cross-machine restore).\n */\nexport async function decryptCapsuleFileInMemory(\n encPath: string,\n memoryDir?: string,\n options: { passphrase?: string } = {},\n): Promise<Buffer> {\n const buf = await readFile(encPath);\n\n if (buf.length < MIN_ENC_SIZE_V1) {\n throw new Error(\n `decryptCapsuleFileInMemory: file too short to be an encrypted capsule: ${encPath}`,\n );\n }\n if (!buf.subarray(0, MAGIC.length).equals(MAGIC)) {\n throw new Error(\n `decryptCapsuleFileInMemory: file does not start with REMNIC-ENC magic: ${encPath}`,\n );\n }\n\n const version = buf.readUInt8(MAGIC.length);\n if (version !== 1 && version !== 2) {\n throw new Error(\n `decryptCapsuleFileInMemory: unsupported encrypted-capsule format version ${version} ` +\n `(this build supports versions 1 and 2): ${encPath}`,\n );\n }\n\n const { key, envelopeOffset } = resolveKeyAndOffset(\n buf,\n version,\n memoryDir,\n \"decryptCapsuleFileInMemory\",\n encPath,\n options.passphrase,\n );\n const envelope = buf.subarray(envelopeOffset);\n\n const basename = path.basename(encPath);\n const aad = Buffer.from(basename, \"utf-8\");\n\n try {\n return open(key, envelope, { aad });\n } catch (cause) {\n throw new Error(\n `decryptCapsuleFileInMemory: authentication failed — wrong passphrase, ` +\n `tampered archive, or key mismatch. ` +\n `Ensure the secure-store is unlocked with the correct passphrase and ` +\n `the archive has not been modified: ${encPath}`,\n { cause: cause as Error },\n );\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Serializable KDF section embedded in format-v2 archives.\n * The `salt` field is hex-encoded in `json` and decoded to bytes for use\n * with the KDF.\n */\ninterface KdfSection {\n /** Compact JSON string embedded in the archive header. */\n json: string;\n /** Decoded salt bytes (same value as the `salt` field in `json`). */\n salt: Buffer;\n}\n\ninterface ParsedKdfSection {\n algorithm: KdfAlgorithm;\n params: ScryptParams | Argon2idParams;\n salt: Buffer;\n}\n\n/**\n * Read the KDF params + canonical salt from the secure-store header and\n * return both a compact JSON representation (for embedding in the archive)\n * and the salt buffer (for passing to `seal`).\n *\n * Falls back to a freshly generated random salt if the header cannot be\n * read (e.g. in tests that skip header init). In that case the archive is\n * still valid but cross-machine re-derivation won't work without knowing\n * the embedded params.\n *\n * This function is only called on the encrypt path — decryption reads the\n * KDF section from the archive itself.\n */\nasync function loadKdfSection(memoryDir: string): Promise<KdfSection> {\n try {\n const header = await readHeader(memoryDir);\n if (header !== null) {\n const { decodeMetadataSalt } = await import(\"../secure-store/metadata.js\");\n const salt = decodeMetadataSalt(header.metadata);\n const kdf = header.metadata.kdf;\n const json = JSON.stringify({\n algorithm: kdf.algorithm,\n params: kdf.params,\n salt: salt.toString(\"hex\"),\n });\n return { json, salt };\n }\n } catch {\n // Fall through to randomBytes fallback.\n }\n const { generateSalt } = await import(\"../secure-store/cipher.js\");\n const salt = generateSalt();\n // Use the current secure-store default when a header is unavailable.\n const { DEFAULT_ARGON2ID_PARAMS } = await import(\"../secure-store/kdf.js\");\n const json = JSON.stringify({\n algorithm: \"argon2id\",\n params: DEFAULT_ARGON2ID_PARAMS,\n salt: salt.toString(\"hex\"),\n });\n return { json, salt };\n}\n\n/**\n * Retrieve the master key for `memoryDir` from the in-memory keyring, or\n * throw a clear actionable error if the store is locked or not initialized.\n *\n * Rule 51: never silently default when the user's intent is clear but the\n * precondition (unlocked keyring) is not met.\n */\nfunction getKeyOrThrow(memoryDir: string | undefined, action: string): Buffer {\n if (!memoryDir) {\n throw new Error(\n `Secure-store memoryDir is required — cannot ${action} without either an unlocked keyring or a format-v2 passphrase.`,\n );\n }\n const storeId = secureStoreDir(memoryDir);\n const key = keyring.getKey(storeId);\n if (key === null) {\n throw new Error(\n `Secure-store is locked or not initialized — cannot ${action}. ` +\n `Run \\`remnic secure-store unlock\\` first, provide the original passphrase for ` +\n `a format-v2 archive restore, or run \\`remnic secure-store init\\` if the store ` +\n `has never been initialized.`,\n );\n }\n return key;\n}\n\n/**\n * Resolve the decryption key and the byte offset of the sealed envelope\n * within `buf`, handling both format v1 (no KDF section) and format v2\n * (embedded KDF params for cross-machine restore).\n *\n * For v2 archives: a caller-supplied passphrase is derived against the\n * embedded KDF section for cross-machine restore. Without a passphrase, the\n * keyring is used as the fast local path.\n *\n * The KDF-params section serves two roles:\n * 1. Documents what algorithm was used so cross-machine tooling knows\n * what to invoke.\n * 2. Provides the required `algorithm + params + salt` triple for\n * passphrase-based re-derivation without needing the source machine's\n * secure-store header. (Codex P1 / #690)\n */\nfunction resolveKeyAndOffset(\n buf: Buffer,\n version: number,\n memoryDir: string | undefined,\n caller: string,\n encPath: string,\n passphrase?: string,\n): { key: Buffer; envelopeOffset: number } {\n if (version === 1) {\n // v1: envelope starts immediately after magic (11) + version (1).\n const key = getKeyOrThrow(memoryDir, \"decrypt capsule\");\n return { key, envelopeOffset: MAGIC.length + 1 };\n }\n\n // v2: KDF_LEN(2 LE) + KDF_JSON(KDF_LEN bytes) + envelope.\n const kdfLenOffset = MAGIC.length + 1; // after magic + version\n if (buf.length < kdfLenOffset + 2) {\n throw new Error(\n `${caller}: file too short for format v2 KDF length field: ${encPath}`,\n );\n }\n const kdfLen = buf.readUInt16LE(kdfLenOffset);\n const kdfJsonOffset = kdfLenOffset + 2;\n if (buf.length < kdfJsonOffset + kdfLen) {\n throw new Error(\n `${caller}: file too short for format v2 KDF params section (expected ${kdfLen} bytes): ${encPath}`,\n );\n }\n if (kdfLen <= 0) {\n throw new Error(`${caller}: format v2 KDF params section is empty: ${encPath}`);\n }\n const kdfJson = buf.subarray(kdfJsonOffset, kdfJsonOffset + kdfLen).toString(\"utf-8\");\n const kdf = parseEmbeddedKdfSection(kdfJson, caller, encPath);\n const envelopeOffset = kdfJsonOffset + kdfLen;\n\n if (passphrase !== undefined) {\n if (passphrase.length === 0) {\n throw new Error(`${caller}: passphrase must not be empty for format v2 archive restore`);\n }\n const key = deriveKey(kdf.algorithm, passphrase, kdf.salt, kdf.params);\n return { key, envelopeOffset };\n }\n\n const key = getKeyOrThrow(memoryDir, \"decrypt capsule\");\n return { key, envelopeOffset };\n}\n\nfunction parseEmbeddedKdfSection(json: string, caller: string, encPath: string): ParsedKdfSection {\n let parsed: unknown;\n try {\n parsed = JSON.parse(json);\n } catch (cause) {\n throw new Error(`${caller}: format v2 KDF params are not valid JSON: ${encPath}`, { cause: cause as Error });\n }\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n throw new Error(`${caller}: format v2 KDF params must be a JSON object: ${encPath}`);\n }\n const obj = parsed as Record<string, unknown>;\n const algorithm = obj.algorithm;\n if (algorithm !== \"scrypt\" && algorithm !== \"argon2id\") {\n throw new Error(`${caller}: unsupported format v2 KDF algorithm ${String(algorithm)}: ${encPath}`);\n }\n if (typeof obj.params !== \"object\" || obj.params === null || Array.isArray(obj.params)) {\n throw new Error(`${caller}: format v2 KDF params.params must be an object: ${encPath}`);\n }\n if (typeof obj.salt !== \"string\" || !/^[0-9a-fA-F]+$/.test(obj.salt) || obj.salt.length % 2 !== 0) {\n throw new Error(`${caller}: format v2 KDF salt must be an even-length hex string: ${encPath}`);\n }\n const salt = Buffer.from(obj.salt, \"hex\");\n if (salt.length !== KDF_SALT_LENGTH) {\n throw new Error(`${caller}: format v2 KDF salt decoded to ${salt.length} bytes, expected ${KDF_SALT_LENGTH}: ${encPath}`);\n }\n return {\n algorithm,\n params: obj.params as ScryptParams | Argon2idParams,\n salt,\n };\n}\n"],"mappings":"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","names":["salt","json","key"]}
@@ -1,15 +1,23 @@
1
+ import {
2
+ writeFileAtomically
3
+ } from "./chunk-4426WSWL.js";
1
4
  import {
2
5
  log
3
6
  } from "./chunk-2ODBA7MQ.js";
4
7
 
5
8
  // src/relevance.ts
6
- import { mkdir, readFile, writeFile } from "fs/promises";
9
+ import { mkdir, readFile } from "fs/promises";
7
10
  import path from "path";
8
11
  var RelevanceStore = class {
9
12
  statePath;
13
+ writeStateFile;
10
14
  state = {};
11
- constructor(memoryDir) {
15
+ stateWriteChain = Promise.resolve();
16
+ constructor(memoryDir, options = {}) {
12
17
  this.statePath = path.join(memoryDir, "state", "relevance.json");
18
+ this.writeStateFile = options.writeStateFile ?? (async (filePath, content) => {
19
+ await writeFileAtomically(filePath, content);
20
+ });
13
21
  }
14
22
  async load() {
15
23
  try {
@@ -35,8 +43,7 @@ var RelevanceStore = class {
35
43
  };
36
44
  this.state[memoryId] = next;
37
45
  try {
38
- await mkdir(path.dirname(this.statePath), { recursive: true });
39
- await writeFile(this.statePath, JSON.stringify(this.state, null, 2), "utf-8");
46
+ await this.flushState();
40
47
  } catch (err) {
41
48
  log.debug(`relevance store write failed: ${err}`);
42
49
  }
@@ -52,9 +59,20 @@ var RelevanceStore = class {
52
59
  const down = Math.min(3, fb.down);
53
60
  return up * 0.05 - down * 0.1;
54
61
  }
62
+ flushState() {
63
+ const run = this.stateWriteChain.catch(() => void 0).then(async () => {
64
+ await mkdir(path.dirname(this.statePath), { recursive: true });
65
+ await this.writeStateFile(this.statePath, JSON.stringify(this.state, null, 2));
66
+ });
67
+ this.stateWriteChain = run.then(
68
+ () => void 0,
69
+ () => void 0
70
+ );
71
+ return run;
72
+ }
55
73
  };
56
74
 
57
75
  export {
58
76
  RelevanceStore
59
77
  };
60
- //# sourceMappingURL=chunk-5NPGSAVB.js.map
78
+ //# sourceMappingURL=chunk-XEKAG3FM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/relevance.ts"],"sourcesContent":["import { mkdir, readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { log } from \"./logger.js\";\nimport { writeFileAtomically } from \"./maintenance/atomic-file.js\";\nimport type { RelevanceFeedback } from \"./types.js\";\n\ntype RelevanceState = Record<string, RelevanceFeedback>;\ntype StateFileWriter = (filePath: string, content: string) => Promise<void>;\n\nexport class RelevanceStore {\n private readonly statePath: string;\n private readonly writeStateFile: StateFileWriter;\n private state: RelevanceState = {};\n private stateWriteChain: Promise<void> = Promise.resolve();\n\n constructor(memoryDir: string, options: { writeStateFile?: StateFileWriter } = {}) {\n this.statePath = path.join(memoryDir, \"state\", \"relevance.json\");\n this.writeStateFile =\n options.writeStateFile ??\n (async (filePath, content) => {\n await writeFileAtomically(filePath, content);\n });\n }\n\n async load(): Promise<void> {\n try {\n const raw = await readFile(this.statePath, \"utf-8\");\n const parsed = JSON.parse(raw) as RelevanceState;\n if (parsed && typeof parsed === \"object\") this.state = parsed;\n } catch {\n this.state = {};\n }\n }\n\n /**\n * Record a thumbs up/down for a memory ID.\n * This is intentionally lightweight; it should never block agent execution.\n */\n async record(memoryId: string, vote: \"up\" | \"down\", note?: string): Promise<void> {\n const now = new Date().toISOString();\n const existing = this.state[memoryId] ?? { up: 0, down: 0, lastUpdatedAt: now };\n const next: RelevanceFeedback = {\n up: existing.up + (vote === \"up\" ? 1 : 0),\n down: existing.down + (vote === \"down\" ? 1 : 0),\n lastUpdatedAt: now,\n notes: note\n ? [...(existing.notes ?? []).slice(-19), note]\n : existing.notes,\n };\n this.state[memoryId] = next;\n\n try {\n await this.flushState();\n } catch (err) {\n log.debug(`relevance store write failed: ${err}`);\n }\n }\n\n /**\n * Convert feedback into a small score adjustment.\n * Intended to be used as a tie-breaker/soft bias, not a hard filter.\n */\n adjustment(memoryId: string): number {\n const fb = this.state[memoryId];\n if (!fb) return 0;\n\n // Cap effect to avoid runaway ranking distortion.\n const up = Math.min(3, fb.up);\n const down = Math.min(3, fb.down);\n\n // Typical QMD scores are around 0-1; keep adjustments small.\n return up * 0.05 - down * 0.10; // max +0.15, min -0.30\n }\n\n private flushState(): Promise<void> {\n const run = this.stateWriteChain.catch(() => undefined).then(async () => {\n await mkdir(path.dirname(this.statePath), { recursive: true });\n await this.writeStateFile(this.statePath, JSON.stringify(this.state, null, 2));\n });\n this.stateWriteChain = run.then(\n () => undefined,\n () => undefined,\n );\n return run;\n }\n}\n"],"mappings":";;;;;;;;AAAA,SAAS,OAAO,gBAAgB;AAChC,OAAO,UAAU;AAQV,IAAM,iBAAN,MAAqB;AAAA,EACT;AAAA,EACA;AAAA,EACT,QAAwB,CAAC;AAAA,EACzB,kBAAiC,QAAQ,QAAQ;AAAA,EAEzD,YAAY,WAAmB,UAAgD,CAAC,GAAG;AACjF,SAAK,YAAY,KAAK,KAAK,WAAW,SAAS,gBAAgB;AAC/D,SAAK,iBACH,QAAQ,mBACP,OAAO,UAAU,YAAY;AAC5B,YAAM,oBAAoB,UAAU,OAAO;AAAA,IAC7C;AAAA,EACJ;AAAA,EAEA,MAAM,OAAsB;AAC1B,QAAI;AACF,YAAM,MAAM,MAAM,SAAS,KAAK,WAAW,OAAO;AAClD,YAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,UAAI,UAAU,OAAO,WAAW,SAAU,MAAK,QAAQ;AAAA,IACzD,QAAQ;AACN,WAAK,QAAQ,CAAC;AAAA,IAChB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,OAAO,UAAkB,MAAqB,MAA8B;AAChF,UAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,UAAM,WAAW,KAAK,MAAM,QAAQ,KAAK,EAAE,IAAI,GAAG,MAAM,GAAG,eAAe,IAAI;AAC9E,UAAM,OAA0B;AAAA,MAC9B,IAAI,SAAS,MAAM,SAAS,OAAO,IAAI;AAAA,MACvC,MAAM,SAAS,QAAQ,SAAS,SAAS,IAAI;AAAA,MAC7C,eAAe;AAAA,MACf,OAAO,OACH,CAAC,IAAI,SAAS,SAAS,CAAC,GAAG,MAAM,GAAG,GAAG,IAAI,IAC3C,SAAS;AAAA,IACf;AACA,SAAK,MAAM,QAAQ,IAAI;AAEvB,QAAI;AACF,YAAM,KAAK,WAAW;AAAA,IACxB,SAAS,KAAK;AACZ,UAAI,MAAM,iCAAiC,GAAG,EAAE;AAAA,IAClD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,WAAW,UAA0B;AACnC,UAAM,KAAK,KAAK,MAAM,QAAQ;AAC9B,QAAI,CAAC,GAAI,QAAO;AAGhB,UAAM,KAAK,KAAK,IAAI,GAAG,GAAG,EAAE;AAC5B,UAAM,OAAO,KAAK,IAAI,GAAG,GAAG,IAAI;AAGhC,WAAO,KAAK,OAAO,OAAO;AAAA,EAC5B;AAAA,EAEQ,aAA4B;AAClC,UAAM,MAAM,KAAK,gBAAgB,MAAM,MAAM,MAAS,EAAE,KAAK,YAAY;AACvE,YAAM,MAAM,KAAK,QAAQ,KAAK,SAAS,GAAG,EAAE,WAAW,KAAK,CAAC;AAC7D,YAAM,KAAK,eAAe,KAAK,WAAW,KAAK,UAAU,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,IAC/E,CAAC;AACD,SAAK,kBAAkB,IAAI;AAAA,MACzB,MAAM;AAAA,MACN,MAAM;AAAA,IACR;AACA,WAAO;AAAA,EACT;AACF;","names":[]}