@remnic/core 9.3.613 → 9.3.615

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 (386) hide show
  1. package/dist/access-cli.js +59 -58
  2. package/dist/access-cli.js.map +1 -1
  3. package/dist/access-http.d.ts +4 -2
  4. package/dist/access-http.js +23 -23
  5. package/dist/access-mcp.d.ts +9 -2
  6. package/dist/access-mcp.js +20 -20
  7. package/dist/access-schema.d.ts +26 -14
  8. package/dist/access-schema.js +3 -3
  9. package/dist/{access-service-D2J9dh_9.d.ts → access-service-CBNEKjzN.d.ts} +71 -6
  10. package/dist/access-service.d.ts +2 -2
  11. package/dist/access-service.js +17 -17
  12. package/dist/active-recall.js +20 -3
  13. package/dist/active-recall.js.map +1 -1
  14. package/dist/adapters/index.js +4 -4
  15. package/dist/adapters/registry.js +2 -2
  16. package/dist/behavior-learner.js +2 -3
  17. package/dist/behavior-learner.js.map +1 -1
  18. package/dist/bootstrap.d.ts +1 -1
  19. package/dist/briefing.js +3 -3
  20. package/dist/buffer.d.ts +1 -1
  21. package/dist/buffer.js +1 -1
  22. package/dist/calibration.d.ts +5 -2
  23. package/dist/calibration.js +7 -5
  24. package/dist/calibration.js.map +1 -1
  25. package/dist/{capsule-crypto-7FJQINUR.js → capsule-crypto-YO5QJ6L3.js} +2 -2
  26. package/dist/causal-consolidation.d.ts +8 -2
  27. package/dist/causal-consolidation.js +13 -11
  28. package/dist/causal-consolidation.js.map +1 -1
  29. package/dist/{chunk-3BP57I6J.js → chunk-2F6NP3NT.js} +2 -1
  30. package/dist/{chunk-3BP57I6J.js.map → chunk-2F6NP3NT.js.map} +1 -1
  31. package/dist/{chunk-AU7Q3LSC.js → chunk-2QSZNTDO.js} +4 -4
  32. package/dist/{chunk-HSVJGWYS.js → chunk-2ROPI5OE.js} +2 -2
  33. package/dist/{chunk-C4SQJZAF.js → chunk-2SGJY2UY.js} +6 -3
  34. package/dist/chunk-2SGJY2UY.js.map +1 -0
  35. package/dist/{chunk-ZDTVJXIP.js → chunk-3MAONBX3.js} +13 -5
  36. package/dist/chunk-3MAONBX3.js.map +1 -0
  37. package/dist/{chunk-G3Z3QEF5.js → chunk-3PY7VHV7.js} +2 -2
  38. package/dist/chunk-3PY7VHV7.js.map +1 -0
  39. package/dist/{chunk-CF3ZF2YU.js → chunk-3QSU4NFF.js} +3 -3
  40. package/dist/{chunk-AJA46VX5.js → chunk-3T74IZB3.js} +11 -2
  41. package/dist/chunk-3T74IZB3.js.map +1 -0
  42. package/dist/{chunk-KVEVLBKC.js → chunk-4HFJQCJZ.js} +13 -8
  43. package/dist/chunk-4HFJQCJZ.js.map +1 -0
  44. package/dist/{chunk-KGK2QKWL.js → chunk-4R4KTDIE.js} +1 -1
  45. package/dist/chunk-4R4KTDIE.js.map +1 -0
  46. package/dist/{chunk-OI27U2HT.js → chunk-5BTCT236.js} +2 -2
  47. package/dist/{chunk-TH67Q46T.js → chunk-5OHHEORR.js} +64 -21
  48. package/dist/chunk-5OHHEORR.js.map +1 -0
  49. package/dist/{chunk-CO7ZO4TU.js → chunk-5VDJMYTF.js} +2 -2
  50. package/dist/{chunk-BFBF3XEF.js → chunk-6BDVBBBY.js} +33 -25
  51. package/dist/{chunk-BFBF3XEF.js.map → chunk-6BDVBBBY.js.map} +1 -1
  52. package/dist/{chunk-EAZGEEG2.js → chunk-6L46YAEZ.js} +45 -9
  53. package/dist/chunk-6L46YAEZ.js.map +1 -0
  54. package/dist/{chunk-YFS5OEKO.js → chunk-7MLB4NCL.js} +2 -2
  55. package/dist/{chunk-LZ3VEOU5.js → chunk-AL4RAJL5.js} +22 -5
  56. package/dist/chunk-AL4RAJL5.js.map +1 -0
  57. package/dist/{chunk-557IAFPD.js → chunk-APRRL26Q.js} +2 -2
  58. package/dist/{chunk-QDDHYAKV.js → chunk-AZDOWD2L.js} +2 -2
  59. package/dist/{chunk-MLT75J5S.js → chunk-B6SU7YSE.js} +3 -3
  60. package/dist/{chunk-FXKPZ3H6.js → chunk-BPSGLMQ4.js} +2 -2
  61. package/dist/{chunk-2NLLXCJG.js → chunk-BXLOS5AJ.js} +2 -2
  62. package/dist/{chunk-NOMEVTUD.js → chunk-C6C7XVKG.js} +5 -4
  63. package/dist/chunk-C6C7XVKG.js.map +1 -0
  64. package/dist/{chunk-XKIQZXUB.js → chunk-CI7RKSRE.js} +7 -1
  65. package/dist/chunk-CI7RKSRE.js.map +1 -0
  66. package/dist/{chunk-IK34DVAC.js → chunk-CIOMS6DI.js} +2 -2
  67. package/dist/{chunk-2I5JGH3M.js → chunk-CYEPCZN5.js} +2 -2
  68. package/dist/{chunk-2I5JGH3M.js.map → chunk-CYEPCZN5.js.map} +1 -1
  69. package/dist/{chunk-JHMFYY7L.js → chunk-DCGT4FPP.js} +13 -5
  70. package/dist/chunk-DCGT4FPP.js.map +1 -0
  71. package/dist/{chunk-7DZRO2DC.js → chunk-DEPRLVLK.js} +2 -2
  72. package/dist/{chunk-CSKLPDN6.js → chunk-DEVUWMME.js} +52 -19
  73. package/dist/chunk-DEVUWMME.js.map +1 -0
  74. package/dist/{chunk-DHGSZ3UD.js → chunk-DGNQRNLL.js} +2 -2
  75. package/dist/{chunk-X7Y7WX73.js → chunk-DQEMWVMT.js} +1 -1
  76. package/dist/{chunk-HJNQQICM.js → chunk-EXUAP5LH.js} +108 -51
  77. package/dist/chunk-EXUAP5LH.js.map +1 -0
  78. package/dist/chunk-FAV25DUZ.js +12 -0
  79. package/dist/chunk-FAV25DUZ.js.map +1 -0
  80. package/dist/{chunk-ETUPBUHB.js → chunk-GDASG7NC.js} +2 -2
  81. package/dist/{chunk-L227SKTB.js → chunk-GDB4J2H3.js} +17 -1
  82. package/dist/chunk-GDB4J2H3.js.map +1 -0
  83. package/dist/{chunk-IP73YCZP.js → chunk-GLPBYIXN.js} +4 -2
  84. package/dist/chunk-GLPBYIXN.js.map +1 -0
  85. package/dist/{chunk-4HP7HIE3.js → chunk-HP5FMB6L.js} +2 -2
  86. package/dist/{chunk-EVZFIAPG.js → chunk-IBTZEBUD.js} +23 -10
  87. package/dist/chunk-IBTZEBUD.js.map +1 -0
  88. package/dist/{chunk-DOX2CG6Y.js → chunk-IEUU7O4F.js} +2 -2
  89. package/dist/{chunk-EUML3N6B.js → chunk-IMA6GU4Y.js} +3 -3
  90. package/dist/chunk-IMA6GU4Y.js.map +1 -0
  91. package/dist/{chunk-JNANKJLN.js → chunk-JOASJWQR.js} +2 -2
  92. package/dist/chunk-JOASJWQR.js.map +1 -0
  93. package/dist/{chunk-WSGF57U2.js → chunk-JQDZQ4TB.js} +2 -2
  94. package/dist/{chunk-HINSGUA7.js → chunk-KBL3JJR6.js} +9 -13
  95. package/dist/chunk-KBL3JJR6.js.map +1 -0
  96. package/dist/{chunk-IOTENEVL.js → chunk-KGLPJROV.js} +57 -50
  97. package/dist/chunk-KGLPJROV.js.map +1 -0
  98. package/dist/{chunk-W7L6HXUC.js → chunk-LXOM6IQU.js} +2 -2
  99. package/dist/{chunk-G6R5UD3Q.js → chunk-MGN7VHWQ.js} +42 -1
  100. package/dist/{chunk-G6R5UD3Q.js.map → chunk-MGN7VHWQ.js.map} +1 -1
  101. package/dist/{chunk-DLJ4IR6M.js → chunk-MHQC2WU2.js} +2 -2
  102. package/dist/chunk-MHQC2WU2.js.map +1 -0
  103. package/dist/{chunk-5RPTH6AU.js → chunk-NM5NQYJE.js} +20 -19
  104. package/dist/chunk-NM5NQYJE.js.map +1 -0
  105. package/dist/{chunk-6JGNHWCI.js → chunk-OBIRVF36.js} +3 -3
  106. package/dist/{chunk-CHCA44C3.js → chunk-ODPLEWB6.js} +3 -3
  107. package/dist/chunk-ODPLEWB6.js.map +1 -0
  108. package/dist/{chunk-HENLZHIT.js → chunk-OIF36KGD.js} +7 -4
  109. package/dist/chunk-OIF36KGD.js.map +1 -0
  110. package/dist/{chunk-GUPISBV2.js → chunk-PP2JH3GP.js} +2 -2
  111. package/dist/{chunk-OXJBNGBK.js → chunk-PSUB67YB.js} +2 -2
  112. package/dist/{chunk-UWY7GIVS.js → chunk-PYIFUBRK.js} +45 -13
  113. package/dist/chunk-PYIFUBRK.js.map +1 -0
  114. package/dist/{chunk-KIB7SDIJ.js → chunk-Q6YIJGXJ.js} +2 -2
  115. package/dist/{chunk-ZT3EGNLR.js → chunk-QPD426WT.js} +2 -2
  116. package/dist/{chunk-RLV3PQGH.js → chunk-QVO4YOB7.js} +6 -6
  117. package/dist/{chunk-GMAG2HS4.js → chunk-RG3LBSGH.js} +46 -9
  118. package/dist/chunk-RG3LBSGH.js.map +1 -0
  119. package/dist/{chunk-XSWKORGM.js → chunk-S53OYO3F.js} +3 -1
  120. package/dist/chunk-S53OYO3F.js.map +1 -0
  121. package/dist/{chunk-YCN4BVDK.js → chunk-SCPFRKIT.js} +4 -2
  122. package/dist/chunk-SCPFRKIT.js.map +1 -0
  123. package/dist/{chunk-NZPF2SYV.js → chunk-T7N6KQGS.js} +138 -5
  124. package/dist/chunk-T7N6KQGS.js.map +1 -0
  125. package/dist/{chunk-VJXSUAO7.js → chunk-TNOWU6RP.js} +13 -10
  126. package/dist/chunk-TNOWU6RP.js.map +1 -0
  127. package/dist/{chunk-PCI747N2.js → chunk-TZVQQTG4.js} +48 -19
  128. package/dist/chunk-TZVQQTG4.js.map +1 -0
  129. package/dist/{chunk-KQAFEZQX.js → chunk-VDX2J7OX.js} +2 -2
  130. package/dist/{chunk-IK7DCC5H.js → chunk-VMGLYN42.js} +2 -2
  131. package/dist/{chunk-KM2A35EO.js → chunk-WB3LYXC5.js} +11 -7
  132. package/dist/chunk-WB3LYXC5.js.map +1 -0
  133. package/dist/{chunk-PPPZY2EU.js → chunk-WD2W4234.js} +9 -3
  134. package/dist/chunk-WD2W4234.js.map +1 -0
  135. package/dist/{chunk-NSKYFGDL.js → chunk-X4QQB7O6.js} +2 -2
  136. package/dist/{chunk-HPWVAEET.js → chunk-X6IRLNOO.js} +3 -7
  137. package/dist/chunk-X6IRLNOO.js.map +1 -0
  138. package/dist/{chunk-46GJIW5M.js → chunk-XAZOWLW4.js} +5 -5
  139. package/dist/{chunk-46GJIW5M.js.map → chunk-XAZOWLW4.js.map} +1 -1
  140. package/dist/{chunk-XPSVGJYA.js → chunk-YRMKDTKF.js} +12 -9
  141. package/dist/chunk-YRMKDTKF.js.map +1 -0
  142. package/dist/{chunk-6ZZP4EJF.js → chunk-ZJR7VG5L.js} +3 -3
  143. package/dist/{chunk-6ZZP4EJF.js.map → chunk-ZJR7VG5L.js.map} +1 -1
  144. package/dist/{chunk-2QANQKSQ.js → chunk-ZK32E74R.js} +156 -45
  145. package/dist/chunk-ZK32E74R.js.map +1 -0
  146. package/dist/{cli-OrfKXNU4.d.ts → cli-Cw729yLf.d.ts} +6 -2
  147. package/dist/cli.d.ts +3 -3
  148. package/dist/cli.js +61 -60
  149. package/dist/compounding/engine.js +3 -3
  150. package/dist/compounding/preference-consolidator.js +39 -11
  151. package/dist/compounding/preference-consolidator.js.map +1 -1
  152. package/dist/config.js +1 -1
  153. package/dist/connectors/codex-materialize-runner.js +3 -3
  154. package/dist/connectors/index.js +3 -3
  155. package/dist/consolidation-provenance-check.js +1 -1
  156. package/dist/contradiction/index.js +4 -4
  157. package/dist/conversation-index/backend.js +2 -2
  158. package/dist/conversation-index/indexer.js +1 -1
  159. package/dist/cross-namespace-budget.js +1 -1
  160. package/dist/enrichment/index.js +1 -1
  161. package/dist/entity-retrieval.js +3 -3
  162. package/dist/evals.js +1 -1
  163. package/dist/explicit-capture.d.ts +11 -1
  164. package/dist/explicit-capture.js +1 -1
  165. package/dist/extraction-judge.js +8 -1
  166. package/dist/extraction.js +2 -2
  167. package/dist/fallback-llm.d.ts +23 -6
  168. package/dist/fallback-llm.js +5 -3
  169. package/dist/{first-start-migration-GYJWIH36.js → first-start-migration-FF7YFGRP.js} +6 -6
  170. package/dist/index.d.ts +3 -3
  171. package/dist/index.js +95 -94
  172. package/dist/index.js.map +1 -1
  173. package/dist/lcm/archive.js +2 -2
  174. package/dist/lcm/engine.js +5 -5
  175. package/dist/lcm/index.js +7 -7
  176. package/dist/lcm/summarizer.js +3 -3
  177. package/dist/maintenance/memory-governance-cron.d.ts +6 -4
  178. package/dist/maintenance/memory-governance-cron.js +1 -1
  179. package/dist/maintenance/memory-governance.js +3 -3
  180. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +3 -3
  181. package/dist/maintenance/rebuild-memory-projection.js +4 -4
  182. package/dist/mcp-memory-inspector-app.d.ts +2 -2
  183. package/dist/mcp-memory-inspector-app.js +1 -1
  184. package/dist/migrate/from-engram.js +1 -1
  185. package/dist/namespaces/migrate.js +16 -15
  186. package/dist/namespaces/search.js +12 -11
  187. package/dist/namespaces/storage.js +3 -3
  188. package/dist/network/webdav.d.ts +2 -0
  189. package/dist/network/webdav.js +1 -1
  190. package/dist/objective-state-writers.js +2 -2
  191. package/dist/operator-toolkit.d.ts +3 -1
  192. package/dist/operator-toolkit.js +21 -20
  193. package/dist/{orchestrator-DTRQG75J.d.ts → orchestrator-CqWOjfgl.d.ts} +46 -3
  194. package/dist/orchestrator.d.ts +1 -1
  195. package/dist/orchestrator.js +48 -45
  196. package/dist/patterns-cli.js +1 -1
  197. package/dist/qmd-recall-cache.d.ts +2 -0
  198. package/dist/qmd-recall-cache.js +1 -1
  199. package/dist/qmd.d.ts +37 -2
  200. package/dist/qmd.js +4 -1
  201. package/dist/recall-explain-renderer.js +3 -3
  202. package/dist/recall-planner-llm.d.ts +57 -0
  203. package/dist/recall-planner-llm.js +167 -0
  204. package/dist/recall-planner-llm.js.map +1 -0
  205. package/dist/recall-xray-cli.js +4 -4
  206. package/dist/recall-xray-renderer.js +3 -3
  207. package/dist/recall-xray.js +2 -2
  208. package/dist/resume-bundles.js +2 -2
  209. package/dist/retrieval-agents.js +2 -2
  210. package/dist/routing/store.js +1 -1
  211. package/dist/schemas.d.ts +22 -22
  212. package/dist/search/factory.js +11 -10
  213. package/dist/search/index.js +11 -10
  214. package/dist/search/lancedb-backend.d.ts +1 -1
  215. package/dist/search/lancedb-backend.js +3 -2
  216. package/dist/search/meilisearch-backend.d.ts +1 -1
  217. package/dist/search/meilisearch-backend.js +3 -2
  218. package/dist/search/noop-backend.d.ts +1 -1
  219. package/dist/search/noop-backend.js +1 -1
  220. package/dist/search/orama-backend.d.ts +1 -1
  221. package/dist/search/orama-backend.js +3 -2
  222. package/dist/search/port.d.ts +6 -1
  223. package/dist/search/port.js +7 -0
  224. package/dist/search/remote-backend.d.ts +1 -1
  225. package/dist/search/remote-backend.js +1 -1
  226. package/dist/semantic-consolidation.js +4 -4
  227. package/dist/semantic-rule-promotion.js +3 -3
  228. package/dist/semantic-rule-verifier.js +3 -3
  229. package/dist/session-observer-state.js +1 -1
  230. package/dist/storage.js +2 -2
  231. package/dist/summarizer.js +2 -2
  232. package/dist/temporal-index.js +1 -1
  233. package/dist/{tier-stats-SKML2OSF.js → tier-stats-3LYQ3VV5.js} +3 -3
  234. package/dist/transfer/backup.js +2 -2
  235. package/dist/transfer/capsule-export.js +2 -2
  236. package/dist/transfer/capsule-import.js +2 -2
  237. package/dist/transfer/export-sqlite.js +1 -1
  238. package/dist/transfer/types.d.ts +12 -12
  239. package/dist/types.d.ts +32 -0
  240. package/dist/types.js +1 -1
  241. package/dist/utility-learner.js +1 -1
  242. package/dist/utility-runtime.js +2 -2
  243. package/dist/verified-recall.js +3 -3
  244. package/dist/work/board.js +2 -2
  245. package/dist/work/storage.d.ts +2 -0
  246. package/dist/work/storage.js +1 -1
  247. package/package.json +1 -1
  248. package/src/access-http.ts +24 -10
  249. package/src/access-mcp.test.ts +160 -0
  250. package/src/access-mcp.ts +72 -7
  251. package/src/access-schema.ts +11 -0
  252. package/src/access-service-coding-write.test.ts +478 -0
  253. package/src/access-service.ts +237 -32
  254. package/src/active-recall.test.ts +40 -0
  255. package/src/active-recall.ts +19 -2
  256. package/src/behavior-learner.ts +5 -3
  257. package/src/buffer-session.test.ts +58 -0
  258. package/src/buffer-surprise-trigger.test.ts +4 -18
  259. package/src/buffer.ts +39 -11
  260. package/src/calibration.ts +10 -4
  261. package/src/causal-consolidation.test.ts +47 -2
  262. package/src/causal-consolidation.ts +13 -9
  263. package/src/cli.ts +19 -4
  264. package/src/compounding/engine.ts +2 -0
  265. package/src/compounding/preference-consolidator.test.ts +292 -0
  266. package/src/compounding/preference-consolidator.ts +55 -19
  267. package/src/config.test.ts +213 -0
  268. package/src/config.ts +175 -4
  269. package/src/connectors/codex-materialize-runner.ts +7 -4
  270. package/src/consolidation-provenance-check.ts +24 -5
  271. package/src/conversation-index/indexer.test.ts +22 -0
  272. package/src/conversation-index/indexer.ts +7 -3
  273. package/src/cross-namespace-budget.test.ts +44 -21
  274. package/src/cross-namespace-budget.ts +2 -2
  275. package/src/enrichment/pipeline.ts +11 -16
  276. package/src/evals.ts +1 -1
  277. package/src/explicit-capture.ts +19 -2
  278. package/src/extraction-judge-chain.test.ts +55 -0
  279. package/src/extraction-judge.ts +7 -9
  280. package/src/extraction.ts +16 -5
  281. package/src/fallback-llm.test.ts +600 -1
  282. package/src/fallback-llm.ts +91 -22
  283. package/src/maintenance/memory-governance-cron.ts +39 -29
  284. package/src/mcp-memory-inspector-app.ts +54 -12
  285. package/src/message-parts/index.ts +6 -0
  286. package/src/message-parts/message-parts.test.ts +30 -0
  287. package/src/migrate/from-engram.ts +19 -5
  288. package/src/namespaces/search.test.ts +15 -2
  289. package/src/namespaces/search.ts +1 -1
  290. package/src/network/webdav.ts +61 -21
  291. package/src/operator-toolkit.ts +6 -2
  292. package/src/orchestrator.ts +173 -20
  293. package/src/qmd-client.test.ts +85 -0
  294. package/src/qmd-recall-cache.test.ts +16 -0
  295. package/src/qmd-recall-cache.ts +7 -0
  296. package/src/qmd.test.ts +54 -0
  297. package/src/qmd.ts +119 -19
  298. package/src/recall-planner-llm.test.ts +224 -0
  299. package/src/recall-planner-llm.ts +289 -0
  300. package/src/routing/store.ts +4 -8
  301. package/src/search/factory.ts +3 -0
  302. package/src/search/lancedb-backend.ts +15 -3
  303. package/src/search/meilisearch-backend.ts +70 -7
  304. package/src/search/noop-backend.ts +5 -1
  305. package/src/search/orama-backend.ts +15 -3
  306. package/src/search/port.ts +15 -0
  307. package/src/search/remote-backend.ts +5 -1
  308. package/src/session-observer-state.ts +1 -1
  309. package/src/summarizer.ts +3 -3
  310. package/src/temporal-index.test.ts +18 -0
  311. package/src/temporal-index.ts +45 -0
  312. package/src/training-export/cli-date-validation.test.ts +36 -0
  313. package/src/training-export/date-parse.ts +21 -2
  314. package/src/transfer/export-sqlite.ts +3 -0
  315. package/src/types.ts +35 -0
  316. package/src/utility-learner.ts +1 -0
  317. package/src/work/storage.ts +23 -0
  318. package/dist/chunk-2QANQKSQ.js.map +0 -1
  319. package/dist/chunk-5RPTH6AU.js.map +0 -1
  320. package/dist/chunk-AJA46VX5.js.map +0 -1
  321. package/dist/chunk-C4SQJZAF.js.map +0 -1
  322. package/dist/chunk-CHCA44C3.js.map +0 -1
  323. package/dist/chunk-CSKLPDN6.js.map +0 -1
  324. package/dist/chunk-DLJ4IR6M.js.map +0 -1
  325. package/dist/chunk-EAZGEEG2.js.map +0 -1
  326. package/dist/chunk-EUML3N6B.js.map +0 -1
  327. package/dist/chunk-EVZFIAPG.js.map +0 -1
  328. package/dist/chunk-G3Z3QEF5.js.map +0 -1
  329. package/dist/chunk-GMAG2HS4.js.map +0 -1
  330. package/dist/chunk-HENLZHIT.js.map +0 -1
  331. package/dist/chunk-HINSGUA7.js.map +0 -1
  332. package/dist/chunk-HJNQQICM.js.map +0 -1
  333. package/dist/chunk-HPWVAEET.js.map +0 -1
  334. package/dist/chunk-IOTENEVL.js.map +0 -1
  335. package/dist/chunk-IP73YCZP.js.map +0 -1
  336. package/dist/chunk-JHMFYY7L.js.map +0 -1
  337. package/dist/chunk-JNANKJLN.js.map +0 -1
  338. package/dist/chunk-KGK2QKWL.js.map +0 -1
  339. package/dist/chunk-KM2A35EO.js.map +0 -1
  340. package/dist/chunk-KVEVLBKC.js.map +0 -1
  341. package/dist/chunk-L227SKTB.js.map +0 -1
  342. package/dist/chunk-LZ3VEOU5.js.map +0 -1
  343. package/dist/chunk-NOMEVTUD.js.map +0 -1
  344. package/dist/chunk-NZPF2SYV.js.map +0 -1
  345. package/dist/chunk-PCI747N2.js.map +0 -1
  346. package/dist/chunk-PPPZY2EU.js.map +0 -1
  347. package/dist/chunk-TH67Q46T.js.map +0 -1
  348. package/dist/chunk-UWY7GIVS.js.map +0 -1
  349. package/dist/chunk-VJXSUAO7.js.map +0 -1
  350. package/dist/chunk-XKIQZXUB.js.map +0 -1
  351. package/dist/chunk-XPSVGJYA.js.map +0 -1
  352. package/dist/chunk-XSWKORGM.js.map +0 -1
  353. package/dist/chunk-YCN4BVDK.js.map +0 -1
  354. package/dist/chunk-ZDTVJXIP.js.map +0 -1
  355. /package/dist/{capsule-crypto-7FJQINUR.js.map → capsule-crypto-YO5QJ6L3.js.map} +0 -0
  356. /package/dist/{chunk-AU7Q3LSC.js.map → chunk-2QSZNTDO.js.map} +0 -0
  357. /package/dist/{chunk-HSVJGWYS.js.map → chunk-2ROPI5OE.js.map} +0 -0
  358. /package/dist/{chunk-CF3ZF2YU.js.map → chunk-3QSU4NFF.js.map} +0 -0
  359. /package/dist/{chunk-OI27U2HT.js.map → chunk-5BTCT236.js.map} +0 -0
  360. /package/dist/{chunk-CO7ZO4TU.js.map → chunk-5VDJMYTF.js.map} +0 -0
  361. /package/dist/{chunk-YFS5OEKO.js.map → chunk-7MLB4NCL.js.map} +0 -0
  362. /package/dist/{chunk-557IAFPD.js.map → chunk-APRRL26Q.js.map} +0 -0
  363. /package/dist/{chunk-QDDHYAKV.js.map → chunk-AZDOWD2L.js.map} +0 -0
  364. /package/dist/{chunk-MLT75J5S.js.map → chunk-B6SU7YSE.js.map} +0 -0
  365. /package/dist/{chunk-FXKPZ3H6.js.map → chunk-BPSGLMQ4.js.map} +0 -0
  366. /package/dist/{chunk-2NLLXCJG.js.map → chunk-BXLOS5AJ.js.map} +0 -0
  367. /package/dist/{chunk-IK34DVAC.js.map → chunk-CIOMS6DI.js.map} +0 -0
  368. /package/dist/{chunk-7DZRO2DC.js.map → chunk-DEPRLVLK.js.map} +0 -0
  369. /package/dist/{chunk-DHGSZ3UD.js.map → chunk-DGNQRNLL.js.map} +0 -0
  370. /package/dist/{chunk-X7Y7WX73.js.map → chunk-DQEMWVMT.js.map} +0 -0
  371. /package/dist/{chunk-ETUPBUHB.js.map → chunk-GDASG7NC.js.map} +0 -0
  372. /package/dist/{chunk-4HP7HIE3.js.map → chunk-HP5FMB6L.js.map} +0 -0
  373. /package/dist/{chunk-DOX2CG6Y.js.map → chunk-IEUU7O4F.js.map} +0 -0
  374. /package/dist/{chunk-WSGF57U2.js.map → chunk-JQDZQ4TB.js.map} +0 -0
  375. /package/dist/{chunk-W7L6HXUC.js.map → chunk-LXOM6IQU.js.map} +0 -0
  376. /package/dist/{chunk-6JGNHWCI.js.map → chunk-OBIRVF36.js.map} +0 -0
  377. /package/dist/{chunk-GUPISBV2.js.map → chunk-PP2JH3GP.js.map} +0 -0
  378. /package/dist/{chunk-OXJBNGBK.js.map → chunk-PSUB67YB.js.map} +0 -0
  379. /package/dist/{chunk-KIB7SDIJ.js.map → chunk-Q6YIJGXJ.js.map} +0 -0
  380. /package/dist/{chunk-ZT3EGNLR.js.map → chunk-QPD426WT.js.map} +0 -0
  381. /package/dist/{chunk-RLV3PQGH.js.map → chunk-QVO4YOB7.js.map} +0 -0
  382. /package/dist/{chunk-KQAFEZQX.js.map → chunk-VDX2J7OX.js.map} +0 -0
  383. /package/dist/{chunk-IK7DCC5H.js.map → chunk-VMGLYN42.js.map} +0 -0
  384. /package/dist/{chunk-NSKYFGDL.js.map → chunk-X4QQB7O6.js.map} +0 -0
  385. /package/dist/{first-start-migration-GYJWIH36.js.map → first-start-migration-FF7YFGRP.js.map} +0 -0
  386. /package/dist/{tier-stats-SKML2OSF.js.map → tier-stats-3LYQ3VV5.js.map} +0 -0
@@ -17,7 +17,7 @@ function isCalendarDateValid(year, month, day) {
17
17
  return day <= maxDay;
18
18
  }
19
19
  function parseStrictCliDate(value, flagName) {
20
- const shape = /^(\d{4})-(\d{2})-(\d{2})(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{1,9}))?)?(Z|[+-]\d{2}:\d{2})?)?$/;
20
+ const shape = /^(\d{4})-(\d{2})-(\d{2})(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{1,9}))?)?(?:Z|([+-])(\d{2}):(\d{2}))?)?$/;
21
21
  const match = value.match(shape);
22
22
  if (!match) {
23
23
  throw new Error(
@@ -42,6 +42,15 @@ function parseStrictCliDate(value, flagName) {
42
42
  );
43
43
  }
44
44
  }
45
+ if (match[8] !== void 0) {
46
+ const offsetHour = Number(match[9]);
47
+ const offsetMinute = Number(match[10]);
48
+ if (offsetHour > 14 || offsetMinute > 59 || offsetHour === 14 && offsetMinute !== 0) {
49
+ throw new Error(
50
+ `Invalid ${flagName} value "${value}": timezone offset out of range.`
51
+ );
52
+ }
53
+ }
45
54
  const d = new Date(value);
46
55
  if (!Number.isFinite(d.getTime())) {
47
56
  throw new Error(
@@ -390,4 +399,4 @@ export {
390
399
  renderPatternsList,
391
400
  renderPatternExplain
392
401
  };
393
- //# sourceMappingURL=chunk-AJA46VX5.js.map
402
+ //# sourceMappingURL=chunk-3T74IZB3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/training-export/date-parse.ts","../src/patterns-cli.ts"],"sourcesContent":["/**\n * Strict ISO 8601 date parsing for training-export CLI flags.\n *\n * Extracted from `cli.ts` so that both the canonical CLI (in\n * `@remnic/core`) and the thin front-end CLI (in `@remnic/cli`) can share\n * the same validator without duplicating the overflow/timezone rules.\n *\n * The parser rejects:\n * - Non-ISO strings (e.g. \"12/25/2026\", \"Dec 25 2026\")\n * - Calendar overflows (Feb 30, Feb 29 in non-leap years, Apr 31, etc.)\n * regardless of timezone suffix\n * - Out-of-range time components (hour >= 24, minute >= 60, second >= 60)\n * - Out-of-range timezone offsets (beyond ±14:00, or offset minute >= 60)\n *\n * Calendar overflow is validated structurally on the Y-M-D components, so\n * results are independent of the host's local timezone.\n */\n\n/**\n * Days in each month (1-indexed). February is 28 here; leap-year handling\n * is applied by `isCalendarDateValid` below.\n */\nconst DAYS_IN_MONTH = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\n\nfunction isLeapYear(year: number): boolean {\n return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n}\n\n/**\n * True iff `year-month-day` is a valid Gregorian calendar date. Input\n * numbers must be integer-valued; month is 1-12, day is 1-31 nominally.\n */\nexport function isCalendarDateValid(\n year: number,\n month: number,\n day: number,\n): boolean {\n if (\n !Number.isInteger(year) ||\n !Number.isInteger(month) ||\n !Number.isInteger(day)\n ) {\n return false;\n }\n if (month < 1 || month > 12) return false;\n if (day < 1) return false;\n const maxDay = month === 2 && isLeapYear(year) ? 29 : DAYS_IN_MONTH[month];\n return day <= maxDay;\n}\n\n/**\n * Parse a strict ISO 8601 date string, rejecting malformed inputs, calendar\n * overflows, and out-of-range time components with a descriptive error.\n *\n * Accepted forms:\n * YYYY-MM-DD\n * YYYY-MM-DDTHH:mm:ss (naive / local time)\n * YYYY-MM-DDTHH:mm:ss.sssZ (UTC)\n * YYYY-MM-DDTHH:mm:ss+HH:MM (with timezone offset)\n * YYYY-MM-DDTHH:mm:ss.sss-HH:MM (with timezone offset)\n *\n * `flagName` is included in the error message so users can identify which\n * input failed (e.g. `--since` vs. `--until`).\n */\nexport function parseStrictCliDate(value: string, flagName: string): Date {\n // 1. Shape check: must begin YYYY-MM-DD and use ISO 8601 structure.\n // This rejects \"12/25/2026\", \"December 25, 2026\", RFC 2822, etc.\n const shape =\n /^(\\d{4})-(\\d{2})-(\\d{2})(?:T(\\d{2}):(\\d{2})(?::(\\d{2})(?:\\.(\\d{1,9}))?)?(?:Z|([+-])(\\d{2}):(\\d{2}))?)?$/;\n const match = value.match(shape);\n if (!match) {\n throw new Error(\n `Invalid ${flagName} value \"${value}\": expected ISO 8601 format (YYYY-MM-DD or YYYY-MM-DDTHH:mm:ss[.sss][Z|±HH:MM]).`,\n );\n }\n\n const year = Number(match[1]);\n const month = Number(match[2]);\n const day = Number(match[3]);\n\n // 2. Structural calendar validation. This rejects Feb 31, Feb 29 in\n // non-leap years, Apr 31, etc. regardless of the timezone suffix, so\n // \"2026-02-31T00:00:00+05:30\" is rejected the same way as \"2026-02-31Z\".\n if (!isCalendarDateValid(year, month, day)) {\n throw new Error(\n `Invalid ${flagName} value \"${value}\": date components overflow (e.g. month has fewer days). Provide a valid calendar date.`,\n );\n }\n\n // 3. Optional time-component validation.\n // JavaScript's Date cannot represent a leap second: `:60` is silently\n // normalised to `:00` of the following minute, which would make a\n // \"strict\" validator return a different timestamp than the user\n // requested. Reject second == 60 outright so a strict parse cannot\n // round-trip to a different clock value.\n if (match[4] !== undefined) {\n const hour = Number(match[4]);\n const minute = Number(match[5]);\n const second = match[6] !== undefined ? Number(match[6]) : 0;\n if (hour > 23 || minute > 59 || second > 59) {\n throw new Error(\n `Invalid ${flagName} value \"${value}\": time components out of range.`,\n );\n }\n }\n\n // 4. Timezone offset validation.\n // Date accepts offset hours beyond the real-world UTC offset range and\n // normalizes impossible offsets into a shifted instant. Reject those\n // before constructing the Date so the CLI cannot silently apply them.\n if (match[8] !== undefined) {\n const offsetHour = Number(match[9]);\n const offsetMinute = Number(match[10]);\n if (\n offsetHour > 14 ||\n offsetMinute > 59 ||\n (offsetHour === 14 && offsetMinute !== 0)\n ) {\n throw new Error(\n `Invalid ${flagName} value \"${value}\": timezone offset out of range.`,\n );\n }\n }\n\n // 5. Finally parse via Date for the actual timestamp value. At this point\n // we've already validated structure and calendar correctness, so any\n // remaining NaN (extremely unlikely) still fails closed.\n const d = new Date(value);\n if (!Number.isFinite(d.getTime())) {\n throw new Error(\n `Invalid ${flagName} value \"${value}\". Provide an ISO 8601 date string (YYYY-MM-DD or YYYY-MM-DDTHH:mm:ss).`,\n );\n }\n\n return d;\n}\n","/**\n * `remnic patterns` CLI helpers (issue #687 PR 4/4).\n *\n * Pure functions that:\n *\n * 1. Validate `--limit`, `--category`, `--since`, `--format` for\n * `remnic patterns list` and `--format` for\n * `remnic patterns explain <id>` (CLAUDE.md rules 14 + 51 — flags\n * throw listed-options errors instead of silently defaulting).\n *\n * 2. Filter the memory corpus to canonical memories produced by the\n * pattern-reinforcement maintenance job from issue #687 PR 2/4\n * (`reinforcement_count > 0`) and sort them by reinforcement\n * count, with `last_reinforced_at` (then `id`) as stable\n * tiebreakers (CLAUDE.md rule 19).\n *\n * 3. Reconstruct a single canonical's full picture: its\n * `derived_from` provenance chain (PR 2/4 stamps these), the\n * cluster members it absorbed (memories pointing at it via\n * `supersededBy`), and the canonical body so operators can read\n * it inline.\n *\n * 4. Render `text` (default) / `markdown` / `json` output for both\n * commands. The CLI handler in `cli.ts` stays thin and delegates\n * formatting here so HTTP / MCP surfaces (if added later) can\n * reuse the same renderers (CLAUDE.md rule 22 — never fork\n * formatting).\n */\n\nimport type { MemoryCategory, MemoryFile } from \"./types.js\";\nimport { DERIVED_FROM_MEMORY_ID_RE } from \"./consolidation-operator.js\";\nimport { parseStrictCliDate } from \"./training-export/date-parse.js\";\n\nexport const PATTERNS_OUTPUT_FORMATS = [\"text\", \"markdown\", \"json\"] as const;\nexport type PatternsOutputFormat = (typeof PATTERNS_OUTPUT_FORMATS)[number];\n\n// ───────────────────────────────────────────────────────────────────────────\n// Flag validation\n// ───────────────────────────────────────────────────────────────────────────\n\n/**\n * Validate `--format <fmt>`. Throws a listed-options error for any\n * value not in `PATTERNS_OUTPUT_FORMATS`. Returns `\"text\"` when the\n * value is `undefined` (no flag supplied).\n */\nexport function parsePatternsFormat(value: unknown): PatternsOutputFormat {\n if (value === undefined || value === null) return \"text\";\n if (\n typeof value !== \"string\" ||\n !(PATTERNS_OUTPUT_FORMATS as readonly string[]).includes(value)\n ) {\n throw new Error(\n `--format expects one of ${PATTERNS_OUTPUT_FORMATS.join(\", \")}; got ${JSON.stringify(value)}`,\n );\n }\n return value as PatternsOutputFormat;\n}\n\n/**\n * Validate `--limit <N>`. Must be a positive integer. Returns\n * `undefined` when the flag is absent (the caller falls back to a\n * default).\n */\nexport function parsePatternsLimit(value: unknown): number | undefined {\n if (value === undefined || value === null) return undefined;\n const parsed = typeof value === \"number\" ? value : Number(value);\n if (!Number.isFinite(parsed) || !Number.isInteger(parsed) || parsed <= 0) {\n throw new Error(\n `--limit expects a positive integer; got ${JSON.stringify(value)}`,\n );\n }\n return parsed;\n}\n\n/**\n * Validate `--category <list>`. Accepts a comma-separated list of\n * non-empty trimmed tokens. Returns the deduplicated list, or\n * `undefined` when no flag was supplied. CLAUDE.md rules 14 + 51:\n * `--category` with no value or with a value that resolves to zero\n * tokens is rejected.\n */\nexport function parsePatternsCategory(value: unknown): string[] | undefined {\n if (value === undefined || value === null) return undefined;\n if (typeof value !== \"string\") {\n throw new Error(\n `--category expects a comma-separated list of category names; got ${JSON.stringify(value)}`,\n );\n }\n const parts = value\n .split(\",\")\n .map((part) => part.trim())\n .filter((part) => part.length > 0);\n if (parts.length === 0) {\n throw new Error(\n `--category expects at least one non-empty category name; got ${JSON.stringify(value)}`,\n );\n }\n // Deduplicate while preserving first-seen order.\n const seen = new Set<string>();\n const unique: string[] = [];\n for (const part of parts) {\n if (!seen.has(part)) {\n seen.add(part);\n unique.push(part);\n }\n }\n return unique;\n}\n\n/**\n * Validate `--since <ISO>`. Delegates to `parseStrictCliDate` which\n * enforces a strict ISO 8601 shape and rejects calendar overflows and\n * non-ISO formats (e.g. \"12/25/2026\", \"Dec 25 2026\") that bare\n * `Date.parse()` would silently accept. Returns the canonical ISO\n * string (round-trip through `toISOString`) so downstream comparisons\n * use a consistent form.\n */\nexport function parsePatternsSince(value: unknown): string | undefined {\n if (value === undefined || value === null) return undefined;\n if (typeof value !== \"string\" || value.trim().length === 0) {\n throw new Error(\n `--since expects an ISO 8601 timestamp (e.g. 2026-04-01T00:00:00Z); got ${JSON.stringify(value)}`,\n );\n }\n // parseStrictCliDate throws with a descriptive message on invalid input.\n return parseStrictCliDate(value.trim(), \"--since\").toISOString();\n}\n\nexport interface ParsedPatternsListOptions {\n format: PatternsOutputFormat;\n limit?: number;\n categories?: string[];\n sinceIso?: string;\n}\n\nexport interface ParsedPatternsExplainOptions {\n format: PatternsOutputFormat;\n}\n\n/**\n * Validate the full option bag for `remnic patterns list`. Extracted\n * from the CLI handler so validation can be unit-tested without\n * booting an orchestrator (CLAUDE.md rules 14 + 51).\n */\nexport function parsePatternsListOptions(\n options: Record<string, unknown>,\n): ParsedPatternsListOptions {\n const format = parsePatternsFormat(options.format);\n const limit = parsePatternsLimit(options.limit);\n const categories = parsePatternsCategory(options.category);\n const sinceIso = parsePatternsSince(options.since);\n return {\n format,\n ...(limit !== undefined ? { limit } : {}),\n ...(categories !== undefined ? { categories } : {}),\n ...(sinceIso !== undefined ? { sinceIso } : {}),\n };\n}\n\n/**\n * Validate `remnic patterns explain` options + positional id. Throws\n * when `<memoryId>` is missing or empty.\n */\nexport function parsePatternsExplainOptions(\n rawId: unknown,\n options: Record<string, unknown>,\n): { id: string } & ParsedPatternsExplainOptions {\n if (typeof rawId !== \"string\" || rawId.trim().length === 0) {\n throw new Error(\"patterns explain: <memoryId> is required and must be non-empty\");\n }\n const format = parsePatternsFormat(options.format);\n return { id: rawId.trim(), format };\n}\n\n// ───────────────────────────────────────────────────────────────────────────\n// Core list / explain behavior\n// ───────────────────────────────────────────────────────────────────────────\n\nexport interface PatternListRow {\n id: string;\n category: MemoryCategory;\n reinforcementCount: number;\n lastReinforcedAt?: string;\n status: string;\n /** First non-empty content line, trimmed to ~120 chars for the table. */\n preview: string;\n /** Full path on disk (relative to memoryDir) for operators who want to inspect the file. */\n path: string;\n}\n\nconst DEFAULT_LIST_LIMIT = 50;\n\n/**\n * Filter, sort, and slice the memory corpus down to the rows the\n * `remnic patterns list` command should print.\n *\n * Rules (each one is exercised by `tests/cli/patterns.test.ts`):\n *\n * - Memories without `reinforcement_count` (or with a count <= 0) are\n * dropped — these are not pattern canonicals.\n * - When `categories` is supplied, only memories whose\n * `frontmatter.category` is in the list survive.\n * - When `sinceIso` is supplied, only memories whose\n * `last_reinforced_at` is `>= sinceIso` survive. Memories without\n * `last_reinforced_at` are dropped under `--since` (PR 2/4 always\n * stamps the timestamp alongside the count, so a missing timestamp\n * means a malformed file the operator should not see in this view).\n * - Sort by `reinforcement_count DESC`, then `last_reinforced_at\n * DESC`, then `id ASC` for a stable, deterministic order\n * (CLAUDE.md rule 19).\n * - Apply `limit` (default 50).\n */\nexport function collectPatternMemories(\n memories: readonly MemoryFile[],\n opts: ParsedPatternsListOptions,\n): PatternListRow[] {\n const sinceMs =\n opts.sinceIso !== undefined ? Date.parse(opts.sinceIso) : undefined;\n const categorySet =\n opts.categories !== undefined ? new Set(opts.categories) : undefined;\n\n const rows: PatternListRow[] = [];\n for (const memory of memories) {\n const fm = memory.frontmatter;\n const count = fm.reinforcement_count;\n if (typeof count !== \"number\" || !Number.isInteger(count) || count <= 0) {\n continue;\n }\n if (categorySet !== undefined && !categorySet.has(fm.category)) {\n continue;\n }\n if (sinceMs !== undefined) {\n if (typeof fm.last_reinforced_at !== \"string\") continue;\n const ts = Date.parse(fm.last_reinforced_at);\n if (!Number.isFinite(ts) || ts < sinceMs) continue;\n }\n rows.push({\n id: fm.id,\n category: fm.category,\n reinforcementCount: count,\n ...(fm.last_reinforced_at !== undefined\n ? { lastReinforcedAt: fm.last_reinforced_at }\n : {}),\n status: fm.status ?? \"active\",\n preview: extractPreview(memory.content),\n path: memory.path,\n });\n }\n\n rows.sort((a, b) => {\n if (b.reinforcementCount !== a.reinforcementCount) {\n return b.reinforcementCount - a.reinforcementCount;\n }\n // Guard NaN: malformed date strings make Date.parse return NaN, which\n // breaks the sort contract (NaN comparator return == non-deterministic\n // ordering). Treat invalid/missing timestamps as 0 (oldest possible).\n const aRaw = a.lastReinforcedAt ? Date.parse(a.lastReinforcedAt) : NaN;\n const bRaw = b.lastReinforcedAt ? Date.parse(b.lastReinforcedAt) : NaN;\n const aTs = Number.isFinite(aRaw) ? aRaw : 0;\n const bTs = Number.isFinite(bRaw) ? bRaw : 0;\n if (bTs !== aTs) return bTs - aTs;\n if (a.id < b.id) return -1;\n if (a.id > b.id) return 1;\n return 0;\n });\n\n const limit = opts.limit ?? DEFAULT_LIST_LIMIT;\n return rows.slice(0, limit);\n}\n\nexport interface PatternDerivedFromEntry {\n /** Raw `\"<path>:<version>\"` reference exactly as stored in `derived_from`. */\n ref: string;\n /** Source memory id, or the path component for older `path:version` references. */\n path: string;\n /** Page-version number component for older `path:version` references. */\n version: number | null;\n /** True when an older path-version reference had an invalid version component. */\n malformed?: boolean;\n}\n\nexport interface PatternClusterMember {\n id: string;\n status: string;\n supersededAt?: string;\n path: string;\n preview: string;\n}\n\nexport interface PatternExplainDetail {\n id: string;\n category: MemoryCategory;\n reinforcementCount: number;\n lastReinforcedAt?: string;\n status: string;\n derivedVia?: string;\n /** Full canonical body (frontmatter stripped). */\n canonicalContent: string;\n canonicalPath: string;\n /** Parsed `derived_from` chain — empty when PR 2/4 did not stamp it. */\n derivedFrom: PatternDerivedFromEntry[];\n /** Memories whose `supersededBy === <id>`, sorted by `supersededAt DESC` then `id ASC`. */\n clusterMembers: PatternClusterMember[];\n}\n\n/**\n * Build the structured detail object for a single canonical. Returns\n * `null` when the memory is not found or has never been touched by\n * pattern reinforcement (i.e., no `reinforcement_count`). The CLI\n * handler then prints a clean \"not a pattern\" error rather than\n * leaking an empty document.\n */\nexport function explainPatternMemory(\n memories: readonly MemoryFile[],\n id: string,\n): PatternExplainDetail | null {\n const canonical = memories.find((m) => m.frontmatter.id === id);\n if (!canonical) return null;\n const fm = canonical.frontmatter;\n const count = fm.reinforcement_count;\n if (typeof count !== \"number\" || !Number.isInteger(count) || count <= 0) {\n return null;\n }\n\n const derivedFrom: PatternDerivedFromEntry[] = (fm.derived_from ?? []).map(\n (ref) => {\n const lastColon = ref.lastIndexOf(\":\");\n const pathLikeRef = looksLikeDerivedFromPath(ref);\n if (lastColon >= 0) {\n const path = ref.slice(0, lastColon);\n const versionStr = ref.slice(lastColon + 1);\n if (\n looksLikeDerivedFromPath(path) &&\n /^\\d+$/.test(versionStr)\n ) {\n return { ref, path, version: Number(versionStr) };\n }\n if (!pathLikeRef && DERIVED_FROM_MEMORY_ID_RE.test(ref)) {\n return { ref, path: ref, version: null };\n }\n return { ref, path: ref, version: null, malformed: true };\n }\n if (DERIVED_FROM_MEMORY_ID_RE.test(ref)) {\n return {\n ref,\n path: ref,\n version: null,\n };\n }\n return { ref, path: ref, version: null, malformed: true };\n },\n );\n\n const members: PatternClusterMember[] = [];\n for (const m of memories) {\n if (m.frontmatter.supersededBy === id) {\n members.push({\n id: m.frontmatter.id,\n status: m.frontmatter.status ?? \"active\",\n ...(m.frontmatter.supersededAt !== undefined\n ? { supersededAt: m.frontmatter.supersededAt }\n : {}),\n path: m.path,\n preview: extractPreview(m.content),\n });\n }\n }\n members.sort((a, b) => {\n // Guard NaN: same rationale as collectPatternMemories sort — malformed\n // supersededAt strings must not produce a NaN return from the comparator.\n const aRaw = a.supersededAt ? Date.parse(a.supersededAt) : NaN;\n const bRaw = b.supersededAt ? Date.parse(b.supersededAt) : NaN;\n const aTs = Number.isFinite(aRaw) ? aRaw : 0;\n const bTs = Number.isFinite(bRaw) ? bRaw : 0;\n if (bTs !== aTs) return bTs - aTs;\n if (a.id < b.id) return -1;\n if (a.id > b.id) return 1;\n return 0;\n });\n\n return {\n id: fm.id,\n category: fm.category,\n reinforcementCount: count,\n ...(fm.last_reinforced_at !== undefined\n ? { lastReinforcedAt: fm.last_reinforced_at }\n : {}),\n status: fm.status ?? \"active\",\n ...(fm.derived_via !== undefined ? { derivedVia: fm.derived_via } : {}),\n canonicalContent: canonical.content.trim(),\n canonicalPath: canonical.path,\n derivedFrom,\n clusterMembers: members,\n };\n}\n\n// ───────────────────────────────────────────────────────────────────────────\n// Renderers\n// ───────────────────────────────────────────────────────────────────────────\n\nexport function renderPatternsList(\n rows: readonly PatternListRow[],\n format: PatternsOutputFormat,\n): string {\n if (format === \"json\") {\n return JSON.stringify({ rows }, null, 2);\n }\n if (rows.length === 0) {\n if (format === \"markdown\") {\n return \"# Pattern memories\\n\\n_No reinforced patterns found._\\n\";\n }\n return \"No reinforced patterns found.\";\n }\n if (format === \"markdown\") {\n const lines: string[] = [\"# Pattern memories\", \"\"];\n lines.push(\"| Count | ID | Category | Last reinforced | Preview |\");\n lines.push(\"| --- | --- | --- | --- | --- |\");\n for (const row of rows) {\n const last = row.lastReinforcedAt ?? \"—\";\n const preview = escapePipes(row.preview);\n lines.push(\n `| ${row.reinforcementCount} | \\`${row.id}\\` | ${row.category} | ${last} | ${preview} |`,\n );\n }\n return lines.join(\"\\n\") + \"\\n\";\n }\n // text\n const lines: string[] = [];\n lines.push(`Pattern memories (${rows.length}):`);\n lines.push(\"\");\n for (const row of rows) {\n const last = row.lastReinforcedAt ?? \"—\";\n lines.push(\n ` [${row.reinforcementCount}x] ${row.id} (${row.category}, last_reinforced=${last}, status=${row.status})`,\n );\n if (row.preview.length > 0) {\n lines.push(` ${row.preview}`);\n }\n lines.push(` path: ${row.path}`);\n }\n return lines.join(\"\\n\");\n}\n\nexport function renderPatternExplain(\n detail: PatternExplainDetail,\n format: PatternsOutputFormat,\n): string {\n if (format === \"json\") {\n return JSON.stringify(detail, null, 2);\n }\n const last = detail.lastReinforcedAt ?? \"—\";\n const derivedVia = detail.derivedVia ?? \"—\";\n if (format === \"markdown\") {\n const lines: string[] = [];\n lines.push(`# Pattern: \\`${detail.id}\\``);\n lines.push(\"\");\n lines.push(`- **Reinforcement count:** ${detail.reinforcementCount}`);\n lines.push(`- **Last reinforced:** ${last}`);\n lines.push(`- **Category:** ${detail.category}`);\n lines.push(`- **Status:** ${detail.status}`);\n lines.push(`- **Derived via:** ${derivedVia}`);\n lines.push(`- **Path:** \\`${detail.canonicalPath}\\``);\n lines.push(\"\");\n lines.push(\"## Canonical content\");\n lines.push(\"\");\n lines.push(\"```\");\n lines.push(detail.canonicalContent);\n lines.push(\"```\");\n lines.push(\"\");\n lines.push(`## Derived from (${detail.derivedFrom.length})`);\n lines.push(\"\");\n if (detail.derivedFrom.length === 0) {\n lines.push(\"_No derived_from entries recorded._\");\n } else {\n for (const entry of detail.derivedFrom) {\n const versionStr =\n entry.version !== null\n ? ` v${entry.version}`\n : entry.malformed\n ? \" (malformed)\"\n : \"\";\n lines.push(`- \\`${entry.path}\\`${versionStr}`);\n }\n }\n lines.push(\"\");\n lines.push(`## Cluster members (${detail.clusterMembers.length})`);\n lines.push(\"\");\n if (detail.clusterMembers.length === 0) {\n lines.push(\"_No superseded members reference this canonical._\");\n } else {\n for (const member of detail.clusterMembers) {\n const ts = member.supersededAt ?? \"—\";\n lines.push(`- \\`${member.id}\\` (status=${member.status}, supersededAt=${ts})`);\n if (member.preview.length > 0) {\n lines.push(` - ${escapePipes(member.preview)}`);\n }\n }\n }\n return lines.join(\"\\n\") + \"\\n\";\n }\n // text\n const lines: string[] = [];\n lines.push(`Pattern: ${detail.id}`);\n lines.push(` reinforcement_count: ${detail.reinforcementCount}`);\n lines.push(` last_reinforced_at: ${last}`);\n lines.push(` category: ${detail.category}`);\n lines.push(` status: ${detail.status}`);\n lines.push(` derived_via: ${derivedVia}`);\n lines.push(` path: ${detail.canonicalPath}`);\n lines.push(\"\");\n lines.push(\"Canonical content:\");\n for (const line of detail.canonicalContent.split(\"\\n\")) {\n lines.push(` ${line}`);\n }\n lines.push(\"\");\n lines.push(`Derived from (${detail.derivedFrom.length}):`);\n if (detail.derivedFrom.length === 0) {\n lines.push(\" (none)\");\n } else {\n for (const entry of detail.derivedFrom) {\n const versionStr =\n entry.version !== null\n ? ` v${entry.version}`\n : entry.malformed\n ? \" (malformed)\"\n : \"\";\n lines.push(` - ${entry.path}${versionStr}`);\n }\n }\n lines.push(\"\");\n lines.push(`Cluster members (${detail.clusterMembers.length}):`);\n if (detail.clusterMembers.length === 0) {\n lines.push(\" (none)\");\n } else {\n for (const member of detail.clusterMembers) {\n const ts = member.supersededAt ?? \"—\";\n lines.push(` - ${member.id} (status=${member.status}, supersededAt=${ts})`);\n if (member.preview.length > 0) {\n lines.push(` ${member.preview}`);\n }\n }\n }\n return lines.join(\"\\n\");\n}\n\n// ───────────────────────────────────────────────────────────────────────────\n// Internal helpers\n// ───────────────────────────────────────────────────────────────────────────\n\nfunction extractPreview(content: string): string {\n const trimmed = content.trim();\n if (trimmed.length === 0) return \"\";\n const firstLine = trimmed.split(\"\\n\").find((line) => line.trim().length > 0) ?? \"\";\n const collapsed = firstLine.trim().replace(/\\s+/g, \" \");\n if (collapsed.length <= 120) return collapsed;\n return collapsed.slice(0, 117) + \"...\";\n}\n\nfunction looksLikeDerivedFromPath(value: string): boolean {\n return value.includes(\"/\") || value.includes(\".\");\n}\n\n/**\n * Escape characters that would break a Markdown table cell:\n * - backslashes first (so the `\\|` escape below isn't double-escaped)\n * - then pipe characters\n *\n * CodeQL \"Incomplete string escaping or encoding\": backslash must be\n * escaped before pipe so that a literal `\\` in content isn't\n * misinterpreted as part of a `\\|` escape sequence.\n */\nfunction escapePipes(value: string): string {\n return value.replace(/\\\\/g, \"\\\\\\\\\").replace(/\\|/g, \"\\\\|\");\n}\n"],"mappings":"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","names":["lines"]}
@@ -205,11 +205,16 @@ function parseRollbackManifestEntry(raw, index) {
205
205
  if (raw.contentHash !== void 0 && (typeof raw.contentHash !== "string" || !/^[a-f0-9]{64}$/u.test(raw.contentHash))) {
206
206
  throw new Error(`rollback manifest entry ${index} has an invalid contentHash`);
207
207
  }
208
+ const rawMode = raw.mode;
209
+ if (rawMode !== void 0 && (typeof rawMode !== "number" || !Number.isInteger(rawMode) || rawMode < 0 || rawMode > 511)) {
210
+ throw new Error(`rollback manifest entry ${index} has an invalid mode`);
211
+ }
208
212
  return {
209
213
  targetPath: raw.targetPath,
210
214
  ...raw.backupPath === void 0 ? {} : { backupPath: raw.backupPath },
211
215
  ...raw.createdByMigration === void 0 ? {} : { createdByMigration: raw.createdByMigration },
212
- ...raw.contentHash === void 0 ? {} : { contentHash: raw.contentHash }
216
+ ...raw.contentHash === void 0 ? {} : { contentHash: raw.contentHash },
217
+ ...rawMode === void 0 ? {} : { mode: rawMode }
213
218
  };
214
219
  }
215
220
  function parseRollbackManifest(raw, manifestPath) {
@@ -350,7 +355,8 @@ async function validateRollbackManifestEntries(manifest, homeDir, options) {
350
355
  targetPath,
351
356
  ...backupPath === void 0 ? {} : { backupPath },
352
357
  ...entry.createdByMigration === void 0 ? {} : { createdByMigration: entry.createdByMigration },
353
- ...entry.contentHash === void 0 ? {} : { contentHash: entry.contentHash }
358
+ ...entry.contentHash === void 0 ? {} : { contentHash: entry.contentHash },
359
+ ...entry.mode === void 0 ? {} : { mode: entry.mode }
354
360
  });
355
361
  }
356
362
  return validated;
@@ -518,14 +524,14 @@ async function backupFile(targetPath, originalContent, homeDir, manifest, persis
518
524
  }
519
525
  const backupPath = connectorBackupPathForTarget(targetPath, homeDir);
520
526
  await ensureParent(backupPath);
527
+ const originalMode = isRemnicTokenStorePath(targetPath, homeDir) ? TOKEN_STORE_MODE : (await stat(targetPath)).mode & 511;
521
528
  if (isRemnicTokenStorePath(targetPath, homeDir)) {
522
529
  await writeOwnerOnlyFile(backupPath, originalContent);
523
530
  } else {
524
- const originalMode = (await stat(targetPath)).mode & 511;
525
531
  await writeFile(backupPath, originalContent, { encoding: "utf8", mode: originalMode });
526
532
  await chmod(backupPath, originalMode);
527
533
  }
528
- manifest.entries.push({ targetPath, backupPath });
534
+ manifest.entries.push({ targetPath, backupPath, mode: originalMode });
529
535
  await persistManifest?.();
530
536
  }
531
537
  async function recordCreatedPath(filePath, manifest, persistManifest) {
@@ -763,9 +769,8 @@ async function rollbackFromEngramMigration(options) {
763
769
  await assertExistingRegularFileNoFollow(entry.backupPath, "rollback manifest backup");
764
770
  await ensureParent(entry.targetPath);
765
771
  await copyFile(entry.backupPath, entry.targetPath);
766
- if (isRemnicTokenStorePath(entry.targetPath, homeDir)) {
767
- await secureTokenFilePermissions(entry.targetPath);
768
- }
772
+ const restoreMode = isRemnicTokenStorePath(entry.targetPath, homeDir) ? TOKEN_STORE_MODE : entry.mode ?? (await lstat(entry.backupPath)).mode & 511;
773
+ await chmod(entry.targetPath, restoreMode);
769
774
  restored.push(entry.targetPath);
770
775
  continue;
771
776
  }
@@ -879,4 +884,4 @@ export {
879
884
  rollbackFromEngramMigration,
880
885
  migrateFromEngram
881
886
  };
882
- //# sourceMappingURL=chunk-KVEVLBKC.js.map
887
+ //# sourceMappingURL=chunk-4HFJQCJZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/migrate/from-engram.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport path from \"node:path\";\nimport {\n chmod,\n copyFile,\n lstat,\n mkdir,\n open,\n readFile,\n readdir,\n rm,\n stat,\n unlink,\n writeFile,\n} from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { resolveHomeDir } from \"../runtime/env.js\";\nimport { launchProcessSync } from \"../runtime/child-process.js\";\n\nexport interface MigrationResult {\n status: \"fresh-install\" | \"already-migrated\" | \"migrated\";\n copied: string[];\n tokensRegenerated: number;\n servicesReinstalled: string[];\n rollbackCommand: string;\n}\n\ninterface RollbackManifestEntry {\n targetPath: string;\n backupPath?: string;\n createdByMigration?: boolean;\n contentHash?: string;\n mode?: number;\n}\n\ninterface RollbackManifest {\n version: 1;\n createdAt: string;\n entries: RollbackManifestEntry[];\n}\n\ninterface ValidatedRollbackManifestEntry extends RollbackManifestEntry {\n targetPath: string;\n backupPath?: string;\n contentHash?: string;\n mode?: number;\n}\n\nexport interface MigrationOptions {\n connectorConfigPaths?: string[];\n cwd?: string;\n execCommand?: (command: string, args: string[]) => void;\n homeDir?: string;\n logger?: (message: string) => void;\n platform?: NodeJS.Platform;\n quiet?: boolean;\n}\n\nexport interface RollbackResult {\n removed: string[];\n restored: string[];\n}\n\ninterface TokenEntry {\n connector: string;\n createdAt: string;\n token: string;\n}\n\ntype PersistRollbackManifest = () => Promise<void>;\n\nconst MARKER_FILE = \".migrated-from-engram\";\nconst LOCK_FILE = \".migration.lock\";\nconst ROLLBACK_MANIFEST = \".rollback.json\";\nconst BACKUP_DIR = \".backup\";\nconst LOCK_RETRY_MS = 100;\nconst LOCK_TIMEOUT_MS = 5_000;\nconst TOKEN_STORE_MODE = 0o600;\n\nfunction resolvePlatform(options?: MigrationOptions): NodeJS.Platform {\n return options?.platform ?? process.platform;\n}\n\nfunction resolveMigrationHome(options?: MigrationOptions): string {\n return options?.homeDir ?? resolveHomeDir();\n}\n\nfunction resolveLogger(options?: MigrationOptions): (message: string) => void {\n const sink = options?.logger ?? ((message: string) => console.log(message));\n return (message: string) => {\n if (!options?.quiet) sink(`[remnic] ${message}`);\n };\n}\n\nfunction resolveExec(options?: MigrationOptions): (command: string, args: string[]) => void {\n return options?.execCommand ?? ((command: string, args: string[]) => {\n const result = launchProcessSync(command, args, { stdio: \"ignore\" });\n if (result.error) {\n throw result.error;\n }\n if (result.status !== 0) {\n const reason = result.status === null\n ? `signal ${result.signal ?? \"unknown\"}`\n : `exit code ${result.status}`;\n throw new Error(`migration command failed: ${command} ${args.join(\" \")} (${reason})`);\n }\n });\n}\n\nfunction remnicRoot(homeDir: string): string {\n return path.join(homeDir, \".remnic\");\n}\n\nfunction legacyRoot(homeDir: string): string {\n return path.join(homeDir, \".engram\");\n}\n\nfunction legacyConfigPath(homeDir: string): string {\n return path.join(homeDir, \".config\", \"engram\", \"config.json\");\n}\n\nfunction remnicConfigPath(homeDir: string): string {\n return path.join(homeDir, \".config\", \"remnic\", \"config.json\");\n}\n\nfunction markerPath(homeDir: string): string {\n return path.join(remnicRoot(homeDir), MARKER_FILE);\n}\n\nfunction lockPath(homeDir: string): string {\n return path.join(remnicRoot(homeDir), LOCK_FILE);\n}\n\nfunction rollbackManifestPath(homeDir: string): string {\n return path.join(remnicRoot(homeDir), ROLLBACK_MANIFEST);\n}\n\nfunction backupRoot(homeDir: string): string {\n return path.join(remnicRoot(homeDir), BACKUP_DIR);\n}\n\nfunction defaultRollbackCommand(): string {\n return \"remnic migrate --rollback\";\n}\n\nfunction resolveMigrationCwd(options?: MigrationOptions): string {\n return path.resolve(options?.cwd ?? process.cwd());\n}\n\nfunction resolveConnectorConfigPath(candidate: string, cwd: string): string {\n return path.isAbsolute(candidate) ? path.resolve(candidate) : path.resolve(cwd, candidate);\n}\n\nasync function ensureParent(filePath: string): Promise<void> {\n await mkdir(path.dirname(filePath), { recursive: true });\n}\n\nasync function secureTokenFilePermissions(filePath: string): Promise<void> {\n await chmod(filePath, TOKEN_STORE_MODE);\n}\n\nasync function writeOwnerOnlyFile(filePath: string, content: string): Promise<void> {\n await writeFile(filePath, content, { encoding: \"utf8\", mode: TOKEN_STORE_MODE });\n await chmod(filePath, TOKEN_STORE_MODE);\n}\n\nasync function fileContentHash(filePath: string): Promise<string> {\n return createHash(\"sha256\").update(await readFile(filePath)).digest(\"hex\");\n}\n\nasync function writeTokenStoreFile(filePath: string, content: string): Promise<void> {\n await writeOwnerOnlyFile(filePath, content);\n}\n\nfunction isRemnicTokenStorePath(filePath: string, homeDir: string): boolean {\n return path.resolve(filePath) === path.resolve(path.join(remnicRoot(homeDir), \"tokens.json\"));\n}\n\nasync function pathExistsNoFollow(filePath: string): Promise<boolean> {\n try {\n await lstat(filePath);\n return true;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return false;\n throw error;\n }\n}\n\nasync function assertExistingRegularFileNoFollow(filePath: string, label: string): Promise<void> {\n const fileStat = await lstat(filePath);\n if (fileStat.isSymbolicLink()) {\n throw new Error(`${label} must not be a symlink: ${filePath}`);\n }\n if (!fileStat.isFile()) {\n throw new Error(`${label} must be a regular file: ${filePath}`);\n }\n}\n\nasync function isExistingRegularFileNoFollow(filePath: string): Promise<boolean> {\n try {\n const fileStat = await lstat(filePath);\n return fileStat.isFile() && !fileStat.isSymbolicLink();\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return false;\n throw error;\n }\n}\n\nasync function copyTreeMissing(\n source: string,\n destination: string,\n copied: string[],\n manifest: RollbackManifest,\n persistManifest?: PersistRollbackManifest,\n isRoot = true,\n): Promise<void> {\n if (!existsSync(source)) return;\n const sourceStat = await lstat(source);\n if (sourceStat.isSymbolicLink()) {\n if (isRoot) {\n throw new Error(`legacy migration root must not be a symlink: ${source}`);\n }\n return;\n }\n if (sourceStat.isDirectory()) {\n await mkdir(destination, { recursive: true });\n const entries = await readdir(source, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.name === MARKER_FILE || entry.name === LOCK_FILE || entry.name === ROLLBACK_MANIFEST) {\n continue;\n }\n await copyTreeMissing(\n path.join(source, entry.name),\n path.join(destination, entry.name),\n copied,\n manifest,\n persistManifest,\n false,\n );\n }\n return;\n }\n\n if (await pathExistsNoFollow(destination)) return;\n await ensureParent(destination);\n await copyFile(source, destination);\n await recordCreatedPath(destination, manifest, persistManifest);\n copied.push(destination);\n}\n\nfunction rewriteRemnicText(content: string): string {\n return content\n .replaceAll(\".engram/\", \".remnic/\")\n .replaceAll(\".engram\\\\\", \".remnic\\\\\")\n .replaceAll(\"ENGRAM_\", \"REMNIC_\")\n .replaceAll(\"{{ENGRAM_TOKEN}}\", \"{{REMNIC_TOKEN}}\")\n .replaceAll(\"${ENGRAM_AUTH_TOKEN}\", \"${REMNIC_AUTH_TOKEN}\")\n .replaceAll(\"ai.engram.daemon\", \"ai.remnic.daemon\")\n .replaceAll(\"engram.service\", \"remnic.service\");\n}\n\nfunction rewriteTokenValue(token: string): string {\n return token.startsWith(\"engram_\") ? `remnic_${token.slice(\"engram_\".length)}` : token;\n}\n\nfunction parseTokenEntries(raw: unknown): TokenEntry[] {\n if (typeof raw !== \"object\" || raw === null) return [];\n\n if (Array.isArray((raw as { tokens?: unknown }).tokens)) {\n return ((raw as { tokens: unknown[] }).tokens)\n .filter((entry): entry is TokenEntry => {\n if (typeof entry !== \"object\" || entry === null) return false;\n const candidate = entry as Partial<TokenEntry>;\n return typeof candidate.connector === \"string\" &&\n candidate.connector.length > 0 &&\n typeof candidate.token === \"string\" &&\n candidate.token.length > 0 &&\n typeof candidate.createdAt === \"string\" &&\n candidate.createdAt.length > 0;\n })\n .map((entry) => ({ ...entry }));\n }\n\n return Object.entries(raw)\n .filter(([key, value]) => key !== \"tokens\" && typeof value === \"string\" && value.length > 0)\n .map(([connector, token]) => ({\n connector,\n createdAt: new Date().toISOString(),\n token,\n }));\n}\n\nfunction isPlainJsonObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction parseRollbackManifestEntry(raw: unknown, index: number): RollbackManifestEntry {\n if (!isPlainJsonObject(raw)) {\n throw new Error(`rollback manifest entry ${index} must be an object`);\n }\n if (typeof raw.targetPath !== \"string\" || raw.targetPath.length === 0 || !path.isAbsolute(raw.targetPath)) {\n throw new Error(`rollback manifest entry ${index} has an invalid targetPath`);\n }\n if (raw.backupPath !== undefined && (typeof raw.backupPath !== \"string\" || raw.backupPath.length === 0 || !path.isAbsolute(raw.backupPath))) {\n throw new Error(`rollback manifest entry ${index} has an invalid backupPath`);\n }\n if (raw.createdByMigration !== undefined && typeof raw.createdByMigration !== \"boolean\") {\n throw new Error(`rollback manifest entry ${index} has an invalid createdByMigration flag`);\n }\n if (raw.contentHash !== undefined && (typeof raw.contentHash !== \"string\" || !/^[a-f0-9]{64}$/u.test(raw.contentHash))) {\n throw new Error(`rollback manifest entry ${index} has an invalid contentHash`);\n }\n const rawMode = raw.mode;\n if (\n rawMode !== undefined &&\n (typeof rawMode !== \"number\" || !Number.isInteger(rawMode) || rawMode < 0 || rawMode > 0o777)\n ) {\n throw new Error(`rollback manifest entry ${index} has an invalid mode`);\n }\n return {\n targetPath: raw.targetPath,\n ...(raw.backupPath === undefined ? {} : { backupPath: raw.backupPath }),\n ...(raw.createdByMigration === undefined ? {} : { createdByMigration: raw.createdByMigration }),\n ...(raw.contentHash === undefined ? {} : { contentHash: raw.contentHash }),\n ...(rawMode === undefined ? {} : { mode: rawMode }),\n };\n}\n\nfunction parseRollbackManifest(raw: unknown, manifestPath: string): RollbackManifest {\n if (!isPlainJsonObject(raw)) {\n throw new Error(`rollback manifest must be an object: ${manifestPath}`);\n }\n if (raw.version !== 1) {\n throw new Error(`rollback manifest has unsupported version: ${manifestPath}`);\n }\n if (typeof raw.createdAt !== \"string\") {\n throw new Error(`rollback manifest has an invalid createdAt: ${manifestPath}`);\n }\n if (!Array.isArray(raw.entries)) {\n throw new Error(`rollback manifest entries must be an array: ${manifestPath}`);\n }\n return {\n version: 1,\n createdAt: raw.createdAt,\n entries: raw.entries.map(parseRollbackManifestEntry),\n };\n}\n\nfunction isPathInside(parentPath: string, candidatePath: string): boolean {\n const relative = path.relative(path.resolve(parentPath), path.resolve(candidatePath));\n return relative === \"\" || (!relative.startsWith(\"..\") && !path.isAbsolute(relative));\n}\n\nfunction isPathDescendant(parentPath: string, candidatePath: string): boolean {\n const relative = path.relative(path.resolve(parentPath), path.resolve(candidatePath));\n return relative !== \"\" && !relative.startsWith(\"..\") && !path.isAbsolute(relative);\n}\n\nfunction hasConnectorConfigShape(targetPath: string, homeDir: string): boolean {\n const relative = path.relative(path.resolve(homeDir), path.resolve(targetPath));\n if (relative === \".claude.json\" || relative === path.join(\".claude\", \".mcp.json\")) {\n return true;\n }\n\n return hasRepoConnectorConfigShape(relative);\n}\n\nfunction hasRepoConnectorConfigShape(relativePath: string): boolean {\n const parts = relativePath.split(path.sep);\n const last = parts.at(-1);\n const packageName = parts.at(-2);\n const packagesDir = parts.at(-3);\n return last === \".mcp.json\" &&\n packagesDir === \"packages\" &&\n (packageName === \"plugin-claude-code\" || packageName === \"plugin-codex\");\n}\n\nfunction connectorBackupPathForTarget(targetPath: string, homeDir: string): string {\n const digest = createHash(\"sha256\").update(targetPath).digest(\"hex\").slice(0, 12);\n return path.join(backupRoot(homeDir), \"mcp\", `${digest}.json`);\n}\n\nfunction isRollbackTargetAllowed(\n entry: RollbackManifestEntry,\n targetPath: string,\n homeDir: string,\n options?: MigrationOptions,\n): boolean {\n const resolvedTarget = path.resolve(targetPath);\n if (isPathDescendant(remnicRoot(homeDir), resolvedTarget)) {\n if (entry.createdByMigration && !entry.backupPath) return true;\n return Boolean(entry.backupPath) && isRemnicTokenStorePath(resolvedTarget, homeDir);\n }\n if (isPathDescendant(path.join(homeDir, \".config\", \"remnic\"), resolvedTarget)) {\n return entry.createdByMigration === true && !entry.backupPath;\n }\n\n const serviceTargets = new Set([\n path.resolve(path.join(homeDir, \"Library\", \"LaunchAgents\", \"ai.remnic.daemon.plist\")),\n path.resolve(path.join(homeDir, \".config\", \"systemd\", \"user\", \"remnic.service\")),\n ]);\n if (serviceTargets.has(resolvedTarget)) return true;\n\n const cwd = resolveMigrationCwd(options);\n const allowedConnectorPaths = new Set(\n [\n ...defaultConnectorConfigPaths(homeDir, cwd),\n ...(options?.connectorConfigPaths ?? []),\n ].map((candidate) => resolveConnectorConfigPath(candidate, cwd)),\n );\n if (allowedConnectorPaths.has(resolvedTarget)) return true;\n\n return isPathInside(homeDir, resolvedTarget) && hasConnectorConfigShape(resolvedTarget, homeDir);\n}\n\nfunction isRollbackBackupAllowed(backupPath: string, homeDir: string): boolean {\n return isPathInside(backupRoot(homeDir), backupPath);\n}\n\nasync function assertNoSymlinkPathSegments(filePath: string, trustedRoot: string, label: string): Promise<void> {\n const resolvedPath = path.resolve(filePath);\n const resolvedRoot = path.resolve(trustedRoot);\n if (!isPathInside(resolvedRoot, resolvedPath)) {\n throw new Error(`${label} is outside the trusted rollback root: ${filePath}`);\n }\n const segments = path.relative(resolvedRoot, resolvedPath).split(path.sep).filter(Boolean);\n let current = resolvedRoot;\n\n for (const [index, segment] of segments.entries()) {\n current = path.join(current, segment);\n try {\n const currentStat = await lstat(current);\n if (currentStat.isSymbolicLink()) {\n throw new Error(`${label} must not contain symlink segments: ${filePath}`);\n }\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\" && index === segments.length - 1) return;\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n throw new Error(`${label} must not contain missing parent segments: ${filePath}`);\n }\n throw error;\n }\n }\n}\n\nfunction rollbackTargetSymlinkRoot(targetPath: string, homeDir: string, options?: MigrationOptions): string {\n if (isPathInside(homeDir, targetPath)) return homeDir;\n\n const cwd = resolveMigrationCwd(options);\n if (isPathInside(cwd, targetPath)) return cwd;\n\n return path.parse(targetPath).root;\n}\n\nasync function validateRollbackManifestEntries(\n manifest: RollbackManifest,\n homeDir: string,\n options?: MigrationOptions,\n): Promise<ValidatedRollbackManifestEntry[]> {\n const validated: ValidatedRollbackManifestEntry[] = [];\n\n for (const entry of manifest.entries) {\n const targetPath = path.resolve(entry.targetPath);\n if (!isRollbackTargetAllowed(entry, targetPath, homeDir, options)) {\n throw new Error(`rollback manifest target is outside migration-owned paths: ${entry.targetPath}`);\n }\n if (entry.backupPath && entry.createdByMigration) {\n throw new Error(`rollback manifest entry cannot restore and remove the same target: ${entry.targetPath}`);\n }\n const targetExists = await pathExistsNoFollow(targetPath);\n if (!entry.createdByMigration || targetExists) {\n const targetSymlinkRoot = rollbackTargetSymlinkRoot(targetPath, homeDir, options);\n await assertNoSymlinkPathSegments(targetPath, targetSymlinkRoot, \"rollback manifest target\");\n }\n if (entry.createdByMigration && targetExists) {\n await assertCreatedRollbackTargetMatchesRecord(entry, targetPath);\n }\n\n let backupPath: string | undefined;\n if (entry.backupPath) {\n backupPath = path.resolve(entry.backupPath);\n if (!isRollbackBackupAllowed(backupPath, homeDir)) {\n throw new Error(`rollback manifest backup is outside migration backup storage: ${entry.backupPath}`);\n }\n if (await pathExistsNoFollow(backupPath)) {\n await assertNoSymlinkPathSegments(backupPath, homeDir, \"rollback manifest backup\");\n await assertExistingRegularFileNoFollow(backupPath, \"rollback manifest backup\");\n }\n if (backupPath !== connectorBackupPathForTarget(targetPath, homeDir)) {\n throw new Error(`rollback manifest backup does not match target: ${entry.targetPath}`);\n }\n }\n\n validated.push({\n targetPath,\n ...(backupPath === undefined ? {} : { backupPath }),\n ...(entry.createdByMigration === undefined ? {} : { createdByMigration: entry.createdByMigration }),\n ...(entry.contentHash === undefined ? {} : { contentHash: entry.contentHash }),\n ...(entry.mode === undefined ? {} : { mode: entry.mode }),\n });\n }\n\n return validated;\n}\n\nasync function assertCreatedRollbackTargetMatchesRecord(\n entry: RollbackManifestEntry,\n targetPath: string,\n): Promise<boolean> {\n const targetStat = await lstat(targetPath);\n if (targetStat.isDirectory()) {\n throw new Error(`rollback manifest created target must be a file path: ${entry.targetPath}`);\n }\n if (!targetStat.isFile() || !entry.contentHash) return false;\n if (await fileContentHash(targetPath) !== entry.contentHash) {\n throw new Error(`rollback manifest created target content does not match migration record: ${entry.targetPath}`);\n }\n return true;\n}\n\nasync function rewriteTokensIfPresent(filePath: string): Promise<number> {\n if (!existsSync(filePath)) return 0;\n await assertExistingRegularFileNoFollow(filePath, \"Remnic token store\");\n await secureTokenFilePermissions(filePath);\n let raw: Record<string, unknown>;\n try {\n raw = JSON.parse(await readFile(filePath, \"utf8\")) as Record<string, unknown>;\n } catch {\n return 0;\n }\n let rewritten = 0;\n\n if (Array.isArray(raw.tokens)) {\n for (const entry of raw.tokens as Array<Record<string, unknown>>) {\n if (typeof entry.token === \"string\") {\n const next = rewriteTokenValue(entry.token);\n if (next !== entry.token) {\n entry.token = next;\n rewritten += 1;\n }\n }\n }\n } else {\n for (const [key, value] of Object.entries(raw)) {\n if (typeof value === \"string\") {\n const next = rewriteTokenValue(value);\n if (next !== value) {\n raw[key] = next;\n rewritten += 1;\n }\n }\n }\n }\n\n if (rewritten > 0) {\n await writeTokenStoreFile(filePath, `${JSON.stringify(raw, null, 2)}\\n`);\n }\n return rewritten;\n}\n\nasync function mergeLegacyTokens(\n legacyTokensPath: string,\n remnicTokensPath: string,\n homeDir: string,\n manifest: RollbackManifest,\n backupExisting: boolean,\n persistManifest?: PersistRollbackManifest,\n): Promise<number> {\n if (existsSync(legacyTokensPath)) {\n await assertExistingRegularFileNoFollow(legacyTokensPath, \"legacy Engram token store\");\n }\n if (!existsSync(remnicTokensPath)) return 0;\n await assertExistingRegularFileNoFollow(remnicTokensPath, \"Remnic token store\");\n await secureTokenFilePermissions(remnicTokensPath);\n if (!existsSync(legacyTokensPath)) return rewriteTokensIfPresent(remnicTokensPath);\n\n let remnicRaw: unknown;\n let legacyRaw: unknown;\n const originalRemnic = await readFile(remnicTokensPath, \"utf8\");\n\n try {\n remnicRaw = JSON.parse(originalRemnic) as unknown;\n legacyRaw = JSON.parse(await readFile(legacyTokensPath, \"utf8\")) as unknown;\n } catch {\n try {\n legacyRaw = JSON.parse(await readFile(legacyTokensPath, \"utf8\")) as unknown;\n } catch {\n return rewriteTokensIfPresent(remnicTokensPath);\n }\n\n const legacyEntries = parseTokenEntries(legacyRaw);\n let rewritten = 0;\n const recoveredEntries = legacyEntries.map((entry) => {\n const nextToken = rewriteTokenValue(entry.token);\n if (nextToken !== entry.token) rewritten += 1;\n return {\n ...entry,\n token: nextToken,\n };\n });\n\n if (backupExisting) {\n await backupFile(remnicTokensPath, originalRemnic, homeDir, manifest, persistManifest);\n }\n\n await writeTokenStoreFile(\n remnicTokensPath,\n `${JSON.stringify({ tokens: recoveredEntries }, null, 2)}\\n`,\n );\n return rewritten;\n }\n\n const mergedEntries = parseTokenEntries(remnicRaw);\n const legacyEntries = parseTokenEntries(legacyRaw);\n const existingConnectors = new Set(mergedEntries.map((entry) => entry.connector));\n let rewritten = 0;\n let changed = false;\n\n for (const entry of mergedEntries) {\n const nextToken = rewriteTokenValue(entry.token);\n if (nextToken !== entry.token) {\n entry.token = nextToken;\n rewritten += 1;\n changed = true;\n }\n }\n\n for (const entry of legacyEntries) {\n const nextToken = rewriteTokenValue(entry.token);\n if (nextToken !== entry.token) {\n rewritten += 1;\n }\n if (existingConnectors.has(entry.connector)) continue;\n mergedEntries.push({ ...entry, token: nextToken });\n existingConnectors.add(entry.connector);\n changed = true;\n }\n\n if (!changed) return rewritten;\n\n if (backupExisting) {\n await backupFile(remnicTokensPath, originalRemnic, homeDir, manifest, persistManifest);\n }\n\n await writeTokenStoreFile(\n remnicTokensPath,\n `${JSON.stringify({ tokens: mergedEntries }, null, 2)}\\n`,\n );\n return rewritten;\n}\n\nasync function rewriteJsonFile(\n targetPath: string,\n homeDir: string,\n manifest: RollbackManifest,\n persistManifest?: PersistRollbackManifest,\n): Promise<boolean> {\n if (!existsSync(targetPath)) return false;\n const targetStat = await lstat(targetPath);\n if (targetStat.isSymbolicLink()) return false;\n if (!targetStat.isFile()) {\n const error = new Error(`connector config must be a regular file: ${targetPath}`) as NodeJS.ErrnoException;\n error.code = targetStat.isDirectory() ? \"EISDIR\" : \"EINVAL\";\n throw error;\n }\n\n const original = await readFile(targetPath, \"utf8\");\n let parsed: unknown;\n try {\n parsed = JSON.parse(original) as unknown;\n } catch {\n return false;\n }\n if (!isPlainJsonObject(parsed)) return false;\n\n let changed = false;\n if (\n parsed.mcpServers &&\n typeof parsed.mcpServers === \"object\" &&\n !Array.isArray(parsed.mcpServers)\n ) {\n const servers = parsed.mcpServers as Record<string, unknown>;\n if (servers.engram && !servers.remnic) {\n servers.remnic = servers.engram;\n delete servers.engram;\n changed = true;\n }\n }\n\n const rewritten = rewriteRemnicText(JSON.stringify(parsed, null, 2));\n const next = `${rewritten}\\n`;\n if (!changed && next === original) return false;\n\n await backupFile(targetPath, original, homeDir, manifest, persistManifest);\n await writeFile(targetPath, next, \"utf8\");\n return true;\n}\n\nasync function backupFile(\n targetPath: string,\n originalContent: string,\n homeDir: string,\n manifest: RollbackManifest,\n persistManifest?: PersistRollbackManifest,\n): Promise<void> {\n if (manifest.entries.some((entry) => entry.targetPath === targetPath && entry.backupPath)) {\n return;\n }\n const backupPath = connectorBackupPathForTarget(targetPath, homeDir);\n await ensureParent(backupPath);\n const originalMode = isRemnicTokenStorePath(targetPath, homeDir)\n ? TOKEN_STORE_MODE\n : (await stat(targetPath)).mode & 0o777;\n if (isRemnicTokenStorePath(targetPath, homeDir)) {\n await writeOwnerOnlyFile(backupPath, originalContent);\n } else {\n await writeFile(backupPath, originalContent, { encoding: \"utf8\", mode: originalMode });\n await chmod(backupPath, originalMode);\n }\n manifest.entries.push({ targetPath, backupPath, mode: originalMode });\n await persistManifest?.();\n}\n\nasync function recordCreatedPath(\n filePath: string,\n manifest: RollbackManifest,\n persistManifest?: PersistRollbackManifest,\n): Promise<void> {\n if (manifest.entries.some((entry) => entry.targetPath === filePath)) return;\n manifest.entries.push({\n targetPath: filePath,\n createdByMigration: true,\n contentHash: await fileContentHash(filePath),\n });\n await persistManifest?.();\n}\n\nasync function refreshCreatedPathHash(\n filePath: string,\n manifest: RollbackManifest,\n persistManifest?: PersistRollbackManifest,\n): Promise<void> {\n const entry = manifest.entries.find((candidate) =>\n candidate.targetPath === filePath && candidate.createdByMigration\n );\n if (!entry) return;\n entry.contentHash = await fileContentHash(filePath);\n await persistManifest?.();\n}\n\nfunction defaultConnectorConfigPaths(homeDir: string, cwd: string): string[] {\n return [\n path.join(homeDir, \".claude.json\"),\n path.join(homeDir, \".claude\", \".mcp.json\"),\n path.join(cwd, \"packages\", \"plugin-claude-code\", \".mcp.json\"),\n path.join(cwd, \"packages\", \"plugin-codex\", \".mcp.json\"),\n ];\n}\n\nasync function updateConnectorConfigs(\n homeDir: string,\n cwd: string,\n options: MigrationOptions | undefined,\n manifest: RollbackManifest,\n persistManifest?: PersistRollbackManifest,\n): Promise<string[]> {\n const updated: string[] = [];\n const candidates = options?.connectorConfigPaths ?? defaultConnectorConfigPaths(homeDir, cwd);\n for (const targetPath of candidates) {\n const resolvedTarget = resolveConnectorConfigPath(targetPath, cwd);\n if (await rewriteJsonFile(resolvedTarget, homeDir, manifest, persistManifest)) {\n updated.push(resolvedTarget);\n }\n }\n return updated;\n}\n\nasync function copyLegacyConfig(\n homeDir: string,\n copied: string[],\n manifest: RollbackManifest,\n persistManifest?: PersistRollbackManifest,\n): Promise<void> {\n const source = legacyConfigPath(homeDir);\n const destination = remnicConfigPath(homeDir);\n if (!existsSync(source) || existsSync(destination)) return;\n if (!(await isExistingRegularFileNoFollow(source))) return;\n await ensureParent(destination);\n const original = await readFile(source, \"utf8\");\n let next = rewriteRemnicText(original);\n try {\n const parsed = JSON.parse(next) as unknown;\n if (isPlainJsonObject(parsed) && parsed.engram && !parsed.remnic) {\n parsed.remnic = parsed.engram;\n delete parsed.engram;\n next = JSON.stringify(parsed, null, 2);\n }\n } catch {\n // Keep rewritten text when config is not JSON.\n }\n await writeFile(destination, `${next.trimEnd()}\\n`, \"utf8\");\n await recordCreatedPath(destination, manifest, persistManifest);\n copied.push(destination);\n}\n\nfunction rewriteServiceText(content: string): string {\n return rewriteRemnicText(content);\n}\n\nasync function migrateServices(\n homeDir: string,\n options: MigrationOptions | undefined,\n manifest: RollbackManifest,\n persistManifest?: PersistRollbackManifest,\n): Promise<string[]> {\n const logger = resolveLogger(options);\n const exec = resolveExec(options);\n const servicesReinstalled: string[] = [];\n const platform = resolvePlatform(options);\n\n if (platform === \"darwin\") {\n const legacyPlist = path.join(homeDir, \"Library\", \"LaunchAgents\", \"ai.engram.daemon.plist\");\n const remnicPlist = path.join(homeDir, \"Library\", \"LaunchAgents\", \"ai.remnic.daemon.plist\");\n if (existsSync(legacyPlist) && !existsSync(remnicPlist)) {\n if (!(await isExistingRegularFileNoFollow(legacyPlist))) return servicesReinstalled;\n const next = rewriteServiceText(await readFile(legacyPlist, \"utf8\"));\n await ensureParent(remnicPlist);\n await writeFile(remnicPlist, next, \"utf8\");\n await recordCreatedPath(remnicPlist, manifest, persistManifest);\n try {\n exec(\"launchctl\", [\"unload\", legacyPlist]);\n } catch {\n // Keep migration fail-open when launchd rejects unload.\n }\n try {\n exec(\"launchctl\", [\"load\", \"-w\", remnicPlist]);\n } catch {\n // Keep migration fail-open when launchd rejects load.\n }\n servicesReinstalled.push(\"ai.remnic.daemon\");\n logger(\"launchd: ai.engram.daemon unloaded, ai.remnic.daemon installed\");\n }\n return servicesReinstalled;\n }\n\n if (platform === \"linux\") {\n const legacyUnit = path.join(homeDir, \".config\", \"systemd\", \"user\", \"engram.service\");\n const remnicUnit = path.join(homeDir, \".config\", \"systemd\", \"user\", \"remnic.service\");\n if (existsSync(legacyUnit) && !existsSync(remnicUnit)) {\n if (!(await isExistingRegularFileNoFollow(legacyUnit))) return servicesReinstalled;\n const next = rewriteServiceText(await readFile(legacyUnit, \"utf8\"));\n await ensureParent(remnicUnit);\n await writeFile(remnicUnit, next, \"utf8\");\n await recordCreatedPath(remnicUnit, manifest, persistManifest);\n try {\n exec(\"systemctl\", [\"--user\", \"stop\", \"engram.service\"]);\n exec(\"systemctl\", [\"--user\", \"disable\", \"engram.service\"]);\n exec(\"systemctl\", [\"--user\", \"daemon-reload\"]);\n exec(\"systemctl\", [\"--user\", \"enable\", \"remnic.service\"]);\n exec(\"systemctl\", [\"--user\", \"start\", \"remnic.service\"]);\n } catch {\n // Keep migration fail-open when systemd is unavailable.\n }\n servicesReinstalled.push(\"remnic.service\");\n logger(\"systemd: engram.service disabled, remnic.service installed\");\n }\n }\n\n return servicesReinstalled;\n}\n\nasync function writeRollbackManifest(homeDir: string, manifest: RollbackManifest): Promise<void> {\n await ensureParent(rollbackManifestPath(homeDir));\n await writeFile(\n rollbackManifestPath(homeDir),\n `${JSON.stringify(manifest, null, 2)}\\n`,\n \"utf8\",\n );\n}\n\nasync function readRollbackManifest(homeDir: string): Promise<RollbackManifest | null> {\n const target = rollbackManifestPath(homeDir);\n let targetStat: Awaited<ReturnType<typeof lstat>>;\n try {\n targetStat = await lstat(target);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return null;\n throw error;\n }\n if (targetStat.isSymbolicLink()) {\n throw new Error(`rollback manifest must not be a symlink: ${target}`);\n }\n if (!targetStat.isFile()) {\n throw new Error(`rollback manifest must be a regular file: ${target}`);\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(await readFile(target, \"utf8\")) as unknown;\n } catch {\n return null;\n }\n return parseRollbackManifest(parsed, target);\n}\n\nasync function acquireLock(homeDir: string): Promise<() => Promise<void>> {\n const target = lockPath(homeDir);\n await mkdir(remnicRoot(homeDir), { recursive: true });\n const started = Date.now();\n\n while (true) {\n try {\n const handle = await open(target, \"wx\");\n await handle.writeFile(`${process.pid}\\n${Date.now()}\\n`, \"utf8\");\n return async () => {\n try {\n await handle.close();\n } finally {\n await unlink(target).catch(() => undefined);\n }\n };\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code !== \"EEXIST\") throw error;\n\n const details = await readFile(target, \"utf8\").catch(() => null);\n if (details === null) {\n if (await removeLock(target)) continue;\n } else {\n const lines = details.split(\"\\n\");\n const pid = Number.parseInt(lines[0] ?? \"\", 10);\n const createdAt = Number.parseInt(lines[1] ?? \"\", 10);\n const malformed = !Number.isSafeInteger(pid) || pid <= 0 || !Number.isFinite(createdAt);\n const deadPid = !malformed && !processIsAlive(pid);\n if (malformed || deadPid) {\n if (await removeLockIfUnchanged(target, details)) continue;\n }\n }\n if (Date.now() - started > LOCK_TIMEOUT_MS) {\n throw new Error(`timed out waiting for migration lock: ${target}`);\n }\n await new Promise((resolve) => setTimeout(resolve, LOCK_RETRY_MS));\n }\n }\n}\n\nasync function removeLockIfUnchanged(target: string, expectedContent: string): Promise<boolean> {\n const current = await readFile(target, \"utf8\").catch(() => null);\n if (current !== expectedContent) return false;\n return removeLock(target);\n}\n\nasync function removeLock(target: string): Promise<boolean> {\n try {\n await rm(target, { force: true });\n return true;\n } catch {\n return false;\n }\n}\n\nfunction processIsAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"EPERM\") return true;\n return false;\n }\n}\n\nexport async function rollbackFromEngramMigration(options?: MigrationOptions): Promise<RollbackResult> {\n const homeDir = resolveMigrationHome(options);\n const manifest = await readRollbackManifest(homeDir);\n const exec = resolveExec(options);\n const platform = resolvePlatform(options);\n const restored: string[] = [];\n const removed: string[] = [];\n\n if (!manifest) return { restored, removed };\n const entries = await validateRollbackManifestEntries(manifest, homeDir, options);\n\n if (platform === \"darwin\") {\n const remnicPlist = path.join(homeDir, \"Library\", \"LaunchAgents\", \"ai.remnic.daemon.plist\");\n if (existsSync(remnicPlist)) {\n try {\n exec(\"launchctl\", [\"unload\", remnicPlist]);\n } catch {\n // Ignore launchctl rollback failures.\n }\n }\n } else if (platform === \"linux\") {\n try {\n exec(\"systemctl\", [\"--user\", \"stop\", \"remnic.service\"]);\n exec(\"systemctl\", [\"--user\", \"disable\", \"remnic.service\"]);\n } catch {\n // Ignore systemd rollback failures.\n }\n }\n\n for (const entry of [...entries].reverse()) {\n if (entry.backupPath && await pathExistsNoFollow(entry.backupPath)) {\n await assertNoSymlinkPathSegments(entry.backupPath, homeDir, \"rollback manifest backup\");\n await assertExistingRegularFileNoFollow(entry.backupPath, \"rollback manifest backup\");\n await ensureParent(entry.targetPath);\n await copyFile(entry.backupPath, entry.targetPath);\n const restoreMode = isRemnicTokenStorePath(entry.targetPath, homeDir)\n ? TOKEN_STORE_MODE\n : entry.mode ?? ((await lstat(entry.backupPath)).mode & 0o777);\n await chmod(entry.targetPath, restoreMode);\n restored.push(entry.targetPath);\n continue;\n }\n if (entry.createdByMigration && existsSync(entry.targetPath)) {\n const targetSymlinkRoot = rollbackTargetSymlinkRoot(entry.targetPath, homeDir, options);\n await assertNoSymlinkPathSegments(entry.targetPath, targetSymlinkRoot, \"rollback manifest target\");\n if (!await assertCreatedRollbackTargetMatchesRecord(entry, entry.targetPath)) continue;\n await rm(entry.targetPath, { recursive: true, force: true });\n removed.push(entry.targetPath);\n }\n }\n\n if (platform === \"linux\") {\n try {\n exec(\"systemctl\", [\"--user\", \"daemon-reload\"]);\n } catch {\n // Ignore systemd rollback failures after removing unit files.\n }\n }\n\n await rm(markerPath(homeDir), { force: true }).catch(() => undefined);\n await rm(rollbackManifestPath(homeDir), { force: true }).catch(() => undefined);\n return { restored, removed };\n}\n\nexport async function migrateFromEngram(options?: MigrationOptions): Promise<MigrationResult> {\n const homeDir = resolveMigrationHome(options);\n const cwd = resolveMigrationCwd(options);\n const logger = resolveLogger(options);\n const copied: string[] = [];\n let tokensRegenerated = 0;\n let servicesReinstalled: string[] = [];\n\n if (existsSync(markerPath(homeDir))) {\n return {\n status: \"already-migrated\",\n copied,\n tokensRegenerated,\n servicesReinstalled,\n rollbackCommand: defaultRollbackCommand(),\n };\n }\n\n const hasLegacyRoot = existsSync(legacyRoot(homeDir));\n const hasLegacyConfig = existsSync(legacyConfigPath(homeDir));\n if (!hasLegacyRoot && !hasLegacyConfig) {\n return {\n status: \"fresh-install\",\n copied,\n tokensRegenerated,\n servicesReinstalled,\n rollbackCommand: defaultRollbackCommand(),\n };\n }\n\n const releaseLock = await acquireLock(homeDir);\n try {\n if (existsSync(markerPath(homeDir))) {\n return {\n status: \"already-migrated\",\n copied,\n tokensRegenerated,\n servicesReinstalled,\n rollbackCommand: defaultRollbackCommand(),\n };\n }\n\n const manifest: RollbackManifest = await readRollbackManifest(homeDir) ?? {\n version: 1,\n createdAt: new Date().toISOString(),\n entries: [],\n };\n const persistManifest = () => writeRollbackManifest(homeDir, manifest);\n\n logger(\"First run after Engram -> Remnic rename. Migrating...\");\n await mkdir(remnicRoot(homeDir), { recursive: true });\n await persistManifest();\n await copyTreeMissing(legacyRoot(homeDir), remnicRoot(homeDir), copied, manifest, persistManifest);\n await copyLegacyConfig(homeDir, copied, manifest, persistManifest);\n\n const legacyTokens = path.join(legacyRoot(homeDir), \"tokens.json\");\n const remnicTokens = path.join(remnicRoot(homeDir), \"tokens.json\");\n if (copied.includes(remnicTokens)) {\n tokensRegenerated += await rewriteTokensIfPresent(remnicTokens);\n await refreshCreatedPathHash(remnicTokens, manifest, persistManifest);\n } else {\n tokensRegenerated += await mergeLegacyTokens(\n legacyTokens,\n remnicTokens,\n homeDir,\n manifest,\n true,\n persistManifest,\n );\n }\n if (existsSync(remnicTokens)) {\n logger(\"tokens copied to ~/.remnic/tokens.json (legacy prefixes rewritten)\");\n }\n\n const updatedConfigs = await updateConnectorConfigs(homeDir, cwd, options, manifest, persistManifest);\n for (const updated of updatedConfigs) {\n logger(`Updated connector config: ${updated}`);\n }\n\n servicesReinstalled = await migrateServices(homeDir, options, manifest, persistManifest);\n await writeRollbackManifest(homeDir, manifest);\n await writeFile(markerPath(homeDir), `${new Date().toISOString()}\\n`, \"utf8\");\n logger(\"Migration complete. Welcome to Remnic.\");\n\n return {\n status: \"migrated\",\n copied,\n tokensRegenerated,\n servicesReinstalled,\n rollbackCommand: defaultRollbackCommand(),\n };\n } finally {\n await releaseLock();\n }\n}\n"],"mappings":"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","names":["legacyEntries","rewritten"]}
@@ -23,4 +23,4 @@ export {
23
23
  confidenceTier,
24
24
  SPECULATIVE_TTL_DAYS
25
25
  };
26
- //# sourceMappingURL=chunk-KGK2QKWL.js.map
26
+ //# sourceMappingURL=chunk-4R4KTDIE.js.map