@agentmemory/agentmemory 0.9.28 → 0.9.29
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 +15 -6
- package/AGENTS.md +6 -6
- package/README.md +220 -152
- package/dist/.env.example +15 -6
- package/dist/cli.d.mts.map +1 -1
- package/dist/cli.mjs +233 -35
- package/dist/cli.mjs.map +1 -1
- package/dist/{connect-JnsJXc68.mjs → connect-Qaeq15TQ.mjs} +599 -41
- package/dist/connect-Qaeq15TQ.mjs.map +1 -0
- package/dist/docker-compose.yml +2 -2
- package/dist/hooks/antigravity-bridge.d.mts +8 -0
- package/dist/hooks/antigravity-bridge.d.mts.map +1 -0
- package/dist/hooks/antigravity-bridge.mjs +114 -0
- package/dist/hooks/antigravity-bridge.mjs.map +1 -0
- package/dist/hooks/notification.mjs +19 -4
- package/dist/hooks/notification.mjs.map +1 -1
- package/dist/hooks/post-commit.mjs +13 -1
- package/dist/hooks/post-commit.mjs.map +1 -1
- package/dist/hooks/post-tool-failure.mjs +14 -3
- package/dist/hooks/post-tool-failure.mjs.map +1 -1
- package/dist/hooks/post-tool-use.mjs +14 -3
- package/dist/hooks/post-tool-use.mjs.map +1 -1
- package/dist/hooks/pre-compact.mjs +12 -2
- package/dist/hooks/pre-compact.mjs.map +1 -1
- package/dist/hooks/pre-tool-use.mjs +1 -1
- package/dist/hooks/pre-tool-use.mjs.map +1 -1
- package/dist/hooks/prompt-submit.mjs +14 -3
- package/dist/hooks/prompt-submit.mjs.map +1 -1
- package/dist/hooks/session-end.mjs +82 -18
- package/dist/hooks/session-end.mjs.map +1 -1
- package/dist/hooks/session-start.mjs +22 -4
- package/dist/hooks/session-start.mjs.map +1 -1
- package/dist/hooks/stop.mjs +1 -7
- package/dist/hooks/stop.mjs.map +1 -1
- package/dist/hooks/subagent-start.mjs +14 -3
- package/dist/hooks/subagent-start.mjs.map +1 -1
- package/dist/hooks/subagent-stop.mjs +14 -3
- package/dist/hooks/subagent-stop.mjs.map +1 -1
- package/dist/hooks/task-completed.mjs +14 -3
- package/dist/hooks/task-completed.mjs.map +1 -1
- package/dist/{image-refs-C2YU7BIm.mjs → image-refs-CJgZmb9X.mjs} +2 -2
- package/dist/{image-refs-C2YU7BIm.mjs.map → image-refs-CJgZmb9X.mjs.map} +1 -1
- package/dist/index.mjs +1557 -755
- package/dist/index.mjs.map +1 -1
- package/dist/schema-BFZhNTF7.mjs +197 -0
- package/dist/schema-BFZhNTF7.mjs.map +1 -0
- package/dist/{src-CzgoepGU.mjs → src-G7yt8gGm.mjs} +1531 -883
- package/dist/src-G7yt8gGm.mjs.map +1 -0
- package/dist/{standalone-YsZFFQBM.mjs → standalone-BqNJDJ04.mjs} +26 -15
- package/dist/standalone-BqNJDJ04.mjs.map +1 -0
- package/dist/standalone.d.mts.map +1 -1
- package/dist/standalone.mjs +50 -14
- package/dist/standalone.mjs.map +1 -1
- package/dist/{tools-registry-D3NEoe5m.mjs → tools-registry-BV_2bu7z.mjs} +293 -3
- package/dist/tools-registry-BV_2bu7z.mjs.map +1 -0
- package/dist/viewer/favicon.svg +35 -1
- package/dist/viewer/index.html +473 -83
- package/docker-compose.yml +2 -2
- package/integrations/pi/README.md +77 -0
- package/integrations/pi/index.ts +403 -0
- package/integrations/pi/package.json +32 -0
- package/integrations/pi/security.ts +35 -0
- package/package.json +3 -4
- package/plugin/.claude-plugin/plugin.json +2 -2
- package/plugin/.codex-plugin/plugin.json +2 -2
- package/plugin/.devin-plugin/plugin.json +32 -0
- package/plugin/cursor/hooks.json +41 -0
- package/plugin/cursor/mcp.json +12 -0
- package/plugin/hooks/hooks.antigravity.json +43 -0
- package/plugin/hooks/hooks.devin.json +67 -0
- package/plugin/hooks/hooks.droid.json +55 -0
- package/plugin/opencode/README.md +1 -1
- package/plugin/opencode/agentmemory-capture.ts +73 -13
- package/plugin/opencode/plugin.json +1 -1
- package/plugin/plugin.json +2 -2
- package/plugin/scripts/antigravity-bridge.d.mts +8 -0
- package/plugin/scripts/antigravity-bridge.d.mts.map +1 -0
- package/plugin/scripts/antigravity-bridge.mjs +114 -0
- package/plugin/scripts/antigravity-bridge.mjs.map +1 -0
- package/plugin/scripts/notification.mjs +19 -4
- package/plugin/scripts/notification.mjs.map +1 -1
- package/plugin/scripts/post-commit.mjs +13 -1
- package/plugin/scripts/post-commit.mjs.map +1 -1
- package/plugin/scripts/post-tool-failure.mjs +14 -3
- package/plugin/scripts/post-tool-failure.mjs.map +1 -1
- package/plugin/scripts/post-tool-use.mjs +14 -3
- package/plugin/scripts/post-tool-use.mjs.map +1 -1
- package/plugin/scripts/pre-compact.mjs +12 -2
- package/plugin/scripts/pre-compact.mjs.map +1 -1
- package/plugin/scripts/pre-tool-use.mjs +1 -1
- package/plugin/scripts/pre-tool-use.mjs.map +1 -1
- package/plugin/scripts/prompt-submit.mjs +14 -3
- package/plugin/scripts/prompt-submit.mjs.map +1 -1
- package/plugin/scripts/session-end.mjs +82 -18
- package/plugin/scripts/session-end.mjs.map +1 -1
- package/plugin/scripts/session-start.mjs +22 -4
- package/plugin/scripts/session-start.mjs.map +1 -1
- package/plugin/scripts/stop.mjs +1 -7
- package/plugin/scripts/stop.mjs.map +1 -1
- package/plugin/scripts/subagent-start.mjs +14 -3
- package/plugin/scripts/subagent-start.mjs.map +1 -1
- package/plugin/scripts/subagent-stop.mjs +14 -3
- package/plugin/scripts/subagent-stop.mjs.map +1 -1
- package/plugin/scripts/task-completed.mjs +14 -3
- package/plugin/scripts/task-completed.mjs.map +1 -1
- package/plugin/skills/agentmemory-agents/REFERENCE.md +6 -3
- package/plugin/skills/agentmemory-config/REFERENCE.md +4 -1
- package/plugin/skills/agentmemory-mcp-tools/REFERENCE.md +3 -2
- package/plugin/skills/agentmemory-rest-api/REFERENCE.md +14 -1
- package/plugin/skills/forget/SKILL.md +4 -1
- package/plugin/skills/lesson/SKILL.md +64 -0
- package/plugin/skills/memory-discipline/SKILL.md +57 -0
- package/plugin/skills/recall/SKILL.md +4 -1
- package/plugin/skills/remember/SKILL.md +6 -1
- package/dist/config-ChC9EtgV.mjs +0 -259
- package/dist/config-ChC9EtgV.mjs.map +0 -1
- package/dist/connect-JnsJXc68.mjs.map +0 -1
- package/dist/schema-CNiCWzV9.mjs +0 -78
- package/dist/schema-CNiCWzV9.mjs.map +0 -1
- package/dist/src-CzgoepGU.mjs.map +0 -1
- package/dist/standalone-YsZFFQBM.mjs.map +0 -1
- package/dist/tools-registry-D3NEoe5m.mjs.map +0 -1
- package/plugin/scripts/diagnostics.d.mts +0 -17
- package/plugin/scripts/diagnostics.d.mts.map +0 -1
- package/plugin/scripts/diagnostics.mjs.map +0 -1
package/dist/config-ChC9EtgV.mjs
DELETED
|
@@ -1,259 +0,0 @@
|
|
|
1
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
-
import { join } from "node:path";
|
|
3
|
-
import { homedir } from "node:os";
|
|
4
|
-
import pc from "picocolors";
|
|
5
|
-
//#region src/config.ts
|
|
6
|
-
function safeParseInt(value, fallback) {
|
|
7
|
-
if (!value) return fallback;
|
|
8
|
-
const parsed = parseInt(value, 10);
|
|
9
|
-
return Number.isNaN(parsed) ? fallback : parsed;
|
|
10
|
-
}
|
|
11
|
-
const DATA_DIR = join(homedir(), ".agentmemory");
|
|
12
|
-
const ENV_FILE = join(DATA_DIR, ".env");
|
|
13
|
-
let warnPremiumModelShown = false;
|
|
14
|
-
function loadEnvFile() {
|
|
15
|
-
if (!existsSync(ENV_FILE)) return {};
|
|
16
|
-
const content = readFileSync(ENV_FILE, "utf-8");
|
|
17
|
-
const vars = {};
|
|
18
|
-
for (const line of content.split("\n")) {
|
|
19
|
-
const trimmed = line.trim();
|
|
20
|
-
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
21
|
-
const eqIdx = trimmed.indexOf("=");
|
|
22
|
-
if (eqIdx === -1) continue;
|
|
23
|
-
const key = trimmed.slice(0, eqIdx).trim();
|
|
24
|
-
let val = trimmed.slice(eqIdx + 1).trim();
|
|
25
|
-
const quoteChar = val[0] === "\"" || val[0] === "'" ? val[0] : "";
|
|
26
|
-
if (quoteChar) {
|
|
27
|
-
const closeIdx = val.indexOf(quoteChar, 1);
|
|
28
|
-
if (closeIdx !== -1) val = val.slice(1, closeIdx);
|
|
29
|
-
} else {
|
|
30
|
-
const hashIdx = val.indexOf(" #");
|
|
31
|
-
if (hashIdx !== -1) val = val.slice(0, hashIdx).trim();
|
|
32
|
-
}
|
|
33
|
-
vars[key] = val;
|
|
34
|
-
}
|
|
35
|
-
return vars;
|
|
36
|
-
}
|
|
37
|
-
function hasRealValue(v) {
|
|
38
|
-
return typeof v === "string" && v.trim().length > 0;
|
|
39
|
-
}
|
|
40
|
-
function detectProvider(env) {
|
|
41
|
-
const maxTokens = parseInt(env["MAX_TOKENS"] || "4096", 10);
|
|
42
|
-
if (hasRealValue(env["OPENAI_API_KEY"]) && env["OPENAI_API_KEY_FOR_LLM"] !== "false") return {
|
|
43
|
-
provider: "openai",
|
|
44
|
-
model: env["OPENAI_MODEL"] || "gpt-4o-mini",
|
|
45
|
-
maxTokens,
|
|
46
|
-
baseURL: env["OPENAI_BASE_URL"]
|
|
47
|
-
};
|
|
48
|
-
if (hasRealValue(env["MINIMAX_API_KEY"])) return {
|
|
49
|
-
provider: "minimax",
|
|
50
|
-
model: env["MINIMAX_MODEL"] || "MiniMax-M2.7",
|
|
51
|
-
maxTokens
|
|
52
|
-
};
|
|
53
|
-
if (hasRealValue(env["ANTHROPIC_API_KEY"])) return {
|
|
54
|
-
provider: "anthropic",
|
|
55
|
-
model: env["ANTHROPIC_MODEL"] || "claude-sonnet-4-20250514",
|
|
56
|
-
maxTokens,
|
|
57
|
-
baseURL: env["ANTHROPIC_BASE_URL"]
|
|
58
|
-
};
|
|
59
|
-
if (hasRealValue(env["GEMINI_API_KEY"]) || hasRealValue(env["GOOGLE_API_KEY"])) {
|
|
60
|
-
if (!hasRealValue(env["GEMINI_API_KEY"]) && hasRealValue(env["GOOGLE_API_KEY"])) process.stderr.write("[agentmemory] GOOGLE_API_KEY detected — treating as GEMINI_API_KEY. Set GEMINI_API_KEY in ~/.agentmemory/.env to silence this warning.\n");
|
|
61
|
-
return {
|
|
62
|
-
provider: "gemini",
|
|
63
|
-
model: env["GEMINI_MODEL"] || "gemini-2.5-flash",
|
|
64
|
-
maxTokens
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
if (hasRealValue(env["OPENROUTER_API_KEY"])) {
|
|
68
|
-
const model = env["OPENROUTER_MODEL"] || "anthropic/claude-sonnet-4-20250514";
|
|
69
|
-
if (!warnPremiumModelShown && /sonnet|opus|gpt-4o(?!.*mini)|gpt-4-turbo/i.test(model) && env["AGENTMEMORY_SUPPRESS_COST_WARNING"] !== "1" && env["AGENTMEMORY_SUPPRESS_COST_WARNING"] !== "true") {
|
|
70
|
-
warnPremiumModelShown = true;
|
|
71
|
-
process.stderr.write(`[agentmemory] OPENROUTER_MODEL=${model} is in the premium tier. Background compression on this model can cost $5+/day under active use. Cheaper alternatives with comparable quality for memory compression: deepseek/deepseek-v4-pro, deepseek/deepseek-chat, qwen/qwen3-coder. See README "Cost-aware model selection" for the full table. Set AGENTMEMORY_SUPPRESS_COST_WARNING=1 to silence.\n`);
|
|
72
|
-
}
|
|
73
|
-
return {
|
|
74
|
-
provider: "openrouter",
|
|
75
|
-
model,
|
|
76
|
-
maxTokens
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
if (!(env["AGENTMEMORY_ALLOW_AGENT_SDK"] === "true")) {
|
|
80
|
-
process.stderr.write(pc.dim("[agentmemory] No LLM provider key set — running zero-LLM (BM25 + on-device embeddings). Set ANTHROPIC_API_KEY (or GEMINI/OPENAI/OPENROUTER/MINIMAX) in ~/.agentmemory/.env for LLM compression and summaries. Agent-SDK fallback stays off by default to avoid a Stop-hook recursion loop; opt in with AGENTMEMORY_AUTO_COMPRESS=true + AGENTMEMORY_ALLOW_AGENT_SDK=true.\n"));
|
|
81
|
-
return {
|
|
82
|
-
provider: "noop",
|
|
83
|
-
model: "noop",
|
|
84
|
-
maxTokens
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
process.stderr.write("[agentmemory] WARNING: agent-sdk fallback enabled via AGENTMEMORY_ALLOW_AGENT_SDK=true. This spawns @anthropic-ai/claude-agent-sdk child sessions that can trigger the Stop-hook recursion loop. A SDK-child env marker is set to block re-entry, but prefer setting a real API key in ~/.agentmemory/.env instead.\n");
|
|
88
|
-
return {
|
|
89
|
-
provider: "agent-sdk",
|
|
90
|
-
model: "claude-sonnet-4-20250514",
|
|
91
|
-
maxTokens
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
function loadConfig() {
|
|
95
|
-
const env = getMergedEnv();
|
|
96
|
-
const provider = detectProvider(env);
|
|
97
|
-
const restPort = parseInt(env["III_REST_PORT"] || "3111", 10) || 3111;
|
|
98
|
-
const streamsPort = parseInt(env["III_STREAM_PORT"] || env["III_STREAMS_PORT"] || "", 10) || restPort + 1;
|
|
99
|
-
return {
|
|
100
|
-
engineUrl: env["III_ENGINE_URL"] || `ws://localhost:${parseInt(env["III_ENGINE_PORT"] || "", 10) || restPort + 46023}`,
|
|
101
|
-
restPort,
|
|
102
|
-
streamsPort,
|
|
103
|
-
provider,
|
|
104
|
-
tokenBudget: safeParseInt(env["TOKEN_BUDGET"], 2e3),
|
|
105
|
-
maxObservationsPerSession: safeParseInt(env["MAX_OBS_PER_SESSION"], 500),
|
|
106
|
-
compressionModel: provider.model,
|
|
107
|
-
dataDir: DATA_DIR
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
function getMergedEnv(overrides) {
|
|
111
|
-
return {
|
|
112
|
-
...loadEnvFile(),
|
|
113
|
-
...process.env,
|
|
114
|
-
...overrides
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
|
-
function getEnvVar(key) {
|
|
118
|
-
return getMergedEnv()[key];
|
|
119
|
-
}
|
|
120
|
-
function isDropStaleIndexEnabled() {
|
|
121
|
-
return getMergedEnv()["AGENTMEMORY_DROP_STALE_INDEX"] === "true";
|
|
122
|
-
}
|
|
123
|
-
function detectLlmProviderKind() {
|
|
124
|
-
const env = getMergedEnv();
|
|
125
|
-
if (hasRealValue(env["ANTHROPIC_API_KEY"]) || hasRealValue(env["GEMINI_API_KEY"]) || hasRealValue(env["GOOGLE_API_KEY"]) || hasRealValue(env["OPENROUTER_API_KEY"]) || hasRealValue(env["MINIMAX_API_KEY"]) || hasRealValue(env["OPENAI_API_KEY"]) && env["OPENAI_API_KEY_FOR_LLM"] !== "false") return "llm";
|
|
126
|
-
return "noop";
|
|
127
|
-
}
|
|
128
|
-
function loadEmbeddingConfig() {
|
|
129
|
-
const env = getMergedEnv();
|
|
130
|
-
let bm25Weight = parseFloat(env["BM25_WEIGHT"] || "0.4");
|
|
131
|
-
let vectorWeight = parseFloat(env["VECTOR_WEIGHT"] || "0.6");
|
|
132
|
-
bm25Weight = isNaN(bm25Weight) || bm25Weight < 0 ? .4 : Math.min(bm25Weight, 1);
|
|
133
|
-
vectorWeight = isNaN(vectorWeight) || vectorWeight < 0 ? .6 : Math.min(vectorWeight, 1);
|
|
134
|
-
return {
|
|
135
|
-
provider: env["EMBEDDING_PROVIDER"] || void 0,
|
|
136
|
-
bm25Weight,
|
|
137
|
-
vectorWeight
|
|
138
|
-
};
|
|
139
|
-
}
|
|
140
|
-
function detectEmbeddingProvider(env) {
|
|
141
|
-
const source = env ?? getMergedEnv();
|
|
142
|
-
const forced = source["EMBEDDING_PROVIDER"];
|
|
143
|
-
if (forced) return forced;
|
|
144
|
-
if (source["GEMINI_API_KEY"]) return "gemini";
|
|
145
|
-
if (source["OPENAI_API_KEY"]) return "openai";
|
|
146
|
-
if (source["VOYAGE_API_KEY"]) return "voyage";
|
|
147
|
-
if (source["COHERE_API_KEY"]) return "cohere";
|
|
148
|
-
if (source["OPENROUTER_API_KEY"]) return "openrouter";
|
|
149
|
-
return null;
|
|
150
|
-
}
|
|
151
|
-
function loadClaudeBridgeConfig() {
|
|
152
|
-
const env = getMergedEnv();
|
|
153
|
-
const enabled = env["CLAUDE_MEMORY_BRIDGE"] === "true";
|
|
154
|
-
const projectPath = env["CLAUDE_PROJECT_PATH"] || "";
|
|
155
|
-
const lineBudget = safeParseInt(env["CLAUDE_MEMORY_LINE_BUDGET"], 200);
|
|
156
|
-
let memoryFilePath = "";
|
|
157
|
-
if (enabled && projectPath) {
|
|
158
|
-
const safePath = projectPath.replace(/[/\\]/g, "-");
|
|
159
|
-
memoryFilePath = join(homedir(), ".claude", "projects", safePath, "MEMORY.md");
|
|
160
|
-
}
|
|
161
|
-
return {
|
|
162
|
-
enabled,
|
|
163
|
-
projectPath,
|
|
164
|
-
memoryFilePath,
|
|
165
|
-
lineBudget
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
|
-
function loadTeamConfig() {
|
|
169
|
-
const env = getMergedEnv();
|
|
170
|
-
const teamId = env["TEAM_ID"];
|
|
171
|
-
const userId = env["USER_ID"];
|
|
172
|
-
if (!teamId || !userId) return null;
|
|
173
|
-
return {
|
|
174
|
-
teamId,
|
|
175
|
-
userId,
|
|
176
|
-
mode: env["TEAM_MODE"] === "shared" ? "shared" : "private"
|
|
177
|
-
};
|
|
178
|
-
}
|
|
179
|
-
function loadAgentScope() {
|
|
180
|
-
const env = getMergedEnv();
|
|
181
|
-
const raw = env["AGENT_ID"];
|
|
182
|
-
if (!raw) return null;
|
|
183
|
-
const agentId = raw.trim().slice(0, 128);
|
|
184
|
-
if (!agentId) return null;
|
|
185
|
-
return {
|
|
186
|
-
agentId,
|
|
187
|
-
mode: env["AGENTMEMORY_AGENT_SCOPE"] === "isolated" ? "isolated" : "shared"
|
|
188
|
-
};
|
|
189
|
-
}
|
|
190
|
-
function getAgentId() {
|
|
191
|
-
return loadAgentScope()?.agentId;
|
|
192
|
-
}
|
|
193
|
-
function isAgentScopeIsolated() {
|
|
194
|
-
return loadAgentScope()?.mode === "isolated";
|
|
195
|
-
}
|
|
196
|
-
function loadSnapshotConfig() {
|
|
197
|
-
const env = getMergedEnv();
|
|
198
|
-
return {
|
|
199
|
-
enabled: env["SNAPSHOT_ENABLED"] === "true",
|
|
200
|
-
interval: safeParseInt(env["SNAPSHOT_INTERVAL"], 3600),
|
|
201
|
-
dir: env["SNAPSHOT_DIR"] || join(homedir(), ".agentmemory", "snapshots")
|
|
202
|
-
};
|
|
203
|
-
}
|
|
204
|
-
function isGraphExtractionEnabled() {
|
|
205
|
-
return getMergedEnv()["GRAPH_EXTRACTION_ENABLED"] === "true";
|
|
206
|
-
}
|
|
207
|
-
const FOLLOWUP_WINDOW_DEFAULT_SECONDS = 30;
|
|
208
|
-
function getFollowupWindowSeconds() {
|
|
209
|
-
return safeParseInt(getMergedEnv()["AGENTMEMORY_FOLLOWUP_WINDOW_SECONDS"], FOLLOWUP_WINDOW_DEFAULT_SECONDS);
|
|
210
|
-
}
|
|
211
|
-
function isConsolidationEnabled() {
|
|
212
|
-
const env = getMergedEnv();
|
|
213
|
-
const explicit = env["CONSOLIDATION_ENABLED"];
|
|
214
|
-
if (explicit === "false" || explicit === "0") return false;
|
|
215
|
-
if (explicit === "true" || explicit === "1") return true;
|
|
216
|
-
return hasLLMProviderConfigured(env);
|
|
217
|
-
}
|
|
218
|
-
function hasLLMProviderConfigured(env) {
|
|
219
|
-
const provider = (env["AGENTMEMORY_PROVIDER"] || "").toLowerCase();
|
|
220
|
-
if (provider === "noop") return false;
|
|
221
|
-
const openaiKeyForLlm = env["OPENAI_API_KEY"] && (env["OPENAI_API_KEY_FOR_LLM"] || "").toLowerCase() !== "false";
|
|
222
|
-
return Boolean(env["ANTHROPIC_API_KEY"] || openaiKeyForLlm || env["OPENROUTER_API_KEY"] || env["GEMINI_API_KEY"] || env["GOOGLE_API_KEY"] || env["MINIMAX_API_KEY"] || env["OPENAI_BASE_URL"] || provider === "agent-sdk");
|
|
223
|
-
}
|
|
224
|
-
function isAutoCompressEnabled() {
|
|
225
|
-
return getMergedEnv()["AGENTMEMORY_AUTO_COMPRESS"] === "true";
|
|
226
|
-
}
|
|
227
|
-
function isContextInjectionEnabled() {
|
|
228
|
-
return getMergedEnv()["AGENTMEMORY_INJECT_CONTEXT"] === "true";
|
|
229
|
-
}
|
|
230
|
-
function getConsolidationDecayDays() {
|
|
231
|
-
return safeParseInt(getMergedEnv()["CONSOLIDATION_DECAY_DAYS"], 30);
|
|
232
|
-
}
|
|
233
|
-
function getStandalonePersistPath() {
|
|
234
|
-
return getMergedEnv()["STANDALONE_PERSIST_PATH"] || join(homedir(), ".agentmemory", "standalone.json");
|
|
235
|
-
}
|
|
236
|
-
const VALID_PROVIDERS = new Set([
|
|
237
|
-
"anthropic",
|
|
238
|
-
"gemini",
|
|
239
|
-
"openrouter",
|
|
240
|
-
"agent-sdk",
|
|
241
|
-
"minimax",
|
|
242
|
-
"openai"
|
|
243
|
-
]);
|
|
244
|
-
function loadFallbackConfig() {
|
|
245
|
-
const env = getMergedEnv();
|
|
246
|
-
const raw = env["FALLBACK_PROVIDERS"] || "";
|
|
247
|
-
const allowAgentSdk = env["AGENTMEMORY_ALLOW_AGENT_SDK"] === "true";
|
|
248
|
-
return { providers: raw.split(",").map((p) => p.trim()).filter((p) => Boolean(p) && VALID_PROVIDERS.has(p)).filter((p) => {
|
|
249
|
-
if (p === "agent-sdk" && !allowAgentSdk) {
|
|
250
|
-
process.stderr.write("[agentmemory] Ignoring FALLBACK_PROVIDERS entry 'agent-sdk' (AGENTMEMORY_ALLOW_AGENT_SDK is not 'true'). The agent-sdk fallback can spawn Claude Agent SDK child sessions that trigger the Stop-hook recursion loop. Opt in explicitly with AGENTMEMORY_ALLOW_AGENT_SDK=true if this is intentional.\n");
|
|
251
|
-
return false;
|
|
252
|
-
}
|
|
253
|
-
return true;
|
|
254
|
-
}) };
|
|
255
|
-
}
|
|
256
|
-
//#endregion
|
|
257
|
-
export { loadFallbackConfig as _, getEnvVar as a, isAgentScopeIsolated as c, isContextInjectionEnabled as d, isDropStaleIndexEnabled as f, loadEmbeddingConfig as g, loadConfig as h, getConsolidationDecayDays as i, isAutoCompressEnabled as l, loadClaudeBridgeConfig as m, detectLlmProviderKind as n, getFollowupWindowSeconds as o, isGraphExtractionEnabled as p, getAgentId as r, getStandalonePersistPath as s, detectEmbeddingProvider as t, isConsolidationEnabled as u, loadSnapshotConfig as v, loadTeamConfig as y };
|
|
258
|
-
|
|
259
|
-
//# sourceMappingURL=config-ChC9EtgV.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"config-ChC9EtgV.mjs","names":[],"sources":["../src/config.ts"],"sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport pc from \"picocolors\";\nimport type {\n AgentMemoryConfig,\n ProviderConfig,\n EmbeddingConfig,\n FallbackConfig,\n ClaudeBridgeConfig,\n TeamConfig,\n} from \"./types.js\";\n\nfunction safeParseInt(value: string | undefined, fallback: number): number {\n if (!value) return fallback;\n const parsed = parseInt(value, 10);\n return Number.isNaN(parsed) ? fallback : parsed;\n}\n\nconst DATA_DIR = join(homedir(), \".agentmemory\");\nconst ENV_FILE = join(DATA_DIR, \".env\");\n\nlet warnPremiumModelShown = false;\n\nfunction loadEnvFile(): Record<string, string> {\n if (!existsSync(ENV_FILE)) return {};\n const content = readFileSync(ENV_FILE, \"utf-8\");\n const vars: Record<string, string> = {};\n for (const line of content.split(\"\\n\")) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) continue;\n const eqIdx = trimmed.indexOf(\"=\");\n if (eqIdx === -1) continue;\n const key = trimmed.slice(0, eqIdx).trim();\n let val = trimmed.slice(eqIdx + 1).trim();\n const quoteChar = val[0] === '\"' || val[0] === \"'\" ? val[0] : \"\";\n if (quoteChar) {\n const closeIdx = val.indexOf(quoteChar, 1);\n if (closeIdx !== -1) val = val.slice(1, closeIdx);\n } else {\n const hashIdx = val.indexOf(\" #\");\n if (hashIdx !== -1) val = val.slice(0, hashIdx).trim();\n }\n vars[key] = val;\n }\n return vars;\n}\n\nfunction hasRealValue(v: string | undefined): v is string {\n return typeof v === \"string\" && v.trim().length > 0;\n}\n\nfunction detectProvider(env: Record<string, string>): ProviderConfig {\n const maxTokens = parseInt(env[\"MAX_TOKENS\"] || \"4096\", 10);\n\n // OpenAI-compatible: supports OpenAI, DeepSeek, SiliconFlow, Azure, vLLM, LM Studio\n if (hasRealValue(env[\"OPENAI_API_KEY\"]) && env[\"OPENAI_API_KEY_FOR_LLM\"] !== \"false\") {\n return {\n provider: \"openai\",\n model: env[\"OPENAI_MODEL\"] || \"gpt-4o-mini\",\n maxTokens,\n baseURL: env[\"OPENAI_BASE_URL\"],\n };\n }\n\n // MiniMax: Anthropic-compatible API, requires raw fetch to avoid SDK stainless headers\n if (hasRealValue(env[\"MINIMAX_API_KEY\"])) {\n return {\n provider: \"minimax\",\n model: env[\"MINIMAX_MODEL\"] || \"MiniMax-M2.7\",\n maxTokens,\n };\n }\n\n if (hasRealValue(env[\"ANTHROPIC_API_KEY\"])) {\n return {\n provider: \"anthropic\",\n model: env[\"ANTHROPIC_MODEL\"] || \"claude-sonnet-4-20250514\",\n maxTokens,\n baseURL: env[\"ANTHROPIC_BASE_URL\"],\n };\n }\n if (hasRealValue(env[\"GEMINI_API_KEY\"]) || hasRealValue(env[\"GOOGLE_API_KEY\"])) {\n if (!hasRealValue(env[\"GEMINI_API_KEY\"]) && hasRealValue(env[\"GOOGLE_API_KEY\"])) {\n process.stderr.write(\n \"[agentmemory] GOOGLE_API_KEY detected — treating as GEMINI_API_KEY. \" +\n \"Set GEMINI_API_KEY in ~/.agentmemory/.env to silence this warning.\\n\",\n );\n }\n return {\n provider: \"gemini\",\n model: env[\"GEMINI_MODEL\"] || \"gemini-2.5-flash\",\n maxTokens,\n };\n }\n if (hasRealValue(env[\"OPENROUTER_API_KEY\"])) {\n const model =\n env[\"OPENROUTER_MODEL\"] || \"anthropic/claude-sonnet-4-20250514\";\n // warn when the configured OpenRouter model is in the\n // premium tier and likely to burn money on background compression.\n // Captured workload data shows ~$5/35h on claude-sonnet-4 vs\n // ~$0.46/35h on deepseek-v4-pro for the same compression mix.\n // Heuristic match avoids hard-coding a pricing table.\n if (\n !warnPremiumModelShown &&\n /sonnet|opus|gpt-4o(?!.*mini)|gpt-4-turbo/i.test(model) &&\n env[\"AGENTMEMORY_SUPPRESS_COST_WARNING\"] !== \"1\" &&\n env[\"AGENTMEMORY_SUPPRESS_COST_WARNING\"] !== \"true\"\n ) {\n warnPremiumModelShown = true;\n process.stderr.write(\n `[agentmemory] OPENROUTER_MODEL=${model} is in the premium tier. ` +\n `Background compression on this model can cost $5+/day under active use. ` +\n `Cheaper alternatives with comparable quality for memory compression: ` +\n `deepseek/deepseek-v4-pro, deepseek/deepseek-chat, qwen/qwen3-coder. ` +\n `See README \"Cost-aware model selection\" for the full table. ` +\n `Set AGENTMEMORY_SUPPRESS_COST_WARNING=1 to silence.\\n`,\n );\n }\n return {\n provider: \"openrouter\",\n model,\n maxTokens,\n };\n }\n\n const allowAgentSdk = env[\"AGENTMEMORY_ALLOW_AGENT_SDK\"] === \"true\";\n if (!allowAgentSdk) {\n process.stderr.write(\n pc.dim(\n \"[agentmemory] No LLM provider key set — running zero-LLM (BM25 + on-device embeddings). \" +\n \"Set ANTHROPIC_API_KEY (or GEMINI/OPENAI/OPENROUTER/MINIMAX) in ~/.agentmemory/.env for LLM compression and summaries. \" +\n \"Agent-SDK fallback stays off by default to avoid a Stop-hook recursion loop; opt in with AGENTMEMORY_AUTO_COMPRESS=true + AGENTMEMORY_ALLOW_AGENT_SDK=true.\\n\",\n ),\n );\n return {\n provider: \"noop\",\n model: \"noop\",\n maxTokens,\n };\n }\n\n process.stderr.write(\n \"[agentmemory] WARNING: agent-sdk fallback enabled via AGENTMEMORY_ALLOW_AGENT_SDK=true. \" +\n \"This spawns @anthropic-ai/claude-agent-sdk child sessions that can trigger the Stop-hook \" +\n \"recursion loop. A SDK-child env marker is set to block re-entry, \" +\n \"but prefer setting a real API key in ~/.agentmemory/.env instead.\\n\",\n );\n return {\n provider: \"agent-sdk\",\n model: \"claude-sonnet-4-20250514\",\n maxTokens,\n };\n}\n\nexport function loadConfig(): AgentMemoryConfig {\n const env = getMergedEnv();\n\n const provider = detectProvider(env);\n\n // Port quartet: REST is the anchor; streams/engine derive from it\n // unless individually overridden. Default anchor 3111 yields the\n // canonical 3112 streams / 49134 engine pair, but `III_REST_PORT=3211`\n // auto-picks 3212 + 49234 so a second instance doesn't collide.\n const restPort = parseInt(env[\"III_REST_PORT\"] || \"3111\", 10) || 3111;\n const streamsPort =\n parseInt(env[\"III_STREAM_PORT\"] || env[\"III_STREAMS_PORT\"] || \"\", 10) ||\n restPort + 1;\n const engineUrl =\n env[\"III_ENGINE_URL\"] ||\n `ws://localhost:${\n parseInt(env[\"III_ENGINE_PORT\"] || \"\", 10) || restPort + 46023\n }`;\n\n return {\n engineUrl,\n restPort,\n streamsPort,\n provider,\n tokenBudget: safeParseInt(env[\"TOKEN_BUDGET\"], 2000),\n maxObservationsPerSession: safeParseInt(env[\"MAX_OBS_PER_SESSION\"], 500),\n compressionModel: provider.model,\n dataDir: DATA_DIR,\n };\n}\n\nfunction getMergedEnv(\n overrides?: Record<string, string>,\n): Record<string, string> {\n const fileEnv = loadEnvFile();\n return { ...fileEnv, ...process.env, ...overrides } as Record<string, string>;\n}\n\nexport function getEnvVar(key: string): string | undefined {\n return getMergedEnv()[key];\n}\n\nexport function isDropStaleIndexEnabled(): boolean {\n return getMergedEnv()[\"AGENTMEMORY_DROP_STALE_INDEX\"] === \"true\";\n}\n\nexport function detectLlmProviderKind(): \"llm\" | \"noop\" {\n const env = getMergedEnv();\n if (\n hasRealValue(env[\"ANTHROPIC_API_KEY\"]) ||\n hasRealValue(env[\"GEMINI_API_KEY\"]) ||\n hasRealValue(env[\"GOOGLE_API_KEY\"]) ||\n hasRealValue(env[\"OPENROUTER_API_KEY\"]) ||\n hasRealValue(env[\"MINIMAX_API_KEY\"]) ||\n (hasRealValue(env[\"OPENAI_API_KEY\"]) &&\n env[\"OPENAI_API_KEY_FOR_LLM\"] !== \"false\")\n ) {\n return \"llm\";\n }\n return \"noop\";\n}\n\nexport function loadEmbeddingConfig(): EmbeddingConfig {\n const env = getMergedEnv();\n let bm25Weight = parseFloat(env[\"BM25_WEIGHT\"] || \"0.4\");\n let vectorWeight = parseFloat(env[\"VECTOR_WEIGHT\"] || \"0.6\");\n bm25Weight =\n isNaN(bm25Weight) || bm25Weight < 0 ? 0.4 : Math.min(bm25Weight, 1);\n vectorWeight =\n isNaN(vectorWeight) || vectorWeight < 0 ? 0.6 : Math.min(vectorWeight, 1);\n return {\n provider: env[\"EMBEDDING_PROVIDER\"] || undefined,\n bm25Weight,\n vectorWeight,\n };\n}\n\nexport function detectEmbeddingProvider(\n env?: Record<string, string>,\n): string | null {\n const source = env ?? getMergedEnv();\n const forced = source[\"EMBEDDING_PROVIDER\"];\n if (forced) return forced;\n\n if (source[\"GEMINI_API_KEY\"]) return \"gemini\";\n if (source[\"OPENAI_API_KEY\"]) return \"openai\";\n if (source[\"VOYAGE_API_KEY\"]) return \"voyage\";\n if (source[\"COHERE_API_KEY\"]) return \"cohere\";\n if (source[\"OPENROUTER_API_KEY\"]) return \"openrouter\";\n return null;\n}\n\nexport function loadClaudeBridgeConfig(): ClaudeBridgeConfig {\n const env = getMergedEnv();\n const enabled = env[\"CLAUDE_MEMORY_BRIDGE\"] === \"true\";\n const projectPath = env[\"CLAUDE_PROJECT_PATH\"] || \"\";\n const lineBudget = safeParseInt(env[\"CLAUDE_MEMORY_LINE_BUDGET\"], 200);\n let memoryFilePath = \"\";\n if (enabled && projectPath) {\n // Claude Code stores MEMORY.md at\n // ~/.claude/projects/<slug>/MEMORY.md\n // where <slug> is the project path with `/` and `\\` swapped for `-`.\n // The leading `-` from an absolute POSIX path is preserved (Claude\n // Code keeps it; stripping it produced a slug Claude never reads).\n // There's also no `memory/` subdirectory — the file sits directly\n // under the slug dir.\n const safePath = projectPath.replace(/[/\\\\]/g, \"-\");\n memoryFilePath = join(\n homedir(),\n \".claude\",\n \"projects\",\n safePath,\n \"MEMORY.md\",\n );\n }\n return { enabled, projectPath, memoryFilePath, lineBudget };\n}\n\nexport function loadTeamConfig(): TeamConfig | null {\n const env = getMergedEnv();\n const teamId = env[\"TEAM_ID\"];\n const userId = env[\"USER_ID\"];\n if (!teamId || !userId) return null;\n const mode = env[\"TEAM_MODE\"] === \"shared\" ? \"shared\" : \"private\";\n return { teamId, userId, mode };\n}\n\n// optional AGENT_ID env for multi-agent memory isolation.\n// Returns null when unset so memory stays unscoped (legacy behavior).\n// Trimmed + length-capped to keep KV writes well-formed.\n//\n// Filtering is gated by AGENTMEMORY_AGENT_SCOPE:\n// \"shared\" (default) — tag everything, do not filter recall paths\n// \"isolated\" — tag everything AND filter recall paths\nexport function loadAgentScope(): {\n agentId: string;\n mode: \"shared\" | \"isolated\";\n} | null {\n const env = getMergedEnv();\n const raw = env[\"AGENT_ID\"];\n if (!raw) return null;\n const agentId = raw.trim().slice(0, 128);\n if (!agentId) return null;\n const mode = env[\"AGENTMEMORY_AGENT_SCOPE\"] === \"isolated\"\n ? \"isolated\"\n : \"shared\";\n return { agentId, mode };\n}\n\nexport function getAgentId(): string | undefined {\n return loadAgentScope()?.agentId;\n}\n\n// True only when AGENT_ID is set AND scope=isolated. Recall paths\n// consult this to decide whether to filter.\nexport function isAgentScopeIsolated(): boolean {\n return loadAgentScope()?.mode === \"isolated\";\n}\n\nexport function loadSnapshotConfig(): {\n enabled: boolean;\n interval: number;\n dir: string;\n} {\n const env = getMergedEnv();\n return {\n enabled: env[\"SNAPSHOT_ENABLED\"] === \"true\",\n interval: safeParseInt(env[\"SNAPSHOT_INTERVAL\"], 3600),\n dir: env[\"SNAPSHOT_DIR\"] || join(homedir(), \".agentmemory\", \"snapshots\"),\n };\n}\n\nexport function isGraphExtractionEnabled(): boolean {\n return getMergedEnv()[\"GRAPH_EXTRACTION_ENABLED\"] === \"true\";\n}\n\nexport function getGraphBatchSize(): number {\n return safeParseInt(getMergedEnv()[\"GRAPH_EXTRACTION_BATCH_SIZE\"], 10);\n}\n\n// window for the smart-search followup-rate diagnostic. A second\n// search arriving within this many seconds (with disjoint results)\n// counts as a \"follow-up\" — a directional signal that the first result\n// set didn't satisfy. Long values overcount (legitimate refinement\n// looks like a follow-up); short values undercount.\nconst FOLLOWUP_WINDOW_DEFAULT_SECONDS = 30;\n\nexport function getFollowupWindowSeconds(): number {\n return safeParseInt(\n getMergedEnv()[\"AGENTMEMORY_FOLLOWUP_WINDOW_SECONDS\"],\n FOLLOWUP_WINDOW_DEFAULT_SECONDS,\n );\n}\n\nexport function isConsolidationEnabled(): boolean {\n const env = getMergedEnv();\n const explicit = env[\"CONSOLIDATION_ENABLED\"];\n if (explicit === \"false\" || explicit === \"0\") return false;\n if (explicit === \"true\" || explicit === \"1\") return true;\n return hasLLMProviderConfigured(env);\n}\n\nfunction hasLLMProviderConfigured(env: Record<string, string | undefined>): boolean {\n const provider = (env[\"AGENTMEMORY_PROVIDER\"] || \"\").toLowerCase();\n if (provider === \"noop\") return false;\n const openaiKeyForLlm =\n env[\"OPENAI_API_KEY\"] &&\n (env[\"OPENAI_API_KEY_FOR_LLM\"] || \"\").toLowerCase() !== \"false\";\n return Boolean(\n env[\"ANTHROPIC_API_KEY\"] ||\n openaiKeyForLlm ||\n env[\"OPENROUTER_API_KEY\"] ||\n env[\"GEMINI_API_KEY\"] ||\n env[\"GOOGLE_API_KEY\"] ||\n env[\"MINIMAX_API_KEY\"] ||\n env[\"OPENAI_BASE_URL\"] ||\n provider === \"agent-sdk\",\n );\n}\n\n// Per-observation LLM compression is OFF by default as of 0.8.8.\n// When disabled, observations are captured and indexed via a synthetic\n// (zero-LLM) compression path so recall/search still works. Users who want\n// richer LLM-generated summaries can set AGENTMEMORY_AUTO_COMPRESS=true in\n// ~/.agentmemory/.env — but should expect their Claude API token usage to\n// climb proportionally with session tool-use frequency.\nexport function isAutoCompressEnabled(): boolean {\n return getMergedEnv()[\"AGENTMEMORY_AUTO_COMPRESS\"] === \"true\";\n}\n\n// Hook-level context injection into Claude Code's conversation is OFF by\n// default as of 0.8.10. When disabled, pre-tool-use and\n// session-start hooks still POST observations for background capture, but\n// never write context to stdout — so Claude Code doesn't inject an extra\n// ~4000-char blob into every tool turn. 0.8.8 stopped the agentmemory-side\n// Claude calls (via ANTHROPIC_API_KEY); this stops the Claude Code-side\n// token burn where every tool call silently grew the model input window.\n// Users who want the in-conversation context injection explicitly opt in\n// with AGENTMEMORY_INJECT_CONTEXT=true and get a loud startup warning.\nexport function isContextInjectionEnabled(): boolean {\n return getMergedEnv()[\"AGENTMEMORY_INJECT_CONTEXT\"] === \"true\";\n}\n\nexport function getConsolidationDecayDays(): number {\n return safeParseInt(getMergedEnv()[\"CONSOLIDATION_DECAY_DAYS\"], 30);\n}\n\nexport function isStandaloneMcp(): boolean {\n return getMergedEnv()[\"STANDALONE_MCP\"] === \"true\";\n}\n\nexport function getStandalonePersistPath(): string {\n const env = getMergedEnv();\n return (\n env[\"STANDALONE_PERSIST_PATH\"] ||\n join(homedir(), \".agentmemory\", \"standalone.json\")\n );\n}\n\nconst VALID_PROVIDERS = new Set([\n \"anthropic\",\n \"gemini\",\n \"openrouter\",\n \"agent-sdk\",\n \"minimax\",\n \"openai\",\n]);\n\nexport function loadFallbackConfig(): FallbackConfig {\n const env = getMergedEnv();\n const raw = env[\"FALLBACK_PROVIDERS\"] || \"\";\n const allowAgentSdk = env[\"AGENTMEMORY_ALLOW_AGENT_SDK\"] === \"true\";\n const providers = raw\n .split(\",\")\n .map((p) => p.trim())\n .filter(\n (p): p is FallbackConfig[\"providers\"][number] =>\n Boolean(p) && VALID_PROVIDERS.has(p),\n )\n .filter((p) => {\n // Honor the same safety gate as detectProvider: agent-sdk is only\n // permitted as a fallback target when the user has explicitly opted\n // in. Without this filter, a user could set FALLBACK_PROVIDERS=agent-sdk\n // and re-introduce the Stop-hook recursion loop even though\n // detectProvider() returned the noop provider.\n if (p === \"agent-sdk\" && !allowAgentSdk) {\n process.stderr.write(\n \"[agentmemory] Ignoring FALLBACK_PROVIDERS entry 'agent-sdk' \" +\n \"(AGENTMEMORY_ALLOW_AGENT_SDK is not 'true'). The agent-sdk \" +\n \"fallback can spawn Claude Agent SDK child sessions that trigger \" +\n \"the Stop-hook recursion loop. Opt in explicitly \" +\n \"with AGENTMEMORY_ALLOW_AGENT_SDK=true if this is intentional.\\n\",\n );\n return false;\n }\n return true;\n });\n return { providers };\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"connect-JnsJXc68.mjs","names":["entryMatches","adapter","entryMatches","adapter","adapter","entryMatches","adapter","adapter","adapter","adapter","adapter","adapter","DOCS","adapter","adapter","adapter","adapter","DOCS","adapter","adapter","adapter","adapter","claudeCode","copilotCli","codex","cursor","geminiCli","qwen","antigravity","kiro","warp","cline","continueDev","zed","droid","opencode","openclaw","hermes","pi","openhuman"],"sources":["../src/cli/connect/util.ts","../src/cli/connect/json-mcp-adapter.ts","../src/cli/connect/antigravity.ts","../src/cli/connect/codex-hooks.ts","../src/cli/connect/claude-code.ts","../src/cli/connect/cline.ts","../src/cli/connect/copilot-cli.ts","../src/cli/connect/codex.ts","../src/cli/connect/continue.ts","../src/cli/connect/cursor.ts","../src/cli/connect/droid.ts","../src/cli/connect/gemini-cli.ts","../src/cli/connect/hermes.ts","../src/cli/connect/kiro.ts","../src/cli/connect/openclaw.ts","../src/cli/connect/opencode.ts","../src/cli/connect/openhuman.ts","../src/cli/connect/pi.ts","../src/cli/connect/qwen.ts","../src/cli/connect/warp.ts","../src/cli/connect/zed.ts","../src/cli/connect/index.ts"],"sourcesContent":["import {\n existsSync,\n mkdirSync,\n readFileSync,\n writeFileSync,\n copyFileSync,\n renameSync,\n} from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport * as p from \"@clack/prompts\";\n\n// Env values use ${VAR:-default} expansion so the wired MCP entry\n// inherits AGENTMEMORY_URL / AGENTMEMORY_SECRET / AGENTMEMORY_TOOLS\n// from the user's shell, but never fails parse when the var is unset\n// (#510). Earlier `${VAR}` form caused Claude Code to silently drop the\n// server when no shell-level export existed — per the Claude Code MCP\n// docs, \"If a required environment variable is not set and has no\n// default value, Claude Code will fail to parse the config.\"\n//\n// Defaults match the documented runtime: localhost:3111 (no auth, all\n// tools). One wired entry now serves local AND remote (Kubernetes /\n// reverse-proxied) deployments without doctor-warning duplicates (#375)\n// AND fresh installs that haven't exported envs (#510).\nexport const AGENTMEMORY_MCP_BLOCK = {\n command: \"npx\",\n args: [\"-y\", \"@agentmemory/mcp\"],\n env: {\n AGENTMEMORY_URL: \"${AGENTMEMORY_URL:-http://localhost:3111}\",\n AGENTMEMORY_SECRET: \"${AGENTMEMORY_SECRET:-}\",\n AGENTMEMORY_TOOLS: \"${AGENTMEMORY_TOOLS:-all}\",\n },\n};\n\nconst COPILOT_MCP_COMMAND =\n process.platform === \"win32\"\n ? {\n command: process.env[\"ComSpec\"] || process.env[\"COMSPEC\"] || \"cmd.exe\",\n args: [\"/d\", \"/s\", \"/c\", \"npx\", \"-y\", \"@agentmemory/mcp\"],\n }\n : {\n command: \"npx\",\n args: [\"-y\", \"@agentmemory/mcp\"],\n };\n\nexport const AGENTMEMORY_COPILOT_MCP_BLOCK = {\n type: \"local\" as const,\n ...COPILOT_MCP_COMMAND,\n env: {\n AGENTMEMORY_URL: \"${AGENTMEMORY_URL:-http://localhost:3111}\",\n AGENTMEMORY_SECRET: \"${AGENTMEMORY_SECRET:-}\",\n AGENTMEMORY_TOOLS: \"${AGENTMEMORY_TOOLS:-all}\",\n },\n tools: [\"*\"],\n};\n\nexport function backupsDir(): string {\n return join(homedir(), \".agentmemory\", \"backups\");\n}\n\nexport function ensureBackupsDir(): string {\n const dir = backupsDir();\n mkdirSync(dir, { recursive: true });\n return dir;\n}\n\nexport function timestampSlug(): string {\n return new Date().toISOString().replace(/[:.]/g, \"-\");\n}\n\nexport function backupFile(\n sourcePath: string,\n agent: string,\n ext = \"json\",\n): string {\n ensureBackupsDir();\n const stamp = timestampSlug();\n const target = join(backupsDir(), `${agent}-${stamp}.${ext}`);\n copyFileSync(sourcePath, target);\n return target;\n}\n\nexport function readJsonSafe<T = unknown>(path: string): T | null {\n if (!existsSync(path)) return null;\n try {\n return JSON.parse(readFileSync(path, \"utf-8\")) as T;\n } catch {\n return null;\n }\n}\n\nexport function writeJsonAtomic(path: string, value: unknown): void {\n mkdirSync(dirname(path), { recursive: true });\n const tmp = `${path}.tmp-${process.pid}-${Date.now()}`;\n writeFileSync(tmp, `${JSON.stringify(value, null, 2)}\\n`, \"utf-8\");\n renameSync(tmp, path);\n}\n\nexport function logInstalled(label: string, target: string): void {\n p.log.success(`${label} → wired into ${target}`);\n}\n\nexport function logAlreadyWired(label: string, target: string): void {\n p.log.info(`${label} already wired in ${target} (use --force to re-install)`);\n}\n\nexport function logBackup(target: string): void {\n p.log.info(`Backup: ${target}`);\n}\n","import { existsSync, mkdirSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\nimport * as p from \"@clack/prompts\";\nimport type { ConnectAdapter, ConnectOptions, ConnectResult } from \"./types.js\";\nimport {\n AGENTMEMORY_MCP_BLOCK,\n backupFile,\n logAlreadyWired,\n logBackup,\n logInstalled,\n readJsonSafe,\n writeJsonAtomic,\n} from \"./util.js\";\n\nexport type JsonMcpAdapterConfig = {\n name: string;\n displayName: string;\n detectDir: string;\n configPath: string;\n docs?: string;\n protocolNote?: string;\n // Integration style for onboarding grouping. Defaults to \"mcp\" since a\n // JSON MCP config writer is MCP-only by construction; hosts that also\n // ship hooks (e.g. OpenClaw) pass \"native\".\n category?: \"native\" | \"mcp\";\n // Wrapper key under which servers live. Default \"mcpServers\".\n // Zed uses \"context_servers\"; otherwise same shape.\n wrapperKey?: string;\n // Extra fields merged into the agentmemory entry. Droid requires\n // type: \"stdio\"; other hosts ignore unknown fields.\n extraEntryFields?: Record<string, unknown>;\n};\n\ntype McpEntry = typeof AGENTMEMORY_MCP_BLOCK;\ntype McpConfig = Record<string, unknown>;\n\nfunction entryMatches(entry: unknown): boolean {\n if (!entry || typeof entry !== \"object\") return false;\n const e = entry as Record<string, unknown>;\n if (e[\"command\"] !== \"npx\") return false;\n const args = Array.isArray(e[\"args\"]) ? (e[\"args\"] as string[]) : [];\n return args.includes(\"@agentmemory/mcp\");\n}\n\nexport function createJsonMcpAdapter(\n config: JsonMcpAdapterConfig,\n): ConnectAdapter {\n const wrapperKey = config.wrapperKey ?? \"mcpServers\";\n return {\n name: config.name,\n displayName: config.displayName,\n category: config.category ?? \"mcp\",\n ...(config.docs !== undefined && { docs: config.docs }),\n ...(config.protocolNote !== undefined && {\n protocolNote: config.protocolNote,\n }),\n\n detect(): boolean {\n return existsSync(config.detectDir);\n },\n\n async install(opts: ConnectOptions): Promise<ConnectResult> {\n const existing = readJsonSafe<McpConfig>(config.configPath);\n const next: McpConfig = existing ? { ...existing } : {};\n const servers: Record<string, McpEntry> = {\n ...((next[wrapperKey] as Record<string, McpEntry>) ?? {}),\n };\n\n const alreadyHas = entryMatches(servers[\"agentmemory\"]);\n if (alreadyHas && !opts.force) {\n logAlreadyWired(config.displayName, config.configPath);\n return { kind: \"already-wired\", mutatedPath: config.configPath };\n }\n\n if (opts.dryRun) {\n p.log.info(\n `[dry-run] Would ${alreadyHas ? \"overwrite\" : \"add\"} ${wrapperKey}.agentmemory in ${config.configPath}`,\n );\n return { kind: \"installed\", mutatedPath: config.configPath };\n }\n\n let backupPath: string | undefined;\n if (existsSync(config.configPath)) {\n backupPath = backupFile(config.configPath, config.name);\n logBackup(backupPath);\n } else {\n mkdirSync(dirname(config.configPath), { recursive: true });\n }\n\n servers[\"agentmemory\"] = {\n ...AGENTMEMORY_MCP_BLOCK,\n ...(config.extraEntryFields ?? {}),\n };\n next[wrapperKey] = servers;\n writeJsonAtomic(config.configPath, next);\n\n const verify = readJsonSafe<McpConfig>(config.configPath);\n const verifyServers = verify?.[wrapperKey] as\n | Record<string, McpEntry>\n | undefined;\n if (!entryMatches(verifyServers?.[\"agentmemory\"])) {\n p.log.error(\n `Verification failed: ${config.configPath} did not contain ${wrapperKey}.agentmemory after write.`,\n );\n return { kind: \"skipped\", reason: \"verification-failed\" };\n }\n\n logInstalled(config.displayName, config.configPath);\n return {\n kind: \"installed\",\n mutatedPath: config.configPath,\n ...(backupPath !== undefined && { backupPath }),\n };\n },\n };\n}\n","import { homedir, platform } from \"node:os\";\nimport { join } from \"node:path\";\nimport { createJsonMcpAdapter } from \"./json-mcp-adapter.js\";\n\n// Antigravity stores MCP config in mcp_config.json under its app\n// support directory. The schema follows the standard MCP envelope —\n// `{ mcpServers: { ... } }`. Path varies by platform:\n// macOS: ~/Library/Application Support/Antigravity/User/mcp_config.json\n// Linux: ~/.config/Antigravity/User/mcp_config.json\n// Windows: %APPDATA%/Antigravity/User/mcp_config.json\n// Connect is gated on win32 elsewhere; we cover macOS + Linux here.\nconst ANTIGRAVITY_DIR =\n platform() === \"darwin\"\n ? join(homedir(), \"Library\", \"Application Support\", \"Antigravity\", \"User\")\n : join(homedir(), \".config\", \"Antigravity\", \"User\");\n\nexport const adapter = createJsonMcpAdapter({\n name: \"antigravity\",\n displayName: \"Antigravity\",\n detectDir: ANTIGRAVITY_DIR,\n configPath: join(ANTIGRAVITY_DIR, \"mcp_config.json\"),\n docs: \"https://github.com/rohitg00/agentmemory#other-agents\",\n protocolNote:\n \"→ Using MCP via mcp_config.json. Antigravity replaces Gemini CLI (sunset 2026-06-18).\",\n});\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\n/**\n * Workaround for openai/codex#16430 — Codex Desktop does not dispatch\n * plugin-local `hooks.json` even though both `CodexHooks` and `PluginHooks`\n * feature flags are stable + default-enabled in\n * `codex-rs/features/src/lib.rs`. Until upstream fixes plugin-scope\n * dispatch, the same hook commands can be mirrored into the global\n * `~/.codex/hooks.json`, which is loaded reliably.\n *\n * This module builds that mirror, with `${CLAUDE_PLUGIN_ROOT}` resolved to\n * the bundled `plugin/` directory so the user-scope file does not depend\n * on env-var expansion (Codex only injects `CLAUDE_PLUGIN_ROOT` for\n * plugin-scope hooks).\n *\n * Identification on re-install: every command we write contains the\n * resolved `<pluginRoot>/scripts/` prefix, so subsequent installs can\n * strip our entries and re-add cleanly without touching the user's other\n * hook entries.\n */\n\ntype HookHandler = { type: string; command: string };\ntype HookEntry = { matcher?: string; hooks: HookHandler[] };\nexport type HookManifest = { hooks: Record<string, HookEntry[]> };\n\n/**\n * Locate the bundled `plugin/` directory at runtime. Walks up from the\n * module's own location looking for `plugin/scripts/` + `plugin/hooks/`,\n * both shipped via the npm `files` field. Works for both `dist/cli.mjs`\n * (bundled) and `src/cli/connect/codex-hooks.ts` (dev) layouts.\n */\nexport function findPluginRoot(startUrl: string = import.meta.url): string {\n const here = dirname(fileURLToPath(startUrl));\n let dir = here;\n for (let i = 0; i < 12; i++) {\n if (\n existsSync(join(dir, \"plugin\", \"scripts\")) &&\n existsSync(join(dir, \"plugin\", \"hooks\"))\n ) {\n return resolve(join(dir, \"plugin\"));\n }\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n throw new Error(\n `agentmemory: could not locate bundled plugin/ directory (searched up from ${here})`,\n );\n}\n\n/**\n * Build the merged hooks.json content.\n *\n * 1. Strip any entry from `existing` whose first hook command points\n * under `<pluginRoot>/scripts/`. This lets us re-install idempotently\n * without leaving stale references.\n * 2. Append fresh entries from the bundled Codex manifest with\n * `${CLAUDE_PLUGIN_ROOT}` rewritten to the absolute plugin path.\n * Matcher values from the bundled manifest are preserved so PreToolUse\n * event routing keeps working.\n */\nexport function buildMergedHooks(\n existing: HookManifest | null,\n pluginRoot: string,\n manifestFile = \"hooks.codex.json\",\n): HookManifest {\n const bundledManifestPath = join(pluginRoot, \"hooks\", manifestFile);\n const ours = JSON.parse(readFileSync(bundledManifestPath, \"utf-8\")) as HookManifest;\n const scriptsDir = join(pluginRoot, \"scripts\");\n\n const out: HookManifest = { hooks: {} };\n\n if (existing?.hooks) {\n for (const [event, entries] of Object.entries(existing.hooks)) {\n const kept = entries.filter((entry) => !isAgentmemoryEntry(entry, scriptsDir));\n if (kept.length > 0) out.hooks[event] = kept;\n }\n }\n\n for (const [event, entries] of Object.entries(ours.hooks)) {\n const resolvedEntries: HookEntry[] = entries.map((entry) => {\n const next: HookEntry = {\n hooks: entry.hooks.map((handler) => ({\n type: handler.type,\n command: handler.command.replace(/\\$\\{CLAUDE_PLUGIN_ROOT\\}/g, pluginRoot),\n })),\n };\n if (entry.matcher !== undefined) next.matcher = entry.matcher;\n return next;\n });\n out.hooks[event] = [...(out.hooks[event] ?? []), ...resolvedEntries];\n }\n\n return out;\n}\n\nfunction isAgentmemoryEntry(entry: HookEntry, scriptsDir: string): boolean {\n const normalizedScriptsDir = normalizePathForCommandMatch(scriptsDir);\n return entry.hooks.some((handler) =>\n normalizePathForCommandMatch(handler.command).includes(normalizedScriptsDir),\n );\n}\n\nfunction normalizePathForCommandMatch(value: string): string {\n return value.replace(/\\\\/g, \"/\");\n}\n","import { existsSync, mkdirSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport * as p from \"@clack/prompts\";\nimport type { ConnectAdapter, ConnectOptions, ConnectResult } from \"./types.js\";\nimport {\n AGENTMEMORY_MCP_BLOCK,\n backupFile,\n logAlreadyWired,\n logBackup,\n logInstalled,\n readJsonSafe,\n writeJsonAtomic,\n} from \"./util.js\";\nimport {\n buildMergedHooks,\n findPluginRoot,\n type HookManifest,\n} from \"./codex-hooks.js\";\n\nconst CLAUDE_DIR = join(homedir(), \".claude\");\nconst CLAUDE_JSON = join(homedir(), \".claude.json\");\nconst CLAUDE_SETTINGS = join(CLAUDE_DIR, \"settings.json\");\n\ntype ClaudeMcpEntry = typeof AGENTMEMORY_MCP_BLOCK;\ntype ClaudeConfig = {\n mcpServers?: Record<string, ClaudeMcpEntry>;\n [key: string]: unknown;\n};\n\nfunction entryMatches(entry: unknown): boolean {\n if (!entry || typeof entry !== \"object\") return false;\n const e = entry as Record<string, unknown>;\n if (e[\"command\"] !== \"npx\") return false;\n const args = Array.isArray(e[\"args\"]) ? (e[\"args\"] as string[]) : [];\n return args.includes(\"@agentmemory/mcp\");\n}\n\nexport const adapter: ConnectAdapter = {\n name: \"claude-code\",\n displayName: \"Claude Code\",\n category: \"native\",\n docs: \"https://github.com/rohitg00/agentmemory#claude-code-one-block-paste-it\",\n protocolNote:\n \"→ Using MCP. Hooks are also available — see https://github.com/rohitg00/agentmemory#claude-code-one-block-paste-it.\",\n\n detect(): boolean {\n return existsSync(CLAUDE_DIR);\n },\n\n async install(opts: ConnectOptions): Promise<ConnectResult> {\n const existing = readJsonSafe<ClaudeConfig>(CLAUDE_JSON);\n const next: ClaudeConfig = existing ? { ...existing } : {};\n const servers: Record<string, ClaudeMcpEntry> = {\n ...((next.mcpServers as Record<string, ClaudeMcpEntry>) ?? {}),\n };\n\n const alreadyHas = entryMatches(servers[\"agentmemory\"]);\n if (alreadyHas && !opts.force) {\n logAlreadyWired(\"Claude Code\", CLAUDE_JSON);\n // --with-hooks is independent of MCP wiring (issue #508). Run the\n // hooks fallback even when MCP is already in place so users with a\n // healthy MCP setup can still pick up version-stable hook paths.\n if (opts.withHooks) {\n const hookResult = installClaudeHooks(opts);\n if (hookResult.kind === \"skipped\") {\n p.log.warn(\n `Claude Code hooks fallback skipped: ${hookResult.reason}.`,\n );\n }\n }\n return { kind: \"already-wired\", mutatedPath: CLAUDE_JSON };\n }\n\n if (opts.dryRun) {\n p.log.info(\n `[dry-run] Would ${alreadyHas ? \"overwrite\" : \"add\"} mcpServers.agentmemory in ${CLAUDE_JSON}`,\n );\n return { kind: \"installed\", mutatedPath: CLAUDE_JSON };\n }\n\n let backupPath: string | undefined;\n if (existsSync(CLAUDE_JSON)) {\n backupPath = backupFile(CLAUDE_JSON, \"claude-code\");\n logBackup(backupPath);\n } else {\n mkdirSync(CLAUDE_DIR, { recursive: true });\n writeFileSync(CLAUDE_JSON, \"{}\\n\", \"utf-8\");\n }\n\n servers[\"agentmemory\"] = AGENTMEMORY_MCP_BLOCK;\n next.mcpServers = servers;\n writeJsonAtomic(CLAUDE_JSON, next);\n\n const verify = readJsonSafe<ClaudeConfig>(CLAUDE_JSON);\n if (!entryMatches(verify?.mcpServers?.[\"agentmemory\"])) {\n p.log.error(\n `Verification failed: ${CLAUDE_JSON} did not contain mcpServers.agentmemory after write.`,\n );\n return { kind: \"skipped\", reason: \"verification-failed\" };\n }\n\n logInstalled(\"Claude Code\", CLAUDE_JSON);\n p.log.info(\n \"Restart Claude Code (or run `/mcp` inside a session) to pick up the new server.\",\n );\n\n if (opts.withHooks) {\n const hookResult = installClaudeHooks(opts);\n if (hookResult.kind === \"skipped\") {\n p.log.warn(\n `Claude Code hooks fallback skipped: ${hookResult.reason}. MCP wiring still applied.`,\n );\n }\n }\n\n return { kind: \"installed\", mutatedPath: CLAUDE_JSON, backupPath };\n },\n};\n\n/**\n * Merge the bundled `plugin/hooks/hooks.json` into\n * `~/.claude/settings.json`'s top-level `hooks` field with absolute\n * script paths. Use this when agentmemory is NOT installed through\n * `/plugin marketplace add` (e.g. MCP standalone wiring), so the\n * hook scripts survive version bumps without `${CLAUDE_PLUGIN_ROOT}`\n * expansion (issue #508).\n *\n * Re-install strips entries whose command points under\n * `<pluginRoot>/scripts/`; unrelated user hook entries survive.\n */\nfunction installClaudeHooks(opts: ConnectOptions): ConnectResult {\n let pluginRoot: string;\n try {\n pluginRoot = findPluginRoot();\n } catch (err) {\n return {\n kind: \"skipped\",\n reason: err instanceof Error ? err.message : String(err),\n };\n }\n\n type ClaudeSettings = { hooks?: HookManifest[\"hooks\"]; [key: string]: unknown };\n const existing = readJsonSafe<ClaudeSettings>(CLAUDE_SETTINGS) ?? {};\n const existingHooks: HookManifest | null = existing.hooks\n ? { hooks: existing.hooks }\n : null;\n const merged = buildMergedHooks(existingHooks, pluginRoot, \"hooks.json\");\n\n if (opts.dryRun) {\n p.log.info(\n `[dry-run] Would merge agentmemory hook entries into ${CLAUDE_SETTINGS} (${Object.keys(merged.hooks).length} event(s))`,\n );\n return { kind: \"installed\", mutatedPath: CLAUDE_SETTINGS };\n }\n\n let backupPath: string | undefined;\n if (existsSync(CLAUDE_SETTINGS)) {\n backupPath = backupFile(CLAUDE_SETTINGS, \"claude-settings\", \"json\");\n logBackup(backupPath);\n } else {\n mkdirSync(CLAUDE_DIR, { recursive: true });\n }\n\n const next: ClaudeSettings = { ...existing, hooks: merged.hooks };\n writeJsonAtomic(CLAUDE_SETTINGS, next);\n\n logInstalled(\"Claude Code hooks (workaround for #508)\", CLAUDE_SETTINGS);\n p.log.info(\n \"User-scope hook entries reference absolute paths under the bundled plugin/ dir. Re-run `agentmemory connect claude-code --with-hooks` after upgrading agentmemory to refresh them.\",\n );\n\n return {\n kind: \"installed\",\n mutatedPath: CLAUDE_SETTINGS,\n ...(backupPath !== undefined && { backupPath }),\n };\n}\n","import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { createJsonMcpAdapter } from \"./json-mcp-adapter.js\";\n\n// Cline CLI stores MCP server config at ~/.cline/mcp.json with the\n// canonical `mcpServers` wrapper — same schema as Claude Code with\n// optional `disabled` and `autoApprove` fields per entry.\n// VS Code extension users manage MCP through Cline's Settings UI;\n// this adapter targets the standalone CLI surface.\n// Source: github.com/cline/cline/blob/main/docs/mcp/mcp-overview.mdx\nexport const adapter = createJsonMcpAdapter({\n name: \"cline\",\n displayName: \"Cline\",\n detectDir: join(homedir(), \".cline\"),\n configPath: join(homedir(), \".cline\", \"mcp.json\"),\n docs: \"https://github.com/rohitg00/agentmemory#other-agents\",\n protocolNote:\n \"→ Using MCP via ~/.cline/mcp.json (CLI). VS Code users: add the same block via Cline Settings → MCP Servers → Edit JSON.\",\n});\n","import { existsSync, mkdirSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport * as p from \"@clack/prompts\";\nimport type { ConnectAdapter, ConnectOptions, ConnectResult } from \"./types.js\";\nimport {\n AGENTMEMORY_COPILOT_MCP_BLOCK,\n backupFile,\n logAlreadyWired,\n logBackup,\n logInstalled,\n readJsonSafe,\n writeJsonAtomic,\n} from \"./util.js\";\n\nconst COPILOT_DIR = process.env[\"COPILOT_HOME\"] || join(homedir(), \".copilot\");\nconst COPILOT_MCP_JSON = join(COPILOT_DIR, \"mcp-config.json\");\n\ntype CopilotMcpEntry = typeof AGENTMEMORY_COPILOT_MCP_BLOCK;\ntype CopilotConfig = {\n mcpServers?: Record<string, CopilotMcpEntry>;\n [key: string]: unknown;\n};\n\nfunction entryMatches(entry: unknown): boolean {\n if (!entry || typeof entry !== \"object\") return false;\n return JSON.stringify(entry) === JSON.stringify(AGENTMEMORY_COPILOT_MCP_BLOCK);\n}\n\nexport const adapter: ConnectAdapter = {\n name: \"copilot-cli\",\n displayName: \"GitHub Copilot CLI\",\n category: \"native\",\n docs: \"https://github.com/rohitg00/agentmemory#github-copilot-cli\",\n protocolNote:\n \"→ Using MCP. Install the plugin too for full hooks/skills coverage.\",\n\n detect(): boolean {\n return existsSync(COPILOT_DIR);\n },\n\n async install(opts: ConnectOptions): Promise<ConnectResult> {\n const existing = readJsonSafe<CopilotConfig>(COPILOT_MCP_JSON);\n const next: CopilotConfig = existing ? { ...existing } : {};\n const servers: Record<string, CopilotMcpEntry> = {\n ...((next.mcpServers as Record<string, CopilotMcpEntry>) ?? {}),\n };\n\n const alreadyHas = entryMatches(servers[\"agentmemory\"]);\n if (alreadyHas && !opts.force) {\n logAlreadyWired(\"GitHub Copilot CLI\", COPILOT_MCP_JSON);\n return { kind: \"already-wired\", mutatedPath: COPILOT_MCP_JSON };\n }\n\n if (opts.dryRun) {\n p.log.info(\n `[dry-run] Would ${alreadyHas ? \"overwrite\" : \"add\"} mcpServers.agentmemory in ${COPILOT_MCP_JSON}`,\n );\n return { kind: \"installed\", mutatedPath: COPILOT_MCP_JSON };\n }\n\n let backupPath: string | undefined;\n if (existsSync(COPILOT_MCP_JSON)) {\n backupPath = backupFile(COPILOT_MCP_JSON, \"copilot-cli\");\n logBackup(backupPath);\n } else {\n mkdirSync(dirname(COPILOT_MCP_JSON), { recursive: true });\n }\n\n servers[\"agentmemory\"] = AGENTMEMORY_COPILOT_MCP_BLOCK;\n next.mcpServers = servers;\n writeJsonAtomic(COPILOT_MCP_JSON, next);\n\n const verify = readJsonSafe<CopilotConfig>(COPILOT_MCP_JSON);\n if (!entryMatches(verify?.mcpServers?.[\"agentmemory\"])) {\n p.log.error(\n `Verification failed: ${COPILOT_MCP_JSON} did not contain mcpServers.agentmemory after write.`,\n );\n return { kind: \"skipped\", reason: \"verification-failed\" };\n }\n\n logInstalled(\"GitHub Copilot CLI\", COPILOT_MCP_JSON);\n p.log.info(\n \"Copilot picks up MCP servers on next launch or after `/mcp`. Install the plugin too for full hooks/skills.\",\n );\n return {\n kind: \"installed\",\n mutatedPath: COPILOT_MCP_JSON,\n ...(backupPath !== undefined && { backupPath }),\n };\n },\n};\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join, dirname } from \"node:path\";\nimport * as p from \"@clack/prompts\";\nimport type { ConnectAdapter, ConnectOptions, ConnectResult } from \"./types.js\";\nimport {\n backupFile,\n logAlreadyWired,\n logBackup,\n logInstalled,\n readJsonSafe,\n writeJsonAtomic,\n} from \"./util.js\";\nimport {\n buildMergedHooks,\n findPluginRoot,\n type HookManifest,\n} from \"./codex-hooks.js\";\n\nconst CODEX_DIR = join(homedir(), \".codex\");\nconst CODEX_TOML = join(CODEX_DIR, \"config.toml\");\nconst CODEX_HOOKS = join(CODEX_DIR, \"hooks.json\");\n\nconst TOML_BLOCK = `[mcp_servers.agentmemory]\ncommand = \"npx\"\nargs = [\"-y\", \"@agentmemory/mcp\"]\n\n[mcp_servers.agentmemory.env]\nAGENTMEMORY_URL = \"http://localhost:3111\"\n`;\n\nconst SECTION_HEADER = \"[mcp_servers.agentmemory]\";\n\nfunction isWiredText(toml: string): boolean {\n return toml.includes(SECTION_HEADER);\n}\n\nfunction stripExistingBlock(toml: string): string {\n const lines = toml.split(/\\r?\\n/);\n const out: string[] = [];\n let skipping = false;\n for (const line of lines) {\n const trimmed = line.trim();\n if (\n trimmed === SECTION_HEADER ||\n trimmed === \"[mcp_servers.agentmemory.env]\"\n ) {\n skipping = true;\n continue;\n }\n if (\n skipping &&\n trimmed.startsWith(\"[\") &&\n trimmed !== \"[mcp_servers.agentmemory.env]\"\n ) {\n skipping = false;\n }\n if (!skipping) out.push(line);\n }\n return out.join(\"\\n\").replace(/\\n{3,}$/, \"\\n\\n\").trimEnd() + \"\\n\";\n}\n\nexport const adapter: ConnectAdapter = {\n name: \"codex\",\n displayName: \"Codex CLI\",\n category: \"native\",\n docs: \"https://github.com/rohitg00/agentmemory#codex-cli-codex-plugin-platform\",\n protocolNote:\n \"→ Using MCP. Hooks ship via the Codex plugin; on Codex Desktop, also pass --with-hooks to install the global hooks.json workaround for openai/codex#16430.\",\n\n detect(): boolean {\n return existsSync(CODEX_DIR);\n },\n\n async install(opts: ConnectOptions): Promise<ConnectResult> {\n const exists = existsSync(CODEX_TOML);\n const current = exists ? readFileSync(CODEX_TOML, \"utf-8\") : \"\";\n const wired = isWiredText(current);\n\n if (wired && !opts.force) {\n logAlreadyWired(\"Codex CLI\", CODEX_TOML);\n return { kind: \"already-wired\", mutatedPath: CODEX_TOML };\n }\n\n if (opts.dryRun) {\n p.log.info(\n `[dry-run] Would ${wired ? \"rewrite\" : \"append\"} [mcp_servers.agentmemory] in ${CODEX_TOML}`,\n );\n if (opts.withHooks) installCodexHooks(opts);\n return { kind: \"installed\", mutatedPath: CODEX_TOML };\n }\n\n let backupPath: string | undefined;\n if (exists) {\n backupPath = backupFile(CODEX_TOML, \"codex\", \"toml\");\n logBackup(backupPath);\n } else {\n mkdirSync(dirname(CODEX_TOML), { recursive: true });\n }\n\n const cleaned = wired ? stripExistingBlock(current) : current;\n const joiner = cleaned.length === 0 || cleaned.endsWith(\"\\n\") ? \"\" : \"\\n\";\n const next = `${cleaned}${joiner}${cleaned.length > 0 ? \"\\n\" : \"\"}${TOML_BLOCK}`;\n writeFileSync(CODEX_TOML, next, \"utf-8\");\n\n const verify = readFileSync(CODEX_TOML, \"utf-8\");\n if (!isWiredText(verify)) {\n p.log.error(\n `Verification failed: ${CODEX_TOML} did not contain ${SECTION_HEADER} after write.`,\n );\n return { kind: \"skipped\", reason: \"verification-failed\" };\n }\n\n logInstalled(\"Codex CLI\", CODEX_TOML);\n p.log.info(\n \"Codex picks up MCP servers on next launch. For the deeper plugin install, run: codex plugin marketplace add rohitg00/agentmemory && codex plugin add agentmemory@agentmemory\",\n );\n\n if (opts.withHooks) {\n const hookResult = installCodexHooks(opts);\n if (hookResult.kind === \"skipped\") {\n p.log.warn(\n `Codex hooks fallback skipped: ${hookResult.reason}. MCP wiring still applied.`,\n );\n }\n }\n\n return {\n kind: \"installed\",\n mutatedPath: CODEX_TOML,\n ...(backupPath !== undefined && { backupPath }),\n };\n },\n};\n\n/**\n * Install the global `~/.codex/hooks.json` fallback. See\n * `codex-hooks.ts` for context (openai/codex#16430). Returns a result\n * describing the side effect for the caller's summary; failures here do\n * not roll back the MCP wiring.\n */\nfunction installCodexHooks(opts: ConnectOptions): ConnectResult {\n let pluginRoot: string;\n try {\n pluginRoot = findPluginRoot();\n } catch (err) {\n return {\n kind: \"skipped\",\n reason: err instanceof Error ? err.message : String(err),\n };\n }\n\n const existing = readJsonSafe<HookManifest>(CODEX_HOOKS);\n const merged = buildMergedHooks(existing, pluginRoot);\n\n if (opts.dryRun) {\n p.log.info(\n `[dry-run] Would ${existing ? \"merge\" : \"create\"} ${CODEX_HOOKS} with ${Object.keys(merged.hooks).length} event(s)`,\n );\n return { kind: \"installed\", mutatedPath: CODEX_HOOKS };\n }\n\n let backupPath: string | undefined;\n if (existsSync(CODEX_HOOKS)) {\n backupPath = backupFile(CODEX_HOOKS, \"codex-hooks\", \"json\");\n logBackup(backupPath);\n }\n\n writeJsonAtomic(CODEX_HOOKS, merged);\n\n logInstalled(\"Codex hooks (workaround for openai/codex#16430)\", CODEX_HOOKS);\n p.log.info(\n \"User-scope hooks reference absolute paths under the bundled plugin/ dir. Re-run `agentmemory connect codex --with-hooks` after upgrading agentmemory to refresh them.\",\n );\n\n return {\n kind: \"installed\",\n mutatedPath: CODEX_HOOKS,\n ...(backupPath !== undefined && { backupPath }),\n };\n}\n","import { existsSync, mkdirSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport * as p from \"@clack/prompts\";\nimport type { ConnectAdapter, ConnectOptions, ConnectResult } from \"./types.js\";\nimport {\n AGENTMEMORY_MCP_BLOCK,\n backupFile,\n logAlreadyWired,\n logBackup,\n logInstalled,\n readJsonSafe,\n writeJsonAtomic,\n} from \"./util.js\";\n\n// Continue.dev v1+ prefers ~/.continue/config.yaml; config.json is\n// deprecated and ignored when yaml is present. Three branches:\n// - config.yaml exists → emit stub with manual edit instructions\n// (no YAML dep in tree; preserving comments/anchors safely needs it)\n// - config.json exists → modify it (legacy path still loaded when no yaml)\n// - neither → create config.yaml from scratch (no merge risk)\n// Source: docs.continue.dev/reference/yaml-migration\nconst CONTINUE_DIR = join(homedir(), \".continue\");\nconst YAML_PATH = join(CONTINUE_DIR, \"config.yaml\");\nconst JSON_PATH = join(CONTINUE_DIR, \"config.json\");\n\ntype ContinueEntry = {\n name: string;\n command: string;\n args: string[];\n env?: Record<string, string>;\n};\n\ntype ContinueJsonConfig = {\n mcpServers?: ContinueEntry[];\n [key: string]: unknown;\n};\n\nfunction buildEntry(): ContinueEntry {\n return {\n name: \"agentmemory\",\n command: AGENTMEMORY_MCP_BLOCK.command,\n args: [...AGENTMEMORY_MCP_BLOCK.args],\n env: { ...AGENTMEMORY_MCP_BLOCK.env },\n };\n}\n\nfunction entryIsAgentmemory(entry: ContinueEntry | undefined): boolean {\n if (!entry) return false;\n return entry.name === \"agentmemory\" && entry.args.includes(\"@agentmemory/mcp\");\n}\n\n// Minimal YAML emitter for the agentmemory entry. Quotes string values\n// that contain ${ ... } expansion to keep parsers happy. Only used when\n// creating a fresh config.yaml — never when modifying an existing one.\nfunction renderFreshYaml(): string {\n const e = buildEntry();\n const envLines = Object.entries(e.env ?? {})\n .map(([k, v]) => ` ${k}: \"${v}\"`)\n .join(\"\\n\");\n return [\n \"mcpServers:\",\n ` - name: ${e.name}`,\n ` command: ${e.command}`,\n \" args:\",\n ...e.args.map((a) => ` - \"${a}\"`),\n \" env:\",\n envLines,\n \"\",\n ].join(\"\\n\");\n}\n\nexport const adapter: ConnectAdapter = {\n name: \"continue\",\n displayName: \"Continue\",\n category: \"mcp\",\n docs: \"https://github.com/rohitg00/agentmemory#other-agents\",\n protocolNote:\n \"→ Using MCP via ~/.continue/config.yaml (preferred) or config.json (legacy, only when no yaml).\",\n\n detect(): boolean {\n return existsSync(CONTINUE_DIR);\n },\n\n async install(opts: ConnectOptions): Promise<ConnectResult> {\n const yamlExists = existsSync(YAML_PATH);\n const jsonExists = existsSync(JSON_PATH);\n\n // Branch 1: yaml present — refuse to silently mutate user's yaml\n // config (preserving comments/anchors needs a proper parser).\n if (yamlExists) {\n const indented = renderFreshYaml()\n .split(\"\\n\")\n .map((l) => (l ? ` ${l}` : l))\n .join(\"\\n\");\n const manual = `\\nMerge this block into ~/.continue/config.yaml (the snippet already includes the top-level mcpServers key — if your config already has a mcpServers list, append the agentmemory entry to it instead of duplicating the key):\\n\\n${indented}`;\n p.log.info(\n `Continue: ${YAML_PATH} already exists. Manual edit needed.${manual}`,\n );\n return { kind: \"stub\", reason: \"config.yaml-needs-manual-edit\" };\n }\n\n // Branch 2: legacy json present — modify in place.\n if (jsonExists) {\n const existing = readJsonSafe<ContinueJsonConfig>(JSON_PATH);\n const next: ContinueJsonConfig = existing ? { ...existing } : {};\n const servers = Array.isArray(next.mcpServers)\n ? [...next.mcpServers]\n : [];\n\n const idx = servers.findIndex((s) => s?.name === \"agentmemory\");\n const alreadyHas = idx >= 0 && entryIsAgentmemory(servers[idx]);\n if (alreadyHas && !opts.force) {\n logAlreadyWired(\"Continue\", JSON_PATH);\n return { kind: \"already-wired\", mutatedPath: JSON_PATH };\n }\n\n if (opts.dryRun) {\n p.log.info(\n `[dry-run] Would ${alreadyHas ? \"overwrite\" : \"add\"} mcpServers[agentmemory] in ${JSON_PATH}`,\n );\n return { kind: \"installed\", mutatedPath: JSON_PATH };\n }\n\n const backupPath = backupFile(JSON_PATH, \"continue\");\n logBackup(backupPath);\n\n const entry = buildEntry();\n if (idx >= 0) servers[idx] = entry;\n else servers.push(entry);\n next.mcpServers = servers;\n writeJsonAtomic(JSON_PATH, next);\n\n const verify = readJsonSafe<ContinueJsonConfig>(JSON_PATH);\n const verifyEntry = verify?.mcpServers?.find(\n (s) => s?.name === \"agentmemory\",\n );\n if (!entryIsAgentmemory(verifyEntry)) {\n p.log.error(\n `Verification failed: ${JSON_PATH} did not contain mcpServers[agentmemory] after write.`,\n );\n return { kind: \"skipped\", reason: \"verification-failed\" };\n }\n\n logInstalled(\"Continue (legacy config.json)\", JSON_PATH);\n return {\n kind: \"installed\",\n mutatedPath: JSON_PATH,\n backupPath,\n };\n }\n\n // Branch 3: neither exists — create config.yaml from scratch (modern path).\n if (opts.dryRun) {\n p.log.info(`[dry-run] Would create ${YAML_PATH} with agentmemory entry`);\n return { kind: \"installed\", mutatedPath: YAML_PATH };\n }\n\n mkdirSync(dirname(YAML_PATH), { recursive: true });\n writeFileSync(YAML_PATH, renderFreshYaml(), \"utf-8\");\n logInstalled(\"Continue\", YAML_PATH);\n return { kind: \"installed\", mutatedPath: YAML_PATH };\n },\n};\n","import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { createJsonMcpAdapter } from \"./json-mcp-adapter.js\";\n\nexport const adapter = createJsonMcpAdapter({\n name: \"cursor\",\n displayName: \"Cursor\",\n detectDir: join(homedir(), \".cursor\"),\n configPath: join(homedir(), \".cursor\", \"mcp.json\"),\n docs: \"https://github.com/rohitg00/agentmemory#other-agents\",\n protocolNote:\n \"→ Using MCP (the only protocol Cursor speaks). Memory bridge runs at :3111 underneath.\",\n});\n","import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { createJsonMcpAdapter } from \"./json-mcp-adapter.js\";\n\n// Factory.ai's Droid CLI stores MCP server config at ~/.factory/mcp.json\n// with the canonical `mcpServers` wrapper. Project-scoped overrides live\n// at <repo>/.factory/mcp.json. Each entry adds an optional `type` field\n// (\"stdio\" | \"http\") and `disabled` boolean — agentmemory's stdio block\n// works against the same shape without needing the explicit type tag.\n// Source: docs.factory.ai/cli/configuration/mcp\nexport const adapter = createJsonMcpAdapter({\n name: \"droid\",\n displayName: \"Droid (Factory.ai)\",\n detectDir: join(homedir(), \".factory\"),\n configPath: join(homedir(), \".factory\", \"mcp.json\"),\n docs: \"https://github.com/rohitg00/agentmemory#other-agents\",\n protocolNote:\n \"→ Using MCP via ~/.factory/mcp.json. The `/mcp` slash command inside droid lists configured servers.\",\n // Droid requires `type` per the documented schema. stdio for npx-spawned shim.\n extraEntryFields: { type: \"stdio\" },\n});\n","import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { createJsonMcpAdapter } from \"./json-mcp-adapter.js\";\n\nexport const adapter = createJsonMcpAdapter({\n name: \"gemini-cli\",\n displayName: \"Gemini CLI\",\n detectDir: join(homedir(), \".gemini\"),\n configPath: join(homedir(), \".gemini\", \"settings.json\"),\n docs: \"https://github.com/rohitg00/agentmemory#other-agents\",\n protocolNote:\n \"→ Using MCP (the only protocol Gemini CLI speaks). Memory bridge runs at :3111 underneath.\",\n});\n","import { existsSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport * as p from \"@clack/prompts\";\nimport type { ConnectAdapter, ConnectOptions, ConnectResult } from \"./types.js\";\n\nconst HERMES_DIR = join(homedir(), \".hermes\");\nconst HERMES_CONFIG = join(HERMES_DIR, \"config.yaml\");\nconst DOCS = \"https://github.com/rohitg00/agentmemory/tree/main/integrations/hermes\";\n\nexport const adapter: ConnectAdapter = {\n name: \"hermes\",\n displayName: \"Hermes Agent\",\n category: \"native\",\n docs: DOCS,\n protocolNote:\n \"→ Using MCP. Hooks are also available — see https://github.com/rohitg00/agentmemory/tree/main/integrations/hermes.\",\n\n detect(): boolean {\n return existsSync(HERMES_DIR);\n },\n\n async install(_opts: ConnectOptions): Promise<ConnectResult> {\n p.log.warn(\n \"Hermes uses YAML config. Automated merge isn't implemented yet — manual install required.\",\n );\n p.note(\n [\n `Add to ${HERMES_CONFIG}:`,\n \"\",\n \" mcp_servers:\",\n \" agentmemory:\",\n \" command: npx\",\n ' args: [\"-y\", \"@agentmemory/mcp\"]',\n \"\",\n \" memory:\",\n \" provider: agentmemory\",\n \"\",\n `Full guide: ${DOCS}`,\n ].join(\"\\n\"),\n \"Hermes manual install\",\n );\n return {\n kind: \"stub\",\n reason: \"yaml-merge-not-implemented\",\n };\n },\n};\n","import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { createJsonMcpAdapter } from \"./json-mcp-adapter.js\";\n\n// Kiro stores user-level MCP servers in ~/.kiro/settings/mcp.json.\n// Schema follows the standard MCP envelope { mcpServers: { ... } }.\n// Source: kiro.dev/docs/cli/mcp\nexport const adapter = createJsonMcpAdapter({\n name: \"kiro\",\n displayName: \"Kiro\",\n detectDir: join(homedir(), \".kiro\"),\n configPath: join(homedir(), \".kiro\", \"settings\", \"mcp.json\"),\n docs: \"https://github.com/rohitg00/agentmemory#other-agents\",\n protocolNote:\n \"→ Using MCP via ~/.kiro/settings/mcp.json (user-level). Workspace overrides live in .kiro/settings/mcp.json.\",\n});\n","import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { createJsonMcpAdapter } from \"./json-mcp-adapter.js\";\n\nexport const adapter = createJsonMcpAdapter({\n name: \"openclaw\",\n displayName: \"OpenClaw\",\n category: \"native\",\n detectDir: join(homedir(), \".openclaw\"),\n configPath: join(homedir(), \".openclaw\", \"openclaw.json\"),\n docs: \"https://github.com/rohitg00/agentmemory/tree/main/integrations/openclaw\",\n protocolNote:\n \"→ Using MCP. Hooks are also available — see https://github.com/rohitg00/agentmemory/tree/main/integrations/openclaw.\",\n});\n","import { existsSync, mkdirSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport * as p from \"@clack/prompts\";\nimport type { ConnectAdapter, ConnectOptions, ConnectResult } from \"./types.js\";\nimport {\n backupFile,\n logAlreadyWired,\n logBackup,\n logInstalled,\n readJsonSafe,\n writeJsonAtomic,\n} from \"./util.js\";\n\n// OpenCode does not use the standard `mcpServers` block. Its config is a\n// top-level `mcp` key whose entries carry `type`, `command` as an array,\n// and `enabled` (docs: README \"OpenCode (MCP only)\"). So it needs its own\n// adapter rather than createJsonMcpAdapter.\n\nconst CONFIG_PATH = join(homedir(), \".config\", \"opencode\", \"opencode.json\");\nconst DETECT_DIR = join(homedir(), \".config\", \"opencode\");\n\n// No `environment` block: OpenCode does not expand shell-style\n// `${VAR:-default}` values, and writing them literally would override the\n// user's real shell AGENTMEMORY_URL with an unexpanded string. The stdio\n// child inherits the shell environment (an exported AGENTMEMORY_URL /\n// AGENTMEMORY_SECRET still reaches the server), and the @agentmemory/mcp\n// shim defaults unset vars (URL -> localhost:3111, no secret, all tools).\nconst OPENCODE_ENTRY = {\n type: \"local\",\n command: [\"npx\", \"-y\", \"@agentmemory/mcp\"],\n enabled: true,\n};\n\ntype OpencodeConfig = Record<string, unknown>;\ntype McpEntry = Record<string, unknown>;\n\nfunction entryMatches(entry: unknown): boolean {\n if (!entry || typeof entry !== \"object\") return false;\n const command = (entry as McpEntry)[\"command\"];\n return Array.isArray(command) && command.includes(\"@agentmemory/mcp\");\n}\n\nexport const adapter: ConnectAdapter = {\n name: \"opencode\",\n displayName: \"OpenCode\",\n category: \"mcp\",\n docs: \"https://github.com/rohitg00/agentmemory#other-agents\",\n protocolNote:\n \"Using MCP via ~/.config/opencode/opencode.json (top-level `mcp` key). For full auto-capture, also install the bundled plugin in plugin/opencode/.\",\n\n detect(): boolean {\n return existsSync(DETECT_DIR);\n },\n\n async install(opts: ConnectOptions): Promise<ConnectResult> {\n const existing = readJsonSafe<OpencodeConfig>(CONFIG_PATH);\n const next: OpencodeConfig = existing ? { ...existing } : {};\n const existingMcp = next[\"mcp\"];\n const mcp: Record<string, McpEntry> =\n existingMcp &&\n typeof existingMcp === \"object\" &&\n !Array.isArray(existingMcp)\n ? { ...(existingMcp as Record<string, McpEntry>) }\n : {};\n\n const alreadyHas = entryMatches(mcp[\"agentmemory\"]);\n if (alreadyHas && !opts.force) {\n logAlreadyWired(this.displayName, CONFIG_PATH);\n return { kind: \"already-wired\", mutatedPath: CONFIG_PATH };\n }\n\n if (opts.dryRun) {\n p.log.info(\n `[dry-run] Would ${alreadyHas ? \"overwrite\" : \"add\"} mcp.agentmemory in ${CONFIG_PATH}`,\n );\n return { kind: \"installed\", mutatedPath: CONFIG_PATH };\n }\n\n let backupPath: string | undefined;\n if (existsSync(CONFIG_PATH)) {\n backupPath = backupFile(CONFIG_PATH, this.name);\n logBackup(backupPath);\n } else {\n mkdirSync(dirname(CONFIG_PATH), { recursive: true });\n }\n\n mcp[\"agentmemory\"] = { ...OPENCODE_ENTRY };\n next[\"mcp\"] = mcp;\n writeJsonAtomic(CONFIG_PATH, next);\n\n const verify = readJsonSafe<OpencodeConfig>(CONFIG_PATH);\n const verifyMcp = verify?.[\"mcp\"] as Record<string, McpEntry> | undefined;\n if (!entryMatches(verifyMcp?.[\"agentmemory\"])) {\n p.log.error(\n `Verification failed: ${CONFIG_PATH} did not contain mcp.agentmemory after write.`,\n );\n return { kind: \"skipped\", reason: \"verification-failed\" };\n }\n\n logInstalled(this.displayName, CONFIG_PATH);\n return {\n kind: \"installed\",\n mutatedPath: CONFIG_PATH,\n ...(backupPath !== undefined && { backupPath }),\n };\n },\n};\n","import { existsSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport * as p from \"@clack/prompts\";\nimport type { ConnectAdapter, ConnectOptions, ConnectResult } from \"./types.js\";\n\nconst OPENHUMAN_DIR = join(homedir(), \".openhuman\");\nconst DOCS = \"https://github.com/tinyhumansai/openhuman\";\n\nexport const adapter: ConnectAdapter = {\n name: \"openhuman\",\n displayName: \"OpenHuman\",\n category: \"native\",\n docs: DOCS,\n protocolNote:\n \"→ Using native hooks (REST API at :3111). MCP not required.\",\n\n detect(): boolean {\n return existsSync(OPENHUMAN_DIR);\n },\n\n async install(_opts: ConnectOptions): Promise<ConnectResult> {\n p.log.warn(\n \"OpenHuman integration is not yet automated. No `integrations/openhuman/` folder exists in the agentmemory repo today.\",\n );\n p.note(\n [\n \"OpenHuman is a Memory-trait host. The expected wiring is the REST\",\n \"proxy at http://localhost:3111 plus an OpenHuman-side Memory trait\",\n \"impl. Once integrations/openhuman/ lands in agentmemory we'll wire\",\n \"this up automatically.\",\n \"\",\n `Tracking: ${DOCS}`,\n ].join(\"\\n\"),\n \"OpenHuman manual install\",\n );\n return {\n kind: \"stub\",\n reason: \"no-integration-folder-yet\",\n };\n },\n};\n","import { existsSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport * as p from \"@clack/prompts\";\nimport type { ConnectAdapter, ConnectOptions, ConnectResult } from \"./types.js\";\n\nconst PI_DIR = join(homedir(), \".pi\");\nconst PI_EXT_DIR = join(PI_DIR, \"agent\", \"extensions\", \"agentmemory\");\nconst DOCS = \"https://github.com/rohitg00/agentmemory/tree/main/integrations/pi\";\n\nexport const adapter: ConnectAdapter = {\n name: \"pi\",\n displayName: \"pi\",\n category: \"native\",\n docs: DOCS,\n protocolNote:\n \"→ Using native hooks (REST API at :3111). MCP not required.\",\n\n detect(): boolean {\n return existsSync(PI_DIR);\n },\n\n async install(_opts: ConnectOptions): Promise<ConnectResult> {\n p.log.warn(\n \"pi uses a TypeScript extension file. Automated copy + register isn't implemented yet — manual install required.\",\n );\n p.note(\n [\n \"Run these from the agentmemory repo root:\",\n \"\",\n ` mkdir -p ${PI_EXT_DIR}`,\n ` cp integrations/pi/index.ts ${PI_EXT_DIR}/index.ts`,\n ` cp integrations/pi/security.ts ${PI_EXT_DIR}/security.ts`,\n \"\",\n \"Then add to ~/.pi/agent/settings.json:\",\n ' { \"extensions\": [\"~/.pi/agent/extensions/agentmemory\"] }',\n \"\",\n `Full guide: ${DOCS}`,\n ].join(\"\\n\"),\n \"pi manual install\",\n );\n return {\n kind: \"stub\",\n reason: \"ts-extension-copy-not-implemented\",\n };\n },\n};\n","import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { createJsonMcpAdapter } from \"./json-mcp-adapter.js\";\n\n// Qwen Code stores its settings (mcpServers + hooks) in\n// ~/.qwen/settings.json. Schema for mcpServers matches Claude Code's\n// shape, so the shared JSON adapter handles the wiring.\n// Source: qwenlm.github.io/qwen-code-docs/en/users/features/mcp\nexport const adapter = createJsonMcpAdapter({\n name: \"qwen\",\n displayName: \"Qwen Code\",\n detectDir: join(homedir(), \".qwen\"),\n configPath: join(homedir(), \".qwen\", \"settings.json\"),\n docs: \"https://github.com/rohitg00/agentmemory#other-agents\",\n protocolNote:\n \"→ Using MCP via ~/.qwen/settings.json. Qwen Code's hook system can also be wired separately — see docs.\",\n});\n","import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { createJsonMcpAdapter } from \"./json-mcp-adapter.js\";\n\n// Warp stores MCP server config at ~/.warp/.mcp.json with the\n// canonical `mcpServers` wrapper — identical schema to Claude Code.\n// Warp also auto-discovers skills from .claude/skills/ so the\n// agentmemory plugin's 8 skills are surfaced natively once the\n// Claude Code plugin is installed.\n// Source: docs.warp.dev/agent-platform/capabilities/mcp/\nexport const adapter = createJsonMcpAdapter({\n name: \"warp\",\n displayName: \"Warp\",\n detectDir: join(homedir(), \".warp\"),\n configPath: join(homedir(), \".warp\", \".mcp.json\"),\n docs: \"https://github.com/rohitg00/agentmemory#other-agents\",\n protocolNote:\n \"→ Using MCP via ~/.warp/.mcp.json. Skills auto-discover from .claude/skills/ if the Claude Code plugin is also installed.\",\n});\n","import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { createJsonMcpAdapter } from \"./json-mcp-adapter.js\";\n\n// Zed stores its settings (including MCP servers) under \"context_servers\"\n// in settings.json — NOT \"mcpServers\". User config lives at\n// ~/.config/zed/settings.json on all platforms (Zed uses the XDG path\n// even on macOS; ~/Library/Application Support/Zed/ holds runtime data\n// like the database + cached language servers, not the config).\n// Source: zed.dev/docs/ai/mcp + zed.dev/docs/configuring-zed\nconst zedConfigDir = join(homedir(), \".config\", \"zed\");\n\nexport const adapter = createJsonMcpAdapter({\n name: \"zed\",\n displayName: \"Zed\",\n detectDir: zedConfigDir,\n configPath: join(zedConfigDir, \"settings.json\"),\n wrapperKey: \"context_servers\",\n docs: \"https://github.com/rohitg00/agentmemory#other-agents\",\n protocolNote:\n \"→ Using MCP via ~/.config/zed/settings.json (key: context_servers).\",\n});\n","import { platform } from \"node:os\";\nimport * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport type { ConnectAdapter, ConnectOptions, ConnectResult } from \"./types.js\";\nimport { adapter as antigravity } from \"./antigravity.js\";\nimport { adapter as claudeCode } from \"./claude-code.js\";\nimport { adapter as cline } from \"./cline.js\";\nimport { adapter as copilotCli } from \"./copilot-cli.js\";\nimport { adapter as codex } from \"./codex.js\";\nimport { adapter as continueDev } from \"./continue.js\";\nimport { adapter as cursor } from \"./cursor.js\";\nimport { adapter as droid } from \"./droid.js\";\nimport { adapter as geminiCli } from \"./gemini-cli.js\";\nimport { adapter as hermes } from \"./hermes.js\";\nimport { adapter as kiro } from \"./kiro.js\";\nimport { adapter as openclaw } from \"./openclaw.js\";\nimport { adapter as opencode } from \"./opencode.js\";\nimport { adapter as openhuman } from \"./openhuman.js\";\nimport { adapter as pi } from \"./pi.js\";\nimport { adapter as qwen } from \"./qwen.js\";\nimport { adapter as warp } from \"./warp.js\";\nimport { adapter as zed } from \"./zed.js\";\n\nexport const ADAPTERS: readonly ConnectAdapter[] = [\n claudeCode,\n copilotCli,\n codex,\n cursor,\n geminiCli,\n qwen,\n antigravity,\n kiro,\n warp,\n cline,\n continueDev,\n zed,\n droid,\n opencode,\n openclaw,\n hermes,\n pi,\n openhuman,\n];\n\nexport function resolveAdapter(name: string): ConnectAdapter | null {\n const lower = name.toLowerCase();\n return ADAPTERS.find((a) => a.name === lower) ?? null;\n}\n\nexport function knownAgents(): string[] {\n return ADAPTERS.map((a) => a.name);\n}\n\nfunction parseFlags(args: string[]): {\n dryRun: boolean;\n force: boolean;\n all: boolean;\n withHooks: boolean;\n positional: string[];\n} {\n const positional: string[] = [];\n let dryRun = false;\n let force = false;\n let all = false;\n let withHooks = false;\n for (const a of args) {\n if (a === \"--dry-run\") dryRun = true;\n else if (a === \"--force\") force = true;\n else if (a === \"--all\") all = true;\n else if (a === \"--with-hooks\") withHooks = true;\n else if (!a.startsWith(\"-\")) positional.push(a);\n }\n return { dryRun, force, all, withHooks, positional };\n}\n\nexport async function runAdapter(\n adapter: ConnectAdapter,\n opts: ConnectOptions,\n): Promise<ConnectResult> {\n if (!adapter.detect()) {\n p.log.warn(\n `${adapter.displayName}: not detected on this machine (skipping).${adapter.docs ? ` Docs: ${adapter.docs}` : \"\"}`,\n );\n return { kind: \"skipped\", reason: \"not-detected\" };\n }\n p.log.step(`Wiring ${adapter.displayName}…`);\n if (adapter.protocolNote) {\n p.log.message(adapter.protocolNote);\n }\n try {\n return await adapter.install(opts);\n } catch (err) {\n p.log.error(\n `${adapter.displayName}: ${err instanceof Error ? err.message : String(err)}`,\n );\n return { kind: \"skipped\", reason: \"exception\" };\n }\n}\n\nexport async function runConnect(args: string[]): Promise<void> {\n const { dryRun, force, all, withHooks, positional } = parseFlags(args);\n const allowWindowsAdapter =\n positional.length === 1 && positional[0]?.toLowerCase() === \"copilot-cli\";\n if (platform() === \"win32\" && !allowWindowsAdapter) {\n p.intro(\"agentmemory connect\");\n p.log.warn(\n \"Windows: automated `connect` is not supported yet. See https://github.com/rohitg00/agentmemory#other-agents for manual install steps.\",\n );\n p.outro(\"Windows: manual install required — see docs\");\n return;\n }\n\n const opts: ConnectOptions = { dryRun, force, withHooks };\n\n p.intro(\"agentmemory connect\");\n\n if (positional.length === 0 && !all) {\n const detected = ADAPTERS.filter((a) => a.detect());\n if (detected.length === 0) {\n p.log.error(\"No supported agents detected on this machine.\");\n p.outro(`Supported: ${knownAgents().join(\", \")}`);\n process.exit(1);\n }\n const picked = await p.multiselect<string>({\n message: \"Wire agentmemory into which agents?\",\n options: detected.map((a) => ({ value: a.name, label: a.displayName })),\n required: true,\n });\n if (p.isCancel(picked)) {\n p.cancel(\"Cancelled.\");\n return;\n }\n const results: { name: string; result: ConnectResult }[] = [];\n for (const name of picked as string[]) {\n const adapter = resolveAdapter(name);\n if (!adapter) continue;\n results.push({ name, result: await runAdapter(adapter, opts) });\n }\n summarize(results);\n return;\n }\n\n if (all) {\n const detected = ADAPTERS.filter((a) => a.detect());\n if (detected.length === 0) {\n p.log.error(\"No supported agents detected on this machine.\");\n process.exit(1);\n }\n const results: { name: string; result: ConnectResult }[] = [];\n for (const adapter of detected) {\n results.push({\n name: adapter.name,\n result: await runAdapter(adapter, opts),\n });\n }\n summarize(results);\n return;\n }\n\n const agentName = positional[0]!;\n const adapter = resolveAdapter(agentName);\n if (!adapter) {\n p.log.error(`Unknown agent: ${agentName}`);\n p.outro(`Supported: ${knownAgents().join(\", \")}`);\n process.exit(1);\n }\n\n const result = await runAdapter(adapter, opts);\n summarize([{ name: agentName, result }]);\n if (result.kind === \"skipped\" && (result as { reason: string }).reason !== \"not-detected\") {\n process.exit(1);\n }\n}\n\nfunction summarize(\n results: { name: string; result: ConnectResult }[],\n): void {\n const lines = results.map(({ name, result }) => {\n switch (result.kind) {\n case \"installed\":\n return ` ${pc.green(\"✓\")} ${pc.bold(name)}${result.mutatedPath ? ` ${pc.dim(\"→\")} ${pc.cyan(result.mutatedPath)}` : \"\"}`;\n case \"already-wired\":\n return ` ${pc.green(\"✓\")} ${pc.bold(name)} ${pc.dim(\"(already wired)\")}`;\n case \"stub\":\n return ` ${pc.yellow(\"⚠\")} ${pc.bold(name)} ${pc.yellow(`(manual install required: ${result.reason})`)}`;\n case \"skipped\":\n return ` ${pc.red(\"✗\")} ${pc.bold(name)} ${pc.dim(`(skipped: ${result.reason})`)}`;\n }\n });\n p.note(lines.join(\"\\n\"), \"summary\");\n\n const stubs = results.filter((r) => r.result.kind === \"stub\");\n if (stubs.length > 0) {\n p.log.info(\n `${stubs.length} agent(s) require manual install — see docs links above.`,\n );\n }\n\n const wiredAny = results.some(\n (r) => r.result.kind === \"installed\" || r.result.kind === \"already-wired\",\n );\n if (wiredAny) {\n p.log.info(\n \"Next: install agentmemory's 15 skills into the same agent(s) so they know when to call the tools:\\n npx skills add rohitg00/agentmemory -y\",\n );\n }\n\n p.outro(\"Restart any wired agent (or open a new session) to pick up agentmemory.\");\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAwBA,MAAa,wBAAwB;CACnC,SAAS;CACT,MAAM,CAAC,MAAM,mBAAmB;CAChC,KAAK;EACH,iBAAiB;EACjB,oBAAoB;EACpB,mBAAmB;EACpB;CACF;AAaD,MAAa,gCAAgC;CAC3C,MAAM;CACN,GAZA,QAAQ,aAAa,UACjB;EACE,SAAS,QAAQ,IAAI,cAAc,QAAQ,IAAI,cAAc;EAC7D,MAAM;GAAC;GAAM;GAAM;GAAM;GAAO;GAAM;GAAmB;EAC1D,GACD;EACE,SAAS;EACT,MAAM,CAAC,MAAM,mBAAmB;EACjC;CAKL,KAAK;EACH,iBAAiB;EACjB,oBAAoB;EACpB,mBAAmB;EACpB;CACD,OAAO,CAAC,IAAI;CACb;AAED,SAAgB,aAAqB;AACnC,QAAO,KAAK,SAAS,EAAE,gBAAgB,UAAU;;AAGnD,SAAgB,mBAA2B;CACzC,MAAM,MAAM,YAAY;AACxB,WAAU,KAAK,EAAE,WAAW,MAAM,CAAC;AACnC,QAAO;;AAGT,SAAgB,gBAAwB;AACtC,yBAAO,IAAI,MAAM,EAAC,aAAa,CAAC,QAAQ,SAAS,IAAI;;AAGvD,SAAgB,WACd,YACA,OACA,MAAM,QACE;AACR,mBAAkB;CAClB,MAAM,QAAQ,eAAe;CAC7B,MAAM,SAAS,KAAK,YAAY,EAAE,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM;AAC7D,cAAa,YAAY,OAAO;AAChC,QAAO;;AAGT,SAAgB,aAA0B,MAAwB;AAChE,KAAI,CAAC,WAAW,KAAK,CAAE,QAAO;AAC9B,KAAI;AACF,SAAO,KAAK,MAAM,aAAa,MAAM,QAAQ,CAAC;SACxC;AACN,SAAO;;;AAIX,SAAgB,gBAAgB,MAAc,OAAsB;AAClE,WAAU,QAAQ,KAAK,EAAE,EAAE,WAAW,MAAM,CAAC;CAC7C,MAAM,MAAM,GAAG,KAAK,OAAO,QAAQ,IAAI,GAAG,KAAK,KAAK;AACpD,eAAc,KAAK,GAAG,KAAK,UAAU,OAAO,MAAM,EAAE,CAAC,KAAK,QAAQ;AAClE,YAAW,KAAK,KAAK;;AAGvB,SAAgB,aAAa,OAAe,QAAsB;AAChE,GAAE,IAAI,QAAQ,GAAG,MAAM,gBAAgB,SAAS;;AAGlD,SAAgB,gBAAgB,OAAe,QAAsB;AACnE,GAAE,IAAI,KAAK,GAAG,MAAM,oBAAoB,OAAO,8BAA8B;;AAG/E,SAAgB,UAAU,QAAsB;AAC9C,GAAE,IAAI,KAAK,WAAW,SAAS;;;;ACvEjC,SAASA,eAAa,OAAyB;AAC7C,KAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO;CAChD,MAAM,IAAI;AACV,KAAI,EAAE,eAAe,MAAO,QAAO;AAEnC,SADa,MAAM,QAAQ,EAAE,QAAQ,GAAI,EAAE,UAAuB,EAAE,EACxD,SAAS,mBAAmB;;AAG1C,SAAgB,qBACd,QACgB;CAChB,MAAM,aAAa,OAAO,cAAc;AACxC,QAAO;EACL,MAAM,OAAO;EACb,aAAa,OAAO;EACpB,UAAU,OAAO,YAAY;EAC7B,GAAI,OAAO,SAAS,KAAA,KAAa,EAAE,MAAM,OAAO,MAAM;EACtD,GAAI,OAAO,iBAAiB,KAAA,KAAa,EACvC,cAAc,OAAO,cACtB;EAED,SAAkB;AAChB,UAAO,WAAW,OAAO,UAAU;;EAGrC,MAAM,QAAQ,MAA8C;GAC1D,MAAM,WAAW,aAAwB,OAAO,WAAW;GAC3D,MAAM,OAAkB,WAAW,EAAE,GAAG,UAAU,GAAG,EAAE;GACvD,MAAM,UAAoC,EACxC,GAAK,KAAK,eAA4C,EAAE,EACzD;GAED,MAAM,aAAaA,eAAa,QAAQ,eAAe;AACvD,OAAI,cAAc,CAAC,KAAK,OAAO;AAC7B,oBAAgB,OAAO,aAAa,OAAO,WAAW;AACtD,WAAO;KAAE,MAAM;KAAiB,aAAa,OAAO;KAAY;;AAGlE,OAAI,KAAK,QAAQ;AACf,MAAE,IAAI,KACJ,mBAAmB,aAAa,cAAc,MAAM,GAAG,WAAW,kBAAkB,OAAO,aAC5F;AACD,WAAO;KAAE,MAAM;KAAa,aAAa,OAAO;KAAY;;GAG9D,IAAI;AACJ,OAAI,WAAW,OAAO,WAAW,EAAE;AACjC,iBAAa,WAAW,OAAO,YAAY,OAAO,KAAK;AACvD,cAAU,WAAW;SAErB,WAAU,QAAQ,OAAO,WAAW,EAAE,EAAE,WAAW,MAAM,CAAC;AAG5D,WAAQ,iBAAiB;IACvB,GAAG;IACH,GAAI,OAAO,oBAAoB,EAAE;IAClC;AACD,QAAK,cAAc;AACnB,mBAAgB,OAAO,YAAY,KAAK;GAGxC,MAAM,gBADS,aAAwB,OAAO,WAClB,GAAG;AAG/B,OAAI,CAACA,eAAa,gBAAgB,eAAe,EAAE;AACjD,MAAE,IAAI,MACJ,wBAAwB,OAAO,WAAW,mBAAmB,WAAW,2BACzE;AACD,WAAO;KAAE,MAAM;KAAW,QAAQ;KAAuB;;AAG3D,gBAAa,OAAO,aAAa,OAAO,WAAW;AACnD,UAAO;IACL,MAAM;IACN,aAAa,OAAO;IACpB,GAAI,eAAe,KAAA,KAAa,EAAE,YAAY;IAC/C;;EAEJ;;;;ACvGH,MAAM,kBACJ,UAAU,KAAK,WACX,KAAK,SAAS,EAAE,WAAW,uBAAuB,eAAe,OAAO,GACxE,KAAK,SAAS,EAAE,WAAW,eAAe,OAAO;AAEvD,MAAaC,aAAU,qBAAqB;CAC1C,MAAM;CACN,aAAa;CACb,WAAW;CACX,YAAY,KAAK,iBAAiB,kBAAkB;CACpD,MAAM;CACN,cACE;CACH,CAAC;;;;;;;;;ACSF,SAAgB,eAAe,WAAmB,OAAO,KAAK,KAAa;CACzE,MAAM,OAAO,QAAQ,cAAc,SAAS,CAAC;CAC7C,IAAI,MAAM;AACV,MAAK,IAAI,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,MACE,WAAW,KAAK,KAAK,UAAU,UAAU,CAAC,IAC1C,WAAW,KAAK,KAAK,UAAU,QAAQ,CAAC,CAExC,QAAO,QAAQ,KAAK,KAAK,SAAS,CAAC;EAErC,MAAM,SAAS,QAAQ,IAAI;AAC3B,MAAI,WAAW,IAAK;AACpB,QAAM;;AAER,OAAM,IAAI,MACR,6EAA6E,KAAK,GACnF;;;;;;;;;;;;;AAcH,SAAgB,iBACd,UACA,YACA,eAAe,oBACD;CACd,MAAM,sBAAsB,KAAK,YAAY,SAAS,aAAa;CACnE,MAAM,OAAO,KAAK,MAAM,aAAa,qBAAqB,QAAQ,CAAC;CACnE,MAAM,aAAa,KAAK,YAAY,UAAU;CAE9C,MAAM,MAAoB,EAAE,OAAO,EAAE,EAAE;AAEvC,KAAI,UAAU,MACZ,MAAK,MAAM,CAAC,OAAO,YAAY,OAAO,QAAQ,SAAS,MAAM,EAAE;EAC7D,MAAM,OAAO,QAAQ,QAAQ,UAAU,CAAC,mBAAmB,OAAO,WAAW,CAAC;AAC9E,MAAI,KAAK,SAAS,EAAG,KAAI,MAAM,SAAS;;AAI5C,MAAK,MAAM,CAAC,OAAO,YAAY,OAAO,QAAQ,KAAK,MAAM,EAAE;EACzD,MAAM,kBAA+B,QAAQ,KAAK,UAAU;GAC1D,MAAM,OAAkB,EACtB,OAAO,MAAM,MAAM,KAAK,aAAa;IACnC,MAAM,QAAQ;IACd,SAAS,QAAQ,QAAQ,QAAQ,6BAA6B,WAAW;IAC1E,EAAE,EACJ;AACD,OAAI,MAAM,YAAY,KAAA,EAAW,MAAK,UAAU,MAAM;AACtD,UAAO;IACP;AACF,MAAI,MAAM,SAAS,CAAC,GAAI,IAAI,MAAM,UAAU,EAAE,EAAG,GAAG,gBAAgB;;AAGtE,QAAO;;AAGT,SAAS,mBAAmB,OAAkB,YAA6B;CACzE,MAAM,uBAAuB,6BAA6B,WAAW;AACrE,QAAO,MAAM,MAAM,MAAM,YACvB,6BAA6B,QAAQ,QAAQ,CAAC,SAAS,qBAAqB,CAC7E;;AAGH,SAAS,6BAA6B,OAAuB;AAC3D,QAAO,MAAM,QAAQ,OAAO,IAAI;;;;ACtFlC,MAAM,aAAa,KAAK,SAAS,EAAE,UAAU;AAC7C,MAAM,cAAc,KAAK,SAAS,EAAE,eAAe;AACnD,MAAM,kBAAkB,KAAK,YAAY,gBAAgB;AAQzD,SAASC,eAAa,OAAyB;AAC7C,KAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO;CAChD,MAAM,IAAI;AACV,KAAI,EAAE,eAAe,MAAO,QAAO;AAEnC,SADa,MAAM,QAAQ,EAAE,QAAQ,GAAI,EAAE,UAAuB,EAAE,EACxD,SAAS,mBAAmB;;AAG1C,MAAaC,aAA0B;CACrC,MAAM;CACN,aAAa;CACb,UAAU;CACV,MAAM;CACN,cACE;CAEF,SAAkB;AAChB,SAAO,WAAW,WAAW;;CAG/B,MAAM,QAAQ,MAA8C;EAC1D,MAAM,WAAW,aAA2B,YAAY;EACxD,MAAM,OAAqB,WAAW,EAAE,GAAG,UAAU,GAAG,EAAE;EAC1D,MAAM,UAA0C,EAC9C,GAAK,KAAK,cAAiD,EAAE,EAC9D;EAED,MAAM,aAAaD,eAAa,QAAQ,eAAe;AACvD,MAAI,cAAc,CAAC,KAAK,OAAO;AAC7B,mBAAgB,eAAe,YAAY;AAI3C,OAAI,KAAK,WAAW;IAClB,MAAM,aAAa,mBAAmB,KAAK;AAC3C,QAAI,WAAW,SAAS,UACtB,GAAE,IAAI,KACJ,uCAAuC,WAAW,OAAO,GAC1D;;AAGL,UAAO;IAAE,MAAM;IAAiB,aAAa;IAAa;;AAG5D,MAAI,KAAK,QAAQ;AACf,KAAE,IAAI,KACJ,mBAAmB,aAAa,cAAc,MAAM,6BAA6B,cAClF;AACD,UAAO;IAAE,MAAM;IAAa,aAAa;IAAa;;EAGxD,IAAI;AACJ,MAAI,WAAW,YAAY,EAAE;AAC3B,gBAAa,WAAW,aAAa,cAAc;AACnD,aAAU,WAAW;SAChB;AACL,aAAU,YAAY,EAAE,WAAW,MAAM,CAAC;AAC1C,iBAAc,aAAa,QAAQ,QAAQ;;AAG7C,UAAQ,iBAAiB;AACzB,OAAK,aAAa;AAClB,kBAAgB,aAAa,KAAK;AAGlC,MAAI,CAACA,eADU,aAA2B,YAClB,EAAE,aAAa,eAAe,EAAE;AACtD,KAAE,IAAI,MACJ,wBAAwB,YAAY,sDACrC;AACD,UAAO;IAAE,MAAM;IAAW,QAAQ;IAAuB;;AAG3D,eAAa,eAAe,YAAY;AACxC,IAAE,IAAI,KACJ,kFACD;AAED,MAAI,KAAK,WAAW;GAClB,MAAM,aAAa,mBAAmB,KAAK;AAC3C,OAAI,WAAW,SAAS,UACtB,GAAE,IAAI,KACJ,uCAAuC,WAAW,OAAO,6BAC1D;;AAIL,SAAO;GAAE,MAAM;GAAa,aAAa;GAAa;GAAY;;CAErE;;;;;;;;;;;;AAaD,SAAS,mBAAmB,MAAqC;CAC/D,IAAI;AACJ,KAAI;AACF,eAAa,gBAAgB;UACtB,KAAK;AACZ,SAAO;GACL,MAAM;GACN,QAAQ,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;GACzD;;CAIH,MAAM,WAAW,aAA6B,gBAAgB,IAAI,EAAE;CAIpE,MAAM,SAAS,iBAH4B,SAAS,QAChD,EAAE,OAAO,SAAS,OAAO,GACzB,MAC2C,YAAY,aAAa;AAExE,KAAI,KAAK,QAAQ;AACf,IAAE,IAAI,KACJ,uDAAuD,gBAAgB,IAAI,OAAO,KAAK,OAAO,MAAM,CAAC,OAAO,YAC7G;AACD,SAAO;GAAE,MAAM;GAAa,aAAa;GAAiB;;CAG5D,IAAI;AACJ,KAAI,WAAW,gBAAgB,EAAE;AAC/B,eAAa,WAAW,iBAAiB,mBAAmB,OAAO;AACnE,YAAU,WAAW;OAErB,WAAU,YAAY,EAAE,WAAW,MAAM,CAAC;AAI5C,iBAAgB,iBAAiB;EADF,GAAG;EAAU,OAAO,OAAO;EACrB,CAAC;AAEtC,cAAa,2CAA2C,gBAAgB;AACxE,GAAE,IAAI,KACJ,qLACD;AAED,QAAO;EACL,MAAM;EACN,aAAa;EACb,GAAI,eAAe,KAAA,KAAa,EAAE,YAAY;EAC/C;;;;ACtKH,MAAaE,aAAU,qBAAqB;CAC1C,MAAM;CACN,aAAa;CACb,WAAW,KAAK,SAAS,EAAE,SAAS;CACpC,YAAY,KAAK,SAAS,EAAE,UAAU,WAAW;CACjD,MAAM;CACN,cACE;CACH,CAAC;;;ACHF,MAAM,cAAc,QAAQ,IAAI,mBAAmB,KAAK,SAAS,EAAE,WAAW;AAC9E,MAAM,mBAAmB,KAAK,aAAa,kBAAkB;AAQ7D,SAASC,eAAa,OAAyB;AAC7C,KAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO;AAChD,QAAO,KAAK,UAAU,MAAM,KAAK,KAAK,UAAU,8BAA8B;;AAGhF,MAAaC,aAA0B;CACrC,MAAM;CACN,aAAa;CACb,UAAU;CACV,MAAM;CACN,cACE;CAEF,SAAkB;AAChB,SAAO,WAAW,YAAY;;CAGhC,MAAM,QAAQ,MAA8C;EAC1D,MAAM,WAAW,aAA4B,iBAAiB;EAC9D,MAAM,OAAsB,WAAW,EAAE,GAAG,UAAU,GAAG,EAAE;EAC3D,MAAM,UAA2C,EAC/C,GAAK,KAAK,cAAkD,EAAE,EAC/D;EAED,MAAM,aAAaD,eAAa,QAAQ,eAAe;AACvD,MAAI,cAAc,CAAC,KAAK,OAAO;AAC7B,mBAAgB,sBAAsB,iBAAiB;AACvD,UAAO;IAAE,MAAM;IAAiB,aAAa;IAAkB;;AAGjE,MAAI,KAAK,QAAQ;AACf,KAAE,IAAI,KACJ,mBAAmB,aAAa,cAAc,MAAM,6BAA6B,mBAClF;AACD,UAAO;IAAE,MAAM;IAAa,aAAa;IAAkB;;EAG7D,IAAI;AACJ,MAAI,WAAW,iBAAiB,EAAE;AAChC,gBAAa,WAAW,kBAAkB,cAAc;AACxD,aAAU,WAAW;QAErB,WAAU,QAAQ,iBAAiB,EAAE,EAAE,WAAW,MAAM,CAAC;AAG3D,UAAQ,iBAAiB;AACzB,OAAK,aAAa;AAClB,kBAAgB,kBAAkB,KAAK;AAGvC,MAAI,CAACA,eADU,aAA4B,iBACnB,EAAE,aAAa,eAAe,EAAE;AACtD,KAAE,IAAI,MACJ,wBAAwB,iBAAiB,sDAC1C;AACD,UAAO;IAAE,MAAM;IAAW,QAAQ;IAAuB;;AAG3D,eAAa,sBAAsB,iBAAiB;AACpD,IAAE,IAAI,KACJ,6GACD;AACD,SAAO;GACL,MAAM;GACN,aAAa;GACb,GAAI,eAAe,KAAA,KAAa,EAAE,YAAY;GAC/C;;CAEJ;;;ACxED,MAAM,YAAY,KAAK,SAAS,EAAE,SAAS;AAC3C,MAAM,aAAa,KAAK,WAAW,cAAc;AACjD,MAAM,cAAc,KAAK,WAAW,aAAa;AAEjD,MAAM,aAAa;;;;;;;AAQnB,MAAM,iBAAiB;AAEvB,SAAS,YAAY,MAAuB;AAC1C,QAAO,KAAK,SAAS,eAAe;;AAGtC,SAAS,mBAAmB,MAAsB;CAChD,MAAM,QAAQ,KAAK,MAAM,QAAQ;CACjC,MAAM,MAAgB,EAAE;CACxB,IAAI,WAAW;AACf,MAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,UAAU,KAAK,MAAM;AAC3B,MACE,YAAY,kBACZ,YAAY,iCACZ;AACA,cAAW;AACX;;AAEF,MACE,YACA,QAAQ,WAAW,IAAI,IACvB,YAAY,gCAEZ,YAAW;AAEb,MAAI,CAAC,SAAU,KAAI,KAAK,KAAK;;AAE/B,QAAO,IAAI,KAAK,KAAK,CAAC,QAAQ,WAAW,OAAO,CAAC,SAAS,GAAG;;AAG/D,MAAaE,aAA0B;CACrC,MAAM;CACN,aAAa;CACb,UAAU;CACV,MAAM;CACN,cACE;CAEF,SAAkB;AAChB,SAAO,WAAW,UAAU;;CAG9B,MAAM,QAAQ,MAA8C;EAC1D,MAAM,SAAS,WAAW,WAAW;EACrC,MAAM,UAAU,SAAS,aAAa,YAAY,QAAQ,GAAG;EAC7D,MAAM,QAAQ,YAAY,QAAQ;AAElC,MAAI,SAAS,CAAC,KAAK,OAAO;AACxB,mBAAgB,aAAa,WAAW;AACxC,UAAO;IAAE,MAAM;IAAiB,aAAa;IAAY;;AAG3D,MAAI,KAAK,QAAQ;AACf,KAAE,IAAI,KACJ,mBAAmB,QAAQ,YAAY,SAAS,gCAAgC,aACjF;AACD,OAAI,KAAK,UAAW,mBAAkB,KAAK;AAC3C,UAAO;IAAE,MAAM;IAAa,aAAa;IAAY;;EAGvD,IAAI;AACJ,MAAI,QAAQ;AACV,gBAAa,WAAW,YAAY,SAAS,OAAO;AACpD,aAAU,WAAW;QAErB,WAAU,QAAQ,WAAW,EAAE,EAAE,WAAW,MAAM,CAAC;EAGrD,MAAM,UAAU,QAAQ,mBAAmB,QAAQ,GAAG;AAGtD,gBAAc,YAAY,GADV,UADD,QAAQ,WAAW,KAAK,QAAQ,SAAS,KAAK,GAAG,KAAK,OAClC,QAAQ,SAAS,IAAI,OAAO,KAAK,cACpC,QAAQ;AAGxC,MAAI,CAAC,YADU,aAAa,YAAY,QACjB,CAAC,EAAE;AACxB,KAAE,IAAI,MACJ,wBAAwB,WAAW,mBAAmB,eAAe,eACtE;AACD,UAAO;IAAE,MAAM;IAAW,QAAQ;IAAuB;;AAG3D,eAAa,aAAa,WAAW;AACrC,IAAE,IAAI,KACJ,+KACD;AAED,MAAI,KAAK,WAAW;GAClB,MAAM,aAAa,kBAAkB,KAAK;AAC1C,OAAI,WAAW,SAAS,UACtB,GAAE,IAAI,KACJ,iCAAiC,WAAW,OAAO,6BACpD;;AAIL,SAAO;GACL,MAAM;GACN,aAAa;GACb,GAAI,eAAe,KAAA,KAAa,EAAE,YAAY;GAC/C;;CAEJ;;;;;;;AAQD,SAAS,kBAAkB,MAAqC;CAC9D,IAAI;AACJ,KAAI;AACF,eAAa,gBAAgB;UACtB,KAAK;AACZ,SAAO;GACL,MAAM;GACN,QAAQ,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;GACzD;;CAGH,MAAM,WAAW,aAA2B,YAAY;CACxD,MAAM,SAAS,iBAAiB,UAAU,WAAW;AAErD,KAAI,KAAK,QAAQ;AACf,IAAE,IAAI,KACJ,mBAAmB,WAAW,UAAU,SAAS,GAAG,YAAY,QAAQ,OAAO,KAAK,OAAO,MAAM,CAAC,OAAO,WAC1G;AACD,SAAO;GAAE,MAAM;GAAa,aAAa;GAAa;;CAGxD,IAAI;AACJ,KAAI,WAAW,YAAY,EAAE;AAC3B,eAAa,WAAW,aAAa,eAAe,OAAO;AAC3D,YAAU,WAAW;;AAGvB,iBAAgB,aAAa,OAAO;AAEpC,cAAa,mDAAmD,YAAY;AAC5E,GAAE,IAAI,KACJ,wKACD;AAED,QAAO;EACL,MAAM;EACN,aAAa;EACb,GAAI,eAAe,KAAA,KAAa,EAAE,YAAY;EAC/C;;;;AC7JH,MAAM,eAAe,KAAK,SAAS,EAAE,YAAY;AACjD,MAAM,YAAY,KAAK,cAAc,cAAc;AACnD,MAAM,YAAY,KAAK,cAAc,cAAc;AAcnD,SAAS,aAA4B;AACnC,QAAO;EACL,MAAM;EACN,SAAS,sBAAsB;EAC/B,MAAM,CAAC,GAAG,sBAAsB,KAAK;EACrC,KAAK,EAAE,GAAG,sBAAsB,KAAK;EACtC;;AAGH,SAAS,mBAAmB,OAA2C;AACrE,KAAI,CAAC,MAAO,QAAO;AACnB,QAAO,MAAM,SAAS,iBAAiB,MAAM,KAAK,SAAS,mBAAmB;;AAMhF,SAAS,kBAA0B;CACjC,MAAM,IAAI,YAAY;CACtB,MAAM,WAAW,OAAO,QAAQ,EAAE,OAAO,EAAE,CAAC,CACzC,KAAK,CAAC,GAAG,OAAO,SAAS,EAAE,KAAK,EAAE,GAAG,CACrC,KAAK,KAAK;AACb,QAAO;EACL;EACA,aAAa,EAAE;EACf,gBAAgB,EAAE;EAClB;EACA,GAAG,EAAE,KAAK,KAAK,MAAM,YAAY,EAAE,GAAG;EACtC;EACA;EACA;EACD,CAAC,KAAK,KAAK;;AAGd,MAAaC,aAA0B;CACrC,MAAM;CACN,aAAa;CACb,UAAU;CACV,MAAM;CACN,cACE;CAEF,SAAkB;AAChB,SAAO,WAAW,aAAa;;CAGjC,MAAM,QAAQ,MAA8C;EAC1D,MAAM,aAAa,WAAW,UAAU;EACxC,MAAM,aAAa,WAAW,UAAU;AAIxC,MAAI,YAAY;GAKd,MAAM,SAAS,qOAJE,iBAAiB,CAC/B,MAAM,KAAK,CACX,KAAK,MAAO,IAAI,KAAK,MAAM,EAAG,CAC9B,KAAK,KACoP;AAC5P,KAAE,IAAI,KACJ,aAAa,UAAU,sCAAsC,SAC9D;AACD,UAAO;IAAE,MAAM;IAAQ,QAAQ;IAAiC;;AAIlE,MAAI,YAAY;GACd,MAAM,WAAW,aAAiC,UAAU;GAC5D,MAAM,OAA2B,WAAW,EAAE,GAAG,UAAU,GAAG,EAAE;GAChE,MAAM,UAAU,MAAM,QAAQ,KAAK,WAAW,GAC1C,CAAC,GAAG,KAAK,WAAW,GACpB,EAAE;GAEN,MAAM,MAAM,QAAQ,WAAW,MAAM,GAAG,SAAS,cAAc;GAC/D,MAAM,aAAa,OAAO,KAAK,mBAAmB,QAAQ,KAAK;AAC/D,OAAI,cAAc,CAAC,KAAK,OAAO;AAC7B,oBAAgB,YAAY,UAAU;AACtC,WAAO;KAAE,MAAM;KAAiB,aAAa;KAAW;;AAG1D,OAAI,KAAK,QAAQ;AACf,MAAE,IAAI,KACJ,mBAAmB,aAAa,cAAc,MAAM,8BAA8B,YACnF;AACD,WAAO;KAAE,MAAM;KAAa,aAAa;KAAW;;GAGtD,MAAM,aAAa,WAAW,WAAW,WAAW;AACpD,aAAU,WAAW;GAErB,MAAM,QAAQ,YAAY;AAC1B,OAAI,OAAO,EAAG,SAAQ,OAAO;OACxB,SAAQ,KAAK,MAAM;AACxB,QAAK,aAAa;AAClB,mBAAgB,WAAW,KAAK;GAGhC,MAAM,cADS,aAAiC,UACtB,EAAE,YAAY,MACrC,MAAM,GAAG,SAAS,cACpB;AACD,OAAI,CAAC,mBAAmB,YAAY,EAAE;AACpC,MAAE,IAAI,MACJ,wBAAwB,UAAU,uDACnC;AACD,WAAO;KAAE,MAAM;KAAW,QAAQ;KAAuB;;AAG3D,gBAAa,iCAAiC,UAAU;AACxD,UAAO;IACL,MAAM;IACN,aAAa;IACb;IACD;;AAIH,MAAI,KAAK,QAAQ;AACf,KAAE,IAAI,KAAK,0BAA0B,UAAU,yBAAyB;AACxE,UAAO;IAAE,MAAM;IAAa,aAAa;IAAW;;AAGtD,YAAU,QAAQ,UAAU,EAAE,EAAE,WAAW,MAAM,CAAC;AAClD,gBAAc,WAAW,iBAAiB,EAAE,QAAQ;AACpD,eAAa,YAAY,UAAU;AACnC,SAAO;GAAE,MAAM;GAAa,aAAa;GAAW;;CAEvD;;;AC/JD,MAAaC,aAAU,qBAAqB;CAC1C,MAAM;CACN,aAAa;CACb,WAAW,KAAK,SAAS,EAAE,UAAU;CACrC,YAAY,KAAK,SAAS,EAAE,WAAW,WAAW;CAClD,MAAM;CACN,cACE;CACH,CAAC;;;ACFF,MAAaC,aAAU,qBAAqB;CAC1C,MAAM;CACN,aAAa;CACb,WAAW,KAAK,SAAS,EAAE,WAAW;CACtC,YAAY,KAAK,SAAS,EAAE,YAAY,WAAW;CACnD,MAAM;CACN,cACE;CAEF,kBAAkB,EAAE,MAAM,SAAS;CACpC,CAAC;;;AChBF,MAAaC,YAAU,qBAAqB;CAC1C,MAAM;CACN,aAAa;CACb,WAAW,KAAK,SAAS,EAAE,UAAU;CACrC,YAAY,KAAK,SAAS,EAAE,WAAW,gBAAgB;CACvD,MAAM;CACN,cACE;CACH,CAAC;;;ACNF,MAAM,aAAa,KAAK,SAAS,EAAE,UAAU;AAC7C,MAAM,gBAAgB,KAAK,YAAY,cAAc;AACrD,MAAMC,SAAO;AAEb,MAAaC,YAA0B;CACrC,MAAM;CACN,aAAa;CACb,UAAU;CACV,MAAMD;CACN,cACE;CAEF,SAAkB;AAChB,SAAO,WAAW,WAAW;;CAG/B,MAAM,QAAQ,OAA+C;AAC3D,IAAE,IAAI,KACJ,4FACD;AACD,IAAE,KACA;GACE,UAAU,cAAc;GACxB;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA,eAAeA;GAChB,CAAC,KAAK,KAAK,EACZ,wBACD;AACD,SAAO;GACL,MAAM;GACN,QAAQ;GACT;;CAEJ;;;ACxCD,MAAaE,YAAU,qBAAqB;CAC1C,MAAM;CACN,aAAa;CACb,WAAW,KAAK,SAAS,EAAE,QAAQ;CACnC,YAAY,KAAK,SAAS,EAAE,SAAS,YAAY,WAAW;CAC5D,MAAM;CACN,cACE;CACH,CAAC;;;ACXF,MAAaC,YAAU,qBAAqB;CAC1C,MAAM;CACN,aAAa;CACb,UAAU;CACV,WAAW,KAAK,SAAS,EAAE,YAAY;CACvC,YAAY,KAAK,SAAS,EAAE,aAAa,gBAAgB;CACzD,MAAM;CACN,cACE;CACH,CAAC;;;ACMF,MAAM,cAAc,KAAK,SAAS,EAAE,WAAW,YAAY,gBAAgB;AAC3E,MAAM,aAAa,KAAK,SAAS,EAAE,WAAW,WAAW;AAQzD,MAAM,iBAAiB;CACrB,MAAM;CACN,SAAS;EAAC;EAAO;EAAM;EAAmB;CAC1C,SAAS;CACV;AAKD,SAAS,aAAa,OAAyB;AAC7C,KAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO;CAChD,MAAM,UAAW,MAAmB;AACpC,QAAO,MAAM,QAAQ,QAAQ,IAAI,QAAQ,SAAS,mBAAmB;;AAGvE,MAAaC,YAA0B;CACrC,MAAM;CACN,aAAa;CACb,UAAU;CACV,MAAM;CACN,cACE;CAEF,SAAkB;AAChB,SAAO,WAAW,WAAW;;CAG/B,MAAM,QAAQ,MAA8C;EAC1D,MAAM,WAAW,aAA6B,YAAY;EAC1D,MAAM,OAAuB,WAAW,EAAE,GAAG,UAAU,GAAG,EAAE;EAC5D,MAAM,cAAc,KAAK;EACzB,MAAM,MACJ,eACA,OAAO,gBAAgB,YACvB,CAAC,MAAM,QAAQ,YAAY,GACvB,EAAE,GAAI,aAA0C,GAChD,EAAE;EAER,MAAM,aAAa,aAAa,IAAI,eAAe;AACnD,MAAI,cAAc,CAAC,KAAK,OAAO;AAC7B,mBAAgB,KAAK,aAAa,YAAY;AAC9C,UAAO;IAAE,MAAM;IAAiB,aAAa;IAAa;;AAG5D,MAAI,KAAK,QAAQ;AACf,KAAE,IAAI,KACJ,mBAAmB,aAAa,cAAc,MAAM,sBAAsB,cAC3E;AACD,UAAO;IAAE,MAAM;IAAa,aAAa;IAAa;;EAGxD,IAAI;AACJ,MAAI,WAAW,YAAY,EAAE;AAC3B,gBAAa,WAAW,aAAa,KAAK,KAAK;AAC/C,aAAU,WAAW;QAErB,WAAU,QAAQ,YAAY,EAAE,EAAE,WAAW,MAAM,CAAC;AAGtD,MAAI,iBAAiB,EAAE,GAAG,gBAAgB;AAC1C,OAAK,SAAS;AACd,kBAAgB,aAAa,KAAK;EAGlC,MAAM,YADS,aAA6B,YACpB,GAAG;AAC3B,MAAI,CAAC,aAAa,YAAY,eAAe,EAAE;AAC7C,KAAE,IAAI,MACJ,wBAAwB,YAAY,+CACrC;AACD,UAAO;IAAE,MAAM;IAAW,QAAQ;IAAuB;;AAG3D,eAAa,KAAK,aAAa,YAAY;AAC3C,SAAO;GACL,MAAM;GACN,aAAa;GACb,GAAI,eAAe,KAAA,KAAa,EAAE,YAAY;GAC/C;;CAEJ;;;ACrGD,MAAM,gBAAgB,KAAK,SAAS,EAAE,aAAa;AACnD,MAAMC,SAAO;AAEb,MAAaC,YAA0B;CACrC,MAAM;CACN,aAAa;CACb,UAAU;CACV,MAAMD;CACN,cACE;CAEF,SAAkB;AAChB,SAAO,WAAW,cAAc;;CAGlC,MAAM,QAAQ,OAA+C;AAC3D,IAAE,IAAI,KACJ,wHACD;AACD,IAAE,KACA;GACE;GACA;GACA;GACA;GACA;GACA,aAAaA;GACd,CAAC,KAAK,KAAK,EACZ,2BACD;AACD,SAAO;GACL,MAAM;GACN,QAAQ;GACT;;CAEJ;;;ACnCD,MAAM,SAAS,KAAK,SAAS,EAAE,MAAM;AACrC,MAAM,aAAa,KAAK,QAAQ,SAAS,cAAc,cAAc;AACrE,MAAM,OAAO;AAEb,MAAaE,YAA0B;CACrC,MAAM;CACN,aAAa;CACb,UAAU;CACV,MAAM;CACN,cACE;CAEF,SAAkB;AAChB,SAAO,WAAW,OAAO;;CAG3B,MAAM,QAAQ,OAA+C;AAC3D,IAAE,IAAI,KACJ,kHACD;AACD,IAAE,KACA;GACE;GACA;GACA,cAAc;GACd,iCAAiC,WAAW;GAC5C,oCAAoC,WAAW;GAC/C;GACA;GACA;GACA;GACA,eAAe;GAChB,CAAC,KAAK,KAAK,EACZ,oBACD;AACD,SAAO;GACL,MAAM;GACN,QAAQ;GACT;;CAEJ;;;ACtCD,MAAaC,YAAU,qBAAqB;CAC1C,MAAM;CACN,aAAa;CACb,WAAW,KAAK,SAAS,EAAE,QAAQ;CACnC,YAAY,KAAK,SAAS,EAAE,SAAS,gBAAgB;CACrD,MAAM;CACN,cACE;CACH,CAAC;;;ACNF,MAAaC,YAAU,qBAAqB;CAC1C,MAAM;CACN,aAAa;CACb,WAAW,KAAK,SAAS,EAAE,QAAQ;CACnC,YAAY,KAAK,SAAS,EAAE,SAAS,YAAY;CACjD,MAAM;CACN,cACE;CACH,CAAC;;;ACRF,MAAM,eAAe,KAAK,SAAS,EAAE,WAAW,MAAM;AAEtD,MAAa,UAAU,qBAAqB;CAC1C,MAAM;CACN,aAAa;CACb,WAAW;CACX,YAAY,KAAK,cAAc,gBAAgB;CAC/C,YAAY;CACZ,MAAM;CACN,cACE;CACH,CAAC;;;;;;;;;;ACEF,MAAa,WAAsC;CACjDC;CACAC;CACAC;CACAC;CACAC;CACAC;CACAC;CACAC;CACAC;CACAC;CACAC;CACAC;CACAC;CACAC;CACAC;CACAC;CACAC;CACAC;CACD;AAED,SAAgB,eAAe,MAAqC;CAClE,MAAM,QAAQ,KAAK,aAAa;AAChC,QAAO,SAAS,MAAM,MAAM,EAAE,SAAS,MAAM,IAAI;;AAGnD,SAAgB,cAAwB;AACtC,QAAO,SAAS,KAAK,MAAM,EAAE,KAAK;;AAGpC,SAAS,WAAW,MAMlB;CACA,MAAM,aAAuB,EAAE;CAC/B,IAAI,SAAS;CACb,IAAI,QAAQ;CACZ,IAAI,MAAM;CACV,IAAI,YAAY;AAChB,MAAK,MAAM,KAAK,KACd,KAAI,MAAM,YAAa,UAAS;UACvB,MAAM,UAAW,SAAQ;UACzB,MAAM,QAAS,OAAM;UACrB,MAAM,eAAgB,aAAY;UAClC,CAAC,EAAE,WAAW,IAAI,CAAE,YAAW,KAAK,EAAE;AAEjD,QAAO;EAAE;EAAQ;EAAO;EAAK;EAAW;EAAY;;AAGtD,eAAsB,WACpB,SACA,MACwB;AACxB,KAAI,CAAC,QAAQ,QAAQ,EAAE;AACrB,IAAE,IAAI,KACJ,GAAG,QAAQ,YAAY,4CAA4C,QAAQ,OAAO,UAAU,QAAQ,SAAS,KAC9G;AACD,SAAO;GAAE,MAAM;GAAW,QAAQ;GAAgB;;AAEpD,GAAE,IAAI,KAAK,UAAU,QAAQ,YAAY,GAAG;AAC5C,KAAI,QAAQ,aACV,GAAE,IAAI,QAAQ,QAAQ,aAAa;AAErC,KAAI;AACF,SAAO,MAAM,QAAQ,QAAQ,KAAK;UAC3B,KAAK;AACZ,IAAE,IAAI,MACJ,GAAG,QAAQ,YAAY,IAAI,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,GAC5E;AACD,SAAO;GAAE,MAAM;GAAW,QAAQ;GAAa;;;AAInD,eAAsB,WAAW,MAA+B;CAC9D,MAAM,EAAE,QAAQ,OAAO,KAAK,WAAW,eAAe,WAAW,KAAK;CACtE,MAAM,sBACJ,WAAW,WAAW,KAAK,WAAW,IAAI,aAAa,KAAK;AAC9D,KAAI,UAAU,KAAK,WAAW,CAAC,qBAAqB;AAClD,IAAE,MAAM,sBAAsB;AAC9B,IAAE,IAAI,KACJ,wIACD;AACD,IAAE,MAAM,8CAA8C;AACtD;;CAGF,MAAM,OAAuB;EAAE;EAAQ;EAAO;EAAW;AAEzD,GAAE,MAAM,sBAAsB;AAE9B,KAAI,WAAW,WAAW,KAAK,CAAC,KAAK;EACnC,MAAM,WAAW,SAAS,QAAQ,MAAM,EAAE,QAAQ,CAAC;AACnD,MAAI,SAAS,WAAW,GAAG;AACzB,KAAE,IAAI,MAAM,gDAAgD;AAC5D,KAAE,MAAM,cAAc,aAAa,CAAC,KAAK,KAAK,GAAG;AACjD,WAAQ,KAAK,EAAE;;EAEjB,MAAM,SAAS,MAAM,EAAE,YAAoB;GACzC,SAAS;GACT,SAAS,SAAS,KAAK,OAAO;IAAE,OAAO,EAAE;IAAM,OAAO,EAAE;IAAa,EAAE;GACvE,UAAU;GACX,CAAC;AACF,MAAI,EAAE,SAAS,OAAO,EAAE;AACtB,KAAE,OAAO,aAAa;AACtB;;EAEF,MAAM,UAAqD,EAAE;AAC7D,OAAK,MAAM,QAAQ,QAAoB;GACrC,MAAM,UAAU,eAAe,KAAK;AACpC,OAAI,CAAC,QAAS;AACd,WAAQ,KAAK;IAAE;IAAM,QAAQ,MAAM,WAAW,SAAS,KAAK;IAAE,CAAC;;AAEjE,YAAU,QAAQ;AAClB;;AAGF,KAAI,KAAK;EACP,MAAM,WAAW,SAAS,QAAQ,MAAM,EAAE,QAAQ,CAAC;AACnD,MAAI,SAAS,WAAW,GAAG;AACzB,KAAE,IAAI,MAAM,gDAAgD;AAC5D,WAAQ,KAAK,EAAE;;EAEjB,MAAM,UAAqD,EAAE;AAC7D,OAAK,MAAM,WAAW,SACpB,SAAQ,KAAK;GACX,MAAM,QAAQ;GACd,QAAQ,MAAM,WAAW,SAAS,KAAK;GACxC,CAAC;AAEJ,YAAU,QAAQ;AAClB;;CAGF,MAAM,YAAY,WAAW;CAC7B,MAAM,UAAU,eAAe,UAAU;AACzC,KAAI,CAAC,SAAS;AACZ,IAAE,IAAI,MAAM,kBAAkB,YAAY;AAC1C,IAAE,MAAM,cAAc,aAAa,CAAC,KAAK,KAAK,GAAG;AACjD,UAAQ,KAAK,EAAE;;CAGjB,MAAM,SAAS,MAAM,WAAW,SAAS,KAAK;AAC9C,WAAU,CAAC;EAAE,MAAM;EAAW;EAAQ,CAAC,CAAC;AACxC,KAAI,OAAO,SAAS,aAAc,OAA8B,WAAW,eACzE,SAAQ,KAAK,EAAE;;AAInB,SAAS,UACP,SACM;CACN,MAAM,QAAQ,QAAQ,KAAK,EAAE,MAAM,aAAa;AAC9C,UAAQ,OAAO,MAAf;GACE,KAAK,YACH,QAAO,KAAK,GAAG,MAAM,IAAI,CAAC,GAAG,GAAG,KAAK,KAAK,GAAG,OAAO,cAAc,IAAI,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,KAAK,OAAO,YAAY,KAAK;GACvH,KAAK,gBACH,QAAO,KAAK,GAAG,MAAM,IAAI,CAAC,GAAG,GAAG,KAAK,KAAK,CAAC,GAAG,GAAG,IAAI,kBAAkB;GACzE,KAAK,OACH,QAAO,KAAK,GAAG,OAAO,IAAI,CAAC,GAAG,GAAG,KAAK,KAAK,CAAC,GAAG,GAAG,OAAO,6BAA6B,OAAO,OAAO,GAAG;GACzG,KAAK,UACH,QAAO,KAAK,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,KAAK,KAAK,CAAC,GAAG,GAAG,IAAI,aAAa,OAAO,OAAO,GAAG;;GAErF;AACF,GAAE,KAAK,MAAM,KAAK,KAAK,EAAE,UAAU;CAEnC,MAAM,QAAQ,QAAQ,QAAQ,MAAM,EAAE,OAAO,SAAS,OAAO;AAC7D,KAAI,MAAM,SAAS,EACjB,GAAE,IAAI,KACJ,GAAG,MAAM,OAAO,0DACjB;AAMH,KAHiB,QAAQ,MACtB,MAAM,EAAE,OAAO,SAAS,eAAe,EAAE,OAAO,SAAS,gBAEhD,CACV,GAAE,IAAI,KACJ,8IACD;AAGH,GAAE,MAAM,0EAA0E"}
|
package/dist/schema-CNiCWzV9.mjs
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { createHash } from "node:crypto";
|
|
2
|
-
//#region src/state/schema.ts
|
|
3
|
-
const KV = {
|
|
4
|
-
sessions: "mem:sessions",
|
|
5
|
-
observations: (sessionId) => `mem:obs:${sessionId}`,
|
|
6
|
-
memories: "mem:memories",
|
|
7
|
-
summaries: "mem:summaries",
|
|
8
|
-
config: "mem:config",
|
|
9
|
-
metrics: "mem:metrics",
|
|
10
|
-
health: "mem:health",
|
|
11
|
-
embeddings: (obsId) => `mem:emb:${obsId}`,
|
|
12
|
-
bm25Index: "mem:index:bm25",
|
|
13
|
-
relations: "mem:relations",
|
|
14
|
-
profiles: "mem:profiles",
|
|
15
|
-
claudeBridge: "mem:claude-bridge",
|
|
16
|
-
graphNodes: "mem:graph:nodes",
|
|
17
|
-
graphEdges: "mem:graph:edges",
|
|
18
|
-
graphSnapshot: "mem:graph:snapshot",
|
|
19
|
-
graphNameIndex: "mem:graph:name-index",
|
|
20
|
-
graphEdgeKey: "mem:graph:edge-key",
|
|
21
|
-
graphNodeDegree: "mem:graph:node-degree",
|
|
22
|
-
semantic: "mem:semantic",
|
|
23
|
-
procedural: "mem:procedural",
|
|
24
|
-
teamShared: (teamId) => `mem:team:${teamId}:shared`,
|
|
25
|
-
teamUsers: (teamId, userId) => `mem:team:${teamId}:users:${userId}`,
|
|
26
|
-
teamProfile: (teamId) => `mem:team:${teamId}:profile`,
|
|
27
|
-
audit: "mem:audit",
|
|
28
|
-
actions: "mem:actions",
|
|
29
|
-
actionEdges: "mem:action-edges",
|
|
30
|
-
leases: "mem:leases",
|
|
31
|
-
routines: "mem:routines",
|
|
32
|
-
routineRuns: "mem:routine-runs",
|
|
33
|
-
signals: "mem:signals",
|
|
34
|
-
checkpoints: "mem:checkpoints",
|
|
35
|
-
mesh: "mem:mesh",
|
|
36
|
-
sketches: "mem:sketches",
|
|
37
|
-
facets: "mem:facets",
|
|
38
|
-
sentinels: "mem:sentinels",
|
|
39
|
-
crystals: "mem:crystals",
|
|
40
|
-
lessons: "mem:lessons",
|
|
41
|
-
insights: "mem:insights",
|
|
42
|
-
graphEdgeHistory: "mem:graph:edge-history",
|
|
43
|
-
enrichedChunks: (sessionId) => `mem:enriched:${sessionId}`,
|
|
44
|
-
latentEmbeddings: (obsId) => `mem:latent:${obsId}`,
|
|
45
|
-
retentionScores: "mem:retention",
|
|
46
|
-
accessLog: "mem:access",
|
|
47
|
-
imageRefs: "mem:image-refs",
|
|
48
|
-
imageEmbeddings: "mem:image-embeddings",
|
|
49
|
-
slots: "mem:slots",
|
|
50
|
-
globalSlots: "mem:slots:global",
|
|
51
|
-
state: "mem:state",
|
|
52
|
-
commits: "mem:commits",
|
|
53
|
-
recentSearches: "mem:recent-searches"
|
|
54
|
-
};
|
|
55
|
-
const STREAM = {
|
|
56
|
-
name: "mem-live",
|
|
57
|
-
group: (sessionId) => sessionId,
|
|
58
|
-
viewerGroup: "viewer"
|
|
59
|
-
};
|
|
60
|
-
function generateId(prefix) {
|
|
61
|
-
return `${prefix}_${Date.now().toString(36)}_${crypto.randomUUID().replace(/-/g, "").slice(0, 12)}`;
|
|
62
|
-
}
|
|
63
|
-
function fingerprintId(prefix, content) {
|
|
64
|
-
return `${prefix}_${createHash("sha256").update(content).digest("hex").slice(0, 16)}`;
|
|
65
|
-
}
|
|
66
|
-
function jaccardSimilarity(a, b) {
|
|
67
|
-
const setA = new Set(a.split(/\s+/).filter((t) => t.length > 2));
|
|
68
|
-
const setB = new Set(b.split(/\s+/).filter((t) => t.length > 2));
|
|
69
|
-
if (setA.size === 0 && setB.size === 0) return 1;
|
|
70
|
-
if (setA.size === 0 || setB.size === 0) return 0;
|
|
71
|
-
let intersection = 0;
|
|
72
|
-
for (const word of setA) if (setB.has(word)) intersection++;
|
|
73
|
-
return intersection / (setA.size + setB.size - intersection);
|
|
74
|
-
}
|
|
75
|
-
//#endregion
|
|
76
|
-
export { jaccardSimilarity as a, generateId as i, STREAM as n, fingerprintId as r, KV as t };
|
|
77
|
-
|
|
78
|
-
//# sourceMappingURL=schema-CNiCWzV9.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"schema-CNiCWzV9.mjs","names":[],"sources":["../src/state/schema.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\n\nexport const KV = {\n sessions: \"mem:sessions\",\n observations: (sessionId: string) => `mem:obs:${sessionId}`,\n memories: \"mem:memories\",\n summaries: \"mem:summaries\",\n config: \"mem:config\",\n metrics: \"mem:metrics\",\n health: \"mem:health\",\n embeddings: (obsId: string) => `mem:emb:${obsId}`,\n bm25Index: \"mem:index:bm25\",\n relations: \"mem:relations\",\n profiles: \"mem:profiles\",\n claudeBridge: \"mem:claude-bridge\",\n graphNodes: \"mem:graph:nodes\",\n graphEdges: \"mem:graph:edges\",\n // #814: precomputed snapshot of the top-degree subgraph and aggregate\n // type counts. Saves /graph/query and /graph/stats from a full\n // kv.list enumeration over 75K+ node corpora, which exceeds the iii\n // invocation timeout and surfaces as \"Invocation stopped\" 500s.\n // Single fixed key (\"current\") so writes are read-modify-write under\n // the same keyed mutex as graph-extract.\n graphSnapshot: \"mem:graph:snapshot\",\n // #814 v2: targeted-lookup indexes so graph-extract never enumerates\n // the full nodes/edges scope. Each entry is a single small kv.get,\n // bounded payload — works at 75K+ nodes where kv.list would block\n // the worker event loop (37MB WS frame parse blocks heartbeat,\n // worker is declared dead before any Promise.race timer can fire).\n // - graphNameIndex: key `${type}|${name}` -> nodeId. Replaces the\n // existingNodes.find() O(n) dedup scan inside mem::graph-extract.\n // - graphEdgeKey: key `${src}|${tgt}|${type}` -> edgeId. Same for\n // edge dedup.\n // - graphNodeDegree: key nodeId -> incident-edge count. Read /\n // incremented on edge writes to maintain the snapshot top-N\n // ranking without scanning all edges.\n graphNameIndex: \"mem:graph:name-index\",\n graphEdgeKey: \"mem:graph:edge-key\",\n graphNodeDegree: \"mem:graph:node-degree\",\n semantic: \"mem:semantic\",\n procedural: \"mem:procedural\",\n teamShared: (teamId: string) => `mem:team:${teamId}:shared`,\n teamUsers: (teamId: string, userId: string) =>\n `mem:team:${teamId}:users:${userId}`,\n teamProfile: (teamId: string) => `mem:team:${teamId}:profile`,\n audit: \"mem:audit\",\n actions: \"mem:actions\",\n actionEdges: \"mem:action-edges\",\n leases: \"mem:leases\",\n routines: \"mem:routines\",\n routineRuns: \"mem:routine-runs\",\n signals: \"mem:signals\",\n checkpoints: \"mem:checkpoints\",\n mesh: \"mem:mesh\",\n sketches: \"mem:sketches\",\n facets: \"mem:facets\",\n sentinels: \"mem:sentinels\",\n crystals: \"mem:crystals\",\n lessons: \"mem:lessons\",\n insights: \"mem:insights\",\n graphEdgeHistory: \"mem:graph:edge-history\",\n enrichedChunks: (sessionId: string) => `mem:enriched:${sessionId}`,\n latentEmbeddings: (obsId: string) => `mem:latent:${obsId}`,\n retentionScores: \"mem:retention\",\n accessLog: \"mem:access\",\n imageRefs: \"mem:image-refs\",\n imageEmbeddings: \"mem:image-embeddings\",\n slots: \"mem:slots\",\n globalSlots: \"mem:slots:global\",\n state: \"mem:state\",\n commits: \"mem:commits\",\n // #771: tracks the most recent smart-search call per session, used by\n // the followup-rate diagnostic. Key = sessionId. TTL-swept hourly.\n recentSearches: \"mem:recent-searches\",\n} as const;\n\nexport const STREAM = {\n name: \"mem-live\",\n group: (sessionId: string) => sessionId,\n viewerGroup: \"viewer\",\n} as const;\n\nexport function generateId(prefix: string): string {\n const ts = Date.now().toString(36);\n const rand = crypto.randomUUID().replace(/-/g, \"\").slice(0, 12);\n return `${prefix}_${ts}_${rand}`;\n}\n\nexport function fingerprintId(prefix: string, content: string): string {\n const hash = createHash(\"sha256\").update(content).digest(\"hex\");\n return `${prefix}_${hash.slice(0, 16)}`;\n}\n\nexport function jaccardSimilarity(a: string, b: string): number {\n const setA = new Set(a.split(/\\s+/).filter((t) => t.length > 2));\n const setB = new Set(b.split(/\\s+/).filter((t) => t.length > 2));\n if (setA.size === 0 && setB.size === 0) return 1;\n if (setA.size === 0 || setB.size === 0) return 0;\n let intersection = 0;\n for (const word of setA) {\n if (setB.has(word)) intersection++;\n }\n return intersection / (setA.size + setB.size - intersection);\n}\n"],"mappings":";;AAEA,MAAa,KAAK;CAChB,UAAU;CACV,eAAe,cAAsB,WAAW;CAChD,UAAU;CACV,WAAW;CACX,QAAQ;CACR,SAAS;CACT,QAAQ;CACR,aAAa,UAAkB,WAAW;CAC1C,WAAW;CACX,WAAW;CACX,UAAU;CACV,cAAc;CACd,YAAY;CACZ,YAAY;CAOZ,eAAe;CAaf,gBAAgB;CAChB,cAAc;CACd,iBAAiB;CACjB,UAAU;CACV,YAAY;CACZ,aAAa,WAAmB,YAAY,OAAO;CACnD,YAAY,QAAgB,WAC1B,YAAY,OAAO,SAAS;CAC9B,cAAc,WAAmB,YAAY,OAAO;CACpD,OAAO;CACP,SAAS;CACT,aAAa;CACb,QAAQ;CACR,UAAU;CACV,aAAa;CACb,SAAS;CACT,aAAa;CACb,MAAM;CACN,UAAU;CACV,QAAQ;CACR,WAAW;CACX,UAAU;CACV,SAAS;CACT,UAAU;CACV,kBAAkB;CAClB,iBAAiB,cAAsB,gBAAgB;CACvD,mBAAmB,UAAkB,cAAc;CACnD,iBAAiB;CACjB,WAAW;CACX,WAAW;CACX,iBAAiB;CACjB,OAAO;CACP,aAAa;CACb,OAAO;CACP,SAAS;CAGT,gBAAgB;CACjB;AAED,MAAa,SAAS;CACpB,MAAM;CACN,QAAQ,cAAsB;CAC9B,aAAa;CACd;AAED,SAAgB,WAAW,QAAwB;AAGjD,QAAO,GAAG,OAAO,GAFN,KAAK,KAAK,CAAC,SAAS,GAET,CAAC,GADV,OAAO,YAAY,CAAC,QAAQ,MAAM,GAAG,CAAC,MAAM,GAAG,GAC9B;;AAGhC,SAAgB,cAAc,QAAgB,SAAyB;AAErE,QAAO,GAAG,OAAO,GADJ,WAAW,SAAS,CAAC,OAAO,QAAQ,CAAC,OAAO,MACjC,CAAC,MAAM,GAAG,GAAG;;AAGvC,SAAgB,kBAAkB,GAAW,GAAmB;CAC9D,MAAM,OAAO,IAAI,IAAI,EAAE,MAAM,MAAM,CAAC,QAAQ,MAAM,EAAE,SAAS,EAAE,CAAC;CAChE,MAAM,OAAO,IAAI,IAAI,EAAE,MAAM,MAAM,CAAC,QAAQ,MAAM,EAAE,SAAS,EAAE,CAAC;AAChE,KAAI,KAAK,SAAS,KAAK,KAAK,SAAS,EAAG,QAAO;AAC/C,KAAI,KAAK,SAAS,KAAK,KAAK,SAAS,EAAG,QAAO;CAC/C,IAAI,eAAe;AACnB,MAAK,MAAM,QAAQ,KACjB,KAAI,KAAK,IAAI,KAAK,CAAE;AAEtB,QAAO,gBAAgB,KAAK,OAAO,KAAK,OAAO"}
|