@agentmemory/agentmemory 0.9.29 → 0.9.31
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.
- package/.env.example +102 -35
- package/AGENTS.md +19 -26
- package/README.md +417 -525
- package/dist/.env.example +102 -35
- package/dist/cli.d.mts.map +1 -1
- package/dist/cli.mjs +2316 -655
- package/dist/cli.mjs.map +1 -1
- package/dist/compression-recovery-CnhLQC6N.mjs +5912 -0
- package/dist/compression-recovery-CnhLQC6N.mjs.map +1 -0
- package/dist/{connect-Qaeq15TQ.mjs → connect-BSLIAMpw.mjs} +900 -302
- package/dist/connect-BSLIAMpw.mjs.map +1 -0
- package/dist/hooks/_capture.d.mts +25 -0
- package/dist/hooks/_capture.d.mts.map +1 -0
- package/dist/hooks/_capture.mjs +944 -0
- package/dist/hooks/_capture.mjs.map +1 -0
- package/dist/hooks/antigravity-bridge.d.mts +1 -1
- package/dist/hooks/antigravity-bridge.d.mts.map +1 -1
- package/dist/hooks/antigravity-bridge.mjs +24 -15
- package/dist/hooks/antigravity-bridge.mjs.map +1 -1
- package/dist/hooks/notification.mjs +35 -29
- package/dist/hooks/notification.mjs.map +1 -1
- package/dist/hooks/post-commit.mjs +91 -1
- package/dist/hooks/post-commit.mjs.map +1 -1
- package/dist/hooks/post-tool-failure.mjs +71 -29
- package/dist/hooks/post-tool-failure.mjs.map +1 -1
- package/dist/hooks/post-tool-use.mjs +99 -39
- package/dist/hooks/post-tool-use.mjs.map +1 -1
- package/dist/hooks/pre-compact.mjs +113 -6
- package/dist/hooks/pre-compact.mjs.map +1 -1
- package/dist/hooks/pre-tool-use.mjs +91 -1
- package/dist/hooks/pre-tool-use.mjs.map +1 -1
- package/dist/hooks/prompt-submit.mjs +25 -25
- package/dist/hooks/prompt-submit.mjs.map +1 -1
- package/dist/hooks/session-end.mjs +67 -31
- package/dist/hooks/session-end.mjs.map +1 -1
- package/dist/hooks/session-start.mjs +110 -6
- package/dist/hooks/session-start.mjs.map +1 -1
- package/dist/hooks/stop.mjs +80 -8
- package/dist/hooks/stop.mjs.map +1 -1
- package/dist/hooks/subagent-start.mjs +28 -29
- package/dist/hooks/subagent-start.mjs.map +1 -1
- package/dist/hooks/subagent-stop.mjs +33 -29
- package/dist/hooks/subagent-stop.mjs.map +1 -1
- package/dist/hooks/task-completed.mjs +31 -31
- package/dist/hooks/task-completed.mjs.map +1 -1
- package/dist/{image-refs-BKLmp_sD.mjs → image-refs-BaT-9oMU.mjs} +2 -2
- package/dist/image-refs-BaT-9oMU.mjs.map +1 -0
- package/dist/{image-refs-CJgZmb9X.mjs → image-refs-Cyta4Lf9.mjs} +3 -3
- package/dist/image-refs-Cyta4Lf9.mjs.map +1 -0
- package/dist/{keyed-mutex-DTHtcZrt.mjs → image-store-BsN4vyjr.mjs} +2 -14
- package/dist/image-store-BsN4vyjr.mjs.map +1 -0
- package/dist/index.mjs +15180 -4119
- package/dist/index.mjs.map +1 -1
- package/dist/integrations/dsh.d.mts +55 -0
- package/dist/integrations/dsh.d.mts.map +1 -0
- package/dist/integrations/dsh.mjs +1145 -0
- package/dist/integrations/dsh.mjs.map +1 -0
- package/dist/{schema-BFZhNTF7.mjs → keyed-mutex-DCUh7PG-.mjs} +81 -8
- package/dist/keyed-mutex-DCUh7PG-.mjs.map +1 -0
- package/dist/secret-store-D9GwO0xp.mjs +2449 -0
- package/dist/secret-store-D9GwO0xp.mjs.map +1 -0
- package/dist/session-arguments-zxsbbd8y.mjs +113 -0
- package/dist/session-arguments-zxsbbd8y.mjs.map +1 -0
- package/dist/{src-G7yt8gGm.mjs → src-DaMtDzt_.mjs} +8320 -4260
- package/dist/src-DaMtDzt_.mjs.map +1 -0
- package/dist/{standalone-BqNJDJ04.mjs → standalone-BlqshyZ5.mjs} +246 -62
- package/dist/standalone-BlqshyZ5.mjs.map +1 -0
- package/dist/standalone.d.mts +1 -1
- package/dist/standalone.d.mts.map +1 -1
- package/dist/standalone.mjs +866 -78
- package/dist/standalone.mjs.map +1 -1
- package/dist/viewer/index.html +7394 -2816
- package/integrations/hermes/README.md +84 -0
- package/integrations/hermes/__init__.py +669 -0
- package/integrations/hermes/plugin.yaml +27 -0
- package/integrations/omp/LICENSE +190 -0
- package/integrations/omp/README.md +76 -0
- package/integrations/omp/capture.ts +1 -0
- package/integrations/omp/dist/index.mjs +1450 -0
- package/integrations/omp/index.ts +488 -0
- package/integrations/omp/package.json +13 -0
- package/integrations/omp/security.ts +67 -0
- package/integrations/omp/skills/agentmemory-agents/REFERENCE.md +32 -0
- package/integrations/omp/skills/agentmemory-agents/SKILL.md +48 -0
- package/integrations/omp/skills/agentmemory-agents/TROUBLESHOOTING.md +70 -0
- package/integrations/omp/skills/agentmemory-architecture/SKILL.md +33 -0
- package/integrations/omp/skills/agentmemory-architecture/TROUBLESHOOTING.md +70 -0
- package/integrations/omp/skills/agentmemory-config/REFERENCE.md +90 -0
- package/integrations/omp/skills/agentmemory-config/SKILL.md +78 -0
- package/integrations/omp/skills/agentmemory-config/TROUBLESHOOTING.md +70 -0
- package/integrations/omp/skills/agentmemory-hooks/REFERENCE.md +20 -0
- package/integrations/omp/skills/agentmemory-hooks/SKILL.md +49 -0
- package/integrations/omp/skills/agentmemory-hooks/TROUBLESHOOTING.md +70 -0
- package/integrations/omp/skills/agentmemory-mcp-tools/REFERENCE.md +66 -0
- package/integrations/omp/skills/agentmemory-mcp-tools/SKILL.md +42 -0
- package/integrations/omp/skills/agentmemory-mcp-tools/TROUBLESHOOTING.md +70 -0
- package/integrations/omp/skills/agentmemory-rest-api/REFERENCE.md +158 -0
- package/integrations/omp/skills/agentmemory-rest-api/SKILL.md +49 -0
- package/integrations/omp/skills/agentmemory-rest-api/TROUBLESHOOTING.md +70 -0
- package/integrations/omp/skills/commit-context/EXAMPLES.md +71 -0
- package/integrations/omp/skills/commit-context/SKILL.md +64 -0
- package/integrations/omp/skills/commit-context/TROUBLESHOOTING.md +70 -0
- package/integrations/omp/skills/commit-history/EXAMPLES.md +71 -0
- package/integrations/omp/skills/commit-history/SKILL.md +62 -0
- package/integrations/omp/skills/commit-history/TROUBLESHOOTING.md +70 -0
- package/integrations/omp/skills/forget/EXAMPLES.md +40 -0
- package/integrations/omp/skills/forget/SKILL.md +73 -0
- package/integrations/omp/skills/forget/TROUBLESHOOTING.md +70 -0
- package/integrations/omp/skills/handoff/EXAMPLES.md +57 -0
- package/integrations/omp/skills/handoff/SKILL.md +75 -0
- package/integrations/omp/skills/handoff/TROUBLESHOOTING.md +70 -0
- package/integrations/omp/skills/lesson/SKILL.md +64 -0
- package/integrations/omp/skills/lesson/TROUBLESHOOTING.md +70 -0
- package/integrations/omp/skills/memory-discipline/SKILL.md +65 -0
- package/integrations/omp/skills/memory-discipline/TROUBLESHOOTING.md +70 -0
- package/integrations/omp/skills/recall/EXAMPLES.md +74 -0
- package/integrations/omp/skills/recall/SKILL.md +74 -0
- package/integrations/omp/skills/recall/TROUBLESHOOTING.md +70 -0
- package/integrations/omp/skills/recap/EXAMPLES.md +62 -0
- package/integrations/omp/skills/recap/SKILL.md +68 -0
- package/integrations/omp/skills/recap/TROUBLESHOOTING.md +70 -0
- package/integrations/omp/skills/remember/EXAMPLES.md +67 -0
- package/integrations/omp/skills/remember/SKILL.md +66 -0
- package/integrations/omp/skills/remember/TROUBLESHOOTING.md +70 -0
- package/integrations/omp/skills/session-history/EXAMPLES.md +59 -0
- package/integrations/omp/skills/session-history/SKILL.md +67 -0
- package/integrations/omp/skills/session-history/TROUBLESHOOTING.md +70 -0
- package/integrations/omp/skills/write-agentmemory-skill/SKILL.md +41 -0
- package/integrations/omp/skills/write-agentmemory-skill/TROUBLESHOOTING.md +70 -0
- package/integrations/openclaw/LICENSE +190 -0
- package/integrations/openclaw/README.md +88 -0
- package/integrations/openclaw/openclaw.plugin.json +71 -0
- package/integrations/openclaw/package.json +38 -0
- package/integrations/openclaw/plugin.mjs +425 -0
- package/integrations/openclaw/plugin.yaml +26 -0
- package/integrations/openclaw/skills/agentmemory-agents/REFERENCE.md +32 -0
- package/integrations/openclaw/skills/agentmemory-agents/SKILL.md +48 -0
- package/integrations/openclaw/skills/agentmemory-agents/TROUBLESHOOTING.md +70 -0
- package/integrations/openclaw/skills/agentmemory-architecture/SKILL.md +33 -0
- package/integrations/openclaw/skills/agentmemory-architecture/TROUBLESHOOTING.md +70 -0
- package/integrations/openclaw/skills/agentmemory-config/REFERENCE.md +90 -0
- package/integrations/openclaw/skills/agentmemory-config/SKILL.md +78 -0
- package/integrations/openclaw/skills/agentmemory-config/TROUBLESHOOTING.md +70 -0
- package/integrations/openclaw/skills/agentmemory-hooks/REFERENCE.md +20 -0
- package/integrations/openclaw/skills/agentmemory-hooks/SKILL.md +49 -0
- package/integrations/openclaw/skills/agentmemory-hooks/TROUBLESHOOTING.md +70 -0
- package/integrations/openclaw/skills/agentmemory-mcp-tools/REFERENCE.md +66 -0
- package/integrations/openclaw/skills/agentmemory-mcp-tools/SKILL.md +42 -0
- package/integrations/openclaw/skills/agentmemory-mcp-tools/TROUBLESHOOTING.md +70 -0
- package/integrations/openclaw/skills/agentmemory-rest-api/REFERENCE.md +158 -0
- package/integrations/openclaw/skills/agentmemory-rest-api/SKILL.md +49 -0
- package/integrations/openclaw/skills/agentmemory-rest-api/TROUBLESHOOTING.md +70 -0
- package/integrations/openclaw/skills/commit-context/EXAMPLES.md +71 -0
- package/integrations/openclaw/skills/commit-context/SKILL.md +64 -0
- package/integrations/openclaw/skills/commit-context/TROUBLESHOOTING.md +70 -0
- package/integrations/openclaw/skills/commit-history/EXAMPLES.md +71 -0
- package/integrations/openclaw/skills/commit-history/SKILL.md +62 -0
- package/integrations/openclaw/skills/commit-history/TROUBLESHOOTING.md +70 -0
- package/integrations/openclaw/skills/forget/EXAMPLES.md +40 -0
- package/integrations/openclaw/skills/forget/SKILL.md +73 -0
- package/integrations/openclaw/skills/forget/TROUBLESHOOTING.md +70 -0
- package/integrations/openclaw/skills/handoff/EXAMPLES.md +57 -0
- package/integrations/openclaw/skills/handoff/SKILL.md +75 -0
- package/integrations/openclaw/skills/handoff/TROUBLESHOOTING.md +70 -0
- package/integrations/openclaw/skills/lesson/SKILL.md +64 -0
- package/integrations/openclaw/skills/lesson/TROUBLESHOOTING.md +70 -0
- package/integrations/openclaw/skills/memory-discipline/SKILL.md +65 -0
- package/integrations/openclaw/skills/memory-discipline/TROUBLESHOOTING.md +70 -0
- package/integrations/openclaw/skills/recall/EXAMPLES.md +74 -0
- package/integrations/openclaw/skills/recall/SKILL.md +74 -0
- package/integrations/openclaw/skills/recall/TROUBLESHOOTING.md +70 -0
- package/integrations/openclaw/skills/recap/EXAMPLES.md +62 -0
- package/integrations/openclaw/skills/recap/SKILL.md +68 -0
- package/integrations/openclaw/skills/recap/TROUBLESHOOTING.md +70 -0
- package/integrations/openclaw/skills/remember/EXAMPLES.md +67 -0
- package/integrations/openclaw/skills/remember/SKILL.md +66 -0
- package/integrations/openclaw/skills/remember/TROUBLESHOOTING.md +70 -0
- package/integrations/openclaw/skills/session-history/EXAMPLES.md +59 -0
- package/integrations/openclaw/skills/session-history/SKILL.md +67 -0
- package/integrations/openclaw/skills/session-history/TROUBLESHOOTING.md +70 -0
- package/integrations/openclaw/skills/write-agentmemory-skill/SKILL.md +41 -0
- package/integrations/openclaw/skills/write-agentmemory-skill/TROUBLESHOOTING.md +70 -0
- package/integrations/pi/LICENSE +190 -0
- package/integrations/pi/README.md +45 -51
- package/integrations/pi/dist/index.mjs +1379 -0
- package/integrations/pi/index.ts +139 -173
- package/integrations/pi/package.json +16 -6
- package/integrations/pi/security.ts +54 -22
- package/integrations/pi/skills/agentmemory-agents/REFERENCE.md +32 -0
- package/integrations/pi/skills/agentmemory-agents/SKILL.md +48 -0
- package/integrations/pi/skills/agentmemory-agents/TROUBLESHOOTING.md +70 -0
- package/integrations/pi/skills/agentmemory-architecture/SKILL.md +33 -0
- package/integrations/pi/skills/agentmemory-architecture/TROUBLESHOOTING.md +70 -0
- package/integrations/pi/skills/agentmemory-config/REFERENCE.md +90 -0
- package/integrations/pi/skills/agentmemory-config/SKILL.md +78 -0
- package/integrations/pi/skills/agentmemory-config/TROUBLESHOOTING.md +70 -0
- package/integrations/pi/skills/agentmemory-hooks/REFERENCE.md +20 -0
- package/integrations/pi/skills/agentmemory-hooks/SKILL.md +49 -0
- package/integrations/pi/skills/agentmemory-hooks/TROUBLESHOOTING.md +70 -0
- package/integrations/pi/skills/agentmemory-mcp-tools/REFERENCE.md +66 -0
- package/integrations/pi/skills/agentmemory-mcp-tools/SKILL.md +42 -0
- package/integrations/pi/skills/agentmemory-mcp-tools/TROUBLESHOOTING.md +70 -0
- package/integrations/pi/skills/agentmemory-rest-api/REFERENCE.md +158 -0
- package/integrations/pi/skills/agentmemory-rest-api/SKILL.md +49 -0
- package/integrations/pi/skills/agentmemory-rest-api/TROUBLESHOOTING.md +70 -0
- package/integrations/pi/skills/commit-context/EXAMPLES.md +71 -0
- package/integrations/pi/skills/commit-context/SKILL.md +64 -0
- package/integrations/pi/skills/commit-context/TROUBLESHOOTING.md +70 -0
- package/integrations/pi/skills/commit-history/EXAMPLES.md +71 -0
- package/integrations/pi/skills/commit-history/SKILL.md +62 -0
- package/integrations/pi/skills/commit-history/TROUBLESHOOTING.md +70 -0
- package/integrations/pi/skills/forget/EXAMPLES.md +40 -0
- package/integrations/pi/skills/forget/SKILL.md +73 -0
- package/integrations/pi/skills/forget/TROUBLESHOOTING.md +70 -0
- package/integrations/pi/skills/handoff/EXAMPLES.md +57 -0
- package/integrations/pi/skills/handoff/SKILL.md +75 -0
- package/integrations/pi/skills/handoff/TROUBLESHOOTING.md +70 -0
- package/integrations/pi/skills/lesson/SKILL.md +64 -0
- package/integrations/pi/skills/lesson/TROUBLESHOOTING.md +70 -0
- package/integrations/pi/skills/memory-discipline/SKILL.md +65 -0
- package/integrations/pi/skills/memory-discipline/TROUBLESHOOTING.md +70 -0
- package/integrations/pi/skills/recall/EXAMPLES.md +74 -0
- package/integrations/pi/skills/recall/SKILL.md +74 -0
- package/integrations/pi/skills/recall/TROUBLESHOOTING.md +70 -0
- package/integrations/pi/skills/recap/EXAMPLES.md +62 -0
- package/integrations/pi/skills/recap/SKILL.md +68 -0
- package/integrations/pi/skills/recap/TROUBLESHOOTING.md +70 -0
- package/integrations/pi/skills/remember/EXAMPLES.md +67 -0
- package/integrations/pi/skills/remember/SKILL.md +66 -0
- package/integrations/pi/skills/remember/TROUBLESHOOTING.md +70 -0
- package/integrations/pi/skills/session-history/EXAMPLES.md +59 -0
- package/integrations/pi/skills/session-history/SKILL.md +67 -0
- package/integrations/pi/skills/session-history/TROUBLESHOOTING.md +70 -0
- package/integrations/pi/skills/write-agentmemory-skill/SKILL.md +41 -0
- package/integrations/pi/skills/write-agentmemory-skill/TROUBLESHOOTING.md +70 -0
- package/package.json +42 -12
- package/plugin/.claude-plugin/plugin.json +2 -2
- package/plugin/.codex-plugin/plugin.json +27 -4
- package/plugin/.devin-plugin/plugin.json +5 -3
- package/plugin/.mcp.codex.json +12 -0
- package/plugin/.mcp.copilot.json +2 -7
- package/plugin/.mcp.json +2 -7
- package/plugin/assets/icon.svg +35 -0
- package/plugin/cursor/hooks.json +23 -8
- package/plugin/hooks/hooks.copilot.json +11 -11
- package/plugin/hooks.json +67 -0
- package/plugin/opencode/README.md +267 -31
- package/plugin/opencode/agentmemory-capture.ts +594 -11
- package/plugin/opencode/plugin.json +1 -1
- package/plugin/plugin.json +1 -1
- package/plugin/scripts/_capture.d.mts +25 -0
- package/plugin/scripts/_capture.d.mts.map +1 -0
- package/plugin/scripts/_capture.mjs +944 -0
- package/plugin/scripts/_capture.mjs.map +1 -0
- package/plugin/scripts/antigravity-bridge.d.mts +1 -1
- package/plugin/scripts/antigravity-bridge.d.mts.map +1 -1
- package/plugin/scripts/antigravity-bridge.mjs +24 -15
- package/plugin/scripts/antigravity-bridge.mjs.map +1 -1
- package/plugin/scripts/cursor/run-detached.d.mts +1 -0
- package/plugin/scripts/cursor/run-detached.mjs +786 -0
- package/plugin/scripts/cursor/run-detached.mjs.map +1 -0
- package/plugin/scripts/cursor/run-hook.d.mts +1 -0
- package/plugin/scripts/cursor/run-hook.mjs +704 -0
- package/plugin/scripts/cursor/run-hook.mjs.map +1 -0
- package/plugin/scripts/notification.mjs +35 -29
- package/plugin/scripts/notification.mjs.map +1 -1
- package/plugin/scripts/plugin-bridge.mjs +409 -0
- package/plugin/scripts/post-commit.mjs +91 -1
- package/plugin/scripts/post-commit.mjs.map +1 -1
- package/plugin/scripts/post-tool-failure.mjs +71 -29
- package/plugin/scripts/post-tool-failure.mjs.map +1 -1
- package/plugin/scripts/post-tool-use.mjs +99 -39
- package/plugin/scripts/post-tool-use.mjs.map +1 -1
- package/plugin/scripts/pre-compact.mjs +113 -6
- package/plugin/scripts/pre-compact.mjs.map +1 -1
- package/plugin/scripts/pre-tool-use.mjs +91 -1
- package/plugin/scripts/pre-tool-use.mjs.map +1 -1
- package/plugin/scripts/prompt-submit.mjs +25 -25
- package/plugin/scripts/prompt-submit.mjs.map +1 -1
- package/plugin/scripts/session-end.mjs +67 -31
- package/plugin/scripts/session-end.mjs.map +1 -1
- package/plugin/scripts/session-start.mjs +110 -6
- package/plugin/scripts/session-start.mjs.map +1 -1
- package/plugin/scripts/stop.mjs +80 -8
- package/plugin/scripts/stop.mjs.map +1 -1
- package/plugin/scripts/subagent-start.mjs +28 -29
- package/plugin/scripts/subagent-start.mjs.map +1 -1
- package/plugin/scripts/subagent-stop.mjs +33 -29
- package/plugin/scripts/subagent-stop.mjs.map +1 -1
- package/plugin/scripts/task-completed.mjs +31 -31
- package/plugin/scripts/task-completed.mjs.map +1 -1
- package/plugin/skills/_shared/TROUBLESHOOTING.md +42 -12
- package/plugin/skills/agentmemory-agents/REFERENCE.md +10 -9
- package/plugin/skills/agentmemory-agents/SKILL.md +19 -5
- package/plugin/skills/agentmemory-agents/TROUBLESHOOTING.md +70 -0
- package/plugin/skills/agentmemory-architecture/SKILL.md +4 -4
- package/plugin/skills/agentmemory-architecture/TROUBLESHOOTING.md +70 -0
- package/plugin/skills/agentmemory-config/REFERENCE.md +48 -3
- package/plugin/skills/agentmemory-config/SKILL.md +51 -10
- package/plugin/skills/agentmemory-config/TROUBLESHOOTING.md +70 -0
- package/plugin/skills/agentmemory-hooks/SKILL.md +15 -5
- package/plugin/skills/agentmemory-hooks/TROUBLESHOOTING.md +70 -0
- package/plugin/skills/agentmemory-mcp-tools/REFERENCE.md +5 -5
- package/plugin/skills/agentmemory-mcp-tools/SKILL.md +6 -3
- package/plugin/skills/agentmemory-mcp-tools/TROUBLESHOOTING.md +70 -0
- package/plugin/skills/agentmemory-rest-api/REFERENCE.md +18 -2
- package/plugin/skills/agentmemory-rest-api/SKILL.md +12 -6
- package/plugin/skills/agentmemory-rest-api/TROUBLESHOOTING.md +70 -0
- package/plugin/skills/commit-context/SKILL.md +1 -1
- package/plugin/skills/commit-context/TROUBLESHOOTING.md +70 -0
- package/plugin/skills/commit-history/SKILL.md +1 -1
- package/plugin/skills/commit-history/TROUBLESHOOTING.md +70 -0
- package/plugin/skills/forget/EXAMPLES.md +19 -54
- package/plugin/skills/forget/SKILL.md +16 -12
- package/plugin/skills/forget/TROUBLESHOOTING.md +70 -0
- package/plugin/skills/handoff/EXAMPLES.md +5 -4
- package/plugin/skills/handoff/SKILL.md +13 -6
- package/plugin/skills/handoff/TROUBLESHOOTING.md +70 -0
- package/plugin/skills/lesson/SKILL.md +1 -1
- package/plugin/skills/lesson/TROUBLESHOOTING.md +70 -0
- package/plugin/skills/memory-discipline/SKILL.md +14 -6
- package/plugin/skills/memory-discipline/TROUBLESHOOTING.md +70 -0
- package/plugin/skills/recall/SKILL.md +18 -7
- package/plugin/skills/recall/TROUBLESHOOTING.md +70 -0
- package/plugin/skills/recap/EXAMPLES.md +5 -3
- package/plugin/skills/recap/SKILL.md +11 -6
- package/plugin/skills/recap/TROUBLESHOOTING.md +70 -0
- package/plugin/skills/remember/EXAMPLES.md +3 -3
- package/plugin/skills/remember/SKILL.md +1 -1
- package/plugin/skills/remember/TROUBLESHOOTING.md +70 -0
- package/plugin/skills/session-history/EXAMPLES.md +2 -2
- package/plugin/skills/session-history/SKILL.md +10 -4
- package/plugin/skills/session-history/TROUBLESHOOTING.md +70 -0
- package/plugin/skills/write-agentmemory-skill/SKILL.md +2 -1
- package/plugin/skills/write-agentmemory-skill/TROUBLESHOOTING.md +70 -0
- package/dist/connect-Qaeq15TQ.mjs.map +0 -1
- package/dist/docker-compose.yml +0 -47
- package/dist/iii-config.docker.yaml +0 -53
- package/dist/iii-config.yaml +0 -61
- package/dist/image-refs-BKLmp_sD.mjs.map +0 -1
- package/dist/image-refs-CJgZmb9X.mjs.map +0 -1
- package/dist/keyed-mutex-DTHtcZrt.mjs.map +0 -1
- package/dist/logger-BEB7pCI9.mjs +0 -43
- package/dist/logger-BEB7pCI9.mjs.map +0 -1
- package/dist/schema-BFZhNTF7.mjs.map +0 -1
- package/dist/src-G7yt8gGm.mjs.map +0 -1
- package/dist/standalone-BqNJDJ04.mjs.map +0 -1
- package/dist/tools-registry-BV_2bu7z.mjs +0 -1405
- package/dist/tools-registry-BV_2bu7z.mjs.map +0 -1
- package/docker-compose.yml +0 -47
- package/iii-config.docker.yaml +0 -53
- package/iii-config.yaml +0 -61
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import "node:module";
|
|
2
|
-
import { copyFileSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
3
|
-
import { dirname, join, resolve } from "node:path";
|
|
2
|
+
import { copyFileSync, cpSync, existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { dirname, join, relative, resolve, sep } from "node:path";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
import { homedir, platform } from "node:os";
|
|
6
6
|
import * as p from "@clack/prompts";
|
|
7
7
|
import pc from "picocolors";
|
|
8
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
9
|
+
import { Document, isMap, isSeq, parseDocument } from "yaml";
|
|
10
|
+
import JSON5 from "json5";
|
|
8
11
|
//#region \0rolldown/runtime.js
|
|
9
12
|
var __defProp = Object.defineProperty;
|
|
10
13
|
var __exportAll = (all, no_symbols) => {
|
|
@@ -17,6 +20,91 @@ var __exportAll = (all, no_symbols) => {
|
|
|
17
20
|
return target;
|
|
18
21
|
};
|
|
19
22
|
//#endregion
|
|
23
|
+
//#region src/cli/connect/util.ts
|
|
24
|
+
const AGENTMEMORY_MCP_BLOCK = {
|
|
25
|
+
command: "npx",
|
|
26
|
+
args: ["-y", "@agentmemory/mcp"],
|
|
27
|
+
env: {
|
|
28
|
+
AGENTMEMORY_URL: "${AGENTMEMORY_URL:-http://localhost:3111}",
|
|
29
|
+
AGENTMEMORY_SECRET: "${AGENTMEMORY_SECRET:-}",
|
|
30
|
+
AGENTMEMORY_TOOLS: "${AGENTMEMORY_TOOLS:-all}"
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
const AGENTMEMORY_COPILOT_MCP_BLOCK = {
|
|
34
|
+
type: "local",
|
|
35
|
+
...process.platform === "win32" ? {
|
|
36
|
+
command: process.env["ComSpec"] || process.env["COMSPEC"] || "cmd.exe",
|
|
37
|
+
args: [
|
|
38
|
+
"/d",
|
|
39
|
+
"/s",
|
|
40
|
+
"/c",
|
|
41
|
+
"npx",
|
|
42
|
+
"-y",
|
|
43
|
+
"@agentmemory/mcp"
|
|
44
|
+
]
|
|
45
|
+
} : {
|
|
46
|
+
command: "npx",
|
|
47
|
+
args: ["-y", "@agentmemory/mcp"]
|
|
48
|
+
},
|
|
49
|
+
env: {
|
|
50
|
+
AGENTMEMORY_URL: "${AGENTMEMORY_URL:-http://localhost:3111}",
|
|
51
|
+
AGENTMEMORY_SECRET: "${AGENTMEMORY_SECRET:-}",
|
|
52
|
+
AGENTMEMORY_TOOLS: "${AGENTMEMORY_TOOLS:-all}"
|
|
53
|
+
},
|
|
54
|
+
tools: ["*"]
|
|
55
|
+
};
|
|
56
|
+
function resolveDshHome(home = homedir()) {
|
|
57
|
+
const override = process.env["DSH_HOME"];
|
|
58
|
+
const value = override?.trim() ? override : join(home, ".dsh");
|
|
59
|
+
if (value === "~") return resolve(home);
|
|
60
|
+
if (value.startsWith("~/") || value.startsWith("~\\")) return resolve(join(home, value.slice(2)));
|
|
61
|
+
return resolve(value);
|
|
62
|
+
}
|
|
63
|
+
function backupsDir() {
|
|
64
|
+
return join(homedir(), ".agentmemory", "backups");
|
|
65
|
+
}
|
|
66
|
+
function ensureBackupsDir() {
|
|
67
|
+
const dir = backupsDir();
|
|
68
|
+
mkdirSync(dir, { recursive: true });
|
|
69
|
+
return dir;
|
|
70
|
+
}
|
|
71
|
+
function timestampSlug() {
|
|
72
|
+
return (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
73
|
+
}
|
|
74
|
+
function backupFile(sourcePath, agent, ext = "json") {
|
|
75
|
+
ensureBackupsDir();
|
|
76
|
+
const stamp = timestampSlug();
|
|
77
|
+
const target = join(backupsDir(), `${agent}-${stamp}.${ext}`);
|
|
78
|
+
copyFileSync(sourcePath, target);
|
|
79
|
+
return target;
|
|
80
|
+
}
|
|
81
|
+
function readJsonSafe(path) {
|
|
82
|
+
if (!existsSync(path)) return null;
|
|
83
|
+
try {
|
|
84
|
+
return JSON.parse(readFileSync(path, "utf-8"));
|
|
85
|
+
} catch {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
function writeJsonAtomic(path, value) {
|
|
90
|
+
writeTextAtomic(path, `${JSON.stringify(value, null, 2)}\n`);
|
|
91
|
+
}
|
|
92
|
+
function writeTextAtomic(path, content) {
|
|
93
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
94
|
+
const tmp = `${path}.tmp-${process.pid}-${Date.now()}`;
|
|
95
|
+
writeFileSync(tmp, content, "utf-8");
|
|
96
|
+
renameSync(tmp, path);
|
|
97
|
+
}
|
|
98
|
+
function logInstalled(label, target) {
|
|
99
|
+
p.log.success(`${label} → wired into ${target}`);
|
|
100
|
+
}
|
|
101
|
+
function logAlreadyWired(label, target) {
|
|
102
|
+
p.log.info(`${label} already wired in ${target} (use --force to re-install)`);
|
|
103
|
+
}
|
|
104
|
+
function logBackup(target) {
|
|
105
|
+
p.log.info(`Backup: ${target}`);
|
|
106
|
+
}
|
|
107
|
+
//#endregion
|
|
20
108
|
//#region src/cli/connect/guidelines.ts
|
|
21
109
|
const START = "<!-- agentmemory:start -->";
|
|
22
110
|
const END = "<!-- agentmemory:end -->";
|
|
@@ -95,6 +183,13 @@ function guidelineTargets(home = homedir()) {
|
|
|
95
183
|
scope: "global",
|
|
96
184
|
source: "https://docs.factory.ai/cli/configuration/agents-md"
|
|
97
185
|
},
|
|
186
|
+
dsh: {
|
|
187
|
+
globalPath: join(resolveDshHome(home), "AGENTS.md"),
|
|
188
|
+
projectPath: "AGENTS.md",
|
|
189
|
+
format: "block",
|
|
190
|
+
scope: "global",
|
|
191
|
+
source: "https://github.com/deepseek-ai/deepseek-harness"
|
|
192
|
+
},
|
|
98
193
|
antigravity: {
|
|
99
194
|
globalPath: join(home, ".gemini", "GEMINI.md"),
|
|
100
195
|
projectPath: join(".agents", "rules", "agentmemory.md"),
|
|
@@ -123,7 +218,7 @@ function renderDedicated(format) {
|
|
|
123
218
|
if (format === "steering") return `---\ninclusion: always\n---\n\n${GUIDELINE_BODY}\n`;
|
|
124
219
|
return `${GUIDELINE_BODY}\n`;
|
|
125
220
|
}
|
|
126
|
-
function upsertBlock(existing) {
|
|
221
|
+
function upsertBlock$1(existing) {
|
|
127
222
|
const block = `${START}\n${GUIDELINE_BODY}\n${END}`;
|
|
128
223
|
const startIdx = existing.indexOf(START);
|
|
129
224
|
const endIdx = existing.indexOf(END);
|
|
@@ -137,7 +232,7 @@ function writeGuideline(agentName, opts = { cwd: process.cwd() }) {
|
|
|
137
232
|
const path = target.globalPath ?? join(opts.cwd, target.projectPath);
|
|
138
233
|
const dedicated = target.format !== "block";
|
|
139
234
|
const existing = existsSync(path) ? readFileSync(path, "utf8") : "";
|
|
140
|
-
const next = dedicated ? renderDedicated(target.format) : upsertBlock(existing);
|
|
235
|
+
const next = dedicated ? renderDedicated(target.format) : upsertBlock$1(existing);
|
|
141
236
|
if (existing === next) return {
|
|
142
237
|
kind: "unchanged",
|
|
143
238
|
path,
|
|
@@ -158,84 +253,6 @@ function writeGuideline(agentName, opts = { cwd: process.cwd() }) {
|
|
|
158
253
|
};
|
|
159
254
|
}
|
|
160
255
|
//#endregion
|
|
161
|
-
//#region src/cli/connect/util.ts
|
|
162
|
-
const AGENTMEMORY_MCP_BLOCK = {
|
|
163
|
-
command: "npx",
|
|
164
|
-
args: ["-y", "@agentmemory/mcp"],
|
|
165
|
-
env: {
|
|
166
|
-
AGENTMEMORY_URL: "${AGENTMEMORY_URL:-http://localhost:3111}",
|
|
167
|
-
AGENTMEMORY_SECRET: "${AGENTMEMORY_SECRET:-}",
|
|
168
|
-
AGENTMEMORY_TOOLS: "${AGENTMEMORY_TOOLS:-all}"
|
|
169
|
-
}
|
|
170
|
-
};
|
|
171
|
-
const AGENTMEMORY_COPILOT_MCP_BLOCK = {
|
|
172
|
-
type: "local",
|
|
173
|
-
...process.platform === "win32" ? {
|
|
174
|
-
command: process.env["ComSpec"] || process.env["COMSPEC"] || "cmd.exe",
|
|
175
|
-
args: [
|
|
176
|
-
"/d",
|
|
177
|
-
"/s",
|
|
178
|
-
"/c",
|
|
179
|
-
"npx",
|
|
180
|
-
"-y",
|
|
181
|
-
"@agentmemory/mcp"
|
|
182
|
-
]
|
|
183
|
-
} : {
|
|
184
|
-
command: "npx",
|
|
185
|
-
args: ["-y", "@agentmemory/mcp"]
|
|
186
|
-
},
|
|
187
|
-
env: {
|
|
188
|
-
AGENTMEMORY_URL: "${AGENTMEMORY_URL:-http://localhost:3111}",
|
|
189
|
-
AGENTMEMORY_SECRET: "${AGENTMEMORY_SECRET:-}",
|
|
190
|
-
AGENTMEMORY_TOOLS: "${AGENTMEMORY_TOOLS:-all}"
|
|
191
|
-
},
|
|
192
|
-
tools: ["*"]
|
|
193
|
-
};
|
|
194
|
-
function backupsDir() {
|
|
195
|
-
return join(homedir(), ".agentmemory", "backups");
|
|
196
|
-
}
|
|
197
|
-
function ensureBackupsDir() {
|
|
198
|
-
const dir = backupsDir();
|
|
199
|
-
mkdirSync(dir, { recursive: true });
|
|
200
|
-
return dir;
|
|
201
|
-
}
|
|
202
|
-
function timestampSlug() {
|
|
203
|
-
return (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
204
|
-
}
|
|
205
|
-
function backupFile(sourcePath, agent, ext = "json") {
|
|
206
|
-
ensureBackupsDir();
|
|
207
|
-
const stamp = timestampSlug();
|
|
208
|
-
const target = join(backupsDir(), `${agent}-${stamp}.${ext}`);
|
|
209
|
-
copyFileSync(sourcePath, target);
|
|
210
|
-
return target;
|
|
211
|
-
}
|
|
212
|
-
function readJsonSafe(path) {
|
|
213
|
-
if (!existsSync(path)) return null;
|
|
214
|
-
try {
|
|
215
|
-
return JSON.parse(readFileSync(path, "utf-8"));
|
|
216
|
-
} catch {
|
|
217
|
-
return null;
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
function writeJsonAtomic(path, value) {
|
|
221
|
-
writeTextAtomic(path, `${JSON.stringify(value, null, 2)}\n`);
|
|
222
|
-
}
|
|
223
|
-
function writeTextAtomic(path, content) {
|
|
224
|
-
mkdirSync(dirname(path), { recursive: true });
|
|
225
|
-
const tmp = `${path}.tmp-${process.pid}-${Date.now()}`;
|
|
226
|
-
writeFileSync(tmp, content, "utf-8");
|
|
227
|
-
renameSync(tmp, path);
|
|
228
|
-
}
|
|
229
|
-
function logInstalled(label, target) {
|
|
230
|
-
p.log.success(`${label} → wired into ${target}`);
|
|
231
|
-
}
|
|
232
|
-
function logAlreadyWired(label, target) {
|
|
233
|
-
p.log.info(`${label} already wired in ${target} (use --force to re-install)`);
|
|
234
|
-
}
|
|
235
|
-
function logBackup(target) {
|
|
236
|
-
p.log.info(`Backup: ${target}`);
|
|
237
|
-
}
|
|
238
|
-
//#endregion
|
|
239
256
|
//#region src/cli/connect/json-mcp-adapter.ts
|
|
240
257
|
function entryMatches$3(entry) {
|
|
241
258
|
if (!entry || typeof entry !== "object") return false;
|
|
@@ -314,17 +331,6 @@ function createJsonMcpAdapter(config) {
|
|
|
314
331
|
};
|
|
315
332
|
}
|
|
316
333
|
//#endregion
|
|
317
|
-
//#region src/cli/connect/antigravity.ts
|
|
318
|
-
const ANTIGRAVITY_DIR = platform() === "darwin" ? join(homedir(), "Library", "Application Support", "Antigravity", "User") : join(homedir(), ".config", "Antigravity", "User");
|
|
319
|
-
const adapter$20 = createJsonMcpAdapter({
|
|
320
|
-
name: "antigravity",
|
|
321
|
-
displayName: "Antigravity",
|
|
322
|
-
detectDir: ANTIGRAVITY_DIR,
|
|
323
|
-
configPath: join(ANTIGRAVITY_DIR, "mcp_config.json"),
|
|
324
|
-
docs: "https://github.com/rohitg00/agentmemory#other-agents",
|
|
325
|
-
protocolNote: "→ Using MCP via mcp_config.json. Antigravity replaces Gemini CLI (sunset 2026-06-18)."
|
|
326
|
-
});
|
|
327
|
-
//#endregion
|
|
328
334
|
//#region src/cli/connect/antigravity-hooks.ts
|
|
329
335
|
/** Tool events: `[ { matcher, hooks: [...] } ]`. */
|
|
330
336
|
const TOOL_EVENT_KEYS = new Set(["PreToolUse", "PostToolUse"]);
|
|
@@ -424,13 +430,14 @@ function findPluginRoot(startUrl = import.meta.url) {
|
|
|
424
430
|
/**
|
|
425
431
|
* Build the merged hooks.json content.
|
|
426
432
|
*
|
|
427
|
-
* 1. Strip
|
|
428
|
-
*
|
|
429
|
-
* without leaving stale
|
|
433
|
+
* 1. Strip every handler in `existing` whose command points under
|
|
434
|
+
* `<pluginRoot>/scripts/`, and an entry only once nothing else is left
|
|
435
|
+
* in it. This lets us re-install idempotently without leaving stale
|
|
436
|
+
* references or dropping the user's own handlers.
|
|
430
437
|
* 2. Append fresh entries from the bundled Codex manifest with
|
|
431
438
|
* `${CLAUDE_PLUGIN_ROOT}` rewritten to the absolute plugin path.
|
|
432
|
-
*
|
|
433
|
-
* event routing keeps working.
|
|
439
|
+
* Matchers and the other handler fields from the bundled manifest are
|
|
440
|
+
* preserved so PreToolUse event routing keeps working.
|
|
434
441
|
*/
|
|
435
442
|
function buildMergedHooks(existing, pluginRoot, manifestFile = "hooks.codex.json") {
|
|
436
443
|
const bundledManifestPath = join(pluginRoot, "hooks", manifestFile);
|
|
@@ -438,14 +445,21 @@ function buildMergedHooks(existing, pluginRoot, manifestFile = "hooks.codex.json
|
|
|
438
445
|
const scriptsDir = join(pluginRoot, "scripts");
|
|
439
446
|
const out = { hooks: {} };
|
|
440
447
|
if (existing?.hooks) for (const [event, entries] of Object.entries(existing.hooks)) {
|
|
441
|
-
const kept = entries.
|
|
448
|
+
const kept = entries.flatMap((entry) => {
|
|
449
|
+
const hooks = entry.hooks.filter((handler) => !isAgentmemoryHandler(handler, scriptsDir));
|
|
450
|
+
if (hooks.length === entry.hooks.length) return [entry];
|
|
451
|
+
return hooks.length > 0 ? [{
|
|
452
|
+
...entry,
|
|
453
|
+
hooks
|
|
454
|
+
}] : [];
|
|
455
|
+
});
|
|
442
456
|
if (kept.length > 0) out.hooks[event] = kept;
|
|
443
457
|
}
|
|
444
458
|
for (const [event, entries] of Object.entries(ours.hooks)) {
|
|
445
459
|
const resolvedEntries = entries.map((entry) => {
|
|
446
460
|
const next = { hooks: entry.hooks.map((handler) => ({
|
|
447
|
-
|
|
448
|
-
command: handler.command
|
|
461
|
+
...handler,
|
|
462
|
+
command: handler.command?.replace(/\$\{CLAUDE_PLUGIN_ROOT\}/g, () => pluginRoot)
|
|
449
463
|
})) };
|
|
450
464
|
if (entry.matcher !== void 0) next.matcher = entry.matcher;
|
|
451
465
|
return next;
|
|
@@ -454,9 +468,8 @@ function buildMergedHooks(existing, pluginRoot, manifestFile = "hooks.codex.json
|
|
|
454
468
|
}
|
|
455
469
|
return out;
|
|
456
470
|
}
|
|
457
|
-
function
|
|
458
|
-
|
|
459
|
-
return entry.hooks.some((handler) => normalizePathForCommandMatch(handler.command).includes(normalizedScriptsDir));
|
|
471
|
+
function isAgentmemoryHandler(handler, scriptsDir) {
|
|
472
|
+
return typeof handler.command === "string" && normalizePathForCommandMatch(handler.command).includes(normalizePathForCommandMatch(scriptsDir));
|
|
460
473
|
}
|
|
461
474
|
function normalizePathForCommandMatch(value) {
|
|
462
475
|
return value.replace(/\\/g, "/");
|
|
@@ -465,15 +478,16 @@ function normalizePathForCommandMatch(value) {
|
|
|
465
478
|
//#region src/cli/connect/antigravity-cli.ts
|
|
466
479
|
const GEMINI_DIR = join(homedir(), ".gemini");
|
|
467
480
|
const ANTIGRAVITY_CLI_DIR = join(GEMINI_DIR, "antigravity-cli");
|
|
468
|
-
const CUSTOMIZATION_DIR = join(GEMINI_DIR, "config");
|
|
469
|
-
const ANTIGRAVITY_CLI_HOOKS = join(CUSTOMIZATION_DIR, "hooks.json");
|
|
470
|
-
const adapter$
|
|
481
|
+
const CUSTOMIZATION_DIR$1 = join(GEMINI_DIR, "config");
|
|
482
|
+
const ANTIGRAVITY_CLI_HOOKS = join(CUSTOMIZATION_DIR$1, "hooks.json");
|
|
483
|
+
const adapter$21 = createJsonMcpAdapter({
|
|
471
484
|
name: "antigravity-cli",
|
|
472
485
|
displayName: "Antigravity CLI (agy)",
|
|
473
486
|
detectDir: ANTIGRAVITY_CLI_DIR,
|
|
474
|
-
configPath: join(CUSTOMIZATION_DIR, "mcp_config.json"),
|
|
487
|
+
configPath: join(CUSTOMIZATION_DIR$1, "mcp_config.json"),
|
|
488
|
+
extraEntryFields: { env: {} },
|
|
475
489
|
docs: "https://github.com/rohitg00/agentmemory#other-agents",
|
|
476
|
-
protocolNote: "→ Using MCP via ~/.gemini/config/mcp_config.json
|
|
490
|
+
protocolNote: "→ 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.",
|
|
477
491
|
installHooks: installAntigravityCliHooks
|
|
478
492
|
});
|
|
479
493
|
/**
|
|
@@ -507,7 +521,7 @@ function installAntigravityCliHooks(opts) {
|
|
|
507
521
|
if (existsSync(ANTIGRAVITY_CLI_HOOKS)) {
|
|
508
522
|
backupPath = backupFile(ANTIGRAVITY_CLI_HOOKS, "antigravity-cli-hooks", "json");
|
|
509
523
|
logBackup(backupPath);
|
|
510
|
-
} else mkdirSync(CUSTOMIZATION_DIR, { recursive: true });
|
|
524
|
+
} else mkdirSync(CUSTOMIZATION_DIR$1, { recursive: true });
|
|
511
525
|
writeJsonAtomic(ANTIGRAVITY_CLI_HOOKS, merged);
|
|
512
526
|
logInstalled("Antigravity CLI hooks", ANTIGRAVITY_CLI_HOOKS);
|
|
513
527
|
p.log.info("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.");
|
|
@@ -518,6 +532,24 @@ function installAntigravityCliHooks(opts) {
|
|
|
518
532
|
};
|
|
519
533
|
}
|
|
520
534
|
//#endregion
|
|
535
|
+
//#region src/cli/connect/antigravity.ts
|
|
536
|
+
const LEGACY_USER_DIR = platform() === "darwin" ? join(homedir(), "Library", "Application Support", "Antigravity", "User") : join(homedir(), ".config", "Antigravity", "User");
|
|
537
|
+
const CUSTOMIZATION_DIR = join(homedir(), ".gemini", "config");
|
|
538
|
+
const mcpAdapter = createJsonMcpAdapter({
|
|
539
|
+
name: "antigravity",
|
|
540
|
+
displayName: "Antigravity",
|
|
541
|
+
detectDir: join(homedir(), ".gemini", "antigravity-ide"),
|
|
542
|
+
configPath: join(CUSTOMIZATION_DIR, "mcp_config.json"),
|
|
543
|
+
extraEntryFields: { env: {} },
|
|
544
|
+
docs: "https://github.com/rohitg00/agentmemory#other-agents",
|
|
545
|
+
protocolNote: "→ Using MCP via ~/.gemini/config/mcp_config.json, shared by current Antigravity surfaces. Pass --with-hooks for capture through ~/.gemini/config/hooks.json.",
|
|
546
|
+
installHooks: installAntigravityCliHooks
|
|
547
|
+
});
|
|
548
|
+
const adapter$20 = {
|
|
549
|
+
...mcpAdapter,
|
|
550
|
+
detect: () => mcpAdapter.detect() || existsSync(join(homedir(), ".gemini", "antigravity")) || existsSync(LEGACY_USER_DIR)
|
|
551
|
+
};
|
|
552
|
+
//#endregion
|
|
521
553
|
//#region src/cli/connect/claude-code.ts
|
|
522
554
|
const CLAUDE_DIR = join(homedir(), ".claude");
|
|
523
555
|
const CLAUDE_JSON = join(homedir(), ".claude.json");
|
|
@@ -528,7 +560,7 @@ function entryMatches$2(entry) {
|
|
|
528
560
|
if (e["command"] !== "npx") return false;
|
|
529
561
|
return (Array.isArray(e["args"]) ? e["args"] : []).includes("@agentmemory/mcp");
|
|
530
562
|
}
|
|
531
|
-
const adapter$
|
|
563
|
+
const adapter$19 = {
|
|
532
564
|
name: "claude-code",
|
|
533
565
|
displayName: "Claude Code",
|
|
534
566
|
category: "native",
|
|
@@ -591,17 +623,6 @@ const adapter$18 = {
|
|
|
591
623
|
};
|
|
592
624
|
}
|
|
593
625
|
};
|
|
594
|
-
/**
|
|
595
|
-
* Merge the bundled `plugin/hooks/hooks.json` into
|
|
596
|
-
* `~/.claude/settings.json`'s top-level `hooks` field with absolute
|
|
597
|
-
* script paths. Use this when agentmemory is NOT installed through
|
|
598
|
-
* `/plugin marketplace add` (e.g. MCP standalone wiring), so the
|
|
599
|
-
* hook scripts survive version bumps without `${CLAUDE_PLUGIN_ROOT}`
|
|
600
|
-
* expansion (issue #508).
|
|
601
|
-
*
|
|
602
|
-
* Re-install strips entries whose command points under
|
|
603
|
-
* `<pluginRoot>/scripts/`; unrelated user hook entries survive.
|
|
604
|
-
*/
|
|
605
626
|
function installClaudeHooks(opts) {
|
|
606
627
|
let pluginRoot;
|
|
607
628
|
try {
|
|
@@ -630,7 +651,7 @@ function installClaudeHooks(opts) {
|
|
|
630
651
|
...existing,
|
|
631
652
|
hooks: merged.hooks
|
|
632
653
|
});
|
|
633
|
-
logInstalled("Claude Code hooks
|
|
654
|
+
logInstalled("Claude Code hooks", CLAUDE_SETTINGS);
|
|
634
655
|
p.log.info("User-scope hook entries reference absolute paths under the bundled plugin/ dir. Re-run `agentmemory connect claude-code --with-hooks` after upgrading agentmemory to refresh them.");
|
|
635
656
|
return {
|
|
636
657
|
kind: "installed",
|
|
@@ -640,7 +661,7 @@ function installClaudeHooks(opts) {
|
|
|
640
661
|
}
|
|
641
662
|
//#endregion
|
|
642
663
|
//#region src/cli/connect/cline.ts
|
|
643
|
-
const adapter$
|
|
664
|
+
const adapter$18 = createJsonMcpAdapter({
|
|
644
665
|
name: "cline",
|
|
645
666
|
displayName: "Cline",
|
|
646
667
|
detectDir: join(homedir(), ".cline"),
|
|
@@ -656,7 +677,7 @@ function entryMatches$1(entry) {
|
|
|
656
677
|
if (!entry || typeof entry !== "object") return false;
|
|
657
678
|
return JSON.stringify(entry) === JSON.stringify(AGENTMEMORY_COPILOT_MCP_BLOCK);
|
|
658
679
|
}
|
|
659
|
-
const adapter$
|
|
680
|
+
const adapter$17 = {
|
|
660
681
|
name: "copilot-cli",
|
|
661
682
|
displayName: "GitHub Copilot CLI",
|
|
662
683
|
category: "native",
|
|
@@ -739,12 +760,12 @@ function stripExistingBlock(toml) {
|
|
|
739
760
|
}
|
|
740
761
|
return out.join("\n").replace(/\n{3,}$/, "\n\n").trimEnd() + "\n";
|
|
741
762
|
}
|
|
742
|
-
const adapter$
|
|
763
|
+
const adapter$16 = {
|
|
743
764
|
name: "codex",
|
|
744
765
|
displayName: "Codex CLI",
|
|
745
766
|
category: "native",
|
|
746
767
|
docs: "https://github.com/rohitg00/agentmemory#codex-cli-codex-plugin-platform",
|
|
747
|
-
protocolNote: "→ Using MCP. Hooks ship via the Codex plugin; on Codex Desktop, also pass --with-hooks to install the global hooks.json workaround
|
|
768
|
+
protocolNote: "→ Using MCP. Hooks ship via the Codex plugin; on Codex Desktop, also pass --with-hooks to install the global hooks.json workaround.",
|
|
748
769
|
detect() {
|
|
749
770
|
return existsSync(CODEX_DIR);
|
|
750
771
|
},
|
|
@@ -794,12 +815,6 @@ const adapter$15 = {
|
|
|
794
815
|
};
|
|
795
816
|
}
|
|
796
817
|
};
|
|
797
|
-
/**
|
|
798
|
-
* Install the global `~/.codex/hooks.json` fallback. See
|
|
799
|
-
* `codex-hooks.ts` for context (openai/codex#16430). Returns a result
|
|
800
|
-
* describing the side effect for the caller's summary; failures here do
|
|
801
|
-
* not roll back the MCP wiring.
|
|
802
|
-
*/
|
|
803
818
|
function installCodexHooks(opts) {
|
|
804
819
|
let pluginRoot;
|
|
805
820
|
try {
|
|
@@ -825,7 +840,7 @@ function installCodexHooks(opts) {
|
|
|
825
840
|
logBackup(backupPath);
|
|
826
841
|
}
|
|
827
842
|
writeJsonAtomic(CODEX_HOOKS, merged);
|
|
828
|
-
logInstalled("Codex hooks
|
|
843
|
+
logInstalled("Codex hooks", CODEX_HOOKS);
|
|
829
844
|
p.log.warn("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.");
|
|
830
845
|
p.log.info("User-scope hooks reference absolute paths under the bundled plugin/ dir. Re-run `agentmemory connect codex --with-hooks` after upgrading agentmemory to refresh them, then re-approve in the TUI.");
|
|
831
846
|
return {
|
|
@@ -865,7 +880,7 @@ function renderFreshYaml() {
|
|
|
865
880
|
""
|
|
866
881
|
].join("\n");
|
|
867
882
|
}
|
|
868
|
-
const adapter$
|
|
883
|
+
const adapter$15 = {
|
|
869
884
|
name: "continue",
|
|
870
885
|
displayName: "Continue",
|
|
871
886
|
category: "mcp",
|
|
@@ -945,13 +960,14 @@ const adapter$14 = {
|
|
|
945
960
|
};
|
|
946
961
|
//#endregion
|
|
947
962
|
//#region src/cli/connect/cursor.ts
|
|
948
|
-
const adapter$
|
|
963
|
+
const adapter$14 = createJsonMcpAdapter({
|
|
949
964
|
name: "cursor",
|
|
950
965
|
displayName: "Cursor",
|
|
966
|
+
category: "native",
|
|
951
967
|
detectDir: join(homedir(), ".cursor"),
|
|
952
968
|
configPath: join(homedir(), ".cursor", "mcp.json"),
|
|
953
|
-
docs: "https://github.com/rohitg00/agentmemory#
|
|
954
|
-
protocolNote: "→ Using MCP
|
|
969
|
+
docs: "https://github.com/rohitg00/agentmemory#cursor",
|
|
970
|
+
protocolNote: "→ Using MCP. Lifecycle hooks ship in the Cursor plugin: Settings → Plugins → Add marketplace → this repo, then enable agentmemory."
|
|
955
971
|
});
|
|
956
972
|
//#endregion
|
|
957
973
|
//#region src/cli/connect/devin.ts
|
|
@@ -965,7 +981,7 @@ function devinDir() {
|
|
|
965
981
|
}
|
|
966
982
|
const DEVIN_DIR = devinDir();
|
|
967
983
|
const DEVIN_CONFIG = join(DEVIN_DIR, "config.json");
|
|
968
|
-
const adapter$
|
|
984
|
+
const adapter$13 = createJsonMcpAdapter({
|
|
969
985
|
name: "devin",
|
|
970
986
|
displayName: "Devin CLI",
|
|
971
987
|
detectDir: DEVIN_DIR,
|
|
@@ -1015,7 +1031,7 @@ function installDevinHooks(opts) {
|
|
|
1015
1031
|
//#region src/cli/connect/droid.ts
|
|
1016
1032
|
const DROID_DIR = join(homedir(), ".factory");
|
|
1017
1033
|
const DROID_HOOKS = join(DROID_DIR, "hooks.json");
|
|
1018
|
-
const adapter$
|
|
1034
|
+
const adapter$12 = createJsonMcpAdapter({
|
|
1019
1035
|
name: "droid",
|
|
1020
1036
|
displayName: "Droid (Factory.ai)",
|
|
1021
1037
|
detectDir: DROID_DIR,
|
|
@@ -1066,9 +1082,6 @@ function installDroidHooks(opts) {
|
|
|
1066
1082
|
}
|
|
1067
1083
|
//#endregion
|
|
1068
1084
|
//#region src/cli/connect/dsh.ts
|
|
1069
|
-
function dshHome() {
|
|
1070
|
-
return process.env["DSH_HOME"] || join(homedir(), ".dsh");
|
|
1071
|
-
}
|
|
1072
1085
|
const MCP_BLOCK = `- insert:
|
|
1073
1086
|
- id: agentmemory
|
|
1074
1087
|
name: '@deepseek-ai/dsh-mcp-client'
|
|
@@ -1078,55 +1091,89 @@ const MCP_BLOCK = `- insert:
|
|
|
1078
1091
|
command: npx
|
|
1079
1092
|
args: ['-y', '@agentmemory/mcp']
|
|
1080
1093
|
env:
|
|
1081
|
-
AGENTMEMORY_URL: http://localhost:3111
|
|
1094
|
+
AGENTMEMORY_URL: !!js process.env.AGENTMEMORY_URL || 'http://localhost:3111'
|
|
1095
|
+
AGENTMEMORY_SECRET: !!js process.env.AGENTMEMORY_SECRET || ''
|
|
1082
1096
|
`;
|
|
1083
1097
|
const MCP_MARKER = "serverName: agentmemory";
|
|
1084
1098
|
const HOOKS_MARKER = "id: agentmemory-hooks";
|
|
1085
|
-
function hooksBlock(
|
|
1099
|
+
function hooksBlock(pluginPath) {
|
|
1086
1100
|
return `- insert:
|
|
1087
1101
|
- id: agentmemory-hooks
|
|
1088
|
-
name:
|
|
1089
|
-
config:
|
|
1090
|
-
configPath: ${JSON.stringify(hooksConfigPath)}
|
|
1102
|
+
name: ${JSON.stringify(pluginPath)}
|
|
1091
1103
|
`;
|
|
1092
1104
|
}
|
|
1093
|
-
function
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1105
|
+
function parsePatch(content) {
|
|
1106
|
+
const doc = parseDocument(content);
|
|
1107
|
+
if (doc.contents === null) doc.contents = doc.createNode([]);
|
|
1108
|
+
if (doc.errors.length || !isSeq(doc.contents)) throw new Error("Cannot update dsh cordis.patch.yml: expected a valid YAML sequence.");
|
|
1109
|
+
return {
|
|
1110
|
+
doc,
|
|
1111
|
+
operations: doc.contents
|
|
1112
|
+
};
|
|
1113
|
+
}
|
|
1114
|
+
function isManaged(entry, marker) {
|
|
1115
|
+
if (!isMap(entry)) return false;
|
|
1116
|
+
return marker === MCP_MARKER ? entry.get("name") === "@deepseek-ai/dsh-mcp-client" && entry.getIn(["config", "serverName"]) === "agentmemory" : entry.get("id") === "agentmemory-hooks" && typeof entry.get("name") === "string" && (entry.get("name") === "@deepseek-ai/dsh-hooks-claude-code" || /[\\/]dist[\\/]integrations[\\/]dsh\.mjs$/.test(String(entry.get("name"))));
|
|
1117
|
+
}
|
|
1118
|
+
function managedEntries(content, marker) {
|
|
1119
|
+
return parsePatch(content).operations.items.flatMap((operation) => {
|
|
1120
|
+
const entries = isMap(operation) ? operation.get("insert", true) : null;
|
|
1121
|
+
return isSeq(entries) ? entries.items.filter((entry) => isManaged(entry, marker)) : [];
|
|
1122
|
+
});
|
|
1123
|
+
}
|
|
1124
|
+
function hasBlock(content, marker) {
|
|
1125
|
+
return managedEntries(content, marker).length > 0;
|
|
1126
|
+
}
|
|
1127
|
+
function upsertBlock(content, marker, block) {
|
|
1128
|
+
const { doc, operations } = parsePatch(content);
|
|
1129
|
+
const addition = parsePatch(block).operations;
|
|
1130
|
+
const replacement = addition.getIn([
|
|
1131
|
+
0,
|
|
1132
|
+
"insert",
|
|
1133
|
+
0
|
|
1134
|
+
], true);
|
|
1135
|
+
let replaced = false;
|
|
1136
|
+
for (let i = 0; i < operations.items.length; i++) {
|
|
1137
|
+
const operation = operations.items[i];
|
|
1138
|
+
if (!isMap(operation)) continue;
|
|
1139
|
+
const entries = operation.get("insert", true);
|
|
1140
|
+
if (!isSeq(entries)) continue;
|
|
1141
|
+
let removed = false;
|
|
1142
|
+
for (let j = 0; j < entries.items.length; j++) {
|
|
1143
|
+
if (!isManaged(entries.items[j], marker)) continue;
|
|
1144
|
+
if (!replaced) {
|
|
1145
|
+
entries.set(j, replacement);
|
|
1146
|
+
replaced = true;
|
|
1147
|
+
} else {
|
|
1148
|
+
entries.delete(j--);
|
|
1149
|
+
removed = true;
|
|
1150
|
+
}
|
|
1151
|
+
}
|
|
1152
|
+
if (removed && entries.items.length === 0) operations.delete(i--);
|
|
1153
|
+
}
|
|
1154
|
+
if (!replaced) operations.items.push(...addition.items);
|
|
1155
|
+
operations.flow = false;
|
|
1156
|
+
return doc.toString();
|
|
1157
|
+
}
|
|
1158
|
+
const adapter$11 = {
|
|
1114
1159
|
name: "dsh",
|
|
1115
1160
|
displayName: "DeepSeek Harness",
|
|
1116
|
-
docs: "https://github.com/rohitg00/agentmemory
|
|
1117
|
-
protocolNote: "→ Using MCP via $DSH_HOME/cordis.patch.yml (the home-level patch layer every profile loads). Tools appear as mcp__agentmemory__*. Pass --with-hooks to also wire auto-capture
|
|
1161
|
+
docs: "https://github.com/rohitg00/agentmemory/blob/main/docs/dsh.md",
|
|
1162
|
+
protocolNote: "→ Using MCP via $DSH_HOME/cordis.patch.yml (the home-level patch layer every profile loads). Tools appear as mcp__agentmemory__*. Pass --with-hooks to also wire auto-capture with the bundled native DSH plugin.",
|
|
1118
1163
|
category: "native",
|
|
1119
1164
|
detect() {
|
|
1120
|
-
return existsSync(
|
|
1165
|
+
return existsSync(resolveDshHome());
|
|
1121
1166
|
},
|
|
1122
1167
|
async install(opts) {
|
|
1123
|
-
const
|
|
1124
|
-
const configPath = join(home, "cordis.patch.yml");
|
|
1168
|
+
const configPath = join(resolveDshHome(), "cordis.patch.yml");
|
|
1125
1169
|
const existing = existsSync(configPath) ? readFileSync(configPath, "utf-8") : "";
|
|
1126
1170
|
const wantHooks = opts.withHooks === true;
|
|
1127
|
-
const hasMcp = existing
|
|
1128
|
-
const
|
|
1129
|
-
|
|
1171
|
+
const hasMcp = hasBlock(existing, MCP_MARKER);
|
|
1172
|
+
const hooks = managedEntries(existing, HOOKS_MARKER);
|
|
1173
|
+
const pluginPath = wantHooks ? join(dirname(findPluginRoot()), "dist", "integrations", "dsh.mjs") : "";
|
|
1174
|
+
const hooksReady = hooks.length === 1 && hooks[0].get("name") === pluginPath && existsSync(pluginPath);
|
|
1175
|
+
if (wantHooks && !opts.force && hooks.some((entry) => entry.get("name") === "@deepseek-ai/dsh-hooks-claude-code")) throw new Error("Legacy DSH hooks bridge found. Run agentmemory connect dsh --with-hooks --force to replace it with the bundled native plugin. Existing manifest files will be preserved.");
|
|
1176
|
+
if (hasMcp && (!wantHooks || hooksReady) && !opts.force) {
|
|
1130
1177
|
logAlreadyWired(this.displayName, configPath);
|
|
1131
1178
|
return {
|
|
1132
1179
|
kind: "already-wired",
|
|
@@ -1134,28 +1181,23 @@ const adapter$10 = {
|
|
|
1134
1181
|
};
|
|
1135
1182
|
}
|
|
1136
1183
|
if (opts.dryRun) {
|
|
1137
|
-
p.log.info(`[dry-run] Would
|
|
1184
|
+
p.log.info(`[dry-run] Would update the agentmemory mcp-client row${wantHooks ? " and the bundled capture plugin" : ""} in ${configPath}`);
|
|
1138
1185
|
return {
|
|
1139
1186
|
kind: "installed",
|
|
1140
1187
|
mutatedPath: configPath
|
|
1141
1188
|
};
|
|
1142
1189
|
}
|
|
1190
|
+
if (wantHooks && !existsSync(pluginPath)) throw new Error("Bundled DSH plugin is missing. Reinstall AgentMemory, or run npm run build in a source checkout.");
|
|
1143
1191
|
let backupPath;
|
|
1144
1192
|
if (existsSync(configPath)) {
|
|
1145
1193
|
backupPath = backupFile(configPath, this.name, "yml");
|
|
1146
1194
|
logBackup(backupPath);
|
|
1147
1195
|
} else mkdirSync(dirname(configPath), { recursive: true });
|
|
1148
|
-
let next =
|
|
1149
|
-
next =
|
|
1150
|
-
if (wantHooks) {
|
|
1151
|
-
const hooksPath = installHooksFile(home);
|
|
1152
|
-
next = stripBlock(next, HOOKS_MARKER);
|
|
1153
|
-
next = appendBlock(next, hooksBlock(hooksPath));
|
|
1154
|
-
p.log.info(`Hook manifest: ${hooksPath}`);
|
|
1155
|
-
}
|
|
1196
|
+
let next = hasMcp && !opts.force ? existing : upsertBlock(existing, MCP_MARKER, MCP_BLOCK);
|
|
1197
|
+
if (wantHooks && (!hooksReady || opts.force)) next = upsertBlock(next, HOOKS_MARKER, hooksBlock(pluginPath));
|
|
1156
1198
|
writeTextAtomic(configPath, next);
|
|
1157
1199
|
const written = readFileSync(configPath, "utf-8");
|
|
1158
|
-
if (!written
|
|
1200
|
+
if (!hasBlock(written, MCP_MARKER) || wantHooks && !hasBlock(written, HOOKS_MARKER)) {
|
|
1159
1201
|
p.log.error(`Verification failed: ${configPath} did not contain the agentmemory rows after write.`);
|
|
1160
1202
|
return {
|
|
1161
1203
|
kind: "skipped",
|
|
@@ -1172,7 +1214,7 @@ const adapter$10 = {
|
|
|
1172
1214
|
};
|
|
1173
1215
|
//#endregion
|
|
1174
1216
|
//#region src/cli/connect/gemini-cli.ts
|
|
1175
|
-
const adapter$
|
|
1217
|
+
const adapter$10 = createJsonMcpAdapter({
|
|
1176
1218
|
name: "gemini-cli",
|
|
1177
1219
|
displayName: "Gemini CLI",
|
|
1178
1220
|
detectDir: join(homedir(), ".gemini"),
|
|
@@ -1181,43 +1223,275 @@ const adapter$9 = createJsonMcpAdapter({
|
|
|
1181
1223
|
protocolNote: "→ Using MCP (the only protocol Gemini CLI speaks). Memory bridge runs at :3111 underneath."
|
|
1182
1224
|
});
|
|
1183
1225
|
//#endregion
|
|
1226
|
+
//#region src/cli/connect/native-install.ts
|
|
1227
|
+
const MANIFEST = ".agentmemory-install.json";
|
|
1228
|
+
const digest = (content) => createHash("sha256").update(content).digest("hex");
|
|
1229
|
+
const record = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
1230
|
+
function nativePackageRoot() {
|
|
1231
|
+
return dirname(findPluginRoot());
|
|
1232
|
+
}
|
|
1233
|
+
function nativeUserPath(value, home) {
|
|
1234
|
+
return resolve(value.replace(/^~(?=$|[/\\])/, () => home));
|
|
1235
|
+
}
|
|
1236
|
+
function nativeMcpEntry(packageRoot) {
|
|
1237
|
+
const entry = join(packageRoot, "dist", "standalone.mjs");
|
|
1238
|
+
if (!existsSync(entry)) throw new Error("Bundled MCP runtime is missing; reinstall AgentMemory before connecting.");
|
|
1239
|
+
return {
|
|
1240
|
+
command: process.execPath,
|
|
1241
|
+
args: [entry],
|
|
1242
|
+
env: {
|
|
1243
|
+
AGENTMEMORY_TOOLS: "all",
|
|
1244
|
+
AGENTMEMORY_FORCE_PROXY: "1"
|
|
1245
|
+
}
|
|
1246
|
+
};
|
|
1247
|
+
}
|
|
1248
|
+
function filesUnder(dir, prefix = "") {
|
|
1249
|
+
const files = /* @__PURE__ */ new Map();
|
|
1250
|
+
for (const item of readdirSync(dir, { withFileTypes: true })) {
|
|
1251
|
+
if ([
|
|
1252
|
+
"__pycache__",
|
|
1253
|
+
".git",
|
|
1254
|
+
"node_modules",
|
|
1255
|
+
MANIFEST
|
|
1256
|
+
].includes(item.name) || item.name.endsWith(".pyc")) continue;
|
|
1257
|
+
const path = join(dir, item.name);
|
|
1258
|
+
if (item.isSymbolicLink()) throw new Error(`Native installation does not follow symbolic links: ${path}`);
|
|
1259
|
+
const name = join(prefix, item.name);
|
|
1260
|
+
if (item.isDirectory()) for (const [key, value] of filesUnder(path, name)) files.set(key, value);
|
|
1261
|
+
else if (item.isFile()) files.set(name, readFileSync(path));
|
|
1262
|
+
}
|
|
1263
|
+
return files;
|
|
1264
|
+
}
|
|
1265
|
+
function rejectSymlink(path) {
|
|
1266
|
+
if (existsSync(path) && lstatSync(path).isSymbolicLink()) throw new Error(`Native installation does not replace symbolic links: ${path}`);
|
|
1267
|
+
}
|
|
1268
|
+
function prepareNativeBundle(source, target, label, required, force, skillsSource, extraFiles = {}) {
|
|
1269
|
+
if (!required.every((name) => existsSync(join(source, name)))) throw new Error(`Bundled ${label} files are missing; reinstall AgentMemory before connecting.`);
|
|
1270
|
+
rejectSymlink(target);
|
|
1271
|
+
const files = filesUnder(source);
|
|
1272
|
+
if (skillsSource) {
|
|
1273
|
+
if (!["remember/SKILL.md", "recall/SKILL.md"].every((name) => existsSync(join(skillsSource, name)))) throw new Error("Bundled skills are missing; reinstall AgentMemory before connecting.");
|
|
1274
|
+
for (const [name, content] of filesUnder(skillsSource)) files.set(join("skills", name), content);
|
|
1275
|
+
}
|
|
1276
|
+
for (const [name, content] of Object.entries(extraFiles)) files.set(name, Buffer.from(content));
|
|
1277
|
+
let previous = {};
|
|
1278
|
+
if (existsSync(join(target, MANIFEST))) {
|
|
1279
|
+
let stored;
|
|
1280
|
+
try {
|
|
1281
|
+
stored = JSON.parse(readFileSync(join(target, MANIFEST), "utf8"));
|
|
1282
|
+
} catch {
|
|
1283
|
+
stored = null;
|
|
1284
|
+
}
|
|
1285
|
+
if (!record(stored) || !record(stored.files) || !Object.values(stored.files).every((hash) => typeof hash === "string")) throw new Error(`Invalid native install manifest in ${target}; restore its backup before reconnecting.`);
|
|
1286
|
+
previous = stored.files;
|
|
1287
|
+
for (const name of Object.keys(previous)) {
|
|
1288
|
+
const location = relative(target, resolve(target, name));
|
|
1289
|
+
if (!location || location === ".." || location.startsWith(`..${sep}`) || resolve(target, name) === resolve(target, MANIFEST)) throw new Error(`Invalid native install path in ${target}.`);
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1292
|
+
const installed = existsSync(target) ? filesUnder(target) : /* @__PURE__ */ new Map();
|
|
1293
|
+
if (!force) for (const [name, content] of installed) {
|
|
1294
|
+
if (!files.has(name) && !(name in previous)) continue;
|
|
1295
|
+
if (previous[name] ? digest(content) !== previous[name] : !files.get(name)?.equals(content)) throw new Error(`Customized ${label} file ${name} was preserved; use --force to replace it with a backup.`);
|
|
1296
|
+
}
|
|
1297
|
+
const changed = !existsSync(join(target, MANIFEST)) || [...files].some(([name, content]) => !installed.get(name)?.equals(content)) || Object.keys(previous).some((name) => !files.has(name) && installed.has(name));
|
|
1298
|
+
return {
|
|
1299
|
+
target,
|
|
1300
|
+
label,
|
|
1301
|
+
files,
|
|
1302
|
+
previous,
|
|
1303
|
+
changed
|
|
1304
|
+
};
|
|
1305
|
+
}
|
|
1306
|
+
function installNativeBundles(bundles, configPath, configText) {
|
|
1307
|
+
rejectSymlink(configPath);
|
|
1308
|
+
const transaction = randomUUID();
|
|
1309
|
+
const configStage = `${configPath}.stage-${transaction}`;
|
|
1310
|
+
const staged = [];
|
|
1311
|
+
let backupPath;
|
|
1312
|
+
try {
|
|
1313
|
+
for (const bundle of bundles.filter((item) => item.changed)) {
|
|
1314
|
+
mkdirSync(dirname(bundle.target), { recursive: true });
|
|
1315
|
+
const stage = `${bundle.target}.stage-${transaction}`;
|
|
1316
|
+
const item = {
|
|
1317
|
+
bundle,
|
|
1318
|
+
stage,
|
|
1319
|
+
rollback: `${bundle.target}.previous-${transaction}`,
|
|
1320
|
+
replaced: false,
|
|
1321
|
+
installed: false
|
|
1322
|
+
};
|
|
1323
|
+
staged.push(item);
|
|
1324
|
+
if (existsSync(bundle.target)) cpSync(bundle.target, stage, { recursive: true });
|
|
1325
|
+
else mkdirSync(stage);
|
|
1326
|
+
for (const name of Object.keys(bundle.previous)) if (!bundle.files.has(name)) rmSync(join(stage, name), { force: true });
|
|
1327
|
+
for (const [name, content] of bundle.files) {
|
|
1328
|
+
mkdirSync(dirname(join(stage, name)), { recursive: true });
|
|
1329
|
+
writeFileSync(join(stage, name), content);
|
|
1330
|
+
}
|
|
1331
|
+
writeFileSync(join(stage, MANIFEST), JSON.stringify({ files: Object.fromEntries([...bundle.files].map(([name, content]) => [name, digest(content)])) }) + "\n");
|
|
1332
|
+
if (existsSync(bundle.target)) {
|
|
1333
|
+
const backup = join(ensureBackupsDir(), `${bundle.label}-${transaction}`);
|
|
1334
|
+
cpSync(bundle.target, backup, { recursive: true });
|
|
1335
|
+
backupPath ??= backup;
|
|
1336
|
+
}
|
|
1337
|
+
}
|
|
1338
|
+
const configChanged = !existsSync(configPath) || readFileSync(configPath, "utf8") !== configText;
|
|
1339
|
+
if (configChanged && existsSync(configPath)) backupPath = backupFile(configPath, `native-config-${transaction}`, "config");
|
|
1340
|
+
if (configChanged) {
|
|
1341
|
+
mkdirSync(dirname(configPath), { recursive: true });
|
|
1342
|
+
writeFileSync(configStage, configText, { mode: existsSync(configPath) ? lstatSync(configPath).mode & 511 : 384 });
|
|
1343
|
+
}
|
|
1344
|
+
for (const item of staged) {
|
|
1345
|
+
if (existsSync(item.bundle.target)) {
|
|
1346
|
+
renameSync(item.bundle.target, item.rollback);
|
|
1347
|
+
item.replaced = true;
|
|
1348
|
+
}
|
|
1349
|
+
renameSync(item.stage, item.bundle.target);
|
|
1350
|
+
item.installed = true;
|
|
1351
|
+
}
|
|
1352
|
+
if (configChanged) renameSync(configStage, configPath);
|
|
1353
|
+
} catch (error) {
|
|
1354
|
+
for (const item of [...staged].reverse()) {
|
|
1355
|
+
if (item.installed) rmSync(item.bundle.target, {
|
|
1356
|
+
recursive: true,
|
|
1357
|
+
force: true
|
|
1358
|
+
});
|
|
1359
|
+
if (item.replaced) renameSync(item.rollback, item.bundle.target);
|
|
1360
|
+
}
|
|
1361
|
+
throw error;
|
|
1362
|
+
} finally {
|
|
1363
|
+
for (const item of staged) rmSync(item.stage, {
|
|
1364
|
+
recursive: true,
|
|
1365
|
+
force: true
|
|
1366
|
+
});
|
|
1367
|
+
rmSync(configStage, { force: true });
|
|
1368
|
+
}
|
|
1369
|
+
for (const item of staged) rmSync(item.rollback, {
|
|
1370
|
+
recursive: true,
|
|
1371
|
+
force: true
|
|
1372
|
+
});
|
|
1373
|
+
return backupPath;
|
|
1374
|
+
}
|
|
1375
|
+
//#endregion
|
|
1184
1376
|
//#region src/cli/connect/hermes.ts
|
|
1185
|
-
const
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
const
|
|
1377
|
+
const hermesHome = () => {
|
|
1378
|
+
return nativeUserPath((process.env.HERMES_HOME?.trim() || join(homedir(), `.hermes${process.env.HERMES_DATA_DIR_SUFFIX ?? ""}`)).replace(/\$(?:\{([^}]+)\}|([A-Za-z_][A-Za-z_0-9]*))/g, (match, braced, plain) => process.env[braced ?? plain] ?? match), homedir());
|
|
1379
|
+
};
|
|
1380
|
+
const DOCS$1 = "https://github.com/rohitg00/agentmemory/tree/main/integrations/hermes";
|
|
1381
|
+
const stringList$1 = (value) => value === void 0 || Array.isArray(value) && value.every((item) => typeof item === "string");
|
|
1382
|
+
const adapter$9 = {
|
|
1189
1383
|
name: "hermes",
|
|
1190
1384
|
displayName: "Hermes Agent",
|
|
1191
1385
|
category: "native",
|
|
1192
|
-
docs: DOCS$
|
|
1193
|
-
protocolNote: "→
|
|
1194
|
-
detect()
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
};
|
|
1386
|
+
docs: DOCS$1,
|
|
1387
|
+
protocolNote: "→ Installs the native memory provider and bundled skills into the active Hermes profile. Credentials stay managed by Hermes.",
|
|
1388
|
+
detect: () => existsSync(hermesHome()),
|
|
1389
|
+
async install(opts) {
|
|
1390
|
+
const home = hermesHome();
|
|
1391
|
+
const path = join(home, "config.yaml");
|
|
1392
|
+
const raw = existsSync(path) ? readFileSync(path, "utf8") : "";
|
|
1393
|
+
const doc = parseDocument(raw);
|
|
1394
|
+
let existing;
|
|
1395
|
+
try {
|
|
1396
|
+
existing = doc.contents === null ? {} : doc.toJS({ maxAliasCount: 100 });
|
|
1397
|
+
} catch {
|
|
1398
|
+
existing = null;
|
|
1399
|
+
}
|
|
1400
|
+
if (doc.errors.length || !record(existing) || existing.memory !== void 0 && !record(existing.memory) || existing.plugins !== void 0 && !record(existing.plugins) || existing.mcp_servers !== void 0 && !record(existing.mcp_servers)) {
|
|
1401
|
+
p.log.warn(`Hermes config is not a valid YAML mapping. Left ${path} unchanged.`);
|
|
1402
|
+
return {
|
|
1403
|
+
kind: "skipped",
|
|
1404
|
+
reason: "invalid-config"
|
|
1405
|
+
};
|
|
1406
|
+
}
|
|
1407
|
+
const memory = existing.memory ?? {};
|
|
1408
|
+
const plugins = existing.plugins ?? {};
|
|
1409
|
+
const servers = existing.mcp_servers ?? {};
|
|
1410
|
+
if (!stringList$1(plugins.enabled) || !stringList$1(plugins.disabled) || memory.provider !== void 0 && typeof memory.provider !== "string") {
|
|
1411
|
+
p.log.warn(`Hermes provider or plugin settings are invalid. Left ${path} unchanged.`);
|
|
1412
|
+
return {
|
|
1413
|
+
kind: "skipped",
|
|
1414
|
+
reason: "invalid-config"
|
|
1415
|
+
};
|
|
1416
|
+
}
|
|
1417
|
+
if (servers.agentmemory !== void 0 && !record(servers.agentmemory) && !(opts.force && opts.withMcp)) {
|
|
1418
|
+
p.log.warn("Hermes's AgentMemory MCP entry is invalid. Repair it or use --force --with-mcp.");
|
|
1419
|
+
return {
|
|
1420
|
+
kind: "skipped",
|
|
1421
|
+
reason: "invalid-entry"
|
|
1422
|
+
};
|
|
1423
|
+
}
|
|
1424
|
+
if (memory.provider && memory.provider !== "agentmemory" && !opts.force) {
|
|
1425
|
+
p.log.warn("Hermes already selects another memory provider. Use --force to select AgentMemory and keep a backup.");
|
|
1426
|
+
return {
|
|
1427
|
+
kind: "skipped",
|
|
1428
|
+
reason: "memory-provider-conflict"
|
|
1429
|
+
};
|
|
1430
|
+
}
|
|
1431
|
+
if (plugins.disabled?.includes("agentmemory") && !opts.force) {
|
|
1432
|
+
p.log.warn("AgentMemory is disabled in this Hermes profile. Use --force to enable it.");
|
|
1433
|
+
return {
|
|
1434
|
+
kind: "skipped",
|
|
1435
|
+
reason: "plugin-disabled"
|
|
1436
|
+
};
|
|
1437
|
+
}
|
|
1438
|
+
try {
|
|
1439
|
+
const root = nativePackageRoot();
|
|
1440
|
+
const bundles = [prepareNativeBundle(join(root, "integrations", "hermes"), join(home, "plugins", "agentmemory"), "hermes-provider", ["__init__.py", "plugin.yaml"], opts.force), prepareNativeBundle(join(root, "plugin", "skills"), join(home, "skills", "agentmemory"), "hermes-skills", ["remember/SKILL.md", "recall/SKILL.md"], opts.force)];
|
|
1441
|
+
if (memory.provider !== "agentmemory") doc.setIn(["memory", "provider"], "agentmemory");
|
|
1442
|
+
const enabled = plugins.enabled ?? [];
|
|
1443
|
+
if (!enabled.includes("agentmemory")) doc.setIn(["plugins", "enabled"], [...enabled, "agentmemory"]);
|
|
1444
|
+
if (plugins.disabled?.includes("agentmemory")) doc.setIn(["plugins", "disabled"], plugins.disabled.filter((name) => name !== "agentmemory"));
|
|
1445
|
+
if (opts.withMcp) {
|
|
1446
|
+
p.log.warn("MCP exposes all AgentMemory tools against the configured backend. It does not enforce the native provider's profile scope; enable it only for a trusted, deliberately shared backend.");
|
|
1447
|
+
if (servers.agentmemory === void 0 || opts.force) {
|
|
1448
|
+
const entry = nativeMcpEntry(root);
|
|
1449
|
+
entry.env = {
|
|
1450
|
+
...entry.env,
|
|
1451
|
+
AGENTMEMORY_URL: "${AGENTMEMORY_URL}",
|
|
1452
|
+
AGENTMEMORY_SECRET: "${AGENTMEMORY_SECRET}",
|
|
1453
|
+
AGENTMEMORY_CREDENTIAL_MODE: "explicit"
|
|
1454
|
+
};
|
|
1455
|
+
doc.setIn(["mcp_servers", "agentmemory"], entry);
|
|
1456
|
+
} else p.log.info("Preserved the existing AgentMemory MCP entry. After moving the installed package, review its settings and reconnect with --with-mcp --force to refresh its runtime path.");
|
|
1457
|
+
}
|
|
1458
|
+
const configText = doc.toString();
|
|
1459
|
+
if (opts.dryRun) {
|
|
1460
|
+
p.log.info(`[dry-run] Would install the native provider and skills, then activate AgentMemory in ${path}`);
|
|
1461
|
+
return {
|
|
1462
|
+
kind: "installed",
|
|
1463
|
+
mutatedPath: path
|
|
1464
|
+
};
|
|
1465
|
+
}
|
|
1466
|
+
let backupPath;
|
|
1467
|
+
const unchanged = !bundles.some((bundle) => bundle.changed) && configText === raw;
|
|
1468
|
+
if (unchanged) logAlreadyWired(this.displayName, path);
|
|
1469
|
+
else {
|
|
1470
|
+
backupPath = installNativeBundles(bundles, path, configText);
|
|
1471
|
+
if (backupPath) logBackup(backupPath);
|
|
1472
|
+
logInstalled(this.displayName, path);
|
|
1473
|
+
}
|
|
1474
|
+
p.log.info("Authentication is not verified. Start AgentMemory, then run `hermes memory setup` in this same HERMES_HOME to set its URL and scoped secret. Verify a save and recall in a new session. Skills needing tools beyond native save, recall and search require the optional --with-mcp connection.");
|
|
1475
|
+
return unchanged ? {
|
|
1476
|
+
kind: "already-wired",
|
|
1477
|
+
mutatedPath: path
|
|
1478
|
+
} : {
|
|
1479
|
+
kind: "installed",
|
|
1480
|
+
mutatedPath: path,
|
|
1481
|
+
...backupPath ? { backupPath } : {}
|
|
1482
|
+
};
|
|
1483
|
+
} catch (error) {
|
|
1484
|
+
p.log.warn(error instanceof Error ? error.message : "Hermes installation failed; configuration was not activated.");
|
|
1485
|
+
return {
|
|
1486
|
+
kind: "skipped",
|
|
1487
|
+
reason: "native-install-failed"
|
|
1488
|
+
};
|
|
1489
|
+
}
|
|
1216
1490
|
}
|
|
1217
1491
|
};
|
|
1218
1492
|
//#endregion
|
|
1219
1493
|
//#region src/cli/connect/kiro.ts
|
|
1220
|
-
const adapter$
|
|
1494
|
+
const adapter$8 = createJsonMcpAdapter({
|
|
1221
1495
|
name: "kiro",
|
|
1222
1496
|
displayName: "Kiro",
|
|
1223
1497
|
detectDir: join(homedir(), ".kiro"),
|
|
@@ -1227,15 +1501,182 @@ const adapter$7 = createJsonMcpAdapter({
|
|
|
1227
1501
|
});
|
|
1228
1502
|
//#endregion
|
|
1229
1503
|
//#region src/cli/connect/openclaw.ts
|
|
1230
|
-
const
|
|
1504
|
+
const paths = () => {
|
|
1505
|
+
const home = nativeUserPath(process.env.OPENCLAW_HOME?.trim() || homedir(), homedir());
|
|
1506
|
+
const preferred = join(home, ".openclaw");
|
|
1507
|
+
const legacy = join(home, ".clawdbot");
|
|
1508
|
+
const state = process.env.OPENCLAW_STATE_DIR?.trim() ? nativeUserPath(process.env.OPENCLAW_STATE_DIR.trim(), home) : !existsSync(preferred) && existsSync(legacy) ? legacy : preferred;
|
|
1509
|
+
return {
|
|
1510
|
+
state,
|
|
1511
|
+
config: process.env.OPENCLAW_CONFIG_PATH?.trim() ? nativeUserPath(process.env.OPENCLAW_CONFIG_PATH.trim(), home) : !existsSync(join(state, "openclaw.json")) && existsSync(join(state, "clawdbot.json")) ? join(state, "clawdbot.json") : join(state, "openclaw.json")
|
|
1512
|
+
};
|
|
1513
|
+
};
|
|
1514
|
+
const stringList = (value) => value === void 0 || Array.isArray(value) && value.every((item) => typeof item === "string");
|
|
1515
|
+
const adapter$7 = {
|
|
1231
1516
|
name: "openclaw",
|
|
1232
1517
|
displayName: "OpenClaw",
|
|
1233
1518
|
category: "native",
|
|
1234
|
-
detectDir: join(homedir(), ".openclaw"),
|
|
1235
|
-
configPath: join(homedir(), ".openclaw", "openclaw.json"),
|
|
1236
1519
|
docs: "https://github.com/rohitg00/agentmemory/tree/main/integrations/openclaw",
|
|
1237
|
-
protocolNote: "→
|
|
1238
|
-
|
|
1520
|
+
protocolNote: "→ Installs native recall/capture and bundled skills into the active OpenClaw state directory. MCP tools are opt-in with --with-mcp.",
|
|
1521
|
+
detect: () => existsSync(paths().config) || existsSync(paths().state),
|
|
1522
|
+
async install(opts) {
|
|
1523
|
+
const { state, config: configPath } = paths();
|
|
1524
|
+
const raw = existsSync(configPath) ? readFileSync(configPath, "utf8") : "";
|
|
1525
|
+
let existing;
|
|
1526
|
+
try {
|
|
1527
|
+
existing = raw ? JSON5.parse(raw) : {};
|
|
1528
|
+
} catch {
|
|
1529
|
+
existing = null;
|
|
1530
|
+
}
|
|
1531
|
+
if (!record(existing) || [
|
|
1532
|
+
"mcp",
|
|
1533
|
+
"plugins",
|
|
1534
|
+
"skills"
|
|
1535
|
+
].some((key) => existing[key] !== void 0 && !record(existing[key]))) {
|
|
1536
|
+
p.log.warn(`OpenClaw config is not a valid JSON/JSON5 object. Left ${configPath} unchanged.`);
|
|
1537
|
+
return {
|
|
1538
|
+
kind: "skipped",
|
|
1539
|
+
reason: "invalid-config"
|
|
1540
|
+
};
|
|
1541
|
+
}
|
|
1542
|
+
const next = { ...existing };
|
|
1543
|
+
const mcp = { ...next.mcp ?? {} };
|
|
1544
|
+
if (mcp.servers !== void 0 && !record(mcp.servers)) return {
|
|
1545
|
+
kind: "skipped",
|
|
1546
|
+
reason: "invalid-config"
|
|
1547
|
+
};
|
|
1548
|
+
const servers = { ...mcp.servers ?? {} };
|
|
1549
|
+
const legacyServers = record(next.mcpServers) ? { ...next.mcpServers } : {};
|
|
1550
|
+
const legacy = legacyServers.agentmemory;
|
|
1551
|
+
const migrateLegacy = record(legacy) && legacy.command === "npx" && Array.isArray(legacy.args) && legacy.args.includes("@agentmemory/mcp");
|
|
1552
|
+
if (next.mcpServers !== void 0 && (!migrateLegacy || Object.keys(legacyServers).some((key) => key !== "agentmemory"))) {
|
|
1553
|
+
p.log.warn("OpenClaw rejects the legacy mcpServers key. Left the file unchanged; migrate custom servers with OpenClaw's native configuration tools first.");
|
|
1554
|
+
return {
|
|
1555
|
+
kind: "skipped",
|
|
1556
|
+
reason: "legacy-config-needs-migration"
|
|
1557
|
+
};
|
|
1558
|
+
}
|
|
1559
|
+
if (servers.agentmemory !== void 0 && !record(servers.agentmemory) && !(opts.force && opts.withMcp)) {
|
|
1560
|
+
p.log.warn("OpenClaw's AgentMemory MCP entry is invalid. Repair it or use --force --with-mcp.");
|
|
1561
|
+
return {
|
|
1562
|
+
kind: "skipped",
|
|
1563
|
+
reason: "invalid-entry"
|
|
1564
|
+
};
|
|
1565
|
+
}
|
|
1566
|
+
const plugins = { ...next.plugins ?? {} };
|
|
1567
|
+
const skills = { ...next.skills ?? {} };
|
|
1568
|
+
if (["entries", "slots"].some((key) => plugins[key] !== void 0 && !record(plugins[key])) || skills.load !== void 0 && !record(skills.load) || !stringList(plugins.allow) || !stringList(plugins.deny)) return {
|
|
1569
|
+
kind: "skipped",
|
|
1570
|
+
reason: "invalid-config"
|
|
1571
|
+
};
|
|
1572
|
+
const entries = { ...plugins.entries ?? {} };
|
|
1573
|
+
const slots = { ...plugins.slots ?? {} };
|
|
1574
|
+
if (!stringList({ ...skills.load ?? {} }.extraDirs) || entries.agentmemory !== void 0 && !record(entries.agentmemory) || slots.memory !== void 0 && typeof slots.memory !== "string") return {
|
|
1575
|
+
kind: "skipped",
|
|
1576
|
+
reason: "invalid-config"
|
|
1577
|
+
};
|
|
1578
|
+
if (slots.memory !== void 0 && slots.memory !== "agentmemory" && !opts.force) {
|
|
1579
|
+
p.log.warn("OpenClaw already selects another memory plugin. Use --force to select AgentMemory and keep a backup.");
|
|
1580
|
+
return {
|
|
1581
|
+
kind: "skipped",
|
|
1582
|
+
reason: "memory-provider-conflict"
|
|
1583
|
+
};
|
|
1584
|
+
}
|
|
1585
|
+
const entry = { ...entries.agentmemory ?? {} };
|
|
1586
|
+
if (entry.hooks !== void 0 && !record(entry.hooks)) return {
|
|
1587
|
+
kind: "skipped",
|
|
1588
|
+
reason: "invalid-config"
|
|
1589
|
+
};
|
|
1590
|
+
const hooks = { ...entry.hooks ?? {} };
|
|
1591
|
+
if (plugins.enabled === false || !opts.force && (entry.enabled === false || hooks.allowConversationAccess === false || plugins.deny?.includes("agentmemory"))) {
|
|
1592
|
+
p.log.warn("OpenClaw plugin execution or AgentMemory conversation access is disabled. Enable it explicitly before connecting, or use --force for AgentMemory's own settings.");
|
|
1593
|
+
return {
|
|
1594
|
+
kind: "skipped",
|
|
1595
|
+
reason: "plugin-disabled"
|
|
1596
|
+
};
|
|
1597
|
+
}
|
|
1598
|
+
try {
|
|
1599
|
+
const root = nativePackageRoot();
|
|
1600
|
+
const bundles = [prepareNativeBundle(join(root, "integrations", "openclaw"), join(state, "extensions", "agentmemory"), "openclaw-plugin", [
|
|
1601
|
+
"plugin.mjs",
|
|
1602
|
+
"openclaw.plugin.json",
|
|
1603
|
+
"package.json"
|
|
1604
|
+
], opts.force, join(root, "plugin", "skills"))];
|
|
1605
|
+
if (opts.withMcp || migrateLegacy) {
|
|
1606
|
+
p.log.warn("MCP exposes all AgentMemory tools against the configured backend. It does not enforce native profile scope; use it only for a trusted, deliberately shared backend.");
|
|
1607
|
+
if (servers.agentmemory === void 0 || opts.force) {
|
|
1608
|
+
const migrated = migrateLegacy && !opts.force ? { ...legacy } : {};
|
|
1609
|
+
const runtime = nativeMcpEntry(root);
|
|
1610
|
+
const env = {
|
|
1611
|
+
...runtime.env,
|
|
1612
|
+
...record(migrated.env) ? migrated.env : {}
|
|
1613
|
+
};
|
|
1614
|
+
for (const [key, value] of Object.entries(env)) {
|
|
1615
|
+
if (key === "AGENTMEMORY_URL" && value === "${AGENTMEMORY_URL:-http://localhost:3111}" || key === "AGENTMEMORY_SECRET" && value === "${AGENTMEMORY_SECRET:-}") delete env[key];
|
|
1616
|
+
if (key === "AGENTMEMORY_TOOLS" && value === "${AGENTMEMORY_TOOLS:-all}") env[key] = "all";
|
|
1617
|
+
}
|
|
1618
|
+
servers.agentmemory = {
|
|
1619
|
+
...migrated,
|
|
1620
|
+
...runtime,
|
|
1621
|
+
transport: "stdio",
|
|
1622
|
+
env
|
|
1623
|
+
};
|
|
1624
|
+
} else p.log.info("Preserved the existing AgentMemory MCP entry. After moving the installed package, review its settings and reconnect with --with-mcp --force to refresh its runtime path.");
|
|
1625
|
+
if (migrateLegacy) delete next.mcpServers;
|
|
1626
|
+
next.mcp = {
|
|
1627
|
+
...mcp,
|
|
1628
|
+
servers
|
|
1629
|
+
};
|
|
1630
|
+
}
|
|
1631
|
+
entries.agentmemory = {
|
|
1632
|
+
...entry,
|
|
1633
|
+
enabled: true,
|
|
1634
|
+
hooks: {
|
|
1635
|
+
...hooks,
|
|
1636
|
+
allowConversationAccess: true
|
|
1637
|
+
}
|
|
1638
|
+
};
|
|
1639
|
+
plugins.entries = entries;
|
|
1640
|
+
plugins.slots = {
|
|
1641
|
+
...slots,
|
|
1642
|
+
memory: "agentmemory"
|
|
1643
|
+
};
|
|
1644
|
+
if (plugins.allow !== void 0) plugins.allow = [...new Set([...plugins.allow, "agentmemory"])];
|
|
1645
|
+
if (plugins.deny?.includes("agentmemory")) plugins.deny = plugins.deny.filter((name) => name !== "agentmemory");
|
|
1646
|
+
next.plugins = plugins;
|
|
1647
|
+
const configText = JSON.stringify(next) === JSON.stringify(existing) ? raw : JSON.stringify(next, null, 2) + "\n";
|
|
1648
|
+
if (opts.dryRun) {
|
|
1649
|
+
p.log.info(`[dry-run] Would install native plugin and skills, then activate AgentMemory in ${configPath}`);
|
|
1650
|
+
return {
|
|
1651
|
+
kind: "installed",
|
|
1652
|
+
mutatedPath: configPath
|
|
1653
|
+
};
|
|
1654
|
+
}
|
|
1655
|
+
if (!bundles.some((bundle) => bundle.changed) && configText === raw) {
|
|
1656
|
+
logAlreadyWired(this.displayName, configPath);
|
|
1657
|
+
return {
|
|
1658
|
+
kind: "already-wired",
|
|
1659
|
+
mutatedPath: configPath
|
|
1660
|
+
};
|
|
1661
|
+
}
|
|
1662
|
+
const backupPath = installNativeBundles(bundles, configPath, configText);
|
|
1663
|
+
if (backupPath) logBackup(backupPath);
|
|
1664
|
+
logInstalled(this.displayName, configPath);
|
|
1665
|
+
p.log.info("Start AgentMemory and verify capture and recall in a new OpenClaw session. Skills that call memory tools require --with-mcp; authentication and connectivity are not yet verified.");
|
|
1666
|
+
return {
|
|
1667
|
+
kind: "installed",
|
|
1668
|
+
mutatedPath: configPath,
|
|
1669
|
+
...backupPath ? { backupPath } : {}
|
|
1670
|
+
};
|
|
1671
|
+
} catch (error) {
|
|
1672
|
+
p.log.warn(error instanceof Error ? error.message : "OpenClaw installation failed; configuration was not activated.");
|
|
1673
|
+
return {
|
|
1674
|
+
kind: "skipped",
|
|
1675
|
+
reason: "native-install-failed"
|
|
1676
|
+
};
|
|
1677
|
+
}
|
|
1678
|
+
}
|
|
1679
|
+
};
|
|
1239
1680
|
//#endregion
|
|
1240
1681
|
//#region src/cli/connect/opencode.ts
|
|
1241
1682
|
const CONFIG_PATH = join(homedir(), ".config", "opencode", "opencode.json");
|
|
@@ -1254,7 +1695,7 @@ function entryMatches(entry) {
|
|
|
1254
1695
|
const command = entry["command"];
|
|
1255
1696
|
return Array.isArray(command) && command.includes("@agentmemory/mcp");
|
|
1256
1697
|
}
|
|
1257
|
-
const adapter$
|
|
1698
|
+
const adapter$6 = {
|
|
1258
1699
|
name: "opencode",
|
|
1259
1700
|
displayName: "OpenCode",
|
|
1260
1701
|
category: "mcp",
|
|
@@ -1310,12 +1751,12 @@ const adapter$5 = {
|
|
|
1310
1751
|
//#endregion
|
|
1311
1752
|
//#region src/cli/connect/openhuman.ts
|
|
1312
1753
|
const OPENHUMAN_DIR = join(homedir(), ".openhuman");
|
|
1313
|
-
const DOCS
|
|
1314
|
-
const adapter$
|
|
1754
|
+
const DOCS = "https://github.com/tinyhumansai/openhuman";
|
|
1755
|
+
const adapter$5 = {
|
|
1315
1756
|
name: "openhuman",
|
|
1316
1757
|
displayName: "OpenHuman",
|
|
1317
1758
|
category: "native",
|
|
1318
|
-
docs: DOCS
|
|
1759
|
+
docs: DOCS,
|
|
1319
1760
|
protocolNote: "→ Using native hooks (REST API at :3111). MCP not required.",
|
|
1320
1761
|
detect() {
|
|
1321
1762
|
return existsSync(OPENHUMAN_DIR);
|
|
@@ -1328,7 +1769,7 @@ const adapter$4 = {
|
|
|
1328
1769
|
"impl. Once integrations/openhuman/ lands in agentmemory we'll wire",
|
|
1329
1770
|
"this up automatically.",
|
|
1330
1771
|
"",
|
|
1331
|
-
`Tracking: ${DOCS
|
|
1772
|
+
`Tracking: ${DOCS}`
|
|
1332
1773
|
].join("\n"), "OpenHuman manual install");
|
|
1333
1774
|
return {
|
|
1334
1775
|
kind: "stub",
|
|
@@ -1337,80 +1778,225 @@ const adapter$4 = {
|
|
|
1337
1778
|
}
|
|
1338
1779
|
};
|
|
1339
1780
|
//#endregion
|
|
1340
|
-
//#region src/cli/connect/
|
|
1341
|
-
|
|
1342
|
-
const
|
|
1343
|
-
const
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
}
|
|
1352
|
-
const dir = join(packageRoot, "integrations", "pi");
|
|
1353
|
-
return EXT_FILES.every((f) => existsSync(join(dir, f))) ? dir : null;
|
|
1781
|
+
//#region src/cli/connect/omp.ts
|
|
1782
|
+
function ompPaths() {
|
|
1783
|
+
const root = join(homedir(), process.env.PI_CONFIG_DIR || ".omp");
|
|
1784
|
+
const profile = (process.env.OMP_PROFILE ?? process.env.PI_PROFILE ?? "").trim();
|
|
1785
|
+
if (profile && profile !== "default" && (!/^[a-z0-9][a-z0-9._-]{0,63}$/.test(profile) || profile.endsWith(".") || /^(?:con|prn|aux|nul|com[0-9]|lpt[0-9])(?:\..*)?$/i.test(profile))) throw new Error("Invalid OMP profile; use the same valid OMP_PROFILE as Oh My Pi.");
|
|
1786
|
+
const configRoot = profile && profile !== "default" ? join(root, "profiles", profile) : root;
|
|
1787
|
+
return {
|
|
1788
|
+
root: configRoot,
|
|
1789
|
+
agent: configRoot !== root ? join(configRoot, "agent") : process.env.PI_CODING_AGENT_DIR ? resolve(process.env.PI_CODING_AGENT_DIR) : join(root, "agent"),
|
|
1790
|
+
profile: profile && profile !== "default" ? profile : void 0
|
|
1791
|
+
};
|
|
1354
1792
|
}
|
|
1355
|
-
const adapter$
|
|
1356
|
-
name: "
|
|
1357
|
-
displayName: "
|
|
1793
|
+
const adapter$4 = {
|
|
1794
|
+
name: "omp",
|
|
1795
|
+
displayName: "Oh My Pi",
|
|
1358
1796
|
category: "native",
|
|
1359
|
-
docs:
|
|
1360
|
-
protocolNote: "
|
|
1361
|
-
detect() {
|
|
1362
|
-
|
|
1797
|
+
docs: "https://github.com/rohitg00/agentmemory/tree/main/integrations/omp",
|
|
1798
|
+
protocolNote: "Installs native recall, capture and skills. Add --with-mcp for the full memory toolset.",
|
|
1799
|
+
detect: () => {
|
|
1800
|
+
try {
|
|
1801
|
+
const paths = ompPaths();
|
|
1802
|
+
return existsSync(paths.agent) || existsSync(paths.root);
|
|
1803
|
+
} catch {
|
|
1804
|
+
return false;
|
|
1805
|
+
}
|
|
1363
1806
|
},
|
|
1364
1807
|
async install(opts) {
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1808
|
+
try {
|
|
1809
|
+
const paths = ompPaths();
|
|
1810
|
+
const target = join(paths.agent, "agentmemory");
|
|
1811
|
+
const config = join(paths.agent, existsSync(join(paths.agent, "config.yml")) || !existsSync(join(paths.agent, "config.yaml")) ? "config.yml" : "config.yaml");
|
|
1812
|
+
const raw = existsSync(config) ? readFileSync(config, "utf8") : "";
|
|
1813
|
+
const legacy = join(paths.agent, "settings.json");
|
|
1814
|
+
const doc = !existsSync(config) && existsSync(legacy) ? new Document(JSON.parse(readFileSync(legacy, "utf8"))) : parseDocument(raw);
|
|
1815
|
+
const existing = doc.contents === null ? {} : doc.toJS({ maxAliasCount: 100 });
|
|
1816
|
+
if (doc.errors.length || !record(existing) || existing.extensions !== void 0 && (!Array.isArray(existing.extensions) || !existing.extensions.every((item) => typeof item === "string"))) throw new Error(`Invalid OMP configuration; left ${config} unchanged.`);
|
|
1817
|
+
const extensions = existing.extensions ?? [];
|
|
1818
|
+
const oldRoots = [
|
|
1819
|
+
...extensions.map((value) => nativeUserPath(value, homedir())).filter((value) => value !== target),
|
|
1820
|
+
join(paths.root, "plugins/node_modules/agentmemory-omp-extension"),
|
|
1821
|
+
join(paths.agent, "plugins/node_modules/agentmemory-omp-extension"),
|
|
1822
|
+
join(process.cwd(), ".omp/plugins/node_modules/agentmemory-omp-extension"),
|
|
1823
|
+
join(paths.agent, "extensions/agentmemory")
|
|
1824
|
+
];
|
|
1825
|
+
if (process.platform === "linux") {
|
|
1826
|
+
const dataRoot = join(process.env.XDG_DATA_HOME || join(homedir(), ".local/share"), "omp");
|
|
1827
|
+
oldRoots.push(join(dataRoot, ...paths.profile ? ["profiles", paths.profile] : [], "plugins/node_modules/agentmemory-omp-extension"));
|
|
1828
|
+
}
|
|
1829
|
+
for (const old of oldRoots) {
|
|
1830
|
+
const manifest = join(old, "package.json");
|
|
1831
|
+
if (existsSync(manifest) && JSON.parse(readFileSync(manifest, "utf8")).name === "agentmemory-omp-extension") throw new Error(`Another OMP AgentMemory extension exists at ${old}. Uninstall it with 'omp plugin uninstall agentmemory-omp-extension' or remove its extensions entry before reconnecting, to prevent duplicate capture.`);
|
|
1832
|
+
}
|
|
1833
|
+
const root = nativePackageRoot();
|
|
1834
|
+
const mcpPath = join(target, ".mcp.json");
|
|
1835
|
+
const extra = {};
|
|
1836
|
+
if (existsSync(mcpPath)) extra[".mcp.json"] = readFileSync(mcpPath, "utf8");
|
|
1837
|
+
let userOwnsMcp = false;
|
|
1838
|
+
if (opts.withMcp || existsSync(mcpPath)) {
|
|
1839
|
+
const nativeMcpPath = join(paths.agent, "mcp.json");
|
|
1840
|
+
userOwnsMcp = (existsSync(nativeMcpPath) ? JSON.parse(readFileSync(nativeMcpPath, "utf8")) : {}).mcpServers?.agentmemory !== void 0;
|
|
1841
|
+
if (userOwnsMcp) {
|
|
1842
|
+
delete extra[".mcp.json"];
|
|
1843
|
+
p.log.info("Preserved the existing AgentMemory MCP server in OMP's mcp.json.");
|
|
1844
|
+
} else if (opts.withMcp) extra[".mcp.json"] = JSON.stringify({ mcpServers: { agentmemory: nativeMcpEntry(root) } }, null, 2) + "\n";
|
|
1845
|
+
}
|
|
1846
|
+
const bundle = prepareNativeBundle(join(root, "integrations/omp"), target, "omp-extension", ["package.json", "dist/index.mjs"], opts.force, join(root, "plugin/skills"), extra);
|
|
1847
|
+
if (userOwnsMcp && existsSync(mcpPath) && !bundle.previous[".mcp.json"] && JSON.parse(readFileSync(mcpPath, "utf8")).mcpServers?.agentmemory !== void 0) throw new Error(`Unmanaged ${mcpPath} conflicts with OMP's mcp.json. Remove the duplicate AgentMemory configuration before reconnecting.`);
|
|
1848
|
+
if (!extensions.includes(target)) doc.set("extensions", [...extensions, target]);
|
|
1849
|
+
const text = doc.toString();
|
|
1850
|
+
if (opts.dryRun) {
|
|
1851
|
+
p.log.info(`[dry-run] Would install OMP's extension and skills into ${target}, then register it in ${config}.`);
|
|
1852
|
+
return {
|
|
1853
|
+
kind: "installed",
|
|
1854
|
+
mutatedPath: config
|
|
1855
|
+
};
|
|
1856
|
+
}
|
|
1857
|
+
const unchanged = !bundle.changed && text === raw;
|
|
1858
|
+
const backupPath = unchanged ? void 0 : installNativeBundles([bundle], config, text);
|
|
1859
|
+
if (backupPath) logBackup(backupPath);
|
|
1860
|
+
if (unchanged) logAlreadyWired(this.displayName, config);
|
|
1861
|
+
else logInstalled(this.displayName, config);
|
|
1862
|
+
p.log.info("Restart OMP and run /agentmemory-status. Native save/search work without MCP; the other bundled skills require --with-mcp. Project extensions arrays override this user setting: include the installed directory there when overriding extensions.");
|
|
1863
|
+
return unchanged ? {
|
|
1864
|
+
kind: "already-wired",
|
|
1865
|
+
mutatedPath: config
|
|
1866
|
+
} : {
|
|
1867
|
+
kind: "installed",
|
|
1868
|
+
mutatedPath: config,
|
|
1869
|
+
...backupPath ? { backupPath } : {}
|
|
1371
1870
|
};
|
|
1372
|
-
}
|
|
1373
|
-
|
|
1374
|
-
name: f,
|
|
1375
|
-
content: readFileSync(join(sourceDir, f), "utf-8"),
|
|
1376
|
-
target: join(PI_EXT_DIR, f)
|
|
1377
|
-
}));
|
|
1378
|
-
if (sources.every((s) => existsSync(s.target) && readFileSync(s.target, "utf-8") === s.content) && !opts.force) {
|
|
1379
|
-
logAlreadyWired(this.displayName, PI_EXT_DIR);
|
|
1871
|
+
} catch (error) {
|
|
1872
|
+
p.log.warn(error instanceof Error ? error.message : "OMP installation failed.");
|
|
1380
1873
|
return {
|
|
1381
|
-
kind: "
|
|
1382
|
-
|
|
1874
|
+
kind: "skipped",
|
|
1875
|
+
reason: "native-install-failed"
|
|
1383
1876
|
};
|
|
1384
1877
|
}
|
|
1385
|
-
|
|
1386
|
-
|
|
1878
|
+
}
|
|
1879
|
+
};
|
|
1880
|
+
//#endregion
|
|
1881
|
+
//#region src/cli/connect/pi.ts
|
|
1882
|
+
const agentDir = () => process.env.PI_CODING_AGENT_DIR ? nativeUserPath(process.env.PI_CODING_AGENT_DIR, homedir()) : join(homedir(), ".pi/agent");
|
|
1883
|
+
const entryHash = (entry) => createHash("sha256").update(JSON.stringify(entry)).digest("hex");
|
|
1884
|
+
function readConfig(path) {
|
|
1885
|
+
if (!existsSync(path)) return {};
|
|
1886
|
+
if (lstatSync(path).isSymbolicLink()) throw new Error(`Pi configuration is a symbolic link; left ${path} unchanged.`);
|
|
1887
|
+
const value = JSON.parse(readFileSync(path, "utf8"));
|
|
1888
|
+
if (!record(value)) throw new Error(`Invalid Pi configuration; left ${path} unchanged.`);
|
|
1889
|
+
return value;
|
|
1890
|
+
}
|
|
1891
|
+
function hasPackage(config, configDir, target) {
|
|
1892
|
+
if (config.packages === void 0) return false;
|
|
1893
|
+
if (!Array.isArray(config.packages)) throw new Error("Pi settings.packages must be an array.");
|
|
1894
|
+
return config.packages.some((item) => {
|
|
1895
|
+
const source = typeof item === "string" ? item : record(item) ? item.source : void 0;
|
|
1896
|
+
if (typeof source !== "string") throw new Error("Invalid Pi package entry; configuration was preserved.");
|
|
1897
|
+
if (/^npm:@agentmemory\/pi(?:@|$)/.test(source)) return true;
|
|
1898
|
+
const path = source.startsWith("~") ? nativeUserPath(source, homedir()) : resolve(configDir, source);
|
|
1899
|
+
if (path === target) return false;
|
|
1900
|
+
const manifest = join(path, "package.json");
|
|
1901
|
+
return existsSync(manifest) && JSON.parse(readFileSync(manifest, "utf8")).name === "@agentmemory/pi";
|
|
1902
|
+
});
|
|
1903
|
+
}
|
|
1904
|
+
const adapter$3 = {
|
|
1905
|
+
name: "pi",
|
|
1906
|
+
displayName: "Pi",
|
|
1907
|
+
category: "native",
|
|
1908
|
+
docs: "https://github.com/rohitg00/agentmemory/tree/main/integrations/pi",
|
|
1909
|
+
protocolNote: "Installs native recall, capture and skills. Add --with-mcp for the full memory toolset.",
|
|
1910
|
+
detect: () => existsSync(agentDir()) || existsSync(join(homedir(), ".pi")),
|
|
1911
|
+
async install(opts) {
|
|
1912
|
+
try {
|
|
1913
|
+
const dir = agentDir();
|
|
1914
|
+
const target = join(dir, "agentmemory");
|
|
1915
|
+
const configPath = join(dir, "settings.json");
|
|
1916
|
+
const config = readConfig(configPath);
|
|
1917
|
+
const projectPath = join(process.cwd(), ".pi/settings.json");
|
|
1918
|
+
const packaged = hasPackage(config, dir, target);
|
|
1919
|
+
const projectConfig = readConfig(projectPath);
|
|
1920
|
+
if (!packaged && hasPackage(projectConfig, dirname(projectPath), target)) throw new Error("AgentMemory is configured as a project Pi package. Remove that package entry before installing globally, or keep using the project installation.");
|
|
1921
|
+
for (const [settings, base] of [[config, dir], [projectConfig, dirname(projectPath)]]) {
|
|
1922
|
+
if (!Array.isArray(settings.extensions)) continue;
|
|
1923
|
+
for (const entry of settings.extensions) {
|
|
1924
|
+
if (typeof entry !== "string") continue;
|
|
1925
|
+
const path = entry.startsWith("~") ? nativeUserPath(entry, homedir()) : resolve(base, entry);
|
|
1926
|
+
const manifest = join(/\.[cm]?[jt]s$/.test(path) ? dirname(path) : path, "package.json");
|
|
1927
|
+
if (existsSync(manifest) && JSON.parse(readFileSync(manifest, "utf8")).name === "@agentmemory/pi") throw new Error("Remove the explicit AgentMemory extensions entry before connecting; the package already declares its extension.");
|
|
1928
|
+
}
|
|
1929
|
+
}
|
|
1930
|
+
const legacy = join(dir, "extensions/agentmemory");
|
|
1931
|
+
if (existsSync(legacy)) throw new Error(`Move the old copied extension at ${legacy} outside Pi's extensions directory before reconnecting, to prevent duplicate capture. Keep it as a backup.`);
|
|
1932
|
+
const root = nativePackageRoot();
|
|
1933
|
+
const bundle = packaged ? void 0 : prepareNativeBundle(join(root, "integrations/pi"), target, "pi-extension", ["package.json", "dist/index.mjs"], opts.force, join(root, "plugin/skills"));
|
|
1934
|
+
if (packaged) p.log.info("Using the existing AgentMemory Pi package; no second extension was installed.");
|
|
1935
|
+
else {
|
|
1936
|
+
const packages = config.packages ?? [];
|
|
1937
|
+
if (!packages.some((item) => (typeof item === "string" ? item : record(item) ? item.source : void 0) === target)) config.packages = [...packages, target];
|
|
1938
|
+
}
|
|
1939
|
+
const text = JSON.stringify(config, null, 2) + "\n";
|
|
1940
|
+
const raw = existsSync(configPath) ? readFileSync(configPath, "utf8") : void 0;
|
|
1941
|
+
const mcpPath = join(dir, "mcp.json");
|
|
1942
|
+
const mcpRaw = existsSync(mcpPath) ? readFileSync(mcpPath, "utf8") : void 0;
|
|
1943
|
+
let mcpText = mcpRaw;
|
|
1944
|
+
if (opts.withMcp) {
|
|
1945
|
+
const mcp = readConfig(mcpPath);
|
|
1946
|
+
if (mcp.mcpServers !== void 0 && !record(mcp.mcpServers)) throw new Error("Invalid Pi mcpServers configuration; nothing was changed.");
|
|
1947
|
+
const servers = mcp.mcpServers ?? {};
|
|
1948
|
+
const managed = servers.agentmemory !== void 0 && record(mcp._agentmemoryConnector) && mcp._agentmemoryConnector.entryHash === entryHash(servers.agentmemory);
|
|
1949
|
+
if (servers.agentmemory !== void 0 && !managed) p.log.info("Preserved the existing AgentMemory MCP server. Project MCP settings apply only to trusted projects.");
|
|
1950
|
+
else {
|
|
1951
|
+
const entry = {
|
|
1952
|
+
...nativeMcpEntry(root),
|
|
1953
|
+
exposure: "direct"
|
|
1954
|
+
};
|
|
1955
|
+
mcpText = JSON.stringify({
|
|
1956
|
+
...mcp,
|
|
1957
|
+
mcpServers: {
|
|
1958
|
+
...servers,
|
|
1959
|
+
agentmemory: entry
|
|
1960
|
+
},
|
|
1961
|
+
_agentmemoryConnector: { entryHash: entryHash(entry) }
|
|
1962
|
+
}, null, 2) + "\n";
|
|
1963
|
+
}
|
|
1964
|
+
}
|
|
1965
|
+
if (opts.dryRun) {
|
|
1966
|
+
p.log.info(`[dry-run] Would configure Pi in ${dir}.`);
|
|
1967
|
+
return {
|
|
1968
|
+
kind: "installed",
|
|
1969
|
+
mutatedPath: configPath
|
|
1970
|
+
};
|
|
1971
|
+
}
|
|
1972
|
+
const configChanged = !packaged && (bundle.changed || text !== raw);
|
|
1973
|
+
const mcpChanged = mcpText !== mcpRaw;
|
|
1974
|
+
let backupPath;
|
|
1975
|
+
if (mcpChanged) backupPath = installNativeBundles([], mcpPath, mcpText);
|
|
1976
|
+
try {
|
|
1977
|
+
if (configChanged) backupPath = installNativeBundles([bundle], configPath, text) ?? backupPath;
|
|
1978
|
+
} catch (error) {
|
|
1979
|
+
if (mcpChanged) if (mcpRaw === void 0) rmSync(mcpPath, { force: true });
|
|
1980
|
+
else installNativeBundles([], mcpPath, mcpRaw);
|
|
1981
|
+
throw error;
|
|
1982
|
+
}
|
|
1983
|
+
if (backupPath) logBackup(backupPath);
|
|
1984
|
+
const changed = configChanged || mcpChanged;
|
|
1985
|
+
if (changed) logInstalled(this.displayName, dir);
|
|
1986
|
+
else logAlreadyWired(this.displayName, dir);
|
|
1987
|
+
p.log.info("Restart Pi or /reload, then /agentmemory-status. Skills appear as /skill:<name>; the wider workflows require MCP. Reconnect after upgrading AgentMemory to refresh bundled runtime paths.");
|
|
1387
1988
|
return {
|
|
1388
|
-
kind: "installed",
|
|
1389
|
-
mutatedPath:
|
|
1989
|
+
kind: changed ? "installed" : "already-wired",
|
|
1990
|
+
mutatedPath: configPath,
|
|
1991
|
+
...backupPath ? { backupPath } : {}
|
|
1390
1992
|
};
|
|
1391
|
-
}
|
|
1392
|
-
|
|
1393
|
-
for (const s of sources) if (existsSync(s.target) && readFileSync(s.target, "utf-8") !== s.content) {
|
|
1394
|
-
const backup = backupFile(s.target, `${this.name}-${s.name.replace(/\.ts$/, "")}`, "ts");
|
|
1395
|
-
logBackup(backup);
|
|
1396
|
-
backupPath ??= backup;
|
|
1397
|
-
}
|
|
1398
|
-
mkdirSync(PI_EXT_DIR, { recursive: true });
|
|
1399
|
-
for (const s of sources) writeTextAtomic(s.target, s.content);
|
|
1400
|
-
if (!sources.every((s) => existsSync(s.target) && readFileSync(s.target, "utf-8") === s.content)) {
|
|
1401
|
-
p.log.error(`Verification failed: ${PI_EXT_DIR} does not match the bundled extension.`);
|
|
1993
|
+
} catch (error) {
|
|
1994
|
+
p.log.warn(error instanceof Error ? error.message : "Pi installation failed.");
|
|
1402
1995
|
return {
|
|
1403
1996
|
kind: "skipped",
|
|
1404
|
-
reason: "
|
|
1997
|
+
reason: "native-install-failed"
|
|
1405
1998
|
};
|
|
1406
1999
|
}
|
|
1407
|
-
logInstalled(this.displayName, PI_EXT_DIR);
|
|
1408
|
-
p.log.info("pi auto-discovers the extension on next launch; a running pi picks it up with /reload. Verify with /agentmemory-status.");
|
|
1409
|
-
return {
|
|
1410
|
-
kind: "installed",
|
|
1411
|
-
mutatedPath: PI_EXT_DIR,
|
|
1412
|
-
backupPath
|
|
1413
|
-
};
|
|
1414
2000
|
}
|
|
1415
2001
|
};
|
|
1416
2002
|
//#endregion
|
|
@@ -1455,27 +2041,28 @@ var connect_exports = /* @__PURE__ */ __exportAll({
|
|
|
1455
2041
|
runConnect: () => runConnect
|
|
1456
2042
|
});
|
|
1457
2043
|
const ADAPTERS = [
|
|
1458
|
-
adapter$
|
|
2044
|
+
adapter$19,
|
|
2045
|
+
adapter$17,
|
|
1459
2046
|
adapter$16,
|
|
1460
|
-
adapter$
|
|
2047
|
+
adapter$14,
|
|
1461
2048
|
adapter$13,
|
|
1462
|
-
adapter$
|
|
1463
|
-
adapter$9,
|
|
2049
|
+
adapter$10,
|
|
1464
2050
|
adapter$2,
|
|
1465
2051
|
adapter$20,
|
|
1466
|
-
adapter$
|
|
1467
|
-
adapter$
|
|
2052
|
+
adapter$21,
|
|
2053
|
+
adapter$8,
|
|
1468
2054
|
adapter$1,
|
|
1469
|
-
adapter$
|
|
1470
|
-
adapter$
|
|
2055
|
+
adapter$18,
|
|
2056
|
+
adapter$15,
|
|
1471
2057
|
adapter,
|
|
2058
|
+
adapter$12,
|
|
1472
2059
|
adapter$11,
|
|
1473
|
-
adapter$10,
|
|
1474
|
-
adapter$5,
|
|
1475
2060
|
adapter$6,
|
|
1476
|
-
adapter$
|
|
2061
|
+
adapter$7,
|
|
2062
|
+
adapter$9,
|
|
1477
2063
|
adapter$3,
|
|
1478
|
-
adapter$4
|
|
2064
|
+
adapter$4,
|
|
2065
|
+
adapter$5
|
|
1479
2066
|
];
|
|
1480
2067
|
function resolveAdapter(name) {
|
|
1481
2068
|
const lower = name.toLowerCase();
|
|
@@ -1490,11 +2077,13 @@ function parseFlags(args) {
|
|
|
1490
2077
|
let force = false;
|
|
1491
2078
|
let all = false;
|
|
1492
2079
|
let withHooks = false;
|
|
2080
|
+
let withMcp = false;
|
|
1493
2081
|
let guidelines = true;
|
|
1494
2082
|
for (const a of args) if (a === "--dry-run") dryRun = true;
|
|
1495
2083
|
else if (a === "--force") force = true;
|
|
1496
2084
|
else if (a === "--all") all = true;
|
|
1497
2085
|
else if (a === "--with-hooks") withHooks = true;
|
|
2086
|
+
else if (a === "--with-mcp") withMcp = true;
|
|
1498
2087
|
else if (a === "--no-guidelines") guidelines = false;
|
|
1499
2088
|
else if (!a.startsWith("-")) positional.push(a);
|
|
1500
2089
|
return {
|
|
@@ -1502,6 +2091,7 @@ function parseFlags(args) {
|
|
|
1502
2091
|
force,
|
|
1503
2092
|
all,
|
|
1504
2093
|
withHooks,
|
|
2094
|
+
withMcp,
|
|
1505
2095
|
guidelines,
|
|
1506
2096
|
positional
|
|
1507
2097
|
};
|
|
@@ -1538,7 +2128,7 @@ async function runAdapter(adapter, opts) {
|
|
|
1538
2128
|
}
|
|
1539
2129
|
}
|
|
1540
2130
|
async function runConnect(args) {
|
|
1541
|
-
const { dryRun, force, all, withHooks, guidelines, positional } = parseFlags(args);
|
|
2131
|
+
const { dryRun, force, all, withHooks, withMcp, guidelines, positional } = parseFlags(args);
|
|
1542
2132
|
const allowWindowsAdapter = positional.length === 1 && positional[0]?.toLowerCase() === "copilot-cli";
|
|
1543
2133
|
if (platform() === "win32" && !allowWindowsAdapter) {
|
|
1544
2134
|
p.intro("agentmemory connect");
|
|
@@ -1550,6 +2140,7 @@ async function runConnect(args) {
|
|
|
1550
2140
|
dryRun,
|
|
1551
2141
|
force,
|
|
1552
2142
|
withHooks,
|
|
2143
|
+
withMcp,
|
|
1553
2144
|
guidelines
|
|
1554
2145
|
};
|
|
1555
2146
|
p.intro("agentmemory connect");
|
|
@@ -1624,10 +2215,17 @@ function summarize(results) {
|
|
|
1624
2215
|
p.note(lines.join("\n"), "summary");
|
|
1625
2216
|
const stubs = results.filter((r) => r.result.kind === "stub");
|
|
1626
2217
|
if (stubs.length > 0) p.log.info(`${stubs.length} agent(s) require manual install — see docs links above.`);
|
|
1627
|
-
if (results.some((r) =>
|
|
2218
|
+
if (results.some((r) => ![
|
|
2219
|
+
"hermes",
|
|
2220
|
+
"hermes-agent",
|
|
2221
|
+
"openclaw",
|
|
2222
|
+
"claw",
|
|
2223
|
+
"omp",
|
|
2224
|
+
"pi"
|
|
2225
|
+
].includes(r.name) && (r.result.kind === "installed" || r.result.kind === "already-wired"))) p.log.info("Next: install agentmemory's 17 skills into the same agent(s) so they know when to call the tools:\n npx skills@1.7.1 add rohitg00/agentmemory -y");
|
|
1628
2226
|
p.outro("Restart any wired agent (or open a new session) to pick up agentmemory.");
|
|
1629
2227
|
}
|
|
1630
2228
|
//#endregion
|
|
1631
2229
|
export { runAdapter as a, resolveAdapter as i, connect_exports as n, knownAgents as r, ADAPTERS as t };
|
|
1632
2230
|
|
|
1633
|
-
//# sourceMappingURL=connect-
|
|
2231
|
+
//# sourceMappingURL=connect-BSLIAMpw.mjs.map
|