@remnic/core 1.1.12 → 1.1.14

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 (1324) hide show
  1. package/dist/access-cli.d.ts +2 -1
  2. package/dist/access-cli.js +263 -82
  3. package/dist/access-cli.js.map +1 -1
  4. package/dist/access-http.d.ts +26 -60
  5. package/dist/access-http.js +43 -29
  6. package/dist/access-mcp.d.ts +24 -6
  7. package/dist/access-mcp.js +35 -28
  8. package/dist/access-schema.d.ts +9 -6
  9. package/dist/access-schema.js +7 -5
  10. package/dist/access-service-DcCDmNYC.d.ts +1542 -0
  11. package/dist/access-service.d.ts +25 -7
  12. package/dist/access-service.js +33 -26
  13. package/dist/active-memory-bridge.js +2 -2
  14. package/dist/active-recall.js +11 -3
  15. package/dist/active-recall.js.map +1 -1
  16. package/dist/adapters/claude-code.d.ts +24 -0
  17. package/dist/adapters/claude-code.js +9 -0
  18. package/dist/adapters/codex.d.ts +25 -0
  19. package/dist/adapters/codex.js +9 -0
  20. package/dist/adapters/hermes.d.ts +35 -0
  21. package/dist/adapters/hermes.js +9 -0
  22. package/dist/adapters/index.d.ts +6 -0
  23. package/dist/adapters/index.js +26 -0
  24. package/dist/adapters/registry.d.ts +20 -0
  25. package/dist/adapters/registry.js +13 -0
  26. package/dist/adapters/replit.d.ts +28 -0
  27. package/dist/adapters/replit.js +9 -0
  28. package/dist/adapters/types.d.ts +43 -0
  29. package/dist/adapters/types.js +8 -0
  30. package/dist/bootstrap.d.ts +20 -5
  31. package/dist/boxes.d.ts +7 -0
  32. package/dist/boxes.js +1 -1
  33. package/dist/briefing.d.ts +5 -3
  34. package/dist/briefing.js +9 -6
  35. package/dist/buffer-surprise-report.js +1 -1
  36. package/dist/buffer.d.ts +18 -4
  37. package/dist/buffer.js +1 -1
  38. package/dist/calibration.js +4 -4
  39. package/dist/capsule-cli.d.ts +4 -4
  40. package/dist/capsule-cli.js +1 -1
  41. package/dist/capsule-crypto-5CYAGVC5.js +18 -0
  42. package/dist/capsule-merge-4MGKE7C5.js +189 -0
  43. package/dist/causal-behavior.d.ts +8 -28
  44. package/dist/causal-behavior.js +6 -3
  45. package/dist/causal-behavior.js.map +1 -1
  46. package/dist/causal-chain.js +3 -2
  47. package/dist/causal-consolidation.d.ts +1 -1
  48. package/dist/causal-consolidation.js +24 -13
  49. package/dist/causal-consolidation.js.map +1 -1
  50. package/dist/causal-retrieval.js +3 -3
  51. package/dist/causal-trajectory.js +1 -1
  52. package/dist/chunk-25MQ7IHJ.js +427 -0
  53. package/dist/chunk-25MQ7IHJ.js.map +1 -0
  54. package/dist/chunk-2F2W355T.js +256 -0
  55. package/dist/chunk-2F2W355T.js.map +1 -0
  56. package/dist/chunk-2KI4QFHU.js +228 -0
  57. package/dist/chunk-2KI4QFHU.js.map +1 -0
  58. package/dist/chunk-2PRQG7PV.js +86 -0
  59. package/dist/chunk-2PRQG7PV.js.map +1 -0
  60. package/dist/chunk-2QR3XXIC.js +2272 -0
  61. package/dist/chunk-2QR3XXIC.js.map +1 -0
  62. package/dist/chunk-2WWLHTZY.js +121 -0
  63. package/dist/chunk-326G7DJK.js +2185 -0
  64. package/dist/chunk-326G7DJK.js.map +1 -0
  65. package/dist/chunk-34DQE4KF.js +174 -0
  66. package/dist/chunk-34DQE4KF.js.map +1 -0
  67. package/dist/chunk-3APJ5EVB.js +601 -0
  68. package/dist/chunk-3APJ5EVB.js.map +1 -0
  69. package/dist/chunk-3HPAPHUK.js +51 -0
  70. package/dist/chunk-3HPAPHUK.js.map +1 -0
  71. package/dist/chunk-3JXBXXM2.js +69 -0
  72. package/dist/chunk-3JXBXXM2.js.map +1 -0
  73. package/dist/chunk-3KW65B36.js +681 -0
  74. package/dist/chunk-3KW65B36.js.map +1 -0
  75. package/dist/chunk-3UXOZBHV.js +20 -0
  76. package/dist/chunk-3UXOZBHV.js.map +1 -0
  77. package/dist/chunk-3VAL7ZL2.js +266 -0
  78. package/dist/chunk-3VAL7ZL2.js.map +1 -0
  79. package/dist/chunk-3Y4P7RXM.js +31 -0
  80. package/dist/chunk-3Y4P7RXM.js.map +1 -0
  81. package/dist/chunk-47VWKCAF.js +273 -0
  82. package/dist/chunk-47VWKCAF.js.map +1 -0
  83. package/dist/chunk-4CRG46BG.js +271 -0
  84. package/dist/chunk-5375UYTQ.js +914 -0
  85. package/dist/chunk-5375UYTQ.js.map +1 -0
  86. package/dist/chunk-56K5QLHX.js +506 -0
  87. package/dist/chunk-56K5QLHX.js.map +1 -0
  88. package/dist/chunk-5RGLBDQF.js +596 -0
  89. package/dist/chunk-5RGLBDQF.js.map +1 -0
  90. package/dist/chunk-5UZXUTVO.js +9 -0
  91. package/dist/chunk-5UZXUTVO.js.map +1 -0
  92. package/dist/chunk-65PG43EQ.js +105 -0
  93. package/dist/chunk-65PG43EQ.js.map +1 -0
  94. package/dist/chunk-66DHUKLO.js +57 -0
  95. package/dist/chunk-66DHUKLO.js.map +1 -0
  96. package/dist/chunk-6FC5EGNV.js +46 -0
  97. package/dist/chunk-6FC5EGNV.js.map +1 -0
  98. package/dist/chunk-6H2TESSP.js +62 -0
  99. package/dist/chunk-6H2TESSP.js.map +1 -0
  100. package/dist/chunk-6LVVDPJ4.js +32 -0
  101. package/dist/chunk-6LVVDPJ4.js.map +1 -0
  102. package/dist/chunk-6RVI47ZR.js +159 -0
  103. package/dist/chunk-6RVI47ZR.js.map +1 -0
  104. package/dist/chunk-7AAT6G4Q.js +5117 -0
  105. package/dist/chunk-7AAT6G4Q.js.map +1 -0
  106. package/dist/chunk-7DTASS5T.js +29 -0
  107. package/dist/chunk-7DTASS5T.js.map +1 -0
  108. package/dist/chunk-7IASACLB.js +596 -0
  109. package/dist/chunk-7MNMYOFP.js +32 -0
  110. package/dist/chunk-7MNMYOFP.js.map +1 -0
  111. package/dist/chunk-7N4KAIGN.js +133 -0
  112. package/dist/chunk-7N4KAIGN.js.map +1 -0
  113. package/dist/chunk-7OZ53EXP.js +101 -0
  114. package/dist/chunk-7OZ53EXP.js.map +1 -0
  115. package/dist/chunk-7XYTQGCC.js +134 -0
  116. package/dist/chunk-7XYTQGCC.js.map +1 -0
  117. package/dist/chunk-A2XUIMJ3.js +341 -0
  118. package/dist/chunk-A2XUIMJ3.js.map +1 -0
  119. package/dist/chunk-AGZQD76C.js +201 -0
  120. package/dist/chunk-AGZQD76C.js.map +1 -0
  121. package/dist/chunk-APO3DCMU.js +361 -0
  122. package/dist/chunk-APO3DCMU.js.map +1 -0
  123. package/dist/chunk-BFBF3XEF.js +283 -0
  124. package/dist/chunk-BFBF3XEF.js.map +1 -0
  125. package/dist/chunk-BJ3KMYTB.js +1974 -0
  126. package/dist/chunk-BJ3KMYTB.js.map +1 -0
  127. package/dist/chunk-CHEL3SKB.js +6758 -0
  128. package/dist/chunk-CHEL3SKB.js.map +1 -0
  129. package/dist/chunk-CQZRLNMV.js +1491 -0
  130. package/dist/chunk-CQZRLNMV.js.map +1 -0
  131. package/dist/chunk-D46YSIYX.js +892 -0
  132. package/dist/chunk-D46YSIYX.js.map +1 -0
  133. package/dist/chunk-DINWEURR.js +648 -0
  134. package/dist/chunk-DINWEURR.js.map +1 -0
  135. package/dist/chunk-DK5LDEQM.js +530 -0
  136. package/dist/chunk-DK5LDEQM.js.map +1 -0
  137. package/dist/chunk-DOM4GKSW.js +34 -0
  138. package/dist/chunk-DOM4GKSW.js.map +1 -0
  139. package/dist/chunk-EDTHC6UD.js +1075 -0
  140. package/dist/chunk-EFJ3MQ4V.js +721 -0
  141. package/dist/chunk-EHRTFRWW.js +89 -0
  142. package/dist/chunk-EHRTFRWW.js.map +1 -0
  143. package/dist/chunk-FAJ7FZYM.js +11 -0
  144. package/dist/chunk-FAJ7FZYM.js.map +1 -0
  145. package/dist/chunk-FBYESMQ2.js +570 -0
  146. package/dist/chunk-FDU6HUUL.js +147 -0
  147. package/dist/chunk-FF4KLI5W.js +99 -0
  148. package/dist/chunk-FF4KLI5W.js.map +1 -0
  149. package/dist/chunk-FIT6DMX6.js +310 -0
  150. package/dist/chunk-FIT6DMX6.js.map +1 -0
  151. package/dist/chunk-FJ43PRLT.js +272 -0
  152. package/dist/chunk-FJ43PRLT.js.map +1 -0
  153. package/dist/chunk-FKFMOY3N.js +32 -0
  154. package/dist/chunk-FKFMOY3N.js.map +1 -0
  155. package/dist/chunk-FLTNHQK6.js +262 -0
  156. package/dist/chunk-FLTNHQK6.js.map +1 -0
  157. package/dist/chunk-GA454ALV.js +12436 -0
  158. package/dist/chunk-GA454ALV.js.map +1 -0
  159. package/dist/chunk-GGKRUQOO.js +228 -0
  160. package/dist/chunk-GIF42EW3.js +63 -0
  161. package/dist/chunk-GIF42EW3.js.map +1 -0
  162. package/dist/chunk-GL6I6MEQ.js +647 -0
  163. package/dist/chunk-H3ME6L6D.js +709 -0
  164. package/dist/chunk-H3ME6L6D.js.map +1 -0
  165. package/dist/chunk-HHLLAQGZ.js +1 -0
  166. package/dist/chunk-HXXBL2KD.js +2040 -0
  167. package/dist/chunk-I5V2VDIW.js +219 -0
  168. package/dist/chunk-I5V2VDIW.js.map +1 -0
  169. package/dist/chunk-I6K5FBRQ.js +35 -0
  170. package/dist/chunk-I6K5FBRQ.js.map +1 -0
  171. package/dist/chunk-ICRIXAP2.js +121 -0
  172. package/dist/chunk-ICRIXAP2.js.map +1 -0
  173. package/dist/chunk-J4EB7DNW.js +11 -0
  174. package/dist/chunk-J4EB7DNW.js.map +1 -0
  175. package/dist/chunk-JLFA7DQG.js +62 -0
  176. package/dist/chunk-JLFA7DQG.js.map +1 -0
  177. package/dist/chunk-KJTKLXTH.js +9 -0
  178. package/dist/chunk-KJTKLXTH.js.map +1 -0
  179. package/dist/chunk-KLAO5DGL.js +917 -0
  180. package/dist/chunk-KLAO5DGL.js.map +1 -0
  181. package/dist/chunk-KNKUID7G.js +183 -0
  182. package/dist/chunk-KOSORCJG.js +624 -0
  183. package/dist/chunk-KOSORCJG.js.map +1 -0
  184. package/dist/chunk-KUJVMMZQ.js +1262 -0
  185. package/dist/chunk-KUJVMMZQ.js.map +1 -0
  186. package/dist/chunk-LCR46JY5.js +123 -0
  187. package/dist/chunk-LCR46JY5.js.map +1 -0
  188. package/dist/chunk-LLQ2LLWF.js +148 -0
  189. package/dist/chunk-LLQ2LLWF.js.map +1 -0
  190. package/dist/chunk-LPMVBPA3.js +236 -0
  191. package/dist/chunk-LT3NLYSI.js +50 -0
  192. package/dist/chunk-LT3NLYSI.js.map +1 -0
  193. package/dist/chunk-LUDTDZLK.js +287 -0
  194. package/dist/chunk-LUDTDZLK.js.map +1 -0
  195. package/dist/chunk-M23FSH32.js +3963 -0
  196. package/dist/chunk-M23FSH32.js.map +1 -0
  197. package/dist/chunk-MC26UJIM.js +118 -0
  198. package/dist/chunk-ME6ESPZU.js +119 -0
  199. package/dist/chunk-ME6ESPZU.js.map +1 -0
  200. package/dist/chunk-MGKYQQYF.js +272 -0
  201. package/dist/chunk-MJFNCJXV.js +66 -0
  202. package/dist/chunk-MJFNCJXV.js.map +1 -0
  203. package/dist/chunk-MSWG7JI6.js +237 -0
  204. package/dist/chunk-MSWG7JI6.js.map +1 -0
  205. package/dist/chunk-MT25YHYH.js +141 -0
  206. package/dist/chunk-MT25YHYH.js.map +1 -0
  207. package/dist/chunk-MT4HVDUZ.js +53 -0
  208. package/dist/chunk-MY6TPVXW.js +219 -0
  209. package/dist/chunk-N2D6GXBM.js +267 -0
  210. package/dist/chunk-N2D6GXBM.js.map +1 -0
  211. package/dist/chunk-NJ3MJQZX.js +46 -0
  212. package/dist/chunk-NJ3MJQZX.js.map +1 -0
  213. package/dist/chunk-NMZY542O.js +335 -0
  214. package/dist/chunk-NMZY542O.js.map +1 -0
  215. package/dist/chunk-NNVTUXEB.js +23 -0
  216. package/dist/chunk-NZL6GGQE.js +375 -0
  217. package/dist/chunk-NZL6GGQE.js.map +1 -0
  218. package/dist/chunk-P4NEIHUT.js +108 -0
  219. package/dist/chunk-P7FMDTKL.js +103 -0
  220. package/dist/chunk-P7FMDTKL.js.map +1 -0
  221. package/dist/chunk-PHK3HARR.js +32 -0
  222. package/dist/chunk-PHK3HARR.js.map +1 -0
  223. package/dist/chunk-PIRJPV5T.js +98 -0
  224. package/dist/chunk-PIRJPV5T.js.map +1 -0
  225. package/dist/chunk-PK7H5L6Y.js +159 -0
  226. package/dist/chunk-PK7H5L6Y.js.map +1 -0
  227. package/dist/chunk-PR5FBTFU.js +233 -0
  228. package/dist/chunk-PR5FBTFU.js.map +1 -0
  229. package/dist/chunk-PU63GXWS.js +174 -0
  230. package/dist/chunk-PU63GXWS.js.map +1 -0
  231. package/dist/chunk-PZIAX57I.js +124 -0
  232. package/dist/chunk-PZIAX57I.js.map +1 -0
  233. package/dist/chunk-Q7P4WJDP.js +26 -0
  234. package/dist/chunk-Q7P4WJDP.js.map +1 -0
  235. package/dist/chunk-QQUAB63I.js +63 -0
  236. package/dist/chunk-QQUAB63I.js.map +1 -0
  237. package/dist/chunk-QRNI5JBH.js +18 -0
  238. package/dist/chunk-RHY3HH7P.js +601 -0
  239. package/dist/chunk-RHY3HH7P.js.map +1 -0
  240. package/dist/chunk-RRF5UOBJ.js +91 -0
  241. package/dist/chunk-RXDLTSWT.js +124 -0
  242. package/dist/chunk-RXDLTSWT.js.map +1 -0
  243. package/dist/chunk-RYED3SPJ.js +42 -0
  244. package/dist/chunk-RYED3SPJ.js.map +1 -0
  245. package/dist/chunk-S7KDBTWT.js +106 -0
  246. package/dist/chunk-S7KDBTWT.js.map +1 -0
  247. package/dist/chunk-SEDEKFYQ.js +1 -0
  248. package/dist/chunk-TECVW3JP.js +36 -0
  249. package/dist/chunk-TECVW3JP.js.map +1 -0
  250. package/dist/chunk-TFO23QT4.js +88 -0
  251. package/dist/chunk-TFO23QT4.js.map +1 -0
  252. package/dist/chunk-TK4UEOSK.js +76 -0
  253. package/dist/chunk-TK4UEOSK.js.map +1 -0
  254. package/dist/chunk-TKWGAOLV.js +122 -0
  255. package/dist/chunk-TKWGAOLV.js.map +1 -0
  256. package/dist/chunk-TMM4S4IJ.js +597 -0
  257. package/dist/chunk-TMM4S4IJ.js.map +1 -0
  258. package/dist/chunk-TMQLARTH.js +188 -0
  259. package/dist/chunk-TMQLARTH.js.map +1 -0
  260. package/dist/chunk-TPDBFYEG.js +130 -0
  261. package/dist/chunk-TPDBFYEG.js.map +1 -0
  262. package/dist/chunk-TPMQ3G6Z.js +145 -0
  263. package/dist/chunk-TPMQ3G6Z.js.map +1 -0
  264. package/dist/chunk-TZOLIGIG.js +61 -0
  265. package/dist/chunk-TZOLIGIG.js.map +1 -0
  266. package/dist/chunk-U3PN77QT.js +113 -0
  267. package/dist/chunk-U3WSW6PZ.js +277 -0
  268. package/dist/chunk-U4SCL7B7.js +640 -0
  269. package/dist/chunk-U4SCL7B7.js.map +1 -0
  270. package/dist/chunk-UWK5OXUJ.js +156 -0
  271. package/dist/chunk-UWK5OXUJ.js.map +1 -0
  272. package/dist/chunk-UWVJF25J.js +74 -0
  273. package/dist/chunk-UXHQAFNA.js +1317 -0
  274. package/dist/chunk-UXHQAFNA.js.map +1 -0
  275. package/dist/chunk-V5OCT34X.js +1 -0
  276. package/dist/chunk-VLXA6PI2.js +304 -0
  277. package/dist/chunk-VLXA6PI2.js.map +1 -0
  278. package/dist/chunk-VNO6ZJ35.js +500 -0
  279. package/dist/chunk-VNO6ZJ35.js.map +1 -0
  280. package/dist/chunk-VW676BEI.js +827 -0
  281. package/dist/chunk-VW676BEI.js.map +1 -0
  282. package/dist/chunk-W3LR522O.js +2296 -0
  283. package/dist/chunk-W4L6CZKA.js +96 -0
  284. package/dist/chunk-W4L6CZKA.js.map +1 -0
  285. package/dist/chunk-W4RVMTHR.js +372 -0
  286. package/dist/chunk-W4RVMTHR.js.map +1 -0
  287. package/dist/chunk-WEHSQBFR.js +188 -0
  288. package/dist/chunk-WEHSQBFR.js.map +1 -0
  289. package/dist/chunk-WELDCG6C.js +380 -0
  290. package/dist/chunk-WELDCG6C.js.map +1 -0
  291. package/dist/chunk-WZYKANL3.js +2800 -0
  292. package/dist/chunk-WZYKANL3.js.map +1 -0
  293. package/dist/chunk-XIG5PDM7.js +48 -0
  294. package/dist/chunk-XJNBEDFE.js +193 -0
  295. package/dist/chunk-XJNBEDFE.js.map +1 -0
  296. package/dist/chunk-XVVIG67A.js +291 -0
  297. package/dist/chunk-XVVIG67A.js.map +1 -0
  298. package/dist/chunk-XVZ7B3HG.js +135 -0
  299. package/dist/chunk-YBPYIAA5.js +73 -0
  300. package/dist/chunk-YBPYIAA5.js.map +1 -0
  301. package/dist/chunk-Z734BLO3.js +21 -0
  302. package/dist/chunk-Z734BLO3.js.map +1 -0
  303. package/dist/chunk-ZKSK55RC.js +269 -0
  304. package/dist/chunk-ZKSK55RC.js.map +1 -0
  305. package/dist/chunk-ZTFCYYEZ.js +69 -0
  306. package/dist/chunk-ZTFCYYEZ.js.map +1 -0
  307. package/dist/chunk-ZY2MNJR6.js +329 -0
  308. package/dist/chunk-ZY2MNJR6.js.map +1 -0
  309. package/dist/cli-D3VpkVwB.d.ts +1136 -0
  310. package/dist/cli.d.ts +39 -10
  311. package/dist/cli.js +108 -49
  312. package/dist/commitment-ledger.js +1 -1
  313. package/dist/compat/checks.d.ts +5 -0
  314. package/dist/compat/checks.js +11 -0
  315. package/dist/compat/checks.js.map +1 -0
  316. package/dist/compat/types.d.ts +30 -0
  317. package/dist/compat/types.js +1 -0
  318. package/dist/compat/types.js.map +1 -0
  319. package/dist/compounding/engine.d.ts +221 -0
  320. package/dist/compounding/engine.js +32 -0
  321. package/dist/compounding/engine.js.map +1 -0
  322. package/dist/compounding/preference-consolidator.d.ts +92 -0
  323. package/dist/compounding/preference-consolidator.js +553 -0
  324. package/dist/compounding/preference-consolidator.js.map +1 -0
  325. package/dist/config.d.ts +4 -2
  326. package/dist/config.js +9 -4
  327. package/dist/conflict-policy-DyJ2wd-h.d.ts +4 -0
  328. package/dist/connectors/codex-materialize-runner.d.ts +64 -0
  329. package/dist/connectors/codex-materialize-runner.js +33 -0
  330. package/dist/connectors/codex-materialize-runner.js.map +1 -0
  331. package/dist/connectors/codex-materialize.d.ts +195 -0
  332. package/dist/connectors/codex-materialize.js +38 -0
  333. package/dist/connectors/codex-materialize.js.map +1 -0
  334. package/dist/connectors/index.d.ts +444 -0
  335. package/dist/connectors/index.js +115 -0
  336. package/dist/connectors/index.js.map +1 -0
  337. package/dist/connectors-cli-CwbyjGR7.d.ts +257 -0
  338. package/dist/connectors-cli.d.ts +1 -1
  339. package/dist/consolidation-provenance-check.d.ts +3 -1
  340. package/dist/consolidation-undo.d.ts +3 -1
  341. package/dist/contradiction/index.d.ts +258 -0
  342. package/dist/contradiction/index.js +43 -0
  343. package/dist/contradiction/index.js.map +1 -0
  344. package/dist/contradiction-review-ATP4S6IC.js +30 -0
  345. package/dist/contradiction-review-ATP4S6IC.js.map +1 -0
  346. package/dist/contradiction-scan-5A4IDZV5.js +13 -0
  347. package/dist/contradiction-scan-5A4IDZV5.js.map +1 -0
  348. package/dist/conversation-index/backend.d.ts +97 -0
  349. package/dist/conversation-index/backend.js +13 -0
  350. package/dist/conversation-index/backend.js.map +1 -0
  351. package/dist/conversation-index/chunker.d.ts +16 -0
  352. package/dist/conversation-index/chunker.js +8 -0
  353. package/dist/conversation-index/chunker.js.map +1 -0
  354. package/dist/conversation-index/cleanup.d.ts +11 -0
  355. package/dist/conversation-index/cleanup.js +9 -0
  356. package/dist/conversation-index/cleanup.js.map +1 -0
  357. package/dist/conversation-index/faiss-adapter.d.ts +6 -0
  358. package/dist/conversation-index/faiss-adapter.js +16 -0
  359. package/dist/conversation-index/faiss-adapter.js.map +1 -0
  360. package/dist/conversation-index/indexer.d.ts +23 -0
  361. package/dist/conversation-index/indexer.js +15 -0
  362. package/dist/conversation-index/indexer.js.map +1 -0
  363. package/dist/conversation-index/search.d.ts +6 -0
  364. package/dist/conversation-index/search.js +11 -0
  365. package/dist/conversation-index/search.js.map +1 -0
  366. package/dist/embedding-fallback.js +2 -2
  367. package/dist/enrichment/index.d.ts +163 -0
  368. package/dist/enrichment/index.js +18 -0
  369. package/dist/enrichment/index.js.map +1 -0
  370. package/dist/entity-retrieval.d.ts +4 -2
  371. package/dist/entity-retrieval.js +8 -5
  372. package/dist/evals.js +1 -1
  373. package/dist/explicit-capture.d.ts +20 -5
  374. package/dist/explicit-capture.js +2 -2
  375. package/dist/extraction-judge-training.js +1 -1
  376. package/dist/extraction.js +8 -8
  377. package/dist/faiss-adapter-CzPghc4C.d.ts +70 -0
  378. package/dist/fallback-llm.d.ts +2 -0
  379. package/dist/fallback-llm.js +4 -4
  380. package/dist/graph-edge-decay-5DI5GUNL.js +207 -0
  381. package/dist/index.d.ts +66 -711
  382. package/dist/index.js +556 -2680
  383. package/dist/index.js.map +1 -1
  384. package/dist/lcm/archive.d.ts +89 -0
  385. package/dist/lcm/archive.js +12 -0
  386. package/dist/lcm/archive.js.map +1 -0
  387. package/dist/lcm/dag.d.ts +48 -0
  388. package/dist/lcm/dag.js +8 -0
  389. package/dist/lcm/dag.js.map +1 -0
  390. package/dist/lcm/engine.d.ts +116 -0
  391. package/dist/lcm/engine.js +20 -0
  392. package/dist/lcm/engine.js.map +1 -0
  393. package/dist/lcm/index.d.ts +12 -0
  394. package/dist/lcm/index.js +44 -0
  395. package/dist/lcm/index.js.map +1 -0
  396. package/dist/lcm/queue.d.ts +62 -0
  397. package/dist/lcm/queue.js +8 -0
  398. package/dist/lcm/queue.js.map +1 -0
  399. package/dist/lcm/recall.d.ts +20 -0
  400. package/dist/lcm/recall.js +8 -0
  401. package/dist/lcm/recall.js.map +1 -0
  402. package/dist/lcm/schema.d.ts +16 -0
  403. package/dist/lcm/schema.js +14 -0
  404. package/dist/lcm/schema.js.map +1 -0
  405. package/dist/lcm/summarizer.d.ts +38 -0
  406. package/dist/lcm/summarizer.js +12 -0
  407. package/dist/lcm/summarizer.js.map +1 -0
  408. package/dist/lcm/tools.d.ts +29 -0
  409. package/dist/lcm/tools.js +8 -0
  410. package/dist/lcm/tools.js.map +1 -0
  411. package/dist/live-connectors-runner.js +5 -5
  412. package/dist/local-llm.js +3 -3
  413. package/dist/maintenance/archive-observations.d.ts +18 -0
  414. package/dist/maintenance/archive-observations.js +8 -0
  415. package/dist/maintenance/archive-observations.js.map +1 -0
  416. package/dist/maintenance/backup-stamp.d.ts +3 -0
  417. package/dist/maintenance/backup-stamp.js +8 -0
  418. package/dist/maintenance/backup-stamp.js.map +1 -0
  419. package/dist/maintenance/memory-governance-cron.d.ts +85 -0
  420. package/dist/maintenance/memory-governance-cron.js +22 -0
  421. package/dist/maintenance/memory-governance-cron.js.map +1 -0
  422. package/dist/maintenance/memory-governance.d.ts +137 -0
  423. package/dist/maintenance/memory-governance.js +40 -0
  424. package/dist/maintenance/memory-governance.js.map +1 -0
  425. package/dist/maintenance/migrate-observations.d.ts +18 -0
  426. package/dist/maintenance/migrate-observations.js +9 -0
  427. package/dist/maintenance/migrate-observations.js.map +1 -0
  428. package/dist/maintenance/observation-ledger-utils.d.ts +10 -0
  429. package/dist/maintenance/observation-ledger-utils.js +10 -0
  430. package/dist/maintenance/observation-ledger-utils.js.map +1 -0
  431. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +15 -0
  432. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +28 -0
  433. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js.map +1 -0
  434. package/dist/maintenance/rebuild-memory-projection.d.ts +77 -0
  435. package/dist/maintenance/rebuild-memory-projection.js +35 -0
  436. package/dist/maintenance/rebuild-memory-projection.js.map +1 -0
  437. package/dist/maintenance/rebuild-observations.d.ts +17 -0
  438. package/dist/maintenance/rebuild-observations.js +9 -0
  439. package/dist/maintenance/rebuild-observations.js.map +1 -0
  440. package/dist/mcp-memory-inspector-app.d.ts +24 -6
  441. package/dist/memory-projection-store.d.ts +108 -3
  442. package/dist/memory-projection-store.js +2 -1
  443. package/dist/memory-worth-outcomes.d.ts +4 -2
  444. package/dist/migrate/from-engram.d.ts +24 -0
  445. package/dist/migrate/from-engram.js +12 -0
  446. package/dist/migrate/from-engram.js.map +1 -0
  447. package/dist/namespaces/migrate.d.ts +50 -0
  448. package/dist/namespaces/migrate.js +50 -0
  449. package/dist/namespaces/migrate.js.map +1 -0
  450. package/dist/namespaces/principal.d.ts +17 -0
  451. package/dist/namespaces/principal.js +16 -0
  452. package/dist/namespaces/principal.js.map +1 -0
  453. package/dist/namespaces/search.d.ts +46 -0
  454. package/dist/namespaces/search.js +28 -0
  455. package/dist/namespaces/search.js.map +1 -0
  456. package/dist/namespaces/storage.d.ts +32 -0
  457. package/dist/namespaces/storage.js +28 -0
  458. package/dist/namespaces/storage.js.map +1 -0
  459. package/dist/network/tailscale.d.ts +41 -0
  460. package/dist/network/tailscale.js +9 -0
  461. package/dist/network/tailscale.js.map +1 -0
  462. package/dist/network/webdav.d.ts +39 -0
  463. package/dist/network/webdav.js +10 -0
  464. package/dist/network/webdav.js.map +1 -0
  465. package/dist/objective-state-writers.js +2 -2
  466. package/dist/operator-toolkit.d.ts +4 -2
  467. package/dist/operator-toolkit.js +32 -14
  468. package/dist/opik-exporter.js +2 -2
  469. package/dist/opik-exporter.js.map +1 -1
  470. package/dist/orchestrator-DuWl9Hwx.d.ts +1244 -0
  471. package/dist/orchestrator.d.ts +22 -7
  472. package/dist/orchestrator.js +79 -44
  473. package/dist/path-MR5JPYOP.js +9 -0
  474. package/dist/path-MR5JPYOP.js.map +1 -0
  475. package/dist/qmd-recall-cache.d.ts +1 -1
  476. package/dist/qmd.d.ts +102 -3
  477. package/dist/qmd.js +23 -5
  478. package/dist/recall-explain-renderer.js +3 -3
  479. package/dist/recall-xray-cli.js +4 -4
  480. package/dist/recall-xray-renderer.js +3 -3
  481. package/dist/recall-xray.js +2 -2
  482. package/dist/replay/normalizers/chatgpt.d.ts +6 -0
  483. package/dist/replay/normalizers/chatgpt.js +11 -0
  484. package/dist/replay/normalizers/chatgpt.js.map +1 -0
  485. package/dist/replay/normalizers/claude.d.ts +6 -0
  486. package/dist/replay/normalizers/claude.js +11 -0
  487. package/dist/replay/normalizers/claude.js.map +1 -0
  488. package/dist/replay/normalizers/openclaw.d.ts +6 -0
  489. package/dist/replay/normalizers/openclaw.js +11 -0
  490. package/dist/replay/normalizers/openclaw.js.map +1 -0
  491. package/dist/replay/normalizers/shared.d.ts +16 -0
  492. package/dist/replay/normalizers/shared.js +14 -0
  493. package/dist/replay/normalizers/shared.js.map +1 -0
  494. package/dist/replay/runner.d.ts +35 -0
  495. package/dist/replay/runner.js +16 -0
  496. package/dist/replay/runner.js.map +1 -0
  497. package/dist/replay/types.d.ts +57 -0
  498. package/dist/replay/types.js +19 -0
  499. package/dist/replay/types.js.map +1 -0
  500. package/dist/resolution-B7FNQSSP.js +12 -0
  501. package/dist/resolution-B7FNQSSP.js.map +1 -0
  502. package/dist/resolve-provider-secret.js +2 -2
  503. package/dist/resume-bundles.js +8 -6
  504. package/dist/retrieval-agents.d.ts +1 -1
  505. package/dist/routing/engine.d.ts +35 -0
  506. package/dist/routing/engine.js +16 -0
  507. package/dist/routing/engine.js.map +1 -0
  508. package/dist/routing/store.d.ts +27 -0
  509. package/dist/routing/store.js +10 -0
  510. package/dist/routing/store.js.map +1 -0
  511. package/dist/runtime/better-sqlite.d.ts +8 -0
  512. package/dist/runtime/better-sqlite.js +10 -0
  513. package/dist/runtime/better-sqlite.js.map +1 -0
  514. package/dist/runtime/child-process.d.ts +32 -0
  515. package/dist/runtime/child-process.js +10 -0
  516. package/dist/runtime/child-process.js.map +1 -0
  517. package/dist/runtime/env.d.ts +5 -0
  518. package/dist/runtime/env.js +12 -0
  519. package/dist/runtime/env.js.map +1 -0
  520. package/dist/schemas.d.ts +22 -22
  521. package/dist/sdk-compat.js +1 -1
  522. package/dist/search/document-scanner.d.ts +22 -0
  523. package/dist/search/document-scanner.js +8 -0
  524. package/dist/search/document-scanner.js.map +1 -0
  525. package/dist/search/embed-helper.d.ts +35 -0
  526. package/dist/search/embed-helper.js +9 -0
  527. package/dist/search/embed-helper.js.map +1 -0
  528. package/dist/search/factory.d.ts +32 -0
  529. package/dist/search/factory.js +29 -0
  530. package/dist/search/factory.js.map +1 -0
  531. package/dist/search/index.d.ts +15 -0
  532. package/dist/search/index.js +50 -0
  533. package/dist/search/index.js.map +1 -0
  534. package/dist/search/lancedb-backend.d.ts +51 -0
  535. package/dist/search/lancedb-backend.js +10 -0
  536. package/dist/search/lancedb-backend.js.map +1 -0
  537. package/dist/search/meilisearch-backend.d.ts +48 -0
  538. package/dist/search/meilisearch-backend.js +10 -0
  539. package/dist/search/meilisearch-backend.js.map +1 -0
  540. package/dist/search/noop-backend.d.ts +26 -0
  541. package/dist/search/noop-backend.js +8 -0
  542. package/dist/search/noop-backend.js.map +1 -0
  543. package/dist/search/orama-backend.d.ts +53 -0
  544. package/dist/search/orama-backend.js +10 -0
  545. package/dist/search/orama-backend.js.map +1 -0
  546. package/dist/search/port.d.ts +61 -0
  547. package/dist/search/port.js +1 -0
  548. package/dist/search/port.js.map +1 -0
  549. package/dist/search/remote-backend.d.ts +39 -0
  550. package/dist/search/remote-backend.js +9 -0
  551. package/dist/search/remote-backend.js.map +1 -0
  552. package/dist/secure-store/index.d.ts +890 -0
  553. package/dist/secure-store/index.js +156 -0
  554. package/dist/secure-store/index.js.map +1 -0
  555. package/dist/semantic-VwGI14Ok.d.ts +69 -0
  556. package/dist/semantic-consolidation-4HkHWgeI.d.ts +180 -0
  557. package/dist/semantic-consolidation.d.ts +2 -2
  558. package/dist/semantic-consolidation.js +13 -6
  559. package/dist/semantic-rule-promotion.js +8 -5
  560. package/dist/semantic-rule-verifier.js +8 -5
  561. package/dist/shared-context/manager.d.ts +131 -0
  562. package/dist/shared-context/manager.js +15 -0
  563. package/dist/shared-context/manager.js.map +1 -0
  564. package/dist/skills-registry.js +13 -1
  565. package/dist/skills-registry.js.map +1 -1
  566. package/dist/state-store-VZU2IA53.js +16 -0
  567. package/dist/state-store-VZU2IA53.js.map +1 -0
  568. package/dist/storage-paths.d.ts +9 -0
  569. package/dist/storage-paths.js +20 -0
  570. package/dist/storage-paths.js.map +1 -0
  571. package/dist/storage.d.ts +3 -1
  572. package/dist/storage.js +7 -4
  573. package/dist/summarizer.d.ts +5 -0
  574. package/dist/summarizer.js +9 -8
  575. package/dist/summary-snapshot.js +2 -1
  576. package/dist/surfaces/dreams.d.ts +16 -0
  577. package/dist/surfaces/dreams.js +282 -0
  578. package/dist/surfaces/dreams.js.map +1 -0
  579. package/dist/surfaces/heartbeat.d.ts +17 -0
  580. package/dist/surfaces/heartbeat.js +265 -0
  581. package/dist/surfaces/heartbeat.js.map +1 -0
  582. package/dist/temporal-supersession.d.ts +3 -1
  583. package/dist/threading.d.ts +5 -0
  584. package/dist/threading.js +2 -1
  585. package/dist/tier-migration.d.ts +4 -2
  586. package/dist/tokens.js +2 -2
  587. package/dist/transcript.d.ts +15 -1
  588. package/dist/transcript.js +2 -1
  589. package/dist/transfer/autodetect.d.ts +4 -0
  590. package/dist/transfer/autodetect.js +15 -0
  591. package/dist/transfer/autodetect.js.map +1 -0
  592. package/dist/transfer/backup.d.ts +21 -0
  593. package/dist/transfer/backup.js +17 -0
  594. package/dist/transfer/backup.js.map +1 -0
  595. package/dist/transfer/capsule-export.d.ts +113 -0
  596. package/dist/transfer/capsule-export.js +19 -0
  597. package/dist/transfer/capsule-export.js.map +1 -0
  598. package/dist/transfer/capsule-import.d.ts +124 -0
  599. package/dist/transfer/capsule-import.js +16 -0
  600. package/dist/transfer/capsule-import.js.map +1 -0
  601. package/dist/transfer/constants.d.ts +13 -0
  602. package/dist/transfer/constants.js +12 -0
  603. package/dist/transfer/constants.js.map +1 -0
  604. package/dist/transfer/export-json.d.ts +11 -0
  605. package/dist/transfer/export-json.js +11 -0
  606. package/dist/transfer/export-json.js.map +1 -0
  607. package/dist/transfer/export-md.d.ts +10 -0
  608. package/dist/transfer/export-md.js +13 -0
  609. package/dist/transfer/export-md.js.map +1 -0
  610. package/dist/transfer/export-sqlite.d.ts +9 -0
  611. package/dist/transfer/export-sqlite.js +12 -0
  612. package/dist/transfer/export-sqlite.js.map +1 -0
  613. package/dist/transfer/fs-utils.d.ts +61 -0
  614. package/dist/transfer/fs-utils.js +40 -0
  615. package/dist/transfer/fs-utils.js.map +1 -0
  616. package/dist/transfer/import-json.d.ts +16 -0
  617. package/dist/transfer/import-json.js +13 -0
  618. package/dist/transfer/import-json.js.map +1 -0
  619. package/dist/transfer/import-md.d.ts +14 -0
  620. package/dist/transfer/import-md.js +11 -0
  621. package/dist/transfer/import-md.js.map +1 -0
  622. package/dist/transfer/import-sqlite.d.ts +14 -0
  623. package/dist/transfer/import-sqlite.js +12 -0
  624. package/dist/transfer/import-sqlite.js.map +1 -0
  625. package/dist/transfer/sqlite-schema.d.ts +4 -0
  626. package/dist/transfer/sqlite-schema.js +10 -0
  627. package/dist/transfer/sqlite-schema.js.map +1 -0
  628. package/dist/transfer/types.d.ts +916 -0
  629. package/dist/transfer/types.js +30 -0
  630. package/dist/transfer/types.js.map +1 -0
  631. package/dist/types.d.ts +28 -1
  632. package/dist/types.js +1 -1
  633. package/dist/verified-recall.js +9 -6
  634. package/dist/work/board.d.ts +43 -0
  635. package/dist/work/board.js +14 -0
  636. package/dist/work/board.js.map +1 -0
  637. package/dist/work/boundary.d.ts +8 -0
  638. package/dist/work/boundary.js +14 -0
  639. package/dist/work/boundary.js.map +1 -0
  640. package/dist/work/storage.d.ts +39 -0
  641. package/dist/work/storage.js +11 -0
  642. package/dist/work/storage.js.map +1 -0
  643. package/dist/work/types.d.ts +75 -0
  644. package/dist/work/types.js +1 -0
  645. package/dist/work/types.js.map +1 -0
  646. package/package.json +2767 -6
  647. package/scripts/faiss_index.py +816 -0
  648. package/scripts/faiss_requirements.txt +3 -0
  649. package/skills/remnic-entities/SKILL.md +51 -0
  650. package/skills/remnic-memory-workflow/SKILL.md +61 -0
  651. package/skills/remnic-recall/SKILL.md +51 -0
  652. package/skills/remnic-remember/SKILL.md +56 -0
  653. package/skills/remnic-search/SKILL.md +51 -0
  654. package/skills/remnic-status/SKILL.md +51 -0
  655. package/src/abort-error.test.ts +49 -0
  656. package/src/abort-error.ts +46 -0
  657. package/src/abstraction-nodes.ts +162 -0
  658. package/src/access-audit.test.ts +178 -0
  659. package/src/access-audit.ts +125 -0
  660. package/src/access-cli.test.ts +439 -0
  661. package/src/access-cli.ts +438 -0
  662. package/src/access-http.test.ts +225 -0
  663. package/src/access-http.ts +1899 -0
  664. package/src/access-idempotency.ts +232 -0
  665. package/src/access-mcp.test.ts +568 -0
  666. package/src/access-mcp.ts +3056 -0
  667. package/src/access-schema-pi.test.ts +60 -0
  668. package/src/access-schema.ts +522 -0
  669. package/src/access-service-namespace.test.ts +123 -0
  670. package/src/access-service.ts +5629 -0
  671. package/src/action-confidence.test.ts +206 -0
  672. package/src/action-confidence.ts +466 -0
  673. package/src/active-memory-bridge.test.ts +285 -0
  674. package/src/active-memory-bridge.ts +217 -0
  675. package/src/active-recall.test.ts +484 -0
  676. package/src/active-recall.ts +459 -0
  677. package/src/adapters/claude-code.ts +56 -0
  678. package/src/adapters/codex.ts +57 -0
  679. package/src/adapters/hermes.ts +64 -0
  680. package/src/adapters/index.ts +6 -0
  681. package/src/adapters/registry.ts +41 -0
  682. package/src/adapters/replit.ts +55 -0
  683. package/src/adapters/types.ts +51 -0
  684. package/src/behavior-learner.ts +144 -0
  685. package/src/behavior-signals.ts +73 -0
  686. package/src/binary-lifecycle/backend.ts +117 -0
  687. package/src/binary-lifecycle/index.ts +35 -0
  688. package/src/binary-lifecycle/manifest.ts +79 -0
  689. package/src/binary-lifecycle/pipeline.ts +352 -0
  690. package/src/binary-lifecycle/scanner.ts +89 -0
  691. package/src/binary-lifecycle/types.ts +89 -0
  692. package/src/bootstrap.ts +178 -0
  693. package/src/boxes.ts +521 -0
  694. package/src/briefing.test.ts +1535 -0
  695. package/src/briefing.ts +1382 -0
  696. package/src/buffer-session.test.ts +443 -0
  697. package/src/buffer-surprise-report.ts +176 -0
  698. package/src/buffer-surprise-telemetry.test.ts +606 -0
  699. package/src/buffer-surprise-trigger.test.ts +766 -0
  700. package/src/buffer-surprise.test.ts +339 -0
  701. package/src/buffer-surprise.ts +203 -0
  702. package/src/buffer.ts +900 -0
  703. package/src/bulk-import/cli-command.test.ts +204 -0
  704. package/src/bulk-import/index.ts +34 -0
  705. package/src/bulk-import/pipeline.test.ts +445 -0
  706. package/src/bulk-import/pipeline.ts +178 -0
  707. package/src/bulk-import/registry.test.ts +151 -0
  708. package/src/bulk-import/registry.ts +72 -0
  709. package/src/bulk-import/types.test.ts +272 -0
  710. package/src/bulk-import/types.ts +145 -0
  711. package/src/calibration.ts +394 -0
  712. package/src/capsule-cli.test.ts +398 -0
  713. package/src/capsule-cli.ts +565 -0
  714. package/src/causal-behavior.ts +308 -0
  715. package/src/causal-chain.ts +419 -0
  716. package/src/causal-consolidation.ts +370 -0
  717. package/src/causal-retrieval.ts +286 -0
  718. package/src/causal-trajectory-graph.ts +60 -0
  719. package/src/causal-trajectory.ts +303 -0
  720. package/src/chunking.ts +220 -0
  721. package/src/citations.ts +232 -0
  722. package/src/cli.ts +9403 -0
  723. package/src/codex-cli-fallback.ts +162 -0
  724. package/src/codex-thread-key.ts +1 -0
  725. package/src/coding/access-coding-context.test.ts +197 -0
  726. package/src/coding/coding-branch-scope.test.ts +281 -0
  727. package/src/coding/coding-namespace.test.ts +360 -0
  728. package/src/coding/coding-namespace.ts +412 -0
  729. package/src/coding/coding-orchestrator.test.ts +249 -0
  730. package/src/coding/git-context.test.ts +507 -0
  731. package/src/coding/git-context.ts +336 -0
  732. package/src/coding/mcp-set-coding-context.test.ts +174 -0
  733. package/src/coding/review-context.test.ts +316 -0
  734. package/src/coding/review-context.ts +349 -0
  735. package/src/coding/wire-coding-context.test.ts +468 -0
  736. package/src/commitment-ledger.test.ts +78 -0
  737. package/src/commitment-ledger.ts +337 -0
  738. package/src/compat/checks.test.ts +206 -0
  739. package/src/compat/checks.ts +716 -0
  740. package/src/compat/types.ts +33 -0
  741. package/src/compounding/engine.ts +1686 -0
  742. package/src/compounding/preference-consolidator.ts +778 -0
  743. package/src/compression-optimizer.ts +312 -0
  744. package/src/config.test.ts +930 -0
  745. package/src/config.ts +3807 -0
  746. package/src/connectors/codex/instructions.md +160 -0
  747. package/src/connectors/codex/resources/namespace-cheatsheet.md +48 -0
  748. package/src/connectors/codex-marketplace.ts +500 -0
  749. package/src/connectors/codex-materialize-runner.ts +212 -0
  750. package/src/connectors/codex-materialize.ts +983 -0
  751. package/src/connectors/coerce.ts +62 -0
  752. package/src/connectors/index.test.ts +1570 -0
  753. package/src/connectors/index.ts +3222 -0
  754. package/src/connectors/live/framework.ts +164 -0
  755. package/src/connectors/live/github.test.ts +1218 -0
  756. package/src/connectors/live/github.ts +1068 -0
  757. package/src/connectors/live/gmail.test.ts +1706 -0
  758. package/src/connectors/live/gmail.ts +1293 -0
  759. package/src/connectors/live/google-drive.test.ts +696 -0
  760. package/src/connectors/live/google-drive.ts +724 -0
  761. package/src/connectors/live/index.ts +101 -0
  762. package/src/connectors/live/live-connectors.test.ts +689 -0
  763. package/src/connectors/live/notion.test.ts +1109 -0
  764. package/src/connectors/live/notion.ts +978 -0
  765. package/src/connectors/live/registry.ts +103 -0
  766. package/src/connectors/live/state-store.ts +399 -0
  767. package/src/connectors/live/transient-errors.ts +150 -0
  768. package/src/connectors/weclone-installer.test.ts +850 -0
  769. package/src/connectors-cli.ts +513 -0
  770. package/src/console/state.test.ts +224 -0
  771. package/src/console/state.ts +514 -0
  772. package/src/console/trace.test.ts +813 -0
  773. package/src/console/trace.ts +603 -0
  774. package/src/console/tui.test.ts +582 -0
  775. package/src/console/tui.ts +508 -0
  776. package/src/consolidation-operator.ts +182 -0
  777. package/src/consolidation-provenance-check.ts +551 -0
  778. package/src/consolidation-undo.ts +718 -0
  779. package/src/contradiction/contradiction-judge.test.ts +189 -0
  780. package/src/contradiction/contradiction-judge.ts +333 -0
  781. package/src/contradiction/contradiction-review.ts +574 -0
  782. package/src/contradiction/contradiction-scan.ts +504 -0
  783. package/src/contradiction/contradiction.test.ts +2230 -0
  784. package/src/contradiction/index.ts +37 -0
  785. package/src/contradiction/resolution.ts +383 -0
  786. package/src/conversation-index/backend.ts +323 -0
  787. package/src/conversation-index/chunker.ts +47 -0
  788. package/src/conversation-index/cleanup.ts +53 -0
  789. package/src/conversation-index/faiss-adapter.ts +384 -0
  790. package/src/conversation-index/indexer.test.ts +164 -0
  791. package/src/conversation-index/indexer.ts +192 -0
  792. package/src/conversation-index/search.ts +37 -0
  793. package/src/cross-namespace-budget.test.ts +275 -0
  794. package/src/cross-namespace-budget.ts +365 -0
  795. package/src/cue-anchors.ts +163 -0
  796. package/src/curation/index.ts +544 -0
  797. package/src/dashboard-runtime.ts +337 -0
  798. package/src/day-summary.ts +122 -0
  799. package/src/dedup/index.ts +330 -0
  800. package/src/dedup/semantic.test.ts +1577 -0
  801. package/src/dedup/semantic.ts +148 -0
  802. package/src/delinearize.ts +193 -0
  803. package/src/direct-answer-wiring.test.ts +473 -0
  804. package/src/direct-answer-wiring.ts +180 -0
  805. package/src/direct-answer.test.ts +484 -0
  806. package/src/direct-answer.ts +273 -0
  807. package/src/embedding-fallback.ts +565 -0
  808. package/src/enrichment/audit.ts +89 -0
  809. package/src/enrichment/index.ts +27 -0
  810. package/src/enrichment/pipeline.ts +197 -0
  811. package/src/enrichment/provider-registry.ts +85 -0
  812. package/src/enrichment/types.ts +100 -0
  813. package/src/enrichment/web-search-provider.ts +63 -0
  814. package/src/entity-retrieval.ts +774 -0
  815. package/src/entity-schema.ts +239 -0
  816. package/src/evals.ts +1312 -0
  817. package/src/event-order-recall.test.ts +4164 -0
  818. package/src/event-order-recall.ts +2802 -0
  819. package/src/evidence-pack.test.ts +89 -0
  820. package/src/evidence-pack.ts +388 -0
  821. package/src/explicit-capture.ts +530 -0
  822. package/src/explicit-cue-recall.test.ts +3019 -0
  823. package/src/explicit-cue-recall.ts +5545 -0
  824. package/src/extraction-judge-telemetry.ts +234 -0
  825. package/src/extraction-judge-training.ts +221 -0
  826. package/src/extraction-judge.ts +846 -0
  827. package/src/extraction-timeout.test.ts +265 -0
  828. package/src/extraction.ts +2719 -0
  829. package/src/fallback-llm.test.ts +1060 -0
  830. package/src/fallback-llm.ts +918 -0
  831. package/src/focused-list-recall.test.ts +734 -0
  832. package/src/focused-list-recall.ts +1160 -0
  833. package/src/graph-dashboard-diff.ts +35 -0
  834. package/src/graph-dashboard-key.ts +5 -0
  835. package/src/graph-dashboard-parser.ts +104 -0
  836. package/src/graph-edge-reinforcement.ts +192 -0
  837. package/src/graph-events.ts +151 -0
  838. package/src/graph-recall.test.ts +164 -0
  839. package/src/graph-recall.ts +189 -0
  840. package/src/graph-retrieval.test.ts +809 -0
  841. package/src/graph-retrieval.ts +823 -0
  842. package/src/graph-snapshot.ts +329 -0
  843. package/src/graph.ts +813 -0
  844. package/src/harmonic-retrieval.ts +223 -0
  845. package/src/himem.ts +154 -0
  846. package/src/hygiene.ts +87 -0
  847. package/src/identity-continuity.ts +333 -0
  848. package/src/importance.ts +328 -0
  849. package/src/importers/base.test.ts +294 -0
  850. package/src/importers/base.ts +436 -0
  851. package/src/importers/index.ts +21 -0
  852. package/src/index.ts +1204 -0
  853. package/src/intent.ts +154 -0
  854. package/src/json-extract.ts +85 -0
  855. package/src/json-store.ts +42 -0
  856. package/src/lcm/archive.ts +617 -0
  857. package/src/lcm/dag.ts +199 -0
  858. package/src/lcm/engine.ts +645 -0
  859. package/src/lcm/index.ts +7 -0
  860. package/src/lcm/queue.test.ts +178 -0
  861. package/src/lcm/queue.ts +200 -0
  862. package/src/lcm/recall.ts +117 -0
  863. package/src/lcm/schema.ts +154 -0
  864. package/src/lcm/summarizer.ts +235 -0
  865. package/src/lcm/tools.ts +191 -0
  866. package/src/lcm-engine.test.ts +660 -0
  867. package/src/legacy-hook-compat.test.ts +20 -0
  868. package/src/legacy-hook-compat.ts +45 -0
  869. package/src/lifecycle.ts +289 -0
  870. package/src/live-connectors-runner.ts +385 -0
  871. package/src/local-llm-qos.test.ts +303 -0
  872. package/src/local-llm-thinking.test.ts +292 -0
  873. package/src/local-llm.ts +1464 -0
  874. package/src/logger.ts +49 -0
  875. package/src/maintenance/archive-observations.ts +147 -0
  876. package/src/maintenance/backup-stamp.ts +3 -0
  877. package/src/maintenance/dreams-ledger.ts +516 -0
  878. package/src/maintenance/first-start-migration.ts +362 -0
  879. package/src/maintenance/forget.test.ts +206 -0
  880. package/src/maintenance/forget.ts +126 -0
  881. package/src/maintenance/graph-edge-decay.test.ts +409 -0
  882. package/src/maintenance/graph-edge-decay.ts +394 -0
  883. package/src/maintenance/memory-governance-cron.ts +447 -0
  884. package/src/maintenance/memory-governance.ts +1039 -0
  885. package/src/maintenance/migrate-observations.ts +216 -0
  886. package/src/maintenance/observation-ledger-utils.ts +54 -0
  887. package/src/maintenance/pattern-reinforcement.test.ts +875 -0
  888. package/src/maintenance/pattern-reinforcement.ts +369 -0
  889. package/src/maintenance/purge.ts +334 -0
  890. package/src/maintenance/rebuild-memory-lifecycle-ledger.ts +78 -0
  891. package/src/maintenance/rebuild-memory-projection.ts +1234 -0
  892. package/src/maintenance/rebuild-observations.ts +178 -0
  893. package/src/maintenance/tier-stats.test.ts +378 -0
  894. package/src/maintenance/tier-stats.ts +222 -0
  895. package/src/mcp-memory-inspector-app.ts +421 -0
  896. package/src/memory-action-policy.ts +80 -0
  897. package/src/memory-cache.ts +208 -0
  898. package/src/memory-extension/claude-code-publisher.ts +51 -0
  899. package/src/memory-extension/codex-publisher.ts +149 -0
  900. package/src/memory-extension/hermes-publisher.ts +51 -0
  901. package/src/memory-extension/index.ts +100 -0
  902. package/src/memory-extension/shared-instructions.ts +133 -0
  903. package/src/memory-extension/types.ts +86 -0
  904. package/src/memory-extension-host/host-discovery.ts +276 -0
  905. package/src/memory-extension-host/index.ts +14 -0
  906. package/src/memory-extension-host/render-extensions-block.ts +73 -0
  907. package/src/memory-extension-host/types.ts +21 -0
  908. package/src/memory-lifecycle-ledger-utils.ts +116 -0
  909. package/src/memory-projection-format.ts +11 -0
  910. package/src/memory-projection-store.ts +951 -0
  911. package/src/memory-provenance.test.ts +196 -0
  912. package/src/memory-provenance.ts +484 -0
  913. package/src/memory-worth-bench.test.ts +71 -0
  914. package/src/memory-worth-bench.ts +265 -0
  915. package/src/memory-worth-filter.test.ts +209 -0
  916. package/src/memory-worth-filter.ts +204 -0
  917. package/src/memory-worth-frontmatter.test.ts +311 -0
  918. package/src/memory-worth-outcomes.test.ts +316 -0
  919. package/src/memory-worth-outcomes.ts +286 -0
  920. package/src/memory-worth.test.ts +317 -0
  921. package/src/memory-worth.ts +215 -0
  922. package/src/message-parts/index.ts +806 -0
  923. package/src/message-parts/message-parts.test.ts +421 -0
  924. package/src/migrate/from-engram.ts +789 -0
  925. package/src/model-registry.ts +313 -0
  926. package/src/models-json.ts +76 -0
  927. package/src/namespaces/migrate.ts +187 -0
  928. package/src/namespaces/path.ts +25 -0
  929. package/src/namespaces/principal.test.ts +195 -0
  930. package/src/namespaces/principal.ts +86 -0
  931. package/src/namespaces/search.test.ts +105 -0
  932. package/src/namespaces/search.ts +233 -0
  933. package/src/namespaces/storage.ts +74 -0
  934. package/src/native-knowledge.ts +1823 -0
  935. package/src/negative.ts +72 -0
  936. package/src/network/tailscale.ts +179 -0
  937. package/src/network/webdav.ts +385 -0
  938. package/src/objective-state-writers.ts +951 -0
  939. package/src/objective-state.ts +320 -0
  940. package/src/onboarding/index.ts +529 -0
  941. package/src/openai-chat-compat.ts +56 -0
  942. package/src/operator-toolkit.ts +2132 -0
  943. package/src/opik-exporter.test.ts +72 -0
  944. package/src/opik-exporter.ts +587 -0
  945. package/src/orchestrator-extraction-queue.test.ts +197 -0
  946. package/src/orchestrator-flush.test.ts +1171 -0
  947. package/src/orchestrator-pattern-reinforcement.test.ts +128 -0
  948. package/src/orchestrator-source-attribution.test.ts +701 -0
  949. package/src/orchestrator.ts +16368 -0
  950. package/src/page-versioning.ts +450 -0
  951. package/src/patterns-cli.ts +574 -0
  952. package/src/peers/index.ts +54 -0
  953. package/src/peers/migrate-from-identity-anchor.test.ts +291 -0
  954. package/src/peers/migrate-from-identity-anchor.ts +350 -0
  955. package/src/peers/peers.test.ts +419 -0
  956. package/src/peers/profile-reasoner.ts +694 -0
  957. package/src/peers/storage.ts +1350 -0
  958. package/src/peers/types.ts +138 -0
  959. package/src/plugin-id.ts +84 -0
  960. package/src/policy-runtime.ts +209 -0
  961. package/src/procedural/procedure-miner.ts +150 -0
  962. package/src/procedural/procedure-recall.ts +93 -0
  963. package/src/procedural/procedure-stats.ts +213 -0
  964. package/src/procedural/procedure-types.ts +132 -0
  965. package/src/procedural/reinforcement-core.test.ts +132 -0
  966. package/src/procedural/reinforcement-core.ts +73 -0
  967. package/src/profiling.test.ts +263 -0
  968. package/src/profiling.ts +435 -0
  969. package/src/projection/index.ts +398 -0
  970. package/src/qmd-recall-cache.test.ts +138 -0
  971. package/src/qmd-recall-cache.ts +111 -0
  972. package/src/qmd.test.ts +258 -0
  973. package/src/qmd.ts +2614 -0
  974. package/src/reasoning-trace-recall.ts +201 -0
  975. package/src/reasoning-trace-types.ts +235 -0
  976. package/src/recall-audit-anomaly.test.ts +246 -0
  977. package/src/recall-audit-anomaly.ts +297 -0
  978. package/src/recall-audit.test.ts +51 -0
  979. package/src/recall-audit.ts +72 -0
  980. package/src/recall-budget-config.test.ts +87 -0
  981. package/src/recall-disclosure-escalation.test.ts +196 -0
  982. package/src/recall-disclosure-escalation.ts +158 -0
  983. package/src/recall-disclosure-shaping.test.ts +146 -0
  984. package/src/recall-disclosure.test.ts +214 -0
  985. package/src/recall-explain-renderer.test.ts +140 -0
  986. package/src/recall-explain-renderer.ts +356 -0
  987. package/src/recall-mmr.test.ts +808 -0
  988. package/src/recall-mmr.ts +607 -0
  989. package/src/recall-qos.test.ts +85 -0
  990. package/src/recall-qos.ts +82 -0
  991. package/src/recall-query-policy.ts +221 -0
  992. package/src/recall-state.test.ts +233 -0
  993. package/src/recall-state.ts +456 -0
  994. package/src/recall-tag-filter.ts +143 -0
  995. package/src/recall-tokenization.ts +35 -0
  996. package/src/recall-xray-cli.test.ts +118 -0
  997. package/src/recall-xray-cli.ts +100 -0
  998. package/src/recall-xray-disclosure-telemetry.test.ts +183 -0
  999. package/src/recall-xray-renderer.test.ts +539 -0
  1000. package/src/recall-xray-renderer.ts +487 -0
  1001. package/src/recall-xray.test.ts +503 -0
  1002. package/src/recall-xray.ts +621 -0
  1003. package/src/reconstruct.ts +41 -0
  1004. package/src/release-changelog.ts +35 -0
  1005. package/src/relevance.ts +67 -0
  1006. package/src/replay/normalizers/chatgpt.ts +133 -0
  1007. package/src/replay/normalizers/claude.ts +102 -0
  1008. package/src/replay/normalizers/openclaw.ts +119 -0
  1009. package/src/replay/normalizers/shared.ts +69 -0
  1010. package/src/replay/runner.ts +197 -0
  1011. package/src/replay/types.ts +143 -0
  1012. package/src/rerank.test.ts +48 -0
  1013. package/src/rerank.ts +176 -0
  1014. package/src/resolve-auth-token.test.ts +226 -0
  1015. package/src/resolve-auth-token.ts +151 -0
  1016. package/src/resolve-provider-secret.test.ts +187 -0
  1017. package/src/resolve-provider-secret.ts +410 -0
  1018. package/src/response-guidance-recall.test.ts +3952 -0
  1019. package/src/response-guidance-recall.ts +4431 -0
  1020. package/src/resume-bundles.ts +415 -0
  1021. package/src/retrieval-agents.ts +623 -0
  1022. package/src/retrieval-tiers.ts +25 -0
  1023. package/src/retrieval.ts +104 -0
  1024. package/src/review/index.test.ts +201 -0
  1025. package/src/review/index.ts +536 -0
  1026. package/src/routing/engine.ts +162 -0
  1027. package/src/routing/store.ts +321 -0
  1028. package/src/runtime/better-sqlite.test.ts +32 -0
  1029. package/src/runtime/better-sqlite.ts +76 -0
  1030. package/src/runtime/child-process.ts +67 -0
  1031. package/src/runtime/env.ts +48 -0
  1032. package/src/sanitize.ts +58 -0
  1033. package/src/schemas.ts +449 -0
  1034. package/src/sdk-compat.ts +87 -0
  1035. package/src/search/document-scanner.ts +96 -0
  1036. package/src/search/embed-helper.ts +142 -0
  1037. package/src/search/factory.ts +189 -0
  1038. package/src/search/index.ts +10 -0
  1039. package/src/search/lancedb-backend.ts +342 -0
  1040. package/src/search/meilisearch-backend.ts +232 -0
  1041. package/src/search/noop-backend.ts +57 -0
  1042. package/src/search/orama-backend.ts +358 -0
  1043. package/src/search/port.ts +86 -0
  1044. package/src/search/remote-backend.ts +124 -0
  1045. package/src/secure-store/cipher.ts +271 -0
  1046. package/src/secure-store/cli-handlers.ts +355 -0
  1047. package/src/secure-store/cli-renderer.ts +131 -0
  1048. package/src/secure-store/header.ts +373 -0
  1049. package/src/secure-store/index.ts +137 -0
  1050. package/src/secure-store/kdf.ts +263 -0
  1051. package/src/secure-store/keyring.ts +106 -0
  1052. package/src/secure-store/metadata.ts +394 -0
  1053. package/src/secure-store/passphrase-reader.ts +252 -0
  1054. package/src/secure-store/secure-fs.ts +571 -0
  1055. package/src/secure-store/secure-store.test.ts +755 -0
  1056. package/src/semantic-chunking.ts +545 -0
  1057. package/src/semantic-consolidation.test.ts +182 -0
  1058. package/src/semantic-consolidation.ts +432 -0
  1059. package/src/semantic-rule-promotion.ts +183 -0
  1060. package/src/semantic-rule-verifier.ts +160 -0
  1061. package/src/session-integrity.ts +569 -0
  1062. package/src/session-observer-bands.ts +11 -0
  1063. package/src/session-observer-state.ts +346 -0
  1064. package/src/session-toggles.test.ts +96 -0
  1065. package/src/session-toggles.ts +159 -0
  1066. package/src/shared-context/manager.ts +810 -0
  1067. package/src/signal.ts +84 -0
  1068. package/src/skills-registry.test.ts +277 -0
  1069. package/src/skills-registry.ts +120 -0
  1070. package/src/source-attribution-roundtrip.test.ts +215 -0
  1071. package/src/source-attribution.test.ts +1425 -0
  1072. package/src/source-attribution.ts +639 -0
  1073. package/src/spaces/index.ts +627 -0
  1074. package/src/storage-paths.ts +117 -0
  1075. package/src/storage.ts +6657 -0
  1076. package/src/store-contract.ts +55 -0
  1077. package/src/summarizer.ts +844 -0
  1078. package/src/summary-snapshot.test.ts +681 -0
  1079. package/src/summary-snapshot.ts +238 -0
  1080. package/src/surfaces/dreams.test.ts +394 -0
  1081. package/src/surfaces/dreams.ts +346 -0
  1082. package/src/surfaces/heartbeat.test.ts +415 -0
  1083. package/src/surfaces/heartbeat.ts +325 -0
  1084. package/src/sync/index.ts +308 -0
  1085. package/src/targeted-fact-recall.test.ts +1694 -0
  1086. package/src/targeted-fact-recall.ts +2905 -0
  1087. package/src/taxonomy/default-taxonomy.ts +87 -0
  1088. package/src/taxonomy/index.ts +26 -0
  1089. package/src/taxonomy/resolver-doc-generator.ts +57 -0
  1090. package/src/taxonomy/resolver.ts +184 -0
  1091. package/src/taxonomy/taxonomy-loader.ts +186 -0
  1092. package/src/taxonomy/types.ts +48 -0
  1093. package/src/telemetry-transcript.ts +70 -0
  1094. package/src/temporal-index.ts +890 -0
  1095. package/src/temporal-supersession.test.ts +2703 -0
  1096. package/src/temporal-supersession.ts +493 -0
  1097. package/src/temporal-validity.test.ts +448 -0
  1098. package/src/temporal-validity.ts +123 -0
  1099. package/src/threading.ts +395 -0
  1100. package/src/tier-migration.ts +124 -0
  1101. package/src/tier-routing.ts +102 -0
  1102. package/src/tmt.ts +462 -0
  1103. package/src/tokens.test.ts +178 -0
  1104. package/src/tokens.ts +279 -0
  1105. package/src/topics.ts +147 -0
  1106. package/src/training-export/cli-date-validation.test.ts +258 -0
  1107. package/src/training-export/converter.test.ts +452 -0
  1108. package/src/training-export/converter.ts +319 -0
  1109. package/src/training-export/date-parse.ts +117 -0
  1110. package/src/training-export/index.ts +26 -0
  1111. package/src/training-export/registry.test.ts +85 -0
  1112. package/src/training-export/registry.ts +57 -0
  1113. package/src/training-export/types.ts +31 -0
  1114. package/src/transcript.ts +1179 -0
  1115. package/src/transfer/autodetect.ts +30 -0
  1116. package/src/transfer/backup.ts +138 -0
  1117. package/src/transfer/capsule-crypto.ts +485 -0
  1118. package/src/transfer/capsule-encrypt.test.ts +690 -0
  1119. package/src/transfer/capsule-export.ts +543 -0
  1120. package/src/transfer/capsule-fork.ts +375 -0
  1121. package/src/transfer/capsule-import.ts +564 -0
  1122. package/src/transfer/capsule-merge.ts +433 -0
  1123. package/src/transfer/conflict-policy.ts +16 -0
  1124. package/src/transfer/constants.ts +13 -0
  1125. package/src/transfer/exclusions.ts +37 -0
  1126. package/src/transfer/export-json.ts +65 -0
  1127. package/src/transfer/export-md.ts +59 -0
  1128. package/src/transfer/export-sqlite.ts +52 -0
  1129. package/src/transfer/fs-utils.ts +269 -0
  1130. package/src/transfer/import-json.ts +108 -0
  1131. package/src/transfer/import-md.ts +84 -0
  1132. package/src/transfer/import-sqlite.ts +100 -0
  1133. package/src/transfer/integrity.ts +71 -0
  1134. package/src/transfer/sqlite-schema.ts +16 -0
  1135. package/src/transfer/types.ts +297 -0
  1136. package/src/trust-zones.ts +1186 -0
  1137. package/src/types.ts +3074 -0
  1138. package/src/user-model.test.ts +124 -0
  1139. package/src/user-model.ts +162 -0
  1140. package/src/utility-learner.ts +353 -0
  1141. package/src/utility-runtime.ts +88 -0
  1142. package/src/utility-telemetry.ts +215 -0
  1143. package/src/utils/category-dir.ts +44 -0
  1144. package/src/utils/errno.ts +6 -0
  1145. package/src/utils/iso-timestamp.test.ts +37 -0
  1146. package/src/utils/iso-timestamp.ts +164 -0
  1147. package/src/utils/path.ts +26 -0
  1148. package/src/verified-recall.ts +138 -0
  1149. package/src/version-utils.test.ts +10 -0
  1150. package/src/version-utils.ts +9 -0
  1151. package/src/whitespace.ts +10 -0
  1152. package/src/work/board.ts +359 -0
  1153. package/src/work/boundary.ts +107 -0
  1154. package/src/work/storage.ts +436 -0
  1155. package/src/work/types.ts +82 -0
  1156. package/src/work-product-ledger.ts +265 -0
  1157. package/dist/access-service-DDjzFALq.d.ts +0 -2088
  1158. package/dist/capsule-crypto-SJS5VVAP.js +0 -18
  1159. package/dist/capsule-export-7QNCBZOQ.js +0 -17
  1160. package/dist/capsule-import-EPBHD2EN.js +0 -16
  1161. package/dist/capsule-merge-DI7PNQ2H.js +0 -189
  1162. package/dist/chunk-23ZZK64Y.js +0 -26
  1163. package/dist/chunk-23ZZK64Y.js.map +0 -1
  1164. package/dist/chunk-242S3I2A.js +0 -647
  1165. package/dist/chunk-2LGMW3DJ.js +0 -111
  1166. package/dist/chunk-3B6KIRBH.js +0 -5213
  1167. package/dist/chunk-3B6KIRBH.js.map +0 -1
  1168. package/dist/chunk-457A4P3L.js +0 -119
  1169. package/dist/chunk-457A4P3L.js.map +0 -1
  1170. package/dist/chunk-4IS4SXIQ.js +0 -2040
  1171. package/dist/chunk-4YM32CRU.js +0 -721
  1172. package/dist/chunk-6TBWYBJ3.js +0 -236
  1173. package/dist/chunk-74EMIVE4.js +0 -329
  1174. package/dist/chunk-74EMIVE4.js.map +0 -1
  1175. package/dist/chunk-767ODGE6.js +0 -183
  1176. package/dist/chunk-7V22HTMD.js +0 -623
  1177. package/dist/chunk-7V22HTMD.js.map +0 -1
  1178. package/dist/chunk-7ZM3BFKK.js +0 -9705
  1179. package/dist/chunk-7ZM3BFKK.js.map +0 -1
  1180. package/dist/chunk-AQJNPMOA.js +0 -643
  1181. package/dist/chunk-AQJNPMOA.js.map +0 -1
  1182. package/dist/chunk-ASAITVLA.js +0 -64
  1183. package/dist/chunk-ASAITVLA.js.map +0 -1
  1184. package/dist/chunk-BBE34QBJ.js +0 -275
  1185. package/dist/chunk-BBE34QBJ.js.map +0 -1
  1186. package/dist/chunk-BZSQEPRW.js +0 -14710
  1187. package/dist/chunk-BZSQEPRW.js.map +0 -1
  1188. package/dist/chunk-CPKTBRS2.js +0 -891
  1189. package/dist/chunk-CPKTBRS2.js.map +0 -1
  1190. package/dist/chunk-D4GAOFF6.js +0 -562
  1191. package/dist/chunk-D4GAOFF6.js.map +0 -1
  1192. package/dist/chunk-D54LZC5L.js +0 -147
  1193. package/dist/chunk-DF3RVK3X.js +0 -119
  1194. package/dist/chunk-DF3RVK3X.js.map +0 -1
  1195. package/dist/chunk-DZZPC36E.js +0 -1451
  1196. package/dist/chunk-DZZPC36E.js.map +0 -1
  1197. package/dist/chunk-E2UCDP5S.js +0 -570
  1198. package/dist/chunk-E6K4NIEU.js +0 -747
  1199. package/dist/chunk-E6K4NIEU.js.map +0 -1
  1200. package/dist/chunk-EEQLFRUM.js +0 -89
  1201. package/dist/chunk-ETOW6ACV.js +0 -158
  1202. package/dist/chunk-ETOW6ACV.js.map +0 -1
  1203. package/dist/chunk-FMEBPEAO.js +0 -347
  1204. package/dist/chunk-FMEBPEAO.js.map +0 -1
  1205. package/dist/chunk-FQDPCE3I.js +0 -1837
  1206. package/dist/chunk-FQDPCE3I.js.map +0 -1
  1207. package/dist/chunk-FYIYMQ5N.js +0 -221
  1208. package/dist/chunk-FYIYMQ5N.js.map +0 -1
  1209. package/dist/chunk-G2WADRQ3.js +0 -219
  1210. package/dist/chunk-G4SK7DSQ.js +0 -121
  1211. package/dist/chunk-GVPWB7EY.js +0 -390
  1212. package/dist/chunk-GVPWB7EY.js.map +0 -1
  1213. package/dist/chunk-HELQZFZO.js +0 -1075
  1214. package/dist/chunk-HL5LRPNA.js +0 -1914
  1215. package/dist/chunk-HL5LRPNA.js.map +0 -1
  1216. package/dist/chunk-HQZVVSVB.js +0 -147
  1217. package/dist/chunk-HQZVVSVB.js.map +0 -1
  1218. package/dist/chunk-HY3L4WKC.js +0 -2195
  1219. package/dist/chunk-HY3L4WKC.js.map +0 -1
  1220. package/dist/chunk-IB3BFHGN.js +0 -228
  1221. package/dist/chunk-IXEJRKCZ.js +0 -18
  1222. package/dist/chunk-JBMSGZEQ.js +0 -441
  1223. package/dist/chunk-JBMSGZEQ.js.map +0 -1
  1224. package/dist/chunk-JESOB2HO.js +0 -108
  1225. package/dist/chunk-JKDVIE52.js +0 -272
  1226. package/dist/chunk-JRNQ3RNA.js +0 -284
  1227. package/dist/chunk-JRNQ3RNA.js.map +0 -1
  1228. package/dist/chunk-K6WK37A6.js +0 -865
  1229. package/dist/chunk-K6WK37A6.js.map +0 -1
  1230. package/dist/chunk-MARWOCVP.js +0 -48
  1231. package/dist/chunk-MNU6ZBWT.js +0 -4454
  1232. package/dist/chunk-MNU6ZBWT.js.map +0 -1
  1233. package/dist/chunk-N5AKDXAI.js +0 -74
  1234. package/dist/chunk-OA3L7BFR.js +0 -183
  1235. package/dist/chunk-OA3L7BFR.js.map +0 -1
  1236. package/dist/chunk-OR64ZGRZ.js +0 -23
  1237. package/dist/chunk-P77UEOU2.js +0 -1521
  1238. package/dist/chunk-P77UEOU2.js.map +0 -1
  1239. package/dist/chunk-PH4C2U43.js +0 -239
  1240. package/dist/chunk-PH4C2U43.js.map +0 -1
  1241. package/dist/chunk-RVPLBATS.js +0 -1586
  1242. package/dist/chunk-RVPLBATS.js.map +0 -1
  1243. package/dist/chunk-U5JMRGKX.js +0 -340
  1244. package/dist/chunk-U5JMRGKX.js.map +0 -1
  1245. package/dist/chunk-URB2WSKZ.js +0 -350
  1246. package/dist/chunk-URB2WSKZ.js.map +0 -1
  1247. package/dist/chunk-UVMUAWVT.js +0 -596
  1248. package/dist/chunk-WEJG4TB5.js +0 -118
  1249. package/dist/chunk-X7HPGUVG.js +0 -271
  1250. package/dist/chunk-XAMBKFQS.js +0 -2777
  1251. package/dist/chunk-XAMBKFQS.js.map +0 -1
  1252. package/dist/chunk-XJKFSSDW.js +0 -726
  1253. package/dist/chunk-XJKFSSDW.js.map +0 -1
  1254. package/dist/chunk-XMHBH5H6.js +0 -283
  1255. package/dist/chunk-XMHBH5H6.js.map +0 -1
  1256. package/dist/chunk-XMVFHBHT.js +0 -277
  1257. package/dist/chunk-Y3VMVTYX.js +0 -53
  1258. package/dist/chunk-YNB73F22.js +0 -137
  1259. package/dist/chunk-YNB73F22.js.map +0 -1
  1260. package/dist/chunk-Z2E7VW55.js +0 -335
  1261. package/dist/chunk-Z2E7VW55.js.map +0 -1
  1262. package/dist/chunk-ZG7PTKBK.js +0 -2296
  1263. package/dist/chunk-ZNQN6ZTA.js +0 -135
  1264. package/dist/chunk-ZVTKDVVM.js +0 -827
  1265. package/dist/chunk-ZVTKDVVM.js.map +0 -1
  1266. package/dist/cli-BR8KpIU0.d.ts +0 -1259
  1267. package/dist/codex-materialize-CQlLTzke.d.ts +0 -139
  1268. package/dist/connectors-cli-DFGtY2DB.d.ts +0 -257
  1269. package/dist/contradiction-review-5LTTVDQV.js +0 -22
  1270. package/dist/contradiction-scan-QTXAMBUA.js +0 -414
  1271. package/dist/contradiction-scan-QTXAMBUA.js.map +0 -1
  1272. package/dist/engine-35M5BKQ7.js +0 -28
  1273. package/dist/fs-utils-IRVUFB6G.js +0 -30
  1274. package/dist/graph-edge-decay-PWB63GRE.js +0 -207
  1275. package/dist/memory-governance-IMPQZXFC.js +0 -37
  1276. package/dist/memory-projection-store-CY8TU40w.d.ts +0 -222
  1277. package/dist/orchestrator-DDMPqU6R.d.ts +0 -1792
  1278. package/dist/path-RMTY5Y5A.js +0 -9
  1279. package/dist/port-B6VEDIkC.d.ts +0 -53
  1280. package/dist/resolution-YGIBORXI.js +0 -101
  1281. package/dist/resolution-YGIBORXI.js.map +0 -1
  1282. package/dist/secure-store-4R2GSO7S.js +0 -156
  1283. package/dist/semantic-consolidation-ByBXb-sf.d.ts +0 -180
  1284. package/dist/state-store-3EH7HYIN.js +0 -16
  1285. package/dist/types-V3FJ26TF.js +0 -30
  1286. /package/dist/{capsule-crypto-SJS5VVAP.js.map → adapters/claude-code.js.map} +0 -0
  1287. /package/dist/{capsule-export-7QNCBZOQ.js.map → adapters/codex.js.map} +0 -0
  1288. /package/dist/{capsule-import-EPBHD2EN.js.map → adapters/hermes.js.map} +0 -0
  1289. /package/dist/{contradiction-review-5LTTVDQV.js.map → adapters/index.js.map} +0 -0
  1290. /package/dist/{engine-35M5BKQ7.js.map → adapters/registry.js.map} +0 -0
  1291. /package/dist/{fs-utils-IRVUFB6G.js.map → adapters/replit.js.map} +0 -0
  1292. /package/dist/{memory-governance-IMPQZXFC.js.map → adapters/types.js.map} +0 -0
  1293. /package/dist/{path-RMTY5Y5A.js.map → capsule-crypto-5CYAGVC5.js.map} +0 -0
  1294. /package/dist/{capsule-merge-DI7PNQ2H.js.map → capsule-merge-4MGKE7C5.js.map} +0 -0
  1295. /package/dist/{chunk-G4SK7DSQ.js.map → chunk-2WWLHTZY.js.map} +0 -0
  1296. /package/dist/{chunk-X7HPGUVG.js.map → chunk-4CRG46BG.js.map} +0 -0
  1297. /package/dist/{chunk-UVMUAWVT.js.map → chunk-7IASACLB.js.map} +0 -0
  1298. /package/dist/{chunk-HELQZFZO.js.map → chunk-EDTHC6UD.js.map} +0 -0
  1299. /package/dist/{chunk-4YM32CRU.js.map → chunk-EFJ3MQ4V.js.map} +0 -0
  1300. /package/dist/{chunk-E2UCDP5S.js.map → chunk-FBYESMQ2.js.map} +0 -0
  1301. /package/dist/{chunk-D54LZC5L.js.map → chunk-FDU6HUUL.js.map} +0 -0
  1302. /package/dist/{chunk-IB3BFHGN.js.map → chunk-GGKRUQOO.js.map} +0 -0
  1303. /package/dist/{chunk-242S3I2A.js.map → chunk-GL6I6MEQ.js.map} +0 -0
  1304. /package/dist/{secure-store-4R2GSO7S.js.map → chunk-HHLLAQGZ.js.map} +0 -0
  1305. /package/dist/{chunk-4IS4SXIQ.js.map → chunk-HXXBL2KD.js.map} +0 -0
  1306. /package/dist/{chunk-767ODGE6.js.map → chunk-KNKUID7G.js.map} +0 -0
  1307. /package/dist/{chunk-6TBWYBJ3.js.map → chunk-LPMVBPA3.js.map} +0 -0
  1308. /package/dist/{chunk-WEJG4TB5.js.map → chunk-MC26UJIM.js.map} +0 -0
  1309. /package/dist/{chunk-JKDVIE52.js.map → chunk-MGKYQQYF.js.map} +0 -0
  1310. /package/dist/{chunk-Y3VMVTYX.js.map → chunk-MT4HVDUZ.js.map} +0 -0
  1311. /package/dist/{chunk-G2WADRQ3.js.map → chunk-MY6TPVXW.js.map} +0 -0
  1312. /package/dist/{chunk-OR64ZGRZ.js.map → chunk-NNVTUXEB.js.map} +0 -0
  1313. /package/dist/{chunk-JESOB2HO.js.map → chunk-P4NEIHUT.js.map} +0 -0
  1314. /package/dist/{chunk-IXEJRKCZ.js.map → chunk-QRNI5JBH.js.map} +0 -0
  1315. /package/dist/{chunk-EEQLFRUM.js.map → chunk-RRF5UOBJ.js.map} +0 -0
  1316. /package/dist/{state-store-3EH7HYIN.js.map → chunk-SEDEKFYQ.js.map} +0 -0
  1317. /package/dist/{chunk-2LGMW3DJ.js.map → chunk-U3PN77QT.js.map} +0 -0
  1318. /package/dist/{chunk-XMVFHBHT.js.map → chunk-U3WSW6PZ.js.map} +0 -0
  1319. /package/dist/{chunk-N5AKDXAI.js.map → chunk-UWVJF25J.js.map} +0 -0
  1320. /package/dist/{types-V3FJ26TF.js.map → chunk-V5OCT34X.js.map} +0 -0
  1321. /package/dist/{chunk-ZG7PTKBK.js.map → chunk-W3LR522O.js.map} +0 -0
  1322. /package/dist/{chunk-MARWOCVP.js.map → chunk-XIG5PDM7.js.map} +0 -0
  1323. /package/dist/{chunk-ZNQN6ZTA.js.map → chunk-XVZ7B3HG.js.map} +0 -0
  1324. /package/dist/{graph-edge-decay-PWB63GRE.js.map → graph-edge-decay-5DI5GUNL.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/connectors/index.ts","../src/connectors/codex-marketplace.ts"],"sourcesContent":["/**\n * @remnic/core — Connector Manager\n *\n * Metadata-driven registry for host adapters (Codex CLI, Claude Code, Cursor, etc.).\n * Manages connector lifecycle: install, remove, configure, health.\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport os from \"node:os\";\nimport { createRequire } from \"node:module\";\nimport { fileURLToPath } from \"node:url\";\n\nimport { generateToken, revokeToken, buildTokenEntry, commitTokenEntry, loadTokenStore, saveTokenStore } from \"../tokens.js\";\nimport { launchProcessSync } from \"../runtime/child-process.js\";\nimport { mergeEnv, readEnvVar, resolveHomeDir } from \"../runtime/env.js\";\nimport { expandTildePath } from \"../utils/path.js\";\nimport { coerceInstallExtension } from \"./coerce.js\";\n\n// Native memory artifact materialization for Codex CLI (#378). Surfaced here\n// so downstream callers can `import { materializeForNamespace } from \"@remnic/core/connectors\"`.\nexport {\n materializeForNamespace,\n ensureSentinel,\n describeMemoriesDir,\n renderMemorySummary,\n renderMemoryMd,\n renderRawMemories,\n renderRolloutSummary,\n validateMemoryMd,\n approximateTokenCount,\n truncateToTokenBudget,\n MATERIALIZE_VERSION,\n SENTINEL_FILE,\n TMP_DIR,\n type MaterializeOptions,\n type MaterializeResult,\n type RolloutSummaryInput,\n type MemoryMdValidation,\n} from \"./codex-materialize.js\";\nexport {\n runCodexMaterialize,\n type RunMaterializeOptions,\n} from \"./codex-materialize-runner.js\";\nexport {\n generateMarketplaceManifest,\n validateMarketplaceManifest,\n checkMarketplaceManifest,\n writeMarketplaceManifest,\n installFromMarketplace,\n MARKETPLACE_SCHEMA_VERSION,\n MARKETPLACE_MANIFEST_FILENAME,\n type MarketplaceManifest,\n type MarketplaceEntry,\n type MarketplaceConfig,\n type MarketplaceInstallType,\n type MarketplaceInstallResult,\n type MarketplaceValidation,\n type MarketplaceLogger,\n} from \"./codex-marketplace.js\";\n\n// ── Types ────────────────────────────────────────────────────────────────────\n\nexport interface ConnectorManifest {\n /** Unique connector ID (e.g. \"claude-code\", \"codex-cli\") */\n id: string;\n /** Human-readable name */\n name: string;\n /** Version */\n version: string;\n /** Description */\n description: string;\n /** Capabilities */\n capabilities: ConnectorCapability;\n /** Required config fields */\n configSchema?: Record<string, string>;\n /** Whether currently installed */\n installed?: boolean;\n /** Homepage URL */\n homepage?: string;\n /** Author */\n author?: string;\n /** Repository URL */\n repository?: string;\n /** Tags */\n tags?: string[];\n /**\n * Whether this connector requires a bearer token for daemon authentication.\n * When false (the default), installConnector will NOT generate or persist a\n * token entry in tokens.json — credentials are never materialized on disk for\n * connectors that use MCP, embedded, CLI, or SDK transports that don't need\n * token auth. Set to true only for HTTP connectors that actually authenticate\n * requests with a bearer token (e.g. hermes, replit, generic-mcp).\n */\n requiresToken?: boolean;\n}\n\nexport interface ConnectorCapability {\n /** Can observe conversations */\n observe: boolean;\n /** Can recall/query memories */\n recall: boolean;\n /** Can store memories */\n store: boolean;\n /** Can search */\n search: boolean;\n /** Can manage entities */\n entities: boolean;\n /** Supports real-time sync */\n realtimeSync: boolean;\n /** Supports batch operations */\n batch: boolean;\n /** Max memory budget in chars */\n maxBudgetChars?: number;\n /** Connection type */\n connectionType: \"mcp\" | \"http\" | \"cli\" | \"sdk\" | \"embedded\";\n}\n\nexport interface ConnectorInstance {\n /** Connector ID */\n connectorId: string;\n /** Resolved config */\n config: Record<string, unknown>;\n /** Status */\n status: \"installed\" | \"running\" | \"error\" | \"disabled\";\n /** Installed at timestamp */\n installedAt?: string;\n /** Error message if erro */\n error?: string;\n}\n\nexport interface ConnectorRegistry {\n /** Known connectors */\n connectors: ConnectorManifest[];\n /** Registry file path */\n registryPath: string;\n}\n\nexport interface InstallOptions {\n /** Connector ID to install */\n connectorId: string;\n /** Config values */\n config?: Record<string, unknown>;\n /** Memory directory */\n memoryDir?: string;\n /** Whether to force reinstall */\n force?: boolean;\n}\n\nexport interface InstallResult {\n /** Connector ID */\n connectorId: string;\n /** Status */\n status: \"installed\" | \"already_installed\" | \"config_required\" | \"error\";\n /** Config path */\n configPath?: string;\n /** Message */\n message: string;\n}\n\nexport interface RemoveResult {\n /** Connector ID */\n connectorId: string;\n /** Removed config path */\n configPath: string;\n /** Message */\n message: string;\n /** Status: \"removed\" on success, \"error\" if the removal failed partway, \"not_found\" if the connector was not installed, \"skipped\" if removal was aborted (e.g. malformed config). */\n status: \"removed\" | \"error\" | \"not_found\" | \"skipped\";\n /** Machine-readable skip reason (present when status === \"skipped\"). */\n reason?: string;\n}\n\nexport interface DoctorResult {\n /** Connector ID */\n connectorId: string;\n /** Checks */\n checks: DoctorCheck[];\n /** All healthy */\n healthy: boolean;\n}\n\nexport interface DoctorCheck {\n /** Check name */\n name: string;\n /** Passed */\n ok: boolean;\n /** Detail */\n detail: string;\n}\n\n// ── Helpers (Finding 4) ───────────────────────────────────────────────────\n\n// Re-export coerceInstallExtension so existing import sites\n// (`import { coerceInstallExtension } from \"./index.js\"`) keep working without\n// change. The binding comes from the top-level import above.\nexport { coerceInstallExtension };\n\n// ── Built-in connector definitions ─────────────────────────────────────────\n\nconst BUILTIN_CONNECTORS: ConnectorManifest[] = [\n {\n id: \"claude-code\",\n name: \"Claude Code\",\n version: \"1.0.0\",\n description: \"Anthropic's Claude Code CLI — direct memory access via MCP\",\n capabilities: {\n observe: true,\n recall: true,\n store: true,\n search: true,\n entities: true,\n realtimeSync: true,\n batch: false,\n maxBudgetChars: 32000,\n connectionType: \"mcp\",\n },\n configSchema: {\n mcpServerUrl: \"URL of the MCP Remnic server\",\n namespace: \"Optional namespace (default: 'default')\",\n },\n homepage: \"https://claude.ai/code\",\n author: \"Anthropic\",\n tags: [\"official\", \"ai\", \"claude\"],\n requiresToken: true,\n },\n {\n id: \"codex-cli\",\n name: \"Codex CLI\",\n version: \"1.0.0\",\n description: \"OpenAI Codex CLI — memory via MCP tool\",\n capabilities: {\n observe: true,\n recall: true,\n store: true,\n search: false,\n entities: false,\n realtimeSync: false,\n batch: true,\n maxBudgetChars: 8000,\n connectionType: \"mcp\",\n },\n configSchema: {\n mcpServerUrl: \"URL of the MCP Remnic server\",\n namespace: \"Optional namespace\",\n },\n homepage: \"https://openai.com/codex\",\n author: \"OpenAI\",\n tags: [\"official\", \"ai\", \"codex\"],\n requiresToken: true,\n },\n {\n id: \"cursor\",\n name: \"Cursor IDE\",\n version: \"1.0.0\",\n description: \"Cursor IDE — memory via config file + tool calls\",\n capabilities: {\n observe: false,\n recall: true,\n store: false,\n search: true,\n entities: false,\n realtimeSync: false,\n batch: false,\n maxBudgetChars: 32000,\n connectionType: \"embedded\",\n },\n configSchema: {\n memoryDir: \"Path to Remnic memory directory\",\n },\n homepage: \"https://cursor.com\",\n author: \"Cursor Inc.\",\n tags: [\"official\", \"ide\"],\n },\n {\n id: \"cline\",\n name: \"Cline\",\n version: \"1.0.0\",\n description: \"VS Code Cline extension — memory via MCP\",\n capabilities: {\n observe: true,\n recall: true,\n store: true,\n search: false,\n entities: false,\n realtimeSync: false,\n batch: true,\n maxBudgetChars: 8000,\n connectionType: \"mcp\",\n },\n configSchema: {\n mcpServerUrl: \"URL of the MCP Remnic server\",\n namespace: \"Optional namespace\",\n },\n homepage: \"https://github.com/cline/cline\",\n author: \"Cline\",\n tags: [\"community\", \"vscode\"],\n },\n {\n id: \"github-copilot\",\n name: \"GitHub Copilot\",\n version: \"1.0.0\",\n description: \"GitHub Copilot — memory via MCP server\",\n capabilities: {\n observe: false,\n recall: true,\n store: false,\n search: true,\n entities: false,\n realtimeSync: false,\n batch: false,\n maxBudgetChars: 16000,\n connectionType: \"mcp\",\n },\n configSchema: {\n mcpServerUrl: \"URL of the MCP Remnic server\",\n },\n homepage: \"https://github.com/features/copilot\",\n author: \"GitHub\",\n tags: [\"official\", \"ai\", \"github\"],\n },\n {\n id: \"roo-code\",\n name: \"Roo Code\",\n version: \"1.0.0\",\n description: \"Roo Code — memory via MCP\",\n capabilities: {\n observe: true,\n recall: true,\n store: true,\n search: false,\n entities: false,\n realtimeSync: false,\n batch: true,\n maxBudgetChars: 16000,\n connectionType: \"mcp\",\n },\n configSchema: {\n mcpServerUrl: \"URL of the MCP Remnic server\",\n namespace: \"Optional namespace\",\n },\n homepage: \"https://roocode.com\",\n author: \"Roo Code\",\n tags: [\"community\", \"vscode\"],\n },\n {\n id: \"windsurf\",\n name: \"Windsurf\",\n version: \"1.0.0\",\n description: \"Windsurf IDE — memory via MCP\",\n capabilities: {\n observe: true,\n recall: true,\n store: true,\n search: true,\n entities: false,\n realtimeSync: false,\n batch: false,\n maxBudgetChars: 32000,\n connectionType: \"mcp\",\n },\n configSchema: {\n mcpServerUrl: \"URL of the MCP Remnic server\",\n },\n homepage: \"https://windsurf.com\",\n author: \"Codeium\",\n tags: [\"official\", \"ide\"],\n },\n {\n id: \"amp\",\n name: \"Amp\",\n version: \"1.0.0\",\n description: \"Amp coding agent — memory via MCP\",\n capabilities: {\n observe: true,\n recall: true,\n store: true,\n search: true,\n entities: false,\n realtimeSync: false,\n batch: false,\n maxBudgetChars: 32000,\n connectionType: \"mcp\",\n },\n configSchema: {\n mcpServerUrl: \"URL of the MCP Remnic server\",\n },\n homepage: \"https://ampcode.com\",\n author: \"Sourcegraph\",\n tags: [\"official\", \"ai\"],\n },\n {\n id: \"pi\",\n name: \"Pi Coding Agent\",\n version: \"1.0.0\",\n description: \"Pi Coding Agent — native extension for recall, observe, MCP tools, and compaction coordination\",\n capabilities: {\n observe: true,\n recall: true,\n store: true,\n search: true,\n entities: true,\n realtimeSync: true,\n batch: true,\n maxBudgetChars: 32000,\n connectionType: \"http\",\n },\n configSchema: {\n remnicDaemonUrl: \"URL of the Remnic daemon (default: http://127.0.0.1:4318)\",\n namespace: \"Optional namespace\",\n installExtension: \"Install the Pi extension into ~/.pi/agent/extensions/remnic (default: true)\",\n },\n homepage: \"https://pi.dev\",\n author: \"Remnic\",\n tags: [\"official\", \"ai\", \"pi\", \"coding-agent\"],\n requiresToken: true,\n },\n {\n id: \"replit\",\n name: \"Replit Agent\",\n version: \"1.0.0\",\n description: \"Replit Agent — memory via HTTP API (reduced capabilities)\",\n capabilities: {\n observe: true,\n recall: true,\n store: true,\n search: false,\n entities: false,\n realtimeSync: false,\n batch: false,\n maxBudgetChars: 8000,\n connectionType: \"http\",\n },\n configSchema: {\n apiUrl: \"URL of the Remnic HTTP API\",\n authToken: \"Bearer token for authentication\",\n },\n homepage: \"https://replit.com\",\n author: \"Replit\",\n tags: [\"official\", \"cloud\"],\n requiresToken: true,\n },\n {\n id: \"generic-mcp\",\n name: \"Generic MCP Client\",\n version: \"1.0.0\",\n description: \"Any MCP-compatible client — connect via standard MCP protocol\",\n capabilities: {\n observe: true,\n recall: true,\n store: true,\n search: true,\n entities: true,\n realtimeSync: true,\n batch: true,\n maxBudgetChars: 64000,\n connectionType: \"mcp\",\n },\n configSchema: {\n mcpServerUrl: \"URL of the MCP Remnic server\",\n namespace: \"Optional namespace\",\n authToken: \"Bearer token for authentication\",\n },\n homepage: \"https://github.com/joshuaswarren/remnic\",\n author: \"Remnic\",\n tags: [\"generic\", \"mcp\"],\n requiresToken: true,\n },\n {\n id: \"weclone\",\n name: \"WeClone Avatar\",\n version: \"1.0.0\",\n description:\n \"Memory-aware OpenAI-compatible proxy for deployed WeClone avatars — \" +\n \"injects Remnic recall into chat completions and buffers turns via observe\",\n capabilities: {\n observe: true,\n recall: true,\n store: false,\n search: false,\n entities: false,\n realtimeSync: false,\n batch: false,\n maxBudgetChars: 32000,\n connectionType: \"http\",\n },\n configSchema: {\n wecloneApiUrl:\n \"Base URL of the WeClone OpenAI-compatible API (e.g. http://localhost:8000/v1)\",\n proxyPort: \"Local port where the memory proxy will listen (default 8100)\",\n remnicDaemonUrl:\n \"URL of the Remnic daemon exposing /engram/v1/recall and /engram/v1/observe\",\n sessionStrategy:\n \"Per-caller session mapping strategy: 'caller-id' | 'single'\",\n wecloneModelName: \"Optional fine-tuned model name passed through to WeClone\",\n },\n homepage: \"https://github.com/xming521/weclone\",\n author: \"Remnic\",\n tags: [\"official\", \"ai\", \"weclone\", \"proxy\"],\n requiresToken: true,\n },\n {\n id: \"hermes\",\n name: \"Hermes Agent\",\n version: \"1.0.0\",\n description: \"Hermes Agent MemoryProvider — automatic recall/observe on every turn via Python plugin protocol\",\n capabilities: {\n observe: true,\n recall: true,\n store: true,\n search: true,\n entities: false,\n realtimeSync: true,\n batch: false,\n maxBudgetChars: 32000,\n connectionType: \"http\",\n },\n configSchema: {\n host: \"Remnic daemon host (default: 127.0.0.1)\",\n port: \"Remnic daemon port (default: 4318)\",\n profile: \"Hermes profile name (default: default)\",\n },\n homepage: \"https://github.com/joshuaswarren/remnic/tree/main/packages/plugin-hermes\",\n author: \"Remnic\",\n tags: [\"official\", \"python\", \"hermes\"],\n requiresToken: true,\n },\n];\n\n// ── Registry management ───────────────────────────────────────────────────\n\nconst REGISTRY_DIR_NAME = \".engram-connectors\";\n\nexport function getRegistryPath(): string {\n const xdgConfigHome = readEnvVar(\"XDG_CONFIG_HOME\");\n const configDir = xdgConfigHome\n ? path.join(xdgConfigHome, \"engram\")\n : path.join(resolveHomeDir(), \".config\", \"engram\");\n return path.join(configDir, REGISTRY_DIR_NAME, \"registry.json\");\n}\n\nexport function loadRegistry(): ConnectorRegistry {\n const regPath = getRegistryPath();\n\n if (!fs.existsSync(regPath)) {\n // First time — bootstrap with built-in connectors\n const registry: ConnectorRegistry = {\n connectors: BUILTIN_CONNECTORS,\n registryPath: regPath,\n };\n saveRegistry(registry);\n return registry;\n }\n\n const raw = fs.readFileSync(regPath, \"utf8\");\n try {\n const parsed = JSON.parse(raw);\n // Built-ins always take precedence over persisted entries with the same ID.\n // This ensures that upgraded manifests (e.g. newly-added requiresToken: true)\n // are never shadowed by stale registry.json entries from an older version.\n // Only connectors whose IDs are NOT in BUILTIN_CONNECTORS are preserved from\n // the persisted file — those are genuine user-added custom connectors.\n const builtinIds = new Set(BUILTIN_CONNECTORS.map((b) => b.id));\n const customOnly = (parsed.connectors ?? []).filter((c: ConnectorManifest) => !builtinIds.has(c.id));\n const merged = [...BUILTIN_CONNECTORS, ...customOnly];\n return {\n connectors: merged,\n registryPath: regPath,\n };\n } catch {\n const registry: ConnectorRegistry = {\n connectors: BUILTIN_CONNECTORS,\n registryPath: regPath,\n };\n saveRegistry(registry);\n return registry;\n }\n}\n\nexport function saveRegistry(registry: ConnectorRegistry): void {\n const regPath = registry.registryPath;\n fs.mkdirSync(path.dirname(regPath), { recursive: true });\n fs.writeFileSync(regPath, JSON.stringify({ connectors: registry.connectors }, null, 2));\n}\n\n// ── List connectors ────────────────────────────────────────────────────────\n\nexport function listConnectors(): {\n installed: ConnectorInstance[];\n available: ConnectorManifest[];\n} {\n const registry = loadRegistry();\n const connectorsDir = getConnectorsDir();\n const installedIds = new Set<string>();\n\n // Find installed connectors\n if (fs.existsSync(connectorsDir)) {\n for (const entry of fs.readdirSync(connectorsDir)) {\n if (entry.endsWith(\".json\")) {\n try {\n const config = JSON.parse(\n fs.readFileSync(path.join(connectorsDir, entry), \"utf8\"),\n );\n installedIds.add(config.connectorId as string);\n } catch {\n // ignore malformed configs\n }\n }\n }\n }\n\n // Mark installed vs available\n const available: ConnectorManifest[] = registry.connectors.map((manifest) => ({\n ...manifest,\n installed: installedIds.has(manifest.id),\n }));\n\n // Build installed list\n const installed: ConnectorInstance[] = [];\n for (const id of installedIds) {\n const configPath = path.join(connectorsDir, `${id}.json`);\n try {\n const raw = JSON.parse(fs.readFileSync(configPath, \"utf8\")) as Record<string, unknown>;\n // Codex P1 (PRRT_kwDORJXyws56U9U0): strip any legacy `token` field from\n // the returned config so that `remnic connectors list --json` never prints\n // a bearer token — tokens live only in tokens.json. This handles existing\n // on-disk connector.json files written by older Remnic versions without\n // rewriting user files.\n const { token: _redacted, ...config } = raw;\n installed.push({\n connectorId: id,\n config,\n status: \"installed\",\n installedAt: raw.installedAt as string | undefined,\n });\n } catch {\n // ignore\n }\n }\n\n return { installed, available };\n}\n\n// ── Get connector token ────────────────────────────────────────────────────\n// Codex P1 (PRRT_kwDORJXyws56U9U0): tokens are stored exclusively in\n// tokens.json. This helper is the canonical way to retrieve the bearer token\n// for a connector — connector.json never contains it.\n\nexport function getConnectorToken(connectorId: string): string | undefined {\n try {\n return loadTokenStore().tokens.find((t) => t.connector === connectorId)?.token;\n } catch {\n return undefined;\n }\n}\n\nfunction readSavedConnectorConfig(configPath: string): Record<string, unknown> {\n if (!fs.existsSync(configPath)) return {};\n try {\n const parsed = JSON.parse(fs.readFileSync(configPath, \"utf8\"));\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) return {};\n const {\n connectorId: _connectorId,\n installedAt: _installedAt,\n token: _token,\n ...config\n } = parsed as Record<string, unknown>;\n return config;\n } catch {\n return {};\n }\n}\n\nfunction removeClearedSavedConnectorConfig(\n savedConnectorConfig: Record<string, unknown>,\n rawUserConfig: Record<string, unknown>,\n): Record<string, unknown> {\n const merged: Record<string, unknown> = { ...savedConnectorConfig };\n for (const [key, value] of Object.entries(rawUserConfig)) {\n if (value === undefined || value === null || value === \"\") {\n delete merged[key];\n }\n }\n return merged;\n}\n\nfunction compactConnectorConfigOverrides(rawUserConfig: Record<string, unknown>): Record<string, unknown> {\n const safeUserConfig: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(rawUserConfig)) {\n if (value === undefined || value === null || value === \"\") continue;\n safeUserConfig[key] = value;\n }\n return safeUserConfig;\n}\n\n// ── Install connector ───────────────────────────────────────────────────────\n\nexport function installConnector(options: InstallOptions): InstallResult {\n const registry = loadRegistry();\n const manifest = registry.connectors.find((c) => c.id === options.connectorId);\n\n if (!manifest) {\n return {\n connectorId: options.connectorId,\n status: \"error\",\n message: `Unknown connector: ${options.connectorId}`,\n };\n }\n\n // Check if already installed\n const existing = listConnectors().installed.find(\n (c) => c.connectorId === options.connectorId,\n );\n\n if (existing && !options.force) {\n return {\n connectorId: options.connectorId,\n status: \"already_installed\",\n message: \"Already installed. Use --force to reinstall.\",\n };\n }\n\n // Write config\n const configDir = getConnectorsDir();\n fs.mkdirSync(configDir, { recursive: true });\n\n const configPath = path.join(configDir, `${options.connectorId}.json`);\n const savedConnectorConfig = existing ? readSavedConnectorConfig(configPath) : {};\n\n // For the hermes connector, resolve profile/host/port with the following\n // precedence: saved-connector-JSON → explicit options.config → defaults.\n // Reading happens BEFORE we overwrite the connector JSON so that a\n // force-reinstall without re-supplied --config options preserves the\n // previously configured values and writes the new token to the correct\n // Hermes profile rather than resetting to \"default\"/127.0.0.1/4318.\n //\n // Issue C fix: sanitizer calls during options resolution are wrapped in\n // try-catch so that invalid user-supplied values (e.g. --config port=abc)\n // return a clean failed InstallResult instead of throwing.\n let hermesSavedProfile: string | undefined;\n let hermesSavedHost: string | undefined;\n let hermesSavedPort: number | undefined;\n // Resolved values (used both in resolvedConfig and in the YAML update below)\n let hermesResolvedProfile: string | undefined;\n let hermesResolvedHost: string | undefined;\n let hermesResolvedPort: number | undefined;\n if (options.connectorId === \"hermes\") {\n if (fs.existsSync(configPath)) {\n try {\n const prev = JSON.parse(fs.readFileSync(configPath, \"utf8\"));\n // Fix 2: coerce saved values through sanitizers so that CLI-written\n // string ports (\"5555\") are accepted just like number ports (5555).\n // Pass each through its sanitizer and fall back to undefined on error\n // so a corrupt saved value doesn't prevent install from defaulting.\n if (prev?.profile != null) {\n try {\n hermesSavedProfile = sanitizeHermesProfile(String(prev.profile));\n } catch {\n // Invalid saved profile — fall through to default\n }\n }\n if (prev?.host != null) {\n try {\n hermesSavedHost = sanitizeHermesHost(String(prev.host));\n } catch {\n // Invalid saved host — fall through to default\n }\n }\n if (prev?.port != null) {\n try {\n const coercedPort = Number(String(prev.port));\n hermesSavedPort = sanitizeHermesPort(coercedPort);\n } catch {\n // Invalid saved port — fall through to default\n }\n }\n } catch {\n // Could not read existing config — fall through to defaults\n }\n }\n // Use saved/default values here; user-supplied profile/host are validated\n // and applied in the sanitization block below (single point of validation).\n hermesResolvedProfile = hermesSavedProfile ?? \"default\";\n hermesResolvedHost = hermesSavedHost ?? \"127.0.0.1\";\n\n // Issue C: wrap sanitizeHermesPort (and profile/host) in try-catch so\n // that invalid user-supplied values return a clean error result.\n if (options.config?.port !== undefined) {\n try {\n hermesResolvedPort = sanitizeHermesPort(Number(String(options.config.port)));\n } catch (err) {\n return {\n connectorId: options.connectorId,\n status: \"error\",\n message: `Invalid Hermes config: ${err instanceof Error ? err.message : String(err)}`,\n };\n }\n }\n if (hermesResolvedPort === undefined) {\n hermesResolvedPort = hermesSavedPort ?? 4318;\n }\n\n // Also validate user-supplied profile and host up-front (Issue C coverage).\n if (options.config?.profile !== undefined) {\n try {\n hermesResolvedProfile = sanitizeHermesProfile(String(options.config.profile));\n } catch (err) {\n return {\n connectorId: options.connectorId,\n status: \"error\",\n message: `Invalid Hermes config: ${err instanceof Error ? err.message : String(err)}`,\n };\n }\n }\n if (options.config?.host !== undefined) {\n try {\n hermesResolvedHost = sanitizeHermesHost(String(options.config.host));\n } catch (err) {\n return {\n connectorId: options.connectorId,\n status: \"error\",\n message: `Invalid Hermes config: ${err instanceof Error ? err.message : String(err)}`,\n };\n }\n }\n }\n\n // Generate a per-connector auth token so the daemon can authenticate\n // requests from this connector.\n //\n // Security gate (PRRT_kwDORJXyws56U9U0 round 6): tokens are ONLY generated\n // and persisted to tokens.json for connectors that actually require bearer-token\n // auth (manifest.requiresToken === true). MCP, CLI, embedded, and SDK connectors\n // never need a token entry on disk — generating one unconditionally materialized\n // credentials for connectors that have no auth requirement, a security regression.\n //\n // For hermes (Issue B fix): use buildTokenEntry() to generate a candidate\n // token WITHOUT immediately persisting it to tokens.json. We commit the\n // candidate to the store only AFTER upsertHermesConfig succeeds, so that\n // a failed or skipped config.yaml write never leaves the daemon with a\n // revoked token and no valid replacement written.\n //\n // For other connectors that requiresToken: generateToken() is idempotent —\n // it filters the old entry and writes a fresh one atomically, so force-reinstall\n // produces a new token automatically.\n //\n // Token write errors (e.g. read-only HOME with writable XDG_CONFIG_HOME)\n // are non-fatal: we degrade gracefully and proceed with the connector\n // config write rather than aborting the whole install.\n //\n // For non-Hermes connectors that requiresToken: snapshot the FULL token store\n // BEFORE generateToken() so that if the connector JSON write later fails, we\n // can restore the store to its pre-install state (UXJG fix — non-Hermes atomic\n // rollback). Using a full-store snapshot (not a single-entry snapshot) ensures\n // that a partial write of tokens.json during generateToken can be unwound\n // atomically, covering both fresh-install and force-reinstall cases uniformly.\n const nonHermesPriorTokenStore = (options.connectorId !== \"hermes\" && manifest.requiresToken)\n ? loadTokenStore()\n : null;\n\n let tokenEntry: ReturnType<typeof generateToken> | null = null;\n if (options.connectorId === \"hermes\") {\n // Build a candidate token; do NOT save yet (Issue B).\n try {\n tokenEntry = buildTokenEntry(options.connectorId);\n } catch {\n // Non-fatal: fall through with tokenEntry === null.\n }\n } else if (manifest.requiresToken) {\n // Only generate and persist a token entry for connectors that need token auth.\n try {\n tokenEntry = generateToken(options.connectorId);\n } catch {\n // Non-fatal: token store unavailable. Connector config will still be\n // written; user can run `remnic token generate <id>` to create the token.\n //\n // Roll back the snapshot so that a partial write of tokens.json during\n // generateToken (e.g. ENOSPC/EIO mid-write) does not leave other\n // connectors' auth state corrupted. Best-effort: if the restore itself\n // fails there is nothing more we can do here, but the error is swallowed\n // so install continues in the same degraded (tokenEntry === null) path\n // as before (PRRT_kwDORJXyws56UleN fix).\n if (nonHermesPriorTokenStore !== null) {\n try {\n saveTokenStore(nonHermesPriorTokenStore);\n } catch {\n // Best-effort: snapshot restore failed; caller sees degraded install.\n }\n }\n }\n }\n // else: connector does not require token auth — tokenEntry stays null and\n // tokens.json is never touched for this connector.\n\n // Thread 2 (PRRT_kwDORJXyws56VYwM): if the connector requires token auth but\n // generateToken threw (tokenEntry is still null), abort now instead of\n // continuing with a broken install that returns \"success\" without a valid token.\n if (options.connectorId !== \"hermes\" && manifest.requiresToken && tokenEntry === null) {\n return {\n connectorId: options.connectorId,\n status: \"error\",\n message:\n `${manifest.name} install aborted: token generation failed. ` +\n `Run \\`remnic token generate ${options.connectorId}\\` to create the token, then reinstall.`,\n };\n }\n\n // Build config from saved values + user overrides.\n // Codex P1 (PRRT_kwDORJXyws56U9U0): tokens MUST NOT be written into\n // connector.json. The authoritative store is tokens.json (0o600). Writing the\n // token here created a second, unredacted copy that `remnic connectors list\n // --json` printed verbatim, leaking live bearer tokens into shell history, CI\n // logs, and telemetry. Callers needing the token for a specific connector\n // must use loadTokenStore() and find the entry by connectorId directly.\n //\n // For hermes, include the resolved profile/host/port so that future\n // force-reinstalls can read them back even if options.config is not supplied.\n //\n // Strip any stray `token` key the caller may have supplied via options.config\n // so it cannot be persisted to disk even on legacy call paths.\n const { token: _callerToken, ...rawUserConfig } = (options.config ?? {}) as Record<string, unknown>;\n const savedConnectorConfigForMerge = removeClearedSavedConnectorConfig(savedConnectorConfig, rawUserConfig);\n const safeUserConfig = compactConnectorConfigOverrides(rawUserConfig);\n const resolvedConfig: Record<string, unknown> = {\n ...savedConnectorConfigForMerge,\n ...safeUserConfig,\n connectorId: options.connectorId,\n installedAt: new Date().toISOString(),\n // For hermes, always overlay the sanitized/coerced resolved values so that\n // the connector JSON always has a numeric port and validated profile/host.\n // This also ensures options.config string values (from --config=port=5555)\n // are replaced with their sanitized numeric equivalents (Fix 2 root cause).\n ...(hermesResolvedProfile !== undefined ? {\n profile: hermesResolvedProfile,\n host: hermesResolvedHost,\n port: hermesResolvedPort,\n } : {}),\n };\n\n // ── Hermes atomic install flow ─────────────────────────────────────────────\n // The Hermes install sequence must be atomic: connector.json must only be\n // written if and only if both the YAML write AND the token-store commit\n // succeed. Partial failures must leave the prior state intact so the daemon\n // keeps working with the old token.\n //\n // Step order (all-or-nothing):\n // a. Generate token candidate (buildTokenEntry, no store write yet).\n // b. Validate profile (fail-fast).\n // c. Write config.yaml via upsertHermesConfig — if skipped (missing dir)\n // or throws, abort with status \"error\". Old token is NOT revoked.\n // d. Commit new token to tokens.json — if this throws, rollback the YAML\n // write (restore prior content or delete new file) and abort.\n // e. Write connector.json only after both (c) and (d) succeed.\n // f. Health check — gated on committed === true && tokenEntry != null.\n //\n // Non-Hermes connectors: connector.json is written immediately (no YAML\n // dependency) and the health check is not performed.\n\n if (options.connectorId === \"hermes\") {\n // hermesResolvedProfile/Host/Port were computed above using the correct\n // precedence (saved JSON → explicit options.config → defaults).\n const rawProfile = hermesResolvedProfile!;\n const hermesHost = hermesResolvedHost!;\n const hermesPort = hermesResolvedPort!;\n\n // (b) Validate profile name — fail-fast before touching any files.\n let hermesProfile: string;\n try {\n hermesProfile = sanitizeHermesProfile(rawProfile);\n } catch (err) {\n return {\n connectorId: options.connectorId,\n status: \"error\",\n message: `Hermes install aborted: ${err instanceof Error ? err.message : String(err)}`,\n };\n }\n\n // Token generation is required for an atomic Hermes install.\n if (!tokenEntry) {\n return {\n connectorId: options.connectorId,\n status: \"error\",\n message:\n \"Hermes install aborted: token store unavailable. \" +\n \"Run `remnic token generate hermes` then reinstall to complete setup.\",\n };\n }\n\n // (c) Write config.yaml. If the profile dir does not exist (skipped) or\n // the write throws, abort WITHOUT committing the token or writing connector.json.\n let yamlResult: HermesConfigResult;\n try {\n yamlResult = upsertHermesConfig({\n profile: hermesProfile,\n host: hermesHost,\n port: hermesPort,\n token: tokenEntry.token,\n });\n } catch (err) {\n // upsertHermesConfig threw — old token preserved, connector.json unchanged.\n return {\n connectorId: options.connectorId,\n status: \"error\",\n message: `Hermes install aborted: config.yaml write failed — ${err instanceof Error ? err.message : String(err)}`,\n };\n }\n\n if (!yamlResult.updated) {\n // Skipped (profile dir missing) — abort so connector.json is NOT written\n // with a token the daemon won't recognize (the profile doesn't exist).\n // Preserves any prior Hermes profile/connector.json untouched.\n return {\n connectorId: options.connectorId,\n status: \"error\",\n message: `Hermes install aborted: ${yamlResult.reason ?? \"config.yaml not written\"}. ` +\n `Create the Hermes profile directory first, then reinstall.`,\n };\n }\n\n // (d) Commit token to tokens.json. If this fails, roll back the YAML write\n // and abort — the old token must remain valid and connector.json must stay\n // unchanged so the daemon keeps working.\n //\n // IMPORTANT (UXJI/UXJT): Snapshot the FULL token store BEFORE calling\n // commitTokenEntry(). A single-entry approach (capturing the return value\n // of commitTokenEntry) is insufficient: if commitTokenEntry throws mid-write\n // (e.g. ENOSPC truncating tokens.json), the assignment never completes and\n // the rollback becomes a no-op, leaving tokens.json potentially corrupt.\n // The full-store snapshot, captured before the write attempt, is guaranteed\n // clean and can be written back atomically by saveTokenStore.\n const priorTokenStore = loadTokenStore();\n let committed = false;\n try {\n commitTokenEntry(tokenEntry);\n committed = true;\n } catch (commitErr) {\n // Roll back the token store: restore the full snapshot so a partial write\n // (e.g. ENOSPC truncating tokens.json mid-write) cannot leave the store\n // corrupt or missing the prior hermes entry.\n let tokensRolledBack = true;\n let tokensRollbackErrMsg = \"\";\n try {\n saveTokenStore(priorTokenStore);\n } catch (tokenRestoreErr) {\n tokensRolledBack = false;\n tokensRollbackErrMsg = tokenRestoreErr instanceof Error ? tokenRestoreErr.message : String(tokenRestoreErr);\n }\n // Roll back the YAML write: restore prior content (or delete newly-created file).\n let yamlRolledBack = true;\n let yamlRollbackErrMsg = \"\";\n try {\n if (yamlResult.priorContent === null) {\n // File was created new — remove it entirely.\n fs.unlinkSync(yamlResult.configPath);\n } else if (typeof yamlResult.priorContent === \"string\") {\n // File existed before — restore original content.\n writeSecretFileSync(yamlResult.configPath, yamlResult.priorContent);\n }\n } catch (yamlRestoreErr) {\n yamlRolledBack = false;\n yamlRollbackErrMsg = yamlRestoreErr instanceof Error ? yamlRestoreErr.message : String(yamlRestoreErr);\n }\n // Build an error message that accurately reflects which rollbacks succeeded.\n const commitErrMsg = commitErr instanceof Error ? commitErr.message : String(commitErr);\n let message: string;\n if (tokensRolledBack && yamlRolledBack) {\n message =\n `Hermes install failed during token commit — ` +\n `${commitErrMsg}. ` +\n `config.yaml and tokens.json restored to prior state. ` +\n `Resolve the tokens.json access issue, then reinstall.`;\n } else if (!yamlRolledBack && tokensRolledBack) {\n message =\n `Hermes install failed during token commit — ` +\n `${commitErrMsg}. ` +\n `tokens.json restored but config.yaml rollback ALSO failed ` +\n `(${yamlRollbackErrMsg}). ` +\n `Hermes daemon may be in an inconsistent state: config references a stale token. ` +\n `Manually inspect ${yamlResult.configPath} and reinstall.`;\n } else if (yamlRolledBack && !tokensRolledBack) {\n message =\n `Hermes install failed during token commit — ` +\n `${commitErrMsg}. ` +\n `config.yaml restored but tokens.json rollback ALSO failed ` +\n `(${tokensRollbackErrMsg}). ` +\n `Hermes daemon may be in an inconsistent state: tokens.json is corrupt or incomplete. ` +\n `Manually inspect ~/.remnic/tokens.json and reinstall.`;\n } else {\n message =\n `Hermes install failed during token commit — ` +\n `${commitErrMsg}. ` +\n `BOTH rollbacks failed: config.yaml rollback failed (${yamlRollbackErrMsg}); ` +\n `tokens.json rollback failed (${tokensRollbackErrMsg}). ` +\n `Hermes daemon is likely in an inconsistent state. ` +\n `Manually inspect ${yamlResult.configPath} ` +\n `and ~/.remnic/tokens.json, then reinstall.`;\n }\n return {\n connectorId: options.connectorId,\n status: \"error\",\n message,\n };\n }\n\n // (e) Both YAML write and token commit succeeded — now attempt to write connector.json.\n // If this write fails (e.g. connectors dir is not writable), roll back Phase D (token\n // commit) and Phase C (YAML upsert) so no partial-install state is left behind.\n // We restore the full token store snapshot captured before Phase D so that\n // tokens.json is guaranteed consistent with the rolled-back config.yaml.\n try {\n writeSecretFileSync(configPath, JSON.stringify(resolvedConfig, null, 2));\n } catch (writeErr) {\n // Roll back Phase D: restore the full token store snapshot so tokens.json\n // is consistent with the rolled-back config.yaml.\n let tokenRollbackFailed = false;\n let tokenRollbackMsg = \"token store restored to pre-install snapshot\";\n try {\n saveTokenStore(priorTokenStore);\n } catch (tokenRestoreErr) {\n tokenRollbackFailed = true;\n tokenRollbackMsg = `token rollback failed: ${tokenRestoreErr instanceof Error ? tokenRestoreErr.message : String(tokenRestoreErr)}`;\n }\n // Roll back Phase C: restore config.yaml to its prior content.\n let yamlRollbackMsg = \"config.yaml restored\";\n try {\n if (yamlResult.priorContent === null) {\n // File was created new — delete it. Track whether the unlink actually\n // succeeded so we report honestly rather than claiming removal when it\n // silently failed inside the inner catch.\n let unlinkSucceeded = false;\n let unlinkErr: unknown;\n try {\n fs.unlinkSync(yamlResult.configPath);\n unlinkSucceeded = true;\n } catch (err) {\n unlinkErr = err;\n }\n if (unlinkSucceeded) {\n yamlRollbackMsg = \"config.yaml removed (was newly created)\";\n } else {\n const unlinkMsg = unlinkErr instanceof Error ? unlinkErr.message : String(unlinkErr);\n yamlRollbackMsg = `config.yaml rollback failed: could not remove newly-created file — ${unlinkMsg}`;\n }\n } else if (typeof yamlResult.priorContent === \"string\") {\n writeSecretFileSync(yamlResult.configPath, yamlResult.priorContent);\n yamlRollbackMsg = \"config.yaml restored to prior content\";\n }\n } catch (yamlRollbackErr) {\n yamlRollbackMsg = `config.yaml rollback failed: ${yamlRollbackErr instanceof Error ? yamlRollbackErr.message : String(yamlRollbackErr)}`;\n }\n const urgentSuffix = tokenRollbackFailed\n ? ` tokens.json may be in an inconsistent state — manually restore hermes token with 'remnic token generate hermes'.`\n : \"\";\n return {\n connectorId: options.connectorId,\n status: \"error\",\n message:\n `Hermes install aborted: connector config write failed — ` +\n `connector directory may not be writable. ` +\n `Rollback: ${tokenRollbackMsg}; ${yamlRollbackMsg}.` +\n `${urgentSuffix} Resolve the permission issue, then reinstall.`,\n };\n }\n\n const notes: string[] = [];\n notes.push(`Updated Hermes config: ${yamlResult.configPath}`);\n\n // If a migrated default-profile install now writes to Hermes' root config,\n // remove stale Remnic credentials from the legacy default profile file too.\n if (hermesProfile === \"default\") {\n const legacyDefaultConfigPath = hermesDefaultProfileConfigPath();\n if (!sameHermesConfigTarget(yamlResult.configPath, legacyDefaultConfigPath)) {\n try {\n const legacyDefaultCleanResult = removeHermesConfigFile(legacyDefaultConfigPath);\n if (legacyDefaultCleanResult.updated) {\n notes.push(`Cleaned stale remnic: block from legacy default profile: ${legacyDefaultConfigPath}`);\n }\n } catch {\n notes.push(\"Note: could not clean stale remnic: block from legacy default profile\");\n }\n }\n }\n\n // Clean up the old profile's remnic: block if the profile changed.\n // Compare resolved config paths (not raw strings) so that case-insensitive\n // filesystems (macOS default) don't treat \"Research\" and \"research\" as\n // different profiles — resolving both would yield the same config.yaml,\n // and removing it would strip the block we just wrote (PRRT_kwDORJXyws56VQ76).\n let oldProfileResolvesToDifferentFile = false;\n if (hermesSavedProfile !== undefined) {\n try {\n oldProfileResolvesToDifferentFile =\n !sameHermesConfigTarget(hermesConfigPath(hermesSavedProfile), hermesConfigPath(hermesProfile));\n } catch {\n // If either profile fails sanitization the comparison is moot; skip cleanup.\n oldProfileResolvesToDifferentFile = false;\n }\n }\n if (oldProfileResolvesToDifferentFile) {\n try {\n const oldCleanResult = removeHermesConfig({ profile: hermesSavedProfile! });\n if (oldCleanResult.updated) {\n notes.push(`Cleaned stale remnic: block from previous profile: ${oldCleanResult.configPath}`);\n }\n } catch {\n // Non-fatal: if we can't clean the old profile, log a note but don't fail.\n notes.push(`Note: could not clean stale remnic: block from previous profile \"${hermesSavedProfile}\"`);\n }\n }\n\n // (f) Health check — only when the token was actually committed to the store.\n // Without commitment, the daemon won't recognise the token → 401 → 6s sleep\n // → false-negative \"Daemon not reachable\". committed is always true here\n // (we returned early on failure above) but the explicit guard is kept for\n // clarity and future robustness.\n if (committed && tokenEntry) {\n const daemonOk = checkDaemonHealth(hermesHost, hermesPort, tokenEntry.token);\n if (daemonOk) {\n notes.push(\"Daemon health check: OK\");\n } else {\n notes.push(\n `Daemon not reachable at ${hermesHost}:${hermesPort} — start with: remnic daemon start`,\n );\n }\n }\n\n const suffix = notes.length > 0 ? `\\n ${notes.join(\"\\n \")}` : \"\";\n return {\n connectorId: options.connectorId,\n status: \"installed\",\n configPath,\n message: `Installed ${manifest.name} v${manifest.version}${suffix}`,\n };\n }\n\n // ── Non-Hermes connectors: write connector.json ───────────────────────────\n // Write with owner-only permissions because the JSON may embed the\n // connector bearer token. Matches the 0o600 hardening on\n // ~/.remnic/tokens.json so the token is never world-readable via this\n // secondary location.\n\n // Codex CLI: also drop the phase-2 memory extension unless the caller\n // explicitly opted out via `config.installExtension: false`.\n let extensionMessage = \"\";\n // Explicit structured flag for the config-write rollback gate. This MUST\n // stay decoupled from `extensionMessage` because that string embeds the\n // install path — substring-matching on \"skipped\" would misfire whenever\n // the codex home happens to contain the word \"skipped\".\n let extensionInstalled = false;\n // Holds the commit/rollback handle returned by installCodexMemoryExtension().\n // The backup of any prior extension is kept alive until commit() is called.\n let extensionHandle: { commit(): void; rollback(): void } | null = null;\n if (options.connectorId === \"codex-cli\") {\n // Finding 1: coerce string \"false\"/\"true\" from CLI config parsing to a real\n // boolean before the gate check, then persist the coerced value so it is\n // stored as a boolean in the config file.\n const coerced = coerceInstallExtension(resolvedConfig.installExtension);\n if (coerced !== undefined) {\n resolvedConfig.installExtension = coerced;\n }\n const shouldInstall = resolvedConfig.installExtension !== false;\n // Persist the effective installExtension boolean explicitly so that\n // removeConnector's provenance check (Finding 3) can match. When the caller\n // did not pass the key, the default is true — write it so later removal\n // knows Remnic owned the install.\n resolvedConfig.installExtension = shouldInstall;\n // Resolve the Codex home path NOW so we can persist the absolute path\n // into the saved config. This guarantees removeConnector can target the\n // exact same directory later even if $CODEX_HOME is unset or changed.\n const codexHomeOverride =\n typeof resolvedConfig.codexHome === \"string\" && resolvedConfig.codexHome.length > 0\n ? (resolvedConfig.codexHome as string)\n : null;\n const resolvedCodexHome = resolveCodexHome(codexHomeOverride);\n resolvedConfig.codexHome = resolvedCodexHome;\n\n if (shouldInstall) {\n try {\n const extensionSourceOverride =\n typeof resolvedConfig.extensionSourceDir === \"string\" &&\n resolvedConfig.extensionSourceDir.length > 0\n ? (resolvedConfig.extensionSourceDir as string)\n : null;\n const extResult = installCodexMemoryExtension({\n codexHome: resolvedCodexHome,\n sourceDir: extensionSourceOverride,\n });\n extensionMessage = ` (memory extension: ${extResult.remnicExtensionDir})`;\n extensionInstalled = true;\n extensionHandle = extResult;\n } catch (err) {\n const errMsg = err instanceof Error ? err.message : \"unknown error\";\n // Codex P2 (PRRT_kwDORJXyws56Ur_G): generateToken already rotated\n // tokens.json before reaching this point. The extension threw, so no\n // connector.json was written — roll back the token store to the\n // pre-install snapshot so tokens.json and the absent connector.json\n // stay consistent (no orphaned/active token without a matching config).\n //\n // Initialize to false: only set true once saveTokenStore() succeeds.\n // For connectors without requiresToken the rollback block is skipped\n // entirely, so the suffix must remain absent — not \"Token has been\n // rolled back.\" (which would be factually incorrect).\n let extensionErrTokenRolledBack = false;\n let extensionErrTokenRollbackMsg = \"\";\n if (tokenEntry !== null && nonHermesPriorTokenStore !== null) {\n try {\n saveTokenStore(nonHermesPriorTokenStore);\n extensionErrTokenRolledBack = true;\n } catch (tokenRestoreErr) {\n extensionErrTokenRolledBack = false;\n extensionErrTokenRollbackMsg =\n tokenRestoreErr instanceof Error ? tokenRestoreErr.message : String(tokenRestoreErr);\n }\n }\n // Only include a token-rollback suffix for connectors that have a token\n // to roll back. Non-token connectors (requiresToken !== true) never\n // generated a token entry, so no rollback occurred and the message must\n // not claim otherwise.\n const tokenRollbackSuffix = manifest.requiresToken\n ? extensionErrTokenRolledBack\n ? \" Token has been rolled back.\"\n : ` Token rollback FAILED (${extensionErrTokenRollbackMsg}) — tokens.json may contain an orphaned entry. ` +\n `Manually inspect ~/.remnic/tokens.json and reinstall.`\n : \"\";\n return {\n connectorId: options.connectorId,\n status: \"error\",\n message: `Memory extension install failed — ${errMsg}.${tokenRollbackSuffix} Resolve the issue, then reinstall.`,\n };\n }\n } else {\n extensionMessage = \" (memory extension: skipped via installExtension=false)\";\n }\n }\n\n // ── WeClone: write proxy config to ~/.remnic/connectors/weclone.json ─────\n //\n // The standalone `remnic-weclone-proxy` CLI (see packages/connector-weclone)\n // reads its config from ~/.remnic/connectors/weclone.json by default so the\n // proxy can start without depending on Remnic's XDG-scoped registry layout.\n // Compose and write that file here, BEFORE the registry connector.json is\n // written, so that a failure in either file's write path rolls back cleanly.\n //\n // Precedence for each field: user-supplied via --config → saved prior proxy\n // config (on --force) → manifest defaults. The generated bearer token (if\n // any) is persisted into remnicAuthToken so the proxy can authenticate with\n // the daemon without a second token lookup at runtime.\n let weCloneProxyHandleRollback: (() => void) | null = null;\n if (options.connectorId === \"weclone\") {\n try {\n // Force-reinstall (and any reinstall path) must keep using the exact\n // proxy config path that was persisted on the previous install. If we\n // re-derive from the current env each time, a user whose REMNIC_HOME /\n // ENGRAM_HOME changed between installs would end up with two proxy\n // config files — the old one stays with stale settings + a revoked\n // token, the new one gets the live token, and any running proxy still\n // reading the old file starts failing auth. Read the saved\n // `proxyConfigPath` from the existing registry config first, and only\n // fall back to env-derivation for genuine first-time installs.\n let proxyConfigPath: string | null = null;\n if (existing && fs.existsSync(configPath)) {\n try {\n const savedRegistryConfig = JSON.parse(fs.readFileSync(configPath, \"utf8\")) as Record<string, unknown>;\n if (\n typeof savedRegistryConfig.proxyConfigPath === \"string\" &&\n savedRegistryConfig.proxyConfigPath.length > 0\n ) {\n proxyConfigPath = savedRegistryConfig.proxyConfigPath;\n }\n } catch {\n // Saved registry config unreadable — fall through to env resolution.\n }\n }\n if (proxyConfigPath === null) {\n proxyConfigPath = resolveWeCloneProxyConfigPath();\n }\n const prior = readWeCloneProxyConfigIfExists(proxyConfigPath);\n const proxyConfig = buildWeCloneProxyConfig({\n userConfig: safeUserConfig,\n priorConfig: prior ? safeParseJson(prior) : null,\n authToken: tokenEntry?.token,\n });\n fs.mkdirSync(path.dirname(proxyConfigPath), { recursive: true });\n // Install the rollback closure BEFORE the write starts. `writeSecretFileSync`\n // opens the file in truncate mode, so a mid-write failure (ENOSPC, EPERM)\n // could leave `weclone.json` empty. Creating the rollback now guarantees\n // we can always restore prior content (or delete a newly-created file)\n // even if the write itself throws.\n weCloneProxyHandleRollback = () => {\n try {\n if (prior === null) {\n // File was created (or would have been created) by this install —\n // delete whatever is left behind, if anything.\n if (fs.existsSync(proxyConfigPath)) {\n fs.unlinkSync(proxyConfigPath);\n }\n } else {\n writeSecretFileSync(proxyConfigPath, prior);\n }\n } catch {\n // Best-effort rollback.\n }\n };\n try {\n writeSecretFileSync(\n proxyConfigPath,\n JSON.stringify(proxyConfig, null, 2),\n );\n } catch (writeErr) {\n // Truncate-and-write failed partway through — restore the file (or\n // remove the empty partial) and re-throw so the outer catch drives\n // the structured error response + token rollback.\n try {\n weCloneProxyHandleRollback();\n } catch {\n // Best-effort.\n }\n weCloneProxyHandleRollback = null;\n throw writeErr;\n }\n // Record the proxy-side config path on the registry JSON so operators\n // and `remnic connectors doctor weclone` can locate it later. Persist the\n // effective proxy port so `remnic connectors list` reflects the resolved\n // value rather than whatever (possibly missing) the user supplied.\n resolvedConfig.proxyConfigPath = proxyConfigPath;\n resolvedConfig.proxyPort = proxyConfig.proxyPort;\n resolvedConfig.wecloneApiUrl = proxyConfig.wecloneApiUrl;\n resolvedConfig.remnicDaemonUrl = proxyConfig.remnicDaemonUrl;\n resolvedConfig.sessionStrategy = proxyConfig.sessionStrategy;\n } catch (weCloneErr) {\n // Track token rollback success/failure explicitly so the error message\n // can truthfully report whether tokens.json was restored or is in a\n // potentially-inconsistent state. Mirrors the care taken in the\n // registry-config-write failure handler below.\n let tokenRolledBack = false;\n let tokenRollbackMsg = \"\";\n if (tokenEntry !== null && nonHermesPriorTokenStore !== null) {\n try {\n saveTokenStore(nonHermesPriorTokenStore);\n tokenRolledBack = true;\n } catch (tokenRestoreErr) {\n tokenRolledBack = false;\n tokenRollbackMsg =\n tokenRestoreErr instanceof Error ? tokenRestoreErr.message : String(tokenRestoreErr);\n }\n }\n const tokenSuffix = manifest.requiresToken && tokenEntry !== null\n ? tokenRolledBack\n ? \" Token has been rolled back.\"\n : ` Token rollback FAILED (${tokenRollbackMsg}) — tokens.json may contain an orphaned entry. ` +\n `Manually inspect ~/.remnic/tokens.json and reinstall.`\n : \"\";\n return {\n connectorId: options.connectorId,\n status: \"error\",\n message:\n `WeClone install aborted: proxy config write failed — ` +\n `${weCloneErr instanceof Error ? weCloneErr.message : String(weCloneErr)}.` +\n `${tokenSuffix} Resolve the write permission issue on ~/.remnic/connectors/, then reinstall.`,\n };\n }\n }\n\n // Finding 5: strip internal/test-only keys that must never be persisted to\n // the config file. These keys are used at install time only (e.g. to inject\n // a synthetic extension source dir in tests) and have no meaning on disk.\n // Denylist — add any future test-only keys here with a comment.\n const INTERNAL_KEYS_DENYLIST = [\n \"extensionSourceDir\", // test-only override for the plugin-codex source path\n ];\n for (const key of INTERNAL_KEYS_DENYLIST) {\n delete resolvedConfig[key];\n }\n\n // Atomic rollback (UXJG / Codex P1): if the JSON write fails (e.g., permission\n // denied on XDG_CONFIG_HOME), generateToken() above already rotated the token in\n // tokens.json. Roll back via the full-store snapshot captured before generateToken\n // so tokens.json and the absent connector.json stay consistent — no stale token\n // lingers without a matching config file. Full-store restore (vs. single-entry\n // restore/revoke) handles partial writes atomically for both fresh-install and\n // force-reinstall paths uniformly.\n //\n // Also roll back any codex-cli memory extension if the config write fails so\n // that no dangling memories_extensions/remnic directory is left with no config\n // provenance for removeConnector to find and clean up later.\n try {\n writeSecretFileSync(configPath, JSON.stringify(resolvedConfig, null, 2));\n } catch (writeErr) {\n // Roll back non-hermes token store if needed. Track success so we can\n // report accurately — unconditionally claiming rollback succeeded when it\n // silently failed would leave operators unable to diagnose inconsistent state.\n //\n // Initialize to false: only set true once saveTokenStore() succeeds.\n // Non-token connectors skip this block entirely, so we must not emit a\n // \"Token has been rolled back.\" suffix for them.\n let configWriteTokenRolledBack = false;\n let configWriteTokenRollbackMsg = \"\";\n if (tokenEntry !== null && nonHermesPriorTokenStore !== null) {\n try {\n saveTokenStore(nonHermesPriorTokenStore);\n configWriteTokenRolledBack = true;\n } catch (tokenRestoreErr) {\n configWriteTokenRolledBack = false;\n configWriteTokenRollbackMsg =\n tokenRestoreErr instanceof Error ? tokenRestoreErr.message : String(tokenRestoreErr);\n }\n }\n // Roll back the codex-cli extension if it was installed.\n // Use extensionHandle.rollback() so that a pre-existing (possibly\n // customised) extension is restored from the backup kept by\n // installCodexMemoryExtension(), rather than unconditionally deleted.\n if (extensionInstalled && extensionHandle !== null) {\n try {\n extensionHandle.rollback();\n } catch {\n // Best-effort rollback: log but don't mask the original write error.\n console.warn(\n \"[remnic/connectors] installConnector: config write failed and extension rollback also failed — \" +\n \"manual cleanup of memories_extensions/remnic may be required.\",\n );\n }\n }\n // Roll back the WeClone proxy config if it was written.\n if (weCloneProxyHandleRollback !== null) {\n try {\n weCloneProxyHandleRollback();\n } catch {\n // Best-effort rollback.\n }\n }\n // Only include a token-rollback suffix for connectors that actually had a\n // token to roll back. Non-token connectors (requiresToken !== true) never\n // generated a token entry. For requiresToken connectors where generateToken\n // threw (tokenEntry === null), no token was written to tokens.json so no\n // rollback occurred — avoid a misleading \"Token rollback FAILED\" message\n // (Thread 1, PRRT_kwDORJXyws56VVnB).\n const configWriteTokenSuffix = manifest.requiresToken && tokenEntry !== null\n ? configWriteTokenRolledBack\n ? \" Token has been rolled back.\"\n : ` Token rollback FAILED (${configWriteTokenRollbackMsg}) — tokens.json may contain an orphaned entry. ` +\n `Manually inspect ~/.remnic/tokens.json and reinstall.`\n : \"\";\n return {\n connectorId: options.connectorId,\n status: \"error\",\n message:\n `${manifest.name} install aborted: connector config write failed — ` +\n `${writeErr instanceof Error ? writeErr.message : String(writeErr)}.` +\n `${configWriteTokenSuffix} Resolve the write permission issue, then reinstall.`,\n };\n }\n\n // Config write succeeded — permanently drop the backup of the prior extension.\n if (extensionInstalled && extensionHandle !== null) {\n extensionHandle.commit();\n }\n\n return {\n connectorId: options.connectorId,\n status: \"installed\",\n configPath,\n message: `Installed ${manifest.name} v${manifest.version}${extensionMessage}`,\n };\n}\n\n// ── Remove connector ───────────────────────────────────────────────────────\n\nexport function removeConnector(connectorId: string): RemoveResult {\n const configDir = getConnectorsDir();\n const configPath = path.join(configDir, `${connectorId}.json`);\n\n // For codex-cli, read the saved config BEFORE touching anything so we have\n // both the persisted codexHome and the installExtension flag available for\n // later use in extension removal (Findings 1, 3, 4, 5).\n let codexHomeOverride: string | null = null;\n let savedInstallExtension: boolean | undefined = undefined;\n // Finding 1: track whether config parsing succeeded. If parsing throws, we\n // cannot trust any metadata and must fail closed (skip extension removal).\n let configParsed = false;\n if (connectorId === \"codex-cli\" && fs.existsSync(configPath)) {\n try {\n const parsed = JSON.parse(fs.readFileSync(configPath, \"utf8\")) as Record<string, unknown>;\n configParsed = true;\n if (typeof parsed.codexHome === \"string\" && parsed.codexHome.length > 0) {\n codexHomeOverride = parsed.codexHome;\n }\n // Finding 4: coerce saved installExtension so string \"false\" still works.\n const coerced = coerceInstallExtension(parsed.installExtension);\n if (coerced !== undefined) {\n savedInstallExtension = coerced;\n }\n } catch {\n // Finding 1: config is malformed — log debug and fail closed.\n // codexHomeOverride and savedInstallExtension remain unset; configParsed\n // stays false so extension removal is skipped below.\n console.debug(\n \"[remnic/connectors] removeConnector: codex-cli.json parse failed — skipping extension removal to avoid touching unverified paths\",\n );\n }\n }\n\n if (!fs.existsSync(configPath)) {\n // Best-effort: revoke any orphan token that may have survived a prior partial\n // cleanup (e.g. connector JSON deleted manually or XDG_CONFIG_HOME change).\n // This prevents a stale bearer token from remaining valid in tokens.json while\n // the connector appears \"not installed\" to the caller.\n // Config file is missing — we have no evidence that this installation ever\n // managed the extension directory, so it is unsafe to remove it (the user\n // may have self-managed it or installed with installExtension=false).\n // Skip removeCodexMemoryExtension entirely in this recovery path.\n let staleTokenRevoked = false;\n try {\n staleTokenRevoked = revokeToken(connectorId);\n } catch {\n // Best-effort: token store may be missing or read-only; do not mask the\n // not_found signal to the caller.\n }\n const message = staleTokenRevoked\n ? `${connectorId} is not installed. Removed stale token entry for ${connectorId}.`\n : \"Not installed\";\n return {\n connectorId,\n configPath,\n status: \"not_found\",\n message,\n };\n }\n\n // Read connector config before deleting it (needed for hermes profile lookup)\n let storedProfile = \"default\";\n if (connectorId === \"hermes\") {\n try {\n const stored = JSON.parse(fs.readFileSync(configPath, \"utf8\"));\n if (typeof stored?.profile === \"string\") storedProfile = stored.profile;\n } catch {\n // use default profile\n }\n }\n\n // For weclone, read the persisted proxy config path from the saved registry\n // config BEFORE deleting it. Using the persisted absolute path (rather than\n // recomputing from current REMNIC_HOME / ENGRAM_HOME / $HOME) guarantees\n // that a remove still targets the original file even if the environment\n // has changed between install and remove.\n //\n // Parse failure handling: if the registry config exists but is malformed,\n // we MUST abort the whole removal (mirror of the codex-cli provenance\n // gate). Silently falling back to an env-derived path would delete the\n // registry entry first and then miss the real proxy config if the\n // environment had since changed, orphaning the file (which may still hold\n // a live bearer token). Only install-time WRITES persist the path; if we\n // lost it on read, the only safe action is to stop and let the operator\n // fix the config or clean up manually.\n let weCloneProxyConfigPath: string | null = null;\n let weCloneRegistryParseFailed = false;\n if (connectorId === \"weclone\") {\n try {\n const stored = JSON.parse(fs.readFileSync(configPath, \"utf8\")) as Record<string, unknown>;\n if (typeof stored.proxyConfigPath === \"string\" && stored.proxyConfigPath.length > 0) {\n weCloneProxyConfigPath = stored.proxyConfigPath;\n }\n } catch {\n weCloneRegistryParseFailed = true;\n }\n // No persisted path AND parse succeeded means this is a legacy install\n // pre-dating proxyConfigPath provenance. Fall back to env resolution\n // only in that specific case so we still make a best-effort cleanup.\n if (weCloneProxyConfigPath === null && !weCloneRegistryParseFailed) {\n try {\n weCloneProxyConfigPath = resolveWeCloneProxyConfigPath();\n } catch {\n // Resolution failed (e.g. no HOME) — leave null; cleanup block skips.\n }\n }\n }\n if (connectorId === \"weclone\" && weCloneRegistryParseFailed) {\n console.warn(\n \"[remnic/connectors] removeConnector: weclone.json is malformed — \" +\n \"aborting removal to preserve provenance. Fix or delete \" +\n configPath +\n \" manually and retry.\",\n );\n return {\n connectorId,\n configPath,\n message:\n \"Removal aborted: weclone.json is malformed. Registry config left in place for inspection; \" +\n \"proxy config NOT removed.\",\n status: \"skipped\",\n reason: \"config-parse-failed\",\n };\n }\n\n // Finding 4: if the codex-cli config exists but failed to parse, abort the\n // entire removal. Leave both the config file AND the extension directory\n // untouched so the operator can inspect/fix the config file and retry.\n // Unlinking the config here would destroy the only provenance record and make\n // deterministic retry impossible.\n if (connectorId === \"codex-cli\" && fs.existsSync(configPath) && !configParsed) {\n console.warn(\n \"[remnic/connectors] removeConnector: codex-cli.json is malformed — \" +\n \"aborting removal to preserve provenance. Fix or delete \" +\n configPath +\n \" manually and retry.\",\n );\n return {\n connectorId,\n configPath,\n message: \"Removal aborted: codex-cli.json is malformed. Config file left in place for inspection.\",\n status: \"skipped\",\n reason: \"config-parse-failed\",\n };\n }\n\n // Finding 5: remove extension BEFORE deleting the config file. If extension\n // removal throws (e.g. EPERM/EBUSY), we re-throw WITHOUT deleting the config\n // so the user can retry — the config still has the persisted codexHome needed\n // to locate the extension directory.\n let extensionMessage = \"\";\n if (connectorId === \"codex-cli\") {\n // Finding 4: skip extension deletion when installExtension was explicitly disabled.\n if (savedInstallExtension === false) {\n extensionMessage = \" (memory extension: skipped — installExtension=false)\";\n // Finding 3: require EXPLICIT provenance (installExtension===true AND a saved\n // codexHome) before removing the extension. Legacy configs that pre-date this\n // feature have no installExtension key, so savedInstallExtension is undefined;\n // without provenance we cannot be sure Remnic ever owned the directory.\n } else if (savedInstallExtension !== true || codexHomeOverride === null) {\n extensionMessage = \" (memory extension: skipped — no install provenance in saved config)\";\n } else {\n const extResult = removeCodexMemoryExtension({ codexHome: codexHomeOverride });\n extensionMessage = extResult.removed\n ? ` (memory extension removed: ${extResult.remnicExtensionDir})`\n : \" (no memory extension present)\";\n }\n }\n\n // Delete the connector config file AFTER extension removal (Finding 5): if\n // extension removal throws, we do not reach here and the config is preserved.\n // Token revocation and YAML cleanup only happen after the file is gone so\n // that a failed unlink (e.g., read-only directory) does not leave a\n // token-less orphan install on disk.\n try {\n fs.unlinkSync(configPath);\n } catch (unlinkErr) {\n const sanitizedErr = unlinkErr instanceof Error ? unlinkErr.message : String(unlinkErr);\n return {\n connectorId,\n configPath,\n status: \"error\",\n message:\n `${connectorId} remove aborted: could not delete connector file (${sanitizedErr}). ` +\n `Token and any connector-specific state were not modified.`,\n };\n }\n\n // File removed — now safe to revoke the auth token.\n // Non-fatal: if the token store is read-only or missing, connector removal\n // should still succeed. Stale tokens will be rejected by the daemon when the\n // token file is later accessible.\n const notes: string[] = [];\n // Track revocation success so downstream error branches (e.g. weclone\n // proxy-delete failure) can accurately report whether the token was\n // cleaned up rather than hardcoding \"Token has been rolled back\".\n let tokenRevoked = true;\n try {\n revokeToken(connectorId);\n } catch (revokeErr) {\n // Surface the failure so callers know the token was not cleaned up.\n // The connector config has already been removed at this point.\n tokenRevoked = false;\n const revokeMsg = revokeErr instanceof Error ? revokeErr.message : String(revokeErr);\n notes.push(`Warning: token revocation failed — ${revokeMsg}. The token for ${connectorId} may still be present in tokens.json.`);\n }\n\n // WeClone-specific: remove the proxy config file at the path persisted in\n // the registry config (read above before the registry file was deleted).\n // Using the persisted absolute path — not a re-derivation from the current\n // environment — is load-bearing: if REMNIC_HOME / ENGRAM_HOME changes (or\n // is unset) between install and remove, recomputing here would leave the\n // original proxy config (with a live bearer token) on disk while reporting\n // success. If the file is present but unlink fails (e.g. EPERM), we MUST\n // surface an error status rather than pretending success — a later retry\n // via `remnic connectors remove weclone` would go down the `not_found`\n // path because the registry config was already unlinked, leaving the\n // proxy config orphaned (potentially with a still-valid token).\n let weCloneProxyDeleteFailed: string | null = null;\n if (connectorId === \"weclone\") {\n if (weCloneProxyConfigPath === null) {\n notes.push(\n \"WeClone proxy config cleanup skipped: no persisted path found in saved config \" +\n \"(likely a legacy install predating proxyConfigPath provenance).\",\n );\n } else {\n // Safety gate: validate the persisted path before unlinking. Because\n // `weCloneProxyConfigPath` is loaded from user-controlled JSON, a\n // malformed or tampered weclone.json could make `removeConnector` delete\n // an arbitrary file. Restrict deletion to paths that are:\n // 1. Absolute (relative paths are CWD-dependent and were never written\n // by the installer).\n // 2. End with the known suffix \"connectors/weclone.json\" — the only\n // filename the installer ever writes, regardless of base directory.\n // If either check fails, skip the unlink and surface an error so the\n // operator can clean up manually. Failing closed is safer than silently\n // deleting an unexpected path.\n const expectedSuffix = path.join(\"connectors\", \"weclone.json\");\n const isSafePath =\n path.isAbsolute(weCloneProxyConfigPath) &&\n weCloneProxyConfigPath.endsWith(expectedSuffix);\n if (!isSafePath) {\n weCloneProxyDeleteFailed =\n `Proxy config path ${JSON.stringify(weCloneProxyConfigPath)} failed safety validation ` +\n `(must be absolute and end with \"${expectedSuffix}\"). ` +\n `Refusing to delete — remove the file manually if it exists.`;\n } else {\n try {\n if (fs.existsSync(weCloneProxyConfigPath)) {\n fs.unlinkSync(weCloneProxyConfigPath);\n notes.push(`Removed WeClone proxy config: ${weCloneProxyConfigPath}`);\n }\n } catch (err) {\n // Hard failure: leaving the file behind with a live token is a\n // security issue. Capture the error so we return status:\"error\".\n weCloneProxyDeleteFailed = err instanceof Error ? err.message : String(err);\n }\n }\n }\n }\n if (weCloneProxyDeleteFailed !== null && weCloneProxyConfigPath !== null) {\n // Report the token-revocation status truthfully. If revocation already\n // failed above, claiming the token was \"cleaned up\" here would mislead\n // the operator into thinking the only action left is deleting the\n // orphan file — when in reality the bearer token is also still live.\n const tokenStatus = tokenRevoked\n ? \"the registry config was deleted and the token was revoked\"\n : \"the registry config was deleted but TOKEN REVOCATION ALSO FAILED — \" +\n \"inspect ~/.remnic/tokens.json and revoke manually\";\n return {\n connectorId,\n configPath,\n status: \"error\",\n message:\n `WeClone remove partially succeeded: ${tokenStatus}, ` +\n `but the proxy config at ${weCloneProxyConfigPath} could not be deleted ` +\n `(${weCloneProxyDeleteFailed}). Manually remove that file — it may still contain ` +\n `a Remnic daemon bearer token.`,\n };\n }\n\n // Hermes-specific: strip the remnic: block from config.yaml.\n // Only attempted after successful file removal so that config.yaml cleanup\n // is consistent with the connector JSON state.\n if (connectorId === \"hermes\") {\n try {\n const yamlResult = removeHermesConfig({ profile: storedProfile });\n if (yamlResult.updated) {\n notes.push(`Removed remnic: block from Hermes config: ${yamlResult.configPath}`);\n } else if (yamlResult.reason?.startsWith(\"Hermes config cleanup partially failed:\")) {\n const tokenStatus = tokenRevoked\n ? \"the connector registry config was deleted and the token was revoked\"\n : \"the connector registry config was deleted but TOKEN REVOCATION ALSO FAILED — \" +\n \"inspect ~/.remnic/tokens.json and revoke manually\";\n return {\n connectorId,\n configPath,\n status: \"error\",\n message:\n `Hermes remove partially succeeded: ${tokenStatus}, but ${yamlResult.reason}. ` +\n `Updated paths: ${yamlResult.configPath}. Manually remove any stale remnic: ` +\n `block and token material from the failed Hermes config path.`,\n };\n } else if (yamlResult.skipped) {\n notes.push(`Hermes config cleanup skipped: ${yamlResult.reason}`);\n }\n } catch (err) {\n notes.push(\n `Hermes config cleanup skipped: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n const suffix = notes.length > 0 ? `\\n ${notes.join(\"\\n \")}` : \"\";\n return {\n connectorId,\n configPath,\n status: \"removed\",\n message: `Removed${extensionMessage}${suffix}`,\n };\n}\n\n// ── Hermes config.yaml helpers ─────────────────────────────────────────────────\n\ninterface HermesConfigResult {\n updated: boolean;\n skipped: boolean;\n reason?: string;\n configPath: string;\n /**\n * The exact byte-for-byte content of the config.yaml that existed BEFORE\n * this upsert ran. `null` when the file did not exist (new file was created).\n * `undefined` when the write was skipped (priorContent is irrelevant).\n * Used by installConnector to roll back the YAML write if commitTokenEntry\n * subsequently throws.\n */\n priorContent?: string | null;\n}\n\n/**\n * Validate and sanitize a Hermes profile name.\n *\n * Profile names appear as a path segment under `~/.hermes/profiles/`, so we\n * must reject any value that could traverse outside that directory. Hermes\n * itself restricts profile names to filesystem-safe identifiers; we mirror\n * that convention and additionally require the resolved config path to stay\n * under the profiles root.\n *\n * Throws on invalid input rather than silently normalizing — the caller\n * should surface the error so the user can supply a valid profile.\n */\nfunction sanitizeHermesProfile(profile: string): string {\n if (typeof profile !== \"string\" || profile.length === 0) {\n throw new Error(\"Hermes profile name must be a non-empty string\");\n }\n // Disallow anything that isn't a plain profile identifier. We accept\n // letters, digits, hyphen, underscore, and dot — but reject leading dots\n // (hidden dirs) and any path separator or parent-dir reference.\n if (!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(profile)) {\n throw new Error(\n `Invalid Hermes profile name: ${JSON.stringify(profile)} — must match [A-Za-z0-9][A-Za-z0-9._-]*`,\n );\n }\n if (profile.includes(\"..\")) {\n throw new Error(`Invalid Hermes profile name: ${JSON.stringify(profile)} — must not contain \"..\"`);\n }\n return profile;\n}\n\nfunction hermesConfigPath(profile: string): string {\n const safeProfile = sanitizeHermesProfile(profile);\n const hermesRoot = path.resolve(resolveHomeDir(), \".hermes\");\n const rootConfigPath = path.join(hermesRoot, \"config.yaml\");\n const profilesRoot = path.join(hermesRoot, \"profiles\");\n if (safeProfile === \"default\") {\n const defaultProfileDir = path.join(profilesRoot, safeProfile);\n if (isFile(rootConfigPath) || (!fs.existsSync(rootConfigPath) && !isDirectory(defaultProfileDir))) {\n return rootConfigPath;\n }\n }\n const cfgPath = path.resolve(profilesRoot, safeProfile, \"config.yaml\");\n // Defense in depth: ensure the resolved path is still under profilesRoot.\n const rel = path.relative(profilesRoot, cfgPath);\n if (rel.startsWith(\"..\") || path.isAbsolute(rel)) {\n throw new Error(\n `Invalid Hermes profile path: resolved outside ${profilesRoot}`,\n );\n }\n return cfgPath;\n}\n\nfunction isDirectory(filePath: string): boolean {\n try {\n return fs.statSync(filePath).isDirectory();\n } catch {\n return false;\n }\n}\n\nfunction isFile(filePath: string): boolean {\n try {\n return fs.statSync(filePath).isFile();\n } catch {\n return false;\n }\n}\n\nfunction hermesConfigTarget(filePath: string): string {\n try {\n return fs.realpathSync.native(filePath);\n } catch {\n return path.resolve(filePath);\n }\n}\n\nfunction sameHermesConfigTarget(leftPath: string, rightPath: string): boolean {\n return hermesConfigTarget(leftPath) === hermesConfigTarget(rightPath);\n}\n\nfunction hermesDefaultProfileConfigPath(): string {\n const hermesRoot = path.resolve(resolveHomeDir(), \".hermes\");\n return path.join(hermesRoot, \"profiles\", \"default\", \"config.yaml\");\n}\n\nfunction hermesConfigCleanupPaths(profile: string): string[] {\n const cfgPath = hermesConfigPath(profile);\n const safeProfile = sanitizeHermesProfile(profile);\n if (safeProfile !== \"default\") {\n return [cfgPath];\n }\n return [...new Set([cfgPath, hermesDefaultProfileConfigPath()])];\n}\n\n/**\n * Validate a Hermes host string before interpolating it into YAML.\n *\n * YAML-injection guard: connector config values come from raw CLI input\n * (`--config host=...`) or config-file JSON, both of which are untrusted.\n * Without validation, a value like `127.0.0.1\"\\n session_key: \"evil`\n * would emit additional YAML keys into the `remnic:` block and silently\n * override Hermes settings.\n *\n * Accepted forms:\n * - Plain IPv4: 127.0.0.1, 10.0.0.5\n * - Plain DNS hostname: localhost, foo.example.com\n * - Bracketed IPv6 literal: [::1], [2001:db8::1]\n *\n * Rejected forms:\n * - host:port combos: 127.0.0.1:4318 (colons not allowed outside brackets)\n * - Unbalanced brackets: [::1\n * - Any whitespace, quotes, or control characters\n *\n * Hermes builds its base URL as `http://{host}:{port}`, so supplying a\n * host that already embeds a port (e.g. \"127.0.0.1:4318\") would produce\n * the double-port URL \"http://127.0.0.1:4318:4318/...\" and fail at runtime\n * even though install reports success. We reject that form here.\n */\nfunction sanitizeHermesHost(host: string): string {\n if (typeof host !== \"string\" || host.length === 0) {\n throw new Error(\"Hermes host must be a non-empty string\");\n }\n if (host.length > 253) {\n throw new Error(`Hermes host too long (max 253 chars): ${JSON.stringify(host.slice(0, 32))}…`);\n }\n\n // Bracketed IPv6 literal: must start with \"[\", end with \"]\", and contain\n // only hex digits and colons inside the brackets.\n if (host.startsWith(\"[\")) {\n if (!host.endsWith(\"]\")) {\n throw new Error(\n `Invalid Hermes host: ${JSON.stringify(host)} — unbalanced brackets in IPv6 literal`,\n );\n }\n const inner = host.slice(1, -1);\n if (inner.length === 0 || !/^[0-9A-Fa-f:]+$/.test(inner)) {\n throw new Error(\n `Invalid Hermes host: ${JSON.stringify(host)} — bracketed IPv6 literal must contain only hex digits and colons`,\n );\n }\n return host;\n }\n\n // Unbracketed value: colons are not allowed (would indicate an embedded port\n // or an unbracketed IPv6 address, both of which must be rejected here).\n if (host.includes(\":\")) {\n throw new Error(\n `Invalid Hermes host: ${JSON.stringify(host)} — host must not include a port; supply the port separately with --config port=<n>`,\n );\n }\n\n // Plain IPv4 or DNS hostname: allow letters, digits, dots, and hyphens only.\n // No whitespace, quotes, or control characters.\n if (!/^[A-Za-z0-9._\\-]+$/.test(host)) {\n throw new Error(\n `Invalid Hermes host: ${JSON.stringify(host)} — must be a plain hostname or IP literal`,\n );\n }\n return host;\n}\n\n/**\n * Validate a Hermes port value. Accepts positive integers in [1, 65535].\n *\n * Rejects non-integer numeric strings (e.g. \"4318.9\") rather than silently\n * truncating them — a fractional port is almost certainly a typo and writing\n * the truncated value to config.yaml would be misleading.\n */\nfunction sanitizeHermesPort(port: number | string): number {\n const numeric = Number(port);\n // Reject NaN, Infinity, -Infinity, and any non-integer (e.g. 4318.9)\n if (!Number.isInteger(numeric)) {\n throw new Error(\n `Invalid Hermes port \"${port}\": must be a positive integer`,\n );\n }\n if (numeric < 1 || numeric > 65535) {\n throw new Error(`Invalid Hermes port: ${JSON.stringify(port)} — must be an integer in [1, 65535]`);\n }\n return numeric;\n}\n\n/**\n * Write a file with owner-only (0o600) permissions.\n *\n * Used for any file that may contain a bearer token. writeFileSync's `mode`\n * option only applies when the file is newly created, so we also chmod\n * afterwards to tighten permissions on pre-existing files. The chmod is\n * best-effort on platforms that don't support POSIX modes.\n */\nfunction writeSecretFileSync(filePath: string, data: string): void {\n fs.writeFileSync(filePath, data, { mode: 0o600 });\n try {\n fs.chmodSync(filePath, 0o600);\n } catch {\n /* best-effort on non-POSIX filesystems */\n }\n}\n\n/**\n * Upsert the `remnic:` block in a Hermes profile config.yaml.\n *\n * Rules:\n * - If the profile directory does not exist, skip with a warning (we do not\n * create arbitrary Hermes state).\n * - If config.yaml does not exist, create it with only the remnic: block.\n * - If config.yaml exists and already contains a `remnic:` block, update the\n * host/port/token lines in-place (line-based, preserves comments elsewhere).\n * - If config.yaml exists with no `remnic:` block, append one.\n * - Idempotent on repeated calls.\n */\nexport function upsertHermesConfig(opts: {\n profile: string;\n host: string;\n port: number;\n token: string;\n}): HermesConfigResult {\n const cfgPath = hermesConfigPath(opts.profile);\n const profileDir = path.dirname(cfgPath);\n\n // YAML-injection guard: validate scalar values before interpolating them\n // into the `remnic:` block. sanitizeHermesHost/Port throw on anything\n // that could break out of the scalar context.\n const safeHost = sanitizeHermesHost(opts.host);\n const safePort = sanitizeHermesPort(opts.port);\n // Token is generated by randomBytes + a fixed alphabetic prefix, so it's\n // already safe for YAML scalar interpolation. We still guard against an\n // unexpectedly malformed token reaching this function.\n if (!/^[A-Za-z0-9_]+$/.test(opts.token)) {\n throw new Error(\"Invalid Hermes token: contains non-alphanumeric characters\");\n }\n\n if (!isDirectory(profileDir)) {\n return {\n updated: false,\n skipped: true,\n reason: `Hermes profile directory not found: ${profileDir}`,\n configPath: cfgPath,\n };\n }\n\n const block = [\n \"remnic:\",\n ` host: \"${safeHost}\"`,\n ` port: ${safePort}`,\n ` token: \"${opts.token}\"`,\n ].join(\"\\n\");\n\n if (!fs.existsSync(cfgPath)) {\n // Create with just the remnic block. 0o600 because the file now holds\n // a bearer token — matching the permissions on ~/.remnic/tokens.json.\n writeSecretFileSync(cfgPath, block + \"\\n\");\n // priorContent: null signals \"file was created new\" — rollback means delete.\n return { updated: true, skipped: false, configPath: cfgPath, priorContent: null };\n }\n\n const raw = fs.readFileSync(cfgPath, \"utf8\");\n\n // Check whether there's an existing remnic: block\n const hasRemnicBlock = /^remnic:/m.test(raw);\n\n if (!hasRemnicBlock) {\n // Append the block (preserve existing content)\n const separator = raw.endsWith(\"\\n\") ? \"\\n\" : \"\\n\\n\";\n writeSecretFileSync(cfgPath, raw + separator + block + \"\\n\");\n // priorContent: raw preserves the original file so it can be restored on rollback.\n return { updated: true, skipped: false, configPath: cfgPath, priorContent: raw };\n }\n\n // Update the existing block. Strategy: replace the content of the remnic:\n // section by matching from `^remnic:` to the next top-level key or end-of-file.\n // We rewrite only the host/port/token sub-keys inside the block; other keys\n // under remnic: (e.g. session_key, timeout) are preserved.\n //\n // Trailing-newline handling: split(\"\\n\") on a file that ends with \"\\n\" produces\n // a final empty-string element. If that element is still inside the remnic block\n // when we hit it, it gets pushed to newLines via the else branch — placing a\n // blank line between existing sub-keys and any newly-appended missing sub-keys.\n // We strip the trailing empty element before the loop and re-add a single \"\\n\"\n // at write time, normalising the file to always end with exactly one newline.\n const splitLines = raw.split(\"\\n\");\n // Remove trailing empty element produced by a file that ends with \"\\n\"\n if (splitLines.length > 0 && splitLines[splitLines.length - 1] === \"\") {\n splitLines.pop();\n }\n const lines = splitLines;\n const newLines: string[] = [];\n let inRemnicBlock = false;\n let blockWritten = false;\n\n // Track which sub-keys we've emitted\n const written = { host: false, port: false, token: false };\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n if (/^remnic:/.test(line)) {\n inRemnicBlock = true;\n newLines.push(line);\n continue;\n }\n\n if (inRemnicBlock) {\n // A line that starts with a non-space character and is not empty signals\n // the start of the next top-level YAML key — we've left the remnic block.\n if (line.length > 0 && !/^\\s/.test(line)) {\n // Emit any un-written keys before closing the block. Uses the\n // already-validated safeHost/safePort values.\n if (!written.host) newLines.push(` host: \"${safeHost}\"`);\n if (!written.port) newLines.push(` port: ${safePort}`);\n if (!written.token) newLines.push(` token: \"${opts.token}\"`);\n blockWritten = true;\n inRemnicBlock = false;\n newLines.push(line);\n continue;\n }\n\n // Replace host/port/token lines; preserve other sub-keys\n if (/^\\s+host:/.test(line)) {\n newLines.push(` host: \"${safeHost}\"`);\n written.host = true;\n } else if (/^\\s+port:/.test(line)) {\n newLines.push(` port: ${safePort}`);\n written.port = true;\n } else if (/^\\s+token:/.test(line)) {\n newLines.push(` token: \"${opts.token}\"`);\n written.token = true;\n } else {\n newLines.push(line);\n }\n continue;\n }\n\n newLines.push(line);\n }\n\n if (inRemnicBlock && !blockWritten) {\n // File ended while still inside the remnic block\n if (!written.host) newLines.push(` host: \"${safeHost}\"`);\n if (!written.port) newLines.push(` port: ${safePort}`);\n if (!written.token) newLines.push(` token: \"${opts.token}\"`);\n }\n\n // Always write exactly one trailing newline, matching the create and append paths.\n writeSecretFileSync(cfgPath, newLines.join(\"\\n\") + \"\\n\");\n // priorContent: raw is the original file content for rollback if needed.\n return { updated: true, skipped: false, configPath: cfgPath, priorContent: raw };\n}\n\n/**\n * Remove the `remnic:` block from a Hermes profile config.yaml.\n * Idempotent — if the block is absent, returns skipped.\n */\nexport function removeHermesConfig(opts: { profile: string }): HermesConfigResult {\n const cfgPaths = hermesConfigCleanupPaths(opts.profile);\n const results = cfgPaths.map((cfgPath) => {\n try {\n return removeHermesConfigFile(cfgPath);\n } catch (err) {\n return {\n updated: false,\n skipped: true,\n reason: `Hermes config cleanup failed: ${err instanceof Error ? err.message : String(err)}`,\n configPath: cfgPath,\n };\n }\n });\n const updated = results.filter((result) => result.updated);\n const cleanupFailures = results.filter((result) => result.reason?.startsWith(\"Hermes config cleanup failed:\"));\n\n if (updated.length > 0) {\n const updatedPaths = updated.map((result) => result.configPath).join(\", \");\n if (cleanupFailures.length > 0) {\n const failedPaths = cleanupFailures.map((result) => result.configPath).join(\", \");\n return {\n updated: false,\n skipped: true,\n reason: `Hermes config cleanup partially failed: updated ${updatedPaths}; failed ${failedPaths}`,\n configPath: `${updatedPaths}; failed: ${failedPaths}`,\n };\n }\n return {\n updated: true,\n skipped: false,\n configPath: updatedPaths,\n };\n }\n\n const cleanupFailure = cleanupFailures[0];\n if (cleanupFailure) {\n return cleanupFailure;\n }\n\n const existingWithoutBlock = results.find((result) => result.reason !== \"Hermes config.yaml not found\");\n return existingWithoutBlock ?? results[0] ?? {\n updated: false,\n skipped: true,\n reason: \"Hermes config.yaml not found\",\n configPath: hermesConfigPath(opts.profile),\n };\n}\n\nfunction removeHermesConfigFile(cfgPath: string): HermesConfigResult {\n if (!fs.existsSync(cfgPath)) {\n return {\n updated: false,\n skipped: true,\n reason: \"Hermes config.yaml not found\",\n configPath: cfgPath,\n };\n }\n\n const raw = fs.readFileSync(cfgPath, \"utf8\");\n if (!/^remnic:/m.test(raw)) {\n return {\n updated: false,\n skipped: true,\n reason: \"No remnic: block found in config.yaml\",\n configPath: cfgPath,\n };\n }\n\n // Strip the remnic: block and its indented children\n const lines = raw.split(\"\\n\");\n const newLines: string[] = [];\n let inRemnicBlock = false;\n\n for (const line of lines) {\n if (/^remnic:/.test(line)) {\n inRemnicBlock = true;\n continue;\n }\n if (inRemnicBlock) {\n if (line.length > 0 && !/^\\s/.test(line)) {\n inRemnicBlock = false;\n newLines.push(line);\n }\n // else: still in the block — skip the line\n continue;\n }\n newLines.push(line);\n }\n\n // Trim trailing blank lines left behind after the block removal\n while (newLines.length > 0 && newLines[newLines.length - 1]?.trim() === \"\") {\n newLines.pop();\n }\n\n // Use writeSecretFileSync to keep the file at 0o600 even after the token\n // has been removed. The file previously held a bearer token (so it was\n // written with 0o600 originally); preserving that mode prevents a window\n // where a rewrite with default umask temporarily widens permissions.\n writeSecretFileSync(cfgPath, newLines.length > 0 ? newLines.join(\"\\n\") + \"\\n\" : \"\");\n return { updated: true, skipped: false, configPath: cfgPath };\n}\n\n// ── Daemon health check (synchronous, non-fatal) ────────────────────────────\n\n/**\n * Probe exit-code contract (used by checkDaemonHealth):\n * 0 — HTTP 200 (healthy)\n * 2 — HTTP 401 (token cache miss: retry after TTL)\n * 1 — any other HTTP status or network error\n */\nconst HEALTH_EXIT_OK = 0;\nconst HEALTH_EXIT_UNAUTHORIZED = 2;\n\n/**\n * Ping /engram/v1/health synchronously.\n * Returns true if the daemon responds with HTTP 200, false otherwise.\n * Uses a synchronous helper to run a one-liner Node script so that the existing\n * installConnector() flow does not need to become async.\n *\n * Data (host, port, token) are passed via environment variables — NOT\n * interpolated into the script string — to prevent injection from\n * user-supplied config values.\n *\n * /engram/v1/health is protected by bearer auth in the access HTTP server,\n * so the caller must pass the connector token (or the configured server\n * token) or the probe will always return 401 and report the daemon as\n * unreachable even when it is running.\n *\n * 401 handling: the daemon caches valid tokens with a 5-second TTL\n * (getAllValidTokensCached). A freshly-rotated token may not appear in the\n * cache for up to 5 s after rotation. We tolerate a single 401 by sleeping\n * one cache TTL (6000 ms = 5 s TTL + 1 s buffer) and retrying exactly once.\n */\nfunction checkDaemonHealth(host: string, port: number, authToken?: string): boolean {\n try {\n // Validate port: must be an integer in [1, 65535].\n // This guards against user config supplying a non-numeric string.\n const safePort = Math.trunc(Number(port));\n if (!Number.isFinite(safePort) || safePort < 1 || safePort > 65535) {\n return false;\n }\n // Finding 7 fix: Node's http.get({ host }) expects an unbracketed IPv6\n // literal (e.g. \"::1\"), but sanitizeHermesHost permits bracketed form\n // \"[::1]\" (required for URL contexts). Strip the brackets here so that\n // http.get receives the bare address and doesn't fail to connect.\n // IPv4 and hostname strings are unaffected (no brackets to strip).\n const bareHost = host.startsWith(\"[\") && host.endsWith(\"]\")\n ? host.slice(1, -1)\n : host;\n\n // Data (host, port, token) are passed via env vars, never interpolated\n // into the script string, preventing any code-injection from malformed\n // config values.\n // Exit codes: 0 = 200 OK, 2 = 401 Unauthorized, 1 = other error.\n const script = [\n \"const http = require('http');\",\n \"const env = process['env'];\",\n \"const headers = {};\",\n \"if (env.REMNIC_HEALTH_TOKEN) {\",\n \" headers['authorization'] = 'Bearer ' + env.REMNIC_HEALTH_TOKEN;\",\n \"}\",\n \"const req = http.get({\",\n \" host: env.REMNIC_HEALTH_HOST,\",\n \" port: parseInt(env.REMNIC_HEALTH_PORT, 10),\",\n \" path: '/engram/v1/health',\",\n \" headers,\",\n \" timeout: 3000,\",\n \"}, (res) => { process.exit(res.statusCode === 200 ? 0 : res.statusCode === 401 ? 2 : 1); });\",\n \"req.on('error', () => process.exit(1));\",\n \"req.on('timeout', () => { req.destroy(); process.exit(1); });\",\n ].join(\"\\n\");\n const env: NodeJS.ProcessEnv = mergeEnv({\n REMNIC_HEALTH_HOST: bareHost,\n REMNIC_HEALTH_PORT: String(safePort),\n });\n if (authToken) {\n env.REMNIC_HEALTH_TOKEN = authToken;\n }\n const processPath = process.execPath;\n const launchOptions = { timeout: 4000, env };\n const result = launchProcessSync(processPath, [\"-e\", script], launchOptions);\n\n if (result.status === HEALTH_EXIT_OK) {\n return true;\n }\n\n if (result.status === HEALTH_EXIT_UNAUTHORIZED) {\n // The daemon's token cache (5 s TTL) has not yet picked up the freshly\n // rotated token. Sleep one TTL + buffer and retry exactly once.\n console.error(\n \"[remnic/connectors] health probe got 401 — retrying after token cache TTL...\",\n );\n // Synchronous sleep without making the caller async.\n launchProcessSync(processPath, [\"-e\", \"setTimeout(() => {}, 6000)\"], {\n timeout: 7000,\n env: {},\n });\n const retry = launchProcessSync(processPath, [\"-e\", script], launchOptions);\n return retry.status === HEALTH_EXIT_OK;\n }\n\n return false;\n } catch {\n return false;\n }\n}\n\n// ── Doctor ────────────────────────────────────────────────────────────────────\n\nexport async function doctorConnector(connectorId: string): Promise<DoctorResult> {\n const installed = listConnectors().installed;\n const instance = installed.find((c) => c.connectorId === connectorId);\n\n if (!instance) {\n return {\n connectorId,\n checks: [{ name: \"Installed\", ok: false, detail: \"Not installed\" }],\n healthy: false,\n };\n }\n\n const configPath = path.join(getConnectorsDir(), `${connectorId}.json`);\n const checks: DoctorCheck[] = [];\n\n // Check config exists\n checks.push({\n name: \"Config file\",\n ok: fs.existsSync(configPath),\n detail: configPath,\n });\n\n // Check config is valid JSON\n try {\n const raw = fs.readFileSync(configPath, \"utf8\");\n JSON.parse(raw);\n checks.push({ name: \"Config valid\", ok: true, detail: \"OK\" });\n } catch (e) {\n checks.push({ name: \"Config valid\", ok: false, detail: String(e) });\n }\n\n // Check MCP server reachable (if applicable)\n const mcpUrl = instance.config.mcpServerUrl as string | undefined;\n if (mcpUrl) {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 3000);\n const response = await fetch(mcpUrl, { signal: controller.signal });\n clearTimeout(timeoutId);\n checks.push({ name: \"MCP server\", ok: response.ok, detail: mcpUrl });\n } catch (e) {\n checks.push({\n name: \"MCP server\",\n ok: false,\n detail: `Cannot reach ${mcpUrl}: ${e instanceof Error ? e.message : \"unknown\"}`,\n });\n }\n }\n\n // Check memory dir (if applicable)\n const memoryDir = instance.config.memoryDir as string | undefined;\n if (memoryDir) {\n if (fs.existsSync(memoryDir)) {\n checks.push({ name: \"Memory directory\", ok: true, detail: memoryDir });\n } else {\n checks.push({ name: \"Memory directory\", ok: false, detail: `Not found: ${memoryDir}` });\n }\n }\n\n const healthy = checks.every((c) => c.ok);\n return { connectorId, checks, healthy };\n}\n\n// ── Codex memory extension install ────────────────────────────────────────\n\n/**\n * Name of the Codex memories folder. Matches Codex's\n * `MEMORIES_SUBDIR = \"memories\"`.\n */\nconst CODEX_MEMORIES_SUBDIR = \"memories\";\n\n/**\n * Name of the Codex memory-extensions folder. Matches Codex's\n * `EXTENSIONS_SUBDIR = \"memories_extensions\"`.\n *\n * Codex computes the extensions root as a **sibling** of the memories dir via\n * Rust's `Path::with_file_name(\"memories_extensions\")` — so for the default\n * Codex home the layout is:\n *\n * ~/.codex/memories/\n * ~/.codex/memories_extensions/\n *\n * Extension files live **outside** of `memories/`, never inside it.\n */\nconst CODEX_EXTENSIONS_SUBDIR = \"memories_extensions\";\n\n/** Folder name Remnic installs its extension under. */\nconst REMNIC_EXTENSION_DIR_NAME = \"remnic\";\n\nexport interface CodexMemoryExtensionPaths {\n /** Resolved Codex home directory (e.g. `~/.codex`). */\n codexHome: string;\n /** Resolved Codex memories directory (`<codex_home>/memories`). */\n memoriesDir: string;\n /** Sibling extensions root (`<codex_home>/memories_extensions`). */\n extensionsRoot: string;\n /** The specific Remnic extension directory inside the extensions root. */\n remnicExtensionDir: string;\n}\n\nexport interface InstallCodexMemoryExtensionOptions {\n /** Optional override for `$CODEX_HOME`. Highest priority. */\n codexHome?: string | null;\n /** Optional override for the plugin-codex extension source directory. */\n sourceDir?: string | null;\n}\n\nexport interface InstallCodexMemoryExtensionResult extends CodexMemoryExtensionPaths {\n /** Absolute path to the installed `instructions.md`. */\n instructionsPath: string;\n /** Number of files copied. */\n filesCopied: number;\n /**\n * Commit the install: permanently remove the backup of the prior extension\n * (if one existed). Call this once the config write has succeeded.\n */\n commit(): void;\n /**\n * Roll back the install: restore the prior extension if one existed, or\n * remove the newly-installed directory for a fresh install. Call this when\n * a subsequent step (e.g. config write) has failed.\n */\n rollback(): void;\n}\n\nexport interface RemoveCodexMemoryExtensionOptions {\n codexHome?: string | null;\n}\n\nexport interface RemoveCodexMemoryExtensionResult extends CodexMemoryExtensionPaths {\n /** True if an existing `remnic` extension directory was removed. */\n removed: boolean;\n}\n\n/**\n * Resolve the Codex home directory. Precedence:\n * 1. explicit `override` argument (from config)\n * 2. `$CODEX_HOME` env var\n * 3. `$HOME/.codex`, `$USERPROFILE/.codex`, or the OS home directory\n */\nexport function resolveCodexHome(override?: string | null): string {\n if (override && typeof override === \"string\" && override.trim().length > 0) {\n return path.resolve(override.trim());\n }\n const envHome = readEnvVar(\"CODEX_HOME\");\n if (envHome && envHome.trim().length > 0) {\n return path.resolve(envHome.trim());\n }\n const home = readEnvVar(\"HOME\") || readEnvVar(\"USERPROFILE\") || resolveHomeDir();\n return path.resolve(home, \".codex\");\n}\n\n/**\n * Compute the Codex memories + memory-extensions layout for a given Codex home.\n *\n * The extensions root is computed as a **sibling** of the memories dir by\n * taking `path.dirname(memoriesDir)` and joining `memories_extensions`. This\n * mirrors Rust's `with_file_name(\"memories_extensions\")` semantics used by\n * Codex's `memory_extensions_root()`. Do NOT place the extension inside\n * `<codex_home>/memories/`.\n */\nexport function resolveCodexMemoryExtensionPaths(\n codexHomeOverride?: string | null,\n): CodexMemoryExtensionPaths {\n const codexHome = resolveCodexHome(codexHomeOverride);\n const memoriesDir = path.join(codexHome, CODEX_MEMORIES_SUBDIR);\n // Sibling computation: with_file_name(EXTENSIONS_SUBDIR)\n const extensionsRoot = path.join(path.dirname(memoriesDir), CODEX_EXTENSIONS_SUBDIR);\n const remnicExtensionDir = path.join(extensionsRoot, REMNIC_EXTENSION_DIR_NAME);\n return { codexHome, memoriesDir, extensionsRoot, remnicExtensionDir };\n}\n\n/**\n * Locate the plugin-codex `memories_extensions/remnic/` source directory on\n * disk. Search order:\n * 1. explicit `override`\n * 2. resolve via `@remnic/plugin-codex` package (handles global npm installs)\n * 3. sibling `node_modules/@remnic/plugin-codex` relative to this module\n * 4. walk upward from this file's location (monorepo development)\n * 5. walk upward from `process.cwd()` (monorepo fallback)\n *\n * Returns the absolute path or throws a descriptive error listing all paths\n * searched when none exist.\n */\nexport function locatePluginCodexExtensionSource(override?: string | null): string {\n if (override && typeof override === \"string\" && override.trim().length > 0) {\n const resolved = path.resolve(override.trim());\n if (fs.existsSync(resolved) && fs.statSync(resolved).isDirectory()) {\n return resolved;\n }\n throw new Error(`Codex extension source directory not found: ${resolved}`);\n }\n\n const EXTENSION_SUBPATH = path.join(\"memories_extensions\", \"remnic\");\n const WORKSPACE_RELATIVE_PATH = path.join(\n \"packages\",\n \"plugin-codex\",\n \"memories_extensions\",\n \"remnic\",\n );\n\n const searched: string[] = [];\n\n // Primary path: the bundled payload shipped with @remnic/core itself.\n // tsup copies src/connectors/codex/ → dist/connectors/codex/ (see tsup.config.ts\n // onSuccess hook). However, tsup bundles all source into dist/ as flat files\n // (dist/index.js, dist/chunk-*.js), so at runtime import.meta.url points to\n // dist/index.js or a dist/chunk-*.js — NOT dist/connectors/index.js.\n // Therefore we probe two sibling-relative candidates:\n // 1. moduleDir/codex — matches tsx/ts-node on src/connectors/index.ts\n // 2. moduleDir/connectors/codex — matches the tsup dist layout where this code\n // lands in dist/index.js or dist/chunk-*.js\n try {\n const moduleDir = path.dirname(fileURLToPath(import.meta.url));\n\n // Candidate 1: adjacent codex/ (tsx/ts-node from src/connectors/)\n const bundledCandidate = path.join(moduleDir, \"codex\");\n searched.push(bundledCandidate);\n if (fs.existsSync(bundledCandidate) && fs.statSync(bundledCandidate).isDirectory()) {\n return bundledCandidate;\n }\n\n // Candidate 2: dist/connectors/codex/ — the tsup output path.\n // When this module is bundled into dist/index.js or dist/chunk-*.js,\n // moduleDir is dist/ and tsup copies the payload to dist/connectors/codex/.\n const distConnectorsCandidate = path.join(moduleDir, \"connectors\", \"codex\");\n searched.push(distConnectorsCandidate);\n if (\n fs.existsSync(distConnectorsCandidate) &&\n fs.statSync(distConnectorsCandidate).isDirectory()\n ) {\n return distConnectorsCandidate;\n }\n } catch {\n // import.meta.url unavailable — not running as ESM, skip bundled path.\n }\n\n // Finding 2 — path 1: resolve via `@remnic/plugin-codex` package.json.\n // This covers global `npm install -g @remnic/remnic-core` or pnpm global installs\n // where the package lives under the global node_modules tree.\n try {\n const requireFromHere = createRequire(import.meta.url);\n const pluginPkgJsonPath = requireFromHere.resolve(\"@remnic/plugin-codex/package.json\");\n const pluginPkgRoot = path.dirname(pluginPkgJsonPath);\n const candidate = path.join(pluginPkgRoot, EXTENSION_SUBPATH);\n searched.push(candidate);\n if (fs.existsSync(candidate) && fs.statSync(candidate).isDirectory()) {\n return candidate;\n }\n } catch {\n // @remnic/plugin-codex not installed — fall through to next strategy.\n }\n\n // Finding 2 — path 2: sibling node_modules under the module's own directory.\n // Handles cases like:\n // .../node_modules/@remnic/remnic-core/src/connectors/index.js\n // .../node_modules/@remnic/plugin-codex/memories_extensions/remnic\n try {\n const moduleDir = path.dirname(fileURLToPath(import.meta.url));\n let dir = moduleDir;\n for (let depth = 0; depth < 8; depth += 1) {\n const candidate = path.join(\n dir,\n \"node_modules\",\n \"@remnic\",\n \"plugin-codex\",\n EXTENSION_SUBPATH,\n );\n searched.push(candidate);\n if (fs.existsSync(candidate) && fs.statSync(candidate).isDirectory()) {\n return candidate;\n }\n const parent = path.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n } catch {\n // import.meta.url unavailable — not running as ESM.\n }\n\n // Finding 2 — path 3 & 4: walk upward from this file's location and from\n // process.cwd() looking for the monorepo layout (`packages/plugin-codex/…`).\n const anchors: string[] = [];\n try {\n anchors.push(path.dirname(fileURLToPath(import.meta.url)));\n } catch {\n // Not running under ESM with import.meta — skip.\n }\n anchors.push(process.cwd());\n\n for (const anchor of anchors) {\n let dir = anchor;\n for (let depth = 0; depth < 12; depth += 1) {\n const candidate = path.join(dir, WORKSPACE_RELATIVE_PATH);\n searched.push(candidate);\n if (fs.existsSync(candidate) && fs.statSync(candidate).isDirectory()) {\n return candidate;\n }\n const parent = path.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n }\n\n throw new Error(\n \"Could not locate the plugin-codex memories_extensions/remnic source directory.\\n\" +\n \"Paths searched:\\n\" +\n searched.map((p) => ` - ${p}`).join(\"\\n\") +\n \"\\nInstall @remnic/plugin-codex or pass sourceDir explicitly.\",\n );\n}\n\n/** Recursive synchronous directory copy. */\nfunction copyDirRecursiveSync(src: string, dest: string): number {\n let count = 0;\n fs.mkdirSync(dest, { recursive: true });\n const entries = fs.readdirSync(src, { withFileTypes: true });\n for (const entry of entries) {\n const from = path.join(src, entry.name);\n const to = path.join(dest, entry.name);\n if (entry.isDirectory()) {\n count += copyDirRecursiveSync(from, to);\n } else if (entry.isFile()) {\n fs.copyFileSync(from, to);\n count += 1;\n }\n // Skip symlinks, sockets, etc. — extension content is plain files.\n }\n return count;\n}\n\n/**\n * Install the Remnic memory extension into `<codex_home>/memories_extensions/remnic/`\n * atomically. The copy is written to a sibling `.remnic.tmp-<pid>-<ts>` directory\n * and then renamed into place, so a concurrent Codex phase-2 run never sees a\n * half-written extension.\n *\n * This function is **idempotent and scoped**: it only touches the `remnic`\n * subfolder inside `memories_extensions/`. Adjacent extensions (other\n * vendors) are never read, written, or removed.\n */\nexport function installCodexMemoryExtension(\n options: InstallCodexMemoryExtensionOptions = {},\n): InstallCodexMemoryExtensionResult {\n const paths = resolveCodexMemoryExtensionPaths(options.codexHome ?? null);\n const sourceDir = locatePluginCodexExtensionSource(options.sourceDir ?? null);\n\n fs.mkdirSync(paths.extensionsRoot, { recursive: true });\n\n // Clean any stale tmp from a previous crashed run by scanning the\n // extensions root for any `.remnic.tmp-*` prefixed entry. We must do this\n // BEFORE creating the new tmp directory. Per-entry errors are swallowed so\n // one bad entry doesn't abort cleanup of the rest.\n //\n // Finding 2: only remove tmp dirs that are provably stale (older than\n // STALE_TMP_THRESHOLD_MS). Dirs younger than the threshold belong to a\n // concurrent install that is still in progress; deleting them would corrupt\n // the other process's atomic rename.\n const tmpPrefix = `.${REMNIC_EXTENSION_DIR_NAME}.tmp-`;\n const STALE_TMP_THRESHOLD_MS = 10 * 60 * 1000; // 10 minutes\n const now = Date.now();\n try {\n const existingEntries = fs.readdirSync(paths.extensionsRoot);\n for (const entry of existingEntries) {\n if (!entry.startsWith(tmpPrefix)) continue;\n const stalePath = path.join(paths.extensionsRoot, entry);\n try {\n const stat = fs.statSync(stalePath);\n const ageMs = now - stat.mtimeMs;\n if (ageMs < STALE_TMP_THRESHOLD_MS) {\n // Too recent — leave it alone; another install is likely still running.\n continue;\n }\n fs.rmSync(stalePath, { recursive: true, force: true });\n } catch {\n // swallow — one bad entry should not abort the others\n }\n }\n } catch {\n // extensions root just-created / unreadable — nothing to clean\n }\n\n const tmpName = `${tmpPrefix}${process.pid}-${Date.now()}`;\n const tmpDir = path.join(paths.extensionsRoot, tmpName);\n\n let filesCopied = 0;\n let commitFn: () => void = () => { /* no-op: set below on success */ };\n let rollbackFn: () => void = () => { /* no-op: set below on success */ };\n try {\n filesCopied = copyDirRecursiveSync(sourceDir, tmpDir);\n\n // Atomic replace: rename old remnic/ to a timestamped backup, then rename\n // the tmp dir into place. If the second rename fails, restore from backup\n // so the old extension is never permanently lost.\n const backupDir = `${paths.remnicExtensionDir}.bak-${Date.now()}`;\n const hadExisting = fs.existsSync(paths.remnicExtensionDir);\n if (hadExisting) {\n fs.renameSync(paths.remnicExtensionDir, backupDir);\n }\n try {\n fs.renameSync(tmpDir, paths.remnicExtensionDir);\n } catch (renameErr) {\n // New rename failed — restore backup so the old extension survives.\n if (hadExisting) {\n try {\n fs.renameSync(backupDir, paths.remnicExtensionDir);\n } catch {\n // swallow — backup restore best-effort\n }\n }\n throw renameErr;\n }\n // The new extension is in place. We intentionally keep the backup alive\n // until the caller calls commit(). This gives the caller a chance to roll\n // back to the prior state if a subsequent operation (e.g. config write) fails.\n //\n // commit() — remove the backup (called on success)\n // rollback() — restore the prior extension from backup, or remove the newly\n // installed directory if this was a fresh install\n commitFn = (): void => {\n if (hadExisting) {\n try {\n fs.rmSync(backupDir, { recursive: true, force: true });\n } catch {\n // swallow — stale backup is harmless\n }\n }\n };\n rollbackFn = (): void => {\n if (hadExisting) {\n // Restore the prior extension from backup.\n try {\n // Remove the newly-installed dir first so rename can succeed.\n if (fs.existsSync(paths.remnicExtensionDir)) {\n fs.rmSync(paths.remnicExtensionDir, { recursive: true, force: true });\n }\n fs.renameSync(backupDir, paths.remnicExtensionDir);\n } catch {\n // swallow — best-effort restore; backup remains on disk\n }\n } else {\n // Fresh install — just remove the directory we created.\n try {\n if (fs.existsSync(paths.remnicExtensionDir)) {\n fs.rmSync(paths.remnicExtensionDir, { recursive: true, force: true });\n }\n } catch {\n // swallow\n }\n }\n };\n } catch (err) {\n // Best-effort cleanup so we never leave .tmp garbage behind.\n if (fs.existsSync(tmpDir)) {\n try {\n fs.rmSync(tmpDir, { recursive: true, force: true });\n } catch {\n // swallow\n }\n }\n throw err;\n }\n\n const instructionsPath = path.join(paths.remnicExtensionDir, \"instructions.md\");\n\n return {\n ...paths,\n instructionsPath,\n filesCopied,\n commit: commitFn,\n rollback: rollbackFn,\n };\n}\n\n/**\n * Remove the Remnic memory extension. Only touches\n * `<codex_home>/memories_extensions/remnic/` — never adjacent extensions.\n */\nexport function removeCodexMemoryExtension(\n options: RemoveCodexMemoryExtensionOptions = {},\n): RemoveCodexMemoryExtensionResult {\n const paths = resolveCodexMemoryExtensionPaths(options.codexHome ?? null);\n let removed = false;\n if (fs.existsSync(paths.remnicExtensionDir)) {\n fs.rmSync(paths.remnicExtensionDir, { recursive: true, force: true });\n removed = true;\n }\n return { ...paths, removed };\n}\n\n// ── Helpers ───────────────────────────────────────────────────────────────────\n\nfunction getConnectorsDir(): string {\n const xdgConfigHome = readEnvVar(\"XDG_CONFIG_HOME\");\n const configDir = xdgConfigHome\n ? path.join(xdgConfigHome, \"engram\")\n : path.join(resolveHomeDir(), \".config\", \"engram\");\n return path.join(configDir, REGISTRY_DIR_NAME, \"connectors\");\n}\n\n// ── WeClone proxy config helpers ───────────────────────────────────────────\n//\n// The standalone `remnic-weclone-proxy` CLI reads its config from\n// ~/.remnic/connectors/weclone.json by default. `remnic connectors install\n// weclone` composes and persists that file so the proxy can start without\n// additional setup. The file is also tracked by the connector registry (at\n// getConnectorsDir()/weclone.json) so `remnic connectors list/remove/doctor`\n// work uniformly across all connectors.\n\nconst WECLONE_PROXY_CONFIG_DIRNAME = \".remnic\";\nconst WECLONE_PROXY_CONFIG_FILENAME = \"weclone.json\";\n\n/**\n * Resolve the path to ~/.remnic/connectors/weclone.json for the current user.\n * Honours REMNIC_HOME / ENGRAM_HOME env overrides so tests can point the\n * install at a temp dir without leaking into the real home directory.\n *\n * Always returns an absolute path via `path.resolve` so install-time and\n * run-time resolution agree even when the override is a relative path like\n * `tmp/remnic` (which would otherwise be interpreted against the caller's\n * current working directory). Must stay in lockstep with the proxy CLI's\n * `defaultConfigPath()` in @remnic/connector-weclone/src/cli.ts.\n *\n * `HOME=\"\"` edge case: a nullish fallback would keep the\n * empty string (empty is not nullish), which `path.resolve(\"\", ...)` then\n * interprets as CWD. `os.homedir()` by contrast falls back to the OS\n * password database when HOME is empty, so the two code paths would\n * disagree. We therefore treat empty HOME as absent and delegate to\n * `os.homedir()` in both places — the same rule the proxy CLI follows.\n */\nexport function resolveWeCloneProxyConfigPath(): string {\n const remnicHome = readEnvVar(\"REMNIC_HOME\");\n const override = remnicHome && remnicHome.length > 0 ? remnicHome : readEnvVar(\"ENGRAM_HOME\");\n if (override && override.length > 0) {\n return path.resolve(expandTildePath(override), \"connectors\", WECLONE_PROXY_CONFIG_FILENAME);\n }\n const envHome = readEnvVar(\"HOME\");\n const home = envHome && envHome.length > 0 ? envHome : os.homedir();\n return path.resolve(\n home,\n WECLONE_PROXY_CONFIG_DIRNAME,\n \"connectors\",\n WECLONE_PROXY_CONFIG_FILENAME,\n );\n}\n\n/**\n * Read the existing proxy config file, if any. Returns raw contents so the\n * caller can both parse it (for value precedence) and restore it verbatim on\n * rollback without touching byte-level formatting.\n */\nfunction readWeCloneProxyConfigIfExists(configPath: string): string | null {\n try {\n if (!fs.existsSync(configPath)) return null;\n return fs.readFileSync(configPath, \"utf8\");\n } catch {\n return null;\n }\n}\n\n/** Safely parse a JSON string into a record; returns null on error. */\nfunction safeParseJson(raw: string): Record<string, unknown> | null {\n try {\n const parsed = JSON.parse(raw);\n if (typeof parsed === \"object\" && parsed !== null && !Array.isArray(parsed)) {\n return parsed as Record<string, unknown>;\n }\n return null;\n } catch {\n return null;\n }\n}\n\ninterface WeCloneProxyConfig {\n wecloneApiUrl: string;\n wecloneModelName: string;\n proxyPort: number;\n remnicDaemonUrl: string;\n remnicAuthToken?: string;\n sessionStrategy: \"caller-id\" | \"single\";\n memoryInjection: {\n maxTokens: number;\n position: \"system-append\" | \"system-prepend\";\n template: string;\n };\n}\n\nconst WECLONE_DEFAULTS = {\n wecloneApiUrl: \"http://localhost:8000/v1\",\n wecloneModelName: \"weclone-avatar\",\n proxyPort: 8100,\n remnicDaemonUrl: \"http://localhost:4318\",\n sessionStrategy: \"single\" as const,\n memoryInjection: {\n maxTokens: 1500,\n position: \"system-append\" as const,\n template: \"[Memory Context]\\n{memories}\\n[End Memory Context]\",\n },\n};\n\n/**\n * Resolve a string field with precedence: userConfig → priorConfig → default.\n * Only non-empty strings are accepted from either source; invalid values fall\n * through so the user gets a working default rather than a broken install.\n */\nfunction resolveStringField(\n userConfig: Record<string, unknown>,\n priorConfig: Record<string, unknown> | null,\n key: string,\n fallback: string,\n): string {\n const fromUser = userConfig[key];\n if (typeof fromUser === \"string\" && fromUser.length > 0) return fromUser;\n if (priorConfig) {\n const fromPrior = priorConfig[key];\n if (typeof fromPrior === \"string\" && fromPrior.length > 0) return fromPrior;\n }\n return fallback;\n}\n\n/**\n * Coerce a config value to an integer port in [1, 65535]. Accepts number or\n * numeric string (parseConnectorConfig produces strings from `--config\n * proxyPort=8100`). Returns null if the value is missing or invalid so the\n * caller can fall through to the next precedence level.\n */\nfunction coercePort(value: unknown): number | null {\n if (typeof value === \"number\" && Number.isInteger(value) && value >= 1 && value <= 65535) {\n return value;\n }\n if (typeof value === \"string\" && value.length > 0) {\n const n = Number(value);\n if (Number.isInteger(n) && n >= 1 && n <= 65535) return n;\n }\n return null;\n}\n\nfunction resolvePort(\n userConfig: Record<string, unknown>,\n priorConfig: Record<string, unknown> | null,\n fallback: number,\n): number {\n const fromUser = coercePort(userConfig.proxyPort);\n if (fromUser !== null) return fromUser;\n if (priorConfig) {\n const fromPrior = coercePort(priorConfig.proxyPort);\n if (fromPrior !== null) return fromPrior;\n }\n return fallback;\n}\n\nfunction resolveSessionStrategy(\n userConfig: Record<string, unknown>,\n priorConfig: Record<string, unknown> | null,\n): \"caller-id\" | \"single\" {\n const valid = new Set([\"caller-id\", \"single\"]);\n const fromUser = userConfig.sessionStrategy;\n if (typeof fromUser === \"string\" && valid.has(fromUser)) {\n return fromUser as \"caller-id\" | \"single\";\n }\n if (priorConfig) {\n const fromPrior = priorConfig.sessionStrategy;\n if (typeof fromPrior === \"string\" && valid.has(fromPrior)) {\n return fromPrior as \"caller-id\" | \"single\";\n }\n }\n return WECLONE_DEFAULTS.sessionStrategy;\n}\n\n/**\n * Compose a WeCloneProxyConfig from user-supplied overrides and any prior\n * saved config, filling in defaults for every required field. The returned\n * shape is exactly what the proxy's parseConfig() expects.\n */\nexport function buildWeCloneProxyConfig(args: {\n userConfig: Record<string, unknown>;\n priorConfig: Record<string, unknown> | null;\n authToken?: string;\n}): WeCloneProxyConfig {\n const { userConfig, priorConfig, authToken } = args;\n\n const wecloneApiUrl = resolveStringField(\n userConfig,\n priorConfig,\n \"wecloneApiUrl\",\n WECLONE_DEFAULTS.wecloneApiUrl,\n );\n const wecloneModelName = resolveStringField(\n userConfig,\n priorConfig,\n \"wecloneModelName\",\n WECLONE_DEFAULTS.wecloneModelName,\n );\n const remnicDaemonUrl = resolveStringField(\n userConfig,\n priorConfig,\n \"remnicDaemonUrl\",\n WECLONE_DEFAULTS.remnicDaemonUrl,\n );\n const proxyPort = resolvePort(\n userConfig,\n priorConfig,\n WECLONE_DEFAULTS.proxyPort,\n );\n const sessionStrategy = resolveSessionStrategy(userConfig, priorConfig);\n\n // Memory injection: always start from defaults, then shallow-merge any\n // prior values, then user overrides. Individual field validation happens in\n // the proxy's parseConfig() at proxy startup — here we only assemble a\n // best-effort shape. A malformed user override would be rejected later with\n // a clean error message.\n //\n // `typeof [] === \"object\"` so a bare `typeof ... === \"object\" && ... !==\n // null` guard would let an array spread numeric-indexed properties into\n // the merged object, silently corrupting it. Explicitly reject arrays.\n const memoryInjection = {\n ...WECLONE_DEFAULTS.memoryInjection,\n ...(priorConfig &&\n typeof priorConfig.memoryInjection === \"object\" &&\n priorConfig.memoryInjection !== null &&\n !Array.isArray(priorConfig.memoryInjection)\n ? (priorConfig.memoryInjection as Record<string, unknown>)\n : {}),\n ...(typeof userConfig.memoryInjection === \"object\" &&\n userConfig.memoryInjection !== null &&\n !Array.isArray(userConfig.memoryInjection)\n ? (userConfig.memoryInjection as Record<string, unknown>)\n : {}),\n } as WeCloneProxyConfig[\"memoryInjection\"];\n\n const config: WeCloneProxyConfig = {\n wecloneApiUrl,\n wecloneModelName,\n proxyPort,\n remnicDaemonUrl,\n sessionStrategy,\n memoryInjection,\n };\n\n // Token precedence: freshly minted token → user-supplied → prior saved.\n // Never write a token if none is available — the proxy tolerates missing\n // tokens (it just won't send Authorization headers to the daemon).\n if (authToken && authToken.length > 0) {\n config.remnicAuthToken = authToken;\n } else if (typeof userConfig.remnicAuthToken === \"string\" && userConfig.remnicAuthToken.length > 0) {\n config.remnicAuthToken = userConfig.remnicAuthToken;\n } else if (priorConfig && typeof priorConfig.remnicAuthToken === \"string\" && priorConfig.remnicAuthToken.length > 0) {\n config.remnicAuthToken = priorConfig.remnicAuthToken;\n }\n\n return config;\n}\n","/**\n * codex-marketplace.ts — Codex marketplace installation support (#418)\n *\n * Provides types and functions for integrating Remnic with the Codex CLI\n * marketplace system (`codex marketplace add`). This module handles:\n *\n * - Generating a `marketplace.json` manifest describing Remnic as an\n * installable plugin in the Codex marketplace ecosystem.\n * - Validating marketplace manifest files against the expected schema.\n * - Writing manifests to disk atomically.\n * - Installing plugins from marketplace sources (GitHub, git, local, URL).\n *\n * Privacy\n * -------\n * This module does not persist any user content. It only reads package\n * metadata (name, version, description) and writes public marketplace\n * manifest files.\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\nimport { log } from \"../logger.js\";\nimport type { PluginConfig } from \"../types.js\";\n\n// ── Types ─────────────────────────────────────────────────────────────────\n\n/** Source type for marketplace installation. */\nexport type MarketplaceInstallType = \"github\" | \"git\" | \"local\" | \"url\";\n\n/** A single plugin entry within a marketplace manifest. */\nexport interface MarketplaceEntry {\n /** Plugin name (e.g. \"remnic\"). */\n name: string;\n /** Semver version string. */\n version: string;\n /** Human-readable description. */\n description: string;\n /** Repository identifier (e.g. \"joshuaswarren/remnic\"). */\n repository: string;\n /** How this plugin should be installed. */\n installType: MarketplaceInstallType;\n /** Optional direct URL to the plugin manifest. */\n manifestUrl?: string;\n /** Optional entry point path within the repository. */\n entry?: string;\n /** Optional config schema reference. */\n configSchema?: string;\n}\n\n/** Top-level marketplace manifest. */\nexport interface MarketplaceManifest {\n /** Schema version. Must be 1. */\n version: 1;\n /** Marketplace name. */\n name: string;\n /** Human-readable description. */\n description: string;\n /** Available plugins. */\n plugins: MarketplaceEntry[];\n}\n\n/** Configuration for the marketplace subsystem. */\nexport interface MarketplaceConfig {\n /** Whether marketplace features are enabled. Default: true. */\n enabled: boolean;\n /** Local path where marketplace data is cached. */\n registryPath: string;\n /** Whether to auto-update marketplace data on install. Default: false. */\n autoUpdate: boolean;\n}\n\n/** Result of a marketplace install operation. */\nexport interface MarketplaceInstallResult {\n /** Whether the install succeeded. */\n ok: boolean;\n /** Human-readable message. */\n message: string;\n /** Source that was installed from. */\n source: string;\n /** Source type. */\n sourceType: MarketplaceInstallType;\n /** Plugins that were discovered. */\n pluginsFound: string[];\n /** Errors encountered (empty on success). */\n errors: string[];\n}\n\n/** Logger interface accepted by marketplace functions. */\nexport interface MarketplaceLogger {\n info: (msg: string) => void;\n warn: (msg: string) => void;\n debug?: (msg: string) => void;\n}\n\n// ── Constants ─────────────────────────────────────────────────────────────\n\n/** Current marketplace schema version. */\nexport const MARKETPLACE_SCHEMA_VERSION = 1 as const;\n\n/** Default marketplace manifest filename. */\nexport const MARKETPLACE_MANIFEST_FILENAME = \"marketplace.json\";\n\n/** Valid install types for validation. */\nconst VALID_INSTALL_TYPES = new Set<string>([\"github\", \"git\", \"local\", \"url\"]);\n\n// ── Generate ──────────────────────────────────────────────────────────────\n\n/**\n * Generate a marketplace manifest describing Remnic as an installable plugin.\n *\n * Reads version from the workspace root `package.json` at the resolved path,\n * or falls back to a default version string.\n */\nexport function generateMarketplaceManifest(\n options?: { packageVersion?: string },\n): MarketplaceManifest {\n const version = options?.packageVersion ?? readPackageVersion() ?? \"0.0.0\";\n\n return {\n version: MARKETPLACE_SCHEMA_VERSION,\n name: \"remnic\",\n description: \"Remnic: Local-first AI memory with semantic search and consolidation\",\n plugins: [\n {\n name: \"remnic\",\n version,\n description: \"Persistent memory plugin for Codex CLI\",\n repository: \"joshuaswarren/remnic\",\n installType: \"github\",\n entry: \"packages/plugin-codex\",\n configSchema: \"openclaw.plugin.json\",\n },\n ],\n };\n}\n\n// ── Validate ──────────────────────────────────────────────────────────────\n\n/** Validation result with structured errors. */\nexport interface MarketplaceValidation {\n valid: boolean;\n errors: string[];\n}\n\n/**\n * Validate that an unknown value conforms to the MarketplaceManifest schema.\n *\n * Returns a typed manifest on success. Throws on invalid input with a\n * descriptive error message listing all schema violations.\n */\nexport function validateMarketplaceManifest(manifest: unknown): MarketplaceManifest {\n const validation = checkMarketplaceManifest(manifest);\n if (!validation.valid) {\n throw new Error(\n `Invalid marketplace manifest: ${validation.errors.join(\"; \")}`,\n );\n }\n return manifest as MarketplaceManifest;\n}\n\n/**\n * Non-throwing validation. Returns a structured result with error details.\n */\nexport function checkMarketplaceManifest(manifest: unknown): MarketplaceValidation {\n const errors: string[] = [];\n\n if (typeof manifest !== \"object\" || manifest === null) {\n return { valid: false, errors: [\"manifest must be a non-null object\"] };\n }\n\n const obj = manifest as Record<string, unknown>;\n\n // version\n if (obj.version !== MARKETPLACE_SCHEMA_VERSION) {\n errors.push(`version must be ${MARKETPLACE_SCHEMA_VERSION}, got ${JSON.stringify(obj.version)}`);\n }\n\n // name\n if (typeof obj.name !== \"string\" || obj.name.trim().length === 0) {\n errors.push(\"name must be a non-empty string\");\n }\n\n // description\n if (typeof obj.description !== \"string\" || obj.description.trim().length === 0) {\n errors.push(\"description must be a non-empty string\");\n }\n\n // plugins\n if (!Array.isArray(obj.plugins)) {\n errors.push(\"plugins must be an array\");\n } else if (obj.plugins.length === 0) {\n errors.push(\"plugins must contain at least one entry\");\n } else {\n for (let i = 0; i < obj.plugins.length; i++) {\n const plugin = obj.plugins[i] as Record<string, unknown>;\n const prefix = `plugins[${i}]`;\n\n if (typeof plugin !== \"object\" || plugin === null) {\n errors.push(`${prefix} must be a non-null object`);\n continue;\n }\n\n if (typeof plugin.name !== \"string\" || plugin.name.trim().length === 0) {\n errors.push(`${prefix}.name must be a non-empty string`);\n }\n\n if (typeof plugin.version !== \"string\" || plugin.version.trim().length === 0) {\n errors.push(`${prefix}.version must be a non-empty string`);\n }\n\n if (typeof plugin.description !== \"string\" || plugin.description.trim().length === 0) {\n errors.push(`${prefix}.description must be a non-empty string`);\n }\n\n if (typeof plugin.repository !== \"string\" || plugin.repository.trim().length === 0) {\n errors.push(`${prefix}.repository must be a non-empty string`);\n }\n\n if (typeof plugin.installType !== \"string\" || !VALID_INSTALL_TYPES.has(plugin.installType)) {\n errors.push(\n `${prefix}.installType must be one of: ${[...VALID_INSTALL_TYPES].join(\", \")}; ` +\n `got ${JSON.stringify(plugin.installType)}`,\n );\n }\n\n // Optional fields — validate type when present (PR #427 post-merge fix).\n if (\"manifestUrl\" in plugin && plugin.manifestUrl !== undefined) {\n if (typeof plugin.manifestUrl !== \"string\" || (plugin.manifestUrl as string).trim().length === 0) {\n errors.push(`${prefix}.manifestUrl must be a non-empty string when provided`);\n }\n }\n if (\"entry\" in plugin && plugin.entry !== undefined) {\n if (typeof plugin.entry !== \"string\" || (plugin.entry as string).trim().length === 0) {\n errors.push(`${prefix}.entry must be a non-empty string when provided`);\n }\n }\n if (\"configSchema\" in plugin && plugin.configSchema !== undefined) {\n if (typeof plugin.configSchema !== \"string\" || (plugin.configSchema as string).trim().length === 0) {\n errors.push(`${prefix}.configSchema must be a non-empty string when provided`);\n }\n }\n }\n }\n\n return { valid: errors.length === 0, errors };\n}\n\n// ── Write ─────────────────────────────────────────────────────────────────\n\n/**\n * Write a marketplace manifest to disk atomically.\n *\n * Uses write-to-temp-then-rename to avoid partial writes (CLAUDE.md gotcha #54).\n */\nexport async function writeMarketplaceManifest(\n outputDir: string,\n manifest: MarketplaceManifest,\n): Promise<void> {\n // Validate before writing — never write garbage to disk.\n const validation = checkMarketplaceManifest(manifest);\n if (!validation.valid) {\n throw new Error(\n `Refusing to write invalid manifest: ${validation.errors.join(\"; \")}`,\n );\n }\n\n fs.mkdirSync(outputDir, { recursive: true });\n\n const destPath = path.join(outputDir, MARKETPLACE_MANIFEST_FILENAME);\n const tmpPath = `${destPath}.tmp.${process.pid}`;\n const content = JSON.stringify(manifest, null, 2) + \"\\n\";\n\n fs.writeFileSync(tmpPath, content);\n fs.renameSync(tmpPath, destPath);\n}\n\n// ── Install ───────────────────────────────────────────────────────────────\n\n/**\n * Install from a marketplace source.\n *\n * Reads the marketplace.json from the given source, validates it, and\n * returns a result describing what was found.\n */\nexport async function installFromMarketplace(\n source: string,\n sourceType: MarketplaceInstallType,\n config: PluginConfig,\n logger?: MarketplaceLogger,\n): Promise<MarketplaceInstallResult> {\n const _log: MarketplaceLogger = logger ?? {\n info: (msg) => log.info(`[marketplace] ${msg}`),\n warn: (msg) => log.warn(`[marketplace] ${msg}`),\n debug: (msg) => log.debug(`[marketplace] ${msg}`),\n };\n\n if (!config.codexMarketplaceEnabled) {\n return {\n ok: false,\n message: \"Codex marketplace is disabled in config (codexMarketplaceEnabled: false)\",\n source,\n sourceType,\n pluginsFound: [],\n errors: [\"marketplace_disabled\"],\n };\n }\n\n try {\n const manifest = await resolveManifest(source, sourceType, _log);\n const pluginNames = manifest.plugins.map((p) => p.name);\n\n _log.info(`marketplace install: found ${pluginNames.length} plugin(s) from ${sourceType}://${source}`);\n\n return {\n ok: true,\n message: `Successfully resolved ${pluginNames.length} plugin(s) from marketplace: ${pluginNames.join(\", \")}`,\n source,\n sourceType,\n pluginsFound: pluginNames,\n errors: [],\n };\n } catch (err) {\n const errMsg = err instanceof Error ? err.message : String(err);\n _log.warn(`marketplace install failed: ${errMsg}`);\n return {\n ok: false,\n message: `Failed to install from marketplace: ${errMsg}`,\n source,\n sourceType,\n pluginsFound: [],\n errors: [errMsg],\n };\n }\n}\n\n// ── Source resolution ─────────────────────────────────────────────────────\n\n/**\n * Resolve a marketplace manifest from the given source.\n */\nasync function resolveManifest(\n source: string,\n sourceType: MarketplaceInstallType,\n logger: MarketplaceLogger,\n): Promise<MarketplaceManifest> {\n switch (sourceType) {\n case \"local\":\n return resolveLocal(source, logger);\n case \"url\":\n return resolveUrl(source, logger);\n case \"github\":\n return resolveGithub(source, logger);\n case \"git\":\n return resolveGit(source, logger);\n default: {\n // Exhaustive check — CLAUDE.md gotcha #51: reject invalid input.\n const _: never = sourceType;\n throw new Error(`Invalid source type: ${String(_)}`);\n }\n }\n}\n\n/**\n * Read marketplace.json from a local directory.\n */\nfunction resolveLocal(\n dirPath: string,\n logger: MarketplaceLogger,\n): MarketplaceManifest {\n const manifestPath = path.join(dirPath, MARKETPLACE_MANIFEST_FILENAME);\n\n if (!fs.existsSync(manifestPath)) {\n throw new Error(`marketplace.json not found at ${manifestPath}`);\n }\n\n logger.debug?.(`reading local marketplace manifest: ${manifestPath}`);\n\n const raw = fs.readFileSync(manifestPath, \"utf-8\");\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n throw new Error(`Invalid JSON in ${manifestPath}`);\n }\n\n // CLAUDE.md gotcha #18: validate parse result type\n if (typeof parsed !== \"object\" || parsed === null) {\n throw new Error(`marketplace.json at ${manifestPath} is not a valid object`);\n }\n\n return validateMarketplaceManifest(parsed);\n}\n\n/**\n * Fetch marketplace.json from a URL.\n */\nasync function resolveUrl(\n url: string,\n logger: MarketplaceLogger,\n): Promise<MarketplaceManifest> {\n logger.debug?.(`fetching marketplace manifest from URL: ${url}`);\n\n let parsedUrl: URL;\n try {\n parsedUrl = new URL(url);\n } catch {\n throw new Error(`Invalid URL: ${url}`);\n }\n\n if (parsedUrl.protocol !== \"https:\" && parsedUrl.protocol !== \"http:\") {\n throw new Error(`Unsupported URL protocol: ${parsedUrl.protocol} (use https or http)`);\n }\n\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`HTTP ${response.status} fetching ${url}`);\n }\n\n const body = await response.json() as unknown;\n return validateMarketplaceManifest(body);\n}\n\n/**\n * Resolve marketplace.json from a GitHub repository reference (owner/repo).\n *\n * Attempts to fetch the raw marketplace.json from the default branch.\n */\nasync function resolveGithub(\n repo: string,\n logger: MarketplaceLogger,\n): Promise<MarketplaceManifest> {\n // Validate format: must be owner/repo\n if (!/^[a-zA-Z0-9._-]+\\/[a-zA-Z0-9._-]+$/u.test(repo)) {\n throw new Error(`Invalid GitHub repo format: \"${repo}\" (expected owner/repo)`);\n }\n\n const rawUrl = `https://raw.githubusercontent.com/${repo}/HEAD/${MARKETPLACE_MANIFEST_FILENAME}`;\n logger.debug?.(`fetching marketplace manifest from GitHub: ${rawUrl}`);\n\n return resolveUrl(rawUrl, logger);\n}\n\n/**\n * Resolve marketplace.json from a git URL.\n *\n * For now this delegates to URL-based resolution by constructing a raw URL.\n * Full git clone support can be added later.\n */\nasync function resolveGit(\n gitUrl: string,\n logger: MarketplaceLogger,\n): Promise<MarketplaceManifest> {\n // For git URLs that look like GitHub HTTPS URLs, extract owner/repo and\n // delegate to the GitHub resolver.\n const ghMatch = gitUrl.match(\n /^(?:https?:\\/\\/)?github\\.com\\/([a-zA-Z0-9._-]+\\/[a-zA-Z0-9._-]+?)(?:\\.git)?$/u,\n );\n if (ghMatch?.[1]) {\n logger.debug?.(`git URL looks like GitHub — delegating to github resolver`);\n return resolveGithub(ghMatch[1], logger);\n }\n\n throw new Error(\n `Git URL resolution requires a GitHub-format URL for now. ` +\n `Got: ${gitUrl}. Use --type github or --type url instead.`,\n );\n}\n\n// ── Helpers ───────────────────────────────────────────────────────────────\n\n/**\n * Read the workspace root package.json version. Returns undefined if not found.\n */\nfunction readPackageVersion(): string | undefined {\n // Walk up from this file to find the workspace root package.json\n // This module lives at packages/remnic-core/src/connectors/codex-marketplace.ts\n // so workspace root is 4 levels up.\n const candidates = [\n path.resolve(import.meta.dirname ?? \".\", \"../../../..\"),\n path.resolve(import.meta.dirname ?? \".\", \"../../../../..\"),\n path.resolve(import.meta.dirname ?? \".\", \"..\"),\n ];\n\n for (const candidate of candidates) {\n const pkgPath = path.join(candidate, \"package.json\");\n try {\n if (!fs.existsSync(pkgPath)) continue;\n const raw = fs.readFileSync(pkgPath, \"utf-8\");\n const parsed = JSON.parse(raw);\n if (typeof parsed === \"object\" && parsed !== null && typeof parsed.version === \"string\") {\n return parsed.version;\n }\n } catch {\n // ignore\n }\n }\n\n return undefined;\n}\n"],"mappings":"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","names":["fs","path","path","fs"]}