@agentmemory/agentmemory 0.9.30 → 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 +39 -33
- package/AGENTS.md +8 -8
- package/README.md +173 -558
- package/dist/.env.example +39 -33
- package/dist/cli.d.mts.map +1 -1
- package/dist/cli.mjs +1741 -966
- 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-B4_ca6BD.mjs → connect-BSLIAMpw.mjs} +874 -267
- package/dist/connect-BSLIAMpw.mjs.map +1 -0
- package/dist/hooks/_capture.d.mts +5 -2
- package/dist/hooks/_capture.d.mts.map +1 -1
- package/dist/hooks/_capture.mjs +55 -19
- package/dist/hooks/_capture.mjs.map +1 -1
- package/dist/hooks/notification.mjs +20 -6
- package/dist/hooks/notification.mjs.map +1 -1
- package/dist/hooks/post-commit.mjs +25 -5
- package/dist/hooks/post-commit.mjs.map +1 -1
- package/dist/hooks/post-tool-failure.mjs +12 -4
- package/dist/hooks/post-tool-failure.mjs.map +1 -1
- package/dist/hooks/post-tool-use.mjs +12 -4
- package/dist/hooks/post-tool-use.mjs.map +1 -1
- package/dist/hooks/pre-compact.mjs +37 -10
- package/dist/hooks/pre-compact.mjs.map +1 -1
- package/dist/hooks/pre-tool-use.mjs +25 -5
- package/dist/hooks/pre-tool-use.mjs.map +1 -1
- package/dist/hooks/prompt-submit.mjs +12 -4
- package/dist/hooks/prompt-submit.mjs.map +1 -1
- package/dist/hooks/session-end.mjs +47 -16
- package/dist/hooks/session-end.mjs.map +1 -1
- package/dist/hooks/session-start.mjs +37 -10
- package/dist/hooks/session-start.mjs.map +1 -1
- package/dist/hooks/stop.mjs +74 -72
- package/dist/hooks/stop.mjs.map +1 -1
- package/dist/hooks/subagent-start.mjs +13 -5
- package/dist/hooks/subagent-start.mjs.map +1 -1
- package/dist/hooks/subagent-stop.mjs +18 -6
- package/dist/hooks/subagent-stop.mjs.map +1 -1
- package/dist/hooks/task-completed.mjs +13 -5
- package/dist/hooks/task-completed.mjs.map +1 -1
- package/dist/{image-refs-T_urbwHM.mjs → image-refs-Cyta4Lf9.mjs} +2 -2
- package/dist/{image-refs-T_urbwHM.mjs.map → image-refs-Cyta4Lf9.mjs.map} +1 -1
- package/dist/index.mjs +8539 -4203
- 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/{keyed-mutex-DchXsyfP.mjs → keyed-mutex-DCUh7PG-.mjs} +58 -9
- package/dist/keyed-mutex-DCUh7PG-.mjs.map +1 -0
- package/dist/{secret-store-BnY3A50C.mjs → secret-store-D9GwO0xp.mjs} +535 -434
- 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-Jsq9LCeH.mjs → src-DaMtDzt_.mjs} +4087 -3788
- package/dist/src-DaMtDzt_.mjs.map +1 -0
- package/dist/{standalone-DKCdrf1d.mjs → standalone-BlqshyZ5.mjs} +213 -56
- 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 +626 -73
- package/dist/standalone.mjs.map +1 -1
- package/dist/viewer/index.html +288 -140
- 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 +138 -171
- package/integrations/pi/package.json +16 -6
- package/integrations/pi/security.ts +6 -26
- 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 +32 -11
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/.codex-plugin/plugin.json +4 -3
- package/plugin/.devin-plugin/plugin.json +5 -3
- package/plugin/cursor/hooks.json +23 -8
- package/plugin/hooks.json +67 -0
- package/plugin/opencode/README.md +1 -1
- package/plugin/opencode/agentmemory-capture.ts +25 -11
- package/plugin/opencode/plugin.json +1 -1
- package/plugin/plugin.json +1 -1
- package/plugin/scripts/_capture.d.mts +5 -2
- package/plugin/scripts/_capture.d.mts.map +1 -1
- package/plugin/scripts/_capture.mjs +55 -19
- package/plugin/scripts/_capture.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 +20 -6
- package/plugin/scripts/notification.mjs.map +1 -1
- package/plugin/scripts/plugin-bridge.mjs +37 -6
- package/plugin/scripts/post-commit.mjs +25 -5
- package/plugin/scripts/post-commit.mjs.map +1 -1
- package/plugin/scripts/post-tool-failure.mjs +12 -4
- package/plugin/scripts/post-tool-failure.mjs.map +1 -1
- package/plugin/scripts/post-tool-use.mjs +12 -4
- package/plugin/scripts/post-tool-use.mjs.map +1 -1
- package/plugin/scripts/pre-compact.mjs +37 -10
- package/plugin/scripts/pre-compact.mjs.map +1 -1
- package/plugin/scripts/pre-tool-use.mjs +25 -5
- package/plugin/scripts/pre-tool-use.mjs.map +1 -1
- package/plugin/scripts/prompt-submit.mjs +12 -4
- package/plugin/scripts/prompt-submit.mjs.map +1 -1
- package/plugin/scripts/session-end.mjs +47 -16
- package/plugin/scripts/session-end.mjs.map +1 -1
- package/plugin/scripts/session-start.mjs +37 -10
- package/plugin/scripts/session-start.mjs.map +1 -1
- package/plugin/scripts/stop.mjs +74 -72
- package/plugin/scripts/stop.mjs.map +1 -1
- package/plugin/scripts/subagent-start.mjs +13 -5
- package/plugin/scripts/subagent-start.mjs.map +1 -1
- package/plugin/scripts/subagent-stop.mjs +18 -6
- package/plugin/scripts/subagent-stop.mjs.map +1 -1
- package/plugin/scripts/task-completed.mjs +13 -5
- package/plugin/scripts/task-completed.mjs.map +1 -1
- package/plugin/skills/_shared/TROUBLESHOOTING.md +21 -7
- package/plugin/skills/agentmemory-agents/REFERENCE.md +7 -6
- 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 +12 -15
- package/plugin/skills/agentmemory-config/SKILL.md +7 -3
- 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 +4 -4
- 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 +9 -1
- 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 +10 -5
- 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 +1 -1
- 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-B4_ca6BD.mjs.map +0 -1
- package/dist/docker-compose.yml +0 -73
- package/dist/iii-config.docker.yaml +0 -53
- package/dist/iii-config.yaml +0 -63
- package/dist/keyed-mutex-DchXsyfP.mjs.map +0 -1
- package/dist/secret-store-BnY3A50C.mjs.map +0 -1
- package/dist/src-Jsq9LCeH.mjs.map +0 -1
- package/dist/standalone-DKCdrf1d.mjs.map +0 -1
- package/dist/status-IRz7ta8-.mjs +0 -2344
- package/dist/status-IRz7ta8-.mjs.map +0 -1
- package/docker-compose.yml +0 -73
- package/iii-config.docker.yaml +0 -53
- package/iii-config.yaml +0 -63
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import "node:module";
|
|
2
|
-
import { copyFileSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
3
|
-
import { dirname, join, resolve } from "node:path";
|
|
2
|
+
import { copyFileSync, cpSync, existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { dirname, join, relative, resolve, sep } from "node:path";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
import { homedir, platform } from "node:os";
|
|
6
6
|
import * as p from "@clack/prompts";
|
|
7
7
|
import pc from "picocolors";
|
|
8
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
9
|
+
import { Document, isMap, isSeq, parseDocument } from "yaml";
|
|
10
|
+
import JSON5 from "json5";
|
|
8
11
|
//#region \0rolldown/runtime.js
|
|
9
12
|
var __defProp = Object.defineProperty;
|
|
10
13
|
var __exportAll = (all, no_symbols) => {
|
|
@@ -17,6 +20,91 @@ var __exportAll = (all, no_symbols) => {
|
|
|
17
20
|
return target;
|
|
18
21
|
};
|
|
19
22
|
//#endregion
|
|
23
|
+
//#region src/cli/connect/util.ts
|
|
24
|
+
const AGENTMEMORY_MCP_BLOCK = {
|
|
25
|
+
command: "npx",
|
|
26
|
+
args: ["-y", "@agentmemory/mcp"],
|
|
27
|
+
env: {
|
|
28
|
+
AGENTMEMORY_URL: "${AGENTMEMORY_URL:-http://localhost:3111}",
|
|
29
|
+
AGENTMEMORY_SECRET: "${AGENTMEMORY_SECRET:-}",
|
|
30
|
+
AGENTMEMORY_TOOLS: "${AGENTMEMORY_TOOLS:-all}"
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
const AGENTMEMORY_COPILOT_MCP_BLOCK = {
|
|
34
|
+
type: "local",
|
|
35
|
+
...process.platform === "win32" ? {
|
|
36
|
+
command: process.env["ComSpec"] || process.env["COMSPEC"] || "cmd.exe",
|
|
37
|
+
args: [
|
|
38
|
+
"/d",
|
|
39
|
+
"/s",
|
|
40
|
+
"/c",
|
|
41
|
+
"npx",
|
|
42
|
+
"-y",
|
|
43
|
+
"@agentmemory/mcp"
|
|
44
|
+
]
|
|
45
|
+
} : {
|
|
46
|
+
command: "npx",
|
|
47
|
+
args: ["-y", "@agentmemory/mcp"]
|
|
48
|
+
},
|
|
49
|
+
env: {
|
|
50
|
+
AGENTMEMORY_URL: "${AGENTMEMORY_URL:-http://localhost:3111}",
|
|
51
|
+
AGENTMEMORY_SECRET: "${AGENTMEMORY_SECRET:-}",
|
|
52
|
+
AGENTMEMORY_TOOLS: "${AGENTMEMORY_TOOLS:-all}"
|
|
53
|
+
},
|
|
54
|
+
tools: ["*"]
|
|
55
|
+
};
|
|
56
|
+
function resolveDshHome(home = homedir()) {
|
|
57
|
+
const override = process.env["DSH_HOME"];
|
|
58
|
+
const value = override?.trim() ? override : join(home, ".dsh");
|
|
59
|
+
if (value === "~") return resolve(home);
|
|
60
|
+
if (value.startsWith("~/") || value.startsWith("~\\")) return resolve(join(home, value.slice(2)));
|
|
61
|
+
return resolve(value);
|
|
62
|
+
}
|
|
63
|
+
function backupsDir() {
|
|
64
|
+
return join(homedir(), ".agentmemory", "backups");
|
|
65
|
+
}
|
|
66
|
+
function ensureBackupsDir() {
|
|
67
|
+
const dir = backupsDir();
|
|
68
|
+
mkdirSync(dir, { recursive: true });
|
|
69
|
+
return dir;
|
|
70
|
+
}
|
|
71
|
+
function timestampSlug() {
|
|
72
|
+
return (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
73
|
+
}
|
|
74
|
+
function backupFile(sourcePath, agent, ext = "json") {
|
|
75
|
+
ensureBackupsDir();
|
|
76
|
+
const stamp = timestampSlug();
|
|
77
|
+
const target = join(backupsDir(), `${agent}-${stamp}.${ext}`);
|
|
78
|
+
copyFileSync(sourcePath, target);
|
|
79
|
+
return target;
|
|
80
|
+
}
|
|
81
|
+
function readJsonSafe(path) {
|
|
82
|
+
if (!existsSync(path)) return null;
|
|
83
|
+
try {
|
|
84
|
+
return JSON.parse(readFileSync(path, "utf-8"));
|
|
85
|
+
} catch {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
function writeJsonAtomic(path, value) {
|
|
90
|
+
writeTextAtomic(path, `${JSON.stringify(value, null, 2)}\n`);
|
|
91
|
+
}
|
|
92
|
+
function writeTextAtomic(path, content) {
|
|
93
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
94
|
+
const tmp = `${path}.tmp-${process.pid}-${Date.now()}`;
|
|
95
|
+
writeFileSync(tmp, content, "utf-8");
|
|
96
|
+
renameSync(tmp, path);
|
|
97
|
+
}
|
|
98
|
+
function logInstalled(label, target) {
|
|
99
|
+
p.log.success(`${label} → wired into ${target}`);
|
|
100
|
+
}
|
|
101
|
+
function logAlreadyWired(label, target) {
|
|
102
|
+
p.log.info(`${label} already wired in ${target} (use --force to re-install)`);
|
|
103
|
+
}
|
|
104
|
+
function logBackup(target) {
|
|
105
|
+
p.log.info(`Backup: ${target}`);
|
|
106
|
+
}
|
|
107
|
+
//#endregion
|
|
20
108
|
//#region src/cli/connect/guidelines.ts
|
|
21
109
|
const START = "<!-- agentmemory:start -->";
|
|
22
110
|
const END = "<!-- agentmemory:end -->";
|
|
@@ -95,6 +183,13 @@ function guidelineTargets(home = homedir()) {
|
|
|
95
183
|
scope: "global",
|
|
96
184
|
source: "https://docs.factory.ai/cli/configuration/agents-md"
|
|
97
185
|
},
|
|
186
|
+
dsh: {
|
|
187
|
+
globalPath: join(resolveDshHome(home), "AGENTS.md"),
|
|
188
|
+
projectPath: "AGENTS.md",
|
|
189
|
+
format: "block",
|
|
190
|
+
scope: "global",
|
|
191
|
+
source: "https://github.com/deepseek-ai/deepseek-harness"
|
|
192
|
+
},
|
|
98
193
|
antigravity: {
|
|
99
194
|
globalPath: join(home, ".gemini", "GEMINI.md"),
|
|
100
195
|
projectPath: join(".agents", "rules", "agentmemory.md"),
|
|
@@ -123,7 +218,7 @@ function renderDedicated(format) {
|
|
|
123
218
|
if (format === "steering") return `---\ninclusion: always\n---\n\n${GUIDELINE_BODY}\n`;
|
|
124
219
|
return `${GUIDELINE_BODY}\n`;
|
|
125
220
|
}
|
|
126
|
-
function upsertBlock(existing) {
|
|
221
|
+
function upsertBlock$1(existing) {
|
|
127
222
|
const block = `${START}\n${GUIDELINE_BODY}\n${END}`;
|
|
128
223
|
const startIdx = existing.indexOf(START);
|
|
129
224
|
const endIdx = existing.indexOf(END);
|
|
@@ -137,7 +232,7 @@ function writeGuideline(agentName, opts = { cwd: process.cwd() }) {
|
|
|
137
232
|
const path = target.globalPath ?? join(opts.cwd, target.projectPath);
|
|
138
233
|
const dedicated = target.format !== "block";
|
|
139
234
|
const existing = existsSync(path) ? readFileSync(path, "utf8") : "";
|
|
140
|
-
const next = dedicated ? renderDedicated(target.format) : upsertBlock(existing);
|
|
235
|
+
const next = dedicated ? renderDedicated(target.format) : upsertBlock$1(existing);
|
|
141
236
|
if (existing === next) return {
|
|
142
237
|
kind: "unchanged",
|
|
143
238
|
path,
|
|
@@ -158,84 +253,6 @@ function writeGuideline(agentName, opts = { cwd: process.cwd() }) {
|
|
|
158
253
|
};
|
|
159
254
|
}
|
|
160
255
|
//#endregion
|
|
161
|
-
//#region src/cli/connect/util.ts
|
|
162
|
-
const AGENTMEMORY_MCP_BLOCK = {
|
|
163
|
-
command: "npx",
|
|
164
|
-
args: ["-y", "@agentmemory/mcp"],
|
|
165
|
-
env: {
|
|
166
|
-
AGENTMEMORY_URL: "${AGENTMEMORY_URL:-http://localhost:3111}",
|
|
167
|
-
AGENTMEMORY_SECRET: "${AGENTMEMORY_SECRET:-}",
|
|
168
|
-
AGENTMEMORY_TOOLS: "${AGENTMEMORY_TOOLS:-all}"
|
|
169
|
-
}
|
|
170
|
-
};
|
|
171
|
-
const AGENTMEMORY_COPILOT_MCP_BLOCK = {
|
|
172
|
-
type: "local",
|
|
173
|
-
...process.platform === "win32" ? {
|
|
174
|
-
command: process.env["ComSpec"] || process.env["COMSPEC"] || "cmd.exe",
|
|
175
|
-
args: [
|
|
176
|
-
"/d",
|
|
177
|
-
"/s",
|
|
178
|
-
"/c",
|
|
179
|
-
"npx",
|
|
180
|
-
"-y",
|
|
181
|
-
"@agentmemory/mcp"
|
|
182
|
-
]
|
|
183
|
-
} : {
|
|
184
|
-
command: "npx",
|
|
185
|
-
args: ["-y", "@agentmemory/mcp"]
|
|
186
|
-
},
|
|
187
|
-
env: {
|
|
188
|
-
AGENTMEMORY_URL: "${AGENTMEMORY_URL:-http://localhost:3111}",
|
|
189
|
-
AGENTMEMORY_SECRET: "${AGENTMEMORY_SECRET:-}",
|
|
190
|
-
AGENTMEMORY_TOOLS: "${AGENTMEMORY_TOOLS:-all}"
|
|
191
|
-
},
|
|
192
|
-
tools: ["*"]
|
|
193
|
-
};
|
|
194
|
-
function backupsDir() {
|
|
195
|
-
return join(homedir(), ".agentmemory", "backups");
|
|
196
|
-
}
|
|
197
|
-
function ensureBackupsDir() {
|
|
198
|
-
const dir = backupsDir();
|
|
199
|
-
mkdirSync(dir, { recursive: true });
|
|
200
|
-
return dir;
|
|
201
|
-
}
|
|
202
|
-
function timestampSlug() {
|
|
203
|
-
return (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
204
|
-
}
|
|
205
|
-
function backupFile(sourcePath, agent, ext = "json") {
|
|
206
|
-
ensureBackupsDir();
|
|
207
|
-
const stamp = timestampSlug();
|
|
208
|
-
const target = join(backupsDir(), `${agent}-${stamp}.${ext}`);
|
|
209
|
-
copyFileSync(sourcePath, target);
|
|
210
|
-
return target;
|
|
211
|
-
}
|
|
212
|
-
function readJsonSafe(path) {
|
|
213
|
-
if (!existsSync(path)) return null;
|
|
214
|
-
try {
|
|
215
|
-
return JSON.parse(readFileSync(path, "utf-8"));
|
|
216
|
-
} catch {
|
|
217
|
-
return null;
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
function writeJsonAtomic(path, value) {
|
|
221
|
-
writeTextAtomic(path, `${JSON.stringify(value, null, 2)}\n`);
|
|
222
|
-
}
|
|
223
|
-
function writeTextAtomic(path, content) {
|
|
224
|
-
mkdirSync(dirname(path), { recursive: true });
|
|
225
|
-
const tmp = `${path}.tmp-${process.pid}-${Date.now()}`;
|
|
226
|
-
writeFileSync(tmp, content, "utf-8");
|
|
227
|
-
renameSync(tmp, path);
|
|
228
|
-
}
|
|
229
|
-
function logInstalled(label, target) {
|
|
230
|
-
p.log.success(`${label} → wired into ${target}`);
|
|
231
|
-
}
|
|
232
|
-
function logAlreadyWired(label, target) {
|
|
233
|
-
p.log.info(`${label} already wired in ${target} (use --force to re-install)`);
|
|
234
|
-
}
|
|
235
|
-
function logBackup(target) {
|
|
236
|
-
p.log.info(`Backup: ${target}`);
|
|
237
|
-
}
|
|
238
|
-
//#endregion
|
|
239
256
|
//#region src/cli/connect/json-mcp-adapter.ts
|
|
240
257
|
function entryMatches$3(entry) {
|
|
241
258
|
if (!entry || typeof entry !== "object") return false;
|
|
@@ -413,13 +430,14 @@ function findPluginRoot(startUrl = import.meta.url) {
|
|
|
413
430
|
/**
|
|
414
431
|
* Build the merged hooks.json content.
|
|
415
432
|
*
|
|
416
|
-
* 1. Strip
|
|
417
|
-
*
|
|
418
|
-
* 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.
|
|
419
437
|
* 2. Append fresh entries from the bundled Codex manifest with
|
|
420
438
|
* `${CLAUDE_PLUGIN_ROOT}` rewritten to the absolute plugin path.
|
|
421
|
-
*
|
|
422
|
-
* event routing keeps working.
|
|
439
|
+
* Matchers and the other handler fields from the bundled manifest are
|
|
440
|
+
* preserved so PreToolUse event routing keeps working.
|
|
423
441
|
*/
|
|
424
442
|
function buildMergedHooks(existing, pluginRoot, manifestFile = "hooks.codex.json") {
|
|
425
443
|
const bundledManifestPath = join(pluginRoot, "hooks", manifestFile);
|
|
@@ -427,14 +445,21 @@ function buildMergedHooks(existing, pluginRoot, manifestFile = "hooks.codex.json
|
|
|
427
445
|
const scriptsDir = join(pluginRoot, "scripts");
|
|
428
446
|
const out = { hooks: {} };
|
|
429
447
|
if (existing?.hooks) for (const [event, entries] of Object.entries(existing.hooks)) {
|
|
430
|
-
const kept = entries.
|
|
448
|
+
const kept = entries.flatMap((entry) => {
|
|
449
|
+
const hooks = entry.hooks.filter((handler) => !isAgentmemoryHandler(handler, scriptsDir));
|
|
450
|
+
if (hooks.length === entry.hooks.length) return [entry];
|
|
451
|
+
return hooks.length > 0 ? [{
|
|
452
|
+
...entry,
|
|
453
|
+
hooks
|
|
454
|
+
}] : [];
|
|
455
|
+
});
|
|
431
456
|
if (kept.length > 0) out.hooks[event] = kept;
|
|
432
457
|
}
|
|
433
458
|
for (const [event, entries] of Object.entries(ours.hooks)) {
|
|
434
459
|
const resolvedEntries = entries.map((entry) => {
|
|
435
460
|
const next = { hooks: entry.hooks.map((handler) => ({
|
|
436
|
-
|
|
437
|
-
command: handler.command
|
|
461
|
+
...handler,
|
|
462
|
+
command: handler.command?.replace(/\$\{CLAUDE_PLUGIN_ROOT\}/g, () => pluginRoot)
|
|
438
463
|
})) };
|
|
439
464
|
if (entry.matcher !== void 0) next.matcher = entry.matcher;
|
|
440
465
|
return next;
|
|
@@ -443,9 +468,8 @@ function buildMergedHooks(existing, pluginRoot, manifestFile = "hooks.codex.json
|
|
|
443
468
|
}
|
|
444
469
|
return out;
|
|
445
470
|
}
|
|
446
|
-
function
|
|
447
|
-
|
|
448
|
-
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));
|
|
449
473
|
}
|
|
450
474
|
function normalizePathForCommandMatch(value) {
|
|
451
475
|
return value.replace(/\\/g, "/");
|
|
@@ -456,7 +480,7 @@ const GEMINI_DIR = join(homedir(), ".gemini");
|
|
|
456
480
|
const ANTIGRAVITY_CLI_DIR = join(GEMINI_DIR, "antigravity-cli");
|
|
457
481
|
const CUSTOMIZATION_DIR$1 = join(GEMINI_DIR, "config");
|
|
458
482
|
const ANTIGRAVITY_CLI_HOOKS = join(CUSTOMIZATION_DIR$1, "hooks.json");
|
|
459
|
-
const adapter$
|
|
483
|
+
const adapter$21 = createJsonMcpAdapter({
|
|
460
484
|
name: "antigravity-cli",
|
|
461
485
|
displayName: "Antigravity CLI (agy)",
|
|
462
486
|
detectDir: ANTIGRAVITY_CLI_DIR,
|
|
@@ -521,7 +545,7 @@ const mcpAdapter = createJsonMcpAdapter({
|
|
|
521
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.",
|
|
522
546
|
installHooks: installAntigravityCliHooks
|
|
523
547
|
});
|
|
524
|
-
const adapter$
|
|
548
|
+
const adapter$20 = {
|
|
525
549
|
...mcpAdapter,
|
|
526
550
|
detect: () => mcpAdapter.detect() || existsSync(join(homedir(), ".gemini", "antigravity")) || existsSync(LEGACY_USER_DIR)
|
|
527
551
|
};
|
|
@@ -536,7 +560,7 @@ function entryMatches$2(entry) {
|
|
|
536
560
|
if (e["command"] !== "npx") return false;
|
|
537
561
|
return (Array.isArray(e["args"]) ? e["args"] : []).includes("@agentmemory/mcp");
|
|
538
562
|
}
|
|
539
|
-
const adapter$
|
|
563
|
+
const adapter$19 = {
|
|
540
564
|
name: "claude-code",
|
|
541
565
|
displayName: "Claude Code",
|
|
542
566
|
category: "native",
|
|
@@ -637,7 +661,7 @@ function installClaudeHooks(opts) {
|
|
|
637
661
|
}
|
|
638
662
|
//#endregion
|
|
639
663
|
//#region src/cli/connect/cline.ts
|
|
640
|
-
const adapter$
|
|
664
|
+
const adapter$18 = createJsonMcpAdapter({
|
|
641
665
|
name: "cline",
|
|
642
666
|
displayName: "Cline",
|
|
643
667
|
detectDir: join(homedir(), ".cline"),
|
|
@@ -653,7 +677,7 @@ function entryMatches$1(entry) {
|
|
|
653
677
|
if (!entry || typeof entry !== "object") return false;
|
|
654
678
|
return JSON.stringify(entry) === JSON.stringify(AGENTMEMORY_COPILOT_MCP_BLOCK);
|
|
655
679
|
}
|
|
656
|
-
const adapter$
|
|
680
|
+
const adapter$17 = {
|
|
657
681
|
name: "copilot-cli",
|
|
658
682
|
displayName: "GitHub Copilot CLI",
|
|
659
683
|
category: "native",
|
|
@@ -736,7 +760,7 @@ function stripExistingBlock(toml) {
|
|
|
736
760
|
}
|
|
737
761
|
return out.join("\n").replace(/\n{3,}$/, "\n\n").trimEnd() + "\n";
|
|
738
762
|
}
|
|
739
|
-
const adapter$
|
|
763
|
+
const adapter$16 = {
|
|
740
764
|
name: "codex",
|
|
741
765
|
displayName: "Codex CLI",
|
|
742
766
|
category: "native",
|
|
@@ -856,7 +880,7 @@ function renderFreshYaml() {
|
|
|
856
880
|
""
|
|
857
881
|
].join("\n");
|
|
858
882
|
}
|
|
859
|
-
const adapter$
|
|
883
|
+
const adapter$15 = {
|
|
860
884
|
name: "continue",
|
|
861
885
|
displayName: "Continue",
|
|
862
886
|
category: "mcp",
|
|
@@ -936,13 +960,14 @@ const adapter$14 = {
|
|
|
936
960
|
};
|
|
937
961
|
//#endregion
|
|
938
962
|
//#region src/cli/connect/cursor.ts
|
|
939
|
-
const adapter$
|
|
963
|
+
const adapter$14 = createJsonMcpAdapter({
|
|
940
964
|
name: "cursor",
|
|
941
965
|
displayName: "Cursor",
|
|
966
|
+
category: "native",
|
|
942
967
|
detectDir: join(homedir(), ".cursor"),
|
|
943
968
|
configPath: join(homedir(), ".cursor", "mcp.json"),
|
|
944
|
-
docs: "https://github.com/rohitg00/agentmemory#
|
|
945
|
-
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."
|
|
946
971
|
});
|
|
947
972
|
//#endregion
|
|
948
973
|
//#region src/cli/connect/devin.ts
|
|
@@ -956,7 +981,7 @@ function devinDir() {
|
|
|
956
981
|
}
|
|
957
982
|
const DEVIN_DIR = devinDir();
|
|
958
983
|
const DEVIN_CONFIG = join(DEVIN_DIR, "config.json");
|
|
959
|
-
const adapter$
|
|
984
|
+
const adapter$13 = createJsonMcpAdapter({
|
|
960
985
|
name: "devin",
|
|
961
986
|
displayName: "Devin CLI",
|
|
962
987
|
detectDir: DEVIN_DIR,
|
|
@@ -1006,7 +1031,7 @@ function installDevinHooks(opts) {
|
|
|
1006
1031
|
//#region src/cli/connect/droid.ts
|
|
1007
1032
|
const DROID_DIR = join(homedir(), ".factory");
|
|
1008
1033
|
const DROID_HOOKS = join(DROID_DIR, "hooks.json");
|
|
1009
|
-
const adapter$
|
|
1034
|
+
const adapter$12 = createJsonMcpAdapter({
|
|
1010
1035
|
name: "droid",
|
|
1011
1036
|
displayName: "Droid (Factory.ai)",
|
|
1012
1037
|
detectDir: DROID_DIR,
|
|
@@ -1057,9 +1082,6 @@ function installDroidHooks(opts) {
|
|
|
1057
1082
|
}
|
|
1058
1083
|
//#endregion
|
|
1059
1084
|
//#region src/cli/connect/dsh.ts
|
|
1060
|
-
function dshHome() {
|
|
1061
|
-
return process.env["DSH_HOME"] || join(homedir(), ".dsh");
|
|
1062
|
-
}
|
|
1063
1085
|
const MCP_BLOCK = `- insert:
|
|
1064
1086
|
- id: agentmemory
|
|
1065
1087
|
name: '@deepseek-ai/dsh-mcp-client'
|
|
@@ -1069,55 +1091,89 @@ const MCP_BLOCK = `- insert:
|
|
|
1069
1091
|
command: npx
|
|
1070
1092
|
args: ['-y', '@agentmemory/mcp']
|
|
1071
1093
|
env:
|
|
1072
|
-
AGENTMEMORY_URL: http://localhost:3111
|
|
1094
|
+
AGENTMEMORY_URL: !!js process.env.AGENTMEMORY_URL || 'http://localhost:3111'
|
|
1095
|
+
AGENTMEMORY_SECRET: !!js process.env.AGENTMEMORY_SECRET || ''
|
|
1073
1096
|
`;
|
|
1074
1097
|
const MCP_MARKER = "serverName: agentmemory";
|
|
1075
1098
|
const HOOKS_MARKER = "id: agentmemory-hooks";
|
|
1076
|
-
function hooksBlock(
|
|
1099
|
+
function hooksBlock(pluginPath) {
|
|
1077
1100
|
return `- insert:
|
|
1078
1101
|
- id: agentmemory-hooks
|
|
1079
|
-
name:
|
|
1080
|
-
config:
|
|
1081
|
-
configPath: ${JSON.stringify(hooksConfigPath)}
|
|
1102
|
+
name: ${JSON.stringify(pluginPath)}
|
|
1082
1103
|
`;
|
|
1083
1104
|
}
|
|
1084
|
-
function
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
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 = {
|
|
1105
1159
|
name: "dsh",
|
|
1106
1160
|
displayName: "DeepSeek Harness",
|
|
1107
|
-
docs: "https://github.com/rohitg00/agentmemory
|
|
1108
|
-
protocolNote: "→ Using MCP via $DSH_HOME/cordis.patch.yml (the home-level patch layer every profile loads). Tools appear as mcp__agentmemory__*. Pass --with-hooks to also wire auto-capture
|
|
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.",
|
|
1109
1163
|
category: "native",
|
|
1110
1164
|
detect() {
|
|
1111
|
-
return existsSync(
|
|
1165
|
+
return existsSync(resolveDshHome());
|
|
1112
1166
|
},
|
|
1113
1167
|
async install(opts) {
|
|
1114
|
-
const
|
|
1115
|
-
const configPath = join(home, "cordis.patch.yml");
|
|
1168
|
+
const configPath = join(resolveDshHome(), "cordis.patch.yml");
|
|
1116
1169
|
const existing = existsSync(configPath) ? readFileSync(configPath, "utf-8") : "";
|
|
1117
1170
|
const wantHooks = opts.withHooks === true;
|
|
1118
|
-
const hasMcp = existing
|
|
1119
|
-
const
|
|
1120
|
-
|
|
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) {
|
|
1121
1177
|
logAlreadyWired(this.displayName, configPath);
|
|
1122
1178
|
return {
|
|
1123
1179
|
kind: "already-wired",
|
|
@@ -1125,28 +1181,23 @@ const adapter$10 = {
|
|
|
1125
1181
|
};
|
|
1126
1182
|
}
|
|
1127
1183
|
if (opts.dryRun) {
|
|
1128
|
-
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}`);
|
|
1129
1185
|
return {
|
|
1130
1186
|
kind: "installed",
|
|
1131
1187
|
mutatedPath: configPath
|
|
1132
1188
|
};
|
|
1133
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.");
|
|
1134
1191
|
let backupPath;
|
|
1135
1192
|
if (existsSync(configPath)) {
|
|
1136
1193
|
backupPath = backupFile(configPath, this.name, "yml");
|
|
1137
1194
|
logBackup(backupPath);
|
|
1138
1195
|
} else mkdirSync(dirname(configPath), { recursive: true });
|
|
1139
|
-
let next =
|
|
1140
|
-
next =
|
|
1141
|
-
if (wantHooks) {
|
|
1142
|
-
const hooksPath = installHooksFile(home);
|
|
1143
|
-
next = stripBlock(next, HOOKS_MARKER);
|
|
1144
|
-
next = appendBlock(next, hooksBlock(hooksPath));
|
|
1145
|
-
p.log.info(`Hook manifest: ${hooksPath}`);
|
|
1146
|
-
}
|
|
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));
|
|
1147
1198
|
writeTextAtomic(configPath, next);
|
|
1148
1199
|
const written = readFileSync(configPath, "utf-8");
|
|
1149
|
-
if (!written
|
|
1200
|
+
if (!hasBlock(written, MCP_MARKER) || wantHooks && !hasBlock(written, HOOKS_MARKER)) {
|
|
1150
1201
|
p.log.error(`Verification failed: ${configPath} did not contain the agentmemory rows after write.`);
|
|
1151
1202
|
return {
|
|
1152
1203
|
kind: "skipped",
|
|
@@ -1163,7 +1214,7 @@ const adapter$10 = {
|
|
|
1163
1214
|
};
|
|
1164
1215
|
//#endregion
|
|
1165
1216
|
//#region src/cli/connect/gemini-cli.ts
|
|
1166
|
-
const adapter$
|
|
1217
|
+
const adapter$10 = createJsonMcpAdapter({
|
|
1167
1218
|
name: "gemini-cli",
|
|
1168
1219
|
displayName: "Gemini CLI",
|
|
1169
1220
|
detectDir: join(homedir(), ".gemini"),
|
|
@@ -1172,43 +1223,275 @@ const adapter$9 = createJsonMcpAdapter({
|
|
|
1172
1223
|
protocolNote: "→ Using MCP (the only protocol Gemini CLI speaks). Memory bridge runs at :3111 underneath."
|
|
1173
1224
|
});
|
|
1174
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
|
|
1175
1376
|
//#region src/cli/connect/hermes.ts
|
|
1176
|
-
const
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
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 = {
|
|
1180
1383
|
name: "hermes",
|
|
1181
1384
|
displayName: "Hermes Agent",
|
|
1182
1385
|
category: "native",
|
|
1183
|
-
docs: DOCS$
|
|
1184
|
-
protocolNote: "→
|
|
1185
|
-
detect()
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
};
|
|
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
|
+
}
|
|
1207
1490
|
}
|
|
1208
1491
|
};
|
|
1209
1492
|
//#endregion
|
|
1210
1493
|
//#region src/cli/connect/kiro.ts
|
|
1211
|
-
const adapter$
|
|
1494
|
+
const adapter$8 = createJsonMcpAdapter({
|
|
1212
1495
|
name: "kiro",
|
|
1213
1496
|
displayName: "Kiro",
|
|
1214
1497
|
detectDir: join(homedir(), ".kiro"),
|
|
@@ -1218,15 +1501,182 @@ const adapter$7 = createJsonMcpAdapter({
|
|
|
1218
1501
|
});
|
|
1219
1502
|
//#endregion
|
|
1220
1503
|
//#region src/cli/connect/openclaw.ts
|
|
1221
|
-
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 = {
|
|
1222
1516
|
name: "openclaw",
|
|
1223
1517
|
displayName: "OpenClaw",
|
|
1224
1518
|
category: "native",
|
|
1225
|
-
detectDir: join(homedir(), ".openclaw"),
|
|
1226
|
-
configPath: join(homedir(), ".openclaw", "openclaw.json"),
|
|
1227
1519
|
docs: "https://github.com/rohitg00/agentmemory/tree/main/integrations/openclaw",
|
|
1228
|
-
protocolNote: "→
|
|
1229
|
-
|
|
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
|
+
};
|
|
1230
1680
|
//#endregion
|
|
1231
1681
|
//#region src/cli/connect/opencode.ts
|
|
1232
1682
|
const CONFIG_PATH = join(homedir(), ".config", "opencode", "opencode.json");
|
|
@@ -1245,7 +1695,7 @@ function entryMatches(entry) {
|
|
|
1245
1695
|
const command = entry["command"];
|
|
1246
1696
|
return Array.isArray(command) && command.includes("@agentmemory/mcp");
|
|
1247
1697
|
}
|
|
1248
|
-
const adapter$
|
|
1698
|
+
const adapter$6 = {
|
|
1249
1699
|
name: "opencode",
|
|
1250
1700
|
displayName: "OpenCode",
|
|
1251
1701
|
category: "mcp",
|
|
@@ -1301,12 +1751,12 @@ const adapter$5 = {
|
|
|
1301
1751
|
//#endregion
|
|
1302
1752
|
//#region src/cli/connect/openhuman.ts
|
|
1303
1753
|
const OPENHUMAN_DIR = join(homedir(), ".openhuman");
|
|
1304
|
-
const DOCS
|
|
1305
|
-
const adapter$
|
|
1754
|
+
const DOCS = "https://github.com/tinyhumansai/openhuman";
|
|
1755
|
+
const adapter$5 = {
|
|
1306
1756
|
name: "openhuman",
|
|
1307
1757
|
displayName: "OpenHuman",
|
|
1308
1758
|
category: "native",
|
|
1309
|
-
docs: DOCS
|
|
1759
|
+
docs: DOCS,
|
|
1310
1760
|
protocolNote: "→ Using native hooks (REST API at :3111). MCP not required.",
|
|
1311
1761
|
detect() {
|
|
1312
1762
|
return existsSync(OPENHUMAN_DIR);
|
|
@@ -1319,7 +1769,7 @@ const adapter$4 = {
|
|
|
1319
1769
|
"impl. Once integrations/openhuman/ lands in agentmemory we'll wire",
|
|
1320
1770
|
"this up automatically.",
|
|
1321
1771
|
"",
|
|
1322
|
-
`Tracking: ${DOCS
|
|
1772
|
+
`Tracking: ${DOCS}`
|
|
1323
1773
|
].join("\n"), "OpenHuman manual install");
|
|
1324
1774
|
return {
|
|
1325
1775
|
kind: "stub",
|
|
@@ -1328,80 +1778,225 @@ const adapter$4 = {
|
|
|
1328
1778
|
}
|
|
1329
1779
|
};
|
|
1330
1780
|
//#endregion
|
|
1331
|
-
//#region src/cli/connect/
|
|
1332
|
-
|
|
1333
|
-
const
|
|
1334
|
-
const
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
}
|
|
1343
|
-
const dir = join(packageRoot, "integrations", "pi");
|
|
1344
|
-
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
|
+
};
|
|
1345
1792
|
}
|
|
1346
|
-
const adapter$
|
|
1347
|
-
name: "
|
|
1348
|
-
displayName: "
|
|
1793
|
+
const adapter$4 = {
|
|
1794
|
+
name: "omp",
|
|
1795
|
+
displayName: "Oh My Pi",
|
|
1349
1796
|
category: "native",
|
|
1350
|
-
docs:
|
|
1351
|
-
protocolNote: "
|
|
1352
|
-
detect() {
|
|
1353
|
-
|
|
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
|
+
}
|
|
1354
1806
|
},
|
|
1355
1807
|
async install(opts) {
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
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 } : {}
|
|
1362
1870
|
};
|
|
1363
|
-
}
|
|
1364
|
-
|
|
1365
|
-
name: f,
|
|
1366
|
-
content: readFileSync(join(sourceDir, f), "utf-8"),
|
|
1367
|
-
target: join(PI_EXT_DIR, f)
|
|
1368
|
-
}));
|
|
1369
|
-
if (sources.every((s) => existsSync(s.target) && readFileSync(s.target, "utf-8") === s.content) && !opts.force) {
|
|
1370
|
-
logAlreadyWired(this.displayName, PI_EXT_DIR);
|
|
1871
|
+
} catch (error) {
|
|
1872
|
+
p.log.warn(error instanceof Error ? error.message : "OMP installation failed.");
|
|
1371
1873
|
return {
|
|
1372
|
-
kind: "
|
|
1373
|
-
|
|
1874
|
+
kind: "skipped",
|
|
1875
|
+
reason: "native-install-failed"
|
|
1374
1876
|
};
|
|
1375
1877
|
}
|
|
1376
|
-
|
|
1377
|
-
|
|
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.");
|
|
1378
1988
|
return {
|
|
1379
|
-
kind: "installed",
|
|
1380
|
-
mutatedPath:
|
|
1989
|
+
kind: changed ? "installed" : "already-wired",
|
|
1990
|
+
mutatedPath: configPath,
|
|
1991
|
+
...backupPath ? { backupPath } : {}
|
|
1381
1992
|
};
|
|
1382
|
-
}
|
|
1383
|
-
|
|
1384
|
-
for (const s of sources) if (existsSync(s.target) && readFileSync(s.target, "utf-8") !== s.content) {
|
|
1385
|
-
const backup = backupFile(s.target, `${this.name}-${s.name.replace(/\.ts$/, "")}`, "ts");
|
|
1386
|
-
logBackup(backup);
|
|
1387
|
-
backupPath ??= backup;
|
|
1388
|
-
}
|
|
1389
|
-
mkdirSync(PI_EXT_DIR, { recursive: true });
|
|
1390
|
-
for (const s of sources) writeTextAtomic(s.target, s.content);
|
|
1391
|
-
if (!sources.every((s) => existsSync(s.target) && readFileSync(s.target, "utf-8") === s.content)) {
|
|
1392
|
-
p.log.error(`Verification failed: ${PI_EXT_DIR} does not match the bundled extension.`);
|
|
1993
|
+
} catch (error) {
|
|
1994
|
+
p.log.warn(error instanceof Error ? error.message : "Pi installation failed.");
|
|
1393
1995
|
return {
|
|
1394
1996
|
kind: "skipped",
|
|
1395
|
-
reason: "
|
|
1997
|
+
reason: "native-install-failed"
|
|
1396
1998
|
};
|
|
1397
1999
|
}
|
|
1398
|
-
logInstalled(this.displayName, PI_EXT_DIR);
|
|
1399
|
-
p.log.info("pi auto-discovers the extension on next launch; a running pi picks it up with /reload. Verify with /agentmemory-status.");
|
|
1400
|
-
return {
|
|
1401
|
-
kind: "installed",
|
|
1402
|
-
mutatedPath: PI_EXT_DIR,
|
|
1403
|
-
backupPath
|
|
1404
|
-
};
|
|
1405
2000
|
}
|
|
1406
2001
|
};
|
|
1407
2002
|
//#endregion
|
|
@@ -1446,27 +2041,28 @@ var connect_exports = /* @__PURE__ */ __exportAll({
|
|
|
1446
2041
|
runConnect: () => runConnect
|
|
1447
2042
|
});
|
|
1448
2043
|
const ADAPTERS = [
|
|
1449
|
-
adapter$
|
|
2044
|
+
adapter$19,
|
|
2045
|
+
adapter$17,
|
|
1450
2046
|
adapter$16,
|
|
1451
|
-
adapter$
|
|
2047
|
+
adapter$14,
|
|
1452
2048
|
adapter$13,
|
|
1453
|
-
adapter$
|
|
1454
|
-
adapter$9,
|
|
2049
|
+
adapter$10,
|
|
1455
2050
|
adapter$2,
|
|
1456
|
-
adapter$19,
|
|
1457
2051
|
adapter$20,
|
|
1458
|
-
adapter$
|
|
2052
|
+
adapter$21,
|
|
2053
|
+
adapter$8,
|
|
1459
2054
|
adapter$1,
|
|
1460
|
-
adapter$
|
|
1461
|
-
adapter$
|
|
2055
|
+
adapter$18,
|
|
2056
|
+
adapter$15,
|
|
1462
2057
|
adapter,
|
|
2058
|
+
adapter$12,
|
|
1463
2059
|
adapter$11,
|
|
1464
|
-
adapter$10,
|
|
1465
|
-
adapter$5,
|
|
1466
2060
|
adapter$6,
|
|
1467
|
-
adapter$
|
|
2061
|
+
adapter$7,
|
|
2062
|
+
adapter$9,
|
|
1468
2063
|
adapter$3,
|
|
1469
|
-
adapter$4
|
|
2064
|
+
adapter$4,
|
|
2065
|
+
adapter$5
|
|
1470
2066
|
];
|
|
1471
2067
|
function resolveAdapter(name) {
|
|
1472
2068
|
const lower = name.toLowerCase();
|
|
@@ -1481,11 +2077,13 @@ function parseFlags(args) {
|
|
|
1481
2077
|
let force = false;
|
|
1482
2078
|
let all = false;
|
|
1483
2079
|
let withHooks = false;
|
|
2080
|
+
let withMcp = false;
|
|
1484
2081
|
let guidelines = true;
|
|
1485
2082
|
for (const a of args) if (a === "--dry-run") dryRun = true;
|
|
1486
2083
|
else if (a === "--force") force = true;
|
|
1487
2084
|
else if (a === "--all") all = true;
|
|
1488
2085
|
else if (a === "--with-hooks") withHooks = true;
|
|
2086
|
+
else if (a === "--with-mcp") withMcp = true;
|
|
1489
2087
|
else if (a === "--no-guidelines") guidelines = false;
|
|
1490
2088
|
else if (!a.startsWith("-")) positional.push(a);
|
|
1491
2089
|
return {
|
|
@@ -1493,6 +2091,7 @@ function parseFlags(args) {
|
|
|
1493
2091
|
force,
|
|
1494
2092
|
all,
|
|
1495
2093
|
withHooks,
|
|
2094
|
+
withMcp,
|
|
1496
2095
|
guidelines,
|
|
1497
2096
|
positional
|
|
1498
2097
|
};
|
|
@@ -1529,7 +2128,7 @@ async function runAdapter(adapter, opts) {
|
|
|
1529
2128
|
}
|
|
1530
2129
|
}
|
|
1531
2130
|
async function runConnect(args) {
|
|
1532
|
-
const { dryRun, force, all, withHooks, guidelines, positional } = parseFlags(args);
|
|
2131
|
+
const { dryRun, force, all, withHooks, withMcp, guidelines, positional } = parseFlags(args);
|
|
1533
2132
|
const allowWindowsAdapter = positional.length === 1 && positional[0]?.toLowerCase() === "copilot-cli";
|
|
1534
2133
|
if (platform() === "win32" && !allowWindowsAdapter) {
|
|
1535
2134
|
p.intro("agentmemory connect");
|
|
@@ -1541,6 +2140,7 @@ async function runConnect(args) {
|
|
|
1541
2140
|
dryRun,
|
|
1542
2141
|
force,
|
|
1543
2142
|
withHooks,
|
|
2143
|
+
withMcp,
|
|
1544
2144
|
guidelines
|
|
1545
2145
|
};
|
|
1546
2146
|
p.intro("agentmemory connect");
|
|
@@ -1615,10 +2215,17 @@ function summarize(results) {
|
|
|
1615
2215
|
p.note(lines.join("\n"), "summary");
|
|
1616
2216
|
const stubs = results.filter((r) => r.result.kind === "stub");
|
|
1617
2217
|
if (stubs.length > 0) p.log.info(`${stubs.length} agent(s) require manual install — see docs links above.`);
|
|
1618
|
-
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");
|
|
1619
2226
|
p.outro("Restart any wired agent (or open a new session) to pick up agentmemory.");
|
|
1620
2227
|
}
|
|
1621
2228
|
//#endregion
|
|
1622
2229
|
export { runAdapter as a, resolveAdapter as i, connect_exports as n, knownAgents as r, ADAPTERS as t };
|
|
1623
2230
|
|
|
1624
|
-
//# sourceMappingURL=connect-
|
|
2231
|
+
//# sourceMappingURL=connect-BSLIAMpw.mjs.map
|