@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
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/operator-toolkit.ts"],"sourcesContent":["import path from \"node:path\";\nimport { constants as fsConstants } from \"node:fs\";\nimport { access, mkdir, readFile, readdir, stat, unlink, writeFile } from \"node:fs/promises\";\nimport { lintWorkspaceFiles } from \"./hygiene.js\";\nimport { parseConfig } from \"./config.js\";\nimport { readEnvVar, resolveHomeDir } from \"./runtime/env.js\";\nimport { resolveRemnicPluginEntry } from \"./plugin-id.js\";\nimport {\n resolveCuratedIncludeFilesStatePath,\n resolveNativeKnowledgeStatePath,\n resolveOpenClawWorkspaceStatePath,\n} from \"./native-knowledge.js\";\nimport { StorageManager } from \"./storage.js\";\nimport { listNamespaces } from \"./namespaces/migrate.js\";\nimport {\n createEvalBaselineSnapshot,\n getEvalHarnessStatus,\n runEvalBaselineDeltaReport,\n runEvalBenchmarkCiGate,\n validateEvalBenchmarkPack,\n type EvalBaselineDeltaReport,\n type EvalCiGateReport,\n type EvalHarnessStatus,\n} from \"./evals.js\";\nimport { analyzeGraphHealth, type GraphHealthReport } from \"./graph.js\";\nimport {\n analyzeSessionIntegrity,\n applySessionRepair,\n planSessionRepair,\n type SessionIntegrityReport,\n type SessionRepairApplyResult,\n type SessionRepairPlan,\n} from \"./session-integrity.js\";\nimport {\n listMemoryGovernanceRuns,\n readMemoryGovernanceRunArtifact,\n} from \"./maintenance/memory-governance.js\";\nimport {\n runConsolidationProvenanceCheck,\n type ConsolidationProvenanceReport,\n} from \"./consolidation-provenance-check.js\";\nimport type {\n BufferSurpriseEvent,\n DreamsPhasesConfig,\n FileHygieneConfig,\n MemoryFile,\n PluginConfig,\n} from \"./types.js\";\nimport { reportBufferSurpriseDistribution } from \"./buffer-surprise-report.js\";\nimport { readJudgeVerdictStats } from \"./extraction-judge-telemetry.js\";\n\ninterface QmdRuntimeLike {\n probe(): Promise<boolean>;\n isAvailable(): boolean;\n ensureCollection(memoryDir: string): Promise<\"present\" | \"missing\" | \"unknown\" | \"skipped\">;\n debugStatus(): string;\n}\n\nfunction isMissingPathError(error: unknown): boolean {\n return typeof error === \"object\"\n && error !== null\n && \"code\" in error\n && (error as { code?: unknown }).code === \"ENOENT\";\n}\n\nfunction formatUnknownError(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\ninterface ConversationIndexLike {\n getConversationIndexHealth(): Promise<{\n enabled: boolean;\n backend: \"qmd\" | \"faiss\";\n status: \"ok\" | \"degraded\" | \"disabled\";\n chunkDocCount: number;\n lastUpdateAt: string | null;\n qmdAvailable?: boolean;\n faiss?: {\n ok: boolean;\n status: \"ok\" | \"degraded\" | \"error\";\n indexPath: string;\n message?: string;\n manifest?: {\n version: number;\n modelId: string;\n normalizedModelId: string;\n dimension: number;\n chunkCount: number;\n updatedAt: string;\n lastSuccessfulRebuildAt: string;\n };\n };\n }>;\n rebuildConversationIndex(\n sessionKey?: string,\n hours?: number,\n opts?: { embed?: boolean },\n ): Promise<{\n chunks: number;\n skipped: boolean;\n reason?: string;\n embedded?: boolean;\n rebuilt?: boolean;\n }>;\n}\n\nexport interface OperatorToolkitOrchestrator extends ConversationIndexLike {\n config: PluginConfig;\n storage: StorageManager;\n qmd: QmdRuntimeLike;\n}\n\nexport interface OperatorConfigLoadResult {\n found: boolean;\n path: string;\n parsed: boolean;\n memoryDir?: string;\n workspaceDir?: string;\n error?: string;\n}\n\nexport interface OperatorSetupReport {\n schemaVersion: 1;\n generatedAt: string;\n config: OperatorConfigLoadResult;\n memoryDir: string;\n workspaceDir: string;\n directories: Array<{ path: string; exists: boolean; writable: boolean }>;\n qmd: {\n enabled: boolean;\n available: boolean;\n collectionState: \"present\" | \"missing\" | \"unknown\" | \"skipped\";\n debugStatus: string;\n };\n nativeKnowledge: {\n enabled: boolean;\n includeFiles: string[];\n curatedIncludeSync: {\n statePath: string;\n exists: boolean;\n updatedAt: string | null;\n fileCount: number;\n activeChunkCount: number;\n deletedFileCount: number;\n };\n openclawWorkspaceAdapterEnabled: boolean;\n obsidianVaultAdapterEnabled: boolean;\n obsidianSync: {\n statePath: string;\n exists: boolean;\n updatedAt: string | null;\n vaultCount: number;\n activeChunkCount: number;\n deletedNoteCount: number;\n };\n openclawWorkspaceSync: {\n statePath: string;\n exists: boolean;\n updatedAt: string | null;\n fileCount: number;\n activeChunkCount: number;\n deletedFileCount: number;\n };\n };\n explicitCapture: {\n captureMode: string;\n enabled: boolean;\n memoryDocPath: string;\n memoryDocExists: boolean;\n memoryDocInstalled: boolean;\n memoryDocUpdated: boolean;\n memoryDocRemoved: boolean;\n preview: string | null;\n };\n nextSteps: string[];\n verificationCommands: string[];\n}\n\nexport interface OperatorDoctorCheck {\n key: string;\n status: \"ok\" | \"warn\" | \"error\";\n summary: string;\n remediation?: string;\n details?: unknown;\n}\n\nexport interface OperatorConfigReviewFinding {\n key: string;\n status: \"recommend\" | \"problem\";\n setting: string;\n currentValue: string;\n defaultValue: string;\n recommendedValue: string;\n summary: string;\n rationale: string;\n}\n\nexport interface OperatorConfigReviewReport {\n schemaVersion: 1;\n generatedAt: string;\n ok: boolean;\n config: OperatorConfigLoadResult;\n profile: {\n memoryOsPreset?: string;\n searchBackend: string;\n qmdEnabled: boolean;\n qmdDaemonEnabled: boolean;\n nativeKnowledgeEnabled: boolean;\n fileHygieneEnabled: boolean;\n conversationIndexEnabled: boolean;\n };\n summary: {\n recommend: number;\n problem: number;\n };\n findings: OperatorConfigReviewFinding[];\n}\n\nexport interface OperatorDoctorReport {\n schemaVersion: 1;\n generatedAt: string;\n ok: boolean;\n summary: {\n ok: number;\n warn: number;\n error: number;\n };\n config: OperatorConfigLoadResult;\n checks: OperatorDoctorCheck[];\n}\n\nexport interface OperatorInventoryNamespaceSummary {\n namespace: string;\n memoryCount: number;\n entityCount: number;\n}\n\nexport interface OperatorInventoryReport {\n schemaVersion: 1;\n generatedAt: string;\n memoryDir: string;\n totals: {\n memories: number;\n entities: number;\n namespaces: number;\n reviewQueue: number;\n storageBytes: number;\n };\n categories: Record<string, number>;\n statuses: Record<string, number>;\n namespaces: OperatorInventoryNamespaceSummary[];\n ageBands: Record<string, number>;\n profile: {\n exists: boolean;\n chars: number;\n lines: number;\n };\n storageFootprint: {\n bytes: number;\n byTopLevel: Record<string, number>;\n };\n archivePressure: {\n archived: number;\n pendingReview: number;\n quarantined: number;\n rejected: number;\n };\n conversationIndex: {\n enabled: boolean;\n backend: \"qmd\" | \"faiss\";\n status: \"ok\" | \"degraded\" | \"disabled\";\n chunkDocCount: number;\n lastUpdateAt: string | null;\n };\n nativeKnowledge: {\n enabled: boolean;\n curatedIncludeSync: {\n exists: boolean;\n updatedAt: string | null;\n fileCount: number;\n activeChunkCount: number;\n deletedFileCount: number;\n };\n obsidianSync: {\n exists: boolean;\n updatedAt: string | null;\n vaultCount: number;\n activeChunkCount: number;\n deletedNoteCount: number;\n };\n openclawWorkspaceSync: {\n exists: boolean;\n updatedAt: string | null;\n fileCount: number;\n activeChunkCount: number;\n deletedFileCount: number;\n };\n };\n}\n\nexport interface BenchmarkRecallReport {\n schemaVersion: 1;\n generatedAt: string;\n mode: \"status\" | \"validate\" | \"baseline-report\" | \"ci-gate\" | \"snapshot\";\n status: EvalHarnessStatus;\n validate?: Awaited<ReturnType<typeof validateEvalBenchmarkPack>>;\n baselineReport?: EvalBaselineDeltaReport;\n ciGate?: EvalCiGateReport;\n snapshot?: {\n targetPath: string;\n snapshotId: string;\n };\n}\n\nexport interface OperatorRepairReport {\n schemaVersion: 1;\n generatedAt: string;\n dryRun: boolean;\n sessionCheck: SessionIntegrityReport;\n sessionRepairPlan: SessionRepairPlan;\n sessionRepairApply: SessionRepairApplyResult;\n graphHealth: GraphHealthReport;\n}\n\nexport interface OperatorSetupOptions {\n orchestrator: OperatorToolkitOrchestrator;\n installCaptureInstructions?: boolean;\n captureInstructionsMode?: \"preview\" | \"install\" | \"remove\";\n configPath?: string;\n now?: Date;\n}\n\nexport interface OperatorDoctorOptions {\n orchestrator: OperatorToolkitOrchestrator;\n configPath?: string;\n now?: Date;\n}\n\nexport interface OperatorConfigReviewOptions {\n orchestrator: OperatorToolkitOrchestrator;\n configPath?: string;\n now?: Date;\n}\n\nexport interface OperatorInventoryOptions {\n orchestrator: OperatorToolkitOrchestrator;\n now?: Date;\n}\n\nexport interface BenchmarkRecallOptions {\n config: Pick<\n PluginConfig,\n | \"memoryDir\"\n | \"evalStoreDir\"\n | \"evalHarnessEnabled\"\n | \"evalShadowModeEnabled\"\n | \"benchmarkBaselineSnapshotsEnabled\"\n | \"benchmarkDeltaReporterEnabled\"\n | \"memoryRedTeamBenchEnabled\"\n >;\n validatePath?: string;\n baseEvalStoreDir?: string;\n candidateEvalStoreDir?: string;\n snapshotId?: string;\n createSnapshot?: boolean;\n snapshotNotes?: string;\n gitRef?: string;\n createdAt?: string;\n now?: Date;\n}\n\nexport interface OperatorRepairOptions {\n config: Pick<\n PluginConfig,\n \"memoryDir\" | \"entityGraphEnabled\" | \"timeGraphEnabled\" | \"causalGraphEnabled\"\n >;\n apply?: boolean;\n dryRun?: boolean;\n allowSessionFileRepair?: boolean;\n sessionFilesDir?: string;\n now?: Date;\n}\n\nfunction resolveConfigPath(explicitPath?: string): string {\n if (explicitPath && explicitPath.trim().length > 0) return explicitPath.trim();\n const configured =\n readEnvVar(\"OPENCLAW_CONFIG_PATH\") ||\n readEnvVar(\"OPENCLAW_ENGRAM_CONFIG_PATH\");\n if (configured && configured.trim().length > 0) return configured.trim();\n return path.join(resolveHomeDir(), \".openclaw\", \"openclaw.json\");\n}\n\nasync function loadCliPluginConfig(configPath?: string): Promise<OperatorConfigLoadResult> {\n const resolvedPath = resolveConfigPath(configPath);\n try {\n const raw = JSON.parse(await readFile(resolvedPath, \"utf-8\")) as Record<string, unknown>;\n // Delegate slot → PLUGIN_ID → LEGACY_PLUGIN_ID resolution to the shared\n // helper so all config loaders stay in sync (#403).\n const entry = resolveRemnicPluginEntry(raw);\n const parsedConfig = parseConfig(\n entry && typeof entry === \"object\"\n ? ((entry[\"config\"] as Record<string, unknown> | undefined) ?? {})\n : {},\n );\n return {\n found: true,\n path: resolvedPath,\n parsed: true,\n memoryDir: parsedConfig.memoryDir,\n workspaceDir: parsedConfig.workspaceDir,\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return {\n found: !/ENOENT/i.test(message),\n path: resolvedPath,\n parsed: false,\n error: message,\n };\n }\n}\n\nasync function isWritable(targetPath: string): Promise<boolean> {\n try {\n await access(targetPath, fsConstants.W_OK);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function pathExists(targetPath: string): Promise<boolean> {\n try {\n await access(targetPath, fsConstants.F_OK);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction formatConfigValue(value: unknown): string {\n if (value === undefined || value === null) return \"(unset)\";\n if (typeof value === \"string\") return value.length > 0 ? value : \"(unset)\";\n if (typeof value === \"number\" || typeof value === \"boolean\") return String(value);\n return JSON.stringify(value);\n}\n\nasync function gatherDirectoryStatus(\n paths: string[],\n): Promise<Array<{ path: string; exists: boolean; writable: boolean }>> {\n return Promise.all(paths.map(async (targetPath) => {\n try {\n await access(targetPath, fsConstants.F_OK);\n return {\n path: targetPath,\n exists: true,\n writable: await isWritable(targetPath),\n };\n } catch {\n return {\n path: targetPath,\n exists: false,\n writable: false,\n };\n }\n }));\n}\n\nfunction getSetupPaths(config: PluginConfig): string[] {\n return [\n config.memoryDir,\n config.workspaceDir,\n path.join(config.memoryDir, \"facts\"),\n path.join(config.memoryDir, \"entities\"),\n path.join(config.memoryDir, \"state\"),\n path.join(config.memoryDir, \"questions\"),\n path.join(config.memoryDir, \"artifacts\"),\n path.join(config.memoryDir, \"config\"),\n ];\n}\n\nasync function readJsonIfExists(filePath: string): Promise<unknown | null> {\n try {\n return JSON.parse(await readFile(filePath, \"utf-8\")) as unknown;\n } catch {\n return null;\n }\n}\n\nasync function summarizeNativeKnowledgeStatus(config: PluginConfig): Promise<{\n enabled: boolean;\n includeFiles: string[];\n curatedIncludeSync: {\n statePath: string;\n exists: boolean;\n updatedAt: string | null;\n fileCount: number;\n activeChunkCount: number;\n deletedFileCount: number;\n };\n openclawWorkspaceAdapterEnabled: boolean;\n obsidianVaultAdapterEnabled: boolean;\n obsidianSync: {\n statePath: string;\n exists: boolean;\n updatedAt: string | null;\n vaultCount: number;\n activeChunkCount: number;\n deletedNoteCount: number;\n };\n openclawWorkspaceSync: {\n statePath: string;\n exists: boolean;\n updatedAt: string | null;\n fileCount: number;\n activeChunkCount: number;\n deletedFileCount: number;\n };\n}> {\n const nativeKnowledge = config.nativeKnowledge;\n const nativeKnowledgeStateDir = nativeKnowledge?.stateDir ?? \"state/native-knowledge\";\n const curatedStatePath = nativeKnowledge\n ? resolveCuratedIncludeFilesStatePath(config.memoryDir, nativeKnowledge)\n : path.join(config.memoryDir, nativeKnowledgeStateDir, \"curated-include-sync.json\");\n const obsidianStatePath = nativeKnowledge\n ? resolveNativeKnowledgeStatePath(config.memoryDir, nativeKnowledge)\n : path.join(config.memoryDir, nativeKnowledgeStateDir, \"obsidian-sync.json\");\n const openclawStatePath = nativeKnowledge\n ? resolveOpenClawWorkspaceStatePath(config.memoryDir, nativeKnowledge)\n : path.join(config.memoryDir, nativeKnowledgeStateDir, \"openclaw-workspace-sync.json\");\n const [curatedRaw, obsidianRaw, openclawRaw] = await Promise.all([\n readJsonIfExists(curatedStatePath),\n readJsonIfExists(obsidianStatePath),\n readJsonIfExists(openclawStatePath),\n ]);\n\n const curatedFiles = curatedRaw && typeof curatedRaw === \"object\" && curatedRaw !== null\n && \"files\" in curatedRaw && typeof (curatedRaw as { files?: unknown }).files === \"object\"\n && (curatedRaw as { files?: unknown }).files !== null\n ? (curatedRaw as {\n updatedAt?: unknown;\n files: Record<string, { deleted?: boolean; chunks?: unknown[] }>;\n })\n : null;\n\n let curatedActiveChunkCount = 0;\n let curatedDeletedFileCount = 0;\n for (const file of Object.values(curatedFiles?.files ?? {})) {\n if (file.deleted) {\n curatedDeletedFileCount += 1;\n continue;\n }\n curatedActiveChunkCount += Array.isArray(file.chunks) ? file.chunks.length : 0;\n }\n\n const obsidianVaults = obsidianRaw && typeof obsidianRaw === \"object\" && obsidianRaw !== null\n && \"vaults\" in obsidianRaw && typeof (obsidianRaw as { vaults?: unknown }).vaults === \"object\"\n && (obsidianRaw as { vaults?: unknown }).vaults !== null\n ? (obsidianRaw as {\n updatedAt?: unknown;\n vaults: Record<string, { notes?: Record<string, { deleted?: boolean; chunks?: unknown[] }> }>;\n })\n : null;\n\n let obsidianActiveChunkCount = 0;\n let obsidianDeletedNoteCount = 0;\n for (const vault of Object.values(obsidianVaults?.vaults ?? {})) {\n for (const note of Object.values(vault.notes ?? {})) {\n if (note.deleted) {\n obsidianDeletedNoteCount += 1;\n continue;\n }\n obsidianActiveChunkCount += Array.isArray(note.chunks) ? note.chunks.length : 0;\n }\n }\n\n const openclawFiles = openclawRaw && typeof openclawRaw === \"object\" && openclawRaw !== null\n && \"files\" in openclawRaw && typeof (openclawRaw as { files?: unknown }).files === \"object\"\n && (openclawRaw as { files?: unknown }).files !== null\n ? (openclawRaw as {\n updatedAt?: unknown;\n files: Record<string, { deleted?: boolean; chunks?: unknown[] }>;\n })\n : null;\n\n let openclawActiveChunkCount = 0;\n let openclawDeletedFileCount = 0;\n for (const file of Object.values(openclawFiles?.files ?? {})) {\n if (file.deleted) {\n openclawDeletedFileCount += 1;\n continue;\n }\n openclawActiveChunkCount += Array.isArray(file.chunks) ? file.chunks.length : 0;\n }\n\n return {\n enabled: nativeKnowledge?.enabled === true,\n includeFiles: nativeKnowledge?.includeFiles ?? [],\n curatedIncludeSync: {\n statePath: curatedStatePath,\n exists: curatedFiles !== null,\n updatedAt: typeof curatedFiles?.updatedAt === \"string\" ? curatedFiles.updatedAt : null,\n fileCount: Object.keys(curatedFiles?.files ?? {}).length,\n activeChunkCount: curatedActiveChunkCount,\n deletedFileCount: curatedDeletedFileCount,\n },\n openclawWorkspaceAdapterEnabled: nativeKnowledge?.openclawWorkspace?.enabled === true,\n obsidianVaultAdapterEnabled: (nativeKnowledge?.obsidianVaults?.length ?? 0) > 0,\n obsidianSync: {\n statePath: obsidianStatePath,\n exists: obsidianVaults !== null,\n updatedAt: typeof obsidianVaults?.updatedAt === \"string\" ? obsidianVaults.updatedAt : null,\n vaultCount: Object.keys(obsidianVaults?.vaults ?? {}).length,\n activeChunkCount: obsidianActiveChunkCount,\n deletedNoteCount: obsidianDeletedNoteCount,\n },\n openclawWorkspaceSync: {\n statePath: openclawStatePath,\n exists: openclawFiles !== null,\n updatedAt: typeof openclawFiles?.updatedAt === \"string\" ? openclawFiles.updatedAt : null,\n fileCount: Object.keys(openclawFiles?.files ?? {}).length,\n activeChunkCount: openclawActiveChunkCount,\n deletedFileCount: openclawDeletedFileCount,\n },\n };\n}\n\nconst CAPTURE_INSTRUCTIONS_START = \"<!-- BEGIN ENGRAM EXPLICIT CAPTURE INSTRUCTIONS -->\";\nconst CAPTURE_INSTRUCTIONS_END = \"<!-- END ENGRAM EXPLICIT CAPTURE INSTRUCTIONS -->\";\n\nfunction buildCaptureInstructions(): string {\n return [\n CAPTURE_INSTRUCTIONS_START,\n \"# Memory\",\n \"\",\n \"Use this file for explicit memory capture notes when Engram runs in explicit or hybrid mode.\",\n \"\",\n \"## Suggested format\",\n \"\",\n \"- Write durable facts, decisions, commitments, or corrections.\",\n \"- Keep entries concise and specific.\",\n \"- Avoid secrets, tokens, and private credentials.\",\n \"\",\n \"## Example\",\n \"\",\n \"- Decision: recall benchmark packs live under `state/evals/benchmarks/`.\",\n \"- Commitment: rerun `openclaw engram doctor --json` after changing retrieval settings.\",\n \"\",\n CAPTURE_INSTRUCTIONS_END,\n ].join(\"\\n\");\n}\n\nfunction upsertManagedCaptureInstructions(existing: string | null, snippet: string): { content: string; updated: boolean; installed: boolean } {\n if (!existing || existing.trim().length === 0) {\n return { content: `${snippet}\\n`, updated: false, installed: true };\n }\n if (existing.includes(CAPTURE_INSTRUCTIONS_START) && existing.includes(CAPTURE_INSTRUCTIONS_END)) {\n const next = existing.replace(\n new RegExp(`${CAPTURE_INSTRUCTIONS_START}[\\\\s\\\\S]*?${CAPTURE_INSTRUCTIONS_END}`),\n snippet,\n );\n return { content: next.endsWith(\"\\n\") ? next : `${next}\\n`, updated: next !== existing, installed: false };\n }\n const trimmed = existing.trimEnd();\n return {\n content: `${trimmed}\\n\\n${snippet}\\n`,\n updated: false,\n installed: true,\n };\n}\n\nfunction removeManagedCaptureInstructions(existing: string): { content: string; removed: boolean } {\n if (!existing.includes(CAPTURE_INSTRUCTIONS_START) || !existing.includes(CAPTURE_INSTRUCTIONS_END)) {\n return { content: existing, removed: false };\n }\n const stripped = existing\n .replace(new RegExp(`\\\\n*${CAPTURE_INSTRUCTIONS_START}[\\\\s\\\\S]*?${CAPTURE_INSTRUCTIONS_END}\\\\n*`), \"\\n\")\n .replace(/\\n{3,}/g, \"\\n\\n\")\n .trim();\n return {\n content: stripped.length > 0 ? `${stripped}\\n` : \"\",\n removed: true,\n };\n}\n\nexport async function runOperatorSetup(options: OperatorSetupOptions): Promise<OperatorSetupReport> {\n const now = options.now ?? new Date();\n const configStatus = await loadCliPluginConfig(options.configPath);\n const storage = options.orchestrator.storage;\n await storage.ensureDirectories();\n await mkdir(options.orchestrator.config.workspaceDir, { recursive: true });\n\n const qmdAvailable = await options.orchestrator.qmd.probe();\n const collectionState = options.orchestrator.config.qmdEnabled\n ? await options.orchestrator.qmd.ensureCollection(options.orchestrator.config.memoryDir)\n : \"skipped\";\n const nativeKnowledgeStatus = await summarizeNativeKnowledgeStatus(options.orchestrator.config);\n\n const memoryDocPath = path.join(options.orchestrator.config.workspaceDir, \"MEMORY.md\");\n const captureInstructionsMode =\n options.captureInstructionsMode\n ?? (options.installCaptureInstructions ? \"install\" : undefined);\n let memoryDocExists = false;\n try {\n await access(memoryDocPath, fsConstants.F_OK);\n memoryDocExists = true;\n } catch {\n memoryDocExists = false;\n }\n let memoryDocInstalled = false;\n let memoryDocUpdated = false;\n let memoryDocRemoved = false;\n const explicitCaptureEnabled = options.orchestrator.config.captureMode === \"explicit\"\n || options.orchestrator.config.captureMode === \"hybrid\";\n const captureInstructionsPreview = captureInstructionsMode ? buildCaptureInstructions() : null;\n if (captureInstructionsMode) {\n if (captureInstructionsMode === \"preview\") {\n // no-op, preview only\n } else if (captureInstructionsMode === \"install\") {\n const existing = memoryDocExists ? await readFile(memoryDocPath, \"utf-8\") : null;\n const next = upsertManagedCaptureInstructions(existing, captureInstructionsPreview ?? \"\");\n if (!existing || next.content !== existing) {\n await writeFile(memoryDocPath, next.content, \"utf-8\");\n }\n memoryDocExists = true;\n memoryDocInstalled = next.installed;\n memoryDocUpdated = next.updated;\n } else if (captureInstructionsMode === \"remove\" && memoryDocExists) {\n const existing = await readFile(memoryDocPath, \"utf-8\");\n const next = removeManagedCaptureInstructions(existing);\n if (next.removed) {\n if (next.content.length === 0) {\n await unlink(memoryDocPath);\n memoryDocExists = false;\n } else {\n await writeFile(memoryDocPath, next.content, \"utf-8\");\n memoryDocExists = true;\n }\n memoryDocRemoved = true;\n }\n }\n }\n\n const directories = await gatherDirectoryStatus(getSetupPaths(options.orchestrator.config));\n const nextSteps = [\n `Run \\`openclaw engram doctor${options.installCaptureInstructions ? \"\" : \" --json\"}\\` to verify runtime health.`,\n \"Run `openclaw engram inventory --json` to capture a baseline footprint.\",\n \"If QMD is enabled and the collection is missing, add the collection to `~/.config/qmd/index.yml` and run `qmd update && qmd embed`.\",\n ];\n if (explicitCaptureEnabled && !memoryDocExists) {\n nextSteps.push(\"Run `openclaw engram setup --preview-capture-instructions` to review the managed explicit-capture snippet, then `--install-capture-instructions` to write it.\");\n }\n\n return {\n schemaVersion: 1,\n generatedAt: now.toISOString(),\n config: configStatus,\n memoryDir: options.orchestrator.config.memoryDir,\n workspaceDir: options.orchestrator.config.workspaceDir,\n directories,\n qmd: {\n enabled: options.orchestrator.config.qmdEnabled,\n available: qmdAvailable,\n collectionState,\n debugStatus: options.orchestrator.qmd.debugStatus(),\n },\n nativeKnowledge: nativeKnowledgeStatus,\n explicitCapture: {\n captureMode: options.orchestrator.config.captureMode,\n enabled: explicitCaptureEnabled,\n memoryDocPath,\n memoryDocExists,\n memoryDocInstalled,\n memoryDocUpdated,\n memoryDocRemoved,\n preview: captureInstructionsMode === \"preview\" ? captureInstructionsPreview : null,\n },\n nextSteps,\n verificationCommands: [\n \"openclaw engram doctor --json\",\n \"openclaw engram inventory --json\",\n \"openclaw engram benchmark recall --json\",\n ],\n };\n}\n\nfunction summarizeHygieneWarnings(\n warnings: Awaited<ReturnType<typeof lintWorkspaceFiles>>,\n hygiene: FileHygieneConfig | undefined,\n): OperatorDoctorCheck {\n if (!hygiene?.enabled || hygiene.lintEnabled !== true) {\n return {\n key: \"file_hygiene\",\n status: \"warn\",\n summary: \"File hygiene linting is disabled; bootstrap file truncation warnings are not active.\",\n remediation: \"Enable `fileHygiene.enabled` and `fileHygiene.lintEnabled` if large workspace bootstrap files are common.\",\n details: {\n enabled: hygiene?.enabled === true,\n lintEnabled: hygiene?.lintEnabled === true,\n },\n };\n }\n if (warnings.length > 0) {\n return {\n key: \"file_hygiene\",\n status: \"warn\",\n summary: `${warnings.length} bootstrap file(s) are near or above the configured budget.`,\n remediation: \"Archive/split the listed files or adjust `fileHygiene` budgets.\",\n details: { warnings },\n };\n }\n return {\n key: \"file_hygiene\",\n status: \"ok\",\n summary: \"Bootstrap file hygiene is within budget.\",\n details: {\n enabled: true,\n lintPaths: hygiene.lintPaths,\n budgetBytes: hygiene.lintBudgetBytes,\n },\n };\n}\n\nfunction buildConfigReviewFinding(input: {\n key: string;\n status: \"recommend\" | \"problem\";\n setting: string;\n currentValue: unknown;\n defaultValue: unknown;\n recommendedValue: unknown;\n summary: string;\n rationale: string;\n}): OperatorConfigReviewFinding {\n return {\n key: input.key,\n status: input.status,\n setting: input.setting,\n currentValue: formatConfigValue(input.currentValue),\n defaultValue: formatConfigValue(input.defaultValue),\n recommendedValue: formatConfigValue(input.recommendedValue),\n summary: input.summary,\n rationale: input.rationale,\n };\n}\n\nexport async function runOperatorConfigReview(\n options: OperatorConfigReviewOptions,\n): Promise<OperatorConfigReviewReport> {\n const now = options.now ?? new Date();\n const configStatus = await loadCliPluginConfig(options.configPath);\n return buildOperatorConfigReviewReport({\n now,\n configStatus,\n config: options.orchestrator.config,\n });\n}\n\nasync function buildOperatorConfigReviewReport(input: {\n now: Date;\n configStatus: OperatorConfigLoadResult;\n config: PluginConfig;\n}): Promise<OperatorConfigReviewReport> {\n const { now, configStatus, config } = input;\n const findings: OperatorConfigReviewFinding[] = [];\n const searchBackend = config.searchBackend ?? \"qmd\";\n const workspaceBootstrapFiles = [\n path.join(config.workspaceDir, \"IDENTITY.md\"),\n path.join(config.workspaceDir, \"MEMORY.md\"),\n path.join(config.workspaceDir, \"USER.md\"),\n ];\n const workspaceBootstrapExists = (await Promise.all(workspaceBootstrapFiles.map(pathExists))).some(Boolean);\n\n if (\n config.memoryOsPreset !== \"conservative\" &&\n config.memoryOsPreset !== \"balanced\" &&\n config.memoryOsPreset !== \"research-max\" &&\n config.memoryOsPreset !== \"local-llm-heavy\" &&\n config.queryAwareIndexingEnabled === false &&\n config.verbatimArtifactsEnabled === false &&\n config.rerankEnabled === false\n ) {\n findings.push(buildConfigReviewFinding({\n key: \"balanced_preset\",\n status: \"recommend\",\n setting: \"memoryOsPreset\",\n currentValue: config.memoryOsPreset,\n defaultValue: \"(unset)\",\n recommendedValue: \"balanced\",\n summary: \"Adopt the balanced preset as the baseline configuration profile.\",\n rationale:\n \"The balanced preset enables the recommended indexing, reranking, and artifact defaults without turning on the higher-churn graph and learning loops.\",\n }));\n }\n\n if (config.qmdEnabled && config.qmdDaemonEnabled === false) {\n findings.push(buildConfigReviewFinding({\n key: \"qmd_daemon\",\n status: \"recommend\",\n setting: \"qmdDaemonEnabled\",\n currentValue: config.qmdDaemonEnabled,\n defaultValue: true,\n recommendedValue: true,\n summary: \"Enable the QMD daemon path when QMD powers recall.\",\n rationale:\n \"The daemon path reduces recall/search contention by preferring the MCP transport instead of repeated subprocess calls when QMD is available.\",\n }));\n }\n\n if (workspaceBootstrapExists && config.nativeKnowledge?.enabled !== true) {\n findings.push(buildConfigReviewFinding({\n key: \"native_knowledge_enabled\",\n status: \"recommend\",\n setting: \"nativeKnowledge.enabled\",\n currentValue: config.nativeKnowledge?.enabled,\n defaultValue: false,\n recommendedValue: true,\n summary: \"Enable native knowledge recall for workspace bootstrap documents.\",\n rationale:\n \"When files like IDENTITY.md or MEMORY.md already exist, native knowledge recall can chunk and inject them directly instead of relying only on extracted memories.\",\n }));\n }\n\n if (workspaceBootstrapExists && config.fileHygiene?.enabled !== true) {\n findings.push(buildConfigReviewFinding({\n key: \"file_hygiene_enabled\",\n status: \"recommend\",\n setting: \"fileHygiene.enabled\",\n currentValue: config.fileHygiene?.enabled,\n defaultValue: false,\n recommendedValue: true,\n summary: \"Enable file hygiene to avoid silent workspace-file truncation.\",\n rationale:\n \"OpenClaw bootstrap files can grow quietly; file hygiene warns before oversized files are truncated during prompt bootstrap.\",\n }));\n }\n\n if (searchBackend === \"qmd\" && config.qmdEnabled === false) {\n findings.push(buildConfigReviewFinding({\n key: \"qmd_search_backend_disabled\",\n status: \"problem\",\n setting: \"qmdEnabled\",\n currentValue: config.qmdEnabled,\n defaultValue: true,\n recommendedValue: true,\n summary: \"QMD search is selected but QMD is disabled.\",\n rationale:\n \"When searchBackend resolves to qmd while qmdEnabled is false, Engram falls back to the noop backend and disables the primary search path.\",\n }));\n }\n\n if (config.qmdColdTierEnabled === true && config.qmdEnabled === false) {\n findings.push(buildConfigReviewFinding({\n key: \"qmd_cold_tier_requires_qmd\",\n status: \"problem\",\n setting: \"qmdEnabled\",\n currentValue: config.qmdEnabled,\n defaultValue: true,\n recommendedValue: true,\n summary: \"Cold-tier QMD recall is enabled while QMD itself is disabled.\",\n rationale:\n \"The cold tier depends on the same QMD runtime as the hot tier, so turning QMD off leaves the extra tiering path unusable.\",\n }));\n }\n\n if (config.qmdTierMigrationEnabled && config.qmdColdTierEnabled !== true) {\n findings.push(buildConfigReviewFinding({\n key: \"qmd_tier_migration_requires_cold_tier\",\n status: \"problem\",\n setting: \"qmdColdTierEnabled\",\n currentValue: config.qmdColdTierEnabled,\n defaultValue: false,\n recommendedValue: true,\n summary: \"Hot/cold tier migration is enabled without the cold tier itself.\",\n rationale:\n \"Tier migration depends on the cold-tier collection and recall path, so enabling migration while the cold tier is off leaves the feature in a contradictory state.\",\n }));\n }\n\n if (config.conversationIndexEnabled && config.conversationIndexBackend === \"qmd\" && config.qmdEnabled === false) {\n findings.push(buildConfigReviewFinding({\n key: \"conversation_index_qmd_requires_qmd\",\n status: \"problem\",\n setting: \"qmdEnabled\",\n currentValue: config.qmdEnabled,\n defaultValue: true,\n recommendedValue: true,\n summary: \"The conversation index is configured for QMD while QMD is disabled.\",\n rationale:\n \"A QMD-backed conversation index cannot rebuild or serve queries when the underlying QMD runtime is disabled.\",\n }));\n }\n\n const summary = findings.reduce(\n (acc, finding) => {\n acc[finding.status] += 1;\n return acc;\n },\n { recommend: 0, problem: 0 },\n );\n\n return {\n schemaVersion: 1,\n generatedAt: now.toISOString(),\n ok: configStatus.parsed && summary.problem === 0,\n config: configStatus,\n profile: {\n memoryOsPreset: config.memoryOsPreset,\n searchBackend,\n qmdEnabled: config.qmdEnabled,\n qmdDaemonEnabled: config.qmdDaemonEnabled,\n nativeKnowledgeEnabled: config.nativeKnowledge?.enabled === true,\n fileHygieneEnabled: config.fileHygiene?.enabled === true,\n conversationIndexEnabled: config.conversationIndexEnabled,\n },\n summary,\n findings,\n };\n}\n\nexport async function runOperatorDoctor(options: OperatorDoctorOptions): Promise<OperatorDoctorReport> {\n const now = options.now ?? new Date();\n const configStatus = await loadCliPluginConfig(options.configPath);\n const checks: OperatorDoctorCheck[] = [];\n const config = options.orchestrator.config;\n const storage = options.orchestrator.storage;\n const configReview = await buildOperatorConfigReviewReport({\n now,\n configStatus,\n config,\n });\n const nativeKnowledgeStatus = await summarizeNativeKnowledgeStatus(config);\n const setupPaths = await gatherDirectoryStatus(getSetupPaths(config));\n const missingPaths = setupPaths.filter((entry) => !entry.exists).map((entry) => entry.path);\n\n checks.push({\n key: \"config\",\n status: configStatus.parsed\n ? \"ok\"\n : options.configPath\n ? \"error\"\n : \"warn\",\n summary: configStatus.parsed ? \"OpenClaw config loaded and Engram config parsed successfully.\" : \"Config file could not be parsed.\",\n remediation: configStatus.parsed ? undefined : \"Fix the config file or set OPENCLAW_ENGRAM_CONFIG_PATH/OPENCLAW_CONFIG_PATH.\",\n details: configStatus,\n });\n\n checks.push({\n key: \"memory_dir\",\n status: missingPaths.length === 0 ? \"ok\" : \"warn\",\n summary: missingPaths.length === 0\n ? \"Expected Engram directories exist.\"\n : `${missingPaths.length} expected directory path(s) are missing.`,\n remediation: missingPaths.length === 0 ? undefined : \"Run `openclaw engram setup` to create missing directories.\",\n details: { directories: setupPaths },\n });\n\n checks.push({\n key: \"config_review\",\n status: configReview.summary.problem > 0 ? \"error\" : configReview.summary.recommend > 0 ? \"warn\" : \"ok\",\n summary: configReview.summary.problem > 0\n ? `${configReview.summary.problem} configuration problem(s) detected.`\n : configReview.summary.recommend > 0\n ? `No configuration problems detected; ${configReview.summary.recommend} optional recommendation(s) are available.`\n : \"No configuration problems detected.\",\n remediation: configReview.summary.problem > 0 || configReview.summary.recommend > 0\n ? \"Run `openclaw engram config-review` to inspect and fix the flagged configuration combinations.\"\n : undefined,\n details: configReview,\n });\n\n const qmdAvailable = await options.orchestrator.qmd.probe();\n const collectionState = config.qmdEnabled\n ? await options.orchestrator.qmd.ensureCollection(config.memoryDir)\n : \"skipped\";\n checks.push({\n key: \"qmd\",\n status: !config.qmdEnabled\n ? \"warn\"\n : !qmdAvailable\n ? \"error\"\n : collectionState === \"present\"\n ? \"ok\"\n : collectionState === \"missing\"\n ? \"error\"\n : \"warn\",\n summary: !config.qmdEnabled\n ? \"QMD is disabled in config.\"\n : qmdAvailable\n ? `QMD is reachable (${collectionState}).`\n : \"QMD is not currently reachable.\",\n remediation: !config.qmdEnabled\n ? \"Enable `qmdEnabled` if you expect hybrid search.\"\n : !qmdAvailable\n ? \"Ensure the `qmd` binary is installed and on PATH, or set `qmdPath`.\"\n : collectionState === \"missing\"\n ? \"Add the configured collection to `~/.config/qmd/index.yml`.\"\n : collectionState === \"present\"\n ? undefined\n : \"Re-run `openclaw engram setup` after restoring QMD access.\",\n details: {\n available: qmdAvailable,\n collectionState,\n debugStatus: options.orchestrator.qmd.debugStatus(),\n },\n });\n\n const conversationIndex = await options.orchestrator.getConversationIndexHealth();\n checks.push({\n key: \"conversation_index\",\n status: conversationIndex.status === \"ok\"\n ? \"ok\"\n : conversationIndex.enabled\n ? \"error\"\n : \"warn\",\n summary: conversationIndex.enabled\n ? `Conversation index backend is ${conversationIndex.status}.`\n : \"Conversation index is disabled.\",\n remediation: conversationIndex.enabled && conversationIndex.status !== \"ok\"\n ? \"Run `openclaw engram rebuild-index` to refresh the conversation index artifacts.\"\n : undefined,\n details: conversationIndex,\n });\n\n const meta = await storage.loadMeta();\n checks.push({\n key: \"maintenance\",\n status: meta.lastExtractionAt || meta.lastConsolidationAt ? \"ok\" : \"warn\",\n summary: meta.lastExtractionAt || meta.lastConsolidationAt\n ? \"Extraction/consolidation metadata is present.\"\n : \"No extraction or consolidation metadata found yet.\",\n remediation: meta.lastExtractionAt || meta.lastConsolidationAt\n ? undefined\n : \"Run a normal agent turn or `openclaw engram consolidate` after seeding memory.\",\n details: meta,\n });\n\n const syncedChunkCount =\n nativeKnowledgeStatus.curatedIncludeSync.activeChunkCount +\n nativeKnowledgeStatus.obsidianSync.activeChunkCount +\n nativeKnowledgeStatus.openclawWorkspaceSync.activeChunkCount;\n const hasSyncState =\n nativeKnowledgeStatus.curatedIncludeSync.exists ||\n nativeKnowledgeStatus.obsidianSync.exists ||\n nativeKnowledgeStatus.openclawWorkspaceSync.exists;\n checks.push({\n key: \"native_knowledge\",\n status: !nativeKnowledgeStatus.enabled\n ? \"warn\"\n : hasSyncState\n ? \"ok\"\n : \"warn\",\n summary: !nativeKnowledgeStatus.enabled\n ? \"Native knowledge sync is disabled.\"\n : hasSyncState\n ? `Native knowledge sync state is present (${syncedChunkCount} active chunks).`\n : \"Native knowledge sync is enabled but no sync state has been written yet.\",\n remediation: !nativeKnowledgeStatus.enabled\n ? \"Enable `nativeKnowledge.enabled` if curated workspace recall should participate in retrieval.\"\n : hasSyncState\n ? undefined\n : \"Run a recall, sync, or setup flow that touches native knowledge sources, then rerun `openclaw engram doctor --json`.\",\n details: nativeKnowledgeStatus,\n });\n\n const agentAccessEnabled = config.agentAccessHttp?.enabled === true;\n // A SecretRef object counts as \"configured\" (issue #757) — resolution\n // happens at service-start time, not at doctor-time. We only check that\n // *something* is set; we never log the resolved value.\n const rawAuthToken = config.agentAccessHttp?.authToken;\n const authTokenConfigured =\n (typeof rawAuthToken === \"string\" && rawAuthToken.length > 0) ||\n (rawAuthToken !== null &&\n typeof rawAuthToken === \"object\" &&\n typeof (rawAuthToken as { source?: unknown }).source === \"string\");\n checks.push({\n key: \"access_http_auth\",\n status: !agentAccessEnabled\n ? \"warn\"\n : authTokenConfigured\n ? \"ok\"\n : \"error\",\n summary: !agentAccessEnabled\n ? \"Agent access HTTP bridge is disabled.\"\n : authTokenConfigured\n ? \"Agent access HTTP bridge has an auth token configured.\"\n : \"Agent access HTTP bridge is enabled without an auth token.\",\n remediation: !agentAccessEnabled\n ? \"Ignore unless you plan to enable the HTTP bridge.\"\n : authTokenConfigured\n ? undefined\n : \"Set `agentAccessHttp.authToken` before exposing the bridge.\",\n });\n\n const warnings = config.fileHygiene?.lintEnabled\n ? await lintWorkspaceFiles({\n workspaceDir: config.workspaceDir,\n paths: config.fileHygiene.lintPaths,\n budgetBytes: config.fileHygiene.lintBudgetBytes,\n warnRatio: config.fileHygiene.lintWarnRatio,\n })\n : [];\n checks.push(summarizeHygieneWarnings(warnings, config.fileHygiene));\n\n // Memory Worth legacy counter audit (issue #560 PR 1).\n // Memories written before #560 have no `mw_success` / `mw_fail` frontmatter\n // fields. That is fully supported — readers treat the absence as a uniform\n // Beta(1,1) prior — but surfacing the count helps operators understand how\n // much history will bootstrap the scoring pipeline landed in later PRs.\n // This is an informational check, never an error.\n checks.push(await summarizeMemoryWorthLegacyCounters(storage));\n\n // Buffer surprise telemetry distribution (issue #563 PR 3).\n // Surfaces recent surprise scores so operators can calibrate the\n // `bufferSurpriseThreshold` from real traffic. Never an error — an empty\n // ledger is the expected state until the flag is turned on.\n checks.push(\n await summarizeBufferSurpriseDistribution(storage, config),\n );\n\n // Consolidation provenance integrity (issue #561 PR 4).\n // Validates that every `derived_from` entry resolves to an on-disk\n // page-version snapshot and every `derived_via` is a known operator.\n // Broken provenance emits warnings with the offending file path — the\n // check is informational (never an error) because a missing snapshot\n // can legitimately occur after log pruning or versioning being disabled\n // retroactively; operators need visibility, not a hard fail. Review\n // feedback (PR #634): the summarizer threads the configured\n // `versioningSidecarDir` into the scan so deployments that override\n // the default `.versions` directory get accurate results instead of\n // false-missing warnings.\n checks.push(await summarizeConsolidationProvenance(storage, config));\n\n // Graph-edge decay maintenance status (issue #681 PR 2/3).\n // Reports whether the periodic decay job has run and surfaces last-run\n // counts. Disabled is \"ok\" with a note; enabled-but-never-run is \"warn\".\n checks.push(await summarizeGraphEdgeDecayStatus(config));\n\n // Tier distribution (issue #686 retention-completion).\n // Shows hot/cold counts, per-status breakdown, and forgotten-memory count.\n // Informational only — never errors, never blocks doctor from returning ok.\n checks.push(await summarizeTierDistribution(options.orchestrator.storage));\n\n // Dreams phases thresholds and last-run timestamps (issue #678 PR 2/4).\n // Surfaces per-phase: enabled status, cadence, threshold values, and the\n // best-available last-run timestamp for each of the three pipeline phases.\n checks.push(await summarizeDreamsPhases(config, storage));\n\n // Security mitigation status (issue #565).\n // Reports whether the cross-namespace budget and anomaly detection\n // mitigations are enabled and surfaces config values for operator review.\n checks.push(summarizeSecurityMitigations(config));\n\n // Observation throughput + judge acceptance rate (issue #685).\n // Surfaces the total verdict count, accept/reject/defer breakdown, and the\n // most recent `observedAt` timestamp from the extraction-judge telemetry\n // ledger. This closes the *(future)* item deferred in\n // `docs/trace-to-primitive.md`. The check is purely informational — it\n // always resolves to `ok`; an empty ledger is the expected cold-install\n // state and is never an error.\n checks.push(await summarizeObservationThroughput(config.memoryDir));\n\n const summary = checks.reduce(\n (acc, check) => {\n acc[check.status] += 1;\n return acc;\n },\n { ok: 0, warn: 0, error: 0 },\n );\n\n return {\n schemaVersion: 1,\n generatedAt: now.toISOString(),\n ok: summary.error === 0,\n summary,\n config: configStatus,\n checks,\n };\n}\n\n/**\n * Categories whose memories are eligible for Memory Worth instrumentation.\n *\n * Memory Worth is a per-fact utility signal: the counters ride on extracted\n * facts whose retrieval outcome can be judged (success/fail) by the feedback\n * pipeline landing in issue #560 PR 3. Procedures, corrections, and other\n * non-fact memory kinds are out of scope — they are not expected to be\n * instrumented, and counting them as \"legacy\" would permanently inflate the\n * legacy bucket and make rollout progress misleading even when every fact\n * memory is instrumented.\n *\n * If a later PR widens Memory Worth to additional categories, extend this set\n * alongside the scoring/increment logic so the doctor audit stays in sync.\n */\nconst MEMORY_WORTH_ELIGIBLE_CATEGORIES: ReadonlySet<MemoryFile[\"frontmatter\"][\"category\"]> =\n new Set([\"fact\"]);\n\n/**\n * Count memories that pre-date the Memory Worth counters introduced in issue\n * #560 — i.e., neither `mw_success` nor `mw_fail` is set on the frontmatter.\n *\n * Only memories whose category is eligible for Memory Worth (see\n * `MEMORY_WORTH_ELIGIBLE_CATEGORIES`) are considered. Procedures, corrections,\n * and other kinds that are not instrumented are excluded entirely — they're\n * neither \"legacy\" nor \"instrumented\" for the purposes of this audit. The\n * total in the returned details reflects only eligible memories.\n *\n * Returned as an `ok` check regardless of count, since legacy memories are\n * fully functional (readers treat missing counters as zero observations). The\n * numbers are informational for operators following the #560 rollout.\n *\n * Exported so unit tests can exercise the classification logic without\n * booting a full orchestrator.\n */\nexport async function summarizeMemoryWorthLegacyCounters(\n storage: StorageManager,\n): Promise<OperatorDoctorCheck> {\n let legacy = 0;\n let instrumented = 0;\n let ineligible = 0;\n try {\n const memories = await storage.readAllMemories();\n for (const memory of memories) {\n if (!MEMORY_WORTH_ELIGIBLE_CATEGORIES.has(memory.frontmatter.category)) {\n ineligible += 1;\n continue;\n }\n const { mw_success, mw_fail } = memory.frontmatter;\n if (mw_success === undefined && mw_fail === undefined) {\n legacy += 1;\n } else {\n instrumented += 1;\n }\n }\n } catch (err) {\n return {\n key: \"memory_worth_legacy\",\n status: \"warn\",\n summary: \"Could not enumerate memories to count Memory Worth instrumentation.\",\n remediation: \"Retry `remnic doctor` after ensuring the memory directory is readable.\",\n details: { error: String(err) },\n };\n }\n\n const total = legacy + instrumented;\n return {\n key: \"memory_worth_legacy\",\n status: \"ok\",\n summary:\n total === 0\n ? \"No Memory Worth–eligible memories on disk yet — counters will populate as facts are extracted.\"\n : `${legacy} of ${total} eligible memories have no Memory Worth counters yet (${instrumented} instrumented).`,\n details: { legacy, instrumented, total, ineligible },\n };\n}\n\n/**\n * Summarize the recent buffer-surprise telemetry distribution for the\n * Doctor report (issue #563 PR 3).\n *\n * Reports mean/median/p90 surprise scores and the triggered-flush rate\n * over the most recent window of ledger rows. An empty ledger is the\n * expected state until `bufferSurpriseTriggerEnabled` is turned on — the\n * check never escalates beyond `ok` / `warn` (ledger unreadable).\n *\n * Exported so tests can exercise the formatting without booting a real\n * orchestrator.\n */\nexport async function summarizeBufferSurpriseDistribution(\n storage: StorageManager,\n config: PluginConfig,\n): Promise<OperatorDoctorCheck> {\n const storageWithLedger = storage as StorageManager & {\n readBufferSurpriseEvents?: (\n opts: { limit?: number },\n ) => Promise<BufferSurpriseEvent[]>;\n };\n\n // Defensive: older StorageManager builds (not yet rebuilt) may lack the\n // reader. Do not fail the entire Doctor run in that case.\n if (typeof storageWithLedger.readBufferSurpriseEvents !== \"function\") {\n return {\n key: \"buffer_surprise_distribution\",\n status: \"ok\",\n summary: \"Buffer-surprise telemetry reader unavailable in this build.\",\n details: { available: false },\n };\n }\n\n try {\n const dist = await reportBufferSurpriseDistribution(\n async (opts) =>\n storageWithLedger.readBufferSurpriseEvents!({ limit: opts.limit }),\n { limit: 200 },\n );\n\n if (dist.count === 0) {\n return {\n key: \"buffer_surprise_distribution\",\n status: \"ok\",\n summary: config.bufferSurpriseTriggerEnabled\n ? \"Surprise trigger is enabled but no telemetry has been recorded yet.\"\n : \"Surprise trigger is disabled; no telemetry expected.\",\n details: {\n enabled: config.bufferSurpriseTriggerEnabled,\n distribution: dist,\n },\n };\n }\n\n const pct = (value: number) => (value * 100).toFixed(1);\n return {\n key: \"buffer_surprise_distribution\",\n status: \"ok\",\n summary: `Recent surprise: mean=${dist.mean.toFixed(3)}, median=${dist.median.toFixed(3)}, p90=${dist.p90.toFixed(3)}, triggered=${pct(dist.triggeredRate)}% over ${dist.count} turns (threshold=${dist.currentThreshold ?? config.bufferSurpriseThreshold}).`,\n details: {\n enabled: config.bufferSurpriseTriggerEnabled,\n distribution: dist,\n },\n };\n } catch (err) {\n return {\n key: \"buffer_surprise_distribution\",\n status: \"warn\",\n summary: \"Could not read buffer-surprise telemetry ledger.\",\n remediation:\n \"Retry `remnic doctor` after ensuring the memory state directory is readable.\",\n details: { error: String(err) },\n };\n }\n}\n\n/**\n * Summarize the consolidation-provenance integrity scan for the doctor\n * report (issue #561 PR 4). Returns an `ok` check when no issues are\n * found, `warn` otherwise. Never returns `error` — a broken provenance\n * pointer is informational because it can legitimately result from log\n * pruning, versioning being disabled retroactively, or operator-driven\n * archive operations.\n *\n * Exported so unit tests can exercise the summarization without booting a\n * full orchestrator.\n */\n\nasync function summarizeGraphEdgeDecayStatus(\n config: Pick<\n PluginConfig,\n \"memoryDir\" | \"graphEdgeDecayEnabled\" | \"graphEdgeDecayCadenceMs\"\n >,\n): Promise<OperatorDoctorCheck> {\n // Lazy import to keep the doctor fast when the feature is disabled.\n const { readGraphEdgeDecayStatus } = await import(\"./maintenance/graph-edge-decay.js\");\n const enabled = config.graphEdgeDecayEnabled === true;\n if (!enabled) {\n return {\n key: \"graph_edge_decay\",\n status: \"ok\",\n summary: \"Graph-edge decay maintenance is disabled (graphEdgeDecayEnabled = false).\",\n remediation: \"Set graphEdgeDecayEnabled = true to opt into the periodic decay job (issue #681).\",\n details: { enabled: false },\n };\n }\n\n const status = await readGraphEdgeDecayStatus(config.memoryDir);\n if (!status) {\n return {\n key: \"graph_edge_decay\",\n status: \"warn\",\n summary: \"Graph-edge decay is enabled but has not run yet (no status file present).\",\n remediation:\n \"Trigger the cron, run `engram.graph_edge_decay_run` via MCP, or wait for the scheduled cadence to fire.\",\n details: { enabled: true, lastRun: null, cadenceMs: config.graphEdgeDecayCadenceMs },\n };\n }\n\n return {\n key: \"graph_edge_decay\",\n status: \"ok\",\n summary:\n `Graph-edge decay last ran at ${status.ranAt} ` +\n `(${status.edgesDecayed}/${status.edgesTotal} edges decayed, ` +\n `${status.edgesBelowVisibilityThreshold} below visibility threshold).`,\n details: {\n enabled: true,\n lastRun: status.ranAt,\n durationMs: status.durationMs,\n edgesTotal: status.edgesTotal,\n edgesDecayed: status.edgesDecayed,\n edgesBelowVisibilityThreshold: status.edgesBelowVisibilityThreshold,\n topDecayedEntities: status.topDecayedEntities,\n cadenceMs: config.graphEdgeDecayCadenceMs,\n },\n };\n}\n\n/**\n * Summarize hot/cold tier distribution for the Doctor report\n * (issue #686 retention-completion).\n *\n * Shows:\n * - hot vs cold memory counts\n * - forgotten-memory count\n * - top per-status breakdown\n * - recent migrations in the last 7 days (from the tier-migration journal)\n * - top demotion reasons from the journal\n *\n * Always returns an `ok` check — this section is informational, never\n * a gate. A missing journal or unreadable corpus is surfaced as a note,\n * not an error.\n *\n * Exported so tests can exercise the summarizer without a full orchestrator.\n */\nexport async function summarizeTierDistribution(\n storage: StorageManager,\n): Promise<OperatorDoctorCheck> {\n try {\n const { summarizeTiers } = await import(\"./maintenance/tier-stats.js\");\n const summary = await summarizeTiers(storage);\n\n // Read recent migration journal entries (last 7 days)\n const storageDir = (storage as unknown as { dir?: string }).dir ?? \"\";\n const journalPath = storageDir.length > 0\n ? path.join(storageDir, \"state\", \"tier-migration-journal.jsonl\")\n : null;\n let recentMigrations = 0;\n const demotionReasons: Record<string, number> = {};\n const sevenDaysAgoMs = Date.now() - 7 * 86_400_000;\n\n if (journalPath) {\n try {\n const { readFile } = await import(\"node:fs/promises\");\n const raw = await readFile(journalPath, \"utf-8\");\n for (const line of raw.split(\"\\n\")) {\n const trimmed = line.trim();\n if (trimmed.length === 0) continue;\n try {\n const entry = JSON.parse(trimmed) as {\n ts?: string;\n changed?: boolean;\n fromTier?: string;\n toTier?: string;\n reason?: string;\n };\n const tsMs = entry.ts ? Date.parse(entry.ts) : NaN;\n if (Number.isFinite(tsMs) && tsMs >= sevenDaysAgoMs && entry.changed === true) {\n recentMigrations += 1;\n if (entry.fromTier === \"hot\" && entry.toTier === \"cold\" && typeof entry.reason === \"string\") {\n const reason = entry.reason;\n demotionReasons[reason] = (demotionReasons[reason] ?? 0) + 1;\n }\n }\n } catch {\n // Malformed line — skip\n }\n }\n } catch {\n // Journal not present yet — expected on fresh installs\n }\n }\n\n const topDemotionReasons = Object.entries(demotionReasons)\n .sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))\n .slice(0, 5)\n .map(([reason, count]) => ({ reason, count }));\n\n const statusParts = Object.entries(summary.byStatus)\n .sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))\n .slice(0, 6)\n .map(([s, n]) => `${s}: ${n}`)\n .join(\", \");\n\n return {\n key: \"tier_distribution\",\n status: \"ok\",\n summary:\n `Tier distribution: hot=${summary.byTier.hot}, cold=${summary.byTier.cold}` +\n (summary.forgottenCount > 0 ? `, forgotten=${summary.forgottenCount}` : \"\") +\n `. Total: ${summary.total}.` +\n (recentMigrations > 0 ? ` Recent migrations (7d): ${recentMigrations}.` : \"\"),\n details: {\n total: summary.total,\n byTier: summary.byTier,\n byStatus: summary.byStatus,\n forgottenCount: summary.forgottenCount,\n statusSummary: statusParts,\n recentMigrations,\n topDemotionReasons,\n },\n };\n } catch (err) {\n return {\n key: \"tier_distribution\",\n status: \"ok\",\n summary: \"Tier distribution unavailable — could not enumerate memories.\",\n details: { error: String(err) },\n };\n }\n}\n\n/**\n * Dreams phases doctor check (issue #678 PR 2/4).\n *\n * Reports per-phase: enabled status, cadence, threshold values, and last-run\n * timestamp sourced from `meta.json` (the existing maintenance ledger).\n *\n * Last-run mapping (best available in PR 2; PR 3/4 will emit per-phase events):\n * light sleep → `meta.lastExtractionAt` (lifecycle pass runs with extraction)\n * REM → `meta.lastConsolidationAt` (semantic consolidation)\n * deep sleep → latest governance run manifest when present, otherwise null\n */\nexport async function summarizeDreamsPhases(\n config: Pick<PluginConfig, \"memoryDir\" | \"dreamsPhases\">,\n storage: StorageManager = new StorageManager(config.memoryDir),\n): Promise<OperatorDoctorCheck> {\n const phases: DreamsPhasesConfig = config.dreamsPhases;\n\n // Load meta.json for best-available last-run timestamps.\n const meta = await storage.loadMeta();\n\n let deepSleepLastRun: string | null = null;\n let deepSleepLastRunWarning: string | null = null;\n try {\n // Read the latest governance run's manifest from the real on-disk format\n // rather than treating every failure as \"no runs yet\".\n const runsDir = path.join(config.memoryDir, \"state\", \"memory-governance\", \"runs\");\n const runIds = (await readdir(runsDir)).sort().reverse();\n if (runIds.length > 0) {\n const latestRunId = runIds[0];\n const manifestPath = path.join(\n runsDir,\n latestRunId,\n \"manifest.json\",\n );\n const raw = await readFile(manifestPath, \"utf-8\");\n const parsed = JSON.parse(raw) as Record<string, unknown>;\n if (typeof parsed.createdAt === \"string\" && parsed.createdAt.length > 0) {\n deepSleepLastRun = parsed.createdAt;\n }\n }\n } catch (error) {\n if (!isMissingPathError(error)) {\n deepSleepLastRunWarning = `Could not read latest governance run manifest: ${formatUnknownError(error)}`;\n }\n }\n\n // Build per-phase summary lines for the human-readable `summary` field.\n const phaseLines: string[] = [\n `lightSleep: enabled=${phases.lightSleep.enabled}, cadenceMs=${phases.lightSleep.cadenceMs}, promoteHeat=${phases.lightSleep.promoteHeatThreshold}, staleDecay=${phases.lightSleep.staleDecayThreshold}, archiveDecay=${phases.lightSleep.archiveDecayThreshold}, filterStale=${phases.lightSleep.filterStaleEnabled}, lastRun=${meta.lastExtractionAt ?? \"never\"}`,\n `rem: enabled=${phases.rem.enabled}, cadenceMs=${phases.rem.cadenceMs}, similarity=${phases.rem.similarityThreshold}, minCluster=${phases.rem.minClusterSize}, maxPerRun=${phases.rem.maxPerRun}, minIntervalMs=${phases.rem.minIntervalMs}, lastRun=${meta.lastConsolidationAt ?? \"never\"}`,\n `deepSleep: enabled=${phases.deepSleep.enabled}, cadenceMs=${phases.deepSleep.cadenceMs}, versioning=${phases.deepSleep.versioningEnabled}, versioningMaxPerPage=${phases.deepSleep.versioningMaxPerPage}, lastRun=${deepSleepLastRun ?? \"never\"}`,\n ];\n\n return {\n key: \"dreams_phases\",\n status: deepSleepLastRunWarning ? \"warn\" : \"ok\",\n summary: `Dreams pipeline phases: ${phaseLines.join(\"; \")}${deepSleepLastRunWarning ? `; ${deepSleepLastRunWarning}` : \"\"}`,\n remediation: deepSleepLastRunWarning\n ? \"Inspect state/memory-governance/runs and repair or remove unreadable governance run artifacts.\"\n : undefined,\n details: {\n lightSleep: {\n enabled: phases.lightSleep.enabled,\n cadenceMs: phases.lightSleep.cadenceMs,\n promoteHeatThreshold: phases.lightSleep.promoteHeatThreshold,\n staleDecayThreshold: phases.lightSleep.staleDecayThreshold,\n archiveDecayThreshold: phases.lightSleep.archiveDecayThreshold,\n filterStaleEnabled: phases.lightSleep.filterStaleEnabled,\n lastRun: meta.lastExtractionAt ?? null,\n },\n rem: {\n enabled: phases.rem.enabled,\n cadenceMs: phases.rem.cadenceMs,\n similarityThreshold: phases.rem.similarityThreshold,\n minClusterSize: phases.rem.minClusterSize,\n maxPerRun: phases.rem.maxPerRun,\n minIntervalMs: phases.rem.minIntervalMs,\n lastRun: meta.lastConsolidationAt ?? null,\n },\n deepSleep: {\n enabled: phases.deepSleep.enabled,\n cadenceMs: phases.deepSleep.cadenceMs,\n versioningEnabled: phases.deepSleep.versioningEnabled,\n versioningMaxPerPage: phases.deepSleep.versioningMaxPerPage,\n lastRun: deepSleepLastRun,\n warning: deepSleepLastRunWarning,\n },\n },\n };\n}\n\nfunction summarizeSecurityMitigations(\n config: Pick<\n PluginConfig,\n | \"recallCrossNamespaceBudgetEnabled\"\n | \"recallCrossNamespaceBudgetWindowMs\"\n | \"recallCrossNamespaceBudgetSoftLimit\"\n | \"recallCrossNamespaceBudgetHardLimit\"\n | \"recallAuditAnomalyDetectionEnabled\"\n | \"recallAuditAnomalyWindowMs\"\n | \"recallAuditAnomalyRepeatQueryLimit\"\n | \"recallAuditAnomalyNamespaceWalkLimit\"\n | \"recallAuditAnomalyHighCardinalityLimit\"\n | \"recallAuditAnomalyRapidFireLimit\"\n >,\n): OperatorDoctorCheck {\n const budgetEnabled = config.recallCrossNamespaceBudgetEnabled === true;\n const anomalyEnabled = config.recallAuditAnomalyDetectionEnabled === true;\n\n if (!budgetEnabled && !anomalyEnabled) {\n return {\n key: \"security_mitigations\",\n status: \"warn\",\n summary: \"Memory-extraction mitigations are disabled (cross-namespace budget and anomaly detection off).\",\n remediation: \"Enable recallCrossNamespaceBudgetEnabled and/or recallAuditAnomalyDetectionEnabled for production deployments. See docs/security/memory-extraction-threat-model.md.\",\n details: {\n budgetEnabled: false,\n anomalyDetectionEnabled: false,\n },\n };\n }\n\n const details: Record<string, unknown> = {\n budgetEnabled,\n anomalyDetectionEnabled: anomalyEnabled,\n };\n\n if (budgetEnabled) {\n details.budgetConfig = {\n windowMs: config.recallCrossNamespaceBudgetWindowMs,\n softLimit: config.recallCrossNamespaceBudgetSoftLimit,\n hardLimit: config.recallCrossNamespaceBudgetHardLimit,\n };\n }\n\n if (anomalyEnabled) {\n details.anomalyConfig = {\n windowMs: config.recallAuditAnomalyWindowMs,\n repeatQueryLimit: config.recallAuditAnomalyRepeatQueryLimit,\n namespaceWalkLimit: config.recallAuditAnomalyNamespaceWalkLimit,\n highCardinalityLimit: config.recallAuditAnomalyHighCardinalityLimit,\n rapidFireLimit: config.recallAuditAnomalyRapidFireLimit,\n };\n }\n\n return {\n key: \"security_mitigations\",\n status: \"ok\",\n summary: `Memory-extraction mitigation config enabled: ${budgetEnabled ? \"budget\" : \"\"}${budgetEnabled && anomalyEnabled ? \", \" : \"\"}${anomalyEnabled ? \"anomaly detection\" : \"\"}.`,\n details: { ...details, configOnly: true },\n };\n}\n\n/**\n * Observation throughput check for `remnic doctor` (issue #685).\n *\n * Reads the extraction-judge verdict ledger to surface:\n * - total observations (verdicts) recorded\n * - accept / reject / defer breakdown\n * - most-recent `observedAt` timestamp\n *\n * The check is purely informational (always `ok`): a missing or empty\n * ledger is the expected state on a fresh install and is never an error.\n * This closes the `*(future)*` item deferred in `docs/trace-to-primitive.md`.\n */\nexport async function summarizeObservationThroughput(\n memoryDir: string,\n): Promise<OperatorDoctorCheck> {\n try {\n const stats = await readJudgeVerdictStats(memoryDir);\n if (stats.total === 0) {\n return {\n key: \"observations\",\n status: \"ok\",\n summary: \"No observations recorded yet (extraction-judge telemetry ledger is empty or missing).\",\n details: { total: 0, accept: 0, reject: 0, defer: 0, lastObservedAt: null },\n };\n }\n const acceptPct = ((stats.accept / stats.total) * 100).toFixed(1);\n const rejectPct = ((stats.reject / stats.total) * 100).toFixed(1);\n const deferPct = ((stats.defer / stats.total) * 100).toFixed(1);\n return {\n key: \"observations\",\n status: \"ok\",\n summary: `${stats.total} observations recorded: accept=${acceptPct}%, reject=${rejectPct}%, defer=${deferPct}%. Last observed: ${stats.lastTs ?? \"unknown\"}.`,\n details: {\n total: stats.total,\n accept: stats.accept,\n reject: stats.reject,\n defer: stats.defer,\n deferCapTriggered: stats.deferCapTriggered,\n deferRate: stats.deferRate,\n meanElapsedMs: stats.meanElapsedMs,\n firstObservedAt: stats.firstTs ?? null,\n lastObservedAt: stats.lastTs ?? null,\n },\n };\n } catch (err) {\n return {\n key: \"observations\",\n status: \"warn\",\n summary: \"Could not read observation telemetry ledger.\",\n remediation: \"Retry `remnic doctor` after ensuring the memory state directory is readable.\",\n details: { error: String(err) },\n };\n }\n}\n\nexport async function summarizeConsolidationProvenance(\n storage: StorageManager,\n config: Pick<PluginConfig, \"memoryDir\"> & { versioningSidecarDir?: string },\n): Promise<OperatorDoctorCheck> {\n let report: ConsolidationProvenanceReport;\n try {\n report = await runConsolidationProvenanceCheck({\n storage,\n memoryDir: config.memoryDir,\n // Honor the configured sidecar directory (PR #634 review): when an\n // operator overrides `versioningSidecarDir`, the default `.versions`\n // would point at the wrong location and every entry would report as\n // missing. Undefined falls back to the helper's default.\n sidecarDir: config.versioningSidecarDir,\n });\n } catch (err) {\n return {\n key: \"consolidation_provenance\",\n status: \"warn\",\n summary: \"Could not run consolidation-provenance integrity check.\",\n remediation: \"Ensure the memory directory is readable and rerun `remnic doctor`.\",\n details: { error: String(err) },\n };\n }\n\n if (report.issues.length === 0) {\n return {\n key: \"consolidation_provenance\",\n status: \"ok\",\n summary:\n report.withProvenance === 0\n ? \"No consolidation-provenance memories on disk yet.\"\n : `${report.withProvenance} consolidation-provenance memories verified (no broken references).`,\n details: report,\n };\n }\n\n return {\n key: \"consolidation_provenance\",\n status: \"warn\",\n summary: `${report.issues.length} consolidation-provenance integrity issue(s) detected across ${report.withProvenance} memories with provenance frontmatter.`,\n remediation:\n \"Broken pointers are informational. Inspect flagged memories, and if they should resolve, re-snapshot via a consolidation pass or accept pruning.\",\n details: report,\n };\n}\n\nfunction getMemoryAgeBand(memory: MemoryFile, now: Date): string {\n const created = Date.parse(memory.frontmatter.created ?? \"\");\n if (!Number.isFinite(created)) return \"unknown\";\n const ageDays = Math.max(0, Math.floor((now.getTime() - created) / 86_400_000));\n if (ageDays < 7) return \"0_6d\";\n if (ageDays < 30) return \"7_29d\";\n if (ageDays < 90) return \"30_89d\";\n return \"90d_plus\";\n}\n\nasync function dirSize(targetPath: string): Promise<number> {\n try {\n const info = await stat(targetPath);\n if (info.isFile()) return info.size;\n if (!info.isDirectory()) return 0;\n } catch {\n return 0;\n }\n\n let total = 0;\n let entries;\n try {\n entries = await readdir(targetPath, { withFileTypes: true });\n } catch {\n return 0;\n }\n for (const entry of entries) {\n total += await dirSize(path.join(targetPath, entry.name));\n }\n return total;\n}\n\nasync function summarizeStorageFootprint(memoryDir: string): Promise<{ bytes: number; byTopLevel: Record<string, number> }> {\n const topLevel = [\n \"facts\",\n \"entities\",\n \"questions\",\n \"corrections\",\n \"artifacts\",\n \"state\",\n \"identity\",\n \"namespaces\",\n \"summaries\",\n \"profile.md\",\n ];\n const byTopLevel: Record<string, number> = {};\n let bytes = 0;\n for (const name of topLevel) {\n const size = await dirSize(path.join(memoryDir, name));\n if (size > 0) {\n byTopLevel[name] = size;\n bytes += size;\n }\n }\n return { bytes, byTopLevel };\n}\n\nexport async function runOperatorInventory(options: OperatorInventoryOptions): Promise<OperatorInventoryReport> {\n const now = options.now ?? new Date();\n const config = options.orchestrator.config;\n const namespaceEntries = await listNamespaces({ config });\n const uniqueRootEntries = new Map<string, { namespace: string; rootDir: string }>();\n for (const entry of namespaceEntries) {\n if (!uniqueRootEntries.has(entry.rootDir)) {\n uniqueRootEntries.set(entry.rootDir, { namespace: entry.namespace, rootDir: entry.rootDir });\n }\n }\n const categories: Record<string, number> = {};\n const statuses: Record<string, number> = {};\n const ageBands: Record<string, number> = {\n \"0_6d\": 0,\n \"7_29d\": 0,\n \"30_89d\": 0,\n \"90d_plus\": 0,\n unknown: 0,\n };\n const namespaces: OperatorInventoryNamespaceSummary[] = [];\n let totalMemories = 0;\n let totalEntities = 0;\n let archived = 0;\n let pendingReview = 0;\n let quarantined = 0;\n let rejected = 0;\n\n for (const entry of uniqueRootEntries.values()) {\n const storage = new StorageManager(entry.rootDir);\n const memories = await storage.readAllMemories();\n const entities = await storage.readAllEntityFiles();\n namespaces.push({\n namespace: entry.namespace,\n memoryCount: memories.length,\n entityCount: entities.length,\n });\n totalMemories += memories.length;\n totalEntities += entities.length;\n for (const memory of memories) {\n const category = memory.frontmatter.category;\n categories[category] = (categories[category] ?? 0) + 1;\n const status = memory.frontmatter.status ?? \"active\";\n statuses[status] = (statuses[status] ?? 0) + 1;\n ageBands[getMemoryAgeBand(memory, now)] += 1;\n if (status === \"archived\") archived += 1;\n if (status === \"pending_review\") pendingReview += 1;\n if (status === \"quarantined\") quarantined += 1;\n if (status === \"rejected\") rejected += 1;\n }\n }\n\n const defaultStorage = new StorageManager(config.memoryDir);\n const profile = await defaultStorage.readProfile();\n const footprint = await summarizeStorageFootprint(config.memoryDir);\n const reviewRunId = (await listMemoryGovernanceRuns(config.memoryDir))[0];\n let reviewQueue = 0;\n if (reviewRunId) {\n try {\n reviewQueue = (await readMemoryGovernanceRunArtifact(config.memoryDir, reviewRunId)).reviewQueue.length;\n } catch {\n reviewQueue = 0;\n }\n }\n const conversationIndex = await options.orchestrator.getConversationIndexHealth();\n const nativeKnowledgeStatus = await summarizeNativeKnowledgeStatus(config);\n\n return {\n schemaVersion: 1,\n generatedAt: now.toISOString(),\n memoryDir: config.memoryDir,\n totals: {\n memories: totalMemories,\n entities: totalEntities,\n namespaces: namespaceEntries.length,\n reviewQueue,\n storageBytes: footprint.bytes,\n },\n categories,\n statuses,\n namespaces,\n ageBands,\n profile: {\n exists: profile.length > 0,\n chars: profile.length,\n lines: profile.length > 0 ? profile.split(\"\\n\").length : 0,\n },\n storageFootprint: footprint,\n archivePressure: {\n archived,\n pendingReview,\n quarantined,\n rejected,\n },\n conversationIndex: {\n enabled: conversationIndex.enabled,\n backend: conversationIndex.backend,\n status: conversationIndex.status,\n chunkDocCount: conversationIndex.chunkDocCount,\n lastUpdateAt: conversationIndex.lastUpdateAt,\n },\n nativeKnowledge: {\n enabled: nativeKnowledgeStatus.enabled,\n curatedIncludeSync: nativeKnowledgeStatus.curatedIncludeSync,\n obsidianSync: nativeKnowledgeStatus.obsidianSync,\n openclawWorkspaceSync: nativeKnowledgeStatus.openclawWorkspaceSync,\n },\n };\n}\n\nexport async function runBenchmarkRecall(options: BenchmarkRecallOptions): Promise<BenchmarkRecallReport> {\n const now = options.now ?? new Date();\n const status = await getEvalHarnessStatus({\n memoryDir: options.config.memoryDir,\n evalStoreDir: options.config.evalStoreDir,\n enabled: options.config.evalHarnessEnabled,\n shadowModeEnabled: options.config.evalShadowModeEnabled,\n baselineSnapshotsEnabled: options.config.benchmarkBaselineSnapshotsEnabled,\n memoryRedTeamBenchEnabled: options.config.memoryRedTeamBenchEnabled,\n });\n\n if (options.createSnapshot && options.snapshotId) {\n const snapshot = await createEvalBaselineSnapshot({\n memoryDir: options.config.memoryDir,\n evalStoreDir: options.config.evalStoreDir,\n baselineSnapshotsEnabled: options.config.benchmarkBaselineSnapshotsEnabled,\n snapshotId: options.snapshotId,\n notes: options.snapshotNotes,\n gitRef: options.gitRef,\n createdAt: options.createdAt,\n });\n return {\n schemaVersion: 1,\n generatedAt: now.toISOString(),\n mode: \"snapshot\",\n status,\n snapshot: {\n targetPath: snapshot.targetPath,\n snapshotId: snapshot.snapshot.snapshotId,\n },\n };\n }\n\n if (options.baseEvalStoreDir && options.candidateEvalStoreDir) {\n const ciGate = await runEvalBenchmarkCiGate({\n baseEvalStoreDir: options.baseEvalStoreDir,\n candidateEvalStoreDir: options.candidateEvalStoreDir,\n });\n return {\n schemaVersion: 1,\n generatedAt: now.toISOString(),\n mode: \"ci-gate\",\n status,\n ciGate,\n };\n }\n\n if (options.snapshotId) {\n const baselineReport = await runEvalBaselineDeltaReport({\n memoryDir: options.config.memoryDir,\n evalStoreDir: options.config.evalStoreDir,\n benchmarkDeltaReporterEnabled: options.config.benchmarkDeltaReporterEnabled,\n snapshotId: options.snapshotId,\n });\n return {\n schemaVersion: 1,\n generatedAt: now.toISOString(),\n mode: \"baseline-report\",\n status,\n baselineReport,\n };\n }\n\n if (options.validatePath) {\n const validate = await validateEvalBenchmarkPack(options.validatePath, {\n memoryRedTeamBenchEnabled: options.config.memoryRedTeamBenchEnabled,\n });\n return {\n schemaVersion: 1,\n generatedAt: now.toISOString(),\n mode: \"validate\",\n status,\n validate,\n };\n }\n\n return {\n schemaVersion: 1,\n generatedAt: now.toISOString(),\n mode: \"status\",\n status,\n };\n}\n\nexport async function runOperatorRepair(options: OperatorRepairOptions): Promise<OperatorRepairReport> {\n const now = options.now ?? new Date();\n const dryRun = options.dryRun === true || options.apply !== true;\n const sessionCheck = await analyzeSessionIntegrity({ memoryDir: options.config.memoryDir });\n const sessionRepairPlan = planSessionRepair({\n report: sessionCheck,\n dryRun,\n allowSessionFileRepair: options.allowSessionFileRepair,\n sessionFilesDir: options.sessionFilesDir,\n });\n const sessionRepairApply = await applySessionRepair({\n plan: sessionRepairPlan,\n });\n const graphHealth = await analyzeGraphHealth(options.config.memoryDir, {\n entityGraphEnabled: options.config.entityGraphEnabled,\n timeGraphEnabled: options.config.timeGraphEnabled,\n causalGraphEnabled: options.config.causalGraphEnabled,\n includeRepairGuidance: true,\n });\n return {\n schemaVersion: 1,\n generatedAt: now.toISOString(),\n dryRun,\n sessionCheck,\n sessionRepairPlan,\n sessionRepairApply,\n graphHealth,\n };\n}\n"],"mappings":"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","names":["readFile"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/work/storage.ts"],"sourcesContent":["import path from \"node:path\";\nimport { randomUUID } from \"node:crypto\";\nimport { mkdir, readdir, readFile, rm, writeFile } from \"node:fs/promises\";\nimport type {\n CreateWorkProjectInput,\n CreateWorkTaskInput,\n UpdateWorkProjectInput,\n UpdateWorkTaskInput,\n WorkProject,\n WorkProjectStatus,\n WorkTask,\n WorkTaskListFilter,\n WorkTaskStatus,\n} from \"./types.js\";\nimport { isErrnoCode } from \"../utils/errno.js\";\n\nconst TASK_TRANSITIONS: Record<WorkTaskStatus, Set<WorkTaskStatus>> = {\n todo: new Set([\"in_progress\", \"blocked\", \"cancelled\"]),\n in_progress: new Set([\"todo\", \"blocked\", \"done\", \"cancelled\"]),\n blocked: new Set([\"todo\", \"in_progress\", \"cancelled\"]),\n done: new Set(),\n cancelled: new Set(),\n};\n\nfunction serializeFrontmatter(values: object): string {\n const lines = Object.entries(values).map(([k, v]) => `${k}: ${JSON.stringify(v)}`);\n return `---\\n${lines.join(\"\\n\")}\\n---`;\n}\n\nfunction parseFrontmatter(raw: string): { data: Record<string, unknown>; body: string } | null {\n const match = raw.match(/^---\\n([\\s\\S]*?)\\n---\\n?([\\s\\S]*)$/);\n if (!match) return null;\n const fm = match[1] ?? \"\";\n const body = match[2] ?? \"\";\n const data: Record<string, unknown> = {};\n for (const line of fm.split(\"\\n\")) {\n if (!line.trim()) continue;\n const idx = line.indexOf(\":\");\n if (idx <= 0) continue;\n const key = line.slice(0, idx).trim();\n const rawValue = line.slice(idx + 1).trim();\n try {\n data[key] = JSON.parse(rawValue);\n } catch {\n data[key] = rawValue;\n }\n }\n return { data, body };\n}\n\nfunction toSafeSlug(value: string): string {\n let slug = value.toLowerCase().trim().replace(/[^a-z0-9]+/g, \"-\");\n // Trim leading/trailing dashes without ReDoS-prone anchored quantifiers\n let start = 0;\n while (start < slug.length && slug[start] === \"-\") start++;\n let end = slug.length;\n while (end > start && slug[end - 1] === \"-\") end--;\n return slug.slice(start, end).slice(0, 80);\n}\n\nexport const WORK_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9-]{0,127}$/;\n\nfunction makeId(prefix: string, titleOrName: string, now: Date): string {\n const slug = toSafeSlug(titleOrName) || \"item\";\n const nonce = randomUUID().slice(0, 8);\n return `${prefix}-${now.getTime()}-${slug}-${nonce}`;\n}\n\nfunction assertValidWorkId(id: string, kind: \"task\" | \"project\"): void {\n if (!WORK_ID_PATTERN.test(id)) {\n throw new Error(`invalid ${kind} id: ${id}`);\n }\n}\n\nfunction ensureString(value: unknown, fallback = \"\"): string {\n return typeof value === \"string\" ? value : fallback;\n}\n\nfunction ensureStringArray(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n return value.filter((entry) => typeof entry === \"string\");\n}\n\nfunction ensureNullableString(value: unknown): string | null {\n return typeof value === \"string\" ? value : null;\n}\n\nfunction ensureTaskStatus(value: unknown): WorkTaskStatus {\n if (value === \"todo\" || value === \"in_progress\" || value === \"blocked\" || value === \"done\" || value === \"cancelled\") {\n return value;\n }\n return \"todo\";\n}\n\nfunction ensureTaskPriority(value: unknown): WorkTask[\"priority\"] {\n if (value === \"low\" || value === \"medium\" || value === \"high\") return value;\n return \"medium\";\n}\n\nfunction ensureProjectStatus(value: unknown): WorkProjectStatus {\n if (value === \"active\" || value === \"on_hold\" || value === \"completed\" || value === \"archived\") return value;\n return \"active\";\n}\n\nexport class WorkStorage {\n private readonly tasksDir: string;\n private readonly projectsDir: string;\n\n constructor(private readonly memoryDir: string) {\n this.tasksDir = path.join(memoryDir, \"work\", \"tasks\");\n this.projectsDir = path.join(memoryDir, \"work\", \"projects\");\n }\n\n async ensureDirectories(): Promise<void> {\n await mkdir(this.tasksDir, { recursive: true });\n await mkdir(this.projectsDir, { recursive: true });\n }\n\n private taskPath(id: string): string {\n assertValidWorkId(id, \"task\");\n return path.join(this.tasksDir, `${id}.md`);\n }\n\n private projectPath(id: string): string {\n assertValidWorkId(id, \"project\");\n return path.join(this.projectsDir, `${id}.md`);\n }\n\n private serializeTask(task: WorkTask): string {\n return `${serializeFrontmatter(task)}\\n\\n${task.description}\\n`;\n }\n\n private serializeProject(project: WorkProject): string {\n return `${serializeFrontmatter(project)}\\n\\n${project.description}\\n`;\n }\n\n private async writeNewTask(task: WorkTask): Promise<void> {\n try {\n await writeFile(this.taskPath(task.id), this.serializeTask(task), { encoding: \"utf-8\", flag: \"wx\" });\n } catch (error) {\n if (isErrnoCode(error, \"EEXIST\")) {\n throw new Error(`task already exists: ${task.id}`);\n }\n throw error;\n }\n }\n\n private async writeNewProject(project: WorkProject): Promise<void> {\n try {\n await writeFile(this.projectPath(project.id), this.serializeProject(project), { encoding: \"utf-8\", flag: \"wx\" });\n } catch (error) {\n if (isErrnoCode(error, \"EEXIST\")) {\n throw new Error(`project already exists: ${project.id}`);\n }\n throw error;\n }\n }\n\n private parseTask(raw: string): WorkTask | null {\n const parsed = parseFrontmatter(raw);\n if (!parsed) return null;\n const d = parsed.data;\n return {\n id: ensureString(d.id),\n title: ensureString(d.title),\n description: ensureString(d.description, parsed.body.trim()),\n status: ensureTaskStatus(d.status),\n priority: ensureTaskPriority(d.priority),\n owner: ensureNullableString(d.owner),\n assignee: ensureNullableString(d.assignee),\n projectId: ensureNullableString(d.projectId),\n tags: ensureStringArray(d.tags),\n dueAt: ensureNullableString(d.dueAt),\n createdAt: ensureString(d.createdAt),\n updatedAt: ensureString(d.updatedAt),\n };\n }\n\n private parseProject(raw: string): WorkProject | null {\n const parsed = parseFrontmatter(raw);\n if (!parsed) return null;\n const d = parsed.data;\n return {\n id: ensureString(d.id),\n name: ensureString(d.name),\n description: ensureString(d.description, parsed.body.trim()),\n status: ensureProjectStatus(d.status),\n owner: ensureNullableString(d.owner),\n tags: ensureStringArray(d.tags),\n taskIds: ensureStringArray(d.taskIds),\n createdAt: ensureString(d.createdAt),\n updatedAt: ensureString(d.updatedAt),\n };\n }\n\n async createTask(input: CreateWorkTaskInput, now = new Date()): Promise<WorkTask> {\n await this.ensureDirectories();\n const timestamp = now.toISOString();\n const task: WorkTask = {\n id: input.id ?? makeId(\"task\", input.title, now),\n title: input.title,\n description: input.description ?? \"\",\n status: input.status ?? \"todo\",\n priority: input.priority ?? \"medium\",\n owner: input.owner ?? null,\n assignee: input.assignee ?? null,\n projectId: input.projectId ?? null,\n tags: input.tags ?? [],\n dueAt: input.dueAt ?? null,\n createdAt: timestamp,\n updatedAt: timestamp,\n };\n\n if (task.projectId) {\n const project = await this.getProject(task.projectId);\n if (!project) {\n throw new Error(`project not found: ${task.projectId}`);\n }\n }\n\n await this.writeNewTask(task);\n\n if (task.projectId) {\n await this.addTaskIdToProject(task.projectId, task.id, now);\n }\n\n return task;\n }\n\n async getTask(id: string): Promise<WorkTask | null> {\n try {\n const raw = await readFile(this.taskPath(id), \"utf-8\");\n return this.parseTask(raw);\n } catch {\n return null;\n }\n }\n\n async listTasks(filter?: WorkTaskListFilter): Promise<WorkTask[]> {\n await this.ensureDirectories();\n const entries = await readdir(this.tasksDir, { withFileTypes: true });\n const out: WorkTask[] = [];\n for (const entry of entries) {\n if (!entry.isFile() || !entry.name.endsWith(\".md\")) continue;\n const raw = await readFile(path.join(this.tasksDir, entry.name), \"utf-8\");\n const task = this.parseTask(raw);\n if (!task) continue;\n if (filter?.status && task.status !== filter.status) continue;\n if (filter?.owner && task.owner !== filter.owner) continue;\n if (filter?.assignee && task.assignee !== filter.assignee) continue;\n if (filter?.projectId && task.projectId !== filter.projectId) continue;\n out.push(task);\n }\n out.sort((a, b) => a.createdAt.localeCompare(b.createdAt));\n return out;\n }\n\n async updateTask(\n id: string,\n patch: UpdateWorkTaskInput,\n now = new Date(),\n options?: { skipStatusTransitionValidation?: boolean },\n ): Promise<WorkTask | null> {\n const existing = await this.getTask(id);\n if (!existing) return null;\n\n const projectIdPatched = Object.prototype.hasOwnProperty.call(patch, \"projectId\");\n const statusPatched = Object.prototype.hasOwnProperty.call(patch, \"status\");\n const nextProjectId = projectIdPatched ? patch.projectId ?? null : existing.projectId;\n\n if (\n statusPatched\n && patch.status\n && existing.status !== patch.status\n && options?.skipStatusTransitionValidation !== true\n && !TASK_TRANSITIONS[existing.status].has(patch.status)\n ) {\n throw new Error(`invalid task status transition: ${existing.status} -> ${patch.status}`);\n }\n\n if (projectIdPatched && nextProjectId) {\n const nextProject = await this.getProject(nextProjectId);\n if (!nextProject) {\n throw new Error(`project not found: ${nextProjectId}`);\n }\n }\n\n if (projectIdPatched && existing.projectId !== nextProjectId) {\n if (existing.projectId) {\n await this.removeTaskIdFromProject(existing.projectId, id, now);\n }\n if (nextProjectId) {\n await this.addTaskIdToProject(nextProjectId, id, now);\n }\n }\n\n const next: WorkTask = {\n ...existing,\n ...patch,\n projectId: nextProjectId,\n tags: patch.tags ?? existing.tags,\n updatedAt: now.toISOString(),\n };\n await writeFile(this.taskPath(id), this.serializeTask(next), \"utf-8\");\n return next;\n }\n\n async transitionTask(id: string, nextStatus: WorkTaskStatus, now = new Date()): Promise<WorkTask> {\n const existing = await this.getTask(id);\n if (!existing) throw new Error(`task not found: ${id}`);\n if (existing.status === nextStatus) return existing;\n if (!TASK_TRANSITIONS[existing.status].has(nextStatus)) {\n throw new Error(`invalid task status transition: ${existing.status} -> ${nextStatus}`);\n }\n const updated = await this.updateTask(id, { status: nextStatus }, now);\n if (!updated) throw new Error(`task not found after update: ${id}`);\n return updated;\n }\n\n async deleteTask(id: string): Promise<boolean> {\n try {\n const existing = await this.getTask(id);\n await rm(this.taskPath(id));\n if (existing?.projectId) {\n await this.removeTaskIdFromProject(existing.projectId, id);\n }\n return true;\n } catch {\n return false;\n }\n }\n\n async createProject(input: CreateWorkProjectInput, now = new Date()): Promise<WorkProject> {\n await this.ensureDirectories();\n const timestamp = now.toISOString();\n const project: WorkProject = {\n id: input.id ?? makeId(\"project\", input.name, now),\n name: input.name,\n description: input.description ?? \"\",\n status: input.status ?? \"active\",\n owner: input.owner ?? null,\n tags: input.tags ?? [],\n taskIds: [],\n createdAt: timestamp,\n updatedAt: timestamp,\n };\n await this.writeNewProject(project);\n return project;\n }\n\n async getProject(id: string): Promise<WorkProject | null> {\n try {\n const raw = await readFile(this.projectPath(id), \"utf-8\");\n return this.parseProject(raw);\n } catch {\n return null;\n }\n }\n\n async listProjects(): Promise<WorkProject[]> {\n await this.ensureDirectories();\n const entries = await readdir(this.projectsDir, { withFileTypes: true });\n const out: WorkProject[] = [];\n for (const entry of entries) {\n if (!entry.isFile() || !entry.name.endsWith(\".md\")) continue;\n const raw = await readFile(path.join(this.projectsDir, entry.name), \"utf-8\");\n const project = this.parseProject(raw);\n if (project) out.push(project);\n }\n out.sort((a, b) => a.createdAt.localeCompare(b.createdAt));\n return out;\n }\n\n async updateProject(id: string, patch: UpdateWorkProjectInput, now = new Date()): Promise<WorkProject | null> {\n const existing = await this.getProject(id);\n if (!existing) return null;\n const next: WorkProject = {\n ...existing,\n ...patch,\n tags: patch.tags ?? existing.tags,\n taskIds: patch.taskIds ? [...patch.taskIds].sort() : existing.taskIds,\n updatedAt: now.toISOString(),\n };\n await writeFile(this.projectPath(id), this.serializeProject(next), \"utf-8\");\n return next;\n }\n\n async deleteProject(id: string): Promise<boolean> {\n try {\n const existing = await this.getProject(id);\n if (existing) {\n for (const taskId of existing.taskIds) {\n await this.updateTask(taskId, { projectId: null });\n }\n }\n await rm(this.projectPath(id));\n return true;\n } catch {\n return false;\n }\n }\n\n async linkTaskToProject(taskId: string, projectId: string, now = new Date()): Promise<{ task: WorkTask; project: WorkProject }> {\n const task = await this.getTask(taskId);\n if (!task) throw new Error(`task not found: ${taskId}`);\n const project = await this.getProject(projectId);\n if (!project) throw new Error(`project not found: ${projectId}`);\n\n const updatedTask = await this.updateTask(taskId, { projectId }, now);\n if (!updatedTask) throw new Error(`task not found after update: ${taskId}`);\n\n const updatedProject = await this.getProject(projectId);\n if (!updatedProject) throw new Error(`project not found after update: ${projectId}`);\n\n return { task: updatedTask, project: updatedProject };\n }\n\n private async removeTaskIdFromProject(projectId: string, taskId: string, now = new Date()): Promise<void> {\n const project = await this.getProject(projectId);\n if (!project) return;\n\n const filtered = project.taskIds.filter((id) => id !== taskId);\n if (filtered.length === project.taskIds.length) return;\n\n await this.updateProject(projectId, { taskIds: filtered }, now);\n }\n\n private async addTaskIdToProject(projectId: string, taskId: string, now = new Date()): Promise<void> {\n const project = await this.getProject(projectId);\n if (!project) return;\n\n const taskIds = new Set(project.taskIds);\n taskIds.add(taskId);\n await this.updateProject(projectId, { taskIds: Array.from(taskIds) }, now);\n }\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/secure-store/cli-handlers.ts","../src/secure-store/cli-renderer.ts","../src/secure-store/passphrase-reader.ts"],"sourcesContent":["/**\n * Pure handlers behind the `remnic secure-store {init,unlock,lock,\n * status,migrate,disable}` CLI surface (issue #690 PR 2/4 + #779/#780).\n *\n * Each handler:\n * - takes an explicit `memoryDir` (already `~`-expanded by the CLI),\n * - takes an injectable passphrase reader (so tests don't need a\n * real TTY and never touch real readline state),\n * - returns a structured report (no `console.log` inside),\n * - never logs the passphrase or any secret material.\n *\n * The actual `console.log` formatting lives in `cli-renderer.ts` so\n * tests can assert on the report shape without parsing text.\n */\n\nimport { generateSalt as generateEnvelopeSalt } from \"./cipher.js\";\nimport {\n buildHeaderFromPassphrase,\n deriveKeyFromHeader,\n headerPath,\n readHeader,\n secureStoreDir,\n verifyKey,\n writeHeader,\n type SecureStoreHeader,\n} from \"./header.js\";\nimport * as keyring from \"./keyring.js\";\nimport {\n DEFAULT_ARGON2ID_PARAMS,\n DEFAULT_SCRYPT_PARAMS,\n KDF_SALT_LENGTH,\n type Argon2idParams,\n type KdfAlgorithm,\n type ScryptParams,\n} from \"./kdf.js\";\nimport {\n decryptMemoryDirToPlaintext,\n migrateMemoryDirToEncrypted,\n type DecryptResult,\n type MigrateResult,\n} from \"./secure-fs.js\";\n\n/** Passphrase source — async so callers can read from a TTY without echo. */\nexport type PassphraseReader = (\n prompt: string,\n options?: { confirm?: boolean },\n) => Promise<string>;\n\n/** Common options accepted by every handler. */\nexport interface SecureStoreHandlerCommon {\n memoryDir: string;\n /**\n * Stable identifier for the in-memory keyring entry. Defaults to\n * the secure-store directory under `memoryDir`. Tests override\n * this to keep entries from leaking across cases.\n */\n keyringId?: string;\n /** Optional clock injection for deterministic tests. */\n now?: () => Date;\n}\n\n// ─── init ─────────────────────────────────────────────────────────────\n\nexport interface SecureStoreInitOptions extends SecureStoreHandlerCommon {\n /** Passphrase reader — called twice (entry + confirmation). */\n readPassphrase: PassphraseReader;\n /**\n * KDF algorithm. Defaults to `\"argon2id\"` for new stores.\n * `\"scrypt\"` remains supported for explicit compatibility cases.\n */\n algorithm?: KdfAlgorithm;\n /** KDF parameter override; defaults to OWASP-acceptable params for the selected KDF. */\n params?: ScryptParams | Argon2idParams;\n /** Pre-generated salt for tests; production callers should omit. */\n salt?: Buffer;\n /** Optional human-readable note recorded in metadata. Never persist secrets. */\n note?: string;\n}\n\nexport interface SecureStoreInitReport {\n ok: true;\n /** Absolute path of the header file that was written. */\n headerPath: string;\n /** Algorithm + params used for the master key derivation. */\n kdf: SecureStoreHeader[\"metadata\"][\"kdf\"];\n /** ISO-8601 timestamp recorded in the header. */\n createdAt: string;\n}\n\n/**\n * Initialize a new secure-store header. Refuses to overwrite an\n * existing header (use `header.ts:writeHeader` directly with explicit\n * intent if you need to reinitialize a destroyed store).\n */\nexport async function runSecureStoreInit(\n options: SecureStoreInitOptions,\n): Promise<SecureStoreInitReport> {\n const { memoryDir, readPassphrase } = options;\n if (typeof memoryDir !== \"string\" || memoryDir.length === 0) {\n throw new Error(\"secure-store init: memoryDir is required\");\n }\n // Fail fast if a header already exists, before we waste KDF time.\n const existing = await readHeader(memoryDir);\n if (existing !== null) {\n throw new Error(\n `secure-store header already exists at ${headerPath(memoryDir)}. Run 'remnic secure-store status' to inspect, or remove the .secure-store directory explicitly to reinitialize.`,\n );\n }\n const passphrase = await readPassphrase(\"Enter new passphrase: \", { confirm: true });\n validatePassphrase(passphrase);\n\n const algorithm: KdfAlgorithm = options.algorithm ?? \"argon2id\";\n const params = resolveParams(algorithm, options.params);\n const salt = options.salt ?? generateEnvelopeSalt();\n if (salt.length !== KDF_SALT_LENGTH) {\n throw new Error(`salt must be ${KDF_SALT_LENGTH} bytes, got ${salt.length}`);\n }\n\n const built = buildHeaderFromPassphrase({\n passphrase,\n salt,\n algorithm,\n params,\n ...(options.note !== undefined ? { note: options.note } : {}),\n ...(options.now ? { createdAt: options.now().toISOString() } : {}),\n });\n // Zero the derived key — init does NOT auto-unlock; the operator\n // must run `unlock` separately. This mirrors GnuPG-style hygiene\n // and keeps `init` safe to run from automation that should never\n // hold the master key in memory.\n built.derivedKey.fill(0);\n\n const writtenPath = await writeHeader(memoryDir, built.header);\n return {\n ok: true,\n headerPath: writtenPath,\n kdf: built.header.metadata.kdf,\n createdAt: built.header.createdAt,\n };\n}\n\n// ─── unlock ───────────────────────────────────────────────────────────\n\nexport interface SecureStoreUnlockOptions extends SecureStoreHandlerCommon {\n readPassphrase: PassphraseReader;\n}\n\nexport type SecureStoreUnlockReport =\n | { ok: true; unlockedAt: string; algorithm: KdfAlgorithm }\n | { ok: false; reason: \"not-initialized\" | \"wrong-passphrase\" };\n\nexport async function runSecureStoreUnlock(\n options: SecureStoreUnlockOptions,\n): Promise<SecureStoreUnlockReport> {\n const { memoryDir, readPassphrase } = options;\n const header = await readHeader(memoryDir);\n if (!header) {\n return { ok: false, reason: \"not-initialized\" };\n }\n const passphrase = await readPassphrase(\"Enter passphrase: \");\n validatePassphrase(passphrase);\n const candidateKey = deriveKeyFromHeader(header, passphrase);\n if (!verifyKey(header, candidateKey)) {\n candidateKey.fill(0);\n return { ok: false, reason: \"wrong-passphrase\" };\n }\n const id = options.keyringId ?? secureStoreDir(memoryDir);\n const now = options.now ?? (() => new Date());\n keyring.unlock(id, candidateKey, now);\n const status = keyring.status(id);\n return {\n ok: true,\n unlockedAt: status.unlockedAt ?? now().toISOString(),\n algorithm: header.metadata.kdf.algorithm,\n };\n}\n\n// ─── lock ─────────────────────────────────────────────────────────────\n\nexport interface SecureStoreLockOptions extends SecureStoreHandlerCommon {}\n\nexport interface SecureStoreLockReport {\n ok: true;\n /** True if a key was registered and is now cleared; false if it was already locked. */\n cleared: boolean;\n}\n\nexport function runSecureStoreLock(options: SecureStoreLockOptions): SecureStoreLockReport {\n const id = options.keyringId ?? secureStoreDir(options.memoryDir);\n const cleared = keyring.lock(id);\n return { ok: true, cleared };\n}\n\n// ─── migrate ─────────────────────────────────────────────────────────\n\nexport interface SecureStoreMigrateOptions extends SecureStoreHandlerCommon {}\n\nexport type SecureStoreMigrateReport =\n | ({ ok: true } & MigrateResult)\n | ({\n ok: false;\n reason: \"not-initialized\" | \"locked\" | \"file-errors\";\n } & MigrateResult);\n\nexport async function runSecureStoreMigrate(\n options: SecureStoreMigrateOptions,\n): Promise<SecureStoreMigrateReport> {\n const { memoryDir } = options;\n const header = await readHeader(memoryDir);\n if (!header) {\n return {\n ok: false,\n reason: \"not-initialized\",\n encrypted: 0,\n skipped: 0,\n errors: [],\n };\n }\n\n const id = options.keyringId ?? secureStoreDir(memoryDir);\n const key = keyring.getKey(id);\n if (key === null) {\n return {\n ok: false,\n reason: \"locked\",\n encrypted: 0,\n skipped: 0,\n errors: [],\n };\n }\n\n const result = await migrateMemoryDirToEncrypted(memoryDir, key);\n if (result.errors.length > 0) {\n return { ok: false, reason: \"file-errors\", ...result };\n }\n return { ok: true, ...result };\n}\n\n// ─── disable/decrypt ─────────────────────────────────────────────────\n\nexport interface SecureStoreDisableOptions extends SecureStoreHandlerCommon {}\n\nexport type SecureStoreDisableReport =\n | ({ ok: true } & DecryptResult)\n | ({\n ok: false;\n reason: \"not-initialized\" | \"locked\" | \"file-errors\";\n } & DecryptResult);\n\nexport async function runSecureStoreDisable(\n options: SecureStoreDisableOptions,\n): Promise<SecureStoreDisableReport> {\n const { memoryDir } = options;\n const header = await readHeader(memoryDir);\n if (!header) {\n return {\n ok: false,\n reason: \"not-initialized\",\n decrypted: 0,\n skipped: 0,\n errors: [],\n };\n }\n\n const id = options.keyringId ?? secureStoreDir(memoryDir);\n const key = keyring.getKey(id);\n if (key === null) {\n return {\n ok: false,\n reason: \"locked\",\n decrypted: 0,\n skipped: 0,\n errors: [],\n };\n }\n\n const result = await decryptMemoryDirToPlaintext(memoryDir, key);\n if (result.errors.length > 0) {\n return { ok: false, reason: \"file-errors\", ...result };\n }\n return { ok: true, ...result };\n}\n\n// ─── status ───────────────────────────────────────────────────────────\n\nexport interface SecureStoreStatusOptions extends SecureStoreHandlerCommon {}\n\nexport interface SecureStoreStatusReport {\n /** True iff a header file exists in `<memoryDir>/.secure-store/`. */\n initialized: boolean;\n /** Path the status check probed. Useful for operators. */\n headerPath: string;\n /** Locked/unlocked state of the in-memory keyring entry. */\n locked: boolean;\n /** ISO-8601 timestamp of the most recent unlock, or null when locked. */\n unlockedAt: string | null;\n /** Header metadata (algorithm + params + salt hex), or null when uninitialized. */\n kdf: SecureStoreHeader[\"metadata\"][\"kdf\"] | null;\n /** Header `createdAt`, or null when uninitialized. */\n createdAt: string | null;\n}\n\nexport async function runSecureStoreStatus(\n options: SecureStoreStatusOptions,\n): Promise<SecureStoreStatusReport> {\n const { memoryDir } = options;\n const id = options.keyringId ?? secureStoreDir(memoryDir);\n const header = await readHeader(memoryDir);\n const ks = keyring.status(id);\n const target = headerPath(memoryDir);\n if (!header) {\n return {\n initialized: false,\n headerPath: target,\n locked: !ks.unlocked,\n unlockedAt: ks.unlockedAt,\n kdf: null,\n createdAt: null,\n };\n }\n return {\n initialized: true,\n headerPath: target,\n locked: !ks.unlocked,\n unlockedAt: ks.unlockedAt,\n kdf: header.metadata.kdf,\n createdAt: header.createdAt,\n };\n}\n\n// ─── helpers ──────────────────────────────────────────────────────────\n\n/** Minimum passphrase length. 8 chars is intentionally permissive — operators may use phrase managers. */\nexport const MIN_PASSPHRASE_LENGTH = 8;\n\nfunction validatePassphrase(passphrase: string): void {\n if (typeof passphrase !== \"string\") {\n throw new Error(\"passphrase must be a string\");\n }\n if (passphrase.length === 0) {\n throw new Error(\"passphrase must not be empty\");\n }\n if (passphrase.length < MIN_PASSPHRASE_LENGTH) {\n throw new Error(`passphrase must be at least ${MIN_PASSPHRASE_LENGTH} characters`);\n }\n}\n\nfunction resolveParams(\n algorithm: KdfAlgorithm,\n override: ScryptParams | Argon2idParams | undefined,\n): ScryptParams | Argon2idParams {\n if (override !== undefined) return override;\n if (algorithm === \"scrypt\") return { ...DEFAULT_SCRYPT_PARAMS };\n return { ...DEFAULT_ARGON2ID_PARAMS };\n}\n","/**\n * Console-text renderers for the `remnic engram secure-store {init,unlock,\n * lock,status,migrate,disable}` CLI surface (issue #690 PR 2/4 + #779/#780).\n *\n * Pure: each `render*` function takes a typed report and returns a\n * string. CLI handlers do the `console.log`. Tests assert on the\n * returned text directly so behavior stays decoupled from stdout.\n */\n\nimport type {\n SecureStoreInitReport,\n SecureStoreLockReport,\n SecureStoreDisableReport,\n SecureStoreMigrateReport,\n SecureStoreStatusReport,\n SecureStoreUnlockReport,\n} from \"./cli-handlers.js\";\nimport type { SecureStoreHeader } from \"./header.js\";\n\nexport function renderInitReport(report: SecureStoreInitReport): string {\n const lines: string[] = [];\n lines.push(\"=== Remnic secure-store initialized ===\");\n lines.push(\"\");\n lines.push(`header: ${report.headerPath}`);\n lines.push(`createdAt: ${report.createdAt}`);\n lines.push(...renderKdfLines(report.kdf));\n lines.push(\"\");\n lines.push(\"Note: init does NOT auto-unlock the store. Run\");\n lines.push(\" remnic engram secure-store unlock\");\n lines.push(\"to register the master key with the running daemon.\");\n return lines.join(\"\\n\");\n}\n\nexport function renderUnlockReport(report: SecureStoreUnlockReport): string {\n if (report.ok) {\n return `OK — secure-store unlocked at ${report.unlockedAt} (algorithm=${report.algorithm}).`;\n }\n if (report.reason === \"not-initialized\") {\n return \"ERR — secure-store is not initialized. Run 'remnic engram secure-store init' first.\";\n }\n return \"ERR — wrong passphrase.\";\n}\n\nexport function renderLockReport(report: SecureStoreLockReport): string {\n if (report.cleared) {\n return \"OK — secure-store key cleared from in-memory keyring.\";\n }\n return \"OK — secure-store was already locked (no in-memory key to clear).\";\n}\n\nexport function renderMigrateReport(report: SecureStoreMigrateReport): string {\n if (!report.ok && report.reason === \"not-initialized\") {\n return \"ERR — secure-store is not initialized. Run 'remnic engram secure-store init' first.\";\n }\n if (!report.ok && report.reason === \"locked\") {\n return \"ERR — secure-store is locked. Run 'remnic engram secure-store unlock' before migrate.\";\n }\n\n const lines: string[] = [];\n lines.push(report.ok ? \"OK — secure-store migration complete.\" : \"ERR — secure-store migration completed with file errors.\");\n lines.push(`encrypted: ${report.encrypted}`);\n lines.push(`skipped: ${report.skipped}`);\n lines.push(`errors: ${report.errors.length}`);\n for (const entry of report.errors.slice(0, 10)) {\n lines.push(`- ${entry.filePath}: ${entry.error}`);\n }\n if (report.errors.length > 10) {\n lines.push(`- ... ${report.errors.length - 10} more error(s)`);\n }\n return lines.join(\"\\n\");\n}\n\nexport function renderDisableReport(report: SecureStoreDisableReport): string {\n if (!report.ok && report.reason === \"not-initialized\") {\n return \"ERR — secure-store is not initialized. Run 'remnic engram secure-store init' first.\";\n }\n if (!report.ok && report.reason === \"locked\") {\n return \"ERR — secure-store is locked. Run 'remnic engram secure-store unlock' before disable.\";\n }\n\n const lines: string[] = [];\n lines.push(report.ok ? \"OK — secure-store disable complete.\" : \"ERR — secure-store disable completed with file errors.\");\n lines.push(`decrypted: ${report.decrypted}`);\n lines.push(`skipped: ${report.skipped}`);\n lines.push(`errors: ${report.errors.length}`);\n for (const entry of report.errors.slice(0, 10)) {\n lines.push(`- ${entry.filePath}: ${entry.error}`);\n }\n if (report.errors.length > 10) {\n lines.push(`- ... ${report.errors.length - 10} more error(s)`);\n }\n lines.push(\"header: kept\");\n return lines.join(\"\\n\");\n}\n\nexport function renderStatusReport(report: SecureStoreStatusReport): string {\n const lines: string[] = [];\n lines.push(\"=== Remnic secure-store status ===\");\n lines.push(\"\");\n lines.push(`header: ${report.headerPath}`);\n lines.push(`initialized: ${report.initialized ? \"yes\" : \"no\"}`);\n if (!report.initialized) {\n lines.push(\"\");\n lines.push(\"Run 'remnic engram secure-store init' to initialize a new store.\");\n return lines.join(\"\\n\");\n }\n lines.push(`createdAt: ${report.createdAt ?? \"n/a\"}`);\n lines.push(`locked: ${report.locked ? \"yes\" : \"no\"}`);\n if (!report.locked) {\n lines.push(`lastUnlockAt: ${report.unlockedAt ?? \"n/a\"}`);\n }\n if (report.kdf) {\n lines.push(...renderKdfLines(report.kdf));\n }\n return lines.join(\"\\n\");\n}\n\nfunction renderKdfLines(kdf: SecureStoreHeader[\"metadata\"][\"kdf\"]): string[] {\n const lines: string[] = [];\n lines.push(`kdf.algorithm: ${kdf.algorithm}`);\n if (kdf.algorithm === \"scrypt\") {\n const { N, r, p, keyLength, maxmem } = kdf.params;\n lines.push(`kdf.params: N=${N} r=${r} p=${p} keyLength=${keyLength} maxmem=${maxmem}`);\n } else {\n const { memoryKiB, iterations, parallelism, keyLength } = kdf.params;\n lines.push(\n `kdf.params: memoryKiB=${memoryKiB} iterations=${iterations} parallelism=${parallelism} keyLength=${keyLength}`,\n );\n }\n return lines;\n}\n","/**\n * TTY passphrase reader (issue #690 PR 2/4).\n *\n * Reads a line from stdin without echoing it back to the terminal.\n * Disables echo by setting raw mode + manually buffering input until\n * Enter / EOT.\n *\n * Why not `readline.question`?\n * ----------------------------\n * `readline` echoes by default and has no clean \"no-echo\" toggle that\n * survives across Node versions. The raw-mode loop is the canonical\n * idiom for reading passwords on Node and matches what `npm` uses\n * internally.\n *\n * Security\n * --------\n * - Never log the passphrase (no `console.log`, no debug output).\n * - Never include it in a thrown error message.\n * - On Ctrl+C / Ctrl+D, abort with a clear error rather than\n * silently treating EOF as an empty submission.\n * - On non-TTY stdin (pipe, redirect), read a line via line-buffered\n * readline so automation (`echo \"passphrase\" | remnic ...`) works.\n * Operators are responsible for not piping plaintext passphrases\n * in shell history; we surface a stderr warning.\n */\n\nimport { createInterface } from \"node:readline\";\nimport type { Readable, Writable } from \"node:stream\";\nimport { StringDecoder } from \"node:string_decoder\";\n\nimport type { PassphraseReader } from \"./cli-handlers.js\";\n\nexport interface CreatePassphraseReaderOptions {\n input?: Readable;\n output?: Writable;\n /** Override stderr for warning surface; defaults to `process.stderr`. */\n errorStream?: Writable;\n}\n\n/**\n * Build a `PassphraseReader` bound to the given streams. Exported so\n * tests can construct one against in-memory streams without touching\n * the real TTY.\n */\nexport function createPassphraseReader(\n options: CreatePassphraseReaderOptions = {},\n): PassphraseReader {\n const input = options.input ?? process.stdin;\n const output = options.output ?? process.stdout;\n const errorStream = options.errorStream ?? process.stderr;\n // Codex/Cursor on PR #737: a fresh readline interface per call\n // breaks confirm-mode on piped non-TTY input — the first\n // `createInterface` consumes the entire prebuffered stream\n // (including the second line), so the second `createInterface`\n // sees an already-ended stream and resolves to \"\". Fix: maintain\n // ONE non-TTY line reader across both reads of a confirm-mode\n // session and pull lines on demand from a buffered queue.\n let nonTtyReader: NonTtyLineReader | null = null;\n let nonTtyWarned = false;\n return async function readPassphrase(\n prompt: string,\n readerOptions?: { confirm?: boolean },\n ): Promise<string> {\n const first = await readSinglePassphrase(prompt);\n if (readerOptions?.confirm) {\n const second = await readSinglePassphrase(\"Confirm passphrase: \");\n if (first !== second) {\n throw new Error(\"passphrases did not match\");\n }\n }\n return first;\n };\n\n async function readSinglePassphrase(prompt: string): Promise<string> {\n const inputAsAny = input as Readable & {\n isTTY?: boolean;\n setRawMode?: (raw: boolean) => Readable;\n };\n if (inputAsAny.isTTY && typeof inputAsAny.setRawMode === \"function\") {\n return readNoEcho(prompt, inputAsAny, output);\n }\n // Non-TTY: line-buffered fallback. Warn once per reader so\n // operators piping plaintext passphrases in shell pipelines are\n // aware their history may contain the secret.\n if (!nonTtyWarned) {\n errorStream.write(\n \"[remnic secure-store] warning: stdin is not a TTY; reading passphrase as a plain line. \" +\n \"Take care that the passphrase is not exposed in shell history.\\n\",\n );\n nonTtyWarned = true;\n }\n // Codex P1 on PR #737: write the prompt to stderr, not stdout.\n // When the surrounding command outputs JSON to stdout (e.g.\n // `remnic secure-store status --json`), injecting prompt text on\n // stdout corrupts the JSON output and breaks machine consumers.\n // The prompt is UI noise — it belongs on the error/diagnostics\n // stream regardless of whether we're in a TTY.\n errorStream.write(prompt);\n if (!nonTtyReader) nonTtyReader = createNonTtyLineReader(input);\n return nonTtyReader.next();\n }\n}\n\nfunction readNoEcho(\n prompt: string,\n input: Readable & { setRawMode?: (raw: boolean) => Readable },\n output: Writable,\n): Promise<string> {\n return new Promise((resolve, reject) => {\n output.write(prompt);\n let buffer = \"\";\n let settled = false;\n const wasRaw = (input as Readable & { isRaw?: boolean }).isRaw === true;\n // Codex P2 on PR #737: per-chunk `chunk.toString(\"utf8\")` corrupts\n // multibyte characters that straddle a chunk boundary (Node inserts\n // U+FFFD replacement characters for incomplete sequences). Use a\n // StringDecoder, which buffers partial sequences across chunks so\n // non-ASCII passphrases survive intact.\n const decoder = new StringDecoder(\"utf8\");\n if (input.setRawMode) input.setRawMode(true);\n input.resume();\n const cleanup = (): void => {\n input.pause();\n input.removeListener(\"data\", onData);\n // Flush any remaining bytes the decoder is holding so trailing\n // partial sequences are surfaced rather than silently swallowed.\n decoder.end();\n // Restore the prior raw-mode state so we don't strand the parent shell\n // in an unexpected configuration.\n if (input.setRawMode) input.setRawMode(wasRaw);\n output.write(\"\\n\");\n };\n const onData = (chunk: Buffer): void => {\n const str = decoder.write(chunk);\n for (const ch of str) {\n if (settled) return;\n const code = ch.charCodeAt(0);\n // Enter / newline: submit.\n if (ch === \"\\n\" || ch === \"\\r\") {\n settled = true;\n cleanup();\n resolve(buffer);\n return;\n }\n // Ctrl+C: abort.\n if (code === 0x03) {\n settled = true;\n cleanup();\n reject(new Error(\"passphrase entry aborted (Ctrl+C)\"));\n return;\n }\n // Ctrl+D / EOT: treat as abort if buffer is empty, else submit.\n if (code === 0x04) {\n settled = true;\n cleanup();\n if (buffer.length === 0) {\n reject(new Error(\"passphrase entry aborted (EOF)\"));\n } else {\n resolve(buffer);\n }\n return;\n }\n // Backspace / DEL.\n // Cursor on PR #737: `buffer.slice(0, -1)` deletes one UTF-16\n // code unit, which splits a surrogate pair when the last\n // character is a non-BMP code point (emoji, etc.). Fix: count\n // code points with `Array.from` and remove the last one. This\n // correctly handles both BMP (single code unit) and non-BMP\n // (surrogate pair) characters atomically.\n if (code === 0x08 || code === 0x7f) {\n if (buffer.length > 0) {\n const codePoints = Array.from(buffer);\n buffer = codePoints.slice(0, -1).join(\"\");\n }\n continue;\n }\n // Ignore other control bytes (escape sequences, etc.).\n if (code < 0x20) {\n continue;\n }\n buffer += ch;\n }\n };\n input.on(\"data\", onData);\n });\n}\n\n/**\n * One-shot line reader bound to a non-TTY input stream.\n *\n * Cursor medium on PR #737: a previous version constructed a fresh\n * `readline.createInterface` per `next()` call. On piped non-TTY\n * input, the first interface consumed the entire prebuffered stream\n * (including any subsequent lines) into its internal buffer. The\n * second interface saw an already-`end()`'d input and resolved to \"\".\n * Fix: construct ONE readline interface, queue every emitted `line`,\n * and let `next()` either return a queued line or wait for the next\n * one. Pending waiters at `close` time are resolved with \"\" (so an\n * abandoned-stream caller still sees a clean empty response).\n */\ninterface NonTtyLineReader {\n next(): Promise<string>;\n}\n\nfunction createNonTtyLineReader(input: Readable): NonTtyLineReader {\n const rl = createInterface({ input, terminal: false });\n const lineQueue: string[] = [];\n const waiterQueue: Array<(value: string) => void> = [];\n const errorQueue: Array<(err: Error) => void> = [];\n let closed = false;\n let error: Error | null = null;\n\n rl.on(\"line\", (line: string) => {\n const waiter = waiterQueue.shift();\n if (waiter) {\n waiter(line);\n } else {\n lineQueue.push(line);\n }\n });\n rl.on(\"close\", () => {\n closed = true;\n while (waiterQueue.length > 0) {\n const w = waiterQueue.shift()!;\n // Drop the matching error slot since we're settling cleanly.\n errorQueue.shift();\n w(\"\");\n }\n });\n rl.on(\"error\", (err: Error) => {\n error = err;\n while (errorQueue.length > 0) {\n const r = errorQueue.shift()!;\n // Drop the matching value slot.\n waiterQueue.shift();\n r(err);\n }\n });\n\n return {\n next(): Promise<string> {\n if (error) return Promise.reject(error);\n const queued = lineQueue.shift();\n if (queued !== undefined) return Promise.resolve(queued);\n if (closed) return Promise.resolve(\"\");\n return new Promise<string>((resolve, reject) => {\n waiterQueue.push(resolve);\n errorQueue.push(reject);\n });\n },\n };\n}\n"],"mappings":"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","names":["status"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/recall-state.ts"],"sourcesContent":["import { appendFile, mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { createHash, randomUUID } from \"node:crypto\";\nimport { log } from \"./logger.js\";\nimport type {\n IdentityInjectionMode,\n RecallPlanMode,\n RecallTierExplain,\n} from \"./types.js\";\n\nexport interface LastRecallBudgetSummary {\n requestedTopK?: number;\n appliedTopK: number;\n recallBudgetChars: number;\n maxMemoryTokens: number;\n qmdFetchLimit?: number;\n qmdHybridFetchLimit?: number;\n finalContextChars?: number;\n truncated?: boolean;\n includedSections?: string[];\n omittedSections?: string[];\n}\n\nexport interface LastRecallSnapshot {\n sessionKey: string;\n recordedAt: string;\n queryHash: string;\n queryLen: number;\n memoryIds: string[];\n namespace?: string;\n traceId?: string;\n plannerMode?: RecallPlanMode;\n requestedMode?: RecallPlanMode;\n source?: string;\n fallbackUsed?: boolean;\n sourcesUsed?: string[];\n budgetsApplied?: LastRecallBudgetSummary;\n latencyMs?: number;\n resultPaths?: string[];\n policyVersion?: string;\n identityInjectionMode?: IdentityInjectionMode | \"none\";\n identityInjectedChars?: number;\n identityInjectionTruncated?: boolean;\n /**\n * Collision-safe write nonce. Random UUID set on every `record()`\n * call so the observation-mode direct-answer hook can detect stale\n * snapshots and avoid annotating a snapshot that a subsequent recall\n * already replaced (issue #518).\n */\n writeNonce?: string;\n /**\n * Optional tier-level explanation of how recall was served\n * (issue #518). Populated by orchestrator call sites that can\n * identify a concrete tier; surfaces expose the block via\n * `engram query --explain`, the `?explain=1` HTTP flag, and the\n * `remnic_recall_explain` MCP tool. Orthogonal to the existing\n * graph-path `recallExplain` operation.\n */\n tierExplain?: RecallTierExplain;\n}\n\nexport interface GraphRecallExpandedEntry {\n path: string;\n score: number;\n namespace: string;\n seed: string;\n hopDepth: number;\n decayedWeight: number;\n graphType: \"entity\" | \"time\" | \"causal\";\n /**\n * Issue #681 PR 3/3 — confidence of the edge that produced this entry's\n * recorded provenance (strongest edge along the chosen entry path).\n * Range `[0, 1]`. Optional so persisted snapshots from older builds\n * round-trip through `clampGraphRecallExpandedEntries` without dropping.\n */\n edgeConfidence?: number;\n}\n\nexport function clampGraphRecallExpandedEntries(\n entries: unknown,\n maxEntries: number = 64,\n): GraphRecallExpandedEntry[] {\n const limit = Math.max(1, Math.floor(maxEntries));\n if (!Array.isArray(entries)) return [];\n return entries\n .filter((item): item is Record<string, unknown> => !!item && typeof item === \"object\")\n .map((item) => {\n const graphType: \"entity\" | \"time\" | \"causal\" =\n item.graphType === \"entity\" || item.graphType === \"time\" || item.graphType === \"causal\"\n ? item.graphType\n : \"entity\";\n const out: GraphRecallExpandedEntry = {\n path: typeof item.path === \"string\" ? item.path : \"\",\n score: typeof item.score === \"number\" && Number.isFinite(item.score) ? item.score : 0,\n namespace: typeof item.namespace === \"string\" ? item.namespace : \"\",\n seed: typeof item.seed === \"string\" ? item.seed : \"\",\n hopDepth:\n typeof item.hopDepth === \"number\" && Number.isFinite(item.hopDepth)\n ? Math.max(0, Math.floor(item.hopDepth))\n : 0,\n decayedWeight:\n typeof item.decayedWeight === \"number\" && Number.isFinite(item.decayedWeight)\n ? Math.max(0, item.decayedWeight)\n : 0,\n graphType,\n };\n // Issue #681 PR 3/3: clamp `edgeConfidence` into [0, 1] when present.\n // Older snapshots without the field round-trip cleanly via the\n // optional shape; legacy callers always rendered as 1.0.\n if (\n typeof item.edgeConfidence === \"number\" &&\n Number.isFinite(item.edgeConfidence)\n ) {\n out.edgeConfidence = Math.min(1, Math.max(0, item.edgeConfidence));\n }\n return out;\n })\n .filter((item) => item.path.length > 0 && item.namespace.length > 0)\n .slice(0, limit);\n}\n\ntype LastRecallState = Record<string, LastRecallSnapshot>;\n\n/**\n * Deep-copy a RecallTierExplain block. Used by both the write path\n * (so caller mutation after `record()` cannot tear the persisted\n * snapshot) and the read path (so caller mutation after `get()` /\n * `getMostRecent()` cannot tear the in-memory store).\n *\n * Uses structuredClone so future additions to RecallTierExplain do\n * not silently share references through hand-enumerated fields —\n * matching the pattern used elsewhere in the codebase (e.g.,\n * qmd-recall-cache.ts). The payload is pure JSON-shaped data, so\n * structuredClone is both safe and complete here.\n */\nfunction cloneTierExplain(\n tierExplain: RecallTierExplain | undefined,\n): RecallTierExplain | undefined {\n if (!tierExplain) return undefined;\n return structuredClone(tierExplain);\n}\n\n/**\n * Deep-copy a LastRecallSnapshot so callers that receive it cannot\n * mutate the store's internal state through mutable array/object\n * fields. Same structuredClone rationale as cloneTierExplain above.\n */\nfunction cloneLastRecallSnapshot(\n snapshot: LastRecallSnapshot | null,\n): LastRecallSnapshot | null {\n if (!snapshot) return null;\n return structuredClone(snapshot);\n}\n\nexport interface TierMigrationCycleSummary {\n trigger: \"extraction\" | \"maintenance\" | \"manual\";\n scanned: number;\n migrated: number;\n promoted: number;\n demoted: number;\n limit: number;\n dryRun: boolean;\n skipped?: string;\n errorCount?: number;\n}\n\nexport interface TierMigrationStatusSnapshot {\n updatedAt: string;\n lastCycle: TierMigrationCycleSummary | null;\n totals: {\n cycles: number;\n scanned: number;\n migrated: number;\n promoted: number;\n demoted: number;\n errors: number;\n };\n}\n\nconst DEFAULT_TIER_MIGRATION_STATUS: TierMigrationStatusSnapshot = {\n updatedAt: new Date(0).toISOString(),\n lastCycle: null,\n totals: {\n cycles: 0,\n scanned: 0,\n migrated: 0,\n promoted: 0,\n demoted: 0,\n errors: 0,\n },\n};\n\nexport class LastRecallStore {\n private readonly statePath: string;\n private readonly impressionsPath: string;\n private state: LastRecallState = {};\n\n constructor(memoryDir: string) {\n this.statePath = path.join(memoryDir, \"state\", \"last_recall.json\");\n this.impressionsPath = path.join(memoryDir, \"state\", \"recall_impressions.jsonl\");\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 LastRecallState;\n if (parsed && typeof parsed === \"object\") this.state = parsed;\n } catch {\n this.state = {};\n }\n }\n\n get(sessionKey: string): LastRecallSnapshot | null {\n // Defensive copy: callers must not be able to mutate internal state\n // by reaching into array/object fields on the returned snapshot.\n return cloneLastRecallSnapshot(this.state[sessionKey] ?? null);\n }\n\n getMostRecent(): LastRecallSnapshot | null {\n const snapshots = Object.values(this.state);\n if (snapshots.length === 0) return null;\n // Secondary key on sessionKey keeps the sort stable when two\n // snapshots share a recordedAt timestamp (CLAUDE.md rule 19).\n snapshots.sort((a, b) => {\n const byTime = b.recordedAt.localeCompare(a.recordedAt);\n if (byTime !== 0) return byTime;\n return a.sessionKey.localeCompare(b.sessionKey);\n });\n return cloneLastRecallSnapshot(snapshots[0] ?? null);\n }\n\n /**\n * Persist last-recall snapshot and append an impression log entry.\n * Does not store raw query text; uses a stable hash for correlation.\n */\n async record(opts: {\n sessionKey: string;\n query: string;\n memoryIds: string[];\n namespace?: string;\n traceId?: string;\n plannerMode?: RecallPlanMode;\n requestedMode?: RecallPlanMode;\n source?: string;\n fallbackUsed?: boolean;\n sourcesUsed?: string[];\n budgetsApplied?: LastRecallBudgetSummary;\n latencyMs?: number;\n resultPaths?: string[];\n policyVersion?: string;\n appendImpression?: boolean;\n identityInjection?: {\n mode: IdentityInjectionMode | \"none\";\n injectedChars: number;\n truncated: boolean;\n };\n /**\n * Per-tier explain annotation (issue #518). When supplied, the\n * snapshot carries it so downstream surfaces (CLI / HTTP / MCP)\n * can render which retrieval tier served the query.\n */\n tierExplain?: RecallTierExplain;\n }): Promise<void> {\n const now = new Date().toISOString();\n const queryHash = createHash(\"sha256\").update(opts.query).digest(\"hex\");\n\n // Build the snapshot from opts, then deep-copy it via\n // cloneLastRecallSnapshot so caller arrays/objects passed in\n // `opts` cannot retain a live reference to the persisted state\n // and tear it after record() returns.\n const liveSnapshot: LastRecallSnapshot = {\n sessionKey: opts.sessionKey,\n recordedAt: now,\n queryHash,\n writeNonce: randomUUID(),\n queryLen: opts.query.length,\n memoryIds: opts.memoryIds,\n namespace: opts.namespace,\n traceId: opts.traceId,\n plannerMode: opts.plannerMode,\n requestedMode: opts.requestedMode,\n source: opts.source,\n fallbackUsed: opts.fallbackUsed,\n sourcesUsed: opts.sourcesUsed,\n budgetsApplied: opts.budgetsApplied,\n latencyMs: opts.latencyMs,\n resultPaths: opts.resultPaths,\n policyVersion: opts.policyVersion,\n identityInjectionMode: opts.identityInjection?.mode,\n identityInjectedChars: opts.identityInjection?.injectedChars,\n identityInjectionTruncated: opts.identityInjection?.truncated,\n tierExplain: opts.tierExplain,\n };\n // `cloneLastRecallSnapshot` handles `null` but that never applies\n // at this call site — the non-null assertion keeps the type\n // checker honest.\n const snapshot = cloneLastRecallSnapshot(liveSnapshot)!;\n\n this.state[opts.sessionKey] = snapshot;\n\n // Keep the state bounded; the impression log is append-only.\n const keys = Object.keys(this.state);\n if (keys.length > 50) {\n const ordered = keys\n .map((k) => ({ k, at: this.state[k]?.recordedAt ?? \"\" }))\n .sort((a, b) => b.at.localeCompare(a.at));\n for (const doomed of ordered.slice(50)) {\n delete this.state[doomed.k];\n }\n }\n\n try {\n await mkdir(path.dirname(this.statePath), { recursive: true });\n await writeFile(this.statePath, JSON.stringify(this.state, null, 2), \"utf-8\");\n } catch (err) {\n log.debug(`last recall store write failed: ${err}`);\n }\n\n if (opts.appendImpression !== false) {\n try {\n await mkdir(path.dirname(this.impressionsPath), { recursive: true });\n await appendFile(this.impressionsPath, JSON.stringify(snapshot) + \"\\n\", \"utf-8\");\n } catch (err) {\n log.debug(`recall impressions append failed: ${err}`);\n }\n }\n }\n\n /**\n * Attach a RecallTierExplain block to the existing snapshot for a\n * session without rewriting the entire snapshot. Used by the\n * post-recall direct-answer annotation path (issue #518 slice 3c):\n * recallInternal records the snapshot first, then the orchestrator\n * fires the direct-answer tier in observation mode and annotates\n * the stored snapshot with whichever tier served the query.\n *\n * No-op when no snapshot exists for the given session; callers do\n * not need to guard on existence.\n */\n async annotateTierExplain(\n sessionKey: string,\n tierExplain: RecallTierExplain,\n expected?: { writeNonce?: string; traceId?: string; recordedAt?: string },\n ): Promise<void> {\n const current = this.state[sessionKey];\n if (!current) return;\n if (expected) {\n if (\n typeof expected.writeNonce === \"string\" &&\n expected.writeNonce.length > 0\n ) {\n if (current.writeNonce !== expected.writeNonce) return;\n } else {\n const hasExpectedTraceId =\n typeof expected.traceId === \"string\" && expected.traceId.length > 0;\n const traceIdMatches =\n hasExpectedTraceId && current.traceId === expected.traceId;\n const recordedAtMatches =\n expected.recordedAt !== undefined &&\n current.recordedAt === expected.recordedAt;\n if (hasExpectedTraceId) {\n if (!traceIdMatches) return;\n } else if (expected.recordedAt !== undefined && !recordedAtMatches) {\n return;\n }\n }\n }\n this.state[sessionKey] = {\n ...current,\n tierExplain: cloneTierExplain(tierExplain),\n };\n try {\n await mkdir(path.dirname(this.statePath), { recursive: true });\n await writeFile(this.statePath, JSON.stringify(this.state, null, 2), \"utf-8\");\n } catch (err) {\n log.debug(`last recall tier-explain annotate failed: ${err}`);\n }\n }\n}\n\nexport class TierMigrationStatusStore {\n private readonly statePath: string;\n private state: TierMigrationStatusSnapshot = structuredClone(DEFAULT_TIER_MIGRATION_STATUS);\n\n constructor(memoryDir: string) {\n this.statePath = path.join(memoryDir, \"state\", \"tier-migration-status.json\");\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 Partial<TierMigrationStatusSnapshot> | null;\n if (!parsed || typeof parsed !== \"object\") {\n this.state = structuredClone(DEFAULT_TIER_MIGRATION_STATUS);\n return;\n }\n const totals = parsed.totals && typeof parsed.totals === \"object\"\n ? parsed.totals\n : DEFAULT_TIER_MIGRATION_STATUS.totals;\n this.state = {\n updatedAt:\n typeof parsed.updatedAt === \"string\" && parsed.updatedAt.length > 0\n ? parsed.updatedAt\n : DEFAULT_TIER_MIGRATION_STATUS.updatedAt,\n lastCycle:\n parsed.lastCycle && typeof parsed.lastCycle === \"object\"\n ? (parsed.lastCycle as TierMigrationCycleSummary)\n : null,\n totals: {\n cycles: typeof totals.cycles === \"number\" && Number.isFinite(totals.cycles) ? totals.cycles : 0,\n scanned: typeof totals.scanned === \"number\" && Number.isFinite(totals.scanned) ? totals.scanned : 0,\n migrated: typeof totals.migrated === \"number\" && Number.isFinite(totals.migrated) ? totals.migrated : 0,\n promoted: typeof totals.promoted === \"number\" && Number.isFinite(totals.promoted) ? totals.promoted : 0,\n demoted: typeof totals.demoted === \"number\" && Number.isFinite(totals.demoted) ? totals.demoted : 0,\n errors: typeof totals.errors === \"number\" && Number.isFinite(totals.errors) ? totals.errors : 0,\n },\n };\n } catch {\n this.state = structuredClone(DEFAULT_TIER_MIGRATION_STATUS);\n }\n }\n\n get(): TierMigrationStatusSnapshot {\n return {\n updatedAt: this.state.updatedAt,\n lastCycle: this.state.lastCycle ? { ...this.state.lastCycle } : null,\n totals: { ...this.state.totals },\n };\n }\n\n async recordCycle(summary: TierMigrationCycleSummary): Promise<void> {\n const now = new Date().toISOString();\n const migratedDelta = summary.dryRun ? 0 : Math.max(0, summary.migrated);\n const promotedDelta = summary.dryRun ? 0 : Math.max(0, summary.promoted);\n const demotedDelta = summary.dryRun ? 0 : Math.max(0, summary.demoted);\n const next: TierMigrationStatusSnapshot = {\n updatedAt: now,\n lastCycle: { ...summary },\n totals: {\n cycles: this.state.totals.cycles + 1,\n scanned: this.state.totals.scanned + Math.max(0, summary.scanned),\n migrated: this.state.totals.migrated + migratedDelta,\n promoted: this.state.totals.promoted + promotedDelta,\n demoted: this.state.totals.demoted + demotedDelta,\n errors: this.state.totals.errors + Math.max(0, summary.errorCount ?? 0),\n },\n };\n this.state = next;\n try {\n await mkdir(path.dirname(this.statePath), { recursive: true });\n await writeFile(this.statePath, JSON.stringify(next, null, 2), \"utf-8\");\n } catch (err) {\n log.debug(`tier migration status write failed: ${err}`);\n }\n }\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/schemas.ts"],"sourcesContent":["import { z } from \"zod\";\n\nexport const MemoryActionTypeSchema = z.enum([\n \"store_episode\",\n \"store_note\",\n \"update_note\",\n \"create_artifact\",\n \"summarize_node\",\n \"discard\",\n \"link_graph\",\n]);\n\nexport const MemoryActionEligibilityContextSchema = z\n .object({\n confidence: z.number().min(0).max(1),\n lifecycleState: z.enum([\"active\", \"validated\", \"candidate\", \"stale\", \"archived\"]),\n importance: z.number().min(0).max(1),\n source: z.enum([\"extraction\", \"consolidation\", \"replay\", \"manual\", \"unknown\"]),\n })\n .strict();\n\nexport function parseMemoryActionType(value: unknown): z.infer<typeof MemoryActionTypeSchema> {\n const parsed = MemoryActionTypeSchema.safeParse(value);\n return parsed.success ? parsed.data : \"discard\";\n}\n\nexport function parseMemoryActionEligibilityContext(\n value: unknown,\n): z.infer<typeof MemoryActionEligibilityContextSchema> {\n const parsed = MemoryActionEligibilityContextSchema.safeParse(value);\n if (parsed.success) return parsed.data;\n return {\n confidence: 0,\n lifecycleState: \"candidate\",\n importance: 0,\n source: \"unknown\",\n };\n}\n\nexport const ProcedureStepExtractSchema = z.object({\n order: z.number(),\n intent: z.string(),\n toolCall: z\n .object({\n kind: z.string(),\n signature: z.string(),\n })\n .optional()\n .nullable(),\n expectedOutcome: z.string().optional().nullable(),\n optional: z.boolean().optional().nullable(),\n});\n\nexport const ExtractedFactSchema = z.object({\n category: z.enum([\n \"fact\",\n \"preference\",\n \"correction\",\n \"entity\",\n \"decision\",\n \"relationship\",\n \"principle\",\n \"commitment\",\n \"moment\",\n \"skill\",\n \"rule\",\n \"procedure\",\n \"reasoning_trace\",\n ]),\n content: z\n .string()\n .describe(\"The memory content — a clear, standalone statement\"),\n confidence: z\n .number()\n .min(0)\n .max(1)\n .describe(\"How confident are you this is correct (0-1)\"),\n tags: z.array(z.string()).describe(\"Relevant tags for categorization\"),\n entityRef: z\n .string()\n .optional()\n .nullable()\n .describe(\"If about an entity, its normalized name (e.g. person-jane-doe)\"),\n promptedByQuestion: z\n .string()\n .optional()\n .nullable()\n .describe(\"Optional proactive follow-up question that surfaced this fact.\"),\n scope: z\n .enum([\"project\", \"global\"])\n .optional()\n .nullable()\n .describe(\n 'Scope classification: \"global\" for cross-project knowledge (framework bugs, library behavior, API patterns, user preferences, tool configs, general coding patterns); \"project\" for project-specific knowledge (file paths, env configs, deployment details, project workarounds). Defaults to \"project\" when a coding context is active.',\n ),\n structuredAttributes: z\n .record(z.string(), z.string())\n .optional()\n .nullable()\n .describe(\"Structured key-value attributes when the fact contains measurable or categorical data (e.g., {\\\"price\\\": \\\"29.99\\\", \\\"color\\\": \\\"blue\\\", \\\"date\\\": \\\"2024-03-15\\\"}).\"),\n procedureSteps: z\n .array(ProcedureStepExtractSchema)\n .optional()\n .nullable()\n .describe(\n 'For category \"procedure\" only: ordered steps (intent per step). At least two steps; include explicit trigger phrasing in content (e.g. \"When you deploy…\").',\n ),\n reasoningTrace: z\n .object({\n steps: z\n .array(\n z.object({\n order: z.number(),\n description: z.string(),\n }),\n )\n // Prompts and normalizer require >=2 ordered steps; enforce it at\n // the schema layer so gateway-path parsing rejects malformed traces\n // rather than persisting them (local/direct-client normalization\n // already enforces this, keeping the two paths symmetric).\n .min(2)\n .describe(\"Ordered reasoning steps the user walked through (require >=2).\"),\n // Accept snake_case aliases so a loose gateway model using\n // `final_answer` / `observed_outcome` does not fail schema parsing\n // and drop the entire extraction result. Local/direct-client\n // normalization already tolerates these keys; the gateway path must\n // too. Zod's `union` keeps the parse successful either way.\n finalAnswer: z\n .string()\n .optional()\n .nullable()\n .describe(\"The conclusion, decision, or answer the chain arrived at.\"),\n final_answer: z\n .string()\n .optional()\n .nullable()\n .describe(\"Alias for finalAnswer (snake_case). Gateway-tolerance shim.\"),\n observedOutcome: z\n .string()\n .optional()\n .nullable()\n .describe(\"Optional note about how the answer actually played out.\"),\n observed_outcome: z\n .string()\n .optional()\n .nullable()\n .describe(\"Alias for observedOutcome (snake_case). Gateway-tolerance shim.\"),\n })\n // Either finalAnswer OR final_answer must be present — enforce here so\n // the rest of the pipeline can assume a usable string downstream.\n .refine(\n (v) =>\n (typeof v.finalAnswer === \"string\" && v.finalAnswer.trim().length > 0) ||\n (typeof v.final_answer === \"string\" && v.final_answer.trim().length > 0),\n { message: \"reasoningTrace requires finalAnswer (or final_answer)\" },\n )\n .optional()\n .nullable()\n .describe(\n 'For category \"reasoning_trace\" only: a stored solution chain with ordered steps, a final answer, and an optional observed outcome. Require at least two steps.',\n ),\n});\n\nexport const EntityMentionSchema = z.object({\n name: z\n .string()\n .describe(\"Normalized entity name (e.g. jane-doe, acme-corp, my-project)\"),\n type: z.enum([\"person\", \"project\", \"tool\", \"company\", \"place\", \"other\"]),\n facts: z\n .array(z.string())\n .describe(\"New facts learned about this entity in this conversation\"),\n promptedByQuestion: z\n .string()\n .optional()\n .nullable()\n .describe(\"Optional proactive follow-up question that surfaced this entity.\"),\n structuredSections: z\n .array(z.object({\n key: z.string(),\n title: z.string(),\n facts: z.array(z.string()),\n }))\n .optional()\n .nullable()\n .describe(\"Optional named sections for entity-specific facts. Use when facts clearly belong under a durable heading such as Beliefs or Building / Working On.\"),\n});\n\nexport const ExtractedQuestionSchema = z.object({\n question: z.string().describe(\"A genuine question the AI is curious about based on this conversation\"),\n context: z.string().describe(\"Why this question matters or what prompted it\"),\n priority: z.number().min(0).max(1).describe(\"How important/urgent this question is (0-1)\"),\n});\n\nexport const ProactiveQuestionsResultSchema = z.object({\n questions: z\n .array(ExtractedQuestionSchema)\n .describe(\"Additional follow-up questions discovered in a proactive second-pass extraction.\"),\n});\n\nexport const ExtractedRelationshipSchema = z.object({\n source: z.string().describe(\"Source entity name (normalized, e.g. person-jane-doe)\"),\n target: z.string().describe(\"Target entity name (normalized, e.g. company-acme-corp)\"),\n label: z.string().describe(\"Relationship label (e.g. 'works at', 'created', 'manages')\"),\n promptedByQuestion: z\n .string()\n .optional()\n .nullable()\n .describe(\"Optional proactive follow-up question that surfaced this relationship.\"),\n});\n\nexport const ProactiveExtractionResultSchema = z.object({\n facts: z\n .array(ExtractedFactSchema)\n .describe(\n \"Additional high-confidence memories recovered only after answering proactive follow-up questions from the same buffered conversation.\",\n ),\n profileUpdates: z\n .array(z.string())\n .describe(\n \"Additional profile updates directly supported by the buffered conversation. Omit anything speculative.\",\n ),\n entities: z\n .array(EntityMentionSchema)\n .describe(\n \"Additional entities or entity facts surfaced by the proactive follow-up pass.\",\n ),\n relationships: z\n .array(ExtractedRelationshipSchema)\n .optional()\n .nullable()\n .describe(\n \"Additional relationships surfaced by the proactive follow-up pass.\",\n ),\n});\n\nexport const ExtractionResultSchema = z.object({\n facts: z\n .array(ExtractedFactSchema)\n .describe(\n \"Extracted memories from the conversation. Include facts, preferences, corrections, and decisions. Only extract genuinely new, durable information — skip transient task state.\",\n ),\n profileUpdates: z\n .array(z.string())\n .describe(\n \"Updates to the user's behavioral profile. Each string is a standalone statement about the user's preferences, habits, or personality. Only include genuinely new insights.\",\n ),\n entities: z\n .array(EntityMentionSchema)\n .describe(\n \"Entities mentioned in the conversation with new facts about them.\",\n ),\n questions: z\n .array(ExtractedQuestionSchema)\n .describe(\n \"1-3 genuine questions you're curious about from this conversation. These should be things you'd actually want to know the answer to in future sessions.\",\n ),\n identityReflection: z\n .string()\n .optional()\n .nullable()\n .describe(\n \"A brief reflection on what you learned about yourself as an agent in this interaction — patterns in your behavior, growth, things you did well or could improve.\",\n ),\n relationships: z\n .array(ExtractedRelationshipSchema)\n .optional()\n .nullable()\n .describe(\n \"Relationships between entities discovered in this conversation. Max 5 per extraction. Format: {source, target, label}.\",\n ),\n});\n\nexport const ConsolidationItemSchema = z.object({\n existingId: z\n .string()\n .describe(\"The ID of the existing memory being evaluated\"),\n action: z.enum([\"ADD\", \"MERGE\", \"UPDATE\", \"INVALIDATE\", \"SKIP\"]),\n mergeWith: z\n .string()\n .optional()\n .nullable()\n .describe(\"If MERGE, the ID of the memory to merge with\"),\n updatedContent: z\n .string()\n .optional()\n .nullable()\n .describe(\"If UPDATE or MERGE, the new content\"),\n reason: z.string().describe(\"Brief reason for this decision\"),\n});\n\nexport const ConsolidationResultSchema = z.object({\n items: z\n .array(ConsolidationItemSchema)\n .describe(\n \"Decisions for each existing memory: ADD (keep as-is), MERGE (combine with another), UPDATE (revise content), INVALIDATE (mark as outdated/wrong), SKIP (no action needed)\",\n ),\n profileUpdates: z\n .array(z.string())\n .describe(\"New profile statements to add or update\"),\n entityUpdates: z\n .array(EntityMentionSchema)\n .describe(\"Entity updates from consolidation analysis\"),\n});\n\nexport function buildProfileConsolidationResultSchema(targetLines: number) {\n return z.object({\n consolidatedProfile: z\n .string()\n .describe(\n `The full consolidated profile as markdown. Preserve all ## section headers. Merge duplicate or near-duplicate bullets into single clear statements. Remove stale or superseded information. Keep the most important and durable observations. Target roughly ${targetLines} lines.`,\n ),\n removedCount: z\n .number()\n .describe(\"Number of bullets removed or merged during consolidation\"),\n summary: z\n .string()\n .describe(\"Brief summary of what was consolidated\"),\n });\n}\n\nexport const ProfileConsolidationResultSchema = buildProfileConsolidationResultSchema(50);\n\nexport const IdentityConsolidationResultSchema = z.object({\n learnedPatterns: z\n .array(z.string())\n .describe(\n \"Consolidated behavioral patterns and lessons learned, each a concise standalone statement\",\n ),\n summary: z\n .string()\n .describe(\n \"A brief paragraph summarizing the agent's core identity insights\",\n ),\n});\n\nexport type IdentityConsolidationResultParsed = z.infer<\n typeof IdentityConsolidationResultSchema\n>;\n\n// Contradiction Verification (Phase 2B)\nexport const ContradictionVerificationSchema = z.object({\n isContradiction: z\n .boolean()\n .describe(\"Whether the two memories truly contradict each other\"),\n confidence: z\n .number()\n .min(0)\n .max(1)\n .describe(\"How confident are you in this assessment (0-1)\"),\n reasoning: z\n .string()\n .describe(\"Explanation of why these are or are not contradictory\"),\n whichIsNewer: z\n .enum([\"first\", \"second\", \"unclear\"])\n .describe(\"Which memory represents the more recent/current state\"),\n});\n\nexport type ContradictionVerificationResult = z.infer<\n typeof ContradictionVerificationSchema\n>;\n\n// Memory Linking (Phase 3A)\nexport const MemoryLinkSchema = z.object({\n targetId: z\n .string()\n .describe(\"The ID of the memory this links to\"),\n linkType: z\n .enum([\"follows\", \"references\", \"contradicts\", \"supports\", \"related\"])\n .describe(\"The type of relationship\"),\n strength: z\n .number()\n .min(0)\n .max(1)\n .describe(\"How strong is this relationship (0-1)\"),\n reason: z\n .string()\n .optional()\n .nullable()\n .describe(\"Why this link exists\"),\n});\n\nexport const SuggestedLinksSchema = z.object({\n links: z\n .array(MemoryLinkSchema)\n .describe(\"Suggested links between memories based on semantic analysis\"),\n});\n\nexport type MemoryLink = z.infer<typeof MemoryLinkSchema>;\nexport type SuggestedLinks = z.infer<typeof SuggestedLinksSchema>;\n\n// Memory Summarization (Phase 4A)\nexport const MemorySummarySchema = z.object({\n summaryText: z\n .string()\n .describe(\"A concise summary of the batch of memories\"),\n keyFacts: z\n .array(z.string())\n .describe(\"The most important facts extracted from these memories\"),\n keyEntities: z\n .array(z.string())\n .describe(\"Key entities mentioned across these memories\"),\n});\n\nexport type MemorySummaryResult = z.infer<typeof MemorySummarySchema>;\n\nexport const DaySummaryResultSchema = z.object({\n summary: z.string().min(1).describe(\"A concise end-of-day summary paragraph.\"),\n bullets: z.array(z.string()).default([]).describe(\"The most important moments from the day.\"),\n next_actions: z.array(z.string()).default([]).describe(\"Concrete next actions for tomorrow.\"),\n risks_or_open_loops: z.array(z.string()).default([]).describe(\"Open loops, blockers, or fragile assumptions still needing attention.\"),\n});\n\n// v8.15 behavior-loop auto-tuning state contracts\nexport const BehaviorLoopAdjustmentSchema = z.object({\n parameter: z.string().min(1),\n previousValue: z.number(),\n nextValue: z.number(),\n delta: z.number(),\n evidenceCount: z.number().int().min(0),\n confidence: z.number().min(0).max(1),\n reason: z.string(),\n appliedAt: z.string(),\n});\n\nexport const BehaviorLoopPolicyStateSchema = z.object({\n version: z.number().int().min(0),\n windowDays: z.number().int().min(0),\n minSignalCount: z.number().int().min(0),\n maxDeltaPerCycle: z.number().min(0).max(1),\n protectedParams: z.array(z.string()),\n adjustments: z.array(BehaviorLoopAdjustmentSchema),\n updatedAt: z.string(),\n});\n\nexport type BehaviorLoopAdjustmentParsed = z.infer<typeof BehaviorLoopAdjustmentSchema>;\nexport type BehaviorLoopPolicyStateParsed = z.infer<typeof BehaviorLoopPolicyStateSchema>;\n\nexport type MemoryActionTypeParsed = z.infer<typeof MemoryActionTypeSchema>;\nexport type MemoryActionEligibilityContextParsed = z.infer<typeof MemoryActionEligibilityContextSchema>;\nexport type ExtractedFactParsed = z.infer<typeof ExtractedFactSchema>;\nexport type EntityMentionParsed = z.infer<typeof EntityMentionSchema>;\nexport type ExtractedQuestionParsed = z.infer<typeof ExtractedQuestionSchema>;\nexport type ProactiveQuestionsResultParsed = z.infer<typeof ProactiveQuestionsResultSchema>;\nexport type ExtractionResultParsed = z.infer<typeof ExtractionResultSchema>;\nexport type ConsolidationItemParsed = z.infer<typeof ConsolidationItemSchema>;\nexport type ConsolidationResultParsed = z.infer<\n typeof ConsolidationResultSchema\n>;\n\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/runtime/env.ts"],"sourcesContent":["import os from \"node:os\";\n\ntype EnvMap = Record<string, string | undefined>;\nconst REMNIC_ENGRAM_PREFIX_PAIRS: Array<[string, string]> = [\n [\"REMNIC_\", \"ENGRAM_\"],\n [\"ENGRAM_\", \"REMNIC_\"],\n];\n\nfunction getEnvMap(): EnvMap | undefined {\n const runtimeProcess = globalThis.process as { env?: EnvMap } | undefined;\n return runtimeProcess?.[\"env\"];\n}\n\nfunction legacyEnvCandidates(name: string): string[] {\n const candidates = [name];\n for (const [primary, legacy] of REMNIC_ENGRAM_PREFIX_PAIRS) {\n if (name.startsWith(primary)) {\n candidates.push(`${legacy}${name.slice(primary.length)}`);\n }\n }\n return candidates;\n}\n\nexport function readEnvVar(name: string): string | undefined {\n const env = getEnvMap();\n for (const candidate of legacyEnvCandidates(name)) {\n const value = env?.[candidate];\n if (typeof value === \"string\") return value;\n }\n return undefined;\n}\n\nexport function resolveHomeDir(): string {\n return readEnvVar(\"HOME\") || os.homedir();\n}\n\nfunction cloneEnv(): NodeJS.ProcessEnv {\n return { ...(getEnvMap() ?? {}) };\n}\n\nexport function mergeEnv(overrides: Record<string, string | undefined>): NodeJS.ProcessEnv {\n const merged = cloneEnv();\n for (const [key, value] of Object.entries(overrides)) {\n if (typeof value === \"string\") merged[key] = value;\n else delete merged[key];\n }\n return merged;\n}\n"],"mappings":";AAAA,OAAO,QAAQ;AAGf,IAAM,6BAAsD;AAAA,EAC1D,CAAC,WAAW,SAAS;AAAA,EACrB,CAAC,WAAW,SAAS;AACvB;AAEA,SAAS,YAAgC;AACvC,QAAM,iBAAiB,WAAW;AAClC,SAAO,iBAAiB,KAAK;AAC/B;AAEA,SAAS,oBAAoB,MAAwB;AACnD,QAAM,aAAa,CAAC,IAAI;AACxB,aAAW,CAAC,SAAS,MAAM,KAAK,4BAA4B;AAC1D,QAAI,KAAK,WAAW,OAAO,GAAG;AAC5B,iBAAW,KAAK,GAAG,MAAM,GAAG,KAAK,MAAM,QAAQ,MAAM,CAAC,EAAE;AAAA,IAC1D;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,WAAW,MAAkC;AAC3D,QAAM,MAAM,UAAU;AACtB,aAAW,aAAa,oBAAoB,IAAI,GAAG;AACjD,UAAM,QAAQ,MAAM,SAAS;AAC7B,QAAI,OAAO,UAAU,SAAU,QAAO;AAAA,EACxC;AACA,SAAO;AACT;AAEO,SAAS,iBAAyB;AACvC,SAAO,WAAW,MAAM,KAAK,GAAG,QAAQ;AAC1C;AAEA,SAAS,WAA8B;AACrC,SAAO,EAAE,GAAI,UAAU,KAAK,CAAC,EAAG;AAClC;AAEO,SAAS,SAAS,WAAkE;AACzF,QAAM,SAAS,SAAS;AACxB,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,SAAS,GAAG;AACpD,QAAI,OAAO,UAAU,SAAU,QAAO,GAAG,IAAI;AAAA,QACxC,QAAO,OAAO,GAAG;AAAA,EACxB;AACA,SAAO;AACT;","names":[]}
@@ -1 +0,0 @@
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 } 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};\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 try {\n const handle = await open(lockPath, \"wx\");\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 unlink(lockPath).catch(() => undefined);\n }\n } catch (error) {\n if (!isAlreadyExistsError(error)) throw error;\n try {\n const lockStat = await stat(lockPath);\n if (Date.now() - lockStat.mtimeMs > staleLockMs) {\n await unlink(lockPath).catch(() => undefined);\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\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n"],"mappings":"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","names":[]}