@agentmemory/agentmemory 0.9.21 → 0.9.23

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