ziiagentmemory 0.1.0

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 (160) hide show
  1. package/.env.example +175 -0
  2. package/AGENTS.md +124 -0
  3. package/LICENSE +190 -0
  4. package/README.md +1546 -0
  5. package/dist/cli.d.mts +5 -0
  6. package/dist/cli.d.mts.map +1 -0
  7. package/dist/cli.mjs +2859 -0
  8. package/dist/cli.mjs.map +1 -0
  9. package/dist/config-ChC9EtgV.mjs +259 -0
  10. package/dist/config-ChC9EtgV.mjs.map +1 -0
  11. package/dist/connect-JnsJXc68.mjs +1075 -0
  12. package/dist/connect-JnsJXc68.mjs.map +1 -0
  13. package/dist/hooks/notification.d.mts +1 -0
  14. package/dist/hooks/notification.mjs +74 -0
  15. package/dist/hooks/notification.mjs.map +1 -0
  16. package/dist/hooks/post-commit.d.mts +1 -0
  17. package/dist/hooks/post-commit.mjs +101 -0
  18. package/dist/hooks/post-commit.mjs.map +1 -0
  19. package/dist/hooks/post-tool-failure.d.mts +1 -0
  20. package/dist/hooks/post-tool-failure.mjs +75 -0
  21. package/dist/hooks/post-tool-failure.mjs.map +1 -0
  22. package/dist/hooks/post-tool-use.d.mts +1 -0
  23. package/dist/hooks/post-tool-use.mjs +120 -0
  24. package/dist/hooks/post-tool-use.mjs.map +1 -0
  25. package/dist/hooks/pre-compact.d.mts +1 -0
  26. package/dist/hooks/pre-compact.mjs +78 -0
  27. package/dist/hooks/pre-compact.mjs.map +1 -0
  28. package/dist/hooks/pre-tool-use.d.mts +1 -0
  29. package/dist/hooks/pre-tool-use.mjs +84 -0
  30. package/dist/hooks/pre-tool-use.mjs.map +1 -0
  31. package/dist/hooks/prompt-submit.d.mts +1 -0
  32. package/dist/hooks/prompt-submit.mjs +67 -0
  33. package/dist/hooks/prompt-submit.mjs.map +1 -0
  34. package/dist/hooks/session-end.d.mts +1 -0
  35. package/dist/hooks/session-end.mjs +60 -0
  36. package/dist/hooks/session-end.mjs.map +1 -0
  37. package/dist/hooks/session-start.d.mts +1 -0
  38. package/dist/hooks/session-start.mjs +85 -0
  39. package/dist/hooks/session-start.mjs.map +1 -0
  40. package/dist/hooks/stop.d.mts +1 -0
  41. package/dist/hooks/stop.mjs +44 -0
  42. package/dist/hooks/stop.mjs.map +1 -0
  43. package/dist/hooks/subagent-start.d.mts +1 -0
  44. package/dist/hooks/subagent-start.mjs +73 -0
  45. package/dist/hooks/subagent-start.mjs.map +1 -0
  46. package/dist/hooks/subagent-stop.d.mts +1 -0
  47. package/dist/hooks/subagent-stop.mjs +74 -0
  48. package/dist/hooks/subagent-stop.mjs.map +1 -0
  49. package/dist/hooks/task-completed.d.mts +1 -0
  50. package/dist/hooks/task-completed.mjs +73 -0
  51. package/dist/hooks/task-completed.mjs.map +1 -0
  52. package/dist/image-refs-BKLmp_sD.mjs +34 -0
  53. package/dist/image-refs-BKLmp_sD.mjs.map +1 -0
  54. package/dist/image-refs-C2YU7BIm.mjs +34 -0
  55. package/dist/image-refs-C2YU7BIm.mjs.map +1 -0
  56. package/dist/index.d.mts +2 -0
  57. package/dist/index.mjs +22324 -0
  58. package/dist/index.mjs.map +1 -0
  59. package/dist/keyed-mutex-DTHtcZrt.mjs +88 -0
  60. package/dist/keyed-mutex-DTHtcZrt.mjs.map +1 -0
  61. package/dist/logger-BEB7pCI9.mjs +43 -0
  62. package/dist/logger-BEB7pCI9.mjs.map +1 -0
  63. package/dist/schema-CNiCWzV9.mjs +78 -0
  64. package/dist/schema-CNiCWzV9.mjs.map +1 -0
  65. package/dist/src-Cr3pH_uH.mjs +20745 -0
  66. package/dist/src-Cr3pH_uH.mjs.map +1 -0
  67. package/dist/standalone-C6KzNkt5.mjs +700 -0
  68. package/dist/standalone-C6KzNkt5.mjs.map +1 -0
  69. package/dist/standalone.d.mts +25 -0
  70. package/dist/standalone.d.mts.map +1 -0
  71. package/dist/standalone.mjs +1867 -0
  72. package/dist/standalone.mjs.map +1 -0
  73. package/dist/tools-registry-DCt2KAWA.mjs +1145 -0
  74. package/dist/tools-registry-DCt2KAWA.mjs.map +1 -0
  75. package/docker-compose.yml +47 -0
  76. package/iii-config.docker.yaml +53 -0
  77. package/iii-config.yaml +61 -0
  78. package/package.json +99 -0
  79. package/plugin/.claude-plugin/plugin.json +13 -0
  80. package/plugin/.codex-plugin/plugin.json +15 -0
  81. package/plugin/.mcp.copilot.json +15 -0
  82. package/plugin/.mcp.json +13 -0
  83. package/plugin/hooks/hooks.codex.json +67 -0
  84. package/plugin/hooks/hooks.copilot.json +72 -0
  85. package/plugin/hooks/hooks.json +125 -0
  86. package/plugin/opencode/README.md +229 -0
  87. package/plugin/opencode/agentmemory-capture.ts +687 -0
  88. package/plugin/opencode/commands/recall.md +19 -0
  89. package/plugin/opencode/commands/remember.md +19 -0
  90. package/plugin/opencode/plugin.json +12 -0
  91. package/plugin/plugin.json +15 -0
  92. package/plugin/scripts/diagnostics.mjs +551 -0
  93. package/plugin/scripts/notification.d.mts +1 -0
  94. package/plugin/scripts/notification.mjs +74 -0
  95. package/plugin/scripts/notification.mjs.map +1 -0
  96. package/plugin/scripts/post-commit.d.mts +1 -0
  97. package/plugin/scripts/post-commit.mjs +101 -0
  98. package/plugin/scripts/post-commit.mjs.map +1 -0
  99. package/plugin/scripts/post-tool-failure.d.mts +1 -0
  100. package/plugin/scripts/post-tool-failure.mjs +75 -0
  101. package/plugin/scripts/post-tool-failure.mjs.map +1 -0
  102. package/plugin/scripts/post-tool-use.d.mts +1 -0
  103. package/plugin/scripts/post-tool-use.mjs +120 -0
  104. package/plugin/scripts/post-tool-use.mjs.map +1 -0
  105. package/plugin/scripts/pre-compact.d.mts +1 -0
  106. package/plugin/scripts/pre-compact.mjs +78 -0
  107. package/plugin/scripts/pre-compact.mjs.map +1 -0
  108. package/plugin/scripts/pre-tool-use.d.mts +1 -0
  109. package/plugin/scripts/pre-tool-use.mjs +84 -0
  110. package/plugin/scripts/pre-tool-use.mjs.map +1 -0
  111. package/plugin/scripts/prompt-submit.d.mts +1 -0
  112. package/plugin/scripts/prompt-submit.mjs +67 -0
  113. package/plugin/scripts/prompt-submit.mjs.map +1 -0
  114. package/plugin/scripts/session-end.d.mts +1 -0
  115. package/plugin/scripts/session-end.mjs +60 -0
  116. package/plugin/scripts/session-end.mjs.map +1 -0
  117. package/plugin/scripts/session-start.d.mts +1 -0
  118. package/plugin/scripts/session-start.mjs +85 -0
  119. package/plugin/scripts/session-start.mjs.map +1 -0
  120. package/plugin/scripts/stop.d.mts +1 -0
  121. package/plugin/scripts/stop.mjs +44 -0
  122. package/plugin/scripts/stop.mjs.map +1 -0
  123. package/plugin/scripts/subagent-start.d.mts +1 -0
  124. package/plugin/scripts/subagent-start.mjs +73 -0
  125. package/plugin/scripts/subagent-start.mjs.map +1 -0
  126. package/plugin/scripts/subagent-stop.d.mts +1 -0
  127. package/plugin/scripts/subagent-stop.mjs +74 -0
  128. package/plugin/scripts/subagent-stop.mjs.map +1 -0
  129. package/plugin/scripts/task-completed.d.mts +1 -0
  130. package/plugin/scripts/task-completed.mjs +73 -0
  131. package/plugin/scripts/task-completed.mjs.map +1 -0
  132. package/plugin/skills/_shared/TROUBLESHOOTING.md +38 -0
  133. package/plugin/skills/agentmemory-agents/REFERENCE.md +28 -0
  134. package/plugin/skills/agentmemory-agents/SKILL.md +34 -0
  135. package/plugin/skills/agentmemory-architecture/SKILL.md +33 -0
  136. package/plugin/skills/agentmemory-config/REFERENCE.md +42 -0
  137. package/plugin/skills/agentmemory-config/SKILL.md +37 -0
  138. package/plugin/skills/agentmemory-hooks/REFERENCE.md +20 -0
  139. package/plugin/skills/agentmemory-hooks/SKILL.md +39 -0
  140. package/plugin/skills/agentmemory-mcp-tools/REFERENCE.md +65 -0
  141. package/plugin/skills/agentmemory-mcp-tools/SKILL.md +39 -0
  142. package/plugin/skills/agentmemory-rest-api/REFERENCE.md +129 -0
  143. package/plugin/skills/agentmemory-rest-api/SKILL.md +43 -0
  144. package/plugin/skills/commit-context/EXAMPLES.md +71 -0
  145. package/plugin/skills/commit-context/SKILL.md +64 -0
  146. package/plugin/skills/commit-history/EXAMPLES.md +71 -0
  147. package/plugin/skills/commit-history/SKILL.md +62 -0
  148. package/plugin/skills/forget/EXAMPLES.md +75 -0
  149. package/plugin/skills/forget/SKILL.md +66 -0
  150. package/plugin/skills/handoff/EXAMPLES.md +56 -0
  151. package/plugin/skills/handoff/SKILL.md +68 -0
  152. package/plugin/skills/recall/EXAMPLES.md +74 -0
  153. package/plugin/skills/recall/SKILL.md +60 -0
  154. package/plugin/skills/recap/EXAMPLES.md +60 -0
  155. package/plugin/skills/recap/SKILL.md +63 -0
  156. package/plugin/skills/remember/EXAMPLES.md +67 -0
  157. package/plugin/skills/remember/SKILL.md +61 -0
  158. package/plugin/skills/session-history/EXAMPLES.md +59 -0
  159. package/plugin/skills/session-history/SKILL.md +61 -0
  160. package/plugin/skills/write-agentmemory-skill/SKILL.md +40 -0
@@ -0,0 +1,1075 @@
1
+ import "node:module";
2
+ import { copyFileSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
3
+ import { dirname, join, resolve } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { homedir, platform } from "node:os";
6
+ import * as p from "@clack/prompts";
7
+ import pc from "picocolors";
8
+ //#region \0rolldown/runtime.js
9
+ var __defProp = Object.defineProperty;
10
+ var __exportAll = (all, no_symbols) => {
11
+ let target = {};
12
+ for (var name in all) __defProp(target, name, {
13
+ get: all[name],
14
+ enumerable: true
15
+ });
16
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
17
+ return target;
18
+ };
19
+ //#endregion
20
+ //#region src/cli/connect/util.ts
21
+ const AGENTMEMORY_MCP_BLOCK = {
22
+ command: "npx",
23
+ args: ["-y", "@agentmemory/mcp"],
24
+ env: {
25
+ AGENTMEMORY_URL: "${AGENTMEMORY_URL:-http://localhost:3111}",
26
+ AGENTMEMORY_SECRET: "${AGENTMEMORY_SECRET:-}",
27
+ AGENTMEMORY_TOOLS: "${AGENTMEMORY_TOOLS:-all}"
28
+ }
29
+ };
30
+ const AGENTMEMORY_COPILOT_MCP_BLOCK = {
31
+ type: "local",
32
+ ...process.platform === "win32" ? {
33
+ command: process.env["ComSpec"] || process.env["COMSPEC"] || "cmd.exe",
34
+ args: [
35
+ "/d",
36
+ "/s",
37
+ "/c",
38
+ "npx",
39
+ "-y",
40
+ "@agentmemory/mcp"
41
+ ]
42
+ } : {
43
+ command: "npx",
44
+ args: ["-y", "@agentmemory/mcp"]
45
+ },
46
+ env: {
47
+ AGENTMEMORY_URL: "${AGENTMEMORY_URL:-http://localhost:3111}",
48
+ AGENTMEMORY_SECRET: "${AGENTMEMORY_SECRET:-}",
49
+ AGENTMEMORY_TOOLS: "${AGENTMEMORY_TOOLS:-all}"
50
+ },
51
+ tools: ["*"]
52
+ };
53
+ function backupsDir() {
54
+ return join(homedir(), ".agentmemory", "backups");
55
+ }
56
+ function ensureBackupsDir() {
57
+ const dir = backupsDir();
58
+ mkdirSync(dir, { recursive: true });
59
+ return dir;
60
+ }
61
+ function timestampSlug() {
62
+ return (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
63
+ }
64
+ function backupFile(sourcePath, agent, ext = "json") {
65
+ ensureBackupsDir();
66
+ const stamp = timestampSlug();
67
+ const target = join(backupsDir(), `${agent}-${stamp}.${ext}`);
68
+ copyFileSync(sourcePath, target);
69
+ return target;
70
+ }
71
+ function readJsonSafe(path) {
72
+ if (!existsSync(path)) return null;
73
+ try {
74
+ return JSON.parse(readFileSync(path, "utf-8"));
75
+ } catch {
76
+ return null;
77
+ }
78
+ }
79
+ function writeJsonAtomic(path, value) {
80
+ mkdirSync(dirname(path), { recursive: true });
81
+ const tmp = `${path}.tmp-${process.pid}-${Date.now()}`;
82
+ writeFileSync(tmp, `${JSON.stringify(value, null, 2)}\n`, "utf-8");
83
+ renameSync(tmp, path);
84
+ }
85
+ function logInstalled(label, target) {
86
+ p.log.success(`${label} → wired into ${target}`);
87
+ }
88
+ function logAlreadyWired(label, target) {
89
+ p.log.info(`${label} already wired in ${target} (use --force to re-install)`);
90
+ }
91
+ function logBackup(target) {
92
+ p.log.info(`Backup: ${target}`);
93
+ }
94
+ //#endregion
95
+ //#region src/cli/connect/json-mcp-adapter.ts
96
+ function entryMatches$3(entry) {
97
+ if (!entry || typeof entry !== "object") return false;
98
+ const e = entry;
99
+ if (e["command"] !== "npx") return false;
100
+ return (Array.isArray(e["args"]) ? e["args"] : []).includes("@agentmemory/mcp");
101
+ }
102
+ function createJsonMcpAdapter(config) {
103
+ const wrapperKey = config.wrapperKey ?? "mcpServers";
104
+ return {
105
+ name: config.name,
106
+ displayName: config.displayName,
107
+ category: config.category ?? "mcp",
108
+ ...config.docs !== void 0 && { docs: config.docs },
109
+ ...config.protocolNote !== void 0 && { protocolNote: config.protocolNote },
110
+ detect() {
111
+ return existsSync(config.detectDir);
112
+ },
113
+ async install(opts) {
114
+ const existing = readJsonSafe(config.configPath);
115
+ const next = existing ? { ...existing } : {};
116
+ const servers = { ...next[wrapperKey] ?? {} };
117
+ const alreadyHas = entryMatches$3(servers["agentmemory"]);
118
+ if (alreadyHas && !opts.force) {
119
+ logAlreadyWired(config.displayName, config.configPath);
120
+ return {
121
+ kind: "already-wired",
122
+ mutatedPath: config.configPath
123
+ };
124
+ }
125
+ if (opts.dryRun) {
126
+ p.log.info(`[dry-run] Would ${alreadyHas ? "overwrite" : "add"} ${wrapperKey}.agentmemory in ${config.configPath}`);
127
+ return {
128
+ kind: "installed",
129
+ mutatedPath: config.configPath
130
+ };
131
+ }
132
+ let backupPath;
133
+ if (existsSync(config.configPath)) {
134
+ backupPath = backupFile(config.configPath, config.name);
135
+ logBackup(backupPath);
136
+ } else mkdirSync(dirname(config.configPath), { recursive: true });
137
+ servers["agentmemory"] = {
138
+ ...AGENTMEMORY_MCP_BLOCK,
139
+ ...config.extraEntryFields ?? {}
140
+ };
141
+ next[wrapperKey] = servers;
142
+ writeJsonAtomic(config.configPath, next);
143
+ const verifyServers = readJsonSafe(config.configPath)?.[wrapperKey];
144
+ if (!entryMatches$3(verifyServers?.["agentmemory"])) {
145
+ p.log.error(`Verification failed: ${config.configPath} did not contain ${wrapperKey}.agentmemory after write.`);
146
+ return {
147
+ kind: "skipped",
148
+ reason: "verification-failed"
149
+ };
150
+ }
151
+ logInstalled(config.displayName, config.configPath);
152
+ return {
153
+ kind: "installed",
154
+ mutatedPath: config.configPath,
155
+ ...backupPath !== void 0 && { backupPath }
156
+ };
157
+ }
158
+ };
159
+ }
160
+ //#endregion
161
+ //#region src/cli/connect/antigravity.ts
162
+ const ANTIGRAVITY_DIR = platform() === "darwin" ? join(homedir(), "Library", "Application Support", "Antigravity", "User") : join(homedir(), ".config", "Antigravity", "User");
163
+ const adapter$17 = createJsonMcpAdapter({
164
+ name: "antigravity",
165
+ displayName: "Antigravity",
166
+ detectDir: ANTIGRAVITY_DIR,
167
+ configPath: join(ANTIGRAVITY_DIR, "mcp_config.json"),
168
+ docs: "https://github.com/rohitg00/agentmemory#other-agents",
169
+ protocolNote: "→ Using MCP via mcp_config.json. Antigravity replaces Gemini CLI (sunset 2026-06-18)."
170
+ });
171
+ //#endregion
172
+ //#region src/cli/connect/codex-hooks.ts
173
+ /**
174
+ * Locate the bundled `plugin/` directory at runtime. Walks up from the
175
+ * module's own location looking for `plugin/scripts/` + `plugin/hooks/`,
176
+ * both shipped via the npm `files` field. Works for both `dist/cli.mjs`
177
+ * (bundled) and `src/cli/connect/codex-hooks.ts` (dev) layouts.
178
+ */
179
+ function findPluginRoot(startUrl = import.meta.url) {
180
+ const here = dirname(fileURLToPath(startUrl));
181
+ let dir = here;
182
+ for (let i = 0; i < 12; i++) {
183
+ if (existsSync(join(dir, "plugin", "scripts")) && existsSync(join(dir, "plugin", "hooks"))) return resolve(join(dir, "plugin"));
184
+ const parent = dirname(dir);
185
+ if (parent === dir) break;
186
+ dir = parent;
187
+ }
188
+ throw new Error(`agentmemory: could not locate bundled plugin/ directory (searched up from ${here})`);
189
+ }
190
+ /**
191
+ * Build the merged hooks.json content.
192
+ *
193
+ * 1. Strip any entry from `existing` whose first hook command points
194
+ * under `<pluginRoot>/scripts/`. This lets us re-install idempotently
195
+ * without leaving stale references.
196
+ * 2. Append fresh entries from the bundled Codex manifest with
197
+ * `${CLAUDE_PLUGIN_ROOT}` rewritten to the absolute plugin path.
198
+ * Matcher values from the bundled manifest are preserved so PreToolUse
199
+ * event routing keeps working.
200
+ */
201
+ function buildMergedHooks(existing, pluginRoot, manifestFile = "hooks.codex.json") {
202
+ const bundledManifestPath = join(pluginRoot, "hooks", manifestFile);
203
+ const ours = JSON.parse(readFileSync(bundledManifestPath, "utf-8"));
204
+ const scriptsDir = join(pluginRoot, "scripts");
205
+ const out = { hooks: {} };
206
+ if (existing?.hooks) for (const [event, entries] of Object.entries(existing.hooks)) {
207
+ const kept = entries.filter((entry) => !isAgentmemoryEntry(entry, scriptsDir));
208
+ if (kept.length > 0) out.hooks[event] = kept;
209
+ }
210
+ for (const [event, entries] of Object.entries(ours.hooks)) {
211
+ const resolvedEntries = entries.map((entry) => {
212
+ const next = { hooks: entry.hooks.map((handler) => ({
213
+ type: handler.type,
214
+ command: handler.command.replace(/\$\{CLAUDE_PLUGIN_ROOT\}/g, pluginRoot)
215
+ })) };
216
+ if (entry.matcher !== void 0) next.matcher = entry.matcher;
217
+ return next;
218
+ });
219
+ out.hooks[event] = [...out.hooks[event] ?? [], ...resolvedEntries];
220
+ }
221
+ return out;
222
+ }
223
+ function isAgentmemoryEntry(entry, scriptsDir) {
224
+ const normalizedScriptsDir = normalizePathForCommandMatch(scriptsDir);
225
+ return entry.hooks.some((handler) => normalizePathForCommandMatch(handler.command).includes(normalizedScriptsDir));
226
+ }
227
+ function normalizePathForCommandMatch(value) {
228
+ return value.replace(/\\/g, "/");
229
+ }
230
+ //#endregion
231
+ //#region src/cli/connect/claude-code.ts
232
+ const CLAUDE_DIR = join(homedir(), ".claude");
233
+ const CLAUDE_JSON = join(homedir(), ".claude.json");
234
+ const CLAUDE_SETTINGS = join(CLAUDE_DIR, "settings.json");
235
+ function entryMatches$2(entry) {
236
+ if (!entry || typeof entry !== "object") return false;
237
+ const e = entry;
238
+ if (e["command"] !== "npx") return false;
239
+ return (Array.isArray(e["args"]) ? e["args"] : []).includes("@agentmemory/mcp");
240
+ }
241
+ const adapter$16 = {
242
+ name: "claude-code",
243
+ displayName: "Claude Code",
244
+ category: "native",
245
+ docs: "https://github.com/rohitg00/agentmemory#claude-code-one-block-paste-it",
246
+ protocolNote: "→ Using MCP. Hooks are also available — see https://github.com/rohitg00/agentmemory#claude-code-one-block-paste-it.",
247
+ detect() {
248
+ return existsSync(CLAUDE_DIR);
249
+ },
250
+ async install(opts) {
251
+ const existing = readJsonSafe(CLAUDE_JSON);
252
+ const next = existing ? { ...existing } : {};
253
+ const servers = { ...next.mcpServers ?? {} };
254
+ const alreadyHas = entryMatches$2(servers["agentmemory"]);
255
+ if (alreadyHas && !opts.force) {
256
+ logAlreadyWired("Claude Code", CLAUDE_JSON);
257
+ if (opts.withHooks) {
258
+ const hookResult = installClaudeHooks(opts);
259
+ if (hookResult.kind === "skipped") p.log.warn(`Claude Code hooks fallback skipped: ${hookResult.reason}.`);
260
+ }
261
+ return {
262
+ kind: "already-wired",
263
+ mutatedPath: CLAUDE_JSON
264
+ };
265
+ }
266
+ if (opts.dryRun) {
267
+ p.log.info(`[dry-run] Would ${alreadyHas ? "overwrite" : "add"} mcpServers.agentmemory in ${CLAUDE_JSON}`);
268
+ return {
269
+ kind: "installed",
270
+ mutatedPath: CLAUDE_JSON
271
+ };
272
+ }
273
+ let backupPath;
274
+ if (existsSync(CLAUDE_JSON)) {
275
+ backupPath = backupFile(CLAUDE_JSON, "claude-code");
276
+ logBackup(backupPath);
277
+ } else {
278
+ mkdirSync(CLAUDE_DIR, { recursive: true });
279
+ writeFileSync(CLAUDE_JSON, "{}\n", "utf-8");
280
+ }
281
+ servers["agentmemory"] = AGENTMEMORY_MCP_BLOCK;
282
+ next.mcpServers = servers;
283
+ writeJsonAtomic(CLAUDE_JSON, next);
284
+ if (!entryMatches$2(readJsonSafe(CLAUDE_JSON)?.mcpServers?.["agentmemory"])) {
285
+ p.log.error(`Verification failed: ${CLAUDE_JSON} did not contain mcpServers.agentmemory after write.`);
286
+ return {
287
+ kind: "skipped",
288
+ reason: "verification-failed"
289
+ };
290
+ }
291
+ logInstalled("Claude Code", CLAUDE_JSON);
292
+ p.log.info("Restart Claude Code (or run `/mcp` inside a session) to pick up the new server.");
293
+ if (opts.withHooks) {
294
+ const hookResult = installClaudeHooks(opts);
295
+ if (hookResult.kind === "skipped") p.log.warn(`Claude Code hooks fallback skipped: ${hookResult.reason}. MCP wiring still applied.`);
296
+ }
297
+ return {
298
+ kind: "installed",
299
+ mutatedPath: CLAUDE_JSON,
300
+ backupPath
301
+ };
302
+ }
303
+ };
304
+ /**
305
+ * Merge the bundled `plugin/hooks/hooks.json` into
306
+ * `~/.claude/settings.json`'s top-level `hooks` field with absolute
307
+ * script paths. Use this when agentmemory is NOT installed through
308
+ * `/plugin marketplace add` (e.g. MCP standalone wiring), so the
309
+ * hook scripts survive version bumps without `${CLAUDE_PLUGIN_ROOT}`
310
+ * expansion (issue #508).
311
+ *
312
+ * Re-install strips entries whose command points under
313
+ * `<pluginRoot>/scripts/`; unrelated user hook entries survive.
314
+ */
315
+ function installClaudeHooks(opts) {
316
+ let pluginRoot;
317
+ try {
318
+ pluginRoot = findPluginRoot();
319
+ } catch (err) {
320
+ return {
321
+ kind: "skipped",
322
+ reason: err instanceof Error ? err.message : String(err)
323
+ };
324
+ }
325
+ const existing = readJsonSafe(CLAUDE_SETTINGS) ?? {};
326
+ const merged = buildMergedHooks(existing.hooks ? { hooks: existing.hooks } : null, pluginRoot, "hooks.json");
327
+ if (opts.dryRun) {
328
+ p.log.info(`[dry-run] Would merge agentmemory hook entries into ${CLAUDE_SETTINGS} (${Object.keys(merged.hooks).length} event(s))`);
329
+ return {
330
+ kind: "installed",
331
+ mutatedPath: CLAUDE_SETTINGS
332
+ };
333
+ }
334
+ let backupPath;
335
+ if (existsSync(CLAUDE_SETTINGS)) {
336
+ backupPath = backupFile(CLAUDE_SETTINGS, "claude-settings", "json");
337
+ logBackup(backupPath);
338
+ } else mkdirSync(CLAUDE_DIR, { recursive: true });
339
+ writeJsonAtomic(CLAUDE_SETTINGS, {
340
+ ...existing,
341
+ hooks: merged.hooks
342
+ });
343
+ logInstalled("Claude Code hooks (workaround for #508)", CLAUDE_SETTINGS);
344
+ p.log.info("User-scope hook entries reference absolute paths under the bundled plugin/ dir. Re-run `agentmemory connect claude-code --with-hooks` after upgrading agentmemory to refresh them.");
345
+ return {
346
+ kind: "installed",
347
+ mutatedPath: CLAUDE_SETTINGS,
348
+ ...backupPath !== void 0 && { backupPath }
349
+ };
350
+ }
351
+ //#endregion
352
+ //#region src/cli/connect/cline.ts
353
+ const adapter$15 = createJsonMcpAdapter({
354
+ name: "cline",
355
+ displayName: "Cline",
356
+ detectDir: join(homedir(), ".cline"),
357
+ configPath: join(homedir(), ".cline", "mcp.json"),
358
+ docs: "https://github.com/rohitg00/agentmemory#other-agents",
359
+ protocolNote: "→ Using MCP via ~/.cline/mcp.json (CLI). VS Code users: add the same block via Cline Settings → MCP Servers → Edit JSON."
360
+ });
361
+ //#endregion
362
+ //#region src/cli/connect/copilot-cli.ts
363
+ const COPILOT_DIR = process.env["COPILOT_HOME"] || join(homedir(), ".copilot");
364
+ const COPILOT_MCP_JSON = join(COPILOT_DIR, "mcp-config.json");
365
+ function entryMatches$1(entry) {
366
+ if (!entry || typeof entry !== "object") return false;
367
+ return JSON.stringify(entry) === JSON.stringify(AGENTMEMORY_COPILOT_MCP_BLOCK);
368
+ }
369
+ const adapter$14 = {
370
+ name: "copilot-cli",
371
+ displayName: "GitHub Copilot CLI",
372
+ category: "native",
373
+ docs: "https://github.com/rohitg00/agentmemory#github-copilot-cli",
374
+ protocolNote: "→ Using MCP. Install the plugin too for full hooks/skills coverage.",
375
+ detect() {
376
+ return existsSync(COPILOT_DIR);
377
+ },
378
+ async install(opts) {
379
+ const existing = readJsonSafe(COPILOT_MCP_JSON);
380
+ const next = existing ? { ...existing } : {};
381
+ const servers = { ...next.mcpServers ?? {} };
382
+ const alreadyHas = entryMatches$1(servers["agentmemory"]);
383
+ if (alreadyHas && !opts.force) {
384
+ logAlreadyWired("GitHub Copilot CLI", COPILOT_MCP_JSON);
385
+ return {
386
+ kind: "already-wired",
387
+ mutatedPath: COPILOT_MCP_JSON
388
+ };
389
+ }
390
+ if (opts.dryRun) {
391
+ p.log.info(`[dry-run] Would ${alreadyHas ? "overwrite" : "add"} mcpServers.agentmemory in ${COPILOT_MCP_JSON}`);
392
+ return {
393
+ kind: "installed",
394
+ mutatedPath: COPILOT_MCP_JSON
395
+ };
396
+ }
397
+ let backupPath;
398
+ if (existsSync(COPILOT_MCP_JSON)) {
399
+ backupPath = backupFile(COPILOT_MCP_JSON, "copilot-cli");
400
+ logBackup(backupPath);
401
+ } else mkdirSync(dirname(COPILOT_MCP_JSON), { recursive: true });
402
+ servers["agentmemory"] = AGENTMEMORY_COPILOT_MCP_BLOCK;
403
+ next.mcpServers = servers;
404
+ writeJsonAtomic(COPILOT_MCP_JSON, next);
405
+ if (!entryMatches$1(readJsonSafe(COPILOT_MCP_JSON)?.mcpServers?.["agentmemory"])) {
406
+ p.log.error(`Verification failed: ${COPILOT_MCP_JSON} did not contain mcpServers.agentmemory after write.`);
407
+ return {
408
+ kind: "skipped",
409
+ reason: "verification-failed"
410
+ };
411
+ }
412
+ logInstalled("GitHub Copilot CLI", COPILOT_MCP_JSON);
413
+ p.log.info("Copilot picks up MCP servers on next launch or after `/mcp`. Install the plugin too for full hooks/skills.");
414
+ return {
415
+ kind: "installed",
416
+ mutatedPath: COPILOT_MCP_JSON,
417
+ ...backupPath !== void 0 && { backupPath }
418
+ };
419
+ }
420
+ };
421
+ //#endregion
422
+ //#region src/cli/connect/codex.ts
423
+ const CODEX_DIR = join(homedir(), ".codex");
424
+ const CODEX_TOML = join(CODEX_DIR, "config.toml");
425
+ const CODEX_HOOKS = join(CODEX_DIR, "hooks.json");
426
+ const TOML_BLOCK = `[mcp_servers.agentmemory]
427
+ command = "npx"
428
+ args = ["-y", "@agentmemory/mcp"]
429
+
430
+ [mcp_servers.agentmemory.env]
431
+ AGENTMEMORY_URL = "http://localhost:3111"
432
+ `;
433
+ const SECTION_HEADER = "[mcp_servers.agentmemory]";
434
+ function isWiredText(toml) {
435
+ return toml.includes(SECTION_HEADER);
436
+ }
437
+ function stripExistingBlock(toml) {
438
+ const lines = toml.split(/\r?\n/);
439
+ const out = [];
440
+ let skipping = false;
441
+ for (const line of lines) {
442
+ const trimmed = line.trim();
443
+ if (trimmed === SECTION_HEADER || trimmed === "[mcp_servers.agentmemory.env]") {
444
+ skipping = true;
445
+ continue;
446
+ }
447
+ if (skipping && trimmed.startsWith("[") && trimmed !== "[mcp_servers.agentmemory.env]") skipping = false;
448
+ if (!skipping) out.push(line);
449
+ }
450
+ return out.join("\n").replace(/\n{3,}$/, "\n\n").trimEnd() + "\n";
451
+ }
452
+ const adapter$13 = {
453
+ name: "codex",
454
+ displayName: "Codex CLI",
455
+ category: "native",
456
+ docs: "https://github.com/rohitg00/agentmemory#codex-cli-codex-plugin-platform",
457
+ protocolNote: "→ Using MCP. Hooks ship via the Codex plugin; on Codex Desktop, also pass --with-hooks to install the global hooks.json workaround for openai/codex#16430.",
458
+ detect() {
459
+ return existsSync(CODEX_DIR);
460
+ },
461
+ async install(opts) {
462
+ const exists = existsSync(CODEX_TOML);
463
+ const current = exists ? readFileSync(CODEX_TOML, "utf-8") : "";
464
+ const wired = isWiredText(current);
465
+ if (wired && !opts.force) {
466
+ logAlreadyWired("Codex CLI", CODEX_TOML);
467
+ return {
468
+ kind: "already-wired",
469
+ mutatedPath: CODEX_TOML
470
+ };
471
+ }
472
+ if (opts.dryRun) {
473
+ p.log.info(`[dry-run] Would ${wired ? "rewrite" : "append"} [mcp_servers.agentmemory] in ${CODEX_TOML}`);
474
+ if (opts.withHooks) installCodexHooks(opts);
475
+ return {
476
+ kind: "installed",
477
+ mutatedPath: CODEX_TOML
478
+ };
479
+ }
480
+ let backupPath;
481
+ if (exists) {
482
+ backupPath = backupFile(CODEX_TOML, "codex", "toml");
483
+ logBackup(backupPath);
484
+ } else mkdirSync(dirname(CODEX_TOML), { recursive: true });
485
+ const cleaned = wired ? stripExistingBlock(current) : current;
486
+ writeFileSync(CODEX_TOML, `${cleaned}${cleaned.length === 0 || cleaned.endsWith("\n") ? "" : "\n"}${cleaned.length > 0 ? "\n" : ""}${TOML_BLOCK}`, "utf-8");
487
+ if (!isWiredText(readFileSync(CODEX_TOML, "utf-8"))) {
488
+ p.log.error(`Verification failed: ${CODEX_TOML} did not contain ${SECTION_HEADER} after write.`);
489
+ return {
490
+ kind: "skipped",
491
+ reason: "verification-failed"
492
+ };
493
+ }
494
+ logInstalled("Codex CLI", CODEX_TOML);
495
+ p.log.info("Codex picks up MCP servers on next launch. For the deeper plugin install, run: codex plugin marketplace add rohitg00/agentmemory && codex plugin add agentmemory@agentmemory");
496
+ if (opts.withHooks) {
497
+ const hookResult = installCodexHooks(opts);
498
+ if (hookResult.kind === "skipped") p.log.warn(`Codex hooks fallback skipped: ${hookResult.reason}. MCP wiring still applied.`);
499
+ }
500
+ return {
501
+ kind: "installed",
502
+ mutatedPath: CODEX_TOML,
503
+ ...backupPath !== void 0 && { backupPath }
504
+ };
505
+ }
506
+ };
507
+ /**
508
+ * Install the global `~/.codex/hooks.json` fallback. See
509
+ * `codex-hooks.ts` for context (openai/codex#16430). Returns a result
510
+ * describing the side effect for the caller's summary; failures here do
511
+ * not roll back the MCP wiring.
512
+ */
513
+ function installCodexHooks(opts) {
514
+ let pluginRoot;
515
+ try {
516
+ pluginRoot = findPluginRoot();
517
+ } catch (err) {
518
+ return {
519
+ kind: "skipped",
520
+ reason: err instanceof Error ? err.message : String(err)
521
+ };
522
+ }
523
+ const existing = readJsonSafe(CODEX_HOOKS);
524
+ const merged = buildMergedHooks(existing, pluginRoot);
525
+ if (opts.dryRun) {
526
+ p.log.info(`[dry-run] Would ${existing ? "merge" : "create"} ${CODEX_HOOKS} with ${Object.keys(merged.hooks).length} event(s)`);
527
+ return {
528
+ kind: "installed",
529
+ mutatedPath: CODEX_HOOKS
530
+ };
531
+ }
532
+ let backupPath;
533
+ if (existsSync(CODEX_HOOKS)) {
534
+ backupPath = backupFile(CODEX_HOOKS, "codex-hooks", "json");
535
+ logBackup(backupPath);
536
+ }
537
+ writeJsonAtomic(CODEX_HOOKS, merged);
538
+ logInstalled("Codex hooks (workaround for openai/codex#16430)", CODEX_HOOKS);
539
+ p.log.info("User-scope hooks reference absolute paths under the bundled plugin/ dir. Re-run `agentmemory connect codex --with-hooks` after upgrading agentmemory to refresh them.");
540
+ return {
541
+ kind: "installed",
542
+ mutatedPath: CODEX_HOOKS,
543
+ ...backupPath !== void 0 && { backupPath }
544
+ };
545
+ }
546
+ //#endregion
547
+ //#region src/cli/connect/continue.ts
548
+ const CONTINUE_DIR = join(homedir(), ".continue");
549
+ const YAML_PATH = join(CONTINUE_DIR, "config.yaml");
550
+ const JSON_PATH = join(CONTINUE_DIR, "config.json");
551
+ function buildEntry() {
552
+ return {
553
+ name: "agentmemory",
554
+ command: AGENTMEMORY_MCP_BLOCK.command,
555
+ args: [...AGENTMEMORY_MCP_BLOCK.args],
556
+ env: { ...AGENTMEMORY_MCP_BLOCK.env }
557
+ };
558
+ }
559
+ function entryIsAgentmemory(entry) {
560
+ if (!entry) return false;
561
+ return entry.name === "agentmemory" && entry.args.includes("@agentmemory/mcp");
562
+ }
563
+ function renderFreshYaml() {
564
+ const e = buildEntry();
565
+ const envLines = Object.entries(e.env ?? {}).map(([k, v]) => ` ${k}: "${v}"`).join("\n");
566
+ return [
567
+ "mcpServers:",
568
+ ` - name: ${e.name}`,
569
+ ` command: ${e.command}`,
570
+ " args:",
571
+ ...e.args.map((a) => ` - "${a}"`),
572
+ " env:",
573
+ envLines,
574
+ ""
575
+ ].join("\n");
576
+ }
577
+ const adapter$12 = {
578
+ name: "continue",
579
+ displayName: "Continue",
580
+ category: "mcp",
581
+ docs: "https://github.com/rohitg00/agentmemory#other-agents",
582
+ protocolNote: "→ Using MCP via ~/.continue/config.yaml (preferred) or config.json (legacy, only when no yaml).",
583
+ detect() {
584
+ return existsSync(CONTINUE_DIR);
585
+ },
586
+ async install(opts) {
587
+ const yamlExists = existsSync(YAML_PATH);
588
+ const jsonExists = existsSync(JSON_PATH);
589
+ if (yamlExists) {
590
+ const manual = `\nMerge this block into ~/.continue/config.yaml (the snippet already includes the top-level mcpServers key — if your config already has a mcpServers list, append the agentmemory entry to it instead of duplicating the key):\n\n${renderFreshYaml().split("\n").map((l) => l ? ` ${l}` : l).join("\n")}`;
591
+ p.log.info(`Continue: ${YAML_PATH} already exists. Manual edit needed.${manual}`);
592
+ return {
593
+ kind: "stub",
594
+ reason: "config.yaml-needs-manual-edit"
595
+ };
596
+ }
597
+ if (jsonExists) {
598
+ const existing = readJsonSafe(JSON_PATH);
599
+ const next = existing ? { ...existing } : {};
600
+ const servers = Array.isArray(next.mcpServers) ? [...next.mcpServers] : [];
601
+ const idx = servers.findIndex((s) => s?.name === "agentmemory");
602
+ const alreadyHas = idx >= 0 && entryIsAgentmemory(servers[idx]);
603
+ if (alreadyHas && !opts.force) {
604
+ logAlreadyWired("Continue", JSON_PATH);
605
+ return {
606
+ kind: "already-wired",
607
+ mutatedPath: JSON_PATH
608
+ };
609
+ }
610
+ if (opts.dryRun) {
611
+ p.log.info(`[dry-run] Would ${alreadyHas ? "overwrite" : "add"} mcpServers[agentmemory] in ${JSON_PATH}`);
612
+ return {
613
+ kind: "installed",
614
+ mutatedPath: JSON_PATH
615
+ };
616
+ }
617
+ const backupPath = backupFile(JSON_PATH, "continue");
618
+ logBackup(backupPath);
619
+ const entry = buildEntry();
620
+ if (idx >= 0) servers[idx] = entry;
621
+ else servers.push(entry);
622
+ next.mcpServers = servers;
623
+ writeJsonAtomic(JSON_PATH, next);
624
+ const verifyEntry = readJsonSafe(JSON_PATH)?.mcpServers?.find((s) => s?.name === "agentmemory");
625
+ if (!entryIsAgentmemory(verifyEntry)) {
626
+ p.log.error(`Verification failed: ${JSON_PATH} did not contain mcpServers[agentmemory] after write.`);
627
+ return {
628
+ kind: "skipped",
629
+ reason: "verification-failed"
630
+ };
631
+ }
632
+ logInstalled("Continue (legacy config.json)", JSON_PATH);
633
+ return {
634
+ kind: "installed",
635
+ mutatedPath: JSON_PATH,
636
+ backupPath
637
+ };
638
+ }
639
+ if (opts.dryRun) {
640
+ p.log.info(`[dry-run] Would create ${YAML_PATH} with agentmemory entry`);
641
+ return {
642
+ kind: "installed",
643
+ mutatedPath: YAML_PATH
644
+ };
645
+ }
646
+ mkdirSync(dirname(YAML_PATH), { recursive: true });
647
+ writeFileSync(YAML_PATH, renderFreshYaml(), "utf-8");
648
+ logInstalled("Continue", YAML_PATH);
649
+ return {
650
+ kind: "installed",
651
+ mutatedPath: YAML_PATH
652
+ };
653
+ }
654
+ };
655
+ //#endregion
656
+ //#region src/cli/connect/cursor.ts
657
+ const adapter$11 = createJsonMcpAdapter({
658
+ name: "cursor",
659
+ displayName: "Cursor",
660
+ detectDir: join(homedir(), ".cursor"),
661
+ configPath: join(homedir(), ".cursor", "mcp.json"),
662
+ docs: "https://github.com/rohitg00/agentmemory#other-agents",
663
+ protocolNote: "→ Using MCP (the only protocol Cursor speaks). Memory bridge runs at :3111 underneath."
664
+ });
665
+ //#endregion
666
+ //#region src/cli/connect/droid.ts
667
+ const adapter$10 = createJsonMcpAdapter({
668
+ name: "droid",
669
+ displayName: "Droid (Factory.ai)",
670
+ detectDir: join(homedir(), ".factory"),
671
+ configPath: join(homedir(), ".factory", "mcp.json"),
672
+ docs: "https://github.com/rohitg00/agentmemory#other-agents",
673
+ protocolNote: "→ Using MCP via ~/.factory/mcp.json. The `/mcp` slash command inside droid lists configured servers.",
674
+ extraEntryFields: { type: "stdio" }
675
+ });
676
+ //#endregion
677
+ //#region src/cli/connect/gemini-cli.ts
678
+ const adapter$9 = createJsonMcpAdapter({
679
+ name: "gemini-cli",
680
+ displayName: "Gemini CLI",
681
+ detectDir: join(homedir(), ".gemini"),
682
+ configPath: join(homedir(), ".gemini", "settings.json"),
683
+ docs: "https://github.com/rohitg00/agentmemory#other-agents",
684
+ protocolNote: "→ Using MCP (the only protocol Gemini CLI speaks). Memory bridge runs at :3111 underneath."
685
+ });
686
+ //#endregion
687
+ //#region src/cli/connect/hermes.ts
688
+ const HERMES_DIR = join(homedir(), ".hermes");
689
+ const HERMES_CONFIG = join(HERMES_DIR, "config.yaml");
690
+ const DOCS$2 = "https://github.com/rohitg00/agentmemory/tree/main/integrations/hermes";
691
+ const adapter$8 = {
692
+ name: "hermes",
693
+ displayName: "Hermes Agent",
694
+ category: "native",
695
+ docs: DOCS$2,
696
+ protocolNote: "→ Using MCP. Hooks are also available — see https://github.com/rohitg00/agentmemory/tree/main/integrations/hermes.",
697
+ detect() {
698
+ return existsSync(HERMES_DIR);
699
+ },
700
+ async install(_opts) {
701
+ p.log.warn("Hermes uses YAML config. Automated merge isn't implemented yet — manual install required.");
702
+ p.note([
703
+ `Add to ${HERMES_CONFIG}:`,
704
+ "",
705
+ " mcp_servers:",
706
+ " agentmemory:",
707
+ " command: npx",
708
+ " args: [\"-y\", \"@agentmemory/mcp\"]",
709
+ "",
710
+ " memory:",
711
+ " provider: agentmemory",
712
+ "",
713
+ `Full guide: ${DOCS$2}`
714
+ ].join("\n"), "Hermes manual install");
715
+ return {
716
+ kind: "stub",
717
+ reason: "yaml-merge-not-implemented"
718
+ };
719
+ }
720
+ };
721
+ //#endregion
722
+ //#region src/cli/connect/kiro.ts
723
+ const adapter$7 = createJsonMcpAdapter({
724
+ name: "kiro",
725
+ displayName: "Kiro",
726
+ detectDir: join(homedir(), ".kiro"),
727
+ configPath: join(homedir(), ".kiro", "settings", "mcp.json"),
728
+ docs: "https://github.com/rohitg00/agentmemory#other-agents",
729
+ protocolNote: "→ Using MCP via ~/.kiro/settings/mcp.json (user-level). Workspace overrides live in .kiro/settings/mcp.json."
730
+ });
731
+ //#endregion
732
+ //#region src/cli/connect/openclaw.ts
733
+ const adapter$6 = createJsonMcpAdapter({
734
+ name: "openclaw",
735
+ displayName: "OpenClaw",
736
+ category: "native",
737
+ detectDir: join(homedir(), ".openclaw"),
738
+ configPath: join(homedir(), ".openclaw", "openclaw.json"),
739
+ docs: "https://github.com/rohitg00/agentmemory/tree/main/integrations/openclaw",
740
+ protocolNote: "→ Using MCP. Hooks are also available — see https://github.com/rohitg00/agentmemory/tree/main/integrations/openclaw."
741
+ });
742
+ //#endregion
743
+ //#region src/cli/connect/opencode.ts
744
+ const CONFIG_PATH = join(homedir(), ".config", "opencode", "opencode.json");
745
+ const DETECT_DIR = join(homedir(), ".config", "opencode");
746
+ const OPENCODE_ENTRY = {
747
+ type: "local",
748
+ command: [
749
+ "npx",
750
+ "-y",
751
+ "@agentmemory/mcp"
752
+ ],
753
+ enabled: true
754
+ };
755
+ function entryMatches(entry) {
756
+ if (!entry || typeof entry !== "object") return false;
757
+ const command = entry["command"];
758
+ return Array.isArray(command) && command.includes("@agentmemory/mcp");
759
+ }
760
+ const adapter$5 = {
761
+ name: "opencode",
762
+ displayName: "OpenCode",
763
+ category: "mcp",
764
+ docs: "https://github.com/rohitg00/agentmemory#other-agents",
765
+ protocolNote: "Using MCP via ~/.config/opencode/opencode.json (top-level `mcp` key). For full auto-capture, also install the bundled plugin in plugin/opencode/.",
766
+ detect() {
767
+ return existsSync(DETECT_DIR);
768
+ },
769
+ async install(opts) {
770
+ const existing = readJsonSafe(CONFIG_PATH);
771
+ const next = existing ? { ...existing } : {};
772
+ const existingMcp = next["mcp"];
773
+ const mcp = existingMcp && typeof existingMcp === "object" && !Array.isArray(existingMcp) ? { ...existingMcp } : {};
774
+ const alreadyHas = entryMatches(mcp["agentmemory"]);
775
+ if (alreadyHas && !opts.force) {
776
+ logAlreadyWired(this.displayName, CONFIG_PATH);
777
+ return {
778
+ kind: "already-wired",
779
+ mutatedPath: CONFIG_PATH
780
+ };
781
+ }
782
+ if (opts.dryRun) {
783
+ p.log.info(`[dry-run] Would ${alreadyHas ? "overwrite" : "add"} mcp.agentmemory in ${CONFIG_PATH}`);
784
+ return {
785
+ kind: "installed",
786
+ mutatedPath: CONFIG_PATH
787
+ };
788
+ }
789
+ let backupPath;
790
+ if (existsSync(CONFIG_PATH)) {
791
+ backupPath = backupFile(CONFIG_PATH, this.name);
792
+ logBackup(backupPath);
793
+ } else mkdirSync(dirname(CONFIG_PATH), { recursive: true });
794
+ mcp["agentmemory"] = { ...OPENCODE_ENTRY };
795
+ next["mcp"] = mcp;
796
+ writeJsonAtomic(CONFIG_PATH, next);
797
+ const verifyMcp = readJsonSafe(CONFIG_PATH)?.["mcp"];
798
+ if (!entryMatches(verifyMcp?.["agentmemory"])) {
799
+ p.log.error(`Verification failed: ${CONFIG_PATH} did not contain mcp.agentmemory after write.`);
800
+ return {
801
+ kind: "skipped",
802
+ reason: "verification-failed"
803
+ };
804
+ }
805
+ logInstalled(this.displayName, CONFIG_PATH);
806
+ return {
807
+ kind: "installed",
808
+ mutatedPath: CONFIG_PATH,
809
+ ...backupPath !== void 0 && { backupPath }
810
+ };
811
+ }
812
+ };
813
+ //#endregion
814
+ //#region src/cli/connect/openhuman.ts
815
+ const OPENHUMAN_DIR = join(homedir(), ".openhuman");
816
+ const DOCS$1 = "https://github.com/tinyhumansai/openhuman";
817
+ const adapter$4 = {
818
+ name: "openhuman",
819
+ displayName: "OpenHuman",
820
+ category: "native",
821
+ docs: DOCS$1,
822
+ protocolNote: "→ Using native hooks (REST API at :3111). MCP not required.",
823
+ detect() {
824
+ return existsSync(OPENHUMAN_DIR);
825
+ },
826
+ async install(_opts) {
827
+ p.log.warn("OpenHuman integration is not yet automated. No `integrations/openhuman/` folder exists in the agentmemory repo today.");
828
+ p.note([
829
+ "OpenHuman is a Memory-trait host. The expected wiring is the REST",
830
+ "proxy at http://localhost:3111 plus an OpenHuman-side Memory trait",
831
+ "impl. Once integrations/openhuman/ lands in agentmemory we'll wire",
832
+ "this up automatically.",
833
+ "",
834
+ `Tracking: ${DOCS$1}`
835
+ ].join("\n"), "OpenHuman manual install");
836
+ return {
837
+ kind: "stub",
838
+ reason: "no-integration-folder-yet"
839
+ };
840
+ }
841
+ };
842
+ //#endregion
843
+ //#region src/cli/connect/pi.ts
844
+ const PI_DIR = join(homedir(), ".pi");
845
+ const PI_EXT_DIR = join(PI_DIR, "agent", "extensions", "agentmemory");
846
+ const DOCS = "https://github.com/rohitg00/agentmemory/tree/main/integrations/pi";
847
+ const adapter$3 = {
848
+ name: "pi",
849
+ displayName: "pi",
850
+ category: "native",
851
+ docs: DOCS,
852
+ protocolNote: "→ Using native hooks (REST API at :3111). MCP not required.",
853
+ detect() {
854
+ return existsSync(PI_DIR);
855
+ },
856
+ async install(_opts) {
857
+ p.log.warn("pi uses a TypeScript extension file. Automated copy + register isn't implemented yet — manual install required.");
858
+ p.note([
859
+ "Run these from the agentmemory repo root:",
860
+ "",
861
+ ` mkdir -p ${PI_EXT_DIR}`,
862
+ ` cp integrations/pi/index.ts ${PI_EXT_DIR}/index.ts`,
863
+ ` cp integrations/pi/security.ts ${PI_EXT_DIR}/security.ts`,
864
+ "",
865
+ "Then add to ~/.pi/agent/settings.json:",
866
+ " { \"extensions\": [\"~/.pi/agent/extensions/agentmemory\"] }",
867
+ "",
868
+ `Full guide: ${DOCS}`
869
+ ].join("\n"), "pi manual install");
870
+ return {
871
+ kind: "stub",
872
+ reason: "ts-extension-copy-not-implemented"
873
+ };
874
+ }
875
+ };
876
+ //#endregion
877
+ //#region src/cli/connect/qwen.ts
878
+ const adapter$2 = createJsonMcpAdapter({
879
+ name: "qwen",
880
+ displayName: "Qwen Code",
881
+ detectDir: join(homedir(), ".qwen"),
882
+ configPath: join(homedir(), ".qwen", "settings.json"),
883
+ docs: "https://github.com/rohitg00/agentmemory#other-agents",
884
+ protocolNote: "→ Using MCP via ~/.qwen/settings.json. Qwen Code's hook system can also be wired separately — see docs."
885
+ });
886
+ //#endregion
887
+ //#region src/cli/connect/warp.ts
888
+ const adapter$1 = createJsonMcpAdapter({
889
+ name: "warp",
890
+ displayName: "Warp",
891
+ detectDir: join(homedir(), ".warp"),
892
+ configPath: join(homedir(), ".warp", ".mcp.json"),
893
+ docs: "https://github.com/rohitg00/agentmemory#other-agents",
894
+ protocolNote: "→ Using MCP via ~/.warp/.mcp.json. Skills auto-discover from .claude/skills/ if the Claude Code plugin is also installed."
895
+ });
896
+ //#endregion
897
+ //#region src/cli/connect/zed.ts
898
+ const zedConfigDir = join(homedir(), ".config", "zed");
899
+ const adapter = createJsonMcpAdapter({
900
+ name: "zed",
901
+ displayName: "Zed",
902
+ detectDir: zedConfigDir,
903
+ configPath: join(zedConfigDir, "settings.json"),
904
+ wrapperKey: "context_servers",
905
+ docs: "https://github.com/rohitg00/agentmemory#other-agents",
906
+ protocolNote: "→ Using MCP via ~/.config/zed/settings.json (key: context_servers)."
907
+ });
908
+ //#endregion
909
+ //#region src/cli/connect/index.ts
910
+ var connect_exports = /* @__PURE__ */ __exportAll({
911
+ ADAPTERS: () => ADAPTERS,
912
+ knownAgents: () => knownAgents,
913
+ resolveAdapter: () => resolveAdapter,
914
+ runAdapter: () => runAdapter,
915
+ runConnect: () => runConnect
916
+ });
917
+ const ADAPTERS = [
918
+ adapter$16,
919
+ adapter$14,
920
+ adapter$13,
921
+ adapter$11,
922
+ adapter$9,
923
+ adapter$2,
924
+ adapter$17,
925
+ adapter$7,
926
+ adapter$1,
927
+ adapter$15,
928
+ adapter$12,
929
+ adapter,
930
+ adapter$10,
931
+ adapter$5,
932
+ adapter$6,
933
+ adapter$8,
934
+ adapter$3,
935
+ adapter$4
936
+ ];
937
+ function resolveAdapter(name) {
938
+ const lower = name.toLowerCase();
939
+ return ADAPTERS.find((a) => a.name === lower) ?? null;
940
+ }
941
+ function knownAgents() {
942
+ return ADAPTERS.map((a) => a.name);
943
+ }
944
+ function parseFlags(args) {
945
+ const positional = [];
946
+ let dryRun = false;
947
+ let force = false;
948
+ let all = false;
949
+ let withHooks = false;
950
+ for (const a of args) if (a === "--dry-run") dryRun = true;
951
+ else if (a === "--force") force = true;
952
+ else if (a === "--all") all = true;
953
+ else if (a === "--with-hooks") withHooks = true;
954
+ else if (!a.startsWith("-")) positional.push(a);
955
+ return {
956
+ dryRun,
957
+ force,
958
+ all,
959
+ withHooks,
960
+ positional
961
+ };
962
+ }
963
+ async function runAdapter(adapter, opts) {
964
+ if (!adapter.detect()) {
965
+ p.log.warn(`${adapter.displayName}: not detected on this machine (skipping).${adapter.docs ? ` Docs: ${adapter.docs}` : ""}`);
966
+ return {
967
+ kind: "skipped",
968
+ reason: "not-detected"
969
+ };
970
+ }
971
+ p.log.step(`Wiring ${adapter.displayName}…`);
972
+ if (adapter.protocolNote) p.log.message(adapter.protocolNote);
973
+ try {
974
+ return await adapter.install(opts);
975
+ } catch (err) {
976
+ p.log.error(`${adapter.displayName}: ${err instanceof Error ? err.message : String(err)}`);
977
+ return {
978
+ kind: "skipped",
979
+ reason: "exception"
980
+ };
981
+ }
982
+ }
983
+ async function runConnect(args) {
984
+ const { dryRun, force, all, withHooks, positional } = parseFlags(args);
985
+ const allowWindowsAdapter = positional.length === 1 && positional[0]?.toLowerCase() === "copilot-cli";
986
+ if (platform() === "win32" && !allowWindowsAdapter) {
987
+ p.intro("agentmemory connect");
988
+ p.log.warn("Windows: automated `connect` is not supported yet. See https://github.com/rohitg00/agentmemory#other-agents for manual install steps.");
989
+ p.outro("Windows: manual install required — see docs");
990
+ return;
991
+ }
992
+ const opts = {
993
+ dryRun,
994
+ force,
995
+ withHooks
996
+ };
997
+ p.intro("agentmemory connect");
998
+ if (positional.length === 0 && !all) {
999
+ const detected = ADAPTERS.filter((a) => a.detect());
1000
+ if (detected.length === 0) {
1001
+ p.log.error("No supported agents detected on this machine.");
1002
+ p.outro(`Supported: ${knownAgents().join(", ")}`);
1003
+ process.exit(1);
1004
+ }
1005
+ const picked = await p.multiselect({
1006
+ message: "Wire agentmemory into which agents?",
1007
+ options: detected.map((a) => ({
1008
+ value: a.name,
1009
+ label: a.displayName
1010
+ })),
1011
+ required: true
1012
+ });
1013
+ if (p.isCancel(picked)) {
1014
+ p.cancel("Cancelled.");
1015
+ return;
1016
+ }
1017
+ const results = [];
1018
+ for (const name of picked) {
1019
+ const adapter = resolveAdapter(name);
1020
+ if (!adapter) continue;
1021
+ results.push({
1022
+ name,
1023
+ result: await runAdapter(adapter, opts)
1024
+ });
1025
+ }
1026
+ summarize(results);
1027
+ return;
1028
+ }
1029
+ if (all) {
1030
+ const detected = ADAPTERS.filter((a) => a.detect());
1031
+ if (detected.length === 0) {
1032
+ p.log.error("No supported agents detected on this machine.");
1033
+ process.exit(1);
1034
+ }
1035
+ const results = [];
1036
+ for (const adapter of detected) results.push({
1037
+ name: adapter.name,
1038
+ result: await runAdapter(adapter, opts)
1039
+ });
1040
+ summarize(results);
1041
+ return;
1042
+ }
1043
+ const agentName = positional[0];
1044
+ const adapter = resolveAdapter(agentName);
1045
+ if (!adapter) {
1046
+ p.log.error(`Unknown agent: ${agentName}`);
1047
+ p.outro(`Supported: ${knownAgents().join(", ")}`);
1048
+ process.exit(1);
1049
+ }
1050
+ const result = await runAdapter(adapter, opts);
1051
+ summarize([{
1052
+ name: agentName,
1053
+ result
1054
+ }]);
1055
+ if (result.kind === "skipped" && result.reason !== "not-detected") process.exit(1);
1056
+ }
1057
+ function summarize(results) {
1058
+ const lines = results.map(({ name, result }) => {
1059
+ switch (result.kind) {
1060
+ case "installed": return ` ${pc.green("✓")} ${pc.bold(name)}${result.mutatedPath ? ` ${pc.dim("→")} ${pc.cyan(result.mutatedPath)}` : ""}`;
1061
+ case "already-wired": return ` ${pc.green("✓")} ${pc.bold(name)} ${pc.dim("(already wired)")}`;
1062
+ case "stub": return ` ${pc.yellow("⚠")} ${pc.bold(name)} ${pc.yellow(`(manual install required: ${result.reason})`)}`;
1063
+ case "skipped": return ` ${pc.red("✗")} ${pc.bold(name)} ${pc.dim(`(skipped: ${result.reason})`)}`;
1064
+ }
1065
+ });
1066
+ p.note(lines.join("\n"), "summary");
1067
+ const stubs = results.filter((r) => r.result.kind === "stub");
1068
+ if (stubs.length > 0) p.log.info(`${stubs.length} agent(s) require manual install — see docs links above.`);
1069
+ if (results.some((r) => r.result.kind === "installed" || r.result.kind === "already-wired")) p.log.info("Next: install agentmemory's 15 skills into the same agent(s) so they know when to call the tools:\n npx skills add rohitg00/agentmemory -y");
1070
+ p.outro("Restart any wired agent (or open a new session) to pick up agentmemory.");
1071
+ }
1072
+ //#endregion
1073
+ export { runAdapter as a, resolveAdapter as i, connect_exports as n, knownAgents as r, ADAPTERS as t };
1074
+
1075
+ //# sourceMappingURL=connect-JnsJXc68.mjs.map