@agentmemory/agentmemory 0.9.28 → 0.9.30

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 (158) hide show
  1. package/.env.example +98 -28
  2. package/AGENTS.md +19 -26
  3. package/README.md +619 -274
  4. package/dist/.env.example +98 -28
  5. package/dist/cli.d.mts.map +1 -1
  6. package/dist/cli.mjs +1328 -244
  7. package/dist/cli.mjs.map +1 -1
  8. package/dist/{connect-JnsJXc68.mjs → connect-B4_ca6BD.mjs} +619 -70
  9. package/dist/connect-B4_ca6BD.mjs.map +1 -0
  10. package/dist/docker-compose.yml +42 -16
  11. package/dist/hooks/_capture.d.mts +22 -0
  12. package/dist/hooks/_capture.d.mts.map +1 -0
  13. package/dist/hooks/_capture.mjs +908 -0
  14. package/dist/hooks/_capture.mjs.map +1 -0
  15. package/dist/hooks/antigravity-bridge.d.mts +8 -0
  16. package/dist/hooks/antigravity-bridge.d.mts.map +1 -0
  17. package/dist/hooks/antigravity-bridge.mjs +123 -0
  18. package/dist/hooks/antigravity-bridge.mjs.map +1 -0
  19. package/dist/hooks/notification.mjs +34 -27
  20. package/dist/hooks/notification.mjs.map +1 -1
  21. package/dist/hooks/post-commit.mjs +84 -2
  22. package/dist/hooks/post-commit.mjs.map +1 -1
  23. package/dist/hooks/post-tool-failure.mjs +71 -26
  24. package/dist/hooks/post-tool-failure.mjs.map +1 -1
  25. package/dist/hooks/post-tool-use.mjs +99 -36
  26. package/dist/hooks/post-tool-use.mjs.map +1 -1
  27. package/dist/hooks/pre-compact.mjs +95 -5
  28. package/dist/hooks/pre-compact.mjs.map +1 -1
  29. package/dist/hooks/pre-tool-use.mjs +72 -2
  30. package/dist/hooks/pre-tool-use.mjs.map +1 -1
  31. package/dist/hooks/prompt-submit.mjs +25 -22
  32. package/dist/hooks/prompt-submit.mjs.map +1 -1
  33. package/dist/hooks/session-end.mjs +93 -24
  34. package/dist/hooks/session-end.mjs.map +1 -1
  35. package/dist/hooks/session-start.mjs +101 -6
  36. package/dist/hooks/session-start.mjs.map +1 -1
  37. package/dist/hooks/stop.mjs +72 -8
  38. package/dist/hooks/stop.mjs.map +1 -1
  39. package/dist/hooks/subagent-start.mjs +28 -26
  40. package/dist/hooks/subagent-start.mjs.map +1 -1
  41. package/dist/hooks/subagent-stop.mjs +29 -26
  42. package/dist/hooks/subagent-stop.mjs.map +1 -1
  43. package/dist/hooks/task-completed.mjs +31 -28
  44. package/dist/hooks/task-completed.mjs.map +1 -1
  45. package/dist/iii-config.docker.yaml +10 -10
  46. package/dist/iii-config.yaml +3 -1
  47. package/dist/{image-refs-BKLmp_sD.mjs → image-refs-BaT-9oMU.mjs} +2 -2
  48. package/dist/image-refs-BaT-9oMU.mjs.map +1 -0
  49. package/dist/{image-refs-C2YU7BIm.mjs → image-refs-T_urbwHM.mjs} +3 -3
  50. package/dist/image-refs-T_urbwHM.mjs.map +1 -0
  51. package/dist/{keyed-mutex-DTHtcZrt.mjs → image-store-BsN4vyjr.mjs} +2 -14
  52. package/dist/image-store-BsN4vyjr.mjs.map +1 -0
  53. package/dist/index.mjs +14021 -6494
  54. package/dist/index.mjs.map +1 -1
  55. package/dist/keyed-mutex-DchXsyfP.mjs +221 -0
  56. package/dist/keyed-mutex-DchXsyfP.mjs.map +1 -0
  57. package/dist/secret-store-BnY3A50C.mjs +2348 -0
  58. package/dist/secret-store-BnY3A50C.mjs.map +1 -0
  59. package/dist/{src-CzgoepGU.mjs → src-Jsq9LCeH.mjs} +7349 -2940
  60. package/dist/src-Jsq9LCeH.mjs.map +1 -0
  61. package/dist/{standalone-YsZFFQBM.mjs → standalone-DKCdrf1d.mjs} +62 -24
  62. package/dist/standalone-DKCdrf1d.mjs.map +1 -0
  63. package/dist/standalone.d.mts.map +1 -1
  64. package/dist/standalone.mjs +298 -27
  65. package/dist/standalone.mjs.map +1 -1
  66. package/dist/status-IRz7ta8-.mjs +2344 -0
  67. package/dist/status-IRz7ta8-.mjs.map +1 -0
  68. package/dist/viewer/favicon.svg +35 -1
  69. package/dist/viewer/index.html +7428 -2608
  70. package/docker-compose.yml +42 -16
  71. package/iii-config.docker.yaml +10 -10
  72. package/iii-config.yaml +3 -1
  73. package/integrations/pi/README.md +77 -0
  74. package/integrations/pi/index.ts +402 -0
  75. package/integrations/pi/package.json +32 -0
  76. package/integrations/pi/security.ts +87 -0
  77. package/package.json +15 -7
  78. package/plugin/.claude-plugin/plugin.json +2 -2
  79. package/plugin/.codex-plugin/plugin.json +26 -4
  80. package/plugin/.devin-plugin/plugin.json +32 -0
  81. package/plugin/.mcp.codex.json +12 -0
  82. package/plugin/.mcp.copilot.json +2 -7
  83. package/plugin/.mcp.json +2 -7
  84. package/plugin/assets/icon.svg +35 -0
  85. package/plugin/cursor/hooks.json +41 -0
  86. package/plugin/cursor/mcp.json +12 -0
  87. package/plugin/hooks/hooks.antigravity.json +43 -0
  88. package/plugin/hooks/hooks.copilot.json +11 -11
  89. package/plugin/hooks/hooks.devin.json +67 -0
  90. package/plugin/hooks/hooks.droid.json +55 -0
  91. package/plugin/opencode/README.md +267 -31
  92. package/plugin/opencode/agentmemory-capture.ts +644 -15
  93. package/plugin/opencode/plugin.json +1 -1
  94. package/plugin/plugin.json +2 -2
  95. package/plugin/scripts/_capture.d.mts +22 -0
  96. package/plugin/scripts/_capture.d.mts.map +1 -0
  97. package/plugin/scripts/_capture.mjs +908 -0
  98. package/plugin/scripts/_capture.mjs.map +1 -0
  99. package/plugin/scripts/antigravity-bridge.d.mts +8 -0
  100. package/plugin/scripts/antigravity-bridge.d.mts.map +1 -0
  101. package/plugin/scripts/antigravity-bridge.mjs +123 -0
  102. package/plugin/scripts/antigravity-bridge.mjs.map +1 -0
  103. package/plugin/scripts/notification.mjs +34 -27
  104. package/plugin/scripts/notification.mjs.map +1 -1
  105. package/plugin/scripts/plugin-bridge.mjs +378 -0
  106. package/plugin/scripts/post-commit.mjs +84 -2
  107. package/plugin/scripts/post-commit.mjs.map +1 -1
  108. package/plugin/scripts/post-tool-failure.mjs +71 -26
  109. package/plugin/scripts/post-tool-failure.mjs.map +1 -1
  110. package/plugin/scripts/post-tool-use.mjs +99 -36
  111. package/plugin/scripts/post-tool-use.mjs.map +1 -1
  112. package/plugin/scripts/pre-compact.mjs +95 -5
  113. package/plugin/scripts/pre-compact.mjs.map +1 -1
  114. package/plugin/scripts/pre-tool-use.mjs +72 -2
  115. package/plugin/scripts/pre-tool-use.mjs.map +1 -1
  116. package/plugin/scripts/prompt-submit.mjs +25 -22
  117. package/plugin/scripts/prompt-submit.mjs.map +1 -1
  118. package/plugin/scripts/session-end.mjs +93 -24
  119. package/plugin/scripts/session-end.mjs.map +1 -1
  120. package/plugin/scripts/session-start.mjs +101 -6
  121. package/plugin/scripts/session-start.mjs.map +1 -1
  122. package/plugin/scripts/stop.mjs +72 -8
  123. package/plugin/scripts/stop.mjs.map +1 -1
  124. package/plugin/scripts/subagent-start.mjs +28 -26
  125. package/plugin/scripts/subagent-start.mjs.map +1 -1
  126. package/plugin/scripts/subagent-stop.mjs +29 -26
  127. package/plugin/scripts/subagent-stop.mjs.map +1 -1
  128. package/plugin/scripts/task-completed.mjs +31 -28
  129. package/plugin/scripts/task-completed.mjs.map +1 -1
  130. package/plugin/skills/_shared/TROUBLESHOOTING.md +22 -6
  131. package/plugin/skills/agentmemory-agents/REFERENCE.md +8 -5
  132. package/plugin/skills/agentmemory-config/REFERENCE.md +52 -1
  133. package/plugin/skills/agentmemory-config/SKILL.md +44 -7
  134. package/plugin/skills/agentmemory-mcp-tools/REFERENCE.md +4 -3
  135. package/plugin/skills/agentmemory-rest-api/REFERENCE.md +23 -2
  136. package/plugin/skills/forget/SKILL.md +4 -1
  137. package/plugin/skills/handoff/SKILL.md +4 -2
  138. package/plugin/skills/lesson/SKILL.md +64 -0
  139. package/plugin/skills/memory-discipline/SKILL.md +65 -0
  140. package/plugin/skills/recall/SKILL.md +4 -1
  141. package/plugin/skills/remember/SKILL.md +6 -1
  142. package/dist/config-ChC9EtgV.mjs +0 -259
  143. package/dist/config-ChC9EtgV.mjs.map +0 -1
  144. package/dist/connect-JnsJXc68.mjs.map +0 -1
  145. package/dist/image-refs-BKLmp_sD.mjs.map +0 -1
  146. package/dist/image-refs-C2YU7BIm.mjs.map +0 -1
  147. package/dist/keyed-mutex-DTHtcZrt.mjs.map +0 -1
  148. package/dist/logger-BEB7pCI9.mjs +0 -43
  149. package/dist/logger-BEB7pCI9.mjs.map +0 -1
  150. package/dist/schema-CNiCWzV9.mjs +0 -78
  151. package/dist/schema-CNiCWzV9.mjs.map +0 -1
  152. package/dist/src-CzgoepGU.mjs.map +0 -1
  153. package/dist/standalone-YsZFFQBM.mjs.map +0 -1
  154. package/dist/tools-registry-D3NEoe5m.mjs +0 -1115
  155. package/dist/tools-registry-D3NEoe5m.mjs.map +0 -1
  156. package/plugin/scripts/diagnostics.d.mts +0 -17
  157. package/plugin/scripts/diagnostics.d.mts.map +0 -1
  158. package/plugin/scripts/diagnostics.mjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connect-B4_ca6BD.mjs","names":["entryMatches","normalizePathForCommandMatch","CUSTOMIZATION_DIR","adapter","adapter","entryMatches","adapter","adapter","entryMatches","adapter","adapter","adapter","adapter","adapter","adapter","adapter","adapter","DOCS","adapter","adapter","adapter","adapter","DOCS","adapter","adapter","adapter","adapter","claudeCode","copilotCli","codex","cursor","devin","geminiCli","qwen","antigravity","antigravityCli","kiro","warp","cline","continueDev","zed","droid","dsh","opencode","openclaw","hermes","pi","openhuman"],"sources":["../src/cli/connect/guidelines.ts","../src/cli/connect/util.ts","../src/cli/connect/json-mcp-adapter.ts","../src/cli/connect/antigravity-hooks.ts","../src/cli/connect/codex-hooks.ts","../src/cli/connect/antigravity-cli.ts","../src/cli/connect/antigravity.ts","../src/cli/connect/claude-code.ts","../src/cli/connect/cline.ts","../src/cli/connect/copilot-cli.ts","../src/cli/connect/codex.ts","../src/cli/connect/continue.ts","../src/cli/connect/cursor.ts","../src/cli/connect/devin.ts","../src/cli/connect/droid.ts","../src/cli/connect/dsh.ts","../src/cli/connect/gemini-cli.ts","../src/cli/connect/hermes.ts","../src/cli/connect/kiro.ts","../src/cli/connect/openclaw.ts","../src/cli/connect/opencode.ts","../src/cli/connect/openhuman.ts","../src/cli/connect/pi.ts","../src/cli/connect/qwen.ts","../src/cli/connect/warp.ts","../src/cli/connect/zed.ts","../src/cli/connect/index.ts"],"sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\n// Activating memory for agents that have no auto-capture hooks: write a short\n// \"use the memory tools\" guideline into each agent's native rules mechanism so\n// the agent proactively calls memory_recall / memory_save. Paths + formats are\n// verified against each agent's OFFICIAL docs (cited per entry below). Claude\n// Code / Codex are omitted here: they already auto-capture via lifecycle hooks.\n\nconst START = \"<!-- agentmemory:start -->\";\nconst END = \"<!-- agentmemory:end -->\";\n\nconst GUIDELINE_BODY = `## Agent memory (agentmemory)\n\nYou have persistent long-term memory via the agentmemory MCP server. Tools: \\`memory_recall\\`, \\`memory_smart_search\\`, \\`memory_save\\`, \\`memory_sessions\\`.\n\n- At the START of a task, call \\`memory_recall\\` (or \\`memory_smart_search\\`) with the task context to load relevant past decisions, fixes, and preferences before asking the user to repeat anything.\n- When you learn something durable (a decision, a fix, a gotcha, a user preference, a project convention), call \\`memory_save\\` to persist it.\n- Prefer recalling over re-deriving, and save concise reusable facts rather than transcripts.`;\n\n// \"block\" -> upsert a marked block inside a shared instructions file\n// \"mdc\" -> Cursor project rule: dedicated .mdc with alwaysApply frontmatter\n// \"steering\" -> Kiro steering file: dedicated .md with inclusion:always frontmatter\n// \"rule\" -> dedicated always-on markdown rule file (own file, safe to own)\ntype GuidelineFormat = \"block\" | \"mdc\" | \"steering\" | \"rule\";\n\ntype GuidelineTarget = {\n // Preferred user-global rules file (absolute). Omitted when the agent has no\n // clean global rules FILE (UI-only or project-scoped), forcing the project\n // fallback. Global is preferred so memory activates across all repos.\n globalPath?: string;\n // Project fallback, relative to cwd.\n projectPath: string;\n format: GuidelineFormat;\n scope: \"global\" | \"project\";\n source: string; // official doc URL the path/format was verified against\n};\n\nexport function guidelineTargets(\n home: string = homedir(),\n): Record<string, GuidelineTarget> {\n return {\n // No global rules FILE (User Rules are UI-only) -> project .cursor/rules/*.mdc\n cursor: {\n projectPath: join(\".cursor\", \"rules\", \"agentmemory.mdc\"),\n format: \"mdc\",\n scope: \"project\",\n source: \"https://cursor.com/docs/rules\",\n },\n // Cline's global rules dir is a non-standard ~/Documents path; the dedicated\n // project rule (no frontmatter = always active) is the verified stable form.\n cline: {\n projectPath: join(\".clinerules\", \"agentmemory.md\"),\n format: \"rule\",\n scope: \"project\",\n source: \"https://docs.cline.bot/customization/cline-rules\",\n },\n // Continue does not auto-read AGENTS.md; rules live in .continue/rules/*.md.\n continue: {\n projectPath: join(\".continue\", \"rules\", \"00-agentmemory.md\"),\n format: \"rule\",\n scope: \"project\",\n source: \"https://docs.continue.dev/customize/deep-dives/rules\",\n },\n zed: {\n globalPath: join(home, \".config\", \"zed\", \"AGENTS.md\"),\n projectPath: \"AGENTS.md\",\n format: \"block\",\n scope: \"global\",\n source: \"https://zed.dev/docs/ai/instructions\",\n },\n // Warp global Rules are UI-managed (no file path) -> project AGENTS.md.\n warp: {\n projectPath: \"AGENTS.md\",\n format: \"block\",\n scope: \"project\",\n source: \"https://docs.warp.dev/agent-platform/capabilities/rules\",\n },\n kiro: {\n globalPath: join(home, \".kiro\", \"steering\", \"agentmemory.md\"),\n projectPath: join(\".kiro\", \"steering\", \"agentmemory.md\"),\n format: \"steering\",\n scope: \"global\",\n source: \"https://kiro.dev/docs/steering\",\n },\n \"gemini-cli\": {\n globalPath: join(home, \".gemini\", \"GEMINI.md\"),\n projectPath: \"GEMINI.md\",\n format: \"block\",\n scope: \"global\",\n source: \"https://github.com/google-gemini/gemini-cli/blob/main/docs/cli/gemini-md.md\",\n },\n qwen: {\n globalPath: join(home, \".qwen\", \"QWEN.md\"),\n projectPath: \"QWEN.md\",\n format: \"block\",\n scope: \"global\",\n source: \"https://github.com/QwenLM/qwen-code/blob/main/docs/users/features/memory.md\",\n },\n opencode: {\n globalPath: join(home, \".config\", \"opencode\", \"AGENTS.md\"),\n projectPath: \"AGENTS.md\",\n format: \"block\",\n scope: \"global\",\n source: \"https://opencode.ai/docs/rules\",\n },\n droid: {\n globalPath: join(home, \".factory\", \"AGENTS.md\"),\n projectPath: \"AGENTS.md\",\n format: \"block\",\n scope: \"global\",\n source: \"https://docs.factory.ai/cli/configuration/agents-md\",\n },\n // Antigravity does NOT read AGENTS.md; global rules live in ~/.gemini/GEMINI.md.\n antigravity: {\n globalPath: join(home, \".gemini\", \"GEMINI.md\"),\n projectPath: join(\".agents\", \"rules\", \"agentmemory.md\"),\n format: \"block\",\n scope: \"global\",\n source: \"https://antigravity.google/docs/rules-workflows\",\n },\n // The agy CLI reads the same ~/.gemini/GEMINI.md as the IDE.\n \"antigravity-cli\": {\n globalPath: join(home, \".gemini\", \"GEMINI.md\"),\n projectPath: join(\".agents\", \"rules\", \"agentmemory.md\"),\n format: \"block\",\n scope: \"global\",\n source: \"https://antigravity.google/docs/rules-workflows\",\n },\n \"copilot-cli\": {\n globalPath: join(home, \".copilot\", \"copilot-instructions.md\"),\n projectPath: join(\".github\", \"copilot-instructions.md\"),\n format: \"block\",\n scope: \"global\",\n source:\n \"https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/add-custom-instructions\",\n },\n };\n}\n\nfunction renderDedicated(format: GuidelineFormat): string {\n if (format === \"mdc\") {\n return `---\\ndescription: agentmemory long-term memory usage\\nalwaysApply: true\\n---\\n\\n${GUIDELINE_BODY}\\n`;\n }\n if (format === \"steering\") {\n return `---\\ninclusion: always\\n---\\n\\n${GUIDELINE_BODY}\\n`;\n }\n // plain dedicated rule (Cline / Continue)\n return `${GUIDELINE_BODY}\\n`;\n}\n\n// Insert or replace the marked block in a shared instructions file, preserving\n// any surrounding user content. Idempotent: re-running updates only our block.\nfunction upsertBlock(existing: string): string {\n const block = `${START}\\n${GUIDELINE_BODY}\\n${END}`;\n const startIdx = existing.indexOf(START);\n const endIdx = existing.indexOf(END);\n if (startIdx !== -1 && endIdx !== -1 && endIdx > startIdx) {\n return (\n existing.slice(0, startIdx) + block + existing.slice(endIdx + END.length)\n );\n }\n // Malformed marker state: a lone or reversed marker. Appending here would\n // let a later run pair the orphan marker with the appended block's twin and\n // cut the user's content between them. Leave the file untouched.\n if (startIdx !== -1 || endIdx !== -1) {\n return existing;\n }\n const sep = existing.length === 0 || existing.endsWith(\"\\n\") ? \"\" : \"\\n\";\n const lead = existing.length === 0 ? \"\" : \"\\n\";\n return `${existing}${sep}${lead}${block}\\n`;\n}\n\nexport type GuidelineResult =\n | { kind: \"written\"; path: string; scope: string; source: string }\n | { kind: \"unchanged\"; path: string; scope: string }\n | { kind: \"would-write\"; path: string; scope: string }\n | { kind: \"no-target\" };\n\nexport function writeGuideline(\n agentName: string,\n opts: { cwd: string; home?: string; dryRun?: boolean } = { cwd: process.cwd() },\n): GuidelineResult {\n const home = opts.home ?? homedir();\n const target = guidelineTargets(home)[agentName];\n if (!target) return { kind: \"no-target\" };\n\n const path = target.globalPath ?? join(opts.cwd, target.projectPath);\n const dedicated = target.format !== \"block\";\n\n const existing = existsSync(path) ? readFileSync(path, \"utf8\") : \"\";\n const next = dedicated ? renderDedicated(target.format) : upsertBlock(existing);\n\n if (existing === next) {\n return { kind: \"unchanged\", path, scope: target.scope };\n }\n if (opts.dryRun) {\n return { kind: \"would-write\", path, scope: target.scope };\n }\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, next, \"utf8\");\n return { kind: \"written\", path, scope: target.scope, source: target.source };\n}\n","import {\n existsSync,\n mkdirSync,\n readFileSync,\n writeFileSync,\n copyFileSync,\n renameSync,\n} from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport * as p from \"@clack/prompts\";\n\nexport const AGENTMEMORY_MCP_BLOCK = {\n command: \"npx\",\n args: [\"-y\", \"@agentmemory/mcp\"],\n env: {\n AGENTMEMORY_URL: \"${AGENTMEMORY_URL:-http://localhost:3111}\",\n AGENTMEMORY_SECRET: \"${AGENTMEMORY_SECRET:-}\",\n AGENTMEMORY_TOOLS: \"${AGENTMEMORY_TOOLS:-all}\",\n },\n};\n\nconst COPILOT_MCP_COMMAND =\n process.platform === \"win32\"\n ? {\n command: process.env[\"ComSpec\"] || process.env[\"COMSPEC\"] || \"cmd.exe\",\n args: [\"/d\", \"/s\", \"/c\", \"npx\", \"-y\", \"@agentmemory/mcp\"],\n }\n : {\n command: \"npx\",\n args: [\"-y\", \"@agentmemory/mcp\"],\n };\n\nexport const AGENTMEMORY_COPILOT_MCP_BLOCK = {\n type: \"local\" as const,\n ...COPILOT_MCP_COMMAND,\n env: {\n AGENTMEMORY_URL: \"${AGENTMEMORY_URL:-http://localhost:3111}\",\n AGENTMEMORY_SECRET: \"${AGENTMEMORY_SECRET:-}\",\n AGENTMEMORY_TOOLS: \"${AGENTMEMORY_TOOLS:-all}\",\n },\n tools: [\"*\"],\n};\n\nexport function backupsDir(): string {\n return join(homedir(), \".agentmemory\", \"backups\");\n}\n\nexport function ensureBackupsDir(): string {\n const dir = backupsDir();\n mkdirSync(dir, { recursive: true });\n return dir;\n}\n\nexport function timestampSlug(): string {\n return new Date().toISOString().replace(/[:.]/g, \"-\");\n}\n\nexport function backupFile(\n sourcePath: string,\n agent: string,\n ext = \"json\",\n): string {\n ensureBackupsDir();\n const stamp = timestampSlug();\n const target = join(backupsDir(), `${agent}-${stamp}.${ext}`);\n copyFileSync(sourcePath, target);\n return target;\n}\n\nexport function readJsonSafe<T = unknown>(path: string): T | null {\n if (!existsSync(path)) return null;\n try {\n return JSON.parse(readFileSync(path, \"utf-8\")) as T;\n } catch {\n return null;\n }\n}\n\nexport function writeJsonAtomic(path: string, value: unknown): void {\n writeTextAtomic(path, `${JSON.stringify(value, null, 2)}\\n`);\n}\n\nexport function writeTextAtomic(path: string, content: string): void {\n mkdirSync(dirname(path), { recursive: true });\n const tmp = `${path}.tmp-${process.pid}-${Date.now()}`;\n writeFileSync(tmp, content, \"utf-8\");\n renameSync(tmp, path);\n}\n\nexport function logInstalled(label: string, target: string): void {\n p.log.success(`${label} → wired into ${target}`);\n}\n\nexport function logAlreadyWired(label: string, target: string): void {\n p.log.info(`${label} already wired in ${target} (use --force to re-install)`);\n}\n\nexport function logBackup(target: string): void {\n p.log.info(`Backup: ${target}`);\n}\n","import { existsSync, mkdirSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\nimport * as p from \"@clack/prompts\";\nimport type { ConnectAdapter, ConnectOptions, ConnectResult } from \"./types.js\";\nimport {\n AGENTMEMORY_MCP_BLOCK,\n backupFile,\n logAlreadyWired,\n logBackup,\n logInstalled,\n readJsonSafe,\n writeJsonAtomic,\n} from \"./util.js\";\n\nexport type JsonMcpAdapterConfig = {\n name: string;\n displayName: string;\n detectDir: string;\n configPath: string;\n docs?: string;\n protocolNote?: string;\n // Integration style for onboarding grouping. Defaults to \"mcp\" since a\n // JSON MCP config writer is MCP-only by construction; hosts that also\n // ship hooks (e.g. OpenClaw) pass \"native\".\n category?: \"native\" | \"mcp\";\n // Wrapper key under which servers live. Default \"mcpServers\".\n // Zed uses \"context_servers\"; otherwise same shape.\n wrapperKey?: string;\n // Extra fields merged into the agentmemory entry. Droid requires\n // type: \"stdio\"; other hosts ignore unknown fields.\n extraEntryFields?: Record<string, unknown>;\n installHooks?: (opts: ConnectOptions) => ConnectResult;\n};\n\ntype McpEntry = typeof AGENTMEMORY_MCP_BLOCK;\ntype McpConfig = Record<string, unknown>;\n\nfunction entryMatches(entry: unknown): boolean {\n if (!entry || typeof entry !== \"object\") return false;\n const e = entry as Record<string, unknown>;\n if (e[\"command\"] !== \"npx\") return false;\n const args = Array.isArray(e[\"args\"]) ? (e[\"args\"] as string[]) : [];\n return args.includes(\"@agentmemory/mcp\");\n}\n\nexport function createJsonMcpAdapter(\n config: JsonMcpAdapterConfig,\n): ConnectAdapter {\n const wrapperKey = config.wrapperKey ?? \"mcpServers\";\n return {\n name: config.name,\n displayName: config.displayName,\n category: config.category ?? \"mcp\",\n ...(config.docs !== undefined && { docs: config.docs }),\n ...(config.protocolNote !== undefined && {\n protocolNote: config.protocolNote,\n }),\n\n detect(): boolean {\n return existsSync(config.detectDir);\n },\n\n async install(opts: ConnectOptions): Promise<ConnectResult> {\n const existing = readJsonSafe<McpConfig>(config.configPath);\n const next: McpConfig = existing ? { ...existing } : {};\n const servers: Record<string, McpEntry> = {\n ...((next[wrapperKey] as Record<string, McpEntry>) ?? {}),\n };\n\n const alreadyHas = entryMatches(servers[\"agentmemory\"]);\n if (alreadyHas && !opts.force) {\n logAlreadyWired(config.displayName, config.configPath);\n if (opts.withHooks && config.installHooks) {\n const hookResult = config.installHooks(opts);\n if (hookResult.kind === \"skipped\") {\n p.log.warn(\n `${config.displayName} hooks skipped: ${hookResult.reason}.`,\n );\n }\n }\n return { kind: \"already-wired\", mutatedPath: config.configPath };\n }\n\n if (opts.dryRun) {\n p.log.info(\n `[dry-run] Would ${alreadyHas ? \"overwrite\" : \"add\"} ${wrapperKey}.agentmemory in ${config.configPath}`,\n );\n if (opts.withHooks && config.installHooks) {\n const hookResult = config.installHooks(opts);\n if (hookResult.kind === \"skipped\") {\n p.log.warn(\n `${config.displayName} hooks skipped: ${hookResult.reason}.`,\n );\n }\n }\n return { kind: \"installed\", mutatedPath: config.configPath };\n }\n\n let backupPath: string | undefined;\n if (existsSync(config.configPath)) {\n backupPath = backupFile(config.configPath, config.name);\n logBackup(backupPath);\n } else {\n mkdirSync(dirname(config.configPath), { recursive: true });\n }\n\n servers[\"agentmemory\"] = {\n ...AGENTMEMORY_MCP_BLOCK,\n ...(config.extraEntryFields ?? {}),\n };\n next[wrapperKey] = servers;\n writeJsonAtomic(config.configPath, next);\n\n const verify = readJsonSafe<McpConfig>(config.configPath);\n const verifyServers = verify?.[wrapperKey] as\n | Record<string, McpEntry>\n | undefined;\n if (!entryMatches(verifyServers?.[\"agentmemory\"])) {\n p.log.error(\n `Verification failed: ${config.configPath} did not contain ${wrapperKey}.agentmemory after write.`,\n );\n return { kind: \"skipped\", reason: \"verification-failed\" };\n }\n\n logInstalled(config.displayName, config.configPath);\n\n if (opts.withHooks && config.installHooks) {\n const hookResult = config.installHooks(opts);\n if (hookResult.kind === \"skipped\") {\n p.log.warn(\n `${config.displayName} hooks skipped: ${hookResult.reason}. MCP wiring still applied.`,\n );\n }\n }\n\n return {\n kind: \"installed\",\n mutatedPath: config.configPath,\n ...(backupPath !== undefined && { backupPath }),\n };\n },\n };\n}\n","import { readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\n/**\n * Merge engine for Antigravity CLI's `hooks.json`.\n *\n * Antigravity does not use the `{ hooks: { <Event>: [...] } }` envelope\n * that `codex-hooks.ts` handles for Claude Code, Codex and Droid. Its file\n * is a map of *named* hook bundles at the root:\n *\n * {\n * \"<hook-name>\": {\n * \"enabled\": true,\n * \"PreToolUse\": [ { \"matcher\": \"…\", \"hooks\": [ { type, command, timeout } ] } ],\n * \"Stop\": [ { type, command, timeout } ]\n * }\n * }\n *\n * The two shapes are not a typo: tool events take the `{ matcher, hooks }`\n * wrapper, lifecycle events a flat handler list. Wrapping a lifecycle event\n * makes agy read the wrapper as a handler and reject the *whole file*\n * (`command hook must specify 'command'`), disabling every other bundle in\n * it too.\n *\n * Named bundles make the merge simpler than the Codex one: agentmemory owns\n * exactly the top-level keys whose commands point under\n * `<pluginRoot>/scripts/`, so a re-install drops those wholesale and re-adds\n * a fresh bundle, preserving user keys and their order.\n *\n * `${CLAUDE_PLUGIN_ROOT}` is resolved at install time — agy expands no env\n * vars and requires absolute paths. The resolved path must also be bare and\n * space-free: agy runs no shell and strips no quotes, so `node \"<root>/…\"`\n * looks for a module whose name starts with a quote, and a space truncates\n * the argument with no escaping form that works.\n *\n * Behaviour above verified against agy 1.0.15.\n * Source: antigravity.google/docs/hooks\n */\n\ntype HookHandler = { type: string; command: string; timeout?: number };\ntype HookEntry = { matcher?: string; hooks: HookHandler[] };\nexport type NamedHook = { enabled?: boolean } & Record<\n string,\n boolean | HookEntry[] | HookHandler[] | undefined\n>;\nexport type AntigravityHookManifest = Record<string, NamedHook>;\n\n/** Tool events: `[ { matcher, hooks: [...] } ]`. */\nconst TOOL_EVENT_KEYS = new Set([\"PreToolUse\", \"PostToolUse\"]);\n\n/** Lifecycle events: a flat `[ { type, command } ]` handler list. */\nconst LIFECYCLE_EVENT_KEYS = new Set([\n \"PreInvocation\",\n \"PostInvocation\",\n \"Stop\",\n]);\n\n/** Events Antigravity dispatches. Anything else in a bundle is metadata. */\nconst EVENT_KEYS = new Set([...TOOL_EVENT_KEYS, ...LIFECYCLE_EVENT_KEYS]);\n\nexport function buildMergedAntigravityHooks(\n existing: AntigravityHookManifest | null,\n pluginRoot: string,\n manifestFile = \"hooks.antigravity.json\",\n): AntigravityHookManifest {\n const ours = JSON.parse(\n readFileSync(join(pluginRoot, \"hooks\", manifestFile), \"utf-8\"),\n ) as AntigravityHookManifest;\n const scriptsDir = join(pluginRoot, \"scripts\");\n\n const out: AntigravityHookManifest = {};\n\n for (const [name, bundle] of Object.entries(existing ?? {})) {\n if (isAgentmemoryBundle(bundle, scriptsDir)) continue;\n out[name] = bundle;\n }\n\n for (const [name, bundle] of Object.entries(ours)) {\n out[name] = resolveBundle(bundle, pluginRoot);\n }\n\n return out;\n}\n\n/** True when `pluginRoot` cannot be expressed in an Antigravity `command`. */\nexport function containsSpaces(pluginRoot: string): boolean {\n return /\\s/.test(pluginRoot);\n}\n\n/**\n * Every handler in a bundle, across both event shapes: an entry that carries\n * no `hooks` array is itself the handler.\n */\nfunction allHandlers(bundle: NamedHook): HookHandler[] {\n const out: HookHandler[] = [];\n for (const [key, value] of Object.entries(bundle)) {\n if (!EVENT_KEYS.has(key) || !Array.isArray(value)) continue;\n for (const entry of value as (HookEntry | HookHandler)[]) {\n if (!entry || typeof entry !== \"object\") continue;\n const nested = (entry as HookEntry).hooks;\n if (Array.isArray(nested)) out.push(...nested);\n else out.push(entry as HookHandler);\n }\n }\n return out;\n}\n\nfunction isAgentmemoryBundle(bundle: unknown, scriptsDir: string): boolean {\n if (!bundle || typeof bundle !== \"object\" || Array.isArray(bundle)) {\n return false;\n }\n const normalizedScriptsDir = normalizePathForCommandMatch(scriptsDir);\n return allHandlers(bundle as NamedHook).some((handler) =>\n normalizePathForCommandMatch(handler?.command ?? \"\").includes(\n normalizedScriptsDir,\n ),\n );\n}\n\nfunction resolveBundle(bundle: NamedHook, pluginRoot: string): NamedHook {\n const out: NamedHook = {};\n for (const [key, value] of Object.entries(bundle)) {\n if (!EVENT_KEYS.has(key) || !Array.isArray(value)) {\n out[key] = value as boolean;\n continue;\n }\n if (LIFECYCLE_EVENT_KEYS.has(key)) {\n out[key] = (value as HookHandler[]).map((handler) =>\n resolveHandler(handler, pluginRoot),\n );\n continue;\n }\n out[key] = (value as HookEntry[]).map((entry) => {\n const next: HookEntry = {\n hooks: entry.hooks.map((handler) => resolveHandler(handler, pluginRoot)),\n };\n if (entry.matcher !== undefined) next.matcher = entry.matcher;\n return next;\n });\n }\n return out;\n}\n\nfunction resolveHandler(\n handler: HookHandler,\n pluginRoot: string,\n): HookHandler {\n return {\n type: handler.type,\n // Replacer function, not a string: a plugin path containing `$$`, `$&`,\n // \"$`\" or `$'` would otherwise be read as a replacement pattern and\n // silently mangle the installed command.\n command: handler.command.replace(\n /\\$\\{CLAUDE_PLUGIN_ROOT\\}/g,\n () => pluginRoot,\n ),\n ...(handler.timeout !== undefined && { timeout: handler.timeout }),\n };\n}\n\nfunction normalizePathForCommandMatch(value: string): string {\n return value.replace(/\\\\/g, \"/\");\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\ntype HookHandler = { type: string; command: string };\ntype HookEntry = { matcher?: string; hooks: HookHandler[] };\nexport type HookManifest = { hooks: Record<string, HookEntry[]> };\n\n/**\n * Locate the bundled `plugin/` directory at runtime. Walks up from the\n * module's own location looking for `plugin/scripts/` + `plugin/hooks/`,\n * both shipped via the npm `files` field. Works for both `dist/cli.mjs`\n * (bundled) and `src/cli/connect/codex-hooks.ts` (dev) layouts.\n */\nexport function findPluginRoot(startUrl: string = import.meta.url): string {\n const here = dirname(fileURLToPath(startUrl));\n let dir = here;\n for (let i = 0; i < 12; i++) {\n if (\n existsSync(join(dir, \"plugin\", \"scripts\")) &&\n existsSync(join(dir, \"plugin\", \"hooks\"))\n ) {\n return resolve(join(dir, \"plugin\"));\n }\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n throw new Error(\n `agentmemory: could not locate bundled plugin/ directory (searched up from ${here})`,\n );\n}\n\n/**\n * Build the merged hooks.json content.\n *\n * 1. Strip any entry from `existing` whose first hook command points\n * under `<pluginRoot>/scripts/`. This lets us re-install idempotently\n * without leaving stale references.\n * 2. Append fresh entries from the bundled Codex manifest with\n * `${CLAUDE_PLUGIN_ROOT}` rewritten to the absolute plugin path.\n * Matcher values from the bundled manifest are preserved so PreToolUse\n * event routing keeps working.\n */\nexport function buildMergedHooks(\n existing: HookManifest | null,\n pluginRoot: string,\n manifestFile = \"hooks.codex.json\",\n): HookManifest {\n const bundledManifestPath = join(pluginRoot, \"hooks\", manifestFile);\n const ours = JSON.parse(readFileSync(bundledManifestPath, \"utf-8\")) as HookManifest;\n const scriptsDir = join(pluginRoot, \"scripts\");\n\n const out: HookManifest = { hooks: {} };\n\n if (existing?.hooks) {\n for (const [event, entries] of Object.entries(existing.hooks)) {\n const kept = entries.filter((entry) => !isAgentmemoryEntry(entry, scriptsDir));\n if (kept.length > 0) out.hooks[event] = kept;\n }\n }\n\n for (const [event, entries] of Object.entries(ours.hooks)) {\n const resolvedEntries: HookEntry[] = entries.map((entry) => {\n const next: HookEntry = {\n hooks: entry.hooks.map((handler) => ({\n type: handler.type,\n command: handler.command.replace(/\\$\\{CLAUDE_PLUGIN_ROOT\\}/g, pluginRoot),\n })),\n };\n if (entry.matcher !== undefined) next.matcher = entry.matcher;\n return next;\n });\n out.hooks[event] = [...(out.hooks[event] ?? []), ...resolvedEntries];\n }\n\n return out;\n}\n\nfunction isAgentmemoryEntry(entry: HookEntry, scriptsDir: string): boolean {\n const normalizedScriptsDir = normalizePathForCommandMatch(scriptsDir);\n return entry.hooks.some((handler) =>\n normalizePathForCommandMatch(handler.command).includes(normalizedScriptsDir),\n );\n}\n\nfunction normalizePathForCommandMatch(value: string): string {\n return value.replace(/\\\\/g, \"/\");\n}\n","import { existsSync, mkdirSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport * as p from \"@clack/prompts\";\nimport { createJsonMcpAdapter } from \"./json-mcp-adapter.js\";\nimport type { ConnectOptions, ConnectResult } from \"./types.js\";\nimport {\n buildMergedAntigravityHooks,\n containsSpaces,\n type AntigravityHookManifest,\n} from \"./antigravity-hooks.js\";\nimport { findPluginRoot } from \"./codex-hooks.js\";\nimport {\n backupFile,\n logBackup,\n logInstalled,\n readJsonSafe,\n writeJsonAtomic,\n} from \"./util.js\";\n\n// Current Antigravity surfaces share ~/.gemini/config customizations.\n// Detection keys off the CLI's own state directory, not Gemini CLI's home.\n// Sources: antigravity.google/docs/hooks, antigravity.google/docs/cli/using\nconst GEMINI_DIR = join(homedir(), \".gemini\");\nconst ANTIGRAVITY_CLI_DIR = join(GEMINI_DIR, \"antigravity-cli\");\nconst CUSTOMIZATION_DIR = join(GEMINI_DIR, \"config\");\nconst ANTIGRAVITY_CLI_HOOKS = join(CUSTOMIZATION_DIR, \"hooks.json\");\n\nexport const adapter = createJsonMcpAdapter({\n name: \"antigravity-cli\",\n displayName: \"Antigravity CLI (agy)\",\n detectDir: ANTIGRAVITY_CLI_DIR,\n configPath: join(CUSTOMIZATION_DIR, \"mcp_config.json\"),\n // agy does not expand shell-style ${NAME:-default} values. Inherit the\n // runtime environment so custom endpoints and credentials survive.\n extraEntryFields: { env: {} },\n docs: \"https://github.com/rohitg00/agentmemory#other-agents\",\n protocolNote:\n \"→ Using MCP via ~/.gemini/config/mcp_config.json, shared with current Antigravity IDE versions. The `/mcp` slash command inside agy lists configured servers. Pass --with-hooks to also install the native ~/.gemini/config/hooks.json auto-capture hooks.\",\n installHooks: installAntigravityCliHooks,\n});\n\n/**\n * Merge the bundled `plugin/hooks/hooks.antigravity.json` into\n * `~/.gemini/config/hooks.json`, replacing only the bundle agentmemory owns.\n */\nexport function installAntigravityCliHooks(opts: ConnectOptions): ConnectResult {\n let pluginRoot: string;\n try {\n pluginRoot = findPluginRoot();\n } catch (err) {\n return {\n kind: \"skipped\",\n reason: err instanceof Error ? err.message : String(err),\n };\n }\n\n // agy honours no quoting, so a space in the path yields hooks that load\n // but never run. Refuse rather than install something that can only fail.\n if (containsSpaces(pluginRoot)) {\n return {\n kind: \"skipped\",\n reason: `Antigravity CLI cannot run hook commands whose path contains spaces, and agentmemory is installed at ${pluginRoot}. Reinstall it under a space-free path to use --with-hooks; MCP works either way.`,\n };\n }\n\n const existing = readJsonSafe<AntigravityHookManifest>(ANTIGRAVITY_CLI_HOOKS);\n const merged = buildMergedAntigravityHooks(existing, pluginRoot);\n\n if (opts.dryRun) {\n p.log.info(\n `[dry-run] Would ${existing ? \"merge\" : \"create\"} ${ANTIGRAVITY_CLI_HOOKS} with ${Object.keys(merged).length} hook bundle(s)`,\n );\n return { kind: \"installed\", mutatedPath: ANTIGRAVITY_CLI_HOOKS };\n }\n\n let backupPath: string | undefined;\n if (existsSync(ANTIGRAVITY_CLI_HOOKS)) {\n backupPath = backupFile(ANTIGRAVITY_CLI_HOOKS, \"antigravity-cli-hooks\", \"json\");\n logBackup(backupPath);\n } else {\n mkdirSync(CUSTOMIZATION_DIR, { recursive: true });\n }\n\n writeJsonAtomic(ANTIGRAVITY_CLI_HOOKS, merged);\n\n logInstalled(\"Antigravity CLI hooks\", ANTIGRAVITY_CLI_HOOKS);\n p.log.info(\n \"User-scope hooks reference absolute paths under the bundled plugin/ dir. Re-run `agentmemory connect antigravity-cli --with-hooks` after upgrading agentmemory to refresh them.\",\n );\n\n return {\n kind: \"installed\",\n mutatedPath: ANTIGRAVITY_CLI_HOOKS,\n ...(backupPath !== undefined && { backupPath }),\n };\n}\n","import { existsSync } from \"node:fs\";\nimport { homedir, platform } from \"node:os\";\nimport { join } from \"node:path\";\nimport { createJsonMcpAdapter } from \"./json-mcp-adapter.js\";\nimport { installAntigravityCliHooks } from \"./antigravity-cli.js\";\n\nconst LEGACY_USER_DIR =\n platform() === \"darwin\"\n ? join(homedir(), \"Library\", \"Application Support\", \"Antigravity\", \"User\")\n : join(homedir(), \".config\", \"Antigravity\", \"User\");\n\nconst CUSTOMIZATION_DIR = join(homedir(), \".gemini\", \"config\");\nconst mcpAdapter = createJsonMcpAdapter({\n name: \"antigravity\",\n displayName: \"Antigravity\",\n detectDir: join(homedir(), \".gemini\", \"antigravity-ide\"),\n configPath: join(CUSTOMIZATION_DIR, \"mcp_config.json\"),\n extraEntryFields: { env: {} },\n docs: \"https://github.com/rohitg00/agentmemory#other-agents\",\n protocolNote:\n \"→ Using MCP via ~/.gemini/config/mcp_config.json, shared by current Antigravity surfaces. Pass --with-hooks for capture through ~/.gemini/config/hooks.json.\",\n installHooks: installAntigravityCliHooks,\n});\n\nexport const adapter = {\n ...mcpAdapter,\n detect: () => mcpAdapter.detect() || existsSync(join(homedir(), \".gemini\", \"antigravity\")) || existsSync(LEGACY_USER_DIR),\n};\n","import { existsSync, mkdirSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport * as p from \"@clack/prompts\";\nimport type { ConnectAdapter, ConnectOptions, ConnectResult } from \"./types.js\";\nimport {\n AGENTMEMORY_MCP_BLOCK,\n backupFile,\n logAlreadyWired,\n logBackup,\n logInstalled,\n readJsonSafe,\n writeJsonAtomic,\n} from \"./util.js\";\nimport {\n buildMergedHooks,\n findPluginRoot,\n type HookManifest,\n} from \"./codex-hooks.js\";\n\nconst CLAUDE_DIR = join(homedir(), \".claude\");\nconst CLAUDE_JSON = join(homedir(), \".claude.json\");\nconst CLAUDE_SETTINGS = join(CLAUDE_DIR, \"settings.json\");\n\ntype ClaudeMcpEntry = typeof AGENTMEMORY_MCP_BLOCK;\ntype ClaudeConfig = {\n mcpServers?: Record<string, ClaudeMcpEntry>;\n [key: string]: unknown;\n};\n\nfunction entryMatches(entry: unknown): boolean {\n if (!entry || typeof entry !== \"object\") return false;\n const e = entry as Record<string, unknown>;\n if (e[\"command\"] !== \"npx\") return false;\n const args = Array.isArray(e[\"args\"]) ? (e[\"args\"] as string[]) : [];\n return args.includes(\"@agentmemory/mcp\");\n}\n\nexport const adapter: ConnectAdapter = {\n name: \"claude-code\",\n displayName: \"Claude Code\",\n category: \"native\",\n docs: \"https://github.com/rohitg00/agentmemory#claude-code-one-block-paste-it\",\n protocolNote:\n \"→ Using MCP. Hooks are also available — see https://github.com/rohitg00/agentmemory#claude-code-one-block-paste-it.\",\n\n detect(): boolean {\n return existsSync(CLAUDE_DIR);\n },\n\n async install(opts: ConnectOptions): Promise<ConnectResult> {\n const existing = readJsonSafe<ClaudeConfig>(CLAUDE_JSON);\n const next: ClaudeConfig = existing ? { ...existing } : {};\n const servers: Record<string, ClaudeMcpEntry> = {\n ...((next.mcpServers as Record<string, ClaudeMcpEntry>) ?? {}),\n };\n\n const alreadyHas = entryMatches(servers[\"agentmemory\"]);\n if (alreadyHas && !opts.force) {\n logAlreadyWired(\"Claude Code\", CLAUDE_JSON);\n if (opts.withHooks) {\n const hookResult = installClaudeHooks(opts);\n if (hookResult.kind === \"skipped\") {\n p.log.warn(\n `Claude Code hooks fallback skipped: ${hookResult.reason}.`,\n );\n }\n }\n return { kind: \"already-wired\", mutatedPath: CLAUDE_JSON };\n }\n\n if (opts.dryRun) {\n p.log.info(\n `[dry-run] Would ${alreadyHas ? \"overwrite\" : \"add\"} mcpServers.agentmemory in ${CLAUDE_JSON}`,\n );\n return { kind: \"installed\", mutatedPath: CLAUDE_JSON };\n }\n\n let backupPath: string | undefined;\n if (existsSync(CLAUDE_JSON)) {\n backupPath = backupFile(CLAUDE_JSON, \"claude-code\");\n logBackup(backupPath);\n } else {\n mkdirSync(CLAUDE_DIR, { recursive: true });\n writeFileSync(CLAUDE_JSON, \"{}\\n\", \"utf-8\");\n }\n\n servers[\"agentmemory\"] = AGENTMEMORY_MCP_BLOCK;\n next.mcpServers = servers;\n writeJsonAtomic(CLAUDE_JSON, next);\n\n const verify = readJsonSafe<ClaudeConfig>(CLAUDE_JSON);\n if (!entryMatches(verify?.mcpServers?.[\"agentmemory\"])) {\n p.log.error(\n `Verification failed: ${CLAUDE_JSON} did not contain mcpServers.agentmemory after write.`,\n );\n return { kind: \"skipped\", reason: \"verification-failed\" };\n }\n\n logInstalled(\"Claude Code\", CLAUDE_JSON);\n p.log.info(\n \"Restart Claude Code (or run `/mcp` inside a session) to pick up the new server.\",\n );\n\n if (opts.withHooks) {\n const hookResult = installClaudeHooks(opts);\n if (hookResult.kind === \"skipped\") {\n p.log.warn(\n `Claude Code hooks fallback skipped: ${hookResult.reason}. MCP wiring still applied.`,\n );\n }\n }\n\n return { kind: \"installed\", mutatedPath: CLAUDE_JSON, backupPath };\n },\n};\n\nfunction installClaudeHooks(opts: ConnectOptions): ConnectResult {\n let pluginRoot: string;\n try {\n pluginRoot = findPluginRoot();\n } catch (err) {\n return {\n kind: \"skipped\",\n reason: err instanceof Error ? err.message : String(err),\n };\n }\n\n type ClaudeSettings = { hooks?: HookManifest[\"hooks\"]; [key: string]: unknown };\n const existing = readJsonSafe<ClaudeSettings>(CLAUDE_SETTINGS) ?? {};\n const existingHooks: HookManifest | null = existing.hooks\n ? { hooks: existing.hooks }\n : null;\n const merged = buildMergedHooks(existingHooks, pluginRoot, \"hooks.json\");\n\n if (opts.dryRun) {\n p.log.info(\n `[dry-run] Would merge agentmemory hook entries into ${CLAUDE_SETTINGS} (${Object.keys(merged.hooks).length} event(s))`,\n );\n return { kind: \"installed\", mutatedPath: CLAUDE_SETTINGS };\n }\n\n let backupPath: string | undefined;\n if (existsSync(CLAUDE_SETTINGS)) {\n backupPath = backupFile(CLAUDE_SETTINGS, \"claude-settings\", \"json\");\n logBackup(backupPath);\n } else {\n mkdirSync(CLAUDE_DIR, { recursive: true });\n }\n\n const next: ClaudeSettings = { ...existing, hooks: merged.hooks };\n writeJsonAtomic(CLAUDE_SETTINGS, next);\n\n logInstalled(\"Claude Code hooks\", CLAUDE_SETTINGS);\n p.log.info(\n \"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.\",\n );\n\n return {\n kind: \"installed\",\n mutatedPath: CLAUDE_SETTINGS,\n ...(backupPath !== undefined && { backupPath }),\n };\n}\n","import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { createJsonMcpAdapter } from \"./json-mcp-adapter.js\";\n\n// Cline CLI stores MCP server config at ~/.cline/mcp.json with the\n// canonical `mcpServers` wrapper — same schema as Claude Code with\n// optional `disabled` and `autoApprove` fields per entry.\n// VS Code extension users manage MCP through Cline's Settings UI;\n// this adapter targets the standalone CLI surface.\n// Source: github.com/cline/cline/blob/main/docs/mcp/mcp-overview.mdx\nexport const adapter = createJsonMcpAdapter({\n name: \"cline\",\n displayName: \"Cline\",\n detectDir: join(homedir(), \".cline\"),\n configPath: join(homedir(), \".cline\", \"mcp.json\"),\n docs: \"https://github.com/rohitg00/agentmemory#other-agents\",\n protocolNote:\n \"→ Using MCP via ~/.cline/mcp.json (CLI). VS Code users: add the same block via Cline Settings → MCP Servers → Edit JSON.\",\n});\n","import { existsSync, mkdirSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport * as p from \"@clack/prompts\";\nimport type { ConnectAdapter, ConnectOptions, ConnectResult } from \"./types.js\";\nimport {\n AGENTMEMORY_COPILOT_MCP_BLOCK,\n backupFile,\n logAlreadyWired,\n logBackup,\n logInstalled,\n readJsonSafe,\n writeJsonAtomic,\n} from \"./util.js\";\n\nconst COPILOT_DIR = process.env[\"COPILOT_HOME\"] || join(homedir(), \".copilot\");\nconst COPILOT_MCP_JSON = join(COPILOT_DIR, \"mcp-config.json\");\n\ntype CopilotMcpEntry = typeof AGENTMEMORY_COPILOT_MCP_BLOCK;\ntype CopilotConfig = {\n mcpServers?: Record<string, CopilotMcpEntry>;\n [key: string]: unknown;\n};\n\nfunction entryMatches(entry: unknown): boolean {\n if (!entry || typeof entry !== \"object\") return false;\n return JSON.stringify(entry) === JSON.stringify(AGENTMEMORY_COPILOT_MCP_BLOCK);\n}\n\nexport const adapter: ConnectAdapter = {\n name: \"copilot-cli\",\n displayName: \"GitHub Copilot CLI\",\n category: \"native\",\n docs: \"https://github.com/rohitg00/agentmemory#github-copilot-cli\",\n protocolNote:\n \"→ Using MCP. Install the plugin too for full hooks/skills coverage.\",\n\n detect(): boolean {\n return existsSync(COPILOT_DIR);\n },\n\n async install(opts: ConnectOptions): Promise<ConnectResult> {\n const existing = readJsonSafe<CopilotConfig>(COPILOT_MCP_JSON);\n const next: CopilotConfig = existing ? { ...existing } : {};\n const servers: Record<string, CopilotMcpEntry> = {\n ...((next.mcpServers as Record<string, CopilotMcpEntry>) ?? {}),\n };\n\n const alreadyHas = entryMatches(servers[\"agentmemory\"]);\n if (alreadyHas && !opts.force) {\n logAlreadyWired(\"GitHub Copilot CLI\", COPILOT_MCP_JSON);\n return { kind: \"already-wired\", mutatedPath: COPILOT_MCP_JSON };\n }\n\n if (opts.dryRun) {\n p.log.info(\n `[dry-run] Would ${alreadyHas ? \"overwrite\" : \"add\"} mcpServers.agentmemory in ${COPILOT_MCP_JSON}`,\n );\n return { kind: \"installed\", mutatedPath: COPILOT_MCP_JSON };\n }\n\n let backupPath: string | undefined;\n if (existsSync(COPILOT_MCP_JSON)) {\n backupPath = backupFile(COPILOT_MCP_JSON, \"copilot-cli\");\n logBackup(backupPath);\n } else {\n mkdirSync(dirname(COPILOT_MCP_JSON), { recursive: true });\n }\n\n servers[\"agentmemory\"] = AGENTMEMORY_COPILOT_MCP_BLOCK;\n next.mcpServers = servers;\n writeJsonAtomic(COPILOT_MCP_JSON, next);\n\n const verify = readJsonSafe<CopilotConfig>(COPILOT_MCP_JSON);\n if (!entryMatches(verify?.mcpServers?.[\"agentmemory\"])) {\n p.log.error(\n `Verification failed: ${COPILOT_MCP_JSON} did not contain mcpServers.agentmemory after write.`,\n );\n return { kind: \"skipped\", reason: \"verification-failed\" };\n }\n\n logInstalled(\"GitHub Copilot CLI\", COPILOT_MCP_JSON);\n p.log.info(\n \"Copilot picks up MCP servers on next launch or after `/mcp`. Install the plugin too for full hooks/skills.\",\n );\n return {\n kind: \"installed\",\n mutatedPath: COPILOT_MCP_JSON,\n ...(backupPath !== undefined && { backupPath }),\n };\n },\n};\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join, dirname } from \"node:path\";\nimport * as p from \"@clack/prompts\";\nimport type { ConnectAdapter, ConnectOptions, ConnectResult } from \"./types.js\";\nimport {\n backupFile,\n logAlreadyWired,\n logBackup,\n logInstalled,\n readJsonSafe,\n writeJsonAtomic,\n} from \"./util.js\";\nimport {\n buildMergedHooks,\n findPluginRoot,\n type HookManifest,\n} from \"./codex-hooks.js\";\n\nconst CODEX_DIR = join(homedir(), \".codex\");\nconst CODEX_TOML = join(CODEX_DIR, \"config.toml\");\nconst CODEX_HOOKS = join(CODEX_DIR, \"hooks.json\");\n\nconst TOML_BLOCK = `[mcp_servers.agentmemory]\ncommand = \"npx\"\nargs = [\"-y\", \"@agentmemory/mcp\"]\n\n[mcp_servers.agentmemory.env]\nAGENTMEMORY_URL = \"http://localhost:3111\"\n`;\n\nconst SECTION_HEADER = \"[mcp_servers.agentmemory]\";\n\nfunction isWiredText(toml: string): boolean {\n return toml.includes(SECTION_HEADER);\n}\n\nfunction stripExistingBlock(toml: string): string {\n const lines = toml.split(/\\r?\\n/);\n const out: string[] = [];\n let skipping = false;\n for (const line of lines) {\n const trimmed = line.trim();\n if (\n trimmed === SECTION_HEADER ||\n trimmed === \"[mcp_servers.agentmemory.env]\"\n ) {\n skipping = true;\n continue;\n }\n if (\n skipping &&\n trimmed.startsWith(\"[\") &&\n trimmed !== \"[mcp_servers.agentmemory.env]\"\n ) {\n skipping = false;\n }\n if (!skipping) out.push(line);\n }\n return out.join(\"\\n\").replace(/\\n{3,}$/, \"\\n\\n\").trimEnd() + \"\\n\";\n}\n\nexport const adapter: ConnectAdapter = {\n name: \"codex\",\n displayName: \"Codex CLI\",\n category: \"native\",\n docs: \"https://github.com/rohitg00/agentmemory#codex-cli-codex-plugin-platform\",\n protocolNote:\n \"→ Using MCP. Hooks ship via the Codex plugin; on Codex Desktop, also pass --with-hooks to install the global hooks.json workaround.\",\n\n detect(): boolean {\n return existsSync(CODEX_DIR);\n },\n\n async install(opts: ConnectOptions): Promise<ConnectResult> {\n const exists = existsSync(CODEX_TOML);\n const current = exists ? readFileSync(CODEX_TOML, \"utf-8\") : \"\";\n const wired = isWiredText(current);\n\n if (wired && !opts.force) {\n logAlreadyWired(\"Codex CLI\", CODEX_TOML);\n return { kind: \"already-wired\", mutatedPath: CODEX_TOML };\n }\n\n if (opts.dryRun) {\n p.log.info(\n `[dry-run] Would ${wired ? \"rewrite\" : \"append\"} [mcp_servers.agentmemory] in ${CODEX_TOML}`,\n );\n if (opts.withHooks) installCodexHooks(opts);\n return { kind: \"installed\", mutatedPath: CODEX_TOML };\n }\n\n let backupPath: string | undefined;\n if (exists) {\n backupPath = backupFile(CODEX_TOML, \"codex\", \"toml\");\n logBackup(backupPath);\n } else {\n mkdirSync(dirname(CODEX_TOML), { recursive: true });\n }\n\n const cleaned = wired ? stripExistingBlock(current) : current;\n const joiner = cleaned.length === 0 || cleaned.endsWith(\"\\n\") ? \"\" : \"\\n\";\n const next = `${cleaned}${joiner}${cleaned.length > 0 ? \"\\n\" : \"\"}${TOML_BLOCK}`;\n writeFileSync(CODEX_TOML, next, \"utf-8\");\n\n const verify = readFileSync(CODEX_TOML, \"utf-8\");\n if (!isWiredText(verify)) {\n p.log.error(\n `Verification failed: ${CODEX_TOML} did not contain ${SECTION_HEADER} after write.`,\n );\n return { kind: \"skipped\", reason: \"verification-failed\" };\n }\n\n logInstalled(\"Codex CLI\", CODEX_TOML);\n p.log.info(\n \"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\",\n );\n\n if (opts.withHooks) {\n const hookResult = installCodexHooks(opts);\n if (hookResult.kind === \"skipped\") {\n p.log.warn(\n `Codex hooks fallback skipped: ${hookResult.reason}. MCP wiring still applied.`,\n );\n }\n }\n\n return {\n kind: \"installed\",\n mutatedPath: CODEX_TOML,\n ...(backupPath !== undefined && { backupPath }),\n };\n },\n};\n\nfunction installCodexHooks(opts: ConnectOptions): ConnectResult {\n let pluginRoot: string;\n try {\n pluginRoot = findPluginRoot();\n } catch (err) {\n return {\n kind: \"skipped\",\n reason: err instanceof Error ? err.message : String(err),\n };\n }\n\n const existing = readJsonSafe<HookManifest>(CODEX_HOOKS);\n const merged = buildMergedHooks(existing, pluginRoot);\n\n if (opts.dryRun) {\n p.log.info(\n `[dry-run] Would ${existing ? \"merge\" : \"create\"} ${CODEX_HOOKS} with ${Object.keys(merged.hooks).length} event(s)`,\n );\n return { kind: \"installed\", mutatedPath: CODEX_HOOKS };\n }\n\n let backupPath: string | undefined;\n if (existsSync(CODEX_HOOKS)) {\n backupPath = backupFile(CODEX_HOOKS, \"codex-hooks\", \"json\");\n logBackup(backupPath);\n }\n\n writeJsonAtomic(CODEX_HOOKS, merged);\n\n logInstalled(\"Codex hooks\", CODEX_HOOKS);\n p.log.warn(\n \"Codex runs only trusted hooks: launch `codex` (the TUI) once and choose \\\"Trust all and continue\\\" at the \\\"Hooks need review\\\" prompt. `codex exec` never shows the prompt, so hooks stay inert until then.\",\n );\n p.log.info(\n \"User-scope hooks reference absolute paths under the bundled plugin/ dir. Re-run `agentmemory connect codex --with-hooks` after upgrading agentmemory to refresh them, then re-approve in the TUI.\",\n );\n\n return {\n kind: \"installed\",\n mutatedPath: CODEX_HOOKS,\n ...(backupPath !== undefined && { backupPath }),\n };\n}\n","import { existsSync, mkdirSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport * as p from \"@clack/prompts\";\nimport type { ConnectAdapter, ConnectOptions, ConnectResult } from \"./types.js\";\nimport {\n AGENTMEMORY_MCP_BLOCK,\n backupFile,\n logAlreadyWired,\n logBackup,\n logInstalled,\n readJsonSafe,\n writeJsonAtomic,\n} from \"./util.js\";\n\n// Continue.dev v1+ prefers ~/.continue/config.yaml; config.json is\n// deprecated and ignored when yaml is present. Three branches:\n// - config.yaml exists → emit stub with manual edit instructions\n// (no YAML dep in tree; preserving comments/anchors safely needs it)\n// - config.json exists → modify it (legacy path still loaded when no yaml)\n// - neither → create config.yaml from scratch (no merge risk)\n// Source: docs.continue.dev/reference/yaml-migration\nconst CONTINUE_DIR = join(homedir(), \".continue\");\nconst YAML_PATH = join(CONTINUE_DIR, \"config.yaml\");\nconst JSON_PATH = join(CONTINUE_DIR, \"config.json\");\n\ntype ContinueEntry = {\n name: string;\n command: string;\n args: string[];\n env?: Record<string, string>;\n};\n\ntype ContinueJsonConfig = {\n mcpServers?: ContinueEntry[];\n [key: string]: unknown;\n};\n\nfunction buildEntry(): ContinueEntry {\n return {\n name: \"agentmemory\",\n command: AGENTMEMORY_MCP_BLOCK.command,\n args: [...AGENTMEMORY_MCP_BLOCK.args],\n env: { ...AGENTMEMORY_MCP_BLOCK.env },\n };\n}\n\nfunction entryIsAgentmemory(entry: ContinueEntry | undefined): boolean {\n if (!entry) return false;\n return entry.name === \"agentmemory\" && entry.args.includes(\"@agentmemory/mcp\");\n}\n\n// Minimal YAML emitter for the agentmemory entry. Quotes string values\n// that contain ${ ... } expansion to keep parsers happy. Only used when\n// creating a fresh config.yaml — never when modifying an existing one.\nfunction renderFreshYaml(): string {\n const e = buildEntry();\n const envLines = Object.entries(e.env ?? {})\n .map(([k, v]) => ` ${k}: \"${v}\"`)\n .join(\"\\n\");\n return [\n \"mcpServers:\",\n ` - name: ${e.name}`,\n ` command: ${e.command}`,\n \" args:\",\n ...e.args.map((a) => ` - \"${a}\"`),\n \" env:\",\n envLines,\n \"\",\n ].join(\"\\n\");\n}\n\nexport const adapter: ConnectAdapter = {\n name: \"continue\",\n displayName: \"Continue\",\n category: \"mcp\",\n docs: \"https://github.com/rohitg00/agentmemory#other-agents\",\n protocolNote:\n \"→ Using MCP via ~/.continue/config.yaml (preferred) or config.json (legacy, only when no yaml).\",\n\n detect(): boolean {\n return existsSync(CONTINUE_DIR);\n },\n\n async install(opts: ConnectOptions): Promise<ConnectResult> {\n const yamlExists = existsSync(YAML_PATH);\n const jsonExists = existsSync(JSON_PATH);\n\n // Branch 1: yaml present — refuse to silently mutate user's yaml\n // config (preserving comments/anchors needs a proper parser).\n if (yamlExists) {\n const indented = renderFreshYaml()\n .split(\"\\n\")\n .map((l) => (l ? ` ${l}` : l))\n .join(\"\\n\");\n 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${indented}`;\n p.log.info(\n `Continue: ${YAML_PATH} already exists. Manual edit needed.${manual}`,\n );\n return { kind: \"stub\", reason: \"config.yaml-needs-manual-edit\" };\n }\n\n // Branch 2: legacy json present — modify in place.\n if (jsonExists) {\n const existing = readJsonSafe<ContinueJsonConfig>(JSON_PATH);\n const next: ContinueJsonConfig = existing ? { ...existing } : {};\n const servers = Array.isArray(next.mcpServers)\n ? [...next.mcpServers]\n : [];\n\n const idx = servers.findIndex((s) => s?.name === \"agentmemory\");\n const alreadyHas = idx >= 0 && entryIsAgentmemory(servers[idx]);\n if (alreadyHas && !opts.force) {\n logAlreadyWired(\"Continue\", JSON_PATH);\n return { kind: \"already-wired\", mutatedPath: JSON_PATH };\n }\n\n if (opts.dryRun) {\n p.log.info(\n `[dry-run] Would ${alreadyHas ? \"overwrite\" : \"add\"} mcpServers[agentmemory] in ${JSON_PATH}`,\n );\n return { kind: \"installed\", mutatedPath: JSON_PATH };\n }\n\n const backupPath = backupFile(JSON_PATH, \"continue\");\n logBackup(backupPath);\n\n const entry = buildEntry();\n if (idx >= 0) servers[idx] = entry;\n else servers.push(entry);\n next.mcpServers = servers;\n writeJsonAtomic(JSON_PATH, next);\n\n const verify = readJsonSafe<ContinueJsonConfig>(JSON_PATH);\n const verifyEntry = verify?.mcpServers?.find(\n (s) => s?.name === \"agentmemory\",\n );\n if (!entryIsAgentmemory(verifyEntry)) {\n p.log.error(\n `Verification failed: ${JSON_PATH} did not contain mcpServers[agentmemory] after write.`,\n );\n return { kind: \"skipped\", reason: \"verification-failed\" };\n }\n\n logInstalled(\"Continue (legacy config.json)\", JSON_PATH);\n return {\n kind: \"installed\",\n mutatedPath: JSON_PATH,\n backupPath,\n };\n }\n\n // Branch 3: neither exists — create config.yaml from scratch (modern path).\n if (opts.dryRun) {\n p.log.info(`[dry-run] Would create ${YAML_PATH} with agentmemory entry`);\n return { kind: \"installed\", mutatedPath: YAML_PATH };\n }\n\n mkdirSync(dirname(YAML_PATH), { recursive: true });\n writeFileSync(YAML_PATH, renderFreshYaml(), \"utf-8\");\n logInstalled(\"Continue\", YAML_PATH);\n return { kind: \"installed\", mutatedPath: YAML_PATH };\n },\n};\n","import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { createJsonMcpAdapter } from \"./json-mcp-adapter.js\";\n\nexport const adapter = createJsonMcpAdapter({\n name: \"cursor\",\n displayName: \"Cursor\",\n detectDir: join(homedir(), \".cursor\"),\n configPath: join(homedir(), \".cursor\", \"mcp.json\"),\n docs: \"https://github.com/rohitg00/agentmemory#other-agents\",\n protocolNote:\n \"→ Using MCP (the only protocol Cursor speaks). Memory bridge runs at :3111 underneath.\",\n});\n","import { existsSync, mkdirSync } from \"node:fs\";\nimport { homedir, platform } from \"node:os\";\nimport { join } from \"node:path\";\nimport * as p from \"@clack/prompts\";\nimport { createJsonMcpAdapter } from \"./json-mcp-adapter.js\";\nimport type { ConnectOptions, ConnectResult } from \"./types.js\";\nimport {\n buildMergedHooks,\n findPluginRoot,\n type HookManifest,\n} from \"./codex-hooks.js\";\nimport {\n backupFile,\n logBackup,\n logInstalled,\n readJsonSafe,\n writeJsonAtomic,\n} from \"./util.js\";\n\nfunction devinDir(): string {\n if (platform() === \"win32\") {\n const appData = process.env[\"APPDATA\"];\n if (appData) return join(appData, \"devin\");\n }\n const xdg = process.env[\"XDG_CONFIG_HOME\"];\n return xdg ? join(xdg, \"devin\") : join(homedir(), \".config\", \"devin\");\n}\n\nconst DEVIN_DIR = devinDir();\nconst DEVIN_CONFIG = join(DEVIN_DIR, \"config.json\");\n\nexport const adapter = createJsonMcpAdapter({\n name: \"devin\",\n displayName: \"Devin CLI\",\n detectDir: DEVIN_DIR,\n configPath: DEVIN_CONFIG,\n docs: \"https://github.com/rohitg00/agentmemory#other-agents\",\n protocolNote:\n \"→ Using MCP via the user config. Devin CLI migrates mcpServers into mcp_config.json on newer builds. Pass --with-hooks for native auto-capture.\",\n installHooks: installDevinHooks,\n});\n\nfunction installDevinHooks(opts: ConnectOptions): ConnectResult {\n let pluginRoot: string;\n try {\n pluginRoot = findPluginRoot();\n } catch (err) {\n return {\n kind: \"skipped\",\n reason: err instanceof Error ? err.message : String(err),\n };\n }\n\n const existing = readJsonSafe<Record<string, unknown>>(DEVIN_CONFIG) ?? {};\n const existingHooks = existing[\"hooks\"]\n ? ({ hooks: existing[\"hooks\"] } as HookManifest)\n : null;\n const merged = buildMergedHooks(existingHooks, pluginRoot, \"hooks.devin.json\");\n const next = { ...existing, hooks: merged.hooks };\n\n if (opts.dryRun) {\n p.log.info(\n `[dry-run] Would write ${Object.keys(merged.hooks).length} hook event(s) into ${DEVIN_CONFIG}`,\n );\n return { kind: \"installed\", mutatedPath: DEVIN_CONFIG };\n }\n\n let backupPath: string | undefined;\n if (existsSync(DEVIN_CONFIG)) {\n backupPath = backupFile(DEVIN_CONFIG, \"devin-hooks\", \"json\");\n logBackup(backupPath);\n } else {\n mkdirSync(DEVIN_DIR, { recursive: true });\n }\n\n writeJsonAtomic(DEVIN_CONFIG, next);\n\n logInstalled(\"Devin CLI hooks\", DEVIN_CONFIG);\n p.log.info(\n \"Verify with `/hooks` inside devin. Re-run `agentmemory connect devin --with-hooks` after upgrading agentmemory so the plugin paths stay current.\",\n );\n\n return {\n kind: \"installed\",\n mutatedPath: DEVIN_CONFIG,\n ...(backupPath !== undefined && { backupPath }),\n };\n}\n","import { existsSync, mkdirSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport * as p from \"@clack/prompts\";\nimport { createJsonMcpAdapter } from \"./json-mcp-adapter.js\";\nimport type { ConnectOptions, ConnectResult } from \"./types.js\";\nimport {\n buildMergedHooks,\n findPluginRoot,\n type HookManifest,\n} from \"./codex-hooks.js\";\nimport { backupFile, logBackup, logInstalled, readJsonSafe, writeJsonAtomic } from \"./util.js\";\n\n// Factory.ai's Droid CLI stores MCP server config at ~/.factory/mcp.json\n// with the canonical `mcpServers` wrapper. Project-scoped overrides live\n// at <repo>/.factory/mcp.json. Each entry adds an optional `type` field\n// (\"stdio\" | \"http\") and `disabled` boolean — agentmemory's stdio block\n// works against the same shape without needing the explicit type tag.\n// Source: docs.factory.ai/cli/configuration/mcp\n//\n// Droid also ships a native, first-party hooks system (SessionStart,\n// SessionEnd, UserPromptSubmit, PreToolUse, PostToolUse) configured via\n// `~/.factory/hooks.json`, in the same `{ hooks: { <event>: [{ matcher?,\n// hooks: [{ type, command }] }] } }` shape Claude Code and Codex use — so\n// `--with-hooks` reuses `buildMergedHooks` from codex-hooks.ts with the\n// bundled `hooks.droid.json` manifest instead of writing a new merge\n// strategy. Source: docs.factory.ai/cli/configuration/hooks-guide\nconst DROID_DIR = join(homedir(), \".factory\");\nconst DROID_HOOKS = join(DROID_DIR, \"hooks.json\");\n\nexport const adapter = createJsonMcpAdapter({\n name: \"droid\",\n displayName: \"Droid (Factory.ai)\",\n detectDir: DROID_DIR,\n configPath: join(DROID_DIR, \"mcp.json\"),\n docs: \"https://github.com/rohitg00/agentmemory#other-agents\",\n protocolNote:\n \"→ Using MCP via ~/.factory/mcp.json. The `/mcp` slash command inside droid lists configured servers. Pass --with-hooks to also install the native ~/.factory/hooks.json auto-capture hooks.\",\n // Droid requires `type` per the documented schema. stdio for npx-spawned shim.\n extraEntryFields: { type: \"stdio\" },\n installHooks: installDroidHooks,\n});\n\n/**\n * Merge the bundled `plugin/hooks/hooks.droid.json` into\n * `~/.factory/hooks.json`. Same idempotent merge/strip-by-script-path\n * behavior as the Codex and Claude Code hook installers: re-running keeps\n * user-authored hook entries and only replaces the ones agentmemory owns.\n */\nfunction installDroidHooks(opts: ConnectOptions): ConnectResult {\n let pluginRoot: string;\n try {\n pluginRoot = findPluginRoot();\n } catch (err) {\n return {\n kind: \"skipped\",\n reason: err instanceof Error ? err.message : String(err),\n };\n }\n\n const existing = readJsonSafe<HookManifest>(DROID_HOOKS);\n const merged = buildMergedHooks(existing, pluginRoot, \"hooks.droid.json\");\n\n if (opts.dryRun) {\n p.log.info(\n `[dry-run] Would ${existing ? \"merge\" : \"create\"} ${DROID_HOOKS} with ${Object.keys(merged.hooks).length} event(s)`,\n );\n return { kind: \"installed\", mutatedPath: DROID_HOOKS };\n }\n\n let backupPath: string | undefined;\n if (existsSync(DROID_HOOKS)) {\n backupPath = backupFile(DROID_HOOKS, \"droid-hooks\", \"json\");\n logBackup(backupPath);\n } else {\n mkdirSync(DROID_DIR, { recursive: true });\n }\n\n writeJsonAtomic(DROID_HOOKS, merged);\n\n logInstalled(\"Droid hooks\", DROID_HOOKS);\n p.log.info(\n \"User-scope hooks reference absolute paths under the bundled plugin/ dir. Re-run `agentmemory connect droid --with-hooks` after upgrading agentmemory to refresh them.\",\n );\n\n return {\n kind: \"installed\",\n mutatedPath: DROID_HOOKS,\n ...(backupPath !== undefined && { backupPath }),\n };\n}\n","import { existsSync, mkdirSync, readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport * as p from \"@clack/prompts\";\nimport type { ConnectAdapter, ConnectOptions, ConnectResult } from \"./types.js\";\nimport {\n backupFile,\n logAlreadyWired,\n logBackup,\n logInstalled,\n readJsonSafe,\n writeJsonAtomic,\n writeTextAtomic,\n} from \"./util.js\";\nimport {\n buildMergedHooks,\n findPluginRoot,\n type HookManifest,\n} from \"./codex-hooks.js\";\n\n// Rows land in the home-level cordis.patch.yml, the patch layer every\n// Harness profile loads; the hooks row reuses the bundled Claude Code\n// hook scripts through Harness's own bridge plugin.\n\nfunction dshHome(): string {\n return process.env[\"DSH_HOME\"] || join(homedir(), \".dsh\");\n}\n\n// Harness env values are literal strings; no ${VAR:-default} interpolation.\nconst MCP_BLOCK = `- insert:\n - id: agentmemory\n name: '@deepseek-ai/dsh-mcp-client'\n config:\n transport: stdio\n serverName: agentmemory\n command: npx\n args: ['-y', '@agentmemory/mcp']\n env:\n AGENTMEMORY_URL: http://localhost:3111\n`;\n\nconst MCP_MARKER = \"serverName: agentmemory\";\nconst HOOKS_MARKER = \"id: agentmemory-hooks\";\n\nfunction hooksBlock(hooksConfigPath: string): string {\n return `- insert:\n - id: agentmemory-hooks\n name: '@deepseek-ai/dsh-hooks-claude-code'\n config:\n configPath: ${JSON.stringify(hooksConfigPath)}\n`;\n}\n\n// Drop the managed top-level block containing `marker`.\nfunction stripBlock(content: string, marker: string): string {\n if (!content.includes(marker)) return content;\n const lines = content.split(\"\\n\");\n const markerIdx = lines.findIndex((l) => l.includes(marker));\n let start = markerIdx;\n while (start > 0 && !lines[start].startsWith(\"- \")) start--;\n let end = markerIdx + 1;\n while (end < lines.length && !lines[end].startsWith(\"- \")) end++;\n return lines\n .slice(0, start)\n .concat(lines.slice(end))\n .join(\"\\n\")\n .replace(/\\n+$/, \"\\n\");\n}\n\nfunction appendBlock(content: string, block: string): string {\n const base = content.replace(/\\n+$/, \"\\n\");\n return base.trim() ? `${base}\\n${block}` : block;\n}\n\nfunction installHooksFile(home: string): string {\n const hooksPath = join(home, \"agentmemory.hooks.json\");\n const pluginRoot = findPluginRoot();\n const existing = readJsonSafe<HookManifest>(hooksPath);\n const merged = buildMergedHooks(existing, pluginRoot, \"hooks.codex.json\");\n writeJsonAtomic(hooksPath, merged);\n return hooksPath;\n}\n\nexport const adapter: ConnectAdapter = {\n name: \"dsh\",\n displayName: \"DeepSeek Harness\",\n docs: \"https://github.com/rohitg00/agentmemory#other-agents\",\n protocolNote:\n \"→ Using MCP via $DSH_HOME/cordis.patch.yml (the home-level patch layer every profile loads). Tools appear as mcp__agentmemory__*. Pass --with-hooks to also wire auto-capture through Harness's Claude Code hook bridge.\",\n category: \"native\",\n detect(): boolean {\n return existsSync(dshHome());\n },\n async install(opts: ConnectOptions): Promise<ConnectResult> {\n const home = dshHome();\n const configPath = join(home, \"cordis.patch.yml\");\n const existing = existsSync(configPath)\n ? readFileSync(configPath, \"utf-8\")\n : \"\";\n\n const wantHooks = opts.withHooks === true;\n const hasMcp = existing.includes(MCP_MARKER);\n const hasHooks = existing.includes(HOOKS_MARKER);\n\n if (hasMcp && (!wantHooks || hasHooks) && !opts.force) {\n logAlreadyWired(this.displayName, configPath);\n return { kind: \"already-wired\", mutatedPath: configPath };\n }\n\n if (opts.dryRun) {\n p.log.info(\n `[dry-run] Would append the agentmemory mcp-client row${wantHooks ? \" and the hooks-claude-code row\" : \"\"} to ${configPath}`,\n );\n return { kind: \"installed\", mutatedPath: configPath };\n }\n\n let backupPath: string | undefined;\n if (existsSync(configPath)) {\n backupPath = backupFile(configPath, this.name, \"yml\");\n logBackup(backupPath);\n } else {\n mkdirSync(dirname(configPath), { recursive: true });\n }\n\n let next = stripBlock(existing, MCP_MARKER);\n next = appendBlock(next, MCP_BLOCK);\n\n if (wantHooks) {\n const hooksPath = installHooksFile(home);\n next = stripBlock(next, HOOKS_MARKER);\n next = appendBlock(next, hooksBlock(hooksPath));\n p.log.info(`Hook manifest: ${hooksPath}`);\n }\n\n writeTextAtomic(configPath, next);\n\n const written = readFileSync(configPath, \"utf-8\");\n if (!written.includes(MCP_MARKER) || (wantHooks && !written.includes(HOOKS_MARKER))) {\n p.log.error(\n `Verification failed: ${configPath} did not contain the agentmemory rows after write.`,\n );\n return { kind: \"skipped\", reason: \"verification-failed\" };\n }\n\n logInstalled(this.displayName, configPath);\n return { kind: \"installed\", mutatedPath: configPath, backupPath };\n },\n};\n","import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { createJsonMcpAdapter } from \"./json-mcp-adapter.js\";\n\nexport const adapter = createJsonMcpAdapter({\n name: \"gemini-cli\",\n displayName: \"Gemini CLI\",\n detectDir: join(homedir(), \".gemini\"),\n configPath: join(homedir(), \".gemini\", \"settings.json\"),\n docs: \"https://github.com/rohitg00/agentmemory#other-agents\",\n protocolNote:\n \"→ Using MCP (the only protocol Gemini CLI speaks). Memory bridge runs at :3111 underneath.\",\n});\n","import { existsSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport * as p from \"@clack/prompts\";\nimport type { ConnectAdapter, ConnectOptions, ConnectResult } from \"./types.js\";\n\nconst HERMES_DIR = join(homedir(), \".hermes\");\nconst HERMES_CONFIG = join(HERMES_DIR, \"config.yaml\");\nconst DOCS = \"https://github.com/rohitg00/agentmemory/tree/main/integrations/hermes\";\n\nexport const adapter: ConnectAdapter = {\n name: \"hermes\",\n displayName: \"Hermes Agent\",\n category: \"native\",\n docs: DOCS,\n protocolNote:\n \"→ Using MCP. Hooks are also available — see https://github.com/rohitg00/agentmemory/tree/main/integrations/hermes.\",\n\n detect(): boolean {\n return existsSync(HERMES_DIR);\n },\n\n async install(_opts: ConnectOptions): Promise<ConnectResult> {\n p.log.warn(\n \"Hermes uses YAML config. Automated merge isn't implemented yet — manual install required.\",\n );\n p.note(\n [\n `Add to ${HERMES_CONFIG}:`,\n \"\",\n \" mcp_servers:\",\n \" agentmemory:\",\n \" command: npx\",\n ' args: [\"-y\", \"@agentmemory/mcp\"]',\n \"\",\n \" memory:\",\n \" provider: agentmemory\",\n \"\",\n `Full guide: ${DOCS}`,\n ].join(\"\\n\"),\n \"Hermes manual install\",\n );\n return {\n kind: \"stub\",\n reason: \"yaml-merge-not-implemented\",\n };\n },\n};\n","import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { createJsonMcpAdapter } from \"./json-mcp-adapter.js\";\n\n// Kiro stores user-level MCP servers in ~/.kiro/settings/mcp.json.\n// Schema follows the standard MCP envelope { mcpServers: { ... } }.\n// Source: kiro.dev/docs/cli/mcp\nexport const adapter = createJsonMcpAdapter({\n name: \"kiro\",\n displayName: \"Kiro\",\n detectDir: join(homedir(), \".kiro\"),\n configPath: join(homedir(), \".kiro\", \"settings\", \"mcp.json\"),\n docs: \"https://github.com/rohitg00/agentmemory#other-agents\",\n protocolNote:\n \"→ Using MCP via ~/.kiro/settings/mcp.json (user-level). Workspace overrides live in .kiro/settings/mcp.json.\",\n});\n","import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { createJsonMcpAdapter } from \"./json-mcp-adapter.js\";\n\nexport const adapter = createJsonMcpAdapter({\n name: \"openclaw\",\n displayName: \"OpenClaw\",\n category: \"native\",\n detectDir: join(homedir(), \".openclaw\"),\n configPath: join(homedir(), \".openclaw\", \"openclaw.json\"),\n docs: \"https://github.com/rohitg00/agentmemory/tree/main/integrations/openclaw\",\n protocolNote:\n \"→ Using MCP. Hooks are also available — see https://github.com/rohitg00/agentmemory/tree/main/integrations/openclaw.\",\n});\n","import { existsSync, mkdirSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport * as p from \"@clack/prompts\";\nimport type { ConnectAdapter, ConnectOptions, ConnectResult } from \"./types.js\";\nimport {\n backupFile,\n logAlreadyWired,\n logBackup,\n logInstalled,\n readJsonSafe,\n writeJsonAtomic,\n} from \"./util.js\";\n\n// OpenCode does not use the standard `mcpServers` block. Its config is a\n// top-level `mcp` key whose entries carry `type`, `command` as an array,\n// and `enabled` (docs: README \"OpenCode (MCP only)\"). So it needs its own\n// adapter rather than createJsonMcpAdapter.\n\nconst CONFIG_PATH = join(homedir(), \".config\", \"opencode\", \"opencode.json\");\nconst DETECT_DIR = join(homedir(), \".config\", \"opencode\");\n\n// No `environment` block: OpenCode does not expand shell-style\n// `${VAR:-default}` values, and writing them literally would override the\n// user's real shell AGENTMEMORY_URL with an unexpanded string. The stdio\n// child inherits the shell environment (an exported AGENTMEMORY_URL /\n// AGENTMEMORY_SECRET still reaches the server), and the @agentmemory/mcp\n// shim defaults unset vars (URL -> localhost:3111, no secret, all tools).\nconst OPENCODE_ENTRY = {\n type: \"local\",\n command: [\"npx\", \"-y\", \"@agentmemory/mcp\"],\n enabled: true,\n};\n\ntype OpencodeConfig = Record<string, unknown>;\ntype McpEntry = Record<string, unknown>;\n\nfunction entryMatches(entry: unknown): boolean {\n if (!entry || typeof entry !== \"object\") return false;\n const command = (entry as McpEntry)[\"command\"];\n return Array.isArray(command) && command.includes(\"@agentmemory/mcp\");\n}\n\nexport const adapter: ConnectAdapter = {\n name: \"opencode\",\n displayName: \"OpenCode\",\n category: \"mcp\",\n docs: \"https://github.com/rohitg00/agentmemory#other-agents\",\n protocolNote:\n \"Using MCP via ~/.config/opencode/opencode.json (top-level `mcp` key). For full auto-capture, also install the bundled plugin in plugin/opencode/.\",\n\n detect(): boolean {\n return existsSync(DETECT_DIR);\n },\n\n async install(opts: ConnectOptions): Promise<ConnectResult> {\n const existing = readJsonSafe<OpencodeConfig>(CONFIG_PATH);\n const next: OpencodeConfig = existing ? { ...existing } : {};\n const existingMcp = next[\"mcp\"];\n const mcp: Record<string, McpEntry> =\n existingMcp &&\n typeof existingMcp === \"object\" &&\n !Array.isArray(existingMcp)\n ? { ...(existingMcp as Record<string, McpEntry>) }\n : {};\n\n const alreadyHas = entryMatches(mcp[\"agentmemory\"]);\n if (alreadyHas && !opts.force) {\n logAlreadyWired(this.displayName, CONFIG_PATH);\n return { kind: \"already-wired\", mutatedPath: CONFIG_PATH };\n }\n\n if (opts.dryRun) {\n p.log.info(\n `[dry-run] Would ${alreadyHas ? \"overwrite\" : \"add\"} mcp.agentmemory in ${CONFIG_PATH}`,\n );\n return { kind: \"installed\", mutatedPath: CONFIG_PATH };\n }\n\n let backupPath: string | undefined;\n if (existsSync(CONFIG_PATH)) {\n backupPath = backupFile(CONFIG_PATH, this.name);\n logBackup(backupPath);\n } else {\n mkdirSync(dirname(CONFIG_PATH), { recursive: true });\n }\n\n mcp[\"agentmemory\"] = { ...OPENCODE_ENTRY };\n next[\"mcp\"] = mcp;\n writeJsonAtomic(CONFIG_PATH, next);\n\n const verify = readJsonSafe<OpencodeConfig>(CONFIG_PATH);\n const verifyMcp = verify?.[\"mcp\"] as Record<string, McpEntry> | undefined;\n if (!entryMatches(verifyMcp?.[\"agentmemory\"])) {\n p.log.error(\n `Verification failed: ${CONFIG_PATH} did not contain mcp.agentmemory after write.`,\n );\n return { kind: \"skipped\", reason: \"verification-failed\" };\n }\n\n logInstalled(this.displayName, CONFIG_PATH);\n return {\n kind: \"installed\",\n mutatedPath: CONFIG_PATH,\n ...(backupPath !== undefined && { backupPath }),\n };\n },\n};\n","import { existsSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport * as p from \"@clack/prompts\";\nimport type { ConnectAdapter, ConnectOptions, ConnectResult } from \"./types.js\";\n\nconst OPENHUMAN_DIR = join(homedir(), \".openhuman\");\nconst DOCS = \"https://github.com/tinyhumansai/openhuman\";\n\nexport const adapter: ConnectAdapter = {\n name: \"openhuman\",\n displayName: \"OpenHuman\",\n category: \"native\",\n docs: DOCS,\n protocolNote:\n \"→ Using native hooks (REST API at :3111). MCP not required.\",\n\n detect(): boolean {\n return existsSync(OPENHUMAN_DIR);\n },\n\n async install(_opts: ConnectOptions): Promise<ConnectResult> {\n p.log.warn(\n \"OpenHuman integration is not yet automated. No `integrations/openhuman/` folder exists in the agentmemory repo today.\",\n );\n p.note(\n [\n \"OpenHuman is a Memory-trait host. The expected wiring is the REST\",\n \"proxy at http://localhost:3111 plus an OpenHuman-side Memory trait\",\n \"impl. Once integrations/openhuman/ lands in agentmemory we'll wire\",\n \"this up automatically.\",\n \"\",\n `Tracking: ${DOCS}`,\n ].join(\"\\n\"),\n \"OpenHuman manual install\",\n );\n return {\n kind: \"stub\",\n reason: \"no-integration-folder-yet\",\n };\n },\n};\n","import { existsSync, mkdirSync, readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport * as p from \"@clack/prompts\";\nimport type { ConnectAdapter, ConnectOptions, ConnectResult } from \"./types.js\";\nimport { findPluginRoot } from \"./codex-hooks.js\";\nimport {\n backupFile,\n logAlreadyWired,\n logBackup,\n logInstalled,\n writeTextAtomic,\n} from \"./util.js\";\n\n// pi auto-discovers ~/.pi/agent/extensions/*/index.ts, so installing is a\n// copy of the bundled extension; no settings.json edit.\n\nconst PI_DIR = join(homedir(), \".pi\");\nconst PI_EXT_DIR = join(PI_DIR, \"agent\", \"extensions\", \"agentmemory\");\nconst DOCS = \"https://github.com/rohitg00/agentmemory/tree/main/integrations/pi\";\nconst EXT_FILES = [\"index.ts\", \"security.ts\"] as const;\n\nfunction findPiSourceDir(): string | null {\n let packageRoot: string;\n try {\n packageRoot = dirname(findPluginRoot());\n } catch {\n return null;\n }\n const dir = join(packageRoot, \"integrations\", \"pi\");\n const complete = EXT_FILES.every((f) => existsSync(join(dir, f)));\n return complete ? dir : null;\n}\n\nexport const adapter: ConnectAdapter = {\n name: \"pi\",\n displayName: \"pi\",\n category: \"native\",\n docs: DOCS,\n protocolNote:\n \"→ Using native lifecycle hooks against the REST API at :3111 (recall on agent start, capture on agent end, memory tools). MCP not required.\",\n\n detect(): boolean {\n return existsSync(PI_DIR);\n },\n\n async install(opts: ConnectOptions): Promise<ConnectResult> {\n const sourceDir = findPiSourceDir();\n if (!sourceDir) {\n p.log.error(\n \"Bundled pi extension not found (integrations/pi missing from the install) — reinstall agentmemory.\",\n );\n return { kind: \"skipped\", reason: \"bundled-extension-missing\" };\n }\n const sources = EXT_FILES.map((f) => ({\n name: f,\n content: readFileSync(join(sourceDir, f), \"utf-8\"),\n target: join(PI_EXT_DIR, f),\n }));\n\n const upToDate = sources.every(\n (s) => existsSync(s.target) && readFileSync(s.target, \"utf-8\") === s.content,\n );\n if (upToDate && !opts.force) {\n logAlreadyWired(this.displayName, PI_EXT_DIR);\n return { kind: \"already-wired\", mutatedPath: PI_EXT_DIR };\n }\n\n if (opts.dryRun) {\n p.log.info(\n `[dry-run] Would install the pi extension (${EXT_FILES.join(\", \")}) into ${PI_EXT_DIR}`,\n );\n return { kind: \"installed\", mutatedPath: PI_EXT_DIR };\n }\n\n let backupPath: string | undefined;\n for (const s of sources) {\n if (existsSync(s.target) && readFileSync(s.target, \"utf-8\") !== s.content) {\n const backup = backupFile(s.target, `${this.name}-${s.name.replace(/\\.ts$/, \"\")}`, \"ts\");\n logBackup(backup);\n backupPath ??= backup;\n }\n }\n\n mkdirSync(PI_EXT_DIR, { recursive: true });\n for (const s of sources) {\n writeTextAtomic(s.target, s.content);\n }\n\n const verified = sources.every(\n (s) => existsSync(s.target) && readFileSync(s.target, \"utf-8\") === s.content,\n );\n if (!verified) {\n p.log.error(`Verification failed: ${PI_EXT_DIR} does not match the bundled extension.`);\n return { kind: \"skipped\", reason: \"verification-failed\" };\n }\n\n logInstalled(this.displayName, PI_EXT_DIR);\n p.log.info(\n \"pi auto-discovers the extension on next launch; a running pi picks it up with /reload. Verify with /agentmemory-status.\",\n );\n return { kind: \"installed\", mutatedPath: PI_EXT_DIR, backupPath };\n },\n};\n","import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { createJsonMcpAdapter } from \"./json-mcp-adapter.js\";\n\n// Qwen Code stores its settings (mcpServers + hooks) in\n// ~/.qwen/settings.json. Schema for mcpServers matches Claude Code's\n// shape, so the shared JSON adapter handles the wiring.\n// Source: qwenlm.github.io/qwen-code-docs/en/users/features/mcp\nexport const adapter = createJsonMcpAdapter({\n name: \"qwen\",\n displayName: \"Qwen Code\",\n detectDir: join(homedir(), \".qwen\"),\n configPath: join(homedir(), \".qwen\", \"settings.json\"),\n docs: \"https://github.com/rohitg00/agentmemory#other-agents\",\n protocolNote:\n \"→ Using MCP via ~/.qwen/settings.json. Qwen Code's hook system can also be wired separately — see docs.\",\n});\n","import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { createJsonMcpAdapter } from \"./json-mcp-adapter.js\";\n\n// Warp stores MCP server config at ~/.warp/.mcp.json with the\n// canonical `mcpServers` wrapper — identical schema to Claude Code.\n// Warp also auto-discovers skills from .claude/skills/ so the\n// agentmemory plugin's 8 skills are surfaced natively once the\n// Claude Code plugin is installed.\n// Source: docs.warp.dev/agent-platform/capabilities/mcp/\nexport const adapter = createJsonMcpAdapter({\n name: \"warp\",\n displayName: \"Warp\",\n detectDir: join(homedir(), \".warp\"),\n configPath: join(homedir(), \".warp\", \".mcp.json\"),\n docs: \"https://github.com/rohitg00/agentmemory#other-agents\",\n protocolNote:\n \"→ Using MCP via ~/.warp/.mcp.json. Skills auto-discover from .claude/skills/ if the Claude Code plugin is also installed.\",\n});\n","import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { createJsonMcpAdapter } from \"./json-mcp-adapter.js\";\n\n// Zed stores its settings (including MCP servers) under \"context_servers\"\n// in settings.json — NOT \"mcpServers\". User config lives at\n// ~/.config/zed/settings.json on all platforms (Zed uses the XDG path\n// even on macOS; ~/Library/Application Support/Zed/ holds runtime data\n// like the database + cached language servers, not the config).\n// Source: zed.dev/docs/ai/mcp + zed.dev/docs/configuring-zed\nconst zedConfigDir = join(homedir(), \".config\", \"zed\");\n\nexport const adapter = createJsonMcpAdapter({\n name: \"zed\",\n displayName: \"Zed\",\n detectDir: zedConfigDir,\n configPath: join(zedConfigDir, \"settings.json\"),\n wrapperKey: \"context_servers\",\n docs: \"https://github.com/rohitg00/agentmemory#other-agents\",\n protocolNote:\n \"→ Using MCP via ~/.config/zed/settings.json (key: context_servers).\",\n});\n","import { platform } from \"node:os\";\nimport * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport type { ConnectAdapter, ConnectOptions, ConnectResult } from \"./types.js\";\nimport { writeGuideline } from \"./guidelines.js\";\nimport { adapter as antigravity } from \"./antigravity.js\";\nimport { adapter as antigravityCli } from \"./antigravity-cli.js\";\nimport { adapter as claudeCode } from \"./claude-code.js\";\nimport { adapter as cline } from \"./cline.js\";\nimport { adapter as copilotCli } from \"./copilot-cli.js\";\nimport { adapter as codex } from \"./codex.js\";\nimport { adapter as continueDev } from \"./continue.js\";\nimport { adapter as cursor } from \"./cursor.js\";\nimport { adapter as devin } from \"./devin.js\";\nimport { adapter as droid } from \"./droid.js\";\nimport { adapter as dsh } from \"./dsh.js\";\nimport { adapter as geminiCli } from \"./gemini-cli.js\";\nimport { adapter as hermes } from \"./hermes.js\";\nimport { adapter as kiro } from \"./kiro.js\";\nimport { adapter as openclaw } from \"./openclaw.js\";\nimport { adapter as opencode } from \"./opencode.js\";\nimport { adapter as openhuman } from \"./openhuman.js\";\nimport { adapter as pi } from \"./pi.js\";\nimport { adapter as qwen } from \"./qwen.js\";\nimport { adapter as warp } from \"./warp.js\";\nimport { adapter as zed } from \"./zed.js\";\n\nexport const ADAPTERS: readonly ConnectAdapter[] = [\n claudeCode,\n copilotCli,\n codex,\n cursor,\n devin,\n geminiCli,\n qwen,\n antigravity,\n antigravityCli,\n kiro,\n warp,\n cline,\n continueDev,\n zed,\n droid,\n dsh,\n opencode,\n openclaw,\n hermes,\n pi,\n openhuman,\n];\n\nexport function resolveAdapter(name: string): ConnectAdapter | null {\n const lower = name.toLowerCase();\n return ADAPTERS.find((a) => a.name === lower) ?? null;\n}\n\nexport function knownAgents(): string[] {\n return ADAPTERS.map((a) => a.name);\n}\n\nfunction parseFlags(args: string[]): {\n dryRun: boolean;\n force: boolean;\n all: boolean;\n withHooks: boolean;\n guidelines: boolean;\n positional: string[];\n} {\n const positional: string[] = [];\n let dryRun = false;\n let force = false;\n let all = false;\n let withHooks = false;\n let guidelines = true; // memory-usage guideline is written by default\n for (const a of args) {\n if (a === \"--dry-run\") dryRun = true;\n else if (a === \"--force\") force = true;\n else if (a === \"--all\") all = true;\n else if (a === \"--with-hooks\") withHooks = true;\n else if (a === \"--no-guidelines\") guidelines = false;\n else if (!a.startsWith(\"-\")) positional.push(a);\n }\n return { dryRun, force, all, withHooks, guidelines, positional };\n}\n\nexport async function runAdapter(\n adapter: ConnectAdapter,\n opts: ConnectOptions,\n): Promise<ConnectResult> {\n if (!adapter.detect()) {\n p.log.warn(\n `${adapter.displayName}: not detected on this machine (skipping).${adapter.docs ? ` Docs: ${adapter.docs}` : \"\"}`,\n );\n return { kind: \"skipped\", reason: \"not-detected\" };\n }\n p.log.step(`Wiring ${adapter.displayName}…`);\n if (adapter.protocolNote) {\n p.log.message(adapter.protocolNote);\n }\n try {\n const result = await adapter.install(opts);\n // After MCP/hooks are wired, activate memory for hook-less agents by\n // writing a memory-usage guideline into their native rules file. Best\n // effort: never fail the connect over the guideline.\n if (\n opts.guidelines !== false &&\n (result.kind === \"installed\" || result.kind === \"already-wired\")\n ) {\n try {\n const g = writeGuideline(adapter.name, {\n cwd: process.cwd(),\n dryRun: opts.dryRun,\n });\n if (g.kind === \"written\") {\n p.log.message(\n ` ${pc.dim(\"guideline\")} ${g.scope} → ${g.path} (memory auto-use)`,\n );\n } else if (g.kind === \"would-write\") {\n p.log.message(` ${pc.dim(\"[dry-run] guideline\")} → ${g.path}`);\n }\n } catch (gerr) {\n p.log.warn(\n `${adapter.displayName}: guideline not written (${gerr instanceof Error ? gerr.message : String(gerr)})`,\n );\n }\n }\n return result;\n } catch (err) {\n p.log.error(\n `${adapter.displayName}: ${err instanceof Error ? err.message : String(err)}`,\n );\n return { kind: \"skipped\", reason: \"exception\" };\n }\n}\n\nexport async function runConnect(args: string[]): Promise<void> {\n const { dryRun, force, all, withHooks, guidelines, positional } =\n parseFlags(args);\n const allowWindowsAdapter =\n positional.length === 1 && positional[0]?.toLowerCase() === \"copilot-cli\";\n if (platform() === \"win32\" && !allowWindowsAdapter) {\n p.intro(\"agentmemory connect\");\n p.log.warn(\n \"Windows: automated `connect` is not supported yet. See https://github.com/rohitg00/agentmemory#other-agents for manual install steps.\",\n );\n p.outro(\"Windows: manual install required — see docs\");\n return;\n }\n\n const opts: ConnectOptions = { dryRun, force, withHooks, guidelines };\n\n p.intro(\"agentmemory connect\");\n\n if (positional.length === 0 && !all) {\n const detected = ADAPTERS.filter((a) => a.detect());\n if (detected.length === 0) {\n p.log.error(\"No supported agents detected on this machine.\");\n p.outro(`Supported: ${knownAgents().join(\", \")}`);\n process.exit(1);\n }\n const picked = await p.multiselect<string>({\n message: \"Wire agentmemory into which agents?\",\n options: detected.map((a) => ({ value: a.name, label: a.displayName })),\n required: true,\n });\n if (p.isCancel(picked)) {\n p.cancel(\"Cancelled.\");\n return;\n }\n const results: { name: string; result: ConnectResult }[] = [];\n for (const name of picked as string[]) {\n const adapter = resolveAdapter(name);\n if (!adapter) continue;\n results.push({ name, result: await runAdapter(adapter, opts) });\n }\n summarize(results);\n return;\n }\n\n if (all) {\n const detected = ADAPTERS.filter((a) => a.detect());\n if (detected.length === 0) {\n p.log.error(\"No supported agents detected on this machine.\");\n process.exit(1);\n }\n const results: { name: string; result: ConnectResult }[] = [];\n for (const adapter of detected) {\n results.push({\n name: adapter.name,\n result: await runAdapter(adapter, opts),\n });\n }\n summarize(results);\n return;\n }\n\n const agentName = positional[0]!;\n const adapter = resolveAdapter(agentName);\n if (!adapter) {\n p.log.error(`Unknown agent: ${agentName}`);\n p.outro(`Supported: ${knownAgents().join(\", \")}`);\n process.exit(1);\n }\n\n const result = await runAdapter(adapter, opts);\n summarize([{ name: agentName, result }]);\n if (result.kind === \"skipped\" && (result as { reason: string }).reason !== \"not-detected\") {\n process.exit(1);\n }\n}\n\nfunction summarize(\n results: { name: string; result: ConnectResult }[],\n): void {\n const lines = results.map(({ name, result }) => {\n switch (result.kind) {\n case \"installed\":\n return ` ${pc.green(\"✓\")} ${pc.bold(name)}${result.mutatedPath ? ` ${pc.dim(\"→\")} ${pc.cyan(result.mutatedPath)}` : \"\"}`;\n case \"already-wired\":\n return ` ${pc.green(\"✓\")} ${pc.bold(name)} ${pc.dim(\"(already wired)\")}`;\n case \"stub\":\n return ` ${pc.yellow(\"⚠\")} ${pc.bold(name)} ${pc.yellow(`(manual install required: ${result.reason})`)}`;\n case \"skipped\":\n return ` ${pc.red(\"✗\")} ${pc.bold(name)} ${pc.dim(`(skipped: ${result.reason})`)}`;\n }\n });\n p.note(lines.join(\"\\n\"), \"summary\");\n\n const stubs = results.filter((r) => r.result.kind === \"stub\");\n if (stubs.length > 0) {\n p.log.info(\n `${stubs.length} agent(s) require manual install — see docs links above.`,\n );\n }\n\n const wiredAny = results.some(\n (r) => r.result.kind === \"installed\" || r.result.kind === \"already-wired\",\n );\n if (wiredAny) {\n p.log.info(\n \"Next: install agentmemory's 17 skills into the same agent(s) so they know when to call the tools:\\n npx skills add rohitg00/agentmemory -y\",\n );\n }\n\n p.outro(\"Restart any wired agent (or open a new session) to pick up agentmemory.\");\n}\n"],"mappings":"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"}
@@ -8,34 +8,60 @@ services:
8
8
  iii-init:
9
9
  image: busybox:1.36
10
10
  user: "0:0"
11
+ environment:
12
+ AGENTMEMORY_DOCKER_UID: "${AGENTMEMORY_DOCKER_UID:-65532}"
13
+ AGENTMEMORY_DOCKER_GID: "${AGENTMEMORY_DOCKER_GID:-65532}"
14
+ AGENTMEMORY_DOCKER_SKIP_CHOWN: "${AGENTMEMORY_DOCKER_SKIP_CHOWN:-0}"
11
15
  volumes:
12
- - iii-data:/data
13
- entrypoint: ["sh", "-c", "chown -R 65532:65532 /data && chmod 755 /data"]
16
+ - "${AGENTMEMORY_DATA_DIR:-iii-data}:/data"
17
+ entrypoint: ["sh", "-c", "if [ \"$${AGENTMEMORY_DOCKER_SKIP_CHOWN}\" = \"1\" ]; then exit 0; fi; chown -R $${AGENTMEMORY_DOCKER_UID}:$${AGENTMEMORY_DOCKER_GID} /data && chmod 755 /data"]
14
18
  restart: "no"
15
19
 
16
20
  iii-engine:
17
- # Pinned to v0.11.2 — the last engine that runs agentmemory's current
18
- # worker model cleanly. v0.11.6 introduces a new sandbox-everything-
19
- # via-`iii worker add` model that agentmemory hasn't been refactored
20
- # for yet; the architectural mismatch surfaces as EPIPE reconnect
21
- # loops and empty search after save. Bump only after agentmemory is
22
- # refactored to register as a sandboxed worker.
21
+ # Pinned to the same release as agentmemory's iii-sdk dependency
22
+ # (package.json). The worker speaks this engine's wire protocol, so
23
+ # bump the image tag and the SDK together, never one of them alone.
24
+ # 0.22.x is the last line before 0.23 removes the config.yaml worker
25
+ # lifecycle; it keeps HTTP routes owned by the reconnecting worker.
23
26
  #
24
27
  # Override per-shell or via .env file:
25
- # AGENTMEMORY_III_VERSION=0.11.7 docker compose up
26
- image: iiidev/iii:${AGENTMEMORY_III_VERSION:-0.11.2}
27
- user: "65532:65532"
28
+ # AGENTMEMORY_III_VERSION=0.22.1 docker compose up
29
+ image: iiidev/iii:${AGENTMEMORY_III_VERSION:-0.22.1}
30
+ user: "${AGENTMEMORY_DOCKER_UID:-65532}:${AGENTMEMORY_DOCKER_GID:-65532}"
28
31
  depends_on:
29
32
  iii-init:
30
33
  condition: service_completed_successfully
34
+ command: ["--config", "/app/config.yaml", "--no-update-check"]
35
+ environment:
36
+ III_TELEMETRY_ENABLED: "${III_TELEMETRY_ENABLED:-false}"
37
+ III_REST_PORT: "${III_REST_PORT:-3111}"
38
+ III_STREAM_PORT: "${III_STREAM_PORT:-3112}"
39
+ III_VIEWER_PORT: "${III_VIEWER_PORT:-3113}"
40
+ III_ENGINE_PORT: "${III_ENGINE_PORT:-49134}"
41
+ AGENTMEMORY_REDIS_URL: "${AGENTMEMORY_REDIS_URL:-}"
42
+ AGENTMEMORY_STATE_SAVE_INTERVAL_MS: "${AGENTMEMORY_STATE_SAVE_INTERVAL_MS:-2000}"
43
+ MALLOC_ARENA_MAX: "${MALLOC_ARENA_MAX:-2}"
44
+ ulimits:
45
+ nofile:
46
+ soft: 10240
47
+ hard: 10240
31
48
  ports:
32
- - "127.0.0.1:49134:49134"
33
- - "127.0.0.1:3111:3111"
34
- - "127.0.0.1:3112:3112"
35
- - "127.0.0.1:9464:9464"
49
+ - "127.0.0.1:${III_ENGINE_PORT:-49134}:${III_ENGINE_PORT:-49134}"
50
+ - "127.0.0.1:${III_REST_PORT:-3111}:${III_REST_PORT:-3111}"
51
+ - "127.0.0.1:${III_STREAM_PORT:-3112}:${III_STREAM_PORT:-3112}"
52
+ - "127.0.0.1:${AGENTMEMORY_METRICS_PORT:-9464}:9464"
36
53
  volumes:
37
- - iii-data:/data
54
+ - "${AGENTMEMORY_DATA_DIR:-iii-data}:/data"
38
55
  - ./iii-config.docker.yaml:/app/config.yaml:ro
56
+ # The engine persists each builtin worker's seeded config block under
57
+ # config/ next to its config file (/app/config in the image) on first
58
+ # boot and treats that copy as the source of truth afterwards. Keeping
59
+ # it on a tmpfs means every container start re-seeds from config.yaml
60
+ # and the III_* env vars, the same behavior the native CLI path has.
61
+ - type: tmpfs
62
+ target: /app/config
63
+ tmpfs:
64
+ mode: 01777
39
65
  restart: unless-stopped
40
66
  logging:
41
67
  driver: json-file
@@ -0,0 +1,22 @@
1
+ //#region src/hooks/_capture.d.ts
2
+ declare const REST_URL: string;
3
+ type CaptureOutcome = "delivered" | "duplicate" | "rejected" | "spooled" | "dropped";
4
+ interface ObserveBody {
5
+ hookType: string;
6
+ sessionId: string;
7
+ project: string;
8
+ cwd: string;
9
+ timestamp: string;
10
+ data: unknown;
11
+ eventId?: string;
12
+ }
13
+ declare function authHeaders(): Record<string, string>;
14
+ declare function withEventId(body: ObserveBody, host: Record<string, unknown>, content?: unknown, options?: {
15
+ stable?: boolean;
16
+ }): ObserveBody;
17
+ declare function captureObservation(body: ObserveBody, timeoutMs: number): Promise<CaptureOutcome>;
18
+ declare function isDrainChild(): boolean;
19
+ declare function runDrainChild(): Promise<void>;
20
+ //#endregion
21
+ export { CaptureOutcome, ObserveBody, REST_URL, authHeaders, captureObservation, isDrainChild, runDrainChild, withEventId };
22
+ //# sourceMappingURL=_capture.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_capture.d.mts","names":[],"sources":["../../src/hooks/_capture.ts"],"mappings":";cAgBa,QAAA;AAAA,KAOD,cAAA;AAAA,UAEK,WAAA;EACf,QAAA;EACA,SAAA;EACA,OAAA;EACA,GAAA;EACA,SAAA;EACA,IAAA;EACA,OAAA;AAAA;AAAA,iBAGc,WAAA,CAAA,GAAe,MAAA;AAAA,iBAMf,WAAA,CACd,IAAA,EAAM,WAAA,EACN,IAAA,EAAM,MAAA,mBACN,OAAA,YACA,OAAA;EAAW,MAAA;AAAA,IACV,WAAA;AAAA,iBAoDmB,kBAAA,CAAmB,IAAA,EAAM,WAAA,EAAa,SAAA,WAAoB,OAAA,CAAQ,cAAA;AAAA,iBAmBxE,YAAA,CAAA;AAAA,iBAIM,aAAA,CAAA,GAAiB,OAAA"}