@agentmemory/agentmemory 0.9.30 → 0.9.32

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 (334) hide show
  1. package/.env.example +57 -48
  2. package/AGENTS.md +8 -8
  3. package/README.md +256 -819
  4. package/dist/.env.example +57 -48
  5. package/dist/cli.d.mts.map +1 -1
  6. package/dist/cli.mjs +2257 -1027
  7. package/dist/cli.mjs.map +1 -1
  8. package/dist/compression-recovery-CZh63Jmz.mjs +5997 -0
  9. package/dist/compression-recovery-CZh63Jmz.mjs.map +1 -0
  10. package/dist/{connect-B4_ca6BD.mjs → connect-BX3njQ3Y.mjs} +897 -276
  11. package/dist/connect-BX3njQ3Y.mjs.map +1 -0
  12. package/dist/hooks/_capture.d.mts +5 -1
  13. package/dist/hooks/_capture.d.mts.map +1 -1
  14. package/dist/hooks/_capture.mjs +141 -26
  15. package/dist/hooks/_capture.mjs.map +1 -1
  16. package/dist/hooks/notification.mjs +20 -6
  17. package/dist/hooks/notification.mjs.map +1 -1
  18. package/dist/hooks/post-commit.mjs +83 -10
  19. package/dist/hooks/post-commit.mjs.map +1 -1
  20. package/dist/hooks/post-tool-failure.mjs +19 -6
  21. package/dist/hooks/post-tool-failure.mjs.map +1 -1
  22. package/dist/hooks/post-tool-use.mjs +19 -6
  23. package/dist/hooks/post-tool-use.mjs.map +1 -1
  24. package/dist/hooks/pre-compact.mjs +104 -22
  25. package/dist/hooks/pre-compact.mjs.map +1 -1
  26. package/dist/hooks/pre-tool-use.mjs +83 -10
  27. package/dist/hooks/pre-tool-use.mjs.map +1 -1
  28. package/dist/hooks/prompt-submit.mjs +12 -4
  29. package/dist/hooks/prompt-submit.mjs.map +1 -1
  30. package/dist/hooks/session-end.mjs +59 -17
  31. package/dist/hooks/session-end.mjs.map +1 -1
  32. package/dist/hooks/session-start.mjs +95 -15
  33. package/dist/hooks/session-start.mjs.map +1 -1
  34. package/dist/hooks/stop.mjs +75 -72
  35. package/dist/hooks/stop.mjs.map +1 -1
  36. package/dist/hooks/subagent-start.mjs +13 -5
  37. package/dist/hooks/subagent-start.mjs.map +1 -1
  38. package/dist/hooks/subagent-stop.mjs +32 -10
  39. package/dist/hooks/subagent-stop.mjs.map +1 -1
  40. package/dist/hooks/task-completed.mjs +21 -6
  41. package/dist/hooks/task-completed.mjs.map +1 -1
  42. package/dist/{image-refs-T_urbwHM.mjs → image-refs-Cyta4Lf9.mjs} +2 -2
  43. package/dist/{image-refs-T_urbwHM.mjs.map → image-refs-Cyta4Lf9.mjs.map} +1 -1
  44. package/dist/index.mjs +16390 -11530
  45. package/dist/index.mjs.map +1 -1
  46. package/dist/integrations/dsh.d.mts +55 -0
  47. package/dist/integrations/dsh.d.mts.map +1 -0
  48. package/dist/integrations/dsh.mjs +1172 -0
  49. package/dist/integrations/dsh.mjs.map +1 -0
  50. package/dist/{keyed-mutex-DchXsyfP.mjs → keyed-mutex-DCUh7PG-.mjs} +58 -9
  51. package/dist/keyed-mutex-DCUh7PG-.mjs.map +1 -0
  52. package/dist/{secret-store-BnY3A50C.mjs → secret-store-iYXRcrO8.mjs} +717 -474
  53. package/dist/secret-store-iYXRcrO8.mjs.map +1 -0
  54. package/dist/session-arguments-zxsbbd8y.mjs +113 -0
  55. package/dist/session-arguments-zxsbbd8y.mjs.map +1 -0
  56. package/dist/{src-Jsq9LCeH.mjs → src-C23nMpda.mjs} +5263 -4667
  57. package/dist/src-C23nMpda.mjs.map +1 -0
  58. package/dist/{standalone-DKCdrf1d.mjs → standalone-BYo5USDb.mjs} +379 -63
  59. package/dist/standalone-BYo5USDb.mjs.map +1 -0
  60. package/dist/standalone.d.mts +1 -1
  61. package/dist/standalone.d.mts.map +1 -1
  62. package/dist/standalone.mjs +864 -81
  63. package/dist/standalone.mjs.map +1 -1
  64. package/dist/viewer/index.html +337 -168
  65. package/integrations/hermes/README.md +94 -0
  66. package/integrations/hermes/__init__.py +670 -0
  67. package/integrations/hermes/plugin.yaml +27 -0
  68. package/integrations/omp/LICENSE +190 -0
  69. package/integrations/omp/README.md +76 -0
  70. package/integrations/omp/capture.ts +1 -0
  71. package/integrations/omp/dist/index.mjs +1477 -0
  72. package/integrations/omp/index.ts +488 -0
  73. package/integrations/omp/package.json +13 -0
  74. package/integrations/omp/security.ts +67 -0
  75. package/integrations/omp/skills/agentmemory-agents/REFERENCE.md +32 -0
  76. package/integrations/omp/skills/agentmemory-agents/SKILL.md +48 -0
  77. package/integrations/omp/skills/agentmemory-agents/TROUBLESHOOTING.md +70 -0
  78. package/integrations/omp/skills/agentmemory-architecture/SKILL.md +37 -0
  79. package/integrations/omp/skills/agentmemory-architecture/TROUBLESHOOTING.md +70 -0
  80. package/integrations/omp/skills/agentmemory-config/REFERENCE.md +91 -0
  81. package/integrations/omp/skills/agentmemory-config/SKILL.md +98 -0
  82. package/integrations/omp/skills/agentmemory-config/TROUBLESHOOTING.md +70 -0
  83. package/integrations/omp/skills/agentmemory-hooks/REFERENCE.md +20 -0
  84. package/integrations/omp/skills/agentmemory-hooks/SKILL.md +60 -0
  85. package/integrations/omp/skills/agentmemory-hooks/TROUBLESHOOTING.md +70 -0
  86. package/integrations/omp/skills/agentmemory-mcp-tools/REFERENCE.md +66 -0
  87. package/integrations/omp/skills/agentmemory-mcp-tools/SKILL.md +52 -0
  88. package/integrations/omp/skills/agentmemory-mcp-tools/TROUBLESHOOTING.md +70 -0
  89. package/integrations/omp/skills/agentmemory-rest-api/REFERENCE.md +159 -0
  90. package/integrations/omp/skills/agentmemory-rest-api/SKILL.md +49 -0
  91. package/integrations/omp/skills/agentmemory-rest-api/TROUBLESHOOTING.md +70 -0
  92. package/integrations/omp/skills/commit-context/EXAMPLES.md +71 -0
  93. package/integrations/omp/skills/commit-context/SKILL.md +64 -0
  94. package/integrations/omp/skills/commit-context/TROUBLESHOOTING.md +70 -0
  95. package/integrations/omp/skills/commit-history/EXAMPLES.md +71 -0
  96. package/integrations/omp/skills/commit-history/SKILL.md +62 -0
  97. package/integrations/omp/skills/commit-history/TROUBLESHOOTING.md +70 -0
  98. package/integrations/omp/skills/forget/EXAMPLES.md +40 -0
  99. package/integrations/omp/skills/forget/SKILL.md +73 -0
  100. package/integrations/omp/skills/forget/TROUBLESHOOTING.md +70 -0
  101. package/integrations/omp/skills/handoff/EXAMPLES.md +57 -0
  102. package/integrations/omp/skills/handoff/SKILL.md +75 -0
  103. package/integrations/omp/skills/handoff/TROUBLESHOOTING.md +70 -0
  104. package/integrations/omp/skills/lesson/SKILL.md +64 -0
  105. package/integrations/omp/skills/lesson/TROUBLESHOOTING.md +70 -0
  106. package/integrations/omp/skills/memory-discipline/SKILL.md +65 -0
  107. package/integrations/omp/skills/memory-discipline/TROUBLESHOOTING.md +70 -0
  108. package/integrations/omp/skills/recall/EXAMPLES.md +74 -0
  109. package/integrations/omp/skills/recall/SKILL.md +74 -0
  110. package/integrations/omp/skills/recall/TROUBLESHOOTING.md +70 -0
  111. package/integrations/omp/skills/recap/EXAMPLES.md +62 -0
  112. package/integrations/omp/skills/recap/SKILL.md +68 -0
  113. package/integrations/omp/skills/recap/TROUBLESHOOTING.md +70 -0
  114. package/integrations/omp/skills/remember/EXAMPLES.md +67 -0
  115. package/integrations/omp/skills/remember/SKILL.md +66 -0
  116. package/integrations/omp/skills/remember/TROUBLESHOOTING.md +70 -0
  117. package/integrations/omp/skills/session-history/EXAMPLES.md +59 -0
  118. package/integrations/omp/skills/session-history/SKILL.md +67 -0
  119. package/integrations/omp/skills/session-history/TROUBLESHOOTING.md +70 -0
  120. package/integrations/omp/skills/write-agentmemory-skill/SKILL.md +41 -0
  121. package/integrations/omp/skills/write-agentmemory-skill/TROUBLESHOOTING.md +70 -0
  122. package/integrations/openclaw/LICENSE +190 -0
  123. package/integrations/openclaw/README.md +98 -0
  124. package/integrations/openclaw/openclaw.plugin.json +71 -0
  125. package/integrations/openclaw/package.json +38 -0
  126. package/integrations/openclaw/plugin.mjs +425 -0
  127. package/integrations/openclaw/plugin.yaml +26 -0
  128. package/integrations/openclaw/skills/agentmemory-agents/REFERENCE.md +32 -0
  129. package/integrations/openclaw/skills/agentmemory-agents/SKILL.md +48 -0
  130. package/integrations/openclaw/skills/agentmemory-agents/TROUBLESHOOTING.md +70 -0
  131. package/integrations/openclaw/skills/agentmemory-architecture/SKILL.md +37 -0
  132. package/integrations/openclaw/skills/agentmemory-architecture/TROUBLESHOOTING.md +70 -0
  133. package/integrations/openclaw/skills/agentmemory-config/REFERENCE.md +91 -0
  134. package/integrations/openclaw/skills/agentmemory-config/SKILL.md +98 -0
  135. package/integrations/openclaw/skills/agentmemory-config/TROUBLESHOOTING.md +70 -0
  136. package/integrations/openclaw/skills/agentmemory-hooks/REFERENCE.md +20 -0
  137. package/integrations/openclaw/skills/agentmemory-hooks/SKILL.md +60 -0
  138. package/integrations/openclaw/skills/agentmemory-hooks/TROUBLESHOOTING.md +70 -0
  139. package/integrations/openclaw/skills/agentmemory-mcp-tools/REFERENCE.md +66 -0
  140. package/integrations/openclaw/skills/agentmemory-mcp-tools/SKILL.md +52 -0
  141. package/integrations/openclaw/skills/agentmemory-mcp-tools/TROUBLESHOOTING.md +70 -0
  142. package/integrations/openclaw/skills/agentmemory-rest-api/REFERENCE.md +159 -0
  143. package/integrations/openclaw/skills/agentmemory-rest-api/SKILL.md +49 -0
  144. package/integrations/openclaw/skills/agentmemory-rest-api/TROUBLESHOOTING.md +70 -0
  145. package/integrations/openclaw/skills/commit-context/EXAMPLES.md +71 -0
  146. package/integrations/openclaw/skills/commit-context/SKILL.md +64 -0
  147. package/integrations/openclaw/skills/commit-context/TROUBLESHOOTING.md +70 -0
  148. package/integrations/openclaw/skills/commit-history/EXAMPLES.md +71 -0
  149. package/integrations/openclaw/skills/commit-history/SKILL.md +62 -0
  150. package/integrations/openclaw/skills/commit-history/TROUBLESHOOTING.md +70 -0
  151. package/integrations/openclaw/skills/forget/EXAMPLES.md +40 -0
  152. package/integrations/openclaw/skills/forget/SKILL.md +73 -0
  153. package/integrations/openclaw/skills/forget/TROUBLESHOOTING.md +70 -0
  154. package/integrations/openclaw/skills/handoff/EXAMPLES.md +57 -0
  155. package/integrations/openclaw/skills/handoff/SKILL.md +75 -0
  156. package/integrations/openclaw/skills/handoff/TROUBLESHOOTING.md +70 -0
  157. package/integrations/openclaw/skills/lesson/SKILL.md +64 -0
  158. package/integrations/openclaw/skills/lesson/TROUBLESHOOTING.md +70 -0
  159. package/integrations/openclaw/skills/memory-discipline/SKILL.md +65 -0
  160. package/integrations/openclaw/skills/memory-discipline/TROUBLESHOOTING.md +70 -0
  161. package/integrations/openclaw/skills/recall/EXAMPLES.md +74 -0
  162. package/integrations/openclaw/skills/recall/SKILL.md +74 -0
  163. package/integrations/openclaw/skills/recall/TROUBLESHOOTING.md +70 -0
  164. package/integrations/openclaw/skills/recap/EXAMPLES.md +62 -0
  165. package/integrations/openclaw/skills/recap/SKILL.md +68 -0
  166. package/integrations/openclaw/skills/recap/TROUBLESHOOTING.md +70 -0
  167. package/integrations/openclaw/skills/remember/EXAMPLES.md +67 -0
  168. package/integrations/openclaw/skills/remember/SKILL.md +66 -0
  169. package/integrations/openclaw/skills/remember/TROUBLESHOOTING.md +70 -0
  170. package/integrations/openclaw/skills/session-history/EXAMPLES.md +59 -0
  171. package/integrations/openclaw/skills/session-history/SKILL.md +67 -0
  172. package/integrations/openclaw/skills/session-history/TROUBLESHOOTING.md +70 -0
  173. package/integrations/openclaw/skills/write-agentmemory-skill/SKILL.md +41 -0
  174. package/integrations/openclaw/skills/write-agentmemory-skill/TROUBLESHOOTING.md +70 -0
  175. package/integrations/pi/LICENSE +190 -0
  176. package/integrations/pi/README.md +46 -51
  177. package/integrations/pi/dist/index.mjs +1460 -0
  178. package/integrations/pi/index.ts +192 -175
  179. package/integrations/pi/package.json +17 -7
  180. package/integrations/pi/security.ts +6 -26
  181. package/integrations/pi/skills/agentmemory-agents/REFERENCE.md +32 -0
  182. package/integrations/pi/skills/agentmemory-agents/SKILL.md +48 -0
  183. package/integrations/pi/skills/agentmemory-agents/TROUBLESHOOTING.md +70 -0
  184. package/integrations/pi/skills/agentmemory-architecture/SKILL.md +37 -0
  185. package/integrations/pi/skills/agentmemory-architecture/TROUBLESHOOTING.md +70 -0
  186. package/integrations/pi/skills/agentmemory-config/REFERENCE.md +91 -0
  187. package/integrations/pi/skills/agentmemory-config/SKILL.md +98 -0
  188. package/integrations/pi/skills/agentmemory-config/TROUBLESHOOTING.md +70 -0
  189. package/integrations/pi/skills/agentmemory-hooks/REFERENCE.md +20 -0
  190. package/integrations/pi/skills/agentmemory-hooks/SKILL.md +60 -0
  191. package/integrations/pi/skills/agentmemory-hooks/TROUBLESHOOTING.md +70 -0
  192. package/integrations/pi/skills/agentmemory-mcp-tools/REFERENCE.md +66 -0
  193. package/integrations/pi/skills/agentmemory-mcp-tools/SKILL.md +52 -0
  194. package/integrations/pi/skills/agentmemory-mcp-tools/TROUBLESHOOTING.md +70 -0
  195. package/integrations/pi/skills/agentmemory-rest-api/REFERENCE.md +159 -0
  196. package/integrations/pi/skills/agentmemory-rest-api/SKILL.md +49 -0
  197. package/integrations/pi/skills/agentmemory-rest-api/TROUBLESHOOTING.md +70 -0
  198. package/integrations/pi/skills/commit-context/EXAMPLES.md +71 -0
  199. package/integrations/pi/skills/commit-context/SKILL.md +64 -0
  200. package/integrations/pi/skills/commit-context/TROUBLESHOOTING.md +70 -0
  201. package/integrations/pi/skills/commit-history/EXAMPLES.md +71 -0
  202. package/integrations/pi/skills/commit-history/SKILL.md +62 -0
  203. package/integrations/pi/skills/commit-history/TROUBLESHOOTING.md +70 -0
  204. package/integrations/pi/skills/forget/EXAMPLES.md +40 -0
  205. package/integrations/pi/skills/forget/SKILL.md +73 -0
  206. package/integrations/pi/skills/forget/TROUBLESHOOTING.md +70 -0
  207. package/integrations/pi/skills/handoff/EXAMPLES.md +57 -0
  208. package/integrations/pi/skills/handoff/SKILL.md +75 -0
  209. package/integrations/pi/skills/handoff/TROUBLESHOOTING.md +70 -0
  210. package/integrations/pi/skills/lesson/SKILL.md +64 -0
  211. package/integrations/pi/skills/lesson/TROUBLESHOOTING.md +70 -0
  212. package/integrations/pi/skills/memory-discipline/SKILL.md +65 -0
  213. package/integrations/pi/skills/memory-discipline/TROUBLESHOOTING.md +70 -0
  214. package/integrations/pi/skills/recall/EXAMPLES.md +74 -0
  215. package/integrations/pi/skills/recall/SKILL.md +74 -0
  216. package/integrations/pi/skills/recall/TROUBLESHOOTING.md +70 -0
  217. package/integrations/pi/skills/recap/EXAMPLES.md +62 -0
  218. package/integrations/pi/skills/recap/SKILL.md +68 -0
  219. package/integrations/pi/skills/recap/TROUBLESHOOTING.md +70 -0
  220. package/integrations/pi/skills/remember/EXAMPLES.md +67 -0
  221. package/integrations/pi/skills/remember/SKILL.md +66 -0
  222. package/integrations/pi/skills/remember/TROUBLESHOOTING.md +70 -0
  223. package/integrations/pi/skills/session-history/EXAMPLES.md +59 -0
  224. package/integrations/pi/skills/session-history/SKILL.md +67 -0
  225. package/integrations/pi/skills/session-history/TROUBLESHOOTING.md +70 -0
  226. package/integrations/pi/skills/write-agentmemory-skill/SKILL.md +41 -0
  227. package/integrations/pi/skills/write-agentmemory-skill/TROUBLESHOOTING.md +70 -0
  228. package/package.json +33 -11
  229. package/plugin/.claude-plugin/plugin.json +16 -3
  230. package/plugin/.codex-plugin/plugin.json +4 -3
  231. package/plugin/.devin-plugin/plugin.json +6 -5
  232. package/plugin/.mcp.json +5 -1
  233. package/plugin/README.md +71 -0
  234. package/plugin/cursor/hooks.json +23 -8
  235. package/plugin/hooks/hooks.json +24 -12
  236. package/plugin/hooks.json +67 -0
  237. package/plugin/opencode/README.md +1 -1
  238. package/plugin/opencode/agentmemory-capture.ts +25 -11
  239. package/plugin/opencode/plugin.json +1 -1
  240. package/plugin/plugin.json +1 -1
  241. package/plugin/scripts/_capture.d.mts +5 -1
  242. package/plugin/scripts/_capture.d.mts.map +1 -1
  243. package/plugin/scripts/_capture.mjs +141 -26
  244. package/plugin/scripts/_capture.mjs.map +1 -1
  245. package/plugin/scripts/cursor/run-detached.mjs +786 -0
  246. package/plugin/scripts/cursor/run-detached.mjs.map +1 -0
  247. package/plugin/scripts/cursor/run-hook.d.mts +1 -0
  248. package/plugin/scripts/cursor/run-hook.mjs +704 -0
  249. package/plugin/scripts/cursor/run-hook.mjs.map +1 -0
  250. package/plugin/scripts/notification.mjs +20 -6
  251. package/plugin/scripts/notification.mjs.map +1 -1
  252. package/plugin/scripts/plugin-bridge.mjs +61 -11
  253. package/plugin/scripts/post-tool-failure.mjs +19 -6
  254. package/plugin/scripts/post-tool-failure.mjs.map +1 -1
  255. package/plugin/scripts/post-tool-use.mjs +19 -6
  256. package/plugin/scripts/post-tool-use.mjs.map +1 -1
  257. package/plugin/scripts/pre-compact.mjs +104 -22
  258. package/plugin/scripts/pre-compact.mjs.map +1 -1
  259. package/plugin/scripts/pre-tool-use.mjs +83 -10
  260. package/plugin/scripts/pre-tool-use.mjs.map +1 -1
  261. package/plugin/scripts/prompt-submit.mjs +12 -4
  262. package/plugin/scripts/prompt-submit.mjs.map +1 -1
  263. package/plugin/scripts/session-end.mjs +59 -17
  264. package/plugin/scripts/session-end.mjs.map +1 -1
  265. package/plugin/scripts/session-start.mjs +95 -15
  266. package/plugin/scripts/session-start.mjs.map +1 -1
  267. package/plugin/scripts/stop.mjs +75 -72
  268. package/plugin/scripts/stop.mjs.map +1 -1
  269. package/plugin/scripts/subagent-start.mjs +13 -5
  270. package/plugin/scripts/subagent-start.mjs.map +1 -1
  271. package/plugin/scripts/subagent-stop.mjs +32 -10
  272. package/plugin/scripts/subagent-stop.mjs.map +1 -1
  273. package/plugin/scripts/task-completed.mjs +21 -6
  274. package/plugin/scripts/task-completed.mjs.map +1 -1
  275. package/plugin/skills/_shared/TROUBLESHOOTING.md +21 -7
  276. package/plugin/skills/agentmemory-agents/REFERENCE.md +8 -7
  277. package/plugin/skills/agentmemory-agents/SKILL.md +19 -5
  278. package/plugin/skills/agentmemory-agents/TROUBLESHOOTING.md +70 -0
  279. package/plugin/skills/agentmemory-architecture/SKILL.md +8 -4
  280. package/plugin/skills/agentmemory-architecture/TROUBLESHOOTING.md +70 -0
  281. package/plugin/skills/agentmemory-config/REFERENCE.md +13 -15
  282. package/plugin/skills/agentmemory-config/SKILL.md +34 -10
  283. package/plugin/skills/agentmemory-config/TROUBLESHOOTING.md +70 -0
  284. package/plugin/skills/agentmemory-hooks/SKILL.md +31 -10
  285. package/plugin/skills/agentmemory-hooks/TROUBLESHOOTING.md +70 -0
  286. package/plugin/skills/agentmemory-mcp-tools/REFERENCE.md +5 -5
  287. package/plugin/skills/agentmemory-mcp-tools/SKILL.md +16 -3
  288. package/plugin/skills/agentmemory-mcp-tools/TROUBLESHOOTING.md +70 -0
  289. package/plugin/skills/agentmemory-rest-api/REFERENCE.md +10 -1
  290. package/plugin/skills/agentmemory-rest-api/SKILL.md +12 -6
  291. package/plugin/skills/agentmemory-rest-api/TROUBLESHOOTING.md +70 -0
  292. package/plugin/skills/commit-context/SKILL.md +1 -1
  293. package/plugin/skills/commit-context/TROUBLESHOOTING.md +70 -0
  294. package/plugin/skills/commit-history/SKILL.md +1 -1
  295. package/plugin/skills/commit-history/TROUBLESHOOTING.md +70 -0
  296. package/plugin/skills/forget/EXAMPLES.md +19 -54
  297. package/plugin/skills/forget/SKILL.md +16 -12
  298. package/plugin/skills/forget/TROUBLESHOOTING.md +70 -0
  299. package/plugin/skills/handoff/EXAMPLES.md +5 -4
  300. package/plugin/skills/handoff/SKILL.md +10 -5
  301. package/plugin/skills/handoff/TROUBLESHOOTING.md +70 -0
  302. package/plugin/skills/lesson/SKILL.md +1 -1
  303. package/plugin/skills/lesson/TROUBLESHOOTING.md +70 -0
  304. package/plugin/skills/memory-discipline/SKILL.md +1 -1
  305. package/plugin/skills/memory-discipline/TROUBLESHOOTING.md +70 -0
  306. package/plugin/skills/recall/SKILL.md +18 -7
  307. package/plugin/skills/recall/TROUBLESHOOTING.md +70 -0
  308. package/plugin/skills/recap/EXAMPLES.md +5 -3
  309. package/plugin/skills/recap/SKILL.md +11 -6
  310. package/plugin/skills/recap/TROUBLESHOOTING.md +70 -0
  311. package/plugin/skills/remember/EXAMPLES.md +3 -3
  312. package/plugin/skills/remember/SKILL.md +1 -1
  313. package/plugin/skills/remember/TROUBLESHOOTING.md +70 -0
  314. package/plugin/skills/session-history/EXAMPLES.md +2 -2
  315. package/plugin/skills/session-history/SKILL.md +10 -4
  316. package/plugin/skills/session-history/TROUBLESHOOTING.md +70 -0
  317. package/plugin/skills/write-agentmemory-skill/SKILL.md +2 -1
  318. package/plugin/skills/write-agentmemory-skill/TROUBLESHOOTING.md +70 -0
  319. package/dist/connect-B4_ca6BD.mjs.map +0 -1
  320. package/dist/docker-compose.yml +0 -73
  321. package/dist/iii-config.docker.yaml +0 -53
  322. package/dist/iii-config.yaml +0 -63
  323. package/dist/keyed-mutex-DchXsyfP.mjs.map +0 -1
  324. package/dist/secret-store-BnY3A50C.mjs.map +0 -1
  325. package/dist/src-Jsq9LCeH.mjs.map +0 -1
  326. package/dist/standalone-DKCdrf1d.mjs.map +0 -1
  327. package/dist/status-IRz7ta8-.mjs +0 -2344
  328. package/dist/status-IRz7ta8-.mjs.map +0 -1
  329. package/docker-compose.yml +0 -73
  330. package/iii-config.docker.yaml +0 -53
  331. package/iii-config.yaml +0 -63
  332. package/plugin/scripts/post-commit.mjs +0 -184
  333. package/plugin/scripts/post-commit.mjs.map +0 -1
  334. /package/plugin/scripts/{post-commit.d.mts → cursor/run-detached.d.mts} +0 -0
@@ -1,10 +1,13 @@
1
1
  import "node:module";
2
- import { copyFileSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
3
- import { dirname, join, resolve } from "node:path";
2
+ import { copyFileSync, cpSync, existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, writeFileSync } from "node:fs";
3
+ import { dirname, join, relative, resolve, sep } from "node:path";
4
4
  import { fileURLToPath } from "node:url";
5
5
  import { homedir, platform } from "node:os";
6
6
  import * as p from "@clack/prompts";
7
7
  import pc from "picocolors";
8
+ import { createHash, randomUUID } from "node:crypto";
9
+ import { Document, isMap, isSeq, parseDocument } from "yaml";
10
+ import JSON5 from "json5";
8
11
  //#region \0rolldown/runtime.js
9
12
  var __defProp = Object.defineProperty;
10
13
  var __exportAll = (all, no_symbols) => {
@@ -17,6 +20,91 @@ var __exportAll = (all, no_symbols) => {
17
20
  return target;
18
21
  };
19
22
  //#endregion
23
+ //#region src/cli/connect/util.ts
24
+ const AGENTMEMORY_MCP_BLOCK = {
25
+ command: "npx",
26
+ args: ["-y", "@agentmemory/mcp"],
27
+ env: {
28
+ AGENTMEMORY_URL: "${AGENTMEMORY_URL:-http://localhost:3111}",
29
+ AGENTMEMORY_SECRET: "${AGENTMEMORY_SECRET:-}",
30
+ AGENTMEMORY_TOOLS: "${AGENTMEMORY_TOOLS:-all}"
31
+ }
32
+ };
33
+ const AGENTMEMORY_COPILOT_MCP_BLOCK = {
34
+ type: "local",
35
+ ...process.platform === "win32" ? {
36
+ command: process.env["ComSpec"] || process.env["COMSPEC"] || "cmd.exe",
37
+ args: [
38
+ "/d",
39
+ "/s",
40
+ "/c",
41
+ "npx",
42
+ "-y",
43
+ "@agentmemory/mcp"
44
+ ]
45
+ } : {
46
+ command: "npx",
47
+ args: ["-y", "@agentmemory/mcp"]
48
+ },
49
+ env: {
50
+ AGENTMEMORY_URL: "${AGENTMEMORY_URL:-http://localhost:3111}",
51
+ AGENTMEMORY_SECRET: "${AGENTMEMORY_SECRET:-}",
52
+ AGENTMEMORY_TOOLS: "${AGENTMEMORY_TOOLS:-all}"
53
+ },
54
+ tools: ["*"]
55
+ };
56
+ function resolveDshHome(home = homedir()) {
57
+ const override = process.env["DSH_HOME"];
58
+ const value = override?.trim() ? override : join(home, ".dsh");
59
+ if (value === "~") return resolve(home);
60
+ if (value.startsWith("~/") || value.startsWith("~\\")) return resolve(join(home, value.slice(2)));
61
+ return resolve(value);
62
+ }
63
+ function backupsDir() {
64
+ return join(homedir(), ".agentmemory", "backups");
65
+ }
66
+ function ensureBackupsDir() {
67
+ const dir = backupsDir();
68
+ mkdirSync(dir, { recursive: true });
69
+ return dir;
70
+ }
71
+ function timestampSlug() {
72
+ return (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
73
+ }
74
+ function backupFile(sourcePath, agent, ext = "json") {
75
+ ensureBackupsDir();
76
+ const stamp = timestampSlug();
77
+ const target = join(backupsDir(), `${agent}-${stamp}.${ext}`);
78
+ copyFileSync(sourcePath, target);
79
+ return target;
80
+ }
81
+ function readJsonSafe(path) {
82
+ if (!existsSync(path)) return null;
83
+ try {
84
+ return JSON.parse(readFileSync(path, "utf-8"));
85
+ } catch {
86
+ return null;
87
+ }
88
+ }
89
+ function writeJsonAtomic(path, value) {
90
+ writeTextAtomic(path, `${JSON.stringify(value, null, 2)}\n`);
91
+ }
92
+ function writeTextAtomic(path, content) {
93
+ mkdirSync(dirname(path), { recursive: true });
94
+ const tmp = `${path}.tmp-${process.pid}-${Date.now()}`;
95
+ writeFileSync(tmp, content, "utf-8");
96
+ renameSync(tmp, path);
97
+ }
98
+ function logInstalled(label, target) {
99
+ p.log.success(`${label} → wired into ${target}`);
100
+ }
101
+ function logAlreadyWired(label, target) {
102
+ p.log.info(`${label} already wired in ${target} (use --force to re-install)`);
103
+ }
104
+ function logBackup(target) {
105
+ p.log.info(`Backup: ${target}`);
106
+ }
107
+ //#endregion
20
108
  //#region src/cli/connect/guidelines.ts
21
109
  const START = "<!-- agentmemory:start -->";
22
110
  const END = "<!-- agentmemory:end -->";
@@ -95,6 +183,13 @@ function guidelineTargets(home = homedir()) {
95
183
  scope: "global",
96
184
  source: "https://docs.factory.ai/cli/configuration/agents-md"
97
185
  },
186
+ dsh: {
187
+ globalPath: join(resolveDshHome(home), "AGENTS.md"),
188
+ projectPath: "AGENTS.md",
189
+ format: "block",
190
+ scope: "global",
191
+ source: "https://github.com/deepseek-ai/deepseek-harness"
192
+ },
98
193
  antigravity: {
99
194
  globalPath: join(home, ".gemini", "GEMINI.md"),
100
195
  projectPath: join(".agents", "rules", "agentmemory.md"),
@@ -123,7 +218,7 @@ function renderDedicated(format) {
123
218
  if (format === "steering") return `---\ninclusion: always\n---\n\n${GUIDELINE_BODY}\n`;
124
219
  return `${GUIDELINE_BODY}\n`;
125
220
  }
126
- function upsertBlock(existing) {
221
+ function upsertBlock$1(existing) {
127
222
  const block = `${START}\n${GUIDELINE_BODY}\n${END}`;
128
223
  const startIdx = existing.indexOf(START);
129
224
  const endIdx = existing.indexOf(END);
@@ -137,7 +232,7 @@ function writeGuideline(agentName, opts = { cwd: process.cwd() }) {
137
232
  const path = target.globalPath ?? join(opts.cwd, target.projectPath);
138
233
  const dedicated = target.format !== "block";
139
234
  const existing = existsSync(path) ? readFileSync(path, "utf8") : "";
140
- const next = dedicated ? renderDedicated(target.format) : upsertBlock(existing);
235
+ const next = dedicated ? renderDedicated(target.format) : upsertBlock$1(existing);
141
236
  if (existing === next) return {
142
237
  kind: "unchanged",
143
238
  path,
@@ -158,84 +253,6 @@ function writeGuideline(agentName, opts = { cwd: process.cwd() }) {
158
253
  };
159
254
  }
160
255
  //#endregion
161
- //#region src/cli/connect/util.ts
162
- const AGENTMEMORY_MCP_BLOCK = {
163
- command: "npx",
164
- args: ["-y", "@agentmemory/mcp"],
165
- env: {
166
- AGENTMEMORY_URL: "${AGENTMEMORY_URL:-http://localhost:3111}",
167
- AGENTMEMORY_SECRET: "${AGENTMEMORY_SECRET:-}",
168
- AGENTMEMORY_TOOLS: "${AGENTMEMORY_TOOLS:-all}"
169
- }
170
- };
171
- const AGENTMEMORY_COPILOT_MCP_BLOCK = {
172
- type: "local",
173
- ...process.platform === "win32" ? {
174
- command: process.env["ComSpec"] || process.env["COMSPEC"] || "cmd.exe",
175
- args: [
176
- "/d",
177
- "/s",
178
- "/c",
179
- "npx",
180
- "-y",
181
- "@agentmemory/mcp"
182
- ]
183
- } : {
184
- command: "npx",
185
- args: ["-y", "@agentmemory/mcp"]
186
- },
187
- env: {
188
- AGENTMEMORY_URL: "${AGENTMEMORY_URL:-http://localhost:3111}",
189
- AGENTMEMORY_SECRET: "${AGENTMEMORY_SECRET:-}",
190
- AGENTMEMORY_TOOLS: "${AGENTMEMORY_TOOLS:-all}"
191
- },
192
- tools: ["*"]
193
- };
194
- function backupsDir() {
195
- return join(homedir(), ".agentmemory", "backups");
196
- }
197
- function ensureBackupsDir() {
198
- const dir = backupsDir();
199
- mkdirSync(dir, { recursive: true });
200
- return dir;
201
- }
202
- function timestampSlug() {
203
- return (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
204
- }
205
- function backupFile(sourcePath, agent, ext = "json") {
206
- ensureBackupsDir();
207
- const stamp = timestampSlug();
208
- const target = join(backupsDir(), `${agent}-${stamp}.${ext}`);
209
- copyFileSync(sourcePath, target);
210
- return target;
211
- }
212
- function readJsonSafe(path) {
213
- if (!existsSync(path)) return null;
214
- try {
215
- return JSON.parse(readFileSync(path, "utf-8"));
216
- } catch {
217
- return null;
218
- }
219
- }
220
- function writeJsonAtomic(path, value) {
221
- writeTextAtomic(path, `${JSON.stringify(value, null, 2)}\n`);
222
- }
223
- function writeTextAtomic(path, content) {
224
- mkdirSync(dirname(path), { recursive: true });
225
- const tmp = `${path}.tmp-${process.pid}-${Date.now()}`;
226
- writeFileSync(tmp, content, "utf-8");
227
- renameSync(tmp, path);
228
- }
229
- function logInstalled(label, target) {
230
- p.log.success(`${label} → wired into ${target}`);
231
- }
232
- function logAlreadyWired(label, target) {
233
- p.log.info(`${label} already wired in ${target} (use --force to re-install)`);
234
- }
235
- function logBackup(target) {
236
- p.log.info(`Backup: ${target}`);
237
- }
238
- //#endregion
239
256
  //#region src/cli/connect/json-mcp-adapter.ts
240
257
  function entryMatches$3(entry) {
241
258
  if (!entry || typeof entry !== "object") return false;
@@ -413,13 +430,14 @@ function findPluginRoot(startUrl = import.meta.url) {
413
430
  /**
414
431
  * Build the merged hooks.json content.
415
432
  *
416
- * 1. Strip any entry from `existing` whose first hook command points
417
- * under `<pluginRoot>/scripts/`. This lets us re-install idempotently
418
- * without leaving stale references.
433
+ * 1. Strip every handler in `existing` whose command points under
434
+ * `<pluginRoot>/scripts/`, and an entry only once nothing else is left
435
+ * in it. This lets us re-install idempotently without leaving stale
436
+ * references or dropping the user's own handlers.
419
437
  * 2. Append fresh entries from the bundled Codex manifest with
420
438
  * `${CLAUDE_PLUGIN_ROOT}` rewritten to the absolute plugin path.
421
- * Matcher values from the bundled manifest are preserved so PreToolUse
422
- * event routing keeps working.
439
+ * Matchers and the other handler fields from the bundled manifest are
440
+ * preserved so PreToolUse event routing keeps working.
423
441
  */
424
442
  function buildMergedHooks(existing, pluginRoot, manifestFile = "hooks.codex.json") {
425
443
  const bundledManifestPath = join(pluginRoot, "hooks", manifestFile);
@@ -427,15 +445,26 @@ function buildMergedHooks(existing, pluginRoot, manifestFile = "hooks.codex.json
427
445
  const scriptsDir = join(pluginRoot, "scripts");
428
446
  const out = { hooks: {} };
429
447
  if (existing?.hooks) for (const [event, entries] of Object.entries(existing.hooks)) {
430
- const kept = entries.filter((entry) => !isAgentmemoryEntry(entry, scriptsDir));
448
+ const kept = entries.flatMap((entry) => {
449
+ const hooks = entry.hooks.filter((handler) => !isAgentmemoryHandler(handler, scriptsDir));
450
+ if (hooks.length === entry.hooks.length) return [entry];
451
+ return hooks.length > 0 ? [{
452
+ ...entry,
453
+ hooks
454
+ }] : [];
455
+ });
431
456
  if (kept.length > 0) out.hooks[event] = kept;
432
457
  }
433
458
  for (const [event, entries] of Object.entries(ours.hooks)) {
434
459
  const resolvedEntries = entries.map((entry) => {
435
- const next = { hooks: entry.hooks.map((handler) => ({
436
- type: handler.type,
437
- command: handler.command.replace(/\$\{CLAUDE_PLUGIN_ROOT\}/g, pluginRoot)
438
- })) };
460
+ const next = { hooks: entry.hooks.map((handler) => {
461
+ const resolved = {
462
+ ...handler,
463
+ command: withPluginRoot(handler.command, pluginRoot)
464
+ };
465
+ if (handler.args) resolved.args = handler.args.map((arg) => withPluginRoot(arg, pluginRoot));
466
+ return resolved;
467
+ }) };
439
468
  if (entry.matcher !== void 0) next.matcher = entry.matcher;
440
469
  return next;
441
470
  });
@@ -443,9 +472,11 @@ function buildMergedHooks(existing, pluginRoot, manifestFile = "hooks.codex.json
443
472
  }
444
473
  return out;
445
474
  }
446
- function isAgentmemoryEntry(entry, scriptsDir) {
447
- const normalizedScriptsDir = normalizePathForCommandMatch(scriptsDir);
448
- return entry.hooks.some((handler) => normalizePathForCommandMatch(handler.command).includes(normalizedScriptsDir));
475
+ function withPluginRoot(value, pluginRoot) {
476
+ return value?.replace(/\$\{CLAUDE_PLUGIN_ROOT\}/g, () => pluginRoot);
477
+ }
478
+ function isAgentmemoryHandler(handler, scriptsDir) {
479
+ return [handler.command, ...Array.isArray(handler.args) ? handler.args : []].some((part) => typeof part === "string" && normalizePathForCommandMatch(part).includes(normalizePathForCommandMatch(scriptsDir)));
449
480
  }
450
481
  function normalizePathForCommandMatch(value) {
451
482
  return value.replace(/\\/g, "/");
@@ -456,7 +487,7 @@ const GEMINI_DIR = join(homedir(), ".gemini");
456
487
  const ANTIGRAVITY_CLI_DIR = join(GEMINI_DIR, "antigravity-cli");
457
488
  const CUSTOMIZATION_DIR$1 = join(GEMINI_DIR, "config");
458
489
  const ANTIGRAVITY_CLI_HOOKS = join(CUSTOMIZATION_DIR$1, "hooks.json");
459
- const adapter$20 = createJsonMcpAdapter({
490
+ const adapter$21 = createJsonMcpAdapter({
460
491
  name: "antigravity-cli",
461
492
  displayName: "Antigravity CLI (agy)",
462
493
  detectDir: ANTIGRAVITY_CLI_DIR,
@@ -521,7 +552,7 @@ const mcpAdapter = createJsonMcpAdapter({
521
552
  protocolNote: "→ Using MCP via ~/.gemini/config/mcp_config.json, shared by current Antigravity surfaces. Pass --with-hooks for capture through ~/.gemini/config/hooks.json.",
522
553
  installHooks: installAntigravityCliHooks
523
554
  });
524
- const adapter$19 = {
555
+ const adapter$20 = {
525
556
  ...mcpAdapter,
526
557
  detect: () => mcpAdapter.detect() || existsSync(join(homedir(), ".gemini", "antigravity")) || existsSync(LEGACY_USER_DIR)
527
558
  };
@@ -536,7 +567,7 @@ function entryMatches$2(entry) {
536
567
  if (e["command"] !== "npx") return false;
537
568
  return (Array.isArray(e["args"]) ? e["args"] : []).includes("@agentmemory/mcp");
538
569
  }
539
- const adapter$18 = {
570
+ const adapter$19 = {
540
571
  name: "claude-code",
541
572
  displayName: "Claude Code",
542
573
  category: "native",
@@ -637,14 +668,21 @@ function installClaudeHooks(opts) {
637
668
  }
638
669
  //#endregion
639
670
  //#region src/cli/connect/cline.ts
640
- const adapter$17 = createJsonMcpAdapter({
641
- name: "cline",
642
- displayName: "Cline",
643
- detectDir: join(homedir(), ".cline"),
644
- configPath: join(homedir(), ".cline", "mcp.json"),
645
- docs: "https://github.com/rohitg00/agentmemory#other-agents",
646
- protocolNote: "→ Using MCP via ~/.cline/mcp.json (CLI). VS Code users: add the same block via Cline Settings → MCP Servers → Edit JSON."
647
- });
671
+ const CLINE_DIR = join(homedir(), ".cline");
672
+ const SETTINGS_OVERRIDE = process.env["CLINE_MCP_SETTINGS_PATH"];
673
+ const adapter$18 = {
674
+ ...createJsonMcpAdapter({
675
+ name: "cline",
676
+ displayName: "Cline",
677
+ detectDir: CLINE_DIR,
678
+ configPath: SETTINGS_OVERRIDE || join(CLINE_DIR, "data", "settings", "cline_mcp_settings.json"),
679
+ docs: "https://github.com/rohitg00/agentmemory#other-agents",
680
+ protocolNote: "→ Using MCP via ~/.cline/data/settings/cline_mcp_settings.json (CLI), or CLINE_MCP_SETTINGS_PATH when set. VS Code users: add the same block via Cline Settings → MCP Servers → Edit JSON."
681
+ }),
682
+ detect() {
683
+ return Boolean(SETTINGS_OVERRIDE) || existsSync(CLINE_DIR);
684
+ }
685
+ };
648
686
  //#endregion
649
687
  //#region src/cli/connect/copilot-cli.ts
650
688
  const COPILOT_DIR = process.env["COPILOT_HOME"] || join(homedir(), ".copilot");
@@ -653,7 +691,7 @@ function entryMatches$1(entry) {
653
691
  if (!entry || typeof entry !== "object") return false;
654
692
  return JSON.stringify(entry) === JSON.stringify(AGENTMEMORY_COPILOT_MCP_BLOCK);
655
693
  }
656
- const adapter$16 = {
694
+ const adapter$17 = {
657
695
  name: "copilot-cli",
658
696
  displayName: "GitHub Copilot CLI",
659
697
  category: "native",
@@ -736,7 +774,7 @@ function stripExistingBlock(toml) {
736
774
  }
737
775
  return out.join("\n").replace(/\n{3,}$/, "\n\n").trimEnd() + "\n";
738
776
  }
739
- const adapter$15 = {
777
+ const adapter$16 = {
740
778
  name: "codex",
741
779
  displayName: "Codex CLI",
742
780
  category: "native",
@@ -856,7 +894,7 @@ function renderFreshYaml() {
856
894
  ""
857
895
  ].join("\n");
858
896
  }
859
- const adapter$14 = {
897
+ const adapter$15 = {
860
898
  name: "continue",
861
899
  displayName: "Continue",
862
900
  category: "mcp",
@@ -936,13 +974,14 @@ const adapter$14 = {
936
974
  };
937
975
  //#endregion
938
976
  //#region src/cli/connect/cursor.ts
939
- const adapter$13 = createJsonMcpAdapter({
977
+ const adapter$14 = createJsonMcpAdapter({
940
978
  name: "cursor",
941
979
  displayName: "Cursor",
980
+ category: "native",
942
981
  detectDir: join(homedir(), ".cursor"),
943
982
  configPath: join(homedir(), ".cursor", "mcp.json"),
944
- docs: "https://github.com/rohitg00/agentmemory#other-agents",
945
- protocolNote: "→ Using MCP (the only protocol Cursor speaks). Memory bridge runs at :3111 underneath."
983
+ docs: "https://github.com/rohitg00/agentmemory#cursor",
984
+ protocolNote: "→ Using MCP. Lifecycle hooks ship in the Cursor plugin: Settings → Plugins → Add marketplace → this repo, then enable agentmemory."
946
985
  });
947
986
  //#endregion
948
987
  //#region src/cli/connect/devin.ts
@@ -956,7 +995,7 @@ function devinDir() {
956
995
  }
957
996
  const DEVIN_DIR = devinDir();
958
997
  const DEVIN_CONFIG = join(DEVIN_DIR, "config.json");
959
- const adapter$12 = createJsonMcpAdapter({
998
+ const adapter$13 = createJsonMcpAdapter({
960
999
  name: "devin",
961
1000
  displayName: "Devin CLI",
962
1001
  detectDir: DEVIN_DIR,
@@ -1006,7 +1045,7 @@ function installDevinHooks(opts) {
1006
1045
  //#region src/cli/connect/droid.ts
1007
1046
  const DROID_DIR = join(homedir(), ".factory");
1008
1047
  const DROID_HOOKS = join(DROID_DIR, "hooks.json");
1009
- const adapter$11 = createJsonMcpAdapter({
1048
+ const adapter$12 = createJsonMcpAdapter({
1010
1049
  name: "droid",
1011
1050
  displayName: "Droid (Factory.ai)",
1012
1051
  detectDir: DROID_DIR,
@@ -1057,9 +1096,6 @@ function installDroidHooks(opts) {
1057
1096
  }
1058
1097
  //#endregion
1059
1098
  //#region src/cli/connect/dsh.ts
1060
- function dshHome() {
1061
- return process.env["DSH_HOME"] || join(homedir(), ".dsh");
1062
- }
1063
1099
  const MCP_BLOCK = `- insert:
1064
1100
  - id: agentmemory
1065
1101
  name: '@deepseek-ai/dsh-mcp-client'
@@ -1069,55 +1105,89 @@ const MCP_BLOCK = `- insert:
1069
1105
  command: npx
1070
1106
  args: ['-y', '@agentmemory/mcp']
1071
1107
  env:
1072
- AGENTMEMORY_URL: http://localhost:3111
1108
+ AGENTMEMORY_URL: !!js process.env.AGENTMEMORY_URL || 'http://localhost:3111'
1109
+ AGENTMEMORY_SECRET: !!js process.env.AGENTMEMORY_SECRET || ''
1073
1110
  `;
1074
1111
  const MCP_MARKER = "serverName: agentmemory";
1075
1112
  const HOOKS_MARKER = "id: agentmemory-hooks";
1076
- function hooksBlock(hooksConfigPath) {
1113
+ function hooksBlock(pluginPath) {
1077
1114
  return `- insert:
1078
1115
  - id: agentmemory-hooks
1079
- name: '@deepseek-ai/dsh-hooks-claude-code'
1080
- config:
1081
- configPath: ${JSON.stringify(hooksConfigPath)}
1116
+ name: ${JSON.stringify(pluginPath)}
1082
1117
  `;
1083
1118
  }
1084
- function stripBlock(content, marker) {
1085
- if (!content.includes(marker)) return content;
1086
- const lines = content.split("\n");
1087
- const markerIdx = lines.findIndex((l) => l.includes(marker));
1088
- let start = markerIdx;
1089
- while (start > 0 && !lines[start].startsWith("- ")) start--;
1090
- let end = markerIdx + 1;
1091
- while (end < lines.length && !lines[end].startsWith("- ")) end++;
1092
- return lines.slice(0, start).concat(lines.slice(end)).join("\n").replace(/\n+$/, "\n");
1093
- }
1094
- function appendBlock(content, block) {
1095
- const base = content.replace(/\n+$/, "\n");
1096
- return base.trim() ? `${base}\n${block}` : block;
1097
- }
1098
- function installHooksFile(home) {
1099
- const hooksPath = join(home, "agentmemory.hooks.json");
1100
- const pluginRoot = findPluginRoot();
1101
- writeJsonAtomic(hooksPath, buildMergedHooks(readJsonSafe(hooksPath), pluginRoot, "hooks.codex.json"));
1102
- return hooksPath;
1103
- }
1104
- const adapter$10 = {
1119
+ function parsePatch(content) {
1120
+ const doc = parseDocument(content);
1121
+ if (doc.contents === null) doc.contents = doc.createNode([]);
1122
+ if (doc.errors.length || !isSeq(doc.contents)) throw new Error("Cannot update dsh cordis.patch.yml: expected a valid YAML sequence.");
1123
+ return {
1124
+ doc,
1125
+ operations: doc.contents
1126
+ };
1127
+ }
1128
+ function isManaged(entry, marker) {
1129
+ if (!isMap(entry)) return false;
1130
+ return marker === MCP_MARKER ? entry.get("name") === "@deepseek-ai/dsh-mcp-client" && entry.getIn(["config", "serverName"]) === "agentmemory" : entry.get("id") === "agentmemory-hooks" && typeof entry.get("name") === "string" && (entry.get("name") === "@deepseek-ai/dsh-hooks-claude-code" || /[\\/]dist[\\/]integrations[\\/]dsh\.mjs$/.test(String(entry.get("name"))));
1131
+ }
1132
+ function managedEntries(content, marker) {
1133
+ return parsePatch(content).operations.items.flatMap((operation) => {
1134
+ const entries = isMap(operation) ? operation.get("insert", true) : null;
1135
+ return isSeq(entries) ? entries.items.filter((entry) => isManaged(entry, marker)) : [];
1136
+ });
1137
+ }
1138
+ function hasBlock(content, marker) {
1139
+ return managedEntries(content, marker).length > 0;
1140
+ }
1141
+ function upsertBlock(content, marker, block) {
1142
+ const { doc, operations } = parsePatch(content);
1143
+ const addition = parsePatch(block).operations;
1144
+ const replacement = addition.getIn([
1145
+ 0,
1146
+ "insert",
1147
+ 0
1148
+ ], true);
1149
+ let replaced = false;
1150
+ for (let i = 0; i < operations.items.length; i++) {
1151
+ const operation = operations.items[i];
1152
+ if (!isMap(operation)) continue;
1153
+ const entries = operation.get("insert", true);
1154
+ if (!isSeq(entries)) continue;
1155
+ let removed = false;
1156
+ for (let j = 0; j < entries.items.length; j++) {
1157
+ if (!isManaged(entries.items[j], marker)) continue;
1158
+ if (!replaced) {
1159
+ entries.set(j, replacement);
1160
+ replaced = true;
1161
+ } else {
1162
+ entries.delete(j--);
1163
+ removed = true;
1164
+ }
1165
+ }
1166
+ if (removed && entries.items.length === 0) operations.delete(i--);
1167
+ }
1168
+ if (!replaced) operations.items.push(...addition.items);
1169
+ operations.flow = false;
1170
+ return doc.toString();
1171
+ }
1172
+ const adapter$11 = {
1105
1173
  name: "dsh",
1106
1174
  displayName: "DeepSeek Harness",
1107
- docs: "https://github.com/rohitg00/agentmemory#other-agents",
1108
- protocolNote: "→ Using MCP via $DSH_HOME/cordis.patch.yml (the home-level patch layer every profile loads). Tools appear as mcp__agentmemory__*. Pass --with-hooks to also wire auto-capture through Harness's Claude Code hook bridge.",
1175
+ docs: "https://github.com/rohitg00/agentmemory/blob/main/docs/dsh.md",
1176
+ protocolNote: "→ Using MCP via $DSH_HOME/cordis.patch.yml (the home-level patch layer every profile loads). Tools appear as mcp__agentmemory__*. Pass --with-hooks to also wire auto-capture with the bundled native DSH plugin.",
1109
1177
  category: "native",
1110
1178
  detect() {
1111
- return existsSync(dshHome());
1179
+ return existsSync(resolveDshHome());
1112
1180
  },
1113
1181
  async install(opts) {
1114
- const home = dshHome();
1115
- const configPath = join(home, "cordis.patch.yml");
1182
+ const configPath = join(resolveDshHome(), "cordis.patch.yml");
1116
1183
  const existing = existsSync(configPath) ? readFileSync(configPath, "utf-8") : "";
1117
1184
  const wantHooks = opts.withHooks === true;
1118
- const hasMcp = existing.includes(MCP_MARKER);
1119
- const hasHooks = existing.includes(HOOKS_MARKER);
1120
- if (hasMcp && (!wantHooks || hasHooks) && !opts.force) {
1185
+ const hasMcp = hasBlock(existing, MCP_MARKER);
1186
+ const hooks = managedEntries(existing, HOOKS_MARKER);
1187
+ const pluginPath = wantHooks ? join(dirname(findPluginRoot()), "dist", "integrations", "dsh.mjs") : "";
1188
+ const hooksReady = hooks.length === 1 && hooks[0].get("name") === pluginPath && existsSync(pluginPath);
1189
+ if (wantHooks && !opts.force && hooks.some((entry) => entry.get("name") === "@deepseek-ai/dsh-hooks-claude-code")) throw new Error("Legacy DSH hooks bridge found. Run agentmemory connect dsh --with-hooks --force to replace it with the bundled native plugin. Existing manifest files will be preserved.");
1190
+ if (hasMcp && (!wantHooks || hooksReady) && !opts.force) {
1121
1191
  logAlreadyWired(this.displayName, configPath);
1122
1192
  return {
1123
1193
  kind: "already-wired",
@@ -1125,28 +1195,23 @@ const adapter$10 = {
1125
1195
  };
1126
1196
  }
1127
1197
  if (opts.dryRun) {
1128
- p.log.info(`[dry-run] Would append the agentmemory mcp-client row${wantHooks ? " and the hooks-claude-code row" : ""} to ${configPath}`);
1198
+ p.log.info(`[dry-run] Would update the agentmemory mcp-client row${wantHooks ? " and the bundled capture plugin" : ""} in ${configPath}`);
1129
1199
  return {
1130
1200
  kind: "installed",
1131
1201
  mutatedPath: configPath
1132
1202
  };
1133
1203
  }
1204
+ if (wantHooks && !existsSync(pluginPath)) throw new Error("Bundled DSH plugin is missing. Reinstall AgentMemory, or run npm run build in a source checkout.");
1134
1205
  let backupPath;
1135
1206
  if (existsSync(configPath)) {
1136
1207
  backupPath = backupFile(configPath, this.name, "yml");
1137
1208
  logBackup(backupPath);
1138
1209
  } else mkdirSync(dirname(configPath), { recursive: true });
1139
- let next = stripBlock(existing, MCP_MARKER);
1140
- next = appendBlock(next, MCP_BLOCK);
1141
- if (wantHooks) {
1142
- const hooksPath = installHooksFile(home);
1143
- next = stripBlock(next, HOOKS_MARKER);
1144
- next = appendBlock(next, hooksBlock(hooksPath));
1145
- p.log.info(`Hook manifest: ${hooksPath}`);
1146
- }
1210
+ let next = hasMcp && !opts.force ? existing : upsertBlock(existing, MCP_MARKER, MCP_BLOCK);
1211
+ if (wantHooks && (!hooksReady || opts.force)) next = upsertBlock(next, HOOKS_MARKER, hooksBlock(pluginPath));
1147
1212
  writeTextAtomic(configPath, next);
1148
1213
  const written = readFileSync(configPath, "utf-8");
1149
- if (!written.includes(MCP_MARKER) || wantHooks && !written.includes(HOOKS_MARKER)) {
1214
+ if (!hasBlock(written, MCP_MARKER) || wantHooks && !hasBlock(written, HOOKS_MARKER)) {
1150
1215
  p.log.error(`Verification failed: ${configPath} did not contain the agentmemory rows after write.`);
1151
1216
  return {
1152
1217
  kind: "skipped",
@@ -1163,7 +1228,7 @@ const adapter$10 = {
1163
1228
  };
1164
1229
  //#endregion
1165
1230
  //#region src/cli/connect/gemini-cli.ts
1166
- const adapter$9 = createJsonMcpAdapter({
1231
+ const adapter$10 = createJsonMcpAdapter({
1167
1232
  name: "gemini-cli",
1168
1233
  displayName: "Gemini CLI",
1169
1234
  detectDir: join(homedir(), ".gemini"),
@@ -1172,43 +1237,275 @@ const adapter$9 = createJsonMcpAdapter({
1172
1237
  protocolNote: "→ Using MCP (the only protocol Gemini CLI speaks). Memory bridge runs at :3111 underneath."
1173
1238
  });
1174
1239
  //#endregion
1240
+ //#region src/cli/connect/native-install.ts
1241
+ const MANIFEST = ".agentmemory-install.json";
1242
+ const digest = (content) => createHash("sha256").update(content).digest("hex");
1243
+ const record = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
1244
+ function nativePackageRoot() {
1245
+ return dirname(findPluginRoot());
1246
+ }
1247
+ function nativeUserPath(value, home) {
1248
+ return resolve(value.replace(/^~(?=$|[/\\])/, () => home));
1249
+ }
1250
+ function nativeMcpEntry(packageRoot) {
1251
+ const entry = join(packageRoot, "dist", "standalone.mjs");
1252
+ if (!existsSync(entry)) throw new Error("Bundled MCP runtime is missing; reinstall AgentMemory before connecting.");
1253
+ return {
1254
+ command: process.execPath,
1255
+ args: [entry],
1256
+ env: {
1257
+ AGENTMEMORY_TOOLS: "all",
1258
+ AGENTMEMORY_FORCE_PROXY: "1"
1259
+ }
1260
+ };
1261
+ }
1262
+ function filesUnder(dir, prefix = "") {
1263
+ const files = /* @__PURE__ */ new Map();
1264
+ for (const item of readdirSync(dir, { withFileTypes: true })) {
1265
+ if ([
1266
+ "__pycache__",
1267
+ ".git",
1268
+ "node_modules",
1269
+ MANIFEST
1270
+ ].includes(item.name) || item.name.endsWith(".pyc")) continue;
1271
+ const path = join(dir, item.name);
1272
+ if (item.isSymbolicLink()) throw new Error(`Native installation does not follow symbolic links: ${path}`);
1273
+ const name = join(prefix, item.name);
1274
+ if (item.isDirectory()) for (const [key, value] of filesUnder(path, name)) files.set(key, value);
1275
+ else if (item.isFile()) files.set(name, readFileSync(path));
1276
+ }
1277
+ return files;
1278
+ }
1279
+ function rejectSymlink(path) {
1280
+ if (existsSync(path) && lstatSync(path).isSymbolicLink()) throw new Error(`Native installation does not replace symbolic links: ${path}`);
1281
+ }
1282
+ function prepareNativeBundle(source, target, label, required, force, skillsSource, extraFiles = {}) {
1283
+ if (!required.every((name) => existsSync(join(source, name)))) throw new Error(`Bundled ${label} files are missing; reinstall AgentMemory before connecting.`);
1284
+ rejectSymlink(target);
1285
+ const files = filesUnder(source);
1286
+ if (skillsSource) {
1287
+ if (!["remember/SKILL.md", "recall/SKILL.md"].every((name) => existsSync(join(skillsSource, name)))) throw new Error("Bundled skills are missing; reinstall AgentMemory before connecting.");
1288
+ for (const [name, content] of filesUnder(skillsSource)) files.set(join("skills", name), content);
1289
+ }
1290
+ for (const [name, content] of Object.entries(extraFiles)) files.set(name, Buffer.from(content));
1291
+ let previous = {};
1292
+ if (existsSync(join(target, MANIFEST))) {
1293
+ let stored;
1294
+ try {
1295
+ stored = JSON.parse(readFileSync(join(target, MANIFEST), "utf8"));
1296
+ } catch {
1297
+ stored = null;
1298
+ }
1299
+ if (!record(stored) || !record(stored.files) || !Object.values(stored.files).every((hash) => typeof hash === "string")) throw new Error(`Invalid native install manifest in ${target}; restore its backup before reconnecting.`);
1300
+ previous = stored.files;
1301
+ for (const name of Object.keys(previous)) {
1302
+ const location = relative(target, resolve(target, name));
1303
+ if (!location || location === ".." || location.startsWith(`..${sep}`) || resolve(target, name) === resolve(target, MANIFEST)) throw new Error(`Invalid native install path in ${target}.`);
1304
+ }
1305
+ }
1306
+ const installed = existsSync(target) ? filesUnder(target) : /* @__PURE__ */ new Map();
1307
+ if (!force) for (const [name, content] of installed) {
1308
+ if (!files.has(name) && !(name in previous)) continue;
1309
+ if (previous[name] ? digest(content) !== previous[name] : !files.get(name)?.equals(content)) throw new Error(`Customized ${label} file ${name} was preserved; use --force to replace it with a backup.`);
1310
+ }
1311
+ const changed = !existsSync(join(target, MANIFEST)) || [...files].some(([name, content]) => !installed.get(name)?.equals(content)) || Object.keys(previous).some((name) => !files.has(name) && installed.has(name));
1312
+ return {
1313
+ target,
1314
+ label,
1315
+ files,
1316
+ previous,
1317
+ changed
1318
+ };
1319
+ }
1320
+ function installNativeBundles(bundles, configPath, configText) {
1321
+ rejectSymlink(configPath);
1322
+ const transaction = randomUUID();
1323
+ const configStage = `${configPath}.stage-${transaction}`;
1324
+ const staged = [];
1325
+ let backupPath;
1326
+ try {
1327
+ for (const bundle of bundles.filter((item) => item.changed)) {
1328
+ mkdirSync(dirname(bundle.target), { recursive: true });
1329
+ const stage = `${bundle.target}.stage-${transaction}`;
1330
+ const item = {
1331
+ bundle,
1332
+ stage,
1333
+ rollback: `${bundle.target}.previous-${transaction}`,
1334
+ replaced: false,
1335
+ installed: false
1336
+ };
1337
+ staged.push(item);
1338
+ if (existsSync(bundle.target)) cpSync(bundle.target, stage, { recursive: true });
1339
+ else mkdirSync(stage);
1340
+ for (const name of Object.keys(bundle.previous)) if (!bundle.files.has(name)) rmSync(join(stage, name), { force: true });
1341
+ for (const [name, content] of bundle.files) {
1342
+ mkdirSync(dirname(join(stage, name)), { recursive: true });
1343
+ writeFileSync(join(stage, name), content);
1344
+ }
1345
+ writeFileSync(join(stage, MANIFEST), JSON.stringify({ files: Object.fromEntries([...bundle.files].map(([name, content]) => [name, digest(content)])) }) + "\n");
1346
+ if (existsSync(bundle.target)) {
1347
+ const backup = join(ensureBackupsDir(), `${bundle.label}-${transaction}`);
1348
+ cpSync(bundle.target, backup, { recursive: true });
1349
+ backupPath ??= backup;
1350
+ }
1351
+ }
1352
+ const configChanged = !existsSync(configPath) || readFileSync(configPath, "utf8") !== configText;
1353
+ if (configChanged && existsSync(configPath)) backupPath = backupFile(configPath, `native-config-${transaction}`, "config");
1354
+ if (configChanged) {
1355
+ mkdirSync(dirname(configPath), { recursive: true });
1356
+ writeFileSync(configStage, configText, { mode: existsSync(configPath) ? lstatSync(configPath).mode & 511 : 384 });
1357
+ }
1358
+ for (const item of staged) {
1359
+ if (existsSync(item.bundle.target)) {
1360
+ renameSync(item.bundle.target, item.rollback);
1361
+ item.replaced = true;
1362
+ }
1363
+ renameSync(item.stage, item.bundle.target);
1364
+ item.installed = true;
1365
+ }
1366
+ if (configChanged) renameSync(configStage, configPath);
1367
+ } catch (error) {
1368
+ for (const item of [...staged].reverse()) {
1369
+ if (item.installed) rmSync(item.bundle.target, {
1370
+ recursive: true,
1371
+ force: true
1372
+ });
1373
+ if (item.replaced) renameSync(item.rollback, item.bundle.target);
1374
+ }
1375
+ throw error;
1376
+ } finally {
1377
+ for (const item of staged) rmSync(item.stage, {
1378
+ recursive: true,
1379
+ force: true
1380
+ });
1381
+ rmSync(configStage, { force: true });
1382
+ }
1383
+ for (const item of staged) rmSync(item.rollback, {
1384
+ recursive: true,
1385
+ force: true
1386
+ });
1387
+ return backupPath;
1388
+ }
1389
+ //#endregion
1175
1390
  //#region src/cli/connect/hermes.ts
1176
- const HERMES_DIR = join(homedir(), ".hermes");
1177
- const HERMES_CONFIG = join(HERMES_DIR, "config.yaml");
1178
- const DOCS$2 = "https://github.com/rohitg00/agentmemory/tree/main/integrations/hermes";
1179
- const adapter$8 = {
1391
+ const hermesHome = () => {
1392
+ return nativeUserPath((process.env.HERMES_HOME?.trim() || join(homedir(), `.hermes${process.env.HERMES_DATA_DIR_SUFFIX ?? ""}`)).replace(/\$(?:\{([^}]+)\}|([A-Za-z_][A-Za-z_0-9]*))/g, (match, braced, plain) => process.env[braced ?? plain] ?? match), homedir());
1393
+ };
1394
+ const DOCS$1 = "https://github.com/rohitg00/agentmemory/tree/main/integrations/hermes";
1395
+ const stringList$1 = (value) => value === void 0 || Array.isArray(value) && value.every((item) => typeof item === "string");
1396
+ const adapter$9 = {
1180
1397
  name: "hermes",
1181
1398
  displayName: "Hermes Agent",
1182
1399
  category: "native",
1183
- docs: DOCS$2,
1184
- protocolNote: "→ Using MCP. Hooks are also available — see https://github.com/rohitg00/agentmemory/tree/main/integrations/hermes.",
1185
- detect() {
1186
- return existsSync(HERMES_DIR);
1187
- },
1188
- async install(_opts) {
1189
- p.log.warn("Hermes uses YAML config. Automated merge isn't implemented yet — manual install required.");
1190
- p.note([
1191
- `Add to ${HERMES_CONFIG}:`,
1192
- "",
1193
- " mcp_servers:",
1194
- " agentmemory:",
1195
- " command: npx",
1196
- " args: [\"-y\", \"@agentmemory/mcp\"]",
1197
- "",
1198
- " memory:",
1199
- " provider: agentmemory",
1200
- "",
1201
- `Full guide: ${DOCS$2}`
1202
- ].join("\n"), "Hermes manual install");
1203
- return {
1204
- kind: "stub",
1205
- reason: "yaml-merge-not-implemented"
1206
- };
1400
+ docs: DOCS$1,
1401
+ protocolNote: "→ Installs the native memory provider and bundled skills into the active Hermes profile. Credentials stay managed by Hermes.",
1402
+ detect: () => existsSync(hermesHome()),
1403
+ async install(opts) {
1404
+ const home = hermesHome();
1405
+ const path = join(home, "config.yaml");
1406
+ const raw = existsSync(path) ? readFileSync(path, "utf8") : "";
1407
+ const doc = parseDocument(raw);
1408
+ let existing;
1409
+ try {
1410
+ existing = doc.contents === null ? {} : doc.toJS({ maxAliasCount: 100 });
1411
+ } catch {
1412
+ existing = null;
1413
+ }
1414
+ if (doc.errors.length || !record(existing) || existing.memory !== void 0 && !record(existing.memory) || existing.plugins !== void 0 && !record(existing.plugins) || existing.mcp_servers !== void 0 && !record(existing.mcp_servers)) {
1415
+ p.log.warn(`Hermes config is not a valid YAML mapping. Left ${path} unchanged.`);
1416
+ return {
1417
+ kind: "skipped",
1418
+ reason: "invalid-config"
1419
+ };
1420
+ }
1421
+ const memory = existing.memory ?? {};
1422
+ const plugins = existing.plugins ?? {};
1423
+ const servers = existing.mcp_servers ?? {};
1424
+ if (!stringList$1(plugins.enabled) || !stringList$1(plugins.disabled) || memory.provider !== void 0 && typeof memory.provider !== "string") {
1425
+ p.log.warn(`Hermes provider or plugin settings are invalid. Left ${path} unchanged.`);
1426
+ return {
1427
+ kind: "skipped",
1428
+ reason: "invalid-config"
1429
+ };
1430
+ }
1431
+ if (servers.agentmemory !== void 0 && !record(servers.agentmemory) && !(opts.force && opts.withMcp)) {
1432
+ p.log.warn("Hermes's AgentMemory MCP entry is invalid. Repair it or use --force --with-mcp.");
1433
+ return {
1434
+ kind: "skipped",
1435
+ reason: "invalid-entry"
1436
+ };
1437
+ }
1438
+ if (memory.provider && memory.provider !== "agentmemory" && !opts.force) {
1439
+ p.log.warn("Hermes already selects another memory provider. Use --force to select AgentMemory and keep a backup.");
1440
+ return {
1441
+ kind: "skipped",
1442
+ reason: "memory-provider-conflict"
1443
+ };
1444
+ }
1445
+ if (plugins.disabled?.includes("agentmemory") && !opts.force) {
1446
+ p.log.warn("AgentMemory is disabled in this Hermes profile. Use --force to enable it.");
1447
+ return {
1448
+ kind: "skipped",
1449
+ reason: "plugin-disabled"
1450
+ };
1451
+ }
1452
+ try {
1453
+ const root = nativePackageRoot();
1454
+ const bundles = [prepareNativeBundle(join(root, "integrations", "hermes"), join(home, "plugins", "agentmemory"), "hermes-provider", ["__init__.py", "plugin.yaml"], opts.force), prepareNativeBundle(join(root, "plugin", "skills"), join(home, "skills", "agentmemory"), "hermes-skills", ["remember/SKILL.md", "recall/SKILL.md"], opts.force)];
1455
+ if (memory.provider !== "agentmemory") doc.setIn(["memory", "provider"], "agentmemory");
1456
+ const enabled = plugins.enabled ?? [];
1457
+ if (!enabled.includes("agentmemory")) doc.setIn(["plugins", "enabled"], [...enabled, "agentmemory"]);
1458
+ if (plugins.disabled?.includes("agentmemory")) doc.setIn(["plugins", "disabled"], plugins.disabled.filter((name) => name !== "agentmemory"));
1459
+ if (opts.withMcp) {
1460
+ p.log.warn("MCP exposes all AgentMemory tools against the configured backend. It does not enforce the native provider's profile scope; enable it only for a trusted, deliberately shared backend.");
1461
+ if (servers.agentmemory === void 0 || opts.force) {
1462
+ const entry = nativeMcpEntry(root);
1463
+ entry.env = {
1464
+ ...entry.env,
1465
+ AGENTMEMORY_URL: "${AGENTMEMORY_URL}",
1466
+ AGENTMEMORY_SECRET: "${AGENTMEMORY_SECRET}",
1467
+ AGENTMEMORY_CREDENTIAL_MODE: "explicit"
1468
+ };
1469
+ doc.setIn(["mcp_servers", "agentmemory"], entry);
1470
+ } else p.log.info("Preserved the existing AgentMemory MCP entry. After moving the installed package, review its settings and reconnect with --with-mcp --force to refresh its runtime path.");
1471
+ }
1472
+ const configText = doc.toString();
1473
+ if (opts.dryRun) {
1474
+ p.log.info(`[dry-run] Would install the native provider and skills, then activate AgentMemory in ${path}`);
1475
+ return {
1476
+ kind: "installed",
1477
+ mutatedPath: path
1478
+ };
1479
+ }
1480
+ let backupPath;
1481
+ const unchanged = !bundles.some((bundle) => bundle.changed) && configText === raw;
1482
+ if (unchanged) logAlreadyWired(this.displayName, path);
1483
+ else {
1484
+ backupPath = installNativeBundles(bundles, path, configText);
1485
+ if (backupPath) logBackup(backupPath);
1486
+ logInstalled(this.displayName, path);
1487
+ }
1488
+ p.log.info("Authentication is not verified. Start AgentMemory, then run `hermes memory setup` in this same HERMES_HOME to set its URL and scoped secret. Verify a save and recall in a new session. Skills needing tools beyond native save, recall and search require the optional --with-mcp connection.");
1489
+ return unchanged ? {
1490
+ kind: "already-wired",
1491
+ mutatedPath: path
1492
+ } : {
1493
+ kind: "installed",
1494
+ mutatedPath: path,
1495
+ ...backupPath ? { backupPath } : {}
1496
+ };
1497
+ } catch (error) {
1498
+ p.log.warn(error instanceof Error ? error.message : "Hermes installation failed; configuration was not activated.");
1499
+ return {
1500
+ kind: "skipped",
1501
+ reason: "native-install-failed"
1502
+ };
1503
+ }
1207
1504
  }
1208
1505
  };
1209
1506
  //#endregion
1210
1507
  //#region src/cli/connect/kiro.ts
1211
- const adapter$7 = createJsonMcpAdapter({
1508
+ const adapter$8 = createJsonMcpAdapter({
1212
1509
  name: "kiro",
1213
1510
  displayName: "Kiro",
1214
1511
  detectDir: join(homedir(), ".kiro"),
@@ -1218,15 +1515,182 @@ const adapter$7 = createJsonMcpAdapter({
1218
1515
  });
1219
1516
  //#endregion
1220
1517
  //#region src/cli/connect/openclaw.ts
1221
- const adapter$6 = createJsonMcpAdapter({
1518
+ const paths = () => {
1519
+ const home = nativeUserPath(process.env.OPENCLAW_HOME?.trim() || homedir(), homedir());
1520
+ const preferred = join(home, ".openclaw");
1521
+ const legacy = join(home, ".clawdbot");
1522
+ const state = process.env.OPENCLAW_STATE_DIR?.trim() ? nativeUserPath(process.env.OPENCLAW_STATE_DIR.trim(), home) : !existsSync(preferred) && existsSync(legacy) ? legacy : preferred;
1523
+ return {
1524
+ state,
1525
+ config: process.env.OPENCLAW_CONFIG_PATH?.trim() ? nativeUserPath(process.env.OPENCLAW_CONFIG_PATH.trim(), home) : !existsSync(join(state, "openclaw.json")) && existsSync(join(state, "clawdbot.json")) ? join(state, "clawdbot.json") : join(state, "openclaw.json")
1526
+ };
1527
+ };
1528
+ const stringList = (value) => value === void 0 || Array.isArray(value) && value.every((item) => typeof item === "string");
1529
+ const adapter$7 = {
1222
1530
  name: "openclaw",
1223
1531
  displayName: "OpenClaw",
1224
1532
  category: "native",
1225
- detectDir: join(homedir(), ".openclaw"),
1226
- configPath: join(homedir(), ".openclaw", "openclaw.json"),
1227
1533
  docs: "https://github.com/rohitg00/agentmemory/tree/main/integrations/openclaw",
1228
- protocolNote: "→ Using MCP. Hooks are also available — see https://github.com/rohitg00/agentmemory/tree/main/integrations/openclaw."
1229
- });
1534
+ protocolNote: "→ Installs native recall/capture and bundled skills into the active OpenClaw state directory. MCP tools are opt-in with --with-mcp.",
1535
+ detect: () => existsSync(paths().config) || existsSync(paths().state),
1536
+ async install(opts) {
1537
+ const { state, config: configPath } = paths();
1538
+ const raw = existsSync(configPath) ? readFileSync(configPath, "utf8") : "";
1539
+ let existing;
1540
+ try {
1541
+ existing = raw ? JSON5.parse(raw) : {};
1542
+ } catch {
1543
+ existing = null;
1544
+ }
1545
+ if (!record(existing) || [
1546
+ "mcp",
1547
+ "plugins",
1548
+ "skills"
1549
+ ].some((key) => existing[key] !== void 0 && !record(existing[key]))) {
1550
+ p.log.warn(`OpenClaw config is not a valid JSON/JSON5 object. Left ${configPath} unchanged.`);
1551
+ return {
1552
+ kind: "skipped",
1553
+ reason: "invalid-config"
1554
+ };
1555
+ }
1556
+ const next = { ...existing };
1557
+ const mcp = { ...next.mcp ?? {} };
1558
+ if (mcp.servers !== void 0 && !record(mcp.servers)) return {
1559
+ kind: "skipped",
1560
+ reason: "invalid-config"
1561
+ };
1562
+ const servers = { ...mcp.servers ?? {} };
1563
+ const legacyServers = record(next.mcpServers) ? { ...next.mcpServers } : {};
1564
+ const legacy = legacyServers.agentmemory;
1565
+ const migrateLegacy = record(legacy) && legacy.command === "npx" && Array.isArray(legacy.args) && legacy.args.includes("@agentmemory/mcp");
1566
+ if (next.mcpServers !== void 0 && (!migrateLegacy || Object.keys(legacyServers).some((key) => key !== "agentmemory"))) {
1567
+ p.log.warn("OpenClaw rejects the legacy mcpServers key. Left the file unchanged; migrate custom servers with OpenClaw's native configuration tools first.");
1568
+ return {
1569
+ kind: "skipped",
1570
+ reason: "legacy-config-needs-migration"
1571
+ };
1572
+ }
1573
+ if (servers.agentmemory !== void 0 && !record(servers.agentmemory) && !(opts.force && opts.withMcp)) {
1574
+ p.log.warn("OpenClaw's AgentMemory MCP entry is invalid. Repair it or use --force --with-mcp.");
1575
+ return {
1576
+ kind: "skipped",
1577
+ reason: "invalid-entry"
1578
+ };
1579
+ }
1580
+ const plugins = { ...next.plugins ?? {} };
1581
+ const skills = { ...next.skills ?? {} };
1582
+ if (["entries", "slots"].some((key) => plugins[key] !== void 0 && !record(plugins[key])) || skills.load !== void 0 && !record(skills.load) || !stringList(plugins.allow) || !stringList(plugins.deny)) return {
1583
+ kind: "skipped",
1584
+ reason: "invalid-config"
1585
+ };
1586
+ const entries = { ...plugins.entries ?? {} };
1587
+ const slots = { ...plugins.slots ?? {} };
1588
+ if (!stringList({ ...skills.load ?? {} }.extraDirs) || entries.agentmemory !== void 0 && !record(entries.agentmemory) || slots.memory !== void 0 && typeof slots.memory !== "string") return {
1589
+ kind: "skipped",
1590
+ reason: "invalid-config"
1591
+ };
1592
+ if (slots.memory !== void 0 && slots.memory !== "agentmemory" && !opts.force) {
1593
+ p.log.warn("OpenClaw already selects another memory plugin. Use --force to select AgentMemory and keep a backup.");
1594
+ return {
1595
+ kind: "skipped",
1596
+ reason: "memory-provider-conflict"
1597
+ };
1598
+ }
1599
+ const entry = { ...entries.agentmemory ?? {} };
1600
+ if (entry.hooks !== void 0 && !record(entry.hooks)) return {
1601
+ kind: "skipped",
1602
+ reason: "invalid-config"
1603
+ };
1604
+ const hooks = { ...entry.hooks ?? {} };
1605
+ if (plugins.enabled === false || !opts.force && (entry.enabled === false || hooks.allowConversationAccess === false || plugins.deny?.includes("agentmemory"))) {
1606
+ p.log.warn("OpenClaw plugin execution or AgentMemory conversation access is disabled. Enable it explicitly before connecting, or use --force for AgentMemory's own settings.");
1607
+ return {
1608
+ kind: "skipped",
1609
+ reason: "plugin-disabled"
1610
+ };
1611
+ }
1612
+ try {
1613
+ const root = nativePackageRoot();
1614
+ const bundles = [prepareNativeBundle(join(root, "integrations", "openclaw"), join(state, "extensions", "agentmemory"), "openclaw-plugin", [
1615
+ "plugin.mjs",
1616
+ "openclaw.plugin.json",
1617
+ "package.json"
1618
+ ], opts.force, join(root, "plugin", "skills"))];
1619
+ if (opts.withMcp || migrateLegacy) {
1620
+ p.log.warn("MCP exposes all AgentMemory tools against the configured backend. It does not enforce native profile scope; use it only for a trusted, deliberately shared backend.");
1621
+ if (servers.agentmemory === void 0 || opts.force) {
1622
+ const migrated = migrateLegacy && !opts.force ? { ...legacy } : {};
1623
+ const runtime = nativeMcpEntry(root);
1624
+ const env = {
1625
+ ...runtime.env,
1626
+ ...record(migrated.env) ? migrated.env : {}
1627
+ };
1628
+ for (const [key, value] of Object.entries(env)) {
1629
+ if (key === "AGENTMEMORY_URL" && value === "${AGENTMEMORY_URL:-http://localhost:3111}" || key === "AGENTMEMORY_SECRET" && value === "${AGENTMEMORY_SECRET:-}") delete env[key];
1630
+ if (key === "AGENTMEMORY_TOOLS" && value === "${AGENTMEMORY_TOOLS:-all}") env[key] = "all";
1631
+ }
1632
+ servers.agentmemory = {
1633
+ ...migrated,
1634
+ ...runtime,
1635
+ transport: "stdio",
1636
+ env
1637
+ };
1638
+ } else p.log.info("Preserved the existing AgentMemory MCP entry. After moving the installed package, review its settings and reconnect with --with-mcp --force to refresh its runtime path.");
1639
+ if (migrateLegacy) delete next.mcpServers;
1640
+ next.mcp = {
1641
+ ...mcp,
1642
+ servers
1643
+ };
1644
+ }
1645
+ entries.agentmemory = {
1646
+ ...entry,
1647
+ enabled: true,
1648
+ hooks: {
1649
+ ...hooks,
1650
+ allowConversationAccess: true
1651
+ }
1652
+ };
1653
+ plugins.entries = entries;
1654
+ plugins.slots = {
1655
+ ...slots,
1656
+ memory: "agentmemory"
1657
+ };
1658
+ if (plugins.allow !== void 0) plugins.allow = [...new Set([...plugins.allow, "agentmemory"])];
1659
+ if (plugins.deny?.includes("agentmemory")) plugins.deny = plugins.deny.filter((name) => name !== "agentmemory");
1660
+ next.plugins = plugins;
1661
+ const configText = JSON.stringify(next) === JSON.stringify(existing) ? raw : JSON.stringify(next, null, 2) + "\n";
1662
+ if (opts.dryRun) {
1663
+ p.log.info(`[dry-run] Would install native plugin and skills, then activate AgentMemory in ${configPath}`);
1664
+ return {
1665
+ kind: "installed",
1666
+ mutatedPath: configPath
1667
+ };
1668
+ }
1669
+ if (!bundles.some((bundle) => bundle.changed) && configText === raw) {
1670
+ logAlreadyWired(this.displayName, configPath);
1671
+ return {
1672
+ kind: "already-wired",
1673
+ mutatedPath: configPath
1674
+ };
1675
+ }
1676
+ const backupPath = installNativeBundles(bundles, configPath, configText);
1677
+ if (backupPath) logBackup(backupPath);
1678
+ logInstalled(this.displayName, configPath);
1679
+ p.log.info("Start AgentMemory and verify capture and recall in a new OpenClaw session. Skills that call memory tools require --with-mcp; authentication and connectivity are not yet verified.");
1680
+ return {
1681
+ kind: "installed",
1682
+ mutatedPath: configPath,
1683
+ ...backupPath ? { backupPath } : {}
1684
+ };
1685
+ } catch (error) {
1686
+ p.log.warn(error instanceof Error ? error.message : "OpenClaw installation failed; configuration was not activated.");
1687
+ return {
1688
+ kind: "skipped",
1689
+ reason: "native-install-failed"
1690
+ };
1691
+ }
1692
+ }
1693
+ };
1230
1694
  //#endregion
1231
1695
  //#region src/cli/connect/opencode.ts
1232
1696
  const CONFIG_PATH = join(homedir(), ".config", "opencode", "opencode.json");
@@ -1245,7 +1709,7 @@ function entryMatches(entry) {
1245
1709
  const command = entry["command"];
1246
1710
  return Array.isArray(command) && command.includes("@agentmemory/mcp");
1247
1711
  }
1248
- const adapter$5 = {
1712
+ const adapter$6 = {
1249
1713
  name: "opencode",
1250
1714
  displayName: "OpenCode",
1251
1715
  category: "mcp",
@@ -1301,12 +1765,12 @@ const adapter$5 = {
1301
1765
  //#endregion
1302
1766
  //#region src/cli/connect/openhuman.ts
1303
1767
  const OPENHUMAN_DIR = join(homedir(), ".openhuman");
1304
- const DOCS$1 = "https://github.com/tinyhumansai/openhuman";
1305
- const adapter$4 = {
1768
+ const DOCS = "https://github.com/tinyhumansai/openhuman";
1769
+ const adapter$5 = {
1306
1770
  name: "openhuman",
1307
1771
  displayName: "OpenHuman",
1308
1772
  category: "native",
1309
- docs: DOCS$1,
1773
+ docs: DOCS,
1310
1774
  protocolNote: "→ Using native hooks (REST API at :3111). MCP not required.",
1311
1775
  detect() {
1312
1776
  return existsSync(OPENHUMAN_DIR);
@@ -1319,7 +1783,7 @@ const adapter$4 = {
1319
1783
  "impl. Once integrations/openhuman/ lands in agentmemory we'll wire",
1320
1784
  "this up automatically.",
1321
1785
  "",
1322
- `Tracking: ${DOCS$1}`
1786
+ `Tracking: ${DOCS}`
1323
1787
  ].join("\n"), "OpenHuman manual install");
1324
1788
  return {
1325
1789
  kind: "stub",
@@ -1328,80 +1792,225 @@ const adapter$4 = {
1328
1792
  }
1329
1793
  };
1330
1794
  //#endregion
1331
- //#region src/cli/connect/pi.ts
1332
- const PI_DIR = join(homedir(), ".pi");
1333
- const PI_EXT_DIR = join(PI_DIR, "agent", "extensions", "agentmemory");
1334
- const DOCS = "https://github.com/rohitg00/agentmemory/tree/main/integrations/pi";
1335
- const EXT_FILES = ["index.ts", "security.ts"];
1336
- function findPiSourceDir() {
1337
- let packageRoot;
1338
- try {
1339
- packageRoot = dirname(findPluginRoot());
1340
- } catch {
1341
- return null;
1342
- }
1343
- const dir = join(packageRoot, "integrations", "pi");
1344
- return EXT_FILES.every((f) => existsSync(join(dir, f))) ? dir : null;
1795
+ //#region src/cli/connect/omp.ts
1796
+ function ompPaths() {
1797
+ const root = join(homedir(), process.env.PI_CONFIG_DIR || ".omp");
1798
+ const profile = (process.env.OMP_PROFILE ?? process.env.PI_PROFILE ?? "").trim();
1799
+ if (profile && profile !== "default" && (!/^[a-z0-9][a-z0-9._-]{0,63}$/.test(profile) || profile.endsWith(".") || /^(?:con|prn|aux|nul|com[0-9]|lpt[0-9])(?:\..*)?$/i.test(profile))) throw new Error("Invalid OMP profile; use the same valid OMP_PROFILE as Oh My Pi.");
1800
+ const configRoot = profile && profile !== "default" ? join(root, "profiles", profile) : root;
1801
+ return {
1802
+ root: configRoot,
1803
+ agent: configRoot !== root ? join(configRoot, "agent") : process.env.PI_CODING_AGENT_DIR ? resolve(process.env.PI_CODING_AGENT_DIR) : join(root, "agent"),
1804
+ profile: profile && profile !== "default" ? profile : void 0
1805
+ };
1345
1806
  }
1346
- const adapter$3 = {
1347
- name: "pi",
1348
- displayName: "pi",
1807
+ const adapter$4 = {
1808
+ name: "omp",
1809
+ displayName: "Oh My Pi",
1349
1810
  category: "native",
1350
- docs: DOCS,
1351
- protocolNote: "→ Using native lifecycle hooks against the REST API at :3111 (recall on agent start, capture on agent end, memory tools). MCP not required.",
1352
- detect() {
1353
- return existsSync(PI_DIR);
1811
+ docs: "https://github.com/rohitg00/agentmemory/tree/main/integrations/omp",
1812
+ protocolNote: "Installs native recall, capture and skills. Add --with-mcp for the full memory toolset.",
1813
+ detect: () => {
1814
+ try {
1815
+ const paths = ompPaths();
1816
+ return existsSync(paths.agent) || existsSync(paths.root);
1817
+ } catch {
1818
+ return false;
1819
+ }
1354
1820
  },
1355
1821
  async install(opts) {
1356
- const sourceDir = findPiSourceDir();
1357
- if (!sourceDir) {
1358
- p.log.error("Bundled pi extension not found (integrations/pi missing from the install) — reinstall agentmemory.");
1359
- return {
1360
- kind: "skipped",
1361
- reason: "bundled-extension-missing"
1822
+ try {
1823
+ const paths = ompPaths();
1824
+ const target = join(paths.agent, "agentmemory");
1825
+ const config = join(paths.agent, existsSync(join(paths.agent, "config.yml")) || !existsSync(join(paths.agent, "config.yaml")) ? "config.yml" : "config.yaml");
1826
+ const raw = existsSync(config) ? readFileSync(config, "utf8") : "";
1827
+ const legacy = join(paths.agent, "settings.json");
1828
+ const doc = !existsSync(config) && existsSync(legacy) ? new Document(JSON.parse(readFileSync(legacy, "utf8"))) : parseDocument(raw);
1829
+ const existing = doc.contents === null ? {} : doc.toJS({ maxAliasCount: 100 });
1830
+ if (doc.errors.length || !record(existing) || existing.extensions !== void 0 && (!Array.isArray(existing.extensions) || !existing.extensions.every((item) => typeof item === "string"))) throw new Error(`Invalid OMP configuration; left ${config} unchanged.`);
1831
+ const extensions = existing.extensions ?? [];
1832
+ const oldRoots = [
1833
+ ...extensions.map((value) => nativeUserPath(value, homedir())).filter((value) => value !== target),
1834
+ join(paths.root, "plugins/node_modules/agentmemory-omp-extension"),
1835
+ join(paths.agent, "plugins/node_modules/agentmemory-omp-extension"),
1836
+ join(process.cwd(), ".omp/plugins/node_modules/agentmemory-omp-extension"),
1837
+ join(paths.agent, "extensions/agentmemory")
1838
+ ];
1839
+ if (process.platform === "linux") {
1840
+ const dataRoot = join(process.env.XDG_DATA_HOME || join(homedir(), ".local/share"), "omp");
1841
+ oldRoots.push(join(dataRoot, ...paths.profile ? ["profiles", paths.profile] : [], "plugins/node_modules/agentmemory-omp-extension"));
1842
+ }
1843
+ for (const old of oldRoots) {
1844
+ const manifest = join(old, "package.json");
1845
+ if (existsSync(manifest) && JSON.parse(readFileSync(manifest, "utf8")).name === "agentmemory-omp-extension") throw new Error(`Another OMP AgentMemory extension exists at ${old}. Uninstall it with 'omp plugin uninstall agentmemory-omp-extension' or remove its extensions entry before reconnecting, to prevent duplicate capture.`);
1846
+ }
1847
+ const root = nativePackageRoot();
1848
+ const mcpPath = join(target, ".mcp.json");
1849
+ const extra = {};
1850
+ if (existsSync(mcpPath)) extra[".mcp.json"] = readFileSync(mcpPath, "utf8");
1851
+ let userOwnsMcp = false;
1852
+ if (opts.withMcp || existsSync(mcpPath)) {
1853
+ const nativeMcpPath = join(paths.agent, "mcp.json");
1854
+ userOwnsMcp = (existsSync(nativeMcpPath) ? JSON.parse(readFileSync(nativeMcpPath, "utf8")) : {}).mcpServers?.agentmemory !== void 0;
1855
+ if (userOwnsMcp) {
1856
+ delete extra[".mcp.json"];
1857
+ p.log.info("Preserved the existing AgentMemory MCP server in OMP's mcp.json.");
1858
+ } else if (opts.withMcp) extra[".mcp.json"] = JSON.stringify({ mcpServers: { agentmemory: nativeMcpEntry(root) } }, null, 2) + "\n";
1859
+ }
1860
+ const bundle = prepareNativeBundle(join(root, "integrations/omp"), target, "omp-extension", ["package.json", "dist/index.mjs"], opts.force, join(root, "plugin/skills"), extra);
1861
+ if (userOwnsMcp && existsSync(mcpPath) && !bundle.previous[".mcp.json"] && JSON.parse(readFileSync(mcpPath, "utf8")).mcpServers?.agentmemory !== void 0) throw new Error(`Unmanaged ${mcpPath} conflicts with OMP's mcp.json. Remove the duplicate AgentMemory configuration before reconnecting.`);
1862
+ if (!extensions.includes(target)) doc.set("extensions", [...extensions, target]);
1863
+ const text = doc.toString();
1864
+ if (opts.dryRun) {
1865
+ p.log.info(`[dry-run] Would install OMP's extension and skills into ${target}, then register it in ${config}.`);
1866
+ return {
1867
+ kind: "installed",
1868
+ mutatedPath: config
1869
+ };
1870
+ }
1871
+ const unchanged = !bundle.changed && text === raw;
1872
+ const backupPath = unchanged ? void 0 : installNativeBundles([bundle], config, text);
1873
+ if (backupPath) logBackup(backupPath);
1874
+ if (unchanged) logAlreadyWired(this.displayName, config);
1875
+ else logInstalled(this.displayName, config);
1876
+ p.log.info("Restart OMP and run /agentmemory-status. Native save/search work without MCP; the other bundled skills require --with-mcp. Project extensions arrays override this user setting: include the installed directory there when overriding extensions.");
1877
+ return unchanged ? {
1878
+ kind: "already-wired",
1879
+ mutatedPath: config
1880
+ } : {
1881
+ kind: "installed",
1882
+ mutatedPath: config,
1883
+ ...backupPath ? { backupPath } : {}
1362
1884
  };
1363
- }
1364
- const sources = EXT_FILES.map((f) => ({
1365
- name: f,
1366
- content: readFileSync(join(sourceDir, f), "utf-8"),
1367
- target: join(PI_EXT_DIR, f)
1368
- }));
1369
- if (sources.every((s) => existsSync(s.target) && readFileSync(s.target, "utf-8") === s.content) && !opts.force) {
1370
- logAlreadyWired(this.displayName, PI_EXT_DIR);
1885
+ } catch (error) {
1886
+ p.log.warn(error instanceof Error ? error.message : "OMP installation failed.");
1371
1887
  return {
1372
- kind: "already-wired",
1373
- mutatedPath: PI_EXT_DIR
1888
+ kind: "skipped",
1889
+ reason: "native-install-failed"
1374
1890
  };
1375
1891
  }
1376
- if (opts.dryRun) {
1377
- p.log.info(`[dry-run] Would install the pi extension (${EXT_FILES.join(", ")}) into ${PI_EXT_DIR}`);
1892
+ }
1893
+ };
1894
+ //#endregion
1895
+ //#region src/cli/connect/pi.ts
1896
+ const agentDir = () => process.env.PI_CODING_AGENT_DIR ? nativeUserPath(process.env.PI_CODING_AGENT_DIR, homedir()) : join(homedir(), ".pi/agent");
1897
+ const entryHash = (entry) => createHash("sha256").update(JSON.stringify(entry)).digest("hex");
1898
+ function readConfig(path) {
1899
+ if (!existsSync(path)) return {};
1900
+ if (lstatSync(path).isSymbolicLink()) throw new Error(`Pi configuration is a symbolic link; left ${path} unchanged.`);
1901
+ const value = JSON.parse(readFileSync(path, "utf8"));
1902
+ if (!record(value)) throw new Error(`Invalid Pi configuration; left ${path} unchanged.`);
1903
+ return value;
1904
+ }
1905
+ function hasPackage(config, configDir, target) {
1906
+ if (config.packages === void 0) return false;
1907
+ if (!Array.isArray(config.packages)) throw new Error("Pi settings.packages must be an array.");
1908
+ return config.packages.some((item) => {
1909
+ const source = typeof item === "string" ? item : record(item) ? item.source : void 0;
1910
+ if (typeof source !== "string") throw new Error("Invalid Pi package entry; configuration was preserved.");
1911
+ if (/^npm:@agentmemory\/pi(?:@|$)/.test(source)) return true;
1912
+ const path = source.startsWith("~") ? nativeUserPath(source, homedir()) : resolve(configDir, source);
1913
+ if (path === target) return false;
1914
+ const manifest = join(path, "package.json");
1915
+ return existsSync(manifest) && JSON.parse(readFileSync(manifest, "utf8")).name === "@agentmemory/pi";
1916
+ });
1917
+ }
1918
+ const adapter$3 = {
1919
+ name: "pi",
1920
+ displayName: "Pi",
1921
+ category: "native",
1922
+ docs: "https://github.com/rohitg00/agentmemory/tree/main/integrations/pi",
1923
+ protocolNote: "Installs native recall, capture and skills. Add --with-mcp for the full memory toolset.",
1924
+ detect: () => existsSync(agentDir()) || existsSync(join(homedir(), ".pi")),
1925
+ async install(opts) {
1926
+ try {
1927
+ const dir = agentDir();
1928
+ const target = join(dir, "agentmemory");
1929
+ const configPath = join(dir, "settings.json");
1930
+ const config = readConfig(configPath);
1931
+ const projectPath = join(process.cwd(), ".pi/settings.json");
1932
+ const packaged = hasPackage(config, dir, target);
1933
+ const projectConfig = readConfig(projectPath);
1934
+ if (!packaged && hasPackage(projectConfig, dirname(projectPath), target)) throw new Error("AgentMemory is configured as a project Pi package. Remove that package entry before installing globally, or keep using the project installation.");
1935
+ for (const [settings, base] of [[config, dir], [projectConfig, dirname(projectPath)]]) {
1936
+ if (!Array.isArray(settings.extensions)) continue;
1937
+ for (const entry of settings.extensions) {
1938
+ if (typeof entry !== "string") continue;
1939
+ const path = entry.startsWith("~") ? nativeUserPath(entry, homedir()) : resolve(base, entry);
1940
+ const manifest = join(/\.[cm]?[jt]s$/.test(path) ? dirname(path) : path, "package.json");
1941
+ if (existsSync(manifest) && JSON.parse(readFileSync(manifest, "utf8")).name === "@agentmemory/pi") throw new Error("Remove the explicit AgentMemory extensions entry before connecting; the package already declares its extension.");
1942
+ }
1943
+ }
1944
+ const legacy = join(dir, "extensions/agentmemory");
1945
+ if (existsSync(legacy)) throw new Error(`Move the old copied extension at ${legacy} outside Pi's extensions directory before reconnecting, to prevent duplicate capture. Keep it as a backup.`);
1946
+ const root = nativePackageRoot();
1947
+ const bundle = packaged ? void 0 : prepareNativeBundle(join(root, "integrations/pi"), target, "pi-extension", ["package.json", "dist/index.mjs"], opts.force, join(root, "plugin/skills"));
1948
+ if (packaged) p.log.info("Using the existing AgentMemory Pi package; no second extension was installed.");
1949
+ else {
1950
+ const packages = config.packages ?? [];
1951
+ if (!packages.some((item) => (typeof item === "string" ? item : record(item) ? item.source : void 0) === target)) config.packages = [...packages, target];
1952
+ }
1953
+ const text = JSON.stringify(config, null, 2) + "\n";
1954
+ const raw = existsSync(configPath) ? readFileSync(configPath, "utf8") : void 0;
1955
+ const mcpPath = join(dir, "mcp.json");
1956
+ const mcpRaw = existsSync(mcpPath) ? readFileSync(mcpPath, "utf8") : void 0;
1957
+ let mcpText = mcpRaw;
1958
+ if (opts.withMcp) {
1959
+ const mcp = readConfig(mcpPath);
1960
+ if (mcp.mcpServers !== void 0 && !record(mcp.mcpServers)) throw new Error("Invalid Pi mcpServers configuration; nothing was changed.");
1961
+ const servers = mcp.mcpServers ?? {};
1962
+ const managed = servers.agentmemory !== void 0 && record(mcp._agentmemoryConnector) && mcp._agentmemoryConnector.entryHash === entryHash(servers.agentmemory);
1963
+ if (servers.agentmemory !== void 0 && !managed) p.log.info("Preserved the existing AgentMemory MCP server. Project MCP settings apply only to trusted projects.");
1964
+ else {
1965
+ const entry = {
1966
+ ...nativeMcpEntry(root),
1967
+ exposure: "direct"
1968
+ };
1969
+ mcpText = JSON.stringify({
1970
+ ...mcp,
1971
+ mcpServers: {
1972
+ ...servers,
1973
+ agentmemory: entry
1974
+ },
1975
+ _agentmemoryConnector: { entryHash: entryHash(entry) }
1976
+ }, null, 2) + "\n";
1977
+ }
1978
+ }
1979
+ if (opts.dryRun) {
1980
+ p.log.info(`[dry-run] Would configure Pi in ${dir}.`);
1981
+ return {
1982
+ kind: "installed",
1983
+ mutatedPath: configPath
1984
+ };
1985
+ }
1986
+ const configChanged = !packaged && (bundle.changed || text !== raw);
1987
+ const mcpChanged = mcpText !== mcpRaw;
1988
+ let backupPath;
1989
+ if (mcpChanged) backupPath = installNativeBundles([], mcpPath, mcpText);
1990
+ try {
1991
+ if (configChanged) backupPath = installNativeBundles([bundle], configPath, text) ?? backupPath;
1992
+ } catch (error) {
1993
+ if (mcpChanged) if (mcpRaw === void 0) rmSync(mcpPath, { force: true });
1994
+ else installNativeBundles([], mcpPath, mcpRaw);
1995
+ throw error;
1996
+ }
1997
+ if (backupPath) logBackup(backupPath);
1998
+ const changed = configChanged || mcpChanged;
1999
+ if (changed) logInstalled(this.displayName, dir);
2000
+ else logAlreadyWired(this.displayName, dir);
2001
+ p.log.info("Restart Pi or /reload, then /agentmemory-status. Skills appear as /skill:<name>; the wider workflows require MCP. Reconnect after upgrading AgentMemory to refresh bundled runtime paths.");
1378
2002
  return {
1379
- kind: "installed",
1380
- mutatedPath: PI_EXT_DIR
2003
+ kind: changed ? "installed" : "already-wired",
2004
+ mutatedPath: configPath,
2005
+ ...backupPath ? { backupPath } : {}
1381
2006
  };
1382
- }
1383
- let backupPath;
1384
- for (const s of sources) if (existsSync(s.target) && readFileSync(s.target, "utf-8") !== s.content) {
1385
- const backup = backupFile(s.target, `${this.name}-${s.name.replace(/\.ts$/, "")}`, "ts");
1386
- logBackup(backup);
1387
- backupPath ??= backup;
1388
- }
1389
- mkdirSync(PI_EXT_DIR, { recursive: true });
1390
- for (const s of sources) writeTextAtomic(s.target, s.content);
1391
- if (!sources.every((s) => existsSync(s.target) && readFileSync(s.target, "utf-8") === s.content)) {
1392
- p.log.error(`Verification failed: ${PI_EXT_DIR} does not match the bundled extension.`);
2007
+ } catch (error) {
2008
+ p.log.warn(error instanceof Error ? error.message : "Pi installation failed.");
1393
2009
  return {
1394
2010
  kind: "skipped",
1395
- reason: "verification-failed"
2011
+ reason: "native-install-failed"
1396
2012
  };
1397
2013
  }
1398
- logInstalled(this.displayName, PI_EXT_DIR);
1399
- p.log.info("pi auto-discovers the extension on next launch; a running pi picks it up with /reload. Verify with /agentmemory-status.");
1400
- return {
1401
- kind: "installed",
1402
- mutatedPath: PI_EXT_DIR,
1403
- backupPath
1404
- };
1405
2014
  }
1406
2015
  };
1407
2016
  //#endregion
@@ -1446,27 +2055,28 @@ var connect_exports = /* @__PURE__ */ __exportAll({
1446
2055
  runConnect: () => runConnect
1447
2056
  });
1448
2057
  const ADAPTERS = [
1449
- adapter$18,
2058
+ adapter$19,
2059
+ adapter$17,
1450
2060
  adapter$16,
1451
- adapter$15,
2061
+ adapter$14,
1452
2062
  adapter$13,
1453
- adapter$12,
1454
- adapter$9,
2063
+ adapter$10,
1455
2064
  adapter$2,
1456
- adapter$19,
1457
2065
  adapter$20,
1458
- adapter$7,
2066
+ adapter$21,
2067
+ adapter$8,
1459
2068
  adapter$1,
1460
- adapter$17,
1461
- adapter$14,
2069
+ adapter$18,
2070
+ adapter$15,
1462
2071
  adapter,
2072
+ adapter$12,
1463
2073
  adapter$11,
1464
- adapter$10,
1465
- adapter$5,
1466
2074
  adapter$6,
1467
- adapter$8,
2075
+ adapter$7,
2076
+ adapter$9,
1468
2077
  adapter$3,
1469
- adapter$4
2078
+ adapter$4,
2079
+ adapter$5
1470
2080
  ];
1471
2081
  function resolveAdapter(name) {
1472
2082
  const lower = name.toLowerCase();
@@ -1481,11 +2091,13 @@ function parseFlags(args) {
1481
2091
  let force = false;
1482
2092
  let all = false;
1483
2093
  let withHooks = false;
2094
+ let withMcp = false;
1484
2095
  let guidelines = true;
1485
2096
  for (const a of args) if (a === "--dry-run") dryRun = true;
1486
2097
  else if (a === "--force") force = true;
1487
2098
  else if (a === "--all") all = true;
1488
2099
  else if (a === "--with-hooks") withHooks = true;
2100
+ else if (a === "--with-mcp") withMcp = true;
1489
2101
  else if (a === "--no-guidelines") guidelines = false;
1490
2102
  else if (!a.startsWith("-")) positional.push(a);
1491
2103
  return {
@@ -1493,6 +2105,7 @@ function parseFlags(args) {
1493
2105
  force,
1494
2106
  all,
1495
2107
  withHooks,
2108
+ withMcp,
1496
2109
  guidelines,
1497
2110
  positional
1498
2111
  };
@@ -1529,7 +2142,7 @@ async function runAdapter(adapter, opts) {
1529
2142
  }
1530
2143
  }
1531
2144
  async function runConnect(args) {
1532
- const { dryRun, force, all, withHooks, guidelines, positional } = parseFlags(args);
2145
+ const { dryRun, force, all, withHooks, withMcp, guidelines, positional } = parseFlags(args);
1533
2146
  const allowWindowsAdapter = positional.length === 1 && positional[0]?.toLowerCase() === "copilot-cli";
1534
2147
  if (platform() === "win32" && !allowWindowsAdapter) {
1535
2148
  p.intro("agentmemory connect");
@@ -1541,6 +2154,7 @@ async function runConnect(args) {
1541
2154
  dryRun,
1542
2155
  force,
1543
2156
  withHooks,
2157
+ withMcp,
1544
2158
  guidelines
1545
2159
  };
1546
2160
  p.intro("agentmemory connect");
@@ -1615,10 +2229,17 @@ function summarize(results) {
1615
2229
  p.note(lines.join("\n"), "summary");
1616
2230
  const stubs = results.filter((r) => r.result.kind === "stub");
1617
2231
  if (stubs.length > 0) p.log.info(`${stubs.length} agent(s) require manual install — see docs links above.`);
1618
- if (results.some((r) => r.result.kind === "installed" || r.result.kind === "already-wired")) p.log.info("Next: install agentmemory's 17 skills into the same agent(s) so they know when to call the tools:\n npx skills add rohitg00/agentmemory -y");
2232
+ if (results.some((r) => ![
2233
+ "hermes",
2234
+ "hermes-agent",
2235
+ "openclaw",
2236
+ "claw",
2237
+ "omp",
2238
+ "pi"
2239
+ ].includes(r.name) && (r.result.kind === "installed" || r.result.kind === "already-wired"))) p.log.info("Next: install agentmemory's 17 skills into the same agent(s) so they know when to call the tools:\n npx skills@1.7.1 add rohitg00/agentmemory -y");
1619
2240
  p.outro("Restart any wired agent (or open a new session) to pick up agentmemory.");
1620
2241
  }
1621
2242
  //#endregion
1622
2243
  export { runAdapter as a, resolveAdapter as i, connect_exports as n, knownAgents as r, ADAPTERS as t };
1623
2244
 
1624
- //# sourceMappingURL=connect-B4_ca6BD.mjs.map
2245
+ //# sourceMappingURL=connect-BX3njQ3Y.mjs.map