@agentmemory/agentmemory 0.9.19 → 0.9.20
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/dist/cli.mjs +4 -4
- package/dist/cli.mjs.map +1 -1
- package/dist/index.mjs +3 -2
- package/dist/index.mjs.map +1 -1
- package/dist/{src-2wwYDPGA.mjs → src-DPSaLB5-.mjs} +3 -2
- package/dist/src-DPSaLB5-.mjs.map +1 -0
- package/dist/standalone.mjs +1 -1
- package/dist/standalone.mjs.map +1 -1
- package/package.json +1 -1
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/.codex-plugin/plugin.json +1 -1
- package/plugin/hooks/hooks.codex.json +0 -4
- package/dist/src-2wwYDPGA.mjs.map +0 -1
package/dist/cli.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.mjs","names":["backupsDir","entryMatches","adapter","adapter","adapter","adapter","DOCS","adapter","adapter","DOCS","adapter","claudeCode","codex","cursor","geminiCli","openclaw","hermes","pi","openhuman","__dirname","findEnvExample","fsConstants","PATH_DELIMITER"],"sources":["../src/state/schema.ts","../src/cli/doctor-diagnostics.ts","../src/cli/remove-plan.ts","../src/cli/splash.ts","../src/cli/preferences.ts","../src/cli/connect/util.ts","../src/cli/connect/claude-code.ts","../src/cli/connect/codex.ts","../src/cli/connect/json-mcp-adapter.ts","../src/cli/connect/cursor.ts","../src/cli/connect/gemini-cli.ts","../src/cli/connect/hermes.ts","../src/cli/connect/openclaw.ts","../src/cli/connect/openhuman.ts","../src/cli/connect/pi.ts","../src/cli/connect/index.ts","../src/cli/onboarding.ts","../src/logger.ts","../src/version.ts","../src/cli.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 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} 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","// Doctor v2 diagnostic catalog.\n//\n// Each entry is a self-describing diagnostic: a check function that returns\n// `{ ok, detail? }`, a human-readable message, an inline fix preview, and\n// an `apply` function that runs the fix. The list is exported as a pure\n// data structure so unit tests can assert on shape without bringing\n// @clack/prompts into the test harness.\n//\n// The runtime (src/cli.ts -> runDoctor) iterates the list, prompts the user\n// per check, and only re-runs the SAME diagnostic after a fix — never the\n// whole suite. Each fix returns `{ ok, message? }` so we can show a one-line\n// outcome before moving on.\n//\n// Doctor v2 surface:\n// agentmemory doctor # interactive: Fix/Skip/More/Quit per failed check\n// agentmemory doctor --all # apply every available fix without prompting (CI)\n// agentmemory doctor --dry-run # show what each fix WOULD do; execute nothing\n\nexport type DiagnosticStatus = {\n ok: boolean;\n /** Short status detail (one line). Shown alongside the check name. */\n detail?: string;\n};\n\nexport type DiagnosticFixResult = {\n ok: boolean;\n message?: string;\n};\n\nexport type DoctorContext = {\n /** Base URL for the running engine, e.g. http://localhost:3111 */\n baseUrl: string;\n /** Viewer URL, e.g. http://localhost:3113 */\n viewerUrl: string;\n /** Path to ~/.agentmemory/.env */\n envPath: string;\n /** Path to ~/.agentmemory/iii.pid */\n pidfilePath: string;\n /** Path to ~/.agentmemory/engine-state.json */\n enginePath: string;\n /** Pinned engine version (e.g. \"0.11.2\"). */\n pinnedVersion: string;\n};\n\nexport type Diagnostic = {\n /** Stable id. Used in --json and tests. */\n id: string;\n /** One-line problem statement shown to the user. */\n message: string;\n /** One-line description of WHAT the fix will do. Shown before the prompt. */\n fixPreview: string;\n /** Longer explanation shown when the user picks [?] More info. */\n moreInfo: string;\n /** Run the check; return ok=true if everything's fine, ok=false otherwise. */\n check: (ctx: DoctorContext) => Promise<DiagnosticStatus>;\n /** Apply the fix. Returns ok=true on success. */\n fix: (ctx: DoctorContext) => Promise<DiagnosticFixResult>;\n /** True when there's nothing to auto-fix (we only suggest). */\n manualOnly?: boolean;\n};\n\n// Diagnostic ids are stable for testing and machine-readable doctor output.\nexport const DIAGNOSTIC_IDS = [\n \"env-missing\",\n \"no-llm-provider-key\",\n \"engine-version-mismatch\",\n \"viewer-unreachable\",\n \"stale-pidfile\",\n \"env-placeholder-keys\",\n \"iii-on-path-not-local-bin\",\n] as const;\n\nexport type DiagnosticId = (typeof DIAGNOSTIC_IDS)[number];\n\n// Pure helpers (no I/O) — exported for direct unit testing.\n// ---------------------------------------------------------------------------\n\n/** Common placeholder values shipped in .env.example. */\nconst PLACEHOLDER_VALUES = new Set([\n \"\",\n \"your-key-here\",\n \"sk-ant-...\",\n \"sk-...\",\n \"changeme\",\n \"todo\",\n \"xxx\",\n]);\n\nconst PROVIDER_KEY_NAMES = [\n \"ANTHROPIC_API_KEY\",\n \"OPENAI_API_KEY\",\n \"GEMINI_API_KEY\",\n \"GOOGLE_API_KEY\",\n \"OPENROUTER_API_KEY\",\n \"MINIMAX_API_KEY\",\n] as const;\n\nexport function parseEnvFile(content: string): Record<string, string> {\n const out: Record<string, string> = {};\n for (const rawLine of content.split(/\\r?\\n/)) {\n const line = rawLine.trim();\n if (!line || line.startsWith(\"#\")) continue;\n const eq = line.indexOf(\"=\");\n if (eq < 0) continue;\n const key = line.slice(0, eq).trim();\n let value = line.slice(eq + 1).trim();\n // Strip surrounding quotes.\n if (\n (value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\n ) {\n value = value.slice(1, -1);\n }\n out[key] = value;\n }\n return out;\n}\n\n/** Returns the list of provider keys that look real (non-placeholder). */\nexport function realProviderKeys(env: Record<string, string>): string[] {\n return PROVIDER_KEY_NAMES.filter((k) => {\n const v = (env[k] ?? \"\").trim();\n if (!v) return false;\n if (PLACEHOLDER_VALUES.has(v.toLowerCase())) return false;\n // Reject values that are just dots/placeholders like \"xxxx-xxxx\".\n if (/^x+$/i.test(v.replace(/[-_]/g, \"\"))) return false;\n return true;\n });\n}\n\n/** Returns the list of provider key NAMES that exist but are placeholders. */\nexport function placeholderProviderKeys(env: Record<string, string>): string[] {\n return PROVIDER_KEY_NAMES.filter((k) => {\n const v = (env[k] ?? \"\").trim();\n if (!v) return false;\n if (PLACEHOLDER_VALUES.has(v.toLowerCase())) return true;\n if (/^x+$/i.test(v.replace(/[-_]/g, \"\"))) return true;\n return false;\n });\n}\n\n/**\n * Build the canonical diagnostic catalog.\n *\n * The factory takes the side-effect helpers as injected functions so tests\n * can swap them with stubs. Production callers pass real implementations\n * from src/cli.ts.\n */\nexport type DoctorEffects = {\n /** Does ~/.agentmemory/.env exist? */\n envFileExists: () => boolean;\n /** Read ~/.agentmemory/.env and return parsed key=value pairs. */\n readEnvFile: () => Record<string, string>;\n /** Is the iii engine PID in the pidfile still alive? */\n pidfilePidIsAlive: () => boolean | null;\n /** Does the pidfile exist on disk? */\n pidfileExists: () => boolean;\n /** Resolve the iii binary on PATH; return null if not found. */\n findIiiBinary: () => string | null;\n /** Path to ~/.local/bin/iii (the location we install to). */\n localBinIiiPath: () => string;\n /** Run `iii --version`; null if it fails. */\n iiiBinaryVersion: (binPath: string) => string | null;\n /** Probe the viewer URL; true if it returns OK within timeoutMs. */\n viewerReachable: (timeoutMs?: number) => Promise<boolean>;\n /** Run init logic (copies .env.example). */\n runInit: () => Promise<DiagnosticFixResult>;\n /** Open a file in $EDITOR (or fallback). Resolves when editor exits. */\n openEditor: (path: string) => Promise<DiagnosticFixResult>;\n /** Run the iii installer. */\n runIiiInstaller: () => Promise<DiagnosticFixResult>;\n /** Stop the running engine cleanly. */\n runStop: () => Promise<DiagnosticFixResult>;\n /** Start the engine (waits for /livez). */\n runStart: () => Promise<DiagnosticFixResult>;\n /** Clear pidfile + engine-state. */\n clearEnginePidAndState: () => void;\n};\n\nexport function buildDiagnostics(effects: DoctorEffects): Diagnostic[] {\n return [\n {\n id: \"env-missing\",\n message: \"~/.agentmemory/.env is missing.\",\n fixPreview: \"Copy .env.example into ~/.agentmemory/.env (your keys file).\",\n moreInfo:\n \"agentmemory reads provider API keys (Anthropic, OpenAI, Gemini, …) from ~/.agentmemory/.env. \" +\n \"Without this file the daemon falls back to BM25-only search and no LLM-backed enrichment runs.\",\n check: async () => ({\n ok: effects.envFileExists(),\n detail: effects.envFileExists() ? undefined : \"no env file\",\n }),\n fix: () => effects.runInit(),\n },\n {\n id: \"no-llm-provider-key\",\n message: \"No LLM provider API key found in ~/.agentmemory/.env.\",\n fixPreview: \"Open ~/.agentmemory/.env in $EDITOR and paste your key, then re-check.\",\n moreInfo:\n \"Set at least one of: ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, \" +\n \"OPENROUTER_API_KEY, MINIMAX_API_KEY. The daemon picks the first that resolves \" +\n \"to a real (non-placeholder) value at startup.\",\n check: async () => {\n if (!effects.envFileExists()) {\n return { ok: false, detail: \"env file missing (run env-missing fix first)\" };\n }\n const env = effects.readEnvFile();\n const real = realProviderKeys(env);\n return {\n ok: real.length > 0,\n detail: real.length > 0 ? `found: ${real.join(\", \")}` : \"no provider key set\",\n };\n },\n fix: (ctx) => effects.openEditor(ctx.envPath),\n },\n {\n id: \"engine-version-mismatch\",\n message: \"iii binary on PATH doesn't match the version agentmemory pins to.\",\n fixPreview:\n \"Re-run the iii installer for the pinned version and restart the engine.\",\n moreInfo:\n \"agentmemory pins the iii engine to a specific release because newer engines \" +\n \"use a different worker model. Running a mismatched binary surfaces as EPIPE \" +\n \"reconnect loops and empty search results.\",\n check: async (ctx) => {\n const bin = effects.findIiiBinary();\n if (!bin) return { ok: false, detail: \"iii not on PATH\" };\n const v = effects.iiiBinaryVersion(bin);\n if (!v) return { ok: false, detail: \"iii on PATH but --version failed\" };\n return {\n ok: v === ctx.pinnedVersion,\n detail: `${v} (pinned ${ctx.pinnedVersion})`,\n };\n },\n fix: async () => {\n const r = await effects.runIiiInstaller();\n if (!r.ok) return r;\n // Best-effort restart: stop then start.\n await effects.runStop();\n return effects.runStart();\n },\n },\n {\n id: \"viewer-unreachable\",\n message: \"Viewer port not reachable.\",\n fixPreview: \"Stop the engine, restart it, and retry the viewer probe.\",\n moreInfo:\n \"The viewer is served on REST port + 2 (default 3113). If it never came up \" +\n \"the most common cause is port collision; a sibling PR ships auto-bump for \" +\n \"this case. If that lands first this check just verifies; otherwise restart \" +\n \"the engine to retry binding.\",\n check: async () => ({\n ok: await effects.viewerReachable(),\n detail: undefined,\n }),\n fix: async () => {\n const stopped = await effects.runStop();\n if (!stopped.ok) return stopped;\n return effects.runStart();\n },\n },\n {\n id: \"stale-pidfile\",\n message: \"Stale pidfile: pid recorded but the process is gone.\",\n fixPreview: \"Clear ~/.agentmemory/iii.pid + engine-state.json, then restart.\",\n moreInfo:\n \"When the engine crashes hard (kill -9, OOM, host reboot) the pidfile sticks \" +\n \"around. agentmemory refuses to start a second engine on top of a stale pid, \" +\n \"so this state must be cleared explicitly.\",\n check: async () => {\n if (!effects.pidfileExists()) return { ok: true, detail: \"no pidfile\" };\n const alive = effects.pidfilePidIsAlive();\n if (alive === null) return { ok: true, detail: \"pidfile unreadable\" };\n return {\n ok: alive,\n detail: alive ? \"pid is alive\" : \"pid is gone\",\n };\n },\n fix: async () => {\n effects.clearEnginePidAndState();\n return effects.runStart();\n },\n },\n {\n id: \"env-placeholder-keys\",\n message: \"~/.agentmemory/.env contains placeholder/empty API keys.\",\n fixPreview: \"Open ~/.agentmemory/.env in $EDITOR to paste real values.\",\n moreInfo:\n \"Lines like ANTHROPIC_API_KEY=sk-ant-... or =your-key-here are treated as \" +\n \"absent. The daemon will fall back to BM25-only search. Replace placeholders \" +\n \"with real keys or comment the line out.\",\n check: async () => {\n if (!effects.envFileExists()) {\n return { ok: true, detail: \"env file missing (handled by env-missing)\" };\n }\n const env = effects.readEnvFile();\n const placeholders = placeholderProviderKeys(env);\n return {\n ok: placeholders.length === 0,\n detail:\n placeholders.length === 0\n ? undefined\n : `placeholder: ${placeholders.join(\", \")}`,\n };\n },\n fix: (ctx) => effects.openEditor(ctx.envPath),\n },\n {\n id: \"iii-on-path-not-local-bin\",\n message:\n \"iii is on PATH but not in ~/.local/bin/iii (where we install).\",\n fixPreview:\n \"Suggest re-installing the pinned version via the installer — won't touch your PATH.\",\n moreInfo:\n \"agentmemory's installer writes to ~/.local/bin/iii. When a user-managed iii \" +\n \"lives somewhere else (homebrew, cargo, $XDG_BIN) we don't auto-overwrite it. \" +\n \"If you want our pinned build, run the installer; otherwise this is informational.\",\n manualOnly: true,\n check: async () => {\n const bin = effects.findIiiBinary();\n if (!bin) return { ok: true, detail: \"iii not on PATH (handled elsewhere)\" };\n const localBin = effects.localBinIiiPath();\n return {\n ok: bin === localBin,\n detail: bin === localBin ? undefined : `iii at: ${bin}`,\n };\n },\n fix: async () =>\n effects.runIiiInstaller().then((r) => ({\n ok: r.ok,\n message:\n r.message ??\n \"Installer wrote to ~/.local/bin/iii. Your PATH wasn't modified — adjust it yourself if needed.\",\n })),\n },\n ];\n}\n\nexport type DoctorRunMode = \"interactive\" | \"all\" | \"dry-run\";\n\n/**\n * Run all diagnostics and return their initial status (no fixes applied).\n * Useful for tests and for `--dry-run` mode.\n */\nexport async function runAllChecks(\n ctx: DoctorContext,\n diagnostics: Diagnostic[],\n): Promise<Array<{ diagnostic: Diagnostic; status: DiagnosticStatus }>> {\n const results: Array<{ diagnostic: Diagnostic; status: DiagnosticStatus }> = [];\n for (const d of diagnostics) {\n const status = await d.check(ctx);\n results.push({ diagnostic: d, status });\n }\n return results;\n}\n\n/**\n * Dry-run output: each failing check's fix preview, prefixed by the diagnostic\n * message. Pure function so we can snapshot-test the format.\n */\nexport function dryRunPlan(\n ctx: DoctorContext,\n results: Array<{ diagnostic: Diagnostic; status: DiagnosticStatus }>,\n): string[] {\n const lines: string[] = [];\n let n = 0;\n for (const { diagnostic, status } of results) {\n if (status.ok) continue;\n n++;\n lines.push(`${n}. [${diagnostic.id}] ${diagnostic.message}`);\n lines.push(` would fix: ${diagnostic.fixPreview}`);\n if (status.detail) lines.push(` detail: ${status.detail}`);\n }\n if (lines.length === 0) {\n lines.push(`All checks passing for ${ctx.baseUrl} — no fixes to run.`);\n }\n return lines;\n}\n","// `agentmemory remove` — destruction plan.\n//\n// Generating the plan is a pure function of the on-disk state (which files\n// exist, whether ~/.local/bin/iii matches the version we installed, the\n// connect-manifest contents). All side effects live in src/cli.ts; this\n// module owns only the planning logic so it's unit-testable without\n// touching $HOME.\n//\n// CLI surface:\n// agentmemory remove # interactive, double-confirms\n// agentmemory remove --force # skip confirmations\n// agentmemory remove --keep-data # remove binaries+symlinks, keep memory data\n\nimport { existsSync, statSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nexport type RemovePlanItem = {\n /** Stable id, used in tests and CLI output. */\n id: string;\n /** Human-readable description of the action. */\n description: string;\n /** Absolute path being acted on (or null for non-fs actions). */\n path: string | null;\n /** Whether this item is `ask-again` even with --force (e.g. memory data). */\n alwaysAsk: boolean;\n /** Whether the file actually exists / action is meaningful. Plan-time hint. */\n applicable: boolean;\n /** Bytes (for files) or -1 (unknown / dir). Pure metadata. */\n sizeBytes: number;\n};\n\nexport type RemoveOptions = {\n /** Skip confirmations (still asks separately about always-ask items). */\n force: boolean;\n /** Keep ~/.agentmemory/* user data; only remove binaries/symlinks. */\n keepData: boolean;\n};\n\nexport type RemoveContext = {\n /** $HOME (so tests can sandbox). */\n home: string;\n /** Pinned engine version we expect ~/.local/bin/iii to match. */\n pinnedVersion: string;\n /**\n * `iii --version` result for ~/.local/bin/iii, or null if it's missing /\n * unreadable / not executable. Passed in so the plan module stays pure.\n */\n localBinIiiVersion: string | null;\n /** Loaded connect manifest, or null if missing. */\n connectManifest: ConnectManifest | null;\n};\n\n/**\n * The `agentmemory connect` PR writes this manifest at\n * ~/.agentmemory/backups/connect-manifest.json. We tolerate it being absent\n * (older versions, fresh installs) by treating it as `{ installed: [] }`.\n */\nexport type ConnectManifest = {\n installed: Array<{\n /** Target path the connect command wrote (symlink or file). */\n target: string;\n /** Agent label, e.g. \"claude-code\", \"cursor\". */\n agent?: string;\n /** Whether this was a symlink (true) or copy (false). */\n symlink?: boolean;\n }>;\n};\n\nexport function pidfilePath(home: string): string {\n return join(home, \".agentmemory\", \"iii.pid\");\n}\n\nexport function enginePath(home: string): string {\n return join(home, \".agentmemory\", \"engine-state.json\");\n}\n\nexport function envPath(home: string): string {\n return join(home, \".agentmemory\", \".env\");\n}\n\nexport function preferencesPath(home: string): string {\n return join(home, \".agentmemory\", \"preferences.json\");\n}\n\nexport function backupsDir(home: string): string {\n return join(home, \".agentmemory\", \"backups\");\n}\n\nexport function dataDir(home: string): string {\n return join(home, \".agentmemory\", \"data\");\n}\n\nexport function localBinIii(home: string): string {\n return join(home, \".local\", \"bin\", \"iii\");\n}\n\nfunction safeSize(path: string): number {\n try {\n return statSync(path).size;\n } catch {\n return -1;\n }\n}\n\nfunction pathExists(path: string): boolean {\n try {\n return existsSync(path);\n } catch {\n return false;\n }\n}\n\n/**\n * Build the destruction plan for `agentmemory remove`.\n *\n * Plan items are returned regardless of whether `applicable` is true — the\n * caller can decide whether to skip-and-log or hide entirely. This keeps\n * the structure stable for tests.\n */\nexport function buildRemovePlan(\n ctx: RemoveContext,\n options: RemoveOptions,\n): RemovePlanItem[] {\n const { home, pinnedVersion, localBinIiiVersion, connectManifest } = ctx;\n const plan: RemovePlanItem[] = [];\n\n plan.push({\n id: \"stop-engine\",\n description: \"Stop running iii-engine (if any) cleanly\",\n path: null,\n alwaysAsk: false,\n applicable: pathExists(pidfilePath(home)) || pathExists(enginePath(home)),\n sizeBytes: -1,\n });\n\n plan.push({\n id: \"pidfile\",\n description: \"Delete pidfile\",\n path: pidfilePath(home),\n alwaysAsk: false,\n applicable: pathExists(pidfilePath(home)),\n sizeBytes: safeSize(pidfilePath(home)),\n });\n\n plan.push({\n id: \"engine-state\",\n description: \"Delete engine-state.json\",\n path: enginePath(home),\n alwaysAsk: false,\n applicable: pathExists(enginePath(home)),\n sizeBytes: safeSize(enginePath(home)),\n });\n\n // .env holds the user's API keys. Always ask before deleting, even on\n // --force. --keep-data keeps it as part of \"user data\".\n plan.push({\n id: \"env\",\n description: \"Delete .env (your API keys) — will ask separately\",\n path: envPath(home),\n alwaysAsk: true,\n applicable: !options.keepData && pathExists(envPath(home)),\n sizeBytes: safeSize(envPath(home)),\n });\n\n plan.push({\n id: \"preferences\",\n description: \"Delete preferences.json\",\n path: preferencesPath(home),\n alwaysAsk: false,\n applicable: !options.keepData && pathExists(preferencesPath(home)),\n sizeBytes: safeSize(preferencesPath(home)),\n });\n\n plan.push({\n id: \"backups\",\n description: \"Delete backups/ directory (connect manifest + backups)\",\n path: backupsDir(home),\n alwaysAsk: false,\n applicable: !options.keepData && pathExists(backupsDir(home)),\n sizeBytes: -1,\n });\n\n // Iterate over connect-installed agent symlinks. We always honor these\n // (even with --keep-data, since they're outside ~/.agentmemory/).\n if (connectManifest?.installed?.length) {\n for (const entry of connectManifest.installed) {\n plan.push({\n id: `connect:${entry.target}`,\n description: `Remove agent connection (${entry.agent ?? \"unknown\"})`,\n path: entry.target,\n alwaysAsk: false,\n applicable: pathExists(entry.target),\n sizeBytes: safeSize(entry.target),\n });\n }\n }\n\n // ~/.local/bin/iii — only remove if it matches the version we installed.\n // Heuristic: spawn `iii --version`; if it returns pinnedVersion, safe to\n // remove. Otherwise mark `alwaysAsk` so the operator confirms explicitly.\n const localIii = localBinIii(home);\n if (pathExists(localIii)) {\n const matches = localBinIiiVersion === pinnedVersion;\n plan.push({\n id: \"local-bin-iii\",\n description: matches\n ? `Delete ~/.local/bin/iii (matches pinned v${pinnedVersion})`\n : `Delete ~/.local/bin/iii (version ${localBinIiiVersion ?? \"unknown\"} != pinned v${pinnedVersion}) — will ask`,\n path: localIii,\n alwaysAsk: !matches,\n applicable: true,\n sizeBytes: safeSize(localIii),\n });\n }\n\n // Memory data dir — ALWAYS asks separately, even with --force. Default\n // behavior is keep.\n plan.push({\n id: \"data-dir\",\n description:\n \"Delete memory data directory (~/.agentmemory/data/) — will ask separately\",\n path: dataDir(home),\n alwaysAsk: true,\n applicable: !options.keepData && pathExists(dataDir(home)),\n sizeBytes: -1,\n });\n\n return plan;\n}\n\n/** Format a plan for the user — one line per item. */\nexport function formatPlan(plan: RemovePlanItem[]): string {\n return plan\n .filter((p) => p.applicable)\n .map((p, i) => {\n const tag = p.alwaysAsk ? \" [asks]\" : \"\";\n const sz =\n p.sizeBytes > 0 ? ` (${humanBytes(p.sizeBytes)})` : \"\";\n return ` ${i + 1}. ${p.description}${tag}${sz}${p.path ? `\\n ${p.path}` : \"\"}`;\n })\n .join(\"\\n\");\n}\n\nfunction humanBytes(n: number): string {\n if (n < 1024) return `${n} B`;\n if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;\n return `${(n / (1024 * 1024)).toFixed(1)} MB`;\n}\n","// Terminal-width-aware splash banner for the agentmemory CLI.\n//\n// Three render tiers, picked from `process.stdout.columns`:\n//\n// >= 120 cols: full block-art logo + tagline.\n// 80–119 cols: compact monospace title + tagline.\n// < 80 cols: single-line `agentmemory v<VERSION>`.\n//\n// The brand accent is the orange `#FF6B35` we already use in the README\n// and viewer; we render it through ANSI 38;5;208 (the closest xterm-256\n// match) when stdout is a TTY, and fall back to plain text otherwise.\n// No colour bytes are hard-coded into the strings themselves so that\n// piping the banner to a file (`agentmemory > log`) stays clean.\n//\n// We don't pull in chalk/picocolors — picocolors is a transitive dep but\n// we never want to depend on transitives directly. The two ANSI escape\n// helpers below are the entire colour surface and they degrade to\n// no-ops automatically.\n\nconst IS_COLOR_TTY = !!process.stdout.isTTY && !process.env[\"NO_COLOR\"];\n\nfunction accent(s: string): string {\n // 256-colour orange that visually matches #FF6B35 in most modern\n // terminal palettes. We pick 208 (a true orange) over the closer-but-\n // pinker 209 because it reads as the brand colour on both dark and\n // light backgrounds.\n return IS_COLOR_TTY ? `\\x1b[38;5;208m${s}\\x1b[0m` : s;\n}\n\nfunction dim(s: string): string {\n return IS_COLOR_TTY ? `\\x1b[2m${s}\\x1b[22m` : s;\n}\n\nfunction bold(s: string): string {\n return IS_COLOR_TTY ? `\\x1b[1m${s}\\x1b[22m` : s;\n}\n\nfunction getTerminalWidth(): number {\n const w = process.stdout.columns;\n return typeof w === \"number\" && w > 0 ? w : 80;\n}\n\nconst TAGLINE = \"Persistent memory for AI coding agents\";\n\n// \"agentmemory\" rendered in figlet's standard font (verified output —\n// regenerate via `figlet agentmemory` if you change the wordmark). Each\n// row is exactly 70 columns wide so the banner aligns cleanly inside\n// the 2-col left margin we add below.\nfunction fullBanner(version: string): string {\n const logo = [\n \" _ \",\n \" __ _ __ _ ___ _ __ | |_ _ __ ___ ___ _ __ ___ ___ _ __ _ _ \",\n \" / _` |/ _` |/ _ \\\\ '_ \\\\| __| '_ ` _ \\\\ / _ \\\\ '_ ` _ \\\\ / _ \\\\| '__| | | |\",\n \"| (_| | (_| | __/ | | | |_| | | | | | __/ | | | | | (_) | | | |_| |\",\n \" \\\\__,_|\\\\__, |\\\\___|_| |_|\\\\__|_| |_| |_|\\\\___|_| |_| |_|\\\\___/|_| \\\\__, |\",\n \" |___/ |___/ \",\n ];\n const lines: string[] = [\"\", ...logo.map((line) => \" \" + accent(line))];\n lines.push(\"\");\n lines.push(\" \" + bold(TAGLINE) + \" \" + dim(`v${version}`));\n lines.push(\"\");\n return lines.join(\"\\n\");\n}\n\nfunction compactBanner(version: string): string {\n const title = \" \" + bold(accent(\"agentmemory\"));\n const meta = \" \" + dim(`v${version} · ${TAGLINE}`);\n return [\"\", title, meta, \"\"].join(\"\\n\");\n}\n\nfunction minimalBanner(version: string): string {\n return `${accent(\"agentmemory\")} ${dim(`v${version}`)}`;\n}\n\nexport function renderSplash(version: string): void {\n const width = getTerminalWidth();\n let out: string;\n if (width >= 120) {\n out = fullBanner(version);\n } else if (width >= 80) {\n out = compactBanner(version);\n } else {\n out = minimalBanner(version);\n }\n process.stdout.write(out + \"\\n\");\n}\n","// JSON-backed CLI preferences.\n//\n// Lives at `~/.agentmemory/preferences.json`. The agentmemory daemon\n// already owns `~/.agentmemory/.env`, `iii.pid`, `engine-state.json` —\n// adding one more sibling here keeps the install-state surface in one\n// place.\n//\n// All functions are synchronous, mirroring the pidfile / engine-state\n// helpers in src/cli.ts. We never throw: read failures collapse to\n// defaults; write failures swallow silently. Preferences are a UX\n// nicety, not data — corrupting `iii.pid` matters, corrupting this\n// file does not.\n//\n// Writes are atomic via tmp + rename so a Ctrl+C between the open and\n// the final write can't leave a half-written JSON blob on disk that\n// the next read would refuse to parse.\n\nimport {\n closeSync,\n existsSync,\n fsyncSync,\n mkdirSync,\n openSync,\n readFileSync,\n renameSync,\n unlinkSync,\n writeSync,\n} from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nexport interface Prefs {\n schemaVersion: 1;\n // Most recently picked single agent (for \"use last agent\" style flows).\n lastAgent: string | null;\n // The full multi-select set from the last onboarding run.\n lastAgents: string[];\n // Most recently picked LLM provider; `null` means BM25-only mode.\n lastProvider: string | null;\n // Once true, splash is rendered only on first run / explicit --reset.\n // The first onboarding sets this to true so the second invocation\n // skips the banner.\n skipSplash: boolean;\n // Reserved for a later \"do not nag me about the npx vs install\n // tradeoff\" toggle. Kept on the schema so we don't have to bump\n // schemaVersion when we ship the flag.\n skipNpxHint: boolean;\n // Set to true when the user declines the \"install agentmemory\n // globally?\" prompt on first npx run. We never ask again on this\n // machine so the prompt stays a one-time DX nudge, not a nag.\n skipGlobalInstall: boolean;\n // Set to true when the user declines the \"install iii console?\"\n // prompt. iii console is first-class engine UI but optional at the\n // install step — once the user says no, we stop asking.\n skipConsoleInstall: boolean;\n // ISO timestamp of the first time onboarding completed. Set once,\n // never updated, so we can show \"you joined agentmemory N days ago\"\n // copy in /status later without keeping a separate file.\n firstRunAt: string | null;\n}\n\nconst DEFAULTS: Prefs = {\n schemaVersion: 1,\n lastAgent: null,\n lastAgents: [],\n lastProvider: null,\n skipSplash: false,\n skipNpxHint: false,\n skipGlobalInstall: false,\n skipConsoleInstall: false,\n firstRunAt: null,\n};\n\nexport function prefsDir(): string {\n return join(homedir(), \".agentmemory\");\n}\n\nexport function prefsPath(): string {\n return join(prefsDir(), \"preferences.json\");\n}\n\nexport function readPrefs(): Prefs {\n try {\n if (!existsSync(prefsPath())) return { ...DEFAULTS };\n const raw = readFileSync(prefsPath(), \"utf-8\");\n const parsed = JSON.parse(raw) as Partial<Prefs>;\n return { ...DEFAULTS, ...parsed, schemaVersion: 1 };\n } catch {\n return { ...DEFAULTS };\n }\n}\n\nexport function writePrefs(p: Partial<Prefs>): void {\n try {\n const dir = prefsDir();\n mkdirSync(dir, { recursive: true });\n const current = readPrefs();\n const next: Prefs = { ...current, ...p, schemaVersion: 1 };\n const target = prefsPath();\n const tmp = target + \".tmp\";\n // Open + write + fsync + rename ensures a Ctrl+C between any two\n // syscalls either leaves the old file intact (rename is atomic on\n // POSIX) or leaves only a .tmp behind that the next writePrefs\n // overwrites. We never end up with a truncated `preferences.json`\n // that readPrefs would have to discard.\n const fd = openSync(tmp, \"w\", 0o600);\n try {\n writeSync(fd, JSON.stringify(next, null, 2) + \"\\n\");\n try {\n fsyncSync(fd);\n } catch {\n // fsync isn't available on every filesystem (e.g. some Docker\n // overlays). The rename below is still atomic; we just can't\n // guarantee durability against a power loss.\n }\n } finally {\n closeSync(fd);\n }\n renameSync(tmp, target);\n } catch {\n // Preferences are best-effort. Don't crash the CLI for them.\n }\n}\n\nexport function resetPrefs(): void {\n try {\n unlinkSync(prefsPath());\n } catch {\n // Already gone — that's exactly the state we wanted.\n }\n}\n\nexport function isFirstRun(): boolean {\n // \"First run\" means: the preferences file doesn't exist OR exists\n // but `firstRunAt` was never recorded. The latter handles users who\n // had `.agentmemory/preferences.json` from a much older agentmemory\n // build that wrote a different schema — we treat them as new.\n if (!existsSync(prefsPath())) return true;\n return readPrefs().firstRunAt === null;\n}\n","import {\n existsSync,\n mkdirSync,\n readFileSync,\n writeFileSync,\n copyFileSync,\n renameSync,\n} from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport * as p from \"@clack/prompts\";\n\n// Env values use ${VAR} expansion so the wired MCP entry inherits\n// AGENTMEMORY_URL / AGENTMEMORY_SECRET from the user's shell. When the\n// vars are unset, the host (Claude Code, Cursor, etc.) substitutes an\n// empty string; the standalone shim treats empty as missing and falls\n// back to http://localhost:3111. This lets a single wired entry serve\n// both local and remote (Kubernetes / reverse-proxied) deployments\n// without doctor-warning duplicates (#375).\nexport const AGENTMEMORY_MCP_BLOCK = {\n command: \"npx\",\n args: [\"-y\", \"@agentmemory/mcp\"],\n env: {\n AGENTMEMORY_URL: \"${AGENTMEMORY_URL}\",\n AGENTMEMORY_SECRET: \"${AGENTMEMORY_SECRET}\",\n },\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, 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\";\n\nconst CLAUDE_DIR = join(homedir(), \".claude\");\nconst CLAUDE_JSON = join(homedir(), \".claude.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 docs: \"https://github.com/rohitg00/agentmemory#claude-code-one-block-paste-it\",\n protocolNote:\n \"→ Using MCP. Hooks are also available — see docs/claude-code.md.\",\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 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 return { kind: \"installed\", mutatedPath: CLAUDE_JSON, backupPath };\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} from \"./util.js\";\n\nconst CODEX_DIR = join(homedir(), \".codex\");\nconst CODEX_TOML = join(CODEX_DIR, \"config.toml\");\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 docs: \"https://github.com/rohitg00/agentmemory#codex-cli-codex-plugin-platform\",\n protocolNote:\n \"→ Using MCP. Hooks are also available — see docs/codex.md.\",\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 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 install agentmemory\",\n );\n return {\n kind: \"installed\",\n mutatedPath: CODEX_TOML,\n ...(backupPath !== undefined && { backupPath }),\n };\n },\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};\n\ntype McpEntry = typeof AGENTMEMORY_MCP_BLOCK;\ntype McpConfig = {\n mcpServers?: Record<string, McpEntry>;\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 function createJsonMcpAdapter(\n config: JsonMcpAdapterConfig,\n): ConnectAdapter {\n return {\n name: config.name,\n displayName: config.displayName,\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.mcpServers 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\"} mcpServers.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\"] = AGENTMEMORY_MCP_BLOCK;\n next.mcpServers = servers;\n writeJsonAtomic(config.configPath, next);\n\n const verify = readJsonSafe<McpConfig>(config.configPath);\n if (!entryMatches(verify?.mcpServers?.[\"agentmemory\"])) {\n p.log.error(\n `Verification failed: ${config.configPath} did not contain mcpServers.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 } 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\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 docs: DOCS,\n protocolNote:\n \"→ Using MCP. Hooks are also available — see docs/hermes.md.\",\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\nexport const adapter = createJsonMcpAdapter({\n name: \"openclaw\",\n displayName: \"OpenClaw\",\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 docs/openclaw.md.\",\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 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 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 { platform } from \"node:os\";\nimport * as p from \"@clack/prompts\";\nimport type { ConnectAdapter, ConnectOptions, ConnectResult } from \"./types.js\";\nimport { adapter as claudeCode } from \"./claude-code.js\";\nimport { adapter as codex } from \"./codex.js\";\nimport { adapter as cursor } from \"./cursor.js\";\nimport { adapter as geminiCli } from \"./gemini-cli.js\";\nimport { adapter as hermes } from \"./hermes.js\";\nimport { adapter as openclaw } from \"./openclaw.js\";\nimport { adapter as openhuman } from \"./openhuman.js\";\nimport { adapter as pi } from \"./pi.js\";\n\nexport const ADAPTERS: readonly ConnectAdapter[] = [\n claudeCode,\n codex,\n cursor,\n geminiCli,\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 positional: string[];\n} {\n const positional: string[] = [];\n let dryRun = false;\n let force = false;\n let all = 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.startsWith(\"-\")) positional.push(a);\n }\n return { dryRun, force, all, 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 if (platform() === \"win32\") {\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 { dryRun, force, all, positional } = parseFlags(args);\n const opts: ConnectOptions = { dryRun, force };\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 ` ✓ ${name}${result.mutatedPath ? ` → ${result.mutatedPath}` : \"\"}`;\n case \"already-wired\":\n return ` ✓ ${name} (already wired)`;\n case \"stub\":\n return ` ⚠ ${name} (manual install required: ${result.reason})`;\n case \"skipped\":\n return ` ✗ ${name} (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 p.outro(\"Restart any wired agent (or open a new session) to pick up agentmemory.\");\n}\n","// First-run interactive onboarding flow.\n//\n// Wakes up only when `isFirstRun()` is true (preferences are missing or\n// have never recorded a `firstRunAt`) or when the user passes\n// `--reset`. The flow asks for:\n//\n// 1. Which agents will be wired to agentmemory (multi-select). Each\n// option carries a small glyph that we reuse in /status output so\n// the user recognises them later. The label mirrors README row 1\n// (native plugins) and row 2 (MCP-only).\n// 2. Which LLM provider to use for compress / consolidate / graph.\n// \"skip — BM25-only mode\" is a real first-class option; lots of\n// users want agentmemory purely as a hybrid keyword + vector\n// memory layer without granting LLM API keys.\n//\n// We then write `~/.agentmemory/preferences.json` and seed\n// `~/.agentmemory/.env` with a commented-out `*_API_KEY=` line for the\n// chosen provider. This matches the existing `agentmemory init` flow\n// closely so users who skip onboarding still get the same file via\n// `agentmemory init`.\n\nimport { copyFile, mkdir } from \"node:fs/promises\";\nimport { constants as fsConstants, existsSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport * as p from \"@clack/prompts\";\nimport { writePrefs } from \"./preferences.js\";\nimport { resolveAdapter, runAdapter } from \"./connect/index.js\";\nimport type { ConnectResult } from \"./connect/types.js\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\n// Native plugin row — these agents ship an agentmemory plugin or\n// first-party integration. Glyphs match SkillKit's published set\n// where they overlap; the rest fall back to the generic `◇`.\nconst NATIVE_AGENTS: { value: string; label: string; glyph: string }[] = [\n { value: \"claude-code\", label: \"Claude Code\", glyph: \"⟁\" },\n { value: \"codex\", label: \"Codex\", glyph: \"◎\" },\n { value: \"openhuman\", label: \"OpenHuman\", glyph: \"◇\" },\n { value: \"openclaw\", label: \"OpenClaw\", glyph: \"◇\" },\n { value: \"hermes\", label: \"Hermes\", glyph: \"◇\" },\n { value: \"pi\", label: \"Pi\", glyph: \"◇\" },\n { value: \"cursor\", label: \"Cursor\", glyph: \"◫\" },\n { value: \"gemini-cli\", label: \"Gemini CLI\", glyph: \"✦\" },\n];\n\n// MCP-only row — these agents use the MCP server we ship rather than\n// a native plugin.\nconst MCP_AGENTS: { value: string; label: string; glyph: string }[] = [\n { value: \"opencode\", label: \"OpenCode\", glyph: \"⬡\" },\n { value: \"cline\", label: \"Cline\", glyph: \"◇\" },\n { value: \"goose\", label: \"Goose\", glyph: \"◇\" },\n { value: \"kilo\", label: \"Kilo\", glyph: \"◇\" },\n { value: \"aider\", label: \"Aider\", glyph: \"◇\" },\n { value: \"claude-desktop\", label: \"Claude Desktop\", glyph: \"⟁\" },\n { value: \"windsurf\", label: \"Windsurf\", glyph: \"◇\" },\n { value: \"roo\", label: \"Roo\", glyph: \"◇\" },\n];\n\nconst PROVIDERS: { value: string; label: string; envKey: string | null }[] = [\n { value: \"anthropic\", label: \"Anthropic — claude\", envKey: \"ANTHROPIC_API_KEY\" },\n { value: \"openai\", label: \"OpenAI — gpt\", envKey: \"OPENAI_API_KEY\" },\n { value: \"gemini\", label: \"Google — gemini\", envKey: \"GEMINI_API_KEY\" },\n { value: \"openrouter\", label: \"OpenRouter — multi-model\", envKey: \"OPENROUTER_API_KEY\" },\n { value: \"minimax\", label: \"MiniMax — minimax-m1\", envKey: \"MINIMAX_API_KEY\" },\n { value: \"skip\", label: \"Skip — BM25-only mode (no LLM key)\", envKey: null },\n];\n\nfunction buildAgentOptions(): { value: string; label: string; hint?: string }[] {\n return [\n ...NATIVE_AGENTS.map((a) => ({\n value: a.value,\n label: `${a.glyph} ${a.label}`,\n hint: \"native plugin\",\n })),\n ...MCP_AGENTS.map((a) => ({\n value: a.value,\n label: `${a.glyph} ${a.label}`,\n hint: \"MCP server\",\n })),\n ];\n}\n\n// Mirror src/cli.ts findEnvExample so onboarding ships the same .env\n// skeleton whether called directly or via `agentmemory init`. We\n// duplicate (rather than import) so the onboarding module doesn't\n// pull cli.ts's top-level side effects into the test runner.\nfunction findEnvExample(): string | null {\n const candidates = [\n join(__dirname, \"..\", \"..\", \".env.example\"),\n join(__dirname, \"..\", \".env.example\"),\n join(__dirname, \".env.example\"),\n join(process.cwd(), \".env.example\"),\n ];\n for (const c of candidates) {\n if (existsSync(c)) return c;\n }\n return null;\n}\n\nasync function seedEnvFile(provider: string | null): Promise<string | null> {\n const target = join(homedir(), \".agentmemory\", \".env\");\n const dir = dirname(target);\n await mkdir(dir, { recursive: true });\n\n const template = findEnvExample();\n if (template && !existsSync(target)) {\n try {\n await copyFile(template, target, fsConstants.COPYFILE_EXCL);\n } catch (err) {\n if ((err as NodeJS.ErrnoException)?.code !== \"EEXIST\") {\n return null;\n }\n }\n } else if (!template && !existsSync(target)) {\n // Fall back to a minimal skeleton so users always get a `.env` to\n // edit. This matches the shape of the bundled `.env.example`\n // without forcing us to keep two copies in sync.\n const lines = [\n \"# agentmemory environment — uncomment what you need\",\n \"# AGENTMEMORY_URL=http://localhost:3111\",\n \"\",\n ];\n const envKey = PROVIDERS.find((x) => x.value === provider)?.envKey;\n if (envKey) {\n lines.push(`# ${envKey}=`);\n }\n writeFileSync(target, lines.join(\"\\n\"), { mode: 0o600 });\n }\n\n return target;\n}\n\nexport interface OnboardingResult {\n agents: string[];\n provider: string | null;\n}\n\nexport async function runOnboarding(): Promise<OnboardingResult> {\n p.note(\n [\n \"Welcome to agentmemory.\",\n \"\",\n \"Persistent memory for your AI coding agents. We'll pick which\",\n \"agents to wire up and which provider (if any) handles compression\",\n \"and consolidation. Either step can be changed later in ~/.agentmemory/.env.\",\n ].join(\"\\n\"),\n \"first-run setup\",\n );\n\n const agentsPicked = await p.multiselect<string>({\n message: \"Which agents will use agentmemory? (space to toggle, enter to confirm)\",\n options: buildAgentOptions(),\n required: false,\n initialValues: [\"claude-code\"],\n });\n if (p.isCancel(agentsPicked)) {\n p.cancel(\"Setup cancelled. Re-run any time with: agentmemory --reset\");\n process.exit(0);\n }\n\n const pickedAgentsList = (agentsPicked as string[]) ?? [];\n if (pickedAgentsList.length > 0) {\n p.note(\n [\n \"━ how this works ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\",\n \"All selected agents share the same memory at :3111.\",\n \"A memory saved by Claude Code is visible to Codex + Cursor instantly.\",\n \"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\",\n ].join(\"\\n\"),\n );\n }\n\n const providerPicked = await p.select<string>({\n message: \"Which LLM provider should agentmemory use for compress/consolidate?\",\n options: PROVIDERS.map(({ value, label }) => ({ value, label })),\n initialValue: \"anthropic\",\n });\n if (p.isCancel(providerPicked)) {\n p.cancel(\"Setup cancelled. Re-run any time with: agentmemory --reset\");\n process.exit(0);\n }\n\n const provider = providerPicked === \"skip\" ? null : providerPicked;\n const agents = (agentsPicked as string[]) ?? [];\n\n const envPath = await seedEnvFile(provider);\n\n writePrefs({\n lastAgent: agents[0] ?? null,\n lastAgents: agents,\n lastProvider: provider,\n skipSplash: true,\n firstRunAt: new Date().toISOString(),\n });\n\n const prefsLocation = join(homedir(), \".agentmemory\", \"preferences.json\");\n const lines = [`✓ Saved preferences to ${prefsLocation}`];\n if (envPath) {\n lines.push(`✓ Wrote ${envPath} (edit to add your API key)`);\n } else {\n lines.push(`! Could not write ~/.agentmemory/.env — run \\`agentmemory init\\` after this completes.`);\n }\n if (provider) {\n const envKey = PROVIDERS.find((x) => x.value === provider)?.envKey;\n if (envKey) {\n lines.push(` Uncomment ${envKey}= in that file to enable ${provider}.`);\n }\n } else {\n lines.push(\" No provider chosen — agentmemory will run in BM25-only mode.\");\n }\n p.note(lines.join(\"\\n\"), \"ready\");\n\n if (agents.length > 0) {\n await wireSelectedAgents(agents);\n }\n\n return { agents, provider };\n}\n\nasync function wireSelectedAgents(agents: string[]): Promise<void> {\n p.note(\"Wire selected agents now?\", \"next step\");\n const confirmed = await p.confirm({\n message: \"Run `agentmemory connect <agent>` for each selected agent now? [Y/n]\",\n initialValue: true,\n });\n\n if (p.isCancel(confirmed) || confirmed === false) {\n const cmds = agents.map((a) => ` agentmemory connect ${a}`);\n p.note([\"Wire later with:\", ...cmds].join(\"\\n\"), \"later\");\n return;\n }\n\n const wired: string[] = [];\n const manual: { name: string; docs?: string }[] = [];\n const failed: { name: string; reason: string }[] = [];\n\n for (const name of agents) {\n const adapter = resolveAdapter(name);\n if (!adapter) {\n failed.push({ name, reason: \"no adapter available\" });\n p.log.warn(`Wiring ${name}… no adapter available (skipped).`);\n continue;\n }\n p.log.step(`Wiring ${name}...`);\n let result: ConnectResult;\n try {\n result = await runAdapter(adapter, { dryRun: false, force: false });\n } catch (err) {\n const reason = err instanceof Error ? err.message : String(err);\n failed.push({ name, reason });\n p.log.error(`${name}: ${reason}`);\n continue;\n }\n switch (result.kind) {\n case \"installed\":\n case \"already-wired\":\n wired.push(name);\n break;\n case \"stub\":\n manual.push({ name, docs: adapter.docs });\n break;\n case \"skipped\":\n failed.push({ name, reason: result.reason });\n break;\n }\n }\n\n const summary: string[] = [];\n if (wired.length > 0) {\n summary.push(`Wired: ${wired.join(\", \")}.`);\n }\n if (manual.length > 0 || failed.length > 0) {\n const parts: string[] = [];\n for (const m of manual) {\n parts.push(`${m.name} (manual install required${m.docs ? ` — see ${m.docs}` : \"\"})`);\n }\n for (const f of failed) {\n parts.push(`${f.name} (${f.reason})`);\n }\n summary.push(`Skipped/failed: ${parts.join(\", \")}.`);\n }\n if (summary.length === 0) {\n summary.push(\"No agents were wired.\");\n }\n p.note(summary.join(\"\\n\"), \"wire summary\");\n}\n","// Thin logging shim for agentmemory.\n//\n// iii-sdk v0.11 dropped `getContext()`, which had been the source of a\n// contextual logger in every function handler (`getContext().logger`).\n// Migrating directly to the v0.11 OTEL-based `getLogger()` would force\n// every call site to care about the OTEL Logger API shape (`emit(...)`\n// with severity numbers and attributes maps). Instead, this module\n// exposes a single `logger` singleton with the same `.info/.warn/.error`\n// signature the old code used, so the mechanical replacement across\n// 30+ function files is: drop the `getContext` import, drop the\n// `const ctx = getContext();` line, and rename `ctx.logger.*` to\n// `logger.*`. Nothing else changes.\n//\n// Output goes to stderr as `[agentmemory] <level> <msg> <json-fields>`.\n// The iii-engine's `iii-exec` worker runs the agentmemory binary as a\n// child process and forwards stderr into `docker logs\n// agentmemory-iii-engine-1`, so these lines end up next to the engine's\n// own output without needing any OTEL wiring. If we later want\n// structured OTEL logs, this file is the only thing that changes.\n//\n// See rohitg00/agentmemory#143 follow-up — the #116 migration updated\n// test mocks but left the real `getContext()` imports in place, which\n// passed `npm test` (tests mock iii-sdk) and `npm run build` (tsdown\n// doesn't type-check) but crashed `node dist/index.mjs` on first\n// import.\n\ntype Fields = Record<string, unknown> | undefined;\n\nfunction fmt(level: string, msg: string, fields: Fields): string {\n if (!fields || Object.keys(fields).length === 0) {\n return `[agentmemory] ${level} ${msg}`;\n }\n try {\n return `[agentmemory] ${level} ${msg} ${JSON.stringify(fields)}`;\n } catch {\n // Fields contained a circular reference or a BigInt — fall back\n // to the plain message so a log line never throws.\n return `[agentmemory] ${level} ${msg}`;\n }\n}\n\nfunction emit(level: string, msg: string, fields: Fields): void {\n try {\n process.stderr.write(fmt(level, msg, fields) + \"\\n\");\n } catch {\n // stderr is unavailable in some weird test/worker contexts — swallow\n // so no log line can ever crash a handler.\n }\n}\n\nexport const logger = {\n info(msg: string, fields?: Fields): void {\n emit(\"info\", msg, fields);\n },\n warn(msg: string, fields?: Fields): void {\n emit(\"warn\", msg, fields);\n },\n error(msg: string, fields?: Fields): void {\n emit(\"error\", msg, fields);\n },\n};\n\n// ---------- boot log ----------\n//\n// `bootLog` is for the one-shot status lines that every register-*\n// function used to dump via `console.log` during engine startup. On a\n// fresh install that's ~25 lines of `[agentmemory] X enabled` noise\n// before the user can see a prompt. In quiet mode (default), each\n// line is captured into a buffer and discarded; the CLI surfaces a\n// single compressed summary instead. In verbose mode (set by\n// `--verbose` or `AGENTMEMORY_VERBOSE=1`) the lines pass straight\n// through to stderr exactly like the old console.log calls.\n\nlet bootVerbose =\n process.env[\"AGENTMEMORY_VERBOSE\"] === \"1\" ||\n process.env[\"AGENTMEMORY_VERBOSE\"] === \"true\";\n\nconst bootBuffer: string[] = [];\n\nexport function setBootVerbose(enabled: boolean): void {\n bootVerbose = enabled;\n}\n\nexport function isBootVerbose(): boolean {\n return bootVerbose;\n}\n\nexport function bootLog(msg: string): void {\n if (bootVerbose) {\n try {\n process.stderr.write(`[agentmemory] ${msg}\\n`);\n } catch {\n // stderr unavailable — drop.\n }\n return;\n }\n if (bootBuffer.length < 500) bootBuffer.push(msg);\n}\n\nexport function bootWarn(msg: string): void {\n // Warnings always surface; they're rare and the user needs to see\n // them even when the rest of the boot log is suppressed.\n try {\n process.stderr.write(`[agentmemory] warn ${msg}\\n`);\n } catch {}\n}\n\nexport function getBootBuffer(): readonly string[] {\n return bootBuffer;\n}\n","export const VERSION = \"0.9.19\";\n","#!/usr/bin/env node\n\nimport {\n spawn,\n execFileSync,\n spawnSync,\n type ChildProcess,\n} from \"node:child_process\";\nimport {\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n readlinkSync,\n rmSync,\n statSync,\n unlinkSync,\n writeFileSync,\n} from \"node:fs\";\nimport { join, dirname, delimiter as PATH_DELIMITER } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { homedir, platform } from \"node:os\";\nimport * as p from \"@clack/prompts\";\nimport { generateId } from \"./state/schema.js\";\nimport {\n buildDiagnostics,\n dryRunPlan,\n parseEnvFile,\n type Diagnostic,\n type DiagnosticFixResult,\n type DoctorContext,\n type DoctorEffects,\n} from \"./cli/doctor-diagnostics.js\";\nimport {\n buildRemovePlan,\n formatPlan,\n localBinIii,\n type ConnectManifest,\n type RemoveOptions,\n} from \"./cli/remove-plan.js\";\nimport { renderSplash } from \"./cli/splash.js\";\nimport { isFirstRun, readPrefs, resetPrefs, writePrefs } from \"./cli/preferences.js\";\nimport { runOnboarding } from \"./cli/onboarding.js\";\nimport { setBootVerbose } from \"./logger.js\";\nimport { VERSION } from \"./version.js\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst args = process.argv.slice(2);\nconst IS_WINDOWS = platform() === \"win32\";\nconst IS_VERBOSE =\n args.includes(\"--verbose\") ||\n args.includes(\"-v\") ||\n process.env[\"AGENTMEMORY_VERBOSE\"] === \"1\" ||\n process.env[\"AGENTMEMORY_VERBOSE\"] === \"true\";\n\n// Propagate the resolved verbosity to the worker's boot logger so the\n// 25-line `[agentmemory] X registered` stream is either dropped or\n// printed verbatim. Without this the worker's default (env-only) would\n// disagree with the CLI flag.\nsetBootVerbose(IS_VERBOSE);\n\nconst IS_RESET = args.includes(\"--reset\");\n\n// Pinned iii-engine version. The unpinned `install.iii.dev/iii/main/install.sh`\n// script tracks `latest`, which made every fresh agentmemory install pull\n// engine 0.11.6 — and 0.11.6 introduces a new sandbox-everything-via-\n// `iii worker add` worker model that agentmemory hasn't been refactored\n// for yet (we still use the old `iii-exec watch` config-file model). The\n// architectural mismatch surfaces as EPIPE reconnect loops and empty\n// search results after save. Pin to v0.11.2 — the last engine that runs\n// agentmemory's current worker model cleanly — until the refactor lands.\n// Override env var AGENTMEMORY_III_VERSION lets users on the sandbox\n// model already point at a newer engine without us cutting a release.\nconst IIPINNED_VERSION =\n process.env[\"AGENTMEMORY_III_VERSION\"] || \"0.11.2\";\n\n// Map Node platform/arch → the asset name iii-hq/iii ships under\n// https://github.com/iii-hq/iii/releases/download/iii/v<version>/<asset>\nfunction iiiReleaseAsset(): string | null {\n const p = platform();\n const a = process.arch;\n if (p === \"darwin\" && a === \"arm64\")\n return \"iii-aarch64-apple-darwin.tar.gz\";\n if (p === \"darwin\" && a === \"x64\")\n return \"iii-x86_64-apple-darwin.tar.gz\";\n if (p === \"linux\" && a === \"x64\")\n return \"iii-x86_64-unknown-linux-gnu.tar.gz\";\n if (p === \"linux\" && a === \"arm64\")\n return \"iii-aarch64-unknown-linux-gnu.tar.gz\";\n if (p === \"linux\" && a === \"arm\")\n return \"iii-armv7-unknown-linux-gnueabihf.tar.gz\";\n if (p === \"win32\" && a === \"x64\")\n return \"iii-x86_64-pc-windows-msvc.zip\";\n if (p === \"win32\" && a === \"arm64\")\n return \"iii-aarch64-pc-windows-msvc.zip\";\n return null;\n}\n\nfunction iiiReleaseUrl(): string | null {\n const asset = iiiReleaseAsset();\n if (!asset) return null;\n // Tag name is monorepo-prefixed: `iii/v0.11.2`. Slash is URL-encoded\n // by GitHub when serving the download path, hence `iii/v...` not `iii%2Fv...`.\n return `https://github.com/iii-hq/iii/releases/download/iii/v${IIPINNED_VERSION}/${asset}`;\n}\n\nfunction vlog(msg: string): void {\n if (IS_VERBOSE) p.log.info(`[verbose] ${msg}`);\n}\n\nif (args.includes(\"--help\") || args.includes(\"-h\")) {\n console.log(`\nagentmemory — persistent memory for AI coding agents\n\nUsage: agentmemory [command] [options]\n\nCommands:\n (default) Start agentmemory worker\n init Copy bundled .env.example to ~/.agentmemory/.env if absent\n connect [agent] Wire agentmemory into an installed agent (claude-code, codex,\n cursor, gemini-cli, openclaw, hermes, pi, openhuman).\n No arg = interactive picker. --all wires every detected agent.\n --dry-run shows what would change. --force re-installs.\n status Show connection status, memory count, flags, and health\n doctor Interactive diagnostic + fixer. [F]ix · [S]kip · [?]more · [Q]uit\n --all: apply every fix without prompting (CI)\n --dry-run: show what each fix would do, don't execute\n remove Cleanly uninstall agentmemory (pidfile, state, .env, binaries).\n --force: skip confirmations · --keep-data: keep memory data\n demo Seed sample sessions and show recall in action\n upgrade Upgrade local deps + iii runtime (best effort)\n stop [--force] Stop the running iii-engine started by this CLI.\n --force bypasses the Docker-heuristic guard and signals\n whatever pidfile+lsof report on the REST port (use when\n the engine was started natively but state file is missing).\n mcp Start standalone MCP shim — opt-in surface for MCP-only clients\n (Cursor, Gemini CLI, etc). REST always available at :3111.\n import-jsonl [p] Import Claude Code JSONL transcripts (default: ~/.claude/projects)\n --max-files <N> | --max-files=<N>: override scan cap (default 200, max 1000;\n out-of-range is rejected; for trees >1000 files, batch by subdirectory)\n\nOptions:\n --help, -h Show this help\n --verbose, -v Show engine stderr, boot log, and diagnostic info\n --reset Wipe ~/.agentmemory/preferences.json and re-run onboarding\n --tools all|core Tool visibility (default: core = 7 tools)\n --no-engine Skip auto-starting iii-engine\n --port <N> Override REST port (default: 3111)\n\nEnvironment:\n AGENTMEMORY_URL Full REST base URL (e.g. http://localhost:3111).\n Honored by status, doctor, and MCP shim commands.\n AGENTMEMORY_USE_DOCKER=1 Prefer the bundled docker-compose path over the\n native iii-engine binary on first run.\n AGENTMEMORY_III_VERSION Override pinned iii-engine version (default ${IIPINNED_VERSION}).\n\nQuick start:\n npx @agentmemory/agentmemory # start with local iii-engine or Docker\n npx @agentmemory/agentmemory demo # see semantic recall in 30 seconds\n npx @agentmemory/agentmemory doctor # diagnose config + feature flags\n npx @agentmemory/agentmemory status # health + memory count + flags\n npx @agentmemory/agentmemory upgrade # upgrade agentmemory + iii runtime\n npx @agentmemory/agentmemory mcp # standalone MCP server (no engine)\n npx @agentmemory/mcp # same as above (shim package)\n`);\n process.exit(0);\n}\n\nconst toolsIdx = args.indexOf(\"--tools\");\nif (toolsIdx !== -1 && args[toolsIdx + 1]) {\n process.env[\"AGENTMEMORY_TOOLS\"] = args[toolsIdx + 1];\n}\n\nconst portIdx = args.indexOf(\"--port\");\nif (portIdx !== -1 && args[portIdx + 1]) {\n process.env[\"III_REST_PORT\"] = args[portIdx + 1];\n}\n\nconst skipEngine = args.includes(\"--no-engine\");\n\nfunction getRestPort(): number {\n const url = process.env[\"AGENTMEMORY_URL\"];\n if (url) {\n try {\n const parsed = new URL(url).port;\n if (parsed) return parseInt(parsed, 10);\n } catch {}\n }\n return parseInt(process.env[\"III_REST_PORT\"] || \"3111\", 10) || 3111;\n}\n\nfunction getBaseUrl(): string {\n const url = process.env[\"AGENTMEMORY_URL\"];\n if (url) return url.replace(/\\/+$/, \"\");\n return `http://localhost:${getRestPort()}`;\n}\n\nfunction getViewerUrl(): string {\n const envUrl = process.env[\"AGENTMEMORY_VIEWER_URL\"];\n if (envUrl) return envUrl.replace(/\\/+$/, \"\");\n try {\n const u = new URL(getBaseUrl());\n const vPort =\n parseInt(process.env[\"III_VIEWER_PORT\"] || \"\", 10) ||\n (parseInt(u.port || \"3111\", 10) || 3111) + 2;\n return `${u.protocol}//${u.hostname}:${vPort}`;\n } catch {\n const vPort =\n parseInt(process.env[\"III_VIEWER_PORT\"] || \"\", 10) ||\n getRestPort() + 2;\n return `http://localhost:${vPort}`;\n }\n}\n\n// WebSocket streams port. Engine writes here; the SDK and viewer\n// subscribe. Honors both `III_STREAM_PORT` (the singular name the\n// engine docs use post-0.11) and `III_STREAMS_PORT` (the name our\n// own config.ts has used since 0.7) so a single source of truth in\n// either form lights up the ready panel.\nfunction getStreamPort(): number {\n return (\n parseInt(process.env[\"III_STREAM_PORT\"] || \"\", 10) ||\n parseInt(process.env[\"III_STREAMS_PORT\"] || \"\", 10) ||\n 3112\n );\n}\n\n// Bridge WebSocket port — the iii engine's internal worker bus.\n// Defaults to 49134 (engine convention) and is overridable via\n// `III_ENGINE_PORT` or the legacy `III_ENGINE_URL=ws://host:port`.\nfunction getEnginePort(): number {\n const explicit = parseInt(process.env[\"III_ENGINE_PORT\"] || \"\", 10);\n if (explicit) return explicit;\n const url = process.env[\"III_ENGINE_URL\"];\n if (url) {\n try {\n const parsed = new URL(url).port;\n if (parsed) return parseInt(parsed, 10);\n } catch {}\n }\n return 49134;\n}\n\nasync function isEngineRunning(): Promise<boolean> {\n try {\n await fetch(`${getBaseUrl()}/`, {\n signal: AbortSignal.timeout(2000),\n });\n return true;\n } catch {\n return false;\n }\n}\n\nasync function isAgentmemoryReady(): Promise<boolean> {\n try {\n const res = await fetch(`${getBaseUrl()}/agentmemory/livez`, {\n signal: AbortSignal.timeout(2000),\n });\n return res.ok;\n } catch {\n return false;\n }\n}\n\nfunction findIiiConfig(): string {\n const candidates = [\n join(__dirname, \"iii-config.yaml\"),\n join(__dirname, \"..\", \"iii-config.yaml\"),\n join(process.cwd(), \"iii-config.yaml\"),\n ];\n for (const c of candidates) {\n if (existsSync(c)) return c;\n }\n return \"\";\n}\n\nfunction whichBinary(name: string): string | null {\n const cmd = IS_WINDOWS ? \"where\" : \"which\";\n try {\n const out = execFileSync(cmd, [name], {\n encoding: \"utf-8\",\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n const first = out\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .find((line) => line.length > 0);\n return first ?? null;\n } catch {\n return null;\n }\n}\n\nfunction fallbackIiiPaths(): string[] {\n if (IS_WINDOWS) {\n const userProfile = process.env[\"USERPROFILE\"];\n if (!userProfile) return [];\n return [\n join(userProfile, \".local\", \"bin\", \"iii.exe\"),\n join(userProfile, \"bin\", \"iii.exe\"),\n ];\n }\n const home = process.env[\"HOME\"];\n if (!home) return [\"/usr/local/bin/iii\"];\n return [join(home, \".local\", \"bin\", \"iii\"), \"/usr/local/bin/iii\"];\n}\n\nfunction iiiBinVersion(binPath: string): string | null {\n try {\n const out = execFileSync(binPath, [\"--version\"], {\n encoding: \"utf-8\",\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n timeout: 3000,\n });\n const match = out.match(/(\\d+\\.\\d+\\.\\d+(?:[-+][\\w.]+)?)/);\n return match ? match[1]! : null;\n } catch {\n return null;\n }\n}\n\nlet warnedVersionMismatch = false;\nfunction warnIfEngineVersionMismatch(iiiBinPath: string | null | undefined): void {\n if (!iiiBinPath || warnedVersionMismatch) return;\n const detected = iiiBinVersion(iiiBinPath);\n if (!detected || detected === IIPINNED_VERSION) return;\n warnedVersionMismatch = true;\n const asset = iiiReleaseAsset();\n const downloadHint = asset\n ? `curl -fsSL https://github.com/iii-hq/iii/releases/download/iii/v${IIPINNED_VERSION}/${asset} | tar -xz -C ~/.local/bin`\n : `download v${IIPINNED_VERSION} from https://github.com/iii-hq/iii/releases/tag/iii%2Fv${IIPINNED_VERSION}`;\n p.log.warn(\n `iii-engine on PATH is v${detected} but agentmemory v${VERSION} pins v${IIPINNED_VERSION}. Set AGENTMEMORY_III_VERSION=${detected} to silence, or downgrade with: \\`${downloadHint}\\``,\n );\n}\n\nfunction enginePidfilePath(): string {\n return join(homedir(), \".agentmemory\", \"iii.pid\");\n}\n\nfunction engineStatePath(): string {\n return join(homedir(), \".agentmemory\", \"engine-state.json\");\n}\n\ntype EngineState =\n | { kind: \"native\"; configPath: string; attached?: boolean }\n | { kind: \"docker\"; composeFile: string };\n\nfunction writeEnginePidfile(pid: number): void {\n try {\n const pidPath = enginePidfilePath();\n mkdirSync(dirname(pidPath), { recursive: true });\n writeFileSync(pidPath, `${pid}\\n`, { encoding: \"utf-8\" });\n } catch (err) {\n vlog(`writeEnginePidfile: ${err instanceof Error ? err.message : String(err)}`);\n }\n}\n\nfunction readEnginePidfile(): number | null {\n try {\n const pidStr = readFileSync(enginePidfilePath(), \"utf-8\").trim();\n const pid = parseInt(pidStr, 10);\n return Number.isFinite(pid) && pid > 0 ? pid : null;\n } catch {\n return null;\n }\n}\n\nfunction clearEnginePidfile(): void {\n try {\n unlinkSync(enginePidfilePath());\n } catch {}\n}\n\nfunction writeEngineState(state: EngineState): void {\n try {\n const statePath = engineStatePath();\n mkdirSync(dirname(statePath), { recursive: true });\n writeFileSync(statePath, `${JSON.stringify(state)}\\n`, { encoding: \"utf-8\" });\n } catch (err) {\n vlog(`writeEngineState: ${err instanceof Error ? err.message : String(err)}`);\n }\n}\n\nfunction readEngineState(): EngineState | null {\n try {\n const raw = readFileSync(engineStatePath(), \"utf-8\");\n const parsed = JSON.parse(raw) as Partial<EngineState>;\n if (parsed && (parsed.kind === \"native\" || parsed.kind === \"docker\")) {\n return parsed as EngineState;\n }\n return null;\n } catch {\n return null;\n }\n}\n\nfunction clearEngineState(): void {\n try {\n unlinkSync(engineStatePath());\n } catch {}\n}\n\nfunction discoverComposeFile(): string | null {\n const candidates = [\n join(__dirname, \"..\", \"docker-compose.yml\"),\n join(__dirname, \"docker-compose.yml\"),\n join(process.cwd(), \"docker-compose.yml\"),\n ];\n return candidates.find((c) => existsSync(c)) ?? null;\n}\n\nfunction isInvokedViaNpx(): boolean {\n if (process.env[\"npm_lifecycle_event\"] === \"npx\") return true;\n const argv1 = process.argv[1] ?? \"\";\n if (argv1.includes(\"_npx\")) return true;\n const ua = process.env[\"npm_config_user_agent\"] ?? \"\";\n if (ua.startsWith(\"npm/\") || ua.includes(\" npm/\")) return true;\n return false;\n}\n\n// First-run global-install prompt. Replaces the previous passive\n// `p.log.info` hint that users ignored — typing `agentmemory stop`\n// in a new shell would then 404 with `command not found`. We now\n// ask once, persist the answer in preferences, and never ask again.\nasync function maybeOfferGlobalInstall(): Promise<void> {\n if (!isInvokedViaNpx()) return;\n if (!process.stdin.isTTY) return;\n if (process.env[\"CI\"]) return;\n const prefs = readPrefs();\n if (prefs.skipGlobalInstall || prefs.skipNpxHint) return;\n\n const answer = await p.confirm({\n message:\n \"Install agentmemory globally so the bare `agentmemory` command works in any shell? [Y/n]\",\n initialValue: true,\n });\n if (p.isCancel(answer)) {\n // Treat Ctrl+C as \"not now\" rather than \"never\". Don't persist.\n return;\n }\n if (answer === false) {\n writePrefs({ skipGlobalInstall: true });\n p.log.info(\n \"Skipped. Re-run via `npx @agentmemory/agentmemory` or install later with: npm install -g @agentmemory/agentmemory\",\n );\n return;\n }\n\n const npmBin = whichBinary(\"npm\");\n if (!npmBin) {\n p.log.warn(\n \"npm not found on PATH. Install manually: npm install -g @agentmemory/agentmemory\",\n );\n return;\n }\n const ok = runCommand(\n npmBin,\n [\"install\", \"-g\", `@agentmemory/agentmemory@${VERSION}`],\n { label: `Installing @agentmemory/agentmemory@${VERSION} globally` },\n );\n if (ok) {\n p.log.success(\n \"Installed globally. `agentmemory stop` etc. will now work in new shells.\",\n );\n // Persist so we never re-prompt even if the user happens to npx\n // again from a CI-less TTY.\n writePrefs({ skipGlobalInstall: true });\n } else {\n p.log.warn(\n \"Global install failed. Try manually: npm install -g @agentmemory/agentmemory\",\n );\n }\n}\n\n// iii-console install state.\n// \"installed\" — `iii-console` is on PATH or at `~/.local/bin/iii-console`\n// \"missing\" — binary not found anywhere we look\n// We deliberately do NOT probe the console's HTTP port: the binary\n// being on disk is the signal we care about (it's not auto-started by\n// agentmemory and its default port 3113 collides with our viewer, so\n// \"is it listening?\" is the wrong question at boot time).\ntype IiiConsoleState =\n | { kind: \"installed\"; binPath: string }\n | { kind: \"missing\" };\n\nfunction detectIiiConsole(): IiiConsoleState {\n const onPath = whichBinary(\"iii-console\");\n if (onPath) return { kind: \"installed\", binPath: onPath };\n const fallback = IS_WINDOWS\n ? join(process.env[\"USERPROFILE\"] ?? \"\", \".local\", \"bin\", \"iii-console.exe\")\n : join(homedir(), \".local\", \"bin\", \"iii-console\");\n if (fallback && existsSync(fallback)) {\n return { kind: \"installed\", binPath: fallback };\n }\n return { kind: \"missing\" };\n}\n\n// install.iii.dev/console/main/install.sh has a bug in its release-tag\n// filter that rejects every stable release for iii-hq/iii: the jq\n// predicate uses `startswith(\"v\")` while the actual tags are\n// `iii/v0.12.0` (slash-prefixed). The `--next` path uses a regex\n// without the startswith constraint and therefore works today,\n// installing the most recent prerelease (e.g. iii/v0.14.0-next.1).\n//\n// Pass `--next` until the upstream fix lands (iii-hq/iii#1652).\n// Switch back to the bare invocation once the script is patched.\nconst III_CONSOLE_INSTALL_CMD =\n \"curl -fsSL https://install.iii.dev/console/main/install.sh | bash -s -- --next\";\n\nasync function ensureIiiConsole(): Promise<IiiConsoleState> {\n const state = detectIiiConsole();\n if (state.kind === \"installed\") return state;\n\n // Non-interactive contexts get the panel hint but no prompt.\n if (!process.stdin.isTTY || process.env[\"CI\"]) return state;\n const prefs = readPrefs();\n if (prefs.skipConsoleInstall) return state;\n\n const answer = await p.confirm({\n message:\n \"iii console gives engine-level visibility (workers, functions, queues, traces). Install now?\",\n initialValue: true,\n });\n if (p.isCancel(answer)) return state;\n if (answer === false) {\n writePrefs({ skipConsoleInstall: true });\n return state;\n }\n\n const shBin = whichBinary(\"sh\");\n const curlBin = whichBinary(\"curl\");\n if (!shBin || !curlBin) {\n p.log.warn(\n `curl or sh not found. Install manually:\\n ${III_CONSOLE_INSTALL_CMD}`,\n );\n return state;\n }\n const ok = runCommand(shBin, [\"-c\", III_CONSOLE_INSTALL_CMD], {\n label: \"Installing iii console\",\n });\n if (!ok) {\n p.log.warn(\n `iii console install failed. Re-run manually:\\n ${III_CONSOLE_INSTALL_CMD}`,\n );\n return state;\n }\n // Re-detect rather than trust install-script output paths.\n return detectIiiConsole();\n}\n\nfunction adoptRunningEngine(): void {\n try {\n const existingState = readEngineState();\n const existingPid = readEnginePidfile();\n if (existingState && existingPid) return;\n\n const pids = findEnginePidsByPort(getRestPort());\n const enginePid = pids[0];\n if (enginePid && !existingPid) {\n writeEnginePidfile(enginePid);\n }\n if (!existingState) {\n writeEngineState({\n kind: \"native\",\n configPath: findIiiConfig() || \"\",\n attached: true,\n });\n }\n if (enginePid && !existingPid) {\n p.log.info(`Attached to existing iii-engine (pid ${enginePid})`);\n }\n } catch (err) {\n vlog(`adoptRunningEngine: ${err instanceof Error ? err.message : String(err)}`);\n }\n}\n\nasync function runIiiInstaller(): Promise<{ ok: boolean; binPath: string | null }> {\n const releaseUrl = iiiReleaseUrl();\n const asset = iiiReleaseAsset();\n const isZipAsset = asset?.endsWith(\".zip\") === true;\n\n if (!releaseUrl) {\n p.log.warn(\n `iii-engine binary not available for ${platform()}/${process.arch}. Use Docker (\\`docker pull iiidev/iii:${IIPINNED_VERSION}\\`) or download manually from https://github.com/iii-hq/iii/releases/tag/iii%2Fv${IIPINNED_VERSION}.`,\n );\n return { ok: false, binPath: null };\n }\n\n if (IS_WINDOWS || isZipAsset) {\n p.log.info(\n `Auto-install unavailable on ${platform()} — ${asset} isn't tar-compatible. Install manually:\\n` +\n ` 1. Download ${releaseUrl}\\n` +\n ` 2. Extract iii.exe and place it on PATH (e.g. %USERPROFILE%\\\\.local\\\\bin)\\n` +\n `Or use Docker: docker pull iiidev/iii:${IIPINNED_VERSION}`,\n );\n return { ok: false, binPath: null };\n }\n\n const shBin = whichBinary(\"sh\");\n const curlBin = whichBinary(\"curl\");\n if (!shBin || !curlBin) {\n p.log.warn(\"curl or sh not found. Cannot auto-install iii-engine.\");\n return { ok: false, binPath: null };\n }\n\n const binDir = join(homedir(), \".local\", \"bin\");\n const binPath = join(binDir, \"iii\");\n const installCmd = [\n `mkdir -p \"${binDir}\"`,\n `curl -fsSL \"${releaseUrl}\" | tar -xz -C \"${binDir}\"`,\n `chmod +x \"${binPath}\"`,\n ].join(\" && \");\n const installerOk = runCommand(shBin, [\"-c\", installCmd], {\n label: `Installing iii-engine v${IIPINNED_VERSION} (pinned)`,\n optional: true,\n });\n if (!installerOk) {\n p.log.warn(\n `iii-engine installer failed. Fallbacks: Docker (\\`docker pull iiidev/iii:${IIPINNED_VERSION}\\`) or download manually from https://github.com/iii-hq/iii/releases/tag/iii%2Fv${IIPINNED_VERSION}.`,\n );\n return { ok: false, binPath: null };\n }\n return { ok: true, binPath };\n}\n\ntype StartupFailure = {\n kind: \"no-engine\" | \"no-docker-compose\" | \"engine-crashed\" | \"docker-crashed\";\n stderr?: string;\n binary?: string;\n};\n\nlet startupFailure: StartupFailure | null = null;\n\n// Spawn a background engine and collect any startup stderr for a short\n// window. The process is unref'd so the CLI parent can exit cleanly; we\n// only care about stderr that shows up BEFORE the health check succeeds,\n// which is what surfaces early crash/config-parse errors on all platforms.\nfunction spawnEngineBackground(\n bin: string,\n spawnArgs: string[],\n label: string,\n): ChildProcess {\n vlog(`spawn: ${bin} ${spawnArgs.join(\" \")}`);\n const child = spawn(bin, spawnArgs, {\n detached: true,\n stdio: [\"ignore\", \"ignore\", \"pipe\"],\n windowsHide: true,\n });\n const isDocker = label.includes(\"Docker\");\n if (!isDocker && typeof child.pid === \"number\") {\n writeEnginePidfile(child.pid);\n }\n const stderrChunks: Buffer[] = [];\n let stderrBytes = 0;\n const MAX_STDERR_CAPTURE = 16 * 1024;\n child.stderr?.on(\"data\", (chunk: Buffer) => {\n if (stderrBytes >= MAX_STDERR_CAPTURE) return;\n const slice = chunk.subarray(0, MAX_STDERR_CAPTURE - stderrBytes);\n stderrChunks.push(slice);\n stderrBytes += slice.length;\n });\n child.on(\"exit\", (code, signal) => {\n const abnormal =\n (code !== null && code !== 0) || (code === null && signal !== null);\n if (abnormal) {\n const stderr = Buffer.concat(stderrChunks).toString(\"utf-8\");\n startupFailure = {\n kind: isDocker ? \"docker-crashed\" : \"engine-crashed\",\n stderr:\n stderr.trim() ||\n (signal\n ? `process killed by signal ${signal}`\n : `process exited with code ${code}`),\n binary: bin,\n };\n vlog(`engine exited early: code=${code} signal=${signal}`);\n if (IS_VERBOSE && stderr.trim()) {\n p.log.error(`engine stderr:\\n${stderr}`);\n }\n if (!isDocker) clearEnginePidfile();\n clearEngineState();\n }\n });\n child.unref();\n return child;\n}\n\nfunction startIiiBin(iiiBin: string, configPath: string): boolean {\n warnIfEngineVersionMismatch(iiiBin);\n const s = p.spinner();\n s.start(`Starting iii-engine: ${iiiBin}`);\n writeEngineState({ kind: \"native\", configPath });\n spawnEngineBackground(iiiBin, [\"--config\", configPath], \"iii-engine\");\n s.stop(\"iii-engine process started\");\n return true;\n}\n\nasync function startEngine(): Promise<boolean> {\n const configPath = findIiiConfig();\n let iiiBin = whichBinary(\"iii\");\n vlog(`iii binary: ${iiiBin ?? \"(not on PATH)\"}, config: ${configPath || \"(not found)\"}`);\n\n if (iiiBin && configPath) return startIiiBin(iiiBin, configPath);\n\n for (const iiiPath of fallbackIiiPaths()) {\n if (existsSync(iiiPath)) {\n const v = iiiBinVersion(iiiPath);\n vlog(`fallback iii at ${iiiPath} reports version: ${v ?? \"unknown\"}`);\n p.log.info(`Found iii at: ${iiiPath}${v ? ` (v${v})` : \"\"}`);\n process.env[\"PATH\"] = `${dirname(iiiPath)}${PATH_DELIMITER}${process.env[\"PATH\"] ?? \"\"}`;\n iiiBin = iiiPath;\n break;\n }\n }\n\n if (iiiBin && configPath) return startIiiBin(iiiBin, configPath);\n\n if (!configPath) {\n startupFailure = { kind: \"no-engine\" };\n return false;\n }\n\n const dockerBin = whichBinary(\"docker\");\n vlog(`docker binary: ${dockerBin ?? \"(not on PATH)\"}`);\n const dockerComposeCandidates = [\n join(__dirname, \"..\", \"docker-compose.yml\"),\n join(__dirname, \"docker-compose.yml\"),\n join(process.cwd(), \"docker-compose.yml\"),\n ];\n const composeFile = dockerComposeCandidates.find((c) => existsSync(c));\n vlog(`docker-compose.yml: ${composeFile ?? \"(not found)\"}`);\n\n const dockerOptIn =\n process.env[\"AGENTMEMORY_USE_DOCKER\"] === \"1\" ||\n process.env[\"AGENTMEMORY_USE_DOCKER\"] === \"true\";\n const interactive = !!process.stdin.isTTY && !process.env[\"CI\"];\n\n type Choice = \"install\" | \"docker\" | \"manual\";\n let choice: Choice;\n\n if (dockerOptIn && dockerBin && composeFile) {\n choice = \"docker\";\n } else if (!interactive) {\n choice = \"install\";\n p.log.info(\"Non-interactive environment detected — auto-installing iii-engine.\");\n } else {\n p.log.warn(`iii-engine binary not found locally.`);\n const options: { value: Choice; label: string; hint?: string }[] = [\n {\n value: \"install\",\n label: `Install iii v${IIPINNED_VERSION} to ~/.local/bin (~6MB, ~5s)`,\n hint: \"recommended\",\n },\n ];\n if (dockerBin && composeFile) {\n options.push({ value: \"docker\", label: \"Use Docker compose\", hint: \"advanced\" });\n }\n options.push({ value: \"manual\", label: \"Show manual install steps and exit\" });\n\n const picked = await p.select<Choice>({\n message: \"How would you like to start iii-engine?\",\n options,\n initialValue: \"install\",\n });\n if (p.isCancel(picked)) {\n startupFailure = { kind: \"no-engine\" };\n return false;\n }\n choice = picked;\n }\n\n if (choice === \"manual\") {\n startupFailure = { kind: \"no-engine\" };\n return false;\n }\n\n if (choice === \"install\") {\n const result = await runIiiInstaller();\n if (result.ok && result.binPath) {\n process.env[\"PATH\"] = `${dirname(result.binPath)}${PATH_DELIMITER}${process.env[\"PATH\"] ?? \"\"}`;\n iiiBin = result.binPath;\n return startIiiBin(iiiBin, configPath);\n }\n if (dockerBin && composeFile && interactive) {\n const fallback = await p.confirm({\n message: \"Auto-install failed. Try Docker compose instead?\",\n initialValue: true,\n });\n if (p.isCancel(fallback) || fallback !== true) {\n startupFailure = { kind: \"no-engine\" };\n return false;\n }\n choice = \"docker\";\n } else {\n startupFailure = { kind: \"no-engine\" };\n return false;\n }\n }\n\n if (choice === \"docker\" && dockerBin && composeFile) {\n const s = p.spinner();\n s.start(\"Starting iii-engine via Docker...\");\n writeEngineState({ kind: \"docker\", composeFile });\n spawnEngineBackground(\n dockerBin,\n [\"compose\", \"-f\", composeFile, \"up\", \"-d\"],\n \"iii-engine via Docker\",\n );\n s.stop(\"Docker compose started\");\n return true;\n }\n\n if (!composeFile && dockerBin) {\n startupFailure = { kind: \"no-docker-compose\" };\n } else {\n startupFailure = { kind: \"no-engine\" };\n }\n return false;\n}\n\nasync function waitForEngine(timeoutMs: number): Promise<boolean> {\n const start = Date.now();\n while (Date.now() - start < timeoutMs) {\n if (await isEngineRunning()) return true;\n await new Promise((r) => setTimeout(r, 500));\n }\n return false;\n}\n\nfunction installInstructions(): string[] {\n const releaseUrl = iiiReleaseUrl();\n if (IS_WINDOWS) {\n return [\n `agentmemory needs iii-engine v${IIPINNED_VERSION}. Pick one:`,\n \"\",\n \" A) Download the prebuilt Windows binary:\",\n ` 1. Open https://github.com/iii-hq/iii/releases/tag/iii%2Fv${IIPINNED_VERSION}`,\n ` 2. Download iii-x86_64-pc-windows-msvc.zip (or iii-aarch64-pc-windows-msvc.zip on ARM)`,\n \" 3. Extract iii.exe to %USERPROFILE%\\\\.local\\\\bin\\\\iii.exe (or add to PATH)\",\n \" 4. Re-run: npx @agentmemory/agentmemory\",\n \"\",\n ` B) Docker: docker pull iiidev/iii:${IIPINNED_VERSION}`,\n \" Re-run with AGENTMEMORY_USE_DOCKER=1 npx @agentmemory/agentmemory\",\n \"\",\n \"Or skip the engine entirely (standalone MCP): npx @agentmemory/agentmemory mcp\",\n \"\",\n \"Docs: https://iii.dev/docs\",\n ];\n }\n const linuxInstall = releaseUrl\n ? ` A) curl -fsSL \"${releaseUrl}\" | tar -xz -C ~/.local/bin && chmod +x ~/.local/bin/iii`\n : ` A) Manual download: https://github.com/iii-hq/iii/releases/tag/iii%2Fv${IIPINNED_VERSION}`;\n return [\n `agentmemory needs iii-engine v${IIPINNED_VERSION}. Pick one:`,\n \"\",\n linuxInstall,\n \" Then re-run: npx @agentmemory/agentmemory\",\n \"\",\n ` B) Docker: docker pull iiidev/iii:${IIPINNED_VERSION}`,\n \" Re-run with AGENTMEMORY_USE_DOCKER=1 npx @agentmemory/agentmemory\",\n \"\",\n \"Or skip the engine entirely (standalone MCP): npx @agentmemory/agentmemory mcp\",\n \"\",\n \"Docs: https://iii.dev/docs\",\n ];\n}\n\nfunction portInUseDiagnostic(port: number): string {\n return IS_WINDOWS\n ? ` netstat -ano | findstr :${port}`\n : ` lsof -i :${port} # or: ss -tlnp | grep :${port}`;\n}\n\nasync function waitForAgentmemoryReady(timeoutMs: number): Promise<boolean> {\n const start = Date.now();\n while (Date.now() - start < timeoutMs) {\n if (await isAgentmemoryReady()) return true;\n await new Promise((r) => setTimeout(r, 250));\n }\n return false;\n}\n\n// Derive a host string for the streams/engine WebSocket lines from\n// the configured engine URL (`III_ENGINE_URL`) or REST base\n// (`AGENTMEMORY_URL`) so a remote-bind setup like\n// `III_ENGINE_URL=ws://my-host:49134` doesn't print misleading\n// localhost addresses. Falls back to localhost.\nfunction getEngineHost(): string {\n for (const envKey of [\"III_ENGINE_URL\", \"AGENTMEMORY_URL\"]) {\n const raw = process.env[envKey];\n if (!raw) continue;\n try {\n const parsed = new URL(raw);\n if (parsed.hostname) return parsed.hostname;\n } catch {}\n }\n return \"localhost\";\n}\n\nfunction printReadyHint(consoleState: IiiConsoleState): void {\n // REST goes through getBaseUrl which already honors AGENTMEMORY_URL\n // for full host+protocol overrides. Streams/Engine are derived from\n // III_ENGINE_URL so a remote bind reads correctly in the panel.\n const restUrl = getBaseUrl();\n const viewerUrl = getViewerUrl();\n const engineHost = getEngineHost();\n const streamUrl = `ws://${engineHost}:${getStreamPort()}`;\n const engineUrl = `ws://${engineHost}:${getEnginePort()}`;\n\n const consoleLine =\n consoleState.kind === \"installed\"\n ? // We can't safely probe iii-console's port (default 3113\n // collides with our viewer) so we surface the binary location\n // and let the user start it on a port of their choice. Use\n // the detected binary path so `(run: ...)` is executable as-\n // is, even when the binary isn't on PATH under the bare\n // name `iii-console`.\n `iii console ${consoleState.binPath} (run: ${consoleState.binPath} -p <port>)`\n : `iii console (install: ${III_CONSOLE_INSTALL_CMD})`;\n\n const lines = [\n `REST API ${restUrl}`,\n `Viewer ${viewerUrl}`,\n `Streams ${streamUrl}`,\n `Engine ${engineUrl}`,\n consoleLine,\n ];\n // p.note renders a bordered panel with a title — same affordance\n // used elsewhere in this CLI for \"Troubleshooting\" / \"Setup\n // required\" blocks, so the visual language stays consistent.\n p.note(lines.join(\"\\n\"), `agentmemory v${VERSION}`);\n\n // Pick a runnable form for the suggested next-step. Users invoked\n // via `npx` don't have the bare `agentmemory` command on PATH yet\n // (unless they accepted the global-install prompt and the npm bin\n // dir was already on PATH in this shell), so we suggest the npx\n // form for them; everyone else gets the global form.\n const demoCommand = isInvokedViaNpx()\n ? \"npx @agentmemory/agentmemory demo\"\n : \"agentmemory demo\";\n process.stdout.write(`\\nTry: ${demoCommand}\\n`);\n}\n\nasync function main() {\n // `--reset` wipes preferences before anything else so the onboarding\n // flow below always runs fresh.\n if (IS_RESET) {\n resetPrefs();\n }\n\n const firstRun = isFirstRun();\n const prefs = readPrefs();\n // Show the splash on the first run, on --reset, or whenever the user\n // hasn't yet opted out via the schema (we set `skipSplash: true`\n // after onboarding completes). Verbose runs always splash since the\n // user explicitly asked for the chatty experience.\n if (firstRun || IS_RESET || IS_VERBOSE || !prefs.skipSplash) {\n renderSplash(VERSION);\n }\n\n if (firstRun || IS_RESET) {\n await runOnboarding();\n }\n\n if (skipEngine) {\n if (IS_VERBOSE) p.log.info(\"Skipping engine check (--no-engine)\");\n await import(\"./index.js\");\n if (await waitForAgentmemoryReady(15000)) {\n const consoleState = await ensureIiiConsole();\n await maybeOfferGlobalInstall();\n printReadyHint(consoleState);\n }\n return;\n }\n\n if (await isEngineRunning()) {\n if (IS_VERBOSE) p.log.success(\"iii-engine is running\");\n const attachedBin =\n whichBinary(\"iii\") ?? fallbackIiiPaths().find((p) => existsSync(p)) ?? null;\n warnIfEngineVersionMismatch(attachedBin);\n adoptRunningEngine();\n await import(\"./index.js\");\n if (await waitForAgentmemoryReady(15000)) {\n const consoleState = await ensureIiiConsole();\n await maybeOfferGlobalInstall();\n printReadyHint(consoleState);\n }\n return;\n }\n\n const started = await startEngine();\n if (!started) {\n p.log.error(\"Could not start iii-engine.\");\n const lines = installInstructions();\n if (startupFailure?.kind === \"no-docker-compose\") {\n lines.unshift(\n \"Docker is installed but docker-compose.yml is missing from this\",\n \"install. Re-install with: npm install -g @agentmemory/agentmemory\",\n \"\",\n );\n }\n p.note(lines.join(\"\\n\"), \"Setup required\");\n process.exit(1);\n }\n\n const s = p.spinner();\n s.start(\"Waiting for iii-engine to be ready...\");\n\n const ready = await waitForEngine(15000);\n if (!ready) {\n const port = getRestPort();\n s.stop(\"iii-engine did not become ready within 15s\");\n\n if (startupFailure?.kind === \"engine-crashed\" || startupFailure?.kind === \"docker-crashed\") {\n p.log.error(\"The iii-engine process crashed on startup.\");\n if (startupFailure.binary) {\n p.log.info(`Binary: ${startupFailure.binary}`);\n }\n if (startupFailure.stderr) {\n p.note(startupFailure.stderr, \"engine stderr\");\n } else {\n p.log.info(\"No stderr was captured. Re-run with --verbose for more detail.\");\n }\n p.note(\n [\n \"Common causes:\",\n \" - iii-engine version mismatch — reinstall the latest binary\",\n \" (sh script on macOS/Linux, GitHub release zip on Windows)\",\n \" - Docker Desktop not running (if you're using the Docker path)\",\n \" - Port already in use (see below)\",\n \"\",\n \"See https://iii.dev/docs for current install instructions.\",\n ].join(\"\\n\"),\n \"Troubleshooting\",\n );\n } else {\n p.log.error(\"The engine process started but the REST API never responded.\");\n p.note(\n [\n `Check whether port ${port} is already bound by another process:`,\n portInUseDiagnostic(port),\n \"\",\n \"If it is, free the port or override: agentmemory --port <N>\",\n \"\",\n \"If it isn't, a firewall may be blocking 127.0.0.1:\" + port + \".\",\n \"Re-run with --verbose to see engine stderr.\",\n ].join(\"\\n\"),\n \"Troubleshooting\",\n );\n }\n process.exit(1);\n }\n\n s.stop(\"iii-engine is ready\");\n await import(\"./index.js\");\n if (await waitForAgentmemoryReady(15000)) {\n const consoleState = await ensureIiiConsole();\n await maybeOfferGlobalInstall();\n printReadyHint(consoleState);\n }\n // Mark splash as something to skip on subsequent runs. This is a\n // no-op if onboarding already flipped the flag (idempotent merge).\n writePrefs({ skipSplash: true });\n}\n\nasync function apiFetch<T = unknown>(base: string, path: string, timeoutMs = 5000): Promise<T | null> {\n try {\n const headers: Record<string, string> = {};\n const secret = process.env[\"AGENTMEMORY_SECRET\"];\n if (secret) headers[\"Authorization\"] = `Bearer ${secret}`;\n const res = await fetch(`${base}/agentmemory/${path}`, {\n signal: AbortSignal.timeout(timeoutMs),\n headers,\n });\n return (await res.json()) as T;\n } catch {\n return null;\n }\n}\n\nasync function runStatus() {\n const port = getRestPort();\n const base = getBaseUrl();\n p.intro(\"agentmemory status\");\n\n const up = await isEngineRunning();\n if (!up) {\n p.log.error(`Not running — no response at ${base}`);\n p.log.info(\"Start with: npx @agentmemory/agentmemory\");\n process.exit(1);\n }\n\n try {\n const [healthRes, sessionsRes, graphRes, memoriesRes, flagsRes] = await Promise.all([\n apiFetch<any>(base, \"health\"),\n apiFetch<any>(base, \"sessions\"),\n apiFetch<any>(base, \"graph/stats\"),\n apiFetch<any>(base, \"export\"),\n apiFetch<any>(base, \"config/flags\"),\n ]);\n\n const h = healthRes?.health;\n const status = healthRes?.status || \"unknown\";\n const version = healthRes?.version || \"?\";\n const sessions = Array.isArray(sessionsRes?.sessions) ? sessionsRes.sessions.length : 0;\n const nodes = Number(graphRes?.totalNodes ?? graphRes?.nodes ?? graphRes?.nodeCount ?? 0);\n const edges = Number(graphRes?.totalEdges ?? graphRes?.edges ?? graphRes?.edgeCount ?? 0);\n const cb = healthRes?.circuitBreaker?.state || \"closed\";\n const heapMB = h?.memory ? Math.round(h.memory.heapUsed / 1048576) : 0;\n const uptime = h?.uptimeSeconds ? Math.round(h.uptimeSeconds) : 0;\n\n const obsCount = memoriesRes?.observations?.length || 0;\n const memCount = memoriesRes?.memories?.length || 0;\n const estFullTokens = obsCount * 80;\n const estInjectedTokens = Math.min(obsCount, 50) * 38;\n const tokensSaved = estFullTokens - estInjectedTokens;\n const pctSaved = estFullTokens > 0 ? Math.round((tokensSaved / estFullTokens) * 100) : 0;\n\n p.log.success(`Connected — v${version} at ${base}`);\n\n const lines = [\n `Health: ${status === \"healthy\" ? \"✓ healthy\" : status}`,\n `Sessions: ${sessions}`,\n `Observations: ${obsCount}`,\n `Memories: ${memCount}`,\n `Graph: ${nodes} nodes, ${edges} edges`,\n `Circuit: ${cb}`,\n `Heap: ${heapMB} MB`,\n `Uptime: ${uptime}s`,\n `Viewer: ${getViewerUrl()}`,\n ];\n\n if (obsCount > 0) {\n lines.push(\"\");\n lines.push(`Token savings: ~${tokensSaved.toLocaleString()} tokens saved (${pctSaved}% reduction)`);\n lines.push(` Full context: ~${estFullTokens.toLocaleString()} tokens`);\n lines.push(` Injected: ~${estInjectedTokens.toLocaleString()} tokens`);\n }\n\n if (flagsRes) {\n const provider = flagsRes.provider === \"llm\" ? \"✓ llm\" : \"✗ noop (no key)\";\n const embed = flagsRes.embeddingProvider === \"embeddings\" ? \"✓ embeddings\" : \"bm25-only\";\n const flagRows = (flagsRes.flags || []).map((f: { key: string; enabled: boolean; label: string }) =>\n ` ${f.enabled ? \"✓\" : \"✗\"} ${f.key.padEnd(32)} ${f.label}`\n );\n lines.push(\"\");\n lines.push(`Provider: ${provider}`);\n lines.push(`Embeddings: ${embed}`);\n lines.push(`Flags:`);\n flagRows.forEach((r: string) => lines.push(r));\n }\n\n p.note(lines.join(\"\\n\"), \"agentmemory\");\n } catch (err) {\n p.log.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n}\n\ntype DoctorCheck = { name: string; ok: boolean; hint?: string };\n\nfunction formatChecks(checks: DoctorCheck[]): string {\n return checks\n .map((c) => `${c.ok ? \"✓\" : \"✗\"} ${c.name}${c.hint ? `\\n ${c.hint}` : \"\"}`)\n .join(\"\\n\");\n}\n\ntype CCHooksCheck =\n | { state: \"loaded\"; manifestPath?: string }\n | { state: \"not-loaded\" }\n | { state: \"no-debug-log\" }\n | { state: \"no-cc-dir\" };\n\nfunction findLatestDebugLog(debugDir: string): string | undefined {\n const latestLink = join(debugDir, \"latest\");\n try {\n if (existsSync(latestLink)) {\n const target = readlinkSync(latestLink);\n const resolved = target.startsWith(\"/\") ? target : join(debugDir, target);\n if (existsSync(resolved)) return resolved;\n }\n } catch {}\n\n try {\n const newest = readdirSync(debugDir)\n .filter((f) => f.endsWith(\".txt\"))\n .map((f) => ({ f, m: statSync(join(debugDir, f)).mtimeMs }))\n .sort((a, b) => b.m - a.m)[0];\n if (newest) return join(debugDir, newest.f);\n } catch {}\n\n return undefined;\n}\n\nfunction checkClaudeCodeHooks(): CCHooksCheck {\n const debugDir = join(homedir(), \".claude\", \"debug\");\n if (!existsSync(debugDir)) return { state: \"no-cc-dir\" };\n\n const logPath = findLatestDebugLog(debugDir);\n if (!logPath) return { state: \"no-debug-log\" };\n\n let content: string;\n try {\n content = readFileSync(logPath, \"utf8\");\n } catch {\n return { state: \"no-debug-log\" };\n }\n\n const match = content.match(\n /Loaded hooks from standard location for plugin agentmemory:\\s*(\\S+)/\n );\n if (match) return { state: \"loaded\", manifestPath: match[1] };\n if (content.includes(\"Loading hooks from plugin: agentmemory\")) return { state: \"loaded\" };\n return { state: \"not-loaded\" };\n}\n\n// ---------------------------------------------------------------------------\n// Doctor v2 — interactive fixer.\n//\n// The legacy passive check-list (server reachable, flags, knowledge-graph,\n// Claude Code hooks) still runs first as an informational summary because\n// those checks need a live engine and don't have a one-shot inline fix.\n// Then we drive the new diagnostic catalog (see src/cli/doctor-diagnostics.ts)\n// which prompts Fix/Skip/More/Quit per failing check, applies the fix\n// inline, and re-checks only the affected diagnostic.\n\nfunction buildDoctorContext(): DoctorContext {\n return {\n baseUrl: getBaseUrl(),\n viewerUrl: getViewerUrl(),\n envPath: join(homedir(), \".agentmemory\", \".env\"),\n pidfilePath: enginePidfilePath(),\n enginePath: engineStatePath(),\n pinnedVersion: IIPINNED_VERSION,\n };\n}\n\nfunction buildDoctorEffects(): DoctorEffects {\n return {\n envFileExists: () => existsSync(join(homedir(), \".agentmemory\", \".env\")),\n readEnvFile: () => {\n try {\n return parseEnvFile(\n readFileSync(join(homedir(), \".agentmemory\", \".env\"), \"utf-8\"),\n );\n } catch {\n return {};\n }\n },\n pidfileExists: () => existsSync(enginePidfilePath()),\n pidfilePidIsAlive: () => {\n const pid = readEnginePidfile();\n if (pid === null) return null;\n return pidAlive(pid);\n },\n findIiiBinary: () => whichBinary(\"iii\"),\n localBinIiiPath: () => join(homedir(), \".local\", \"bin\", IS_WINDOWS ? \"iii.exe\" : \"iii\"),\n iiiBinaryVersion: (binPath: string) => iiiBinVersion(binPath),\n viewerReachable: async (timeoutMs = 2000) => {\n try {\n const res = await fetch(getViewerUrl(), {\n signal: AbortSignal.timeout(timeoutMs),\n });\n return res.ok;\n } catch {\n return false;\n }\n },\n runInit: async () => {\n try {\n await runInit();\n return { ok: true, message: \"Wrote ~/.agentmemory/.env\" };\n } catch (err) {\n return {\n ok: false,\n message: err instanceof Error ? err.message : String(err),\n };\n }\n },\n openEditor: async (path: string) => {\n const editor = process.env[\"EDITOR\"] || process.env[\"VISUAL\"] || \"nano\";\n p.log.info(`Opening ${path} in ${editor}…`);\n try {\n // Inherit stdio so the user actually sees the editor.\n const result = spawnSync(editor, [path], { stdio: \"inherit\" });\n if (result.error) {\n return {\n ok: false,\n message: `Failed to launch ${editor}: ${result.error.message}`,\n };\n }\n if ((result.status ?? 0) !== 0) {\n return {\n ok: false,\n message: `${editor} exited with code ${result.status}`,\n };\n }\n return { ok: true, message: `Saved ${path}` };\n } catch (err) {\n return {\n ok: false,\n message: err instanceof Error ? err.message : String(err),\n };\n }\n },\n runIiiInstaller: async () => {\n const r = await runIiiInstaller();\n return {\n ok: r.ok,\n message: r.ok\n ? `Installed iii v${IIPINNED_VERSION} to ${r.binPath}`\n : \"iii installer failed (see warnings above)\",\n };\n },\n runStop: async () => {\n try {\n // runStop calls process.exit on its own — guard against that here\n // by short-circuiting when there's nothing to stop.\n const port = getRestPort();\n const portPids = findEnginePidsByPort(port);\n const pidfilePid = readEnginePidfile();\n if (portPids.length === 0 && pidfilePid === null) {\n clearEnginePidfile();\n clearEngineState();\n return { ok: true, message: \"Nothing to stop.\" };\n }\n const candidates = new Set<number>();\n if (pidfilePid) candidates.add(pidfilePid);\n for (const pid of portPids) candidates.add(pid);\n let allStopped = true;\n for (const pid of candidates) {\n const ok = await signalAndWait(pid, \"SIGTERM\", 3000);\n if (!ok) allStopped = false;\n }\n clearEnginePidfile();\n clearEngineState();\n return {\n ok: allStopped,\n message: allStopped ? \"Engine stopped.\" : \"Some engine pids survived.\",\n };\n } catch (err) {\n return {\n ok: false,\n message: err instanceof Error ? err.message : String(err),\n };\n }\n },\n runStart: async () => {\n try {\n const started = await startEngine();\n if (!started) return { ok: false, message: \"startEngine() returned false\" };\n const ready = await waitForEngine(15000);\n return {\n ok: ready,\n message: ready ? \"Engine ready\" : \"Engine did not become ready within 15s\",\n };\n } catch (err) {\n return {\n ok: false,\n message: err instanceof Error ? err.message : String(err),\n };\n }\n },\n clearEnginePidAndState: () => {\n clearEnginePidfile();\n clearEngineState();\n },\n };\n}\n\nasync function passiveServerChecks(): Promise<DoctorCheck[]> {\n const base = getBaseUrl();\n const checks: DoctorCheck[] = [];\n\n const serverUp = await isEngineRunning();\n checks.push({\n name: \"Server reachable\",\n ok: serverUp,\n hint: serverUp\n ? undefined\n : `Start with: npx @agentmemory/agentmemory (tried ${base})`,\n });\n if (!serverUp) return checks;\n\n const [health, flags, graph] = await Promise.all([\n apiFetch<any>(base, \"health\", 3000),\n apiFetch<any>(base, \"config/flags\", 3000),\n apiFetch<any>(base, \"graph/stats\", 3000),\n ]);\n\n const hasLlm = flags?.provider === \"llm\";\n const hasEmbed = flags?.embeddingProvider === \"embeddings\";\n const graphNodeCount = Number(\n graph?.totalNodes ?? graph?.nodes ?? graph?.nodeCount ?? 0,\n );\n const graphHas = graphNodeCount > 0;\n\n checks.push(\n {\n name: \"Health status\",\n ok: health?.status === \"healthy\",\n hint:\n health?.status === \"healthy\"\n ? undefined\n : `Status: ${health?.status || \"unknown\"}`,\n },\n {\n name: \"LLM provider\",\n ok: hasLlm,\n hint: hasLlm ? undefined : \"set ANTHROPIC_API_KEY (or GEMINI/OPENROUTER/MINIMAX) in ~/.agentmemory/.env\",\n },\n {\n name: \"Embedding provider\",\n ok: hasEmbed,\n hint: hasEmbed\n ? undefined\n : \"Running BM25-only. Add OPENAI_API_KEY / VOYAGE_API_KEY / COHERE_API_KEY / OLLAMA_HOST\",\n },\n );\n\n for (const f of (flags?.flags || []) as {\n label: string;\n enabled: boolean;\n enableHow: string;\n }[]) {\n checks.push({\n name: f.label,\n ok: f.enabled,\n hint: f.enabled ? undefined : f.enableHow,\n });\n }\n\n const cc = checkClaudeCodeHooks();\n const ccCheck = (() => {\n switch (cc.state) {\n case \"loaded\":\n return {\n ok: true,\n hint: cc.manifestPath ? `manifest: ${cc.manifestPath}` : undefined,\n };\n case \"not-loaded\":\n return {\n ok: false,\n hint:\n \"Plugin enabled but hooks not loaded by Claude Code. Try: /plugin uninstall agentmemory@agentmemory && /plugin install agentmemory@agentmemory, then restart the session.\",\n };\n case \"no-debug-log\":\n return {\n ok: false,\n hint:\n 'Cannot verify — no Claude Code debug log found. Run once with `claude --debug -p \"x\"`, then re-run doctor.',\n };\n case \"no-cc-dir\":\n return undefined;\n }\n })();\n if (ccCheck) checks.push({ name: \"Claude Code plugin hooks registered\", ...ccCheck });\n\n checks.push({\n name: \"Knowledge graph populated\",\n ok: graphHas,\n hint: graphHas\n ? undefined\n : \"Graph is empty. Run a session with GRAPH_EXTRACTION_ENABLED=true.\",\n });\n\n return checks;\n}\n\ntype DoctorAction = \"fix\" | \"skip\" | \"more\" | \"quit\";\n\nasync function askFixAction(d: Diagnostic): Promise<DoctorAction> {\n const choice = await p.select<DoctorAction>({\n message: `[${d.id}] ${d.message}`,\n options: [\n { value: \"fix\", label: \"F Fix\", hint: d.fixPreview },\n { value: \"skip\", label: \"S Skip\" },\n { value: \"more\", label: \"? More info\" },\n { value: \"quit\", label: \"Q Quit doctor\" },\n ],\n initialValue: \"fix\",\n });\n if (p.isCancel(choice)) return \"quit\";\n return choice;\n}\n\nasync function applyFixWithReport(\n d: Diagnostic,\n ctx: DoctorContext,\n dryRun: boolean,\n): Promise<DiagnosticFixResult> {\n if (dryRun) {\n p.log.info(`[dry-run] would: ${d.fixPreview}`);\n return { ok: true, message: \"(dry-run)\" };\n }\n const result = await d.fix(ctx);\n if (result.ok) {\n p.log.success(result.message ?? `${d.id} fixed.`);\n } else {\n p.log.error(result.message ?? `${d.id} fix failed.`);\n }\n return result;\n}\n\nasync function runDoctor() {\n p.intro(\"agentmemory doctor\");\n const applyAll = args.includes(\"--all\");\n const dryRun = args.includes(\"--dry-run\");\n if (applyAll && dryRun) {\n p.log.error(\"Cannot combine --all and --dry-run.\");\n process.exit(2);\n }\n\n // Passive server checks (informational).\n const passive = await passiveServerChecks();\n const passivePassed = passive.filter((c) => c.ok).length;\n p.note(formatChecks(passive), `server: ${passivePassed}/${passive.length} passing`);\n\n // Doctor v2 interactive catalog.\n const ctx = buildDoctorContext();\n const effects = buildDoctorEffects();\n const diagnostics = buildDiagnostics(effects);\n\n if (dryRun) {\n const results: Array<{ diagnostic: Diagnostic; status: { ok: boolean; detail?: string } }> = [];\n for (const d of diagnostics) results.push({ diagnostic: d, status: await d.check(ctx) });\n const lines = dryRunPlan(ctx, results);\n p.note(lines.join(\"\\n\"), \"dry-run plan\");\n p.outro(\"Dry-run complete. Re-run without --dry-run to apply.\");\n return;\n }\n\n let failed = 0;\n let fixed = 0;\n let skipped = 0;\n let quit = false;\n\n for (const d of diagnostics) {\n if (quit) {\n skipped++;\n continue;\n }\n const status = await d.check(ctx);\n if (status.ok) {\n p.log.success(`${d.id} ✓${status.detail ? ` (${status.detail})` : \"\"}`);\n continue;\n }\n failed++;\n p.log.warn(`${d.id} ✗ ${status.detail ?? \"\"}`.trim());\n p.log.info(`why: ${d.fixPreview}`);\n\n if (d.manualOnly) {\n p.log.info(`(manual fix only — see \"${d.id}\" docs)`);\n }\n\n if (applyAll) {\n const r = await applyFixWithReport(d, ctx, false);\n if (r.ok) fixed++;\n // Re-check only this diagnostic.\n const after = await d.check(ctx);\n if (!after.ok) p.log.warn(`${d.id} still failing after fix.`);\n continue;\n }\n\n // Interactive prompt loop — allow [?] More info without leaving the check.\n while (true) {\n const action = await askFixAction(d);\n if (action === \"fix\") {\n const r = await applyFixWithReport(d, ctx, false);\n if (r.ok) {\n const after = await d.check(ctx);\n if (after.ok) {\n fixed++;\n } else {\n p.log.warn(`${d.id} still failing after fix: ${after.detail ?? \"\"}`);\n }\n }\n break;\n }\n if (action === \"skip\") {\n skipped++;\n break;\n }\n if (action === \"more\") {\n p.note(d.moreInfo, `[${d.id}] more info`);\n continue;\n }\n if (action === \"quit\") {\n quit = true;\n break;\n }\n }\n }\n\n const summary = `${diagnostics.length} checks · ${failed} failing · ${fixed} fixed · ${skipped} skipped`;\n if (quit) {\n p.outro(`Quit early. ${summary}`);\n process.exit(1);\n }\n if (failed === 0) {\n p.outro(\"All diagnostics passing. agentmemory is healthy.\");\n return;\n }\n if (failed - fixed === 0) {\n p.outro(`All fixes applied. ${summary}`);\n return;\n }\n p.outro(summary);\n process.exit(1);\n}\n\ntype DemoObservation = {\n toolName: string;\n toolInput: Record<string, string>;\n toolOutput: string;\n};\n\ntype DemoSession = {\n id: string;\n title: string;\n observations: DemoObservation[];\n};\n\ntype SearchResult = { query: string; hits: number; topTitle: string };\n\nfunction buildDemoSessions(): DemoSession[] {\n return [\n {\n id: generateId(\"demo\"),\n title: \"Session 1: JWT auth setup\",\n observations: [\n {\n toolName: \"Write\",\n toolInput: { file_path: \"src/middleware/auth.ts\" },\n toolOutput:\n \"Created JWT middleware using jose library. Tokens expire after 30 days. Chose jose over jsonwebtoken for Edge compatibility.\",\n },\n {\n toolName: \"Write\",\n toolInput: { file_path: \"test/auth.test.ts\" },\n toolOutput:\n \"Added token validation tests covering expired, malformed, and valid cases.\",\n },\n {\n toolName: \"Bash\",\n toolInput: { command: \"npm test\" },\n toolOutput: \"All 12 auth tests passing.\",\n },\n ],\n },\n {\n id: generateId(\"demo\"),\n title: \"Session 2: Database migration debugging\",\n observations: [\n {\n toolName: \"Read\",\n toolInput: { file_path: \"prisma/schema.prisma\" },\n toolOutput:\n \"Found N+1 query issue in user relations. Need to add include on posts query.\",\n },\n {\n toolName: \"Edit\",\n toolInput: { file_path: \"src/api/users.ts\" },\n toolOutput:\n \"Fixed N+1 by adding Prisma include. Query time dropped from 450ms to 28ms.\",\n },\n ],\n },\n {\n id: generateId(\"demo\"),\n title: \"Session 3: Rate limiting\",\n observations: [\n {\n toolName: \"Write\",\n toolInput: { file_path: \"src/middleware/ratelimit.ts\" },\n toolOutput:\n \"Added rate limiting middleware with 100 req/min default. Uses in-memory store for dev, Redis for prod.\",\n },\n ],\n },\n ];\n}\n\nasync function postJson<T = unknown>(\n url: string,\n body: unknown,\n timeoutMs = 5000,\n): Promise<T | null> {\n try {\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n signal: AbortSignal.timeout(timeoutMs),\n });\n if (!res.ok) return null;\n return (await res.json().catch(() => null)) as T | null;\n } catch {\n return null;\n }\n}\n\nasync function postJsonStrict<T = unknown>(\n url: string,\n body: unknown,\n timeoutMs = 5000,\n): Promise<T | null> {\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n signal: AbortSignal.timeout(timeoutMs),\n });\n if (!res.ok) {\n const errBody = await res.text().catch(() => \"\");\n const suffix = errBody ? ` — ${errBody.slice(0, 200)}` : \"\";\n throw new Error(`POST ${url} failed: ${res.status} ${res.statusText}${suffix}`);\n }\n return (await res.json().catch(() => null)) as T | null;\n}\n\nasync function seedDemoSession(\n base: string,\n project: string,\n session: DemoSession,\n): Promise<number> {\n await postJsonStrict(`${base}/agentmemory/session/start`, {\n sessionId: session.id,\n project,\n cwd: project,\n });\n\n let stored = 0;\n for (const obs of session.observations) {\n const url = `${base}/agentmemory/observe`;\n const payload = {\n hookType: \"post_tool_use\",\n sessionId: session.id,\n project,\n cwd: project,\n timestamp: new Date().toISOString(),\n data: {\n tool_name: obs.toolName,\n tool_input: obs.toolInput,\n tool_output: obs.toolOutput,\n },\n };\n\n try {\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(payload),\n signal: AbortSignal.timeout(5000),\n });\n if (res.ok) {\n stored++;\n } else {\n const body = await res.text().catch(() => \"\");\n p.log.warn(\n `observe failed for ${obs.toolName}: ${res.status} ${res.statusText}${body ? ` — ${body.slice(0, 160)}` : \"\"}`,\n );\n }\n } catch (err) {\n p.log.warn(\n `observe request failed for ${obs.toolName}: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n await postJsonStrict(`${base}/agentmemory/session/end`, { sessionId: session.id });\n return stored;\n}\n\nasync function runDemoSearch(base: string, query: string): Promise<SearchResult> {\n const data = await postJson<{ results?: Array<{ title?: string }> }>(\n `${base}/agentmemory/smart-search`,\n { query, limit: 5 },\n 10000,\n );\n const items = data?.results ?? [];\n return {\n query,\n hits: items.length,\n topTitle: items[0]?.title ?? \"(no results)\",\n };\n}\n\n// Prefer the packaged `.env.example` (next to `dist/cli.mjs`); fall back to\n// the repo root when running from a source checkout.\nfunction findEnvExample(): string | null {\n const candidates = [\n join(__dirname, \"..\", \".env.example\"),\n join(__dirname, \".env.example\"),\n join(process.cwd(), \".env.example\"),\n ];\n for (const c of candidates) {\n if (existsSync(c)) return c;\n }\n return null;\n}\n\nasync function runInit() {\n p.intro(\"agentmemory init\");\n const target = join(homedir(), \".agentmemory\", \".env\");\n const template = findEnvExample();\n if (!template) {\n p.log.error(\n \"Could not locate .env.example in the package. Re-install with: npm i -g @agentmemory/agentmemory\",\n );\n process.exit(1);\n }\n const dir = dirname(target);\n const { mkdir, copyFile } = await import(\"node:fs/promises\");\n const { constants: fsConstants } = await import(\"node:fs\");\n try {\n await mkdir(dir, { recursive: true });\n // COPYFILE_EXCL collapses the exists-check + copy into one syscall —\n // an existsSync(target) + copyFile() pair races with a parallel init\n // (or any other process touching ~/.agentmemory/.env between the two\n // calls) and would silently overwrite a config the operator just\n // wrote. EEXIST out of copyFile is the only \"already configured\"\n // signal we trust.\n await copyFile(template, target, fsConstants.COPYFILE_EXCL);\n } catch (err) {\n if ((err as NodeJS.ErrnoException)?.code === \"EEXIST\") {\n p.log.warn(`${target} already exists — leaving it untouched.`);\n p.log.info(\n `Compare against the latest template: diff ${target} ${template}`,\n );\n p.outro(\"Nothing changed.\");\n return;\n }\n p.log.error(\n `Failed to copy template: ${err instanceof Error ? err.message : String(err)}`,\n );\n process.exit(1);\n }\n p.log.success(`Wrote ${target}`);\n p.note(\n [\n \"All keys are commented out by default. Uncomment the ones you want.\",\n \"\",\n \"Common next steps:\",\n \" 1. Pick an LLM provider key (ANTHROPIC_API_KEY / OPENAI_API_KEY / GEMINI_API_KEY / etc.)\",\n \" 2. Run `npx @agentmemory/agentmemory doctor` to verify the daemon sees them\",\n \" 3. Run `npx @agentmemory/agentmemory` to start the worker\",\n ].join(\"\\n\"),\n \"Next steps\",\n );\n p.outro(`Edit ${target} and you're set.`);\n}\n\nasync function runDemo() {\n const port = getRestPort();\n const base = `http://localhost:${port}`;\n p.intro(\"agentmemory demo\");\n\n if (!(await isAgentmemoryReady())) {\n p.log.error(\n `agentmemory worker not reachable on port ${port} (livez probe failed). Something may be on the port but it isn't serving /agentmemory/*.`,\n );\n p.log.info(\"Start it with: npx @agentmemory/agentmemory\");\n process.exit(1);\n }\n\n const demoProject = \"/tmp/agentmemory-demo\";\n const sessions = buildDemoSessions();\n\n const sSeed = p.spinner();\n sSeed.start(\"Seeding 3 demo sessions with realistic observations...\");\n\n let totalObs = 0;\n for (const session of sessions) {\n totalObs += await seedDemoSession(base, demoProject, session);\n }\n\n sSeed.stop(`Seeded ${totalObs} observations across ${sessions.length} sessions`);\n\n const queries = [\n \"jwt auth middleware\",\n \"database performance optimization\",\n \"rate limiting\",\n ];\n\n const sQuery = p.spinner();\n sQuery.start(`Running ${queries.length} smart-search queries...`);\n\n const results: SearchResult[] = [];\n for (const query of queries) {\n results.push(await runDemoSearch(base, query));\n }\n\n sQuery.stop(\"Search complete\");\n\n const lines = [\n `Project: ${demoProject}`,\n `Sessions: ${sessions.length} seeded (${totalObs} observations)`,\n \"\",\n \"Search results:\",\n ...results.flatMap((r) => [\n ` \"${r.query}\"`,\n ` → ${r.hits} hit(s), top: ${r.topTitle.slice(0, 60)}`,\n ]),\n \"\",\n `Notice: searching \"database performance optimization\"`,\n `found the N+1 query fix — keyword matching can't do that.`,\n \"\",\n `Viewer: ${getViewerUrl()}`,\n `Clean up with: curl -X DELETE \"${base}/agentmemory/sessions?project=${demoProject}\"`,\n ];\n\n p.note(lines.join(\"\\n\"), \"demo complete\");\n p.log.success(\"agentmemory is working. Point your agent at it and get back to coding.\");\n}\n\nfunction runCommand(\n command: string,\n commandArgs: string[],\n options: { cwd?: string; label: string; optional?: boolean } = { label: \"command\" },\n): boolean {\n const spinner = p.spinner();\n spinner.start(options.label);\n const result = spawnSync(command, commandArgs, {\n cwd: options.cwd || process.cwd(),\n stdio: \"pipe\",\n encoding: \"utf-8\",\n });\n\n if (result.status === 0) {\n spinner.stop(`${options.label} ✓`);\n return true;\n }\n\n const stderr = (result.stderr || \"\").toString().trim();\n const stdout = (result.stdout || \"\").toString().trim();\n const msg = stderr || stdout || \"unknown error\";\n\n if (options.optional) {\n spinner.stop(`${options.label} (skipped)`);\n p.log.warn(msg.slice(0, 300));\n return false;\n }\n\n spinner.stop(`${options.label} ✗`);\n p.log.error(msg.slice(0, 300));\n return false;\n}\n\nasync function runUpgrade() {\n p.intro(\"agentmemory upgrade\");\n\n const cwd = process.cwd();\n const hasPackageJson = existsSync(join(cwd, \"package.json\"));\n const hasPnpmLock = existsSync(join(cwd, \"pnpm-lock.yaml\"));\n\n const pnpmBin = whichBinary(\"pnpm\");\n const npmBin = whichBinary(\"npm\");\n const dockerBin = whichBinary(\"docker\");\n\n p.log.info(`Working directory: ${cwd}`);\n const requireSuccess = (ok: boolean, label: string): void => {\n if (!ok) {\n p.log.error(`Upgrade aborted: ${label} failed.`);\n process.exit(1);\n }\n };\n\n if (hasPackageJson) {\n const usePnpm = !!pnpmBin && hasPnpmLock;\n if (usePnpm && pnpmBin) {\n const installOk = runCommand(pnpmBin, [\"install\"], {\n label: \"Refreshing dependencies (pnpm install)\",\n });\n requireSuccess(installOk, \"pnpm install\");\n runCommand(pnpmBin, [\"up\", \"iii-sdk@latest\"], {\n label: \"Upgrading iii-sdk to latest\",\n optional: true,\n });\n } else if (npmBin) {\n const installOk = runCommand(npmBin, [\"install\"], {\n label: \"Refreshing dependencies (npm install)\",\n });\n requireSuccess(installOk, \"npm install\");\n runCommand(npmBin, [\"install\", \"iii-sdk@latest\"], {\n label: \"Upgrading iii-sdk to latest\",\n optional: true,\n });\n } else {\n p.log.warn(\"No package manager found (pnpm/npm). Skipping JS dependency upgrade.\");\n }\n } else {\n p.log.warn(\"No package.json in current directory. Skipping JS dependency upgrade.\");\n }\n\n const upgradeEngine = await p.confirm({\n message: \"Re-run the iii-engine install script (curl | sh)?\",\n initialValue: true,\n });\n if (p.isCancel(upgradeEngine)) {\n p.cancel(\"Cancelled.\");\n return process.exit(0);\n }\n if (upgradeEngine === true) {\n await runIiiInstaller();\n } else {\n p.log.info(\"Skipped iii-engine installer.\");\n }\n\n if (dockerBin) {\n runCommand(dockerBin, [\"pull\", `iiidev/iii:${IIPINNED_VERSION}`], {\n label: `Pulling iii Docker image v${IIPINNED_VERSION} (pinned)`,\n optional: true,\n });\n } else {\n p.log.info(\"Docker not found. Skipping Docker image refresh.\");\n }\n\n p.note(\n [\n \"Upgrade flow completed.\",\n \"\",\n \"Recommended next steps:\",\n \" 1) agentmemory status\",\n \" 2) npm/pnpm test\",\n \" 3) restart agentmemory process\",\n ].join(\"\\n\"),\n \"agentmemory upgrade\",\n );\n}\n\nfunction pidAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch (err) {\n return (err as NodeJS.ErrnoException)?.code === \"EPERM\";\n }\n}\n\nasync function signalAndWait(\n pid: number,\n initialSignal: NodeJS.Signals,\n timeoutMs: number,\n): Promise<boolean> {\n try {\n process.kill(pid, initialSignal);\n } catch (err) {\n const code = (err as NodeJS.ErrnoException)?.code;\n if (code === \"ESRCH\") return true;\n if (code === \"EPERM\") {\n p.log.warn(`No permission to signal pid ${pid}. Try: kill ${pid}`);\n return false;\n }\n vlog(`${initialSignal} ${pid}: ${err instanceof Error ? err.message : String(err)}`);\n return false;\n }\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n if (!pidAlive(pid)) return true;\n await new Promise((r) => setTimeout(r, 200));\n }\n if (!pidAlive(pid)) return true;\n try {\n process.kill(pid, \"SIGKILL\");\n } catch (err) {\n if ((err as NodeJS.ErrnoException)?.code === \"ESRCH\") return true;\n vlog(`SIGKILL ${pid}: ${err instanceof Error ? err.message : String(err)}`);\n return false;\n }\n await new Promise((r) => setTimeout(r, 200));\n return !pidAlive(pid);\n}\n\nfunction findEnginePidsByPort(port: number): number[] {\n if (IS_WINDOWS) return [];\n const lsof = whichBinary(\"lsof\");\n if (!lsof) return [];\n // -sTCP:LISTEN restricts to listening server sockets only. Without\n // this, lsof also returns client-side PIDs (any process with an\n // active TCP connection to :port), which includes the agentmemory\n // CLI itself thanks to the keep-alive fetch in isEngineRunning().\n // signalAndWait would then SIGKILL its own parent — exit code 137.\n const selfPid = process.pid;\n try {\n const out = execFileSync(lsof, [\"-i\", `:${port}`, \"-sTCP:LISTEN\", \"-t\"], {\n encoding: \"utf-8\",\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n });\n return out\n .split(/\\s+/)\n .map((s) => parseInt(s, 10))\n .filter((n) => Number.isFinite(n) && n > 0 && n !== selfPid);\n } catch (err) {\n vlog(`lsof :${port}: ${err instanceof Error ? err.message : String(err)}`);\n return [];\n }\n}\n\nasync function stopDockerEngine(composeFile: string, port: number): Promise<void> {\n const dockerBin = whichBinary(\"docker\");\n if (!dockerBin) {\n p.log.error(\n `Engine was started via Docker compose, but \\`docker\\` is no longer on PATH. Stop it manually:\\n docker compose -f ${composeFile} down`,\n );\n process.exit(1);\n }\n if (!existsSync(composeFile)) {\n p.log.error(\n `Engine state references ${composeFile}, but the file is gone. Stop it manually:\\n docker compose down (from the dir holding the original docker-compose.yml)`,\n );\n process.exit(1);\n }\n const ok = runCommand(dockerBin, [\"compose\", \"-f\", composeFile, \"down\"], {\n label: `docker compose -f ${composeFile} down`,\n });\n clearEnginePidfile();\n clearEngineState();\n if (!ok) {\n p.log.error(\n `docker compose down failed. The engine may still be running on :${port}. Inspect with:\\n docker compose -f ${composeFile} ps`,\n );\n process.exit(1);\n }\n p.outro(\"Stopped. Memories persisted to disk; restart anytime with: npx @agentmemory/agentmemory\");\n}\n\nasync function runStop(): Promise<void> {\n p.intro(\"agentmemory stop\");\n const port = getRestPort();\n const state = readEngineState();\n const running = await isEngineRunning();\n const force = args.includes(\"--force\");\n\n if (state?.kind === \"docker\") {\n if (!running) {\n p.log.info(`No engine responding on port ${port}.`);\n clearEnginePidfile();\n clearEngineState();\n p.outro(\"Nothing to stop.\");\n return;\n }\n await stopDockerEngine(state.composeFile, port);\n return;\n }\n\n const portPids = findEnginePidsByPort(port);\n const pidfilePid = readEnginePidfile();\n\n if (!running) {\n if (portPids.length === 0 && pidfilePid === null) {\n clearEnginePidfile();\n clearEngineState();\n p.outro(\"Nothing to stop.\");\n return;\n }\n const survivors = new Set<number>(portPids);\n if (pidfilePid) survivors.add(pidfilePid);\n p.log.warn(\n `Engine not responding on :${port}, but ${survivors.size} process(es) still hold the port or pidfile: ${[...survivors].join(\", \")}`,\n );\n p.log.info(\n `Preserving ~/.agentmemory/iii.pid. Investigate before manual cleanup:\\n ps -p ${[...survivors].join(\",\")} -o pid,ppid,comm,etime\\n ${IS_WINDOWS ? \"netstat -ano | findstr :\" + port : \"lsof -i :\" + port}`,\n );\n process.exit(1);\n }\n\n if (!state) {\n const compose = discoverComposeFile();\n if (compose && pidfilePid === null) {\n if (force) {\n p.log.warn(\n `--force: bypassing Docker-heuristic guard. Falling back to native pidfile + lsof on :${port}.`,\n );\n } else {\n p.log.error(\n `Engine is running on :${port} but no pidfile or state file is present. It may have been started via Docker compose by a different shell. Refusing to signal host PIDs.\\n\\nStop it with:\\n docker compose -f ${compose} down\\n\\nOr re-run with --force to signal whatever lsof finds on :${port}, or AGENTMEMORY_USE_DOCKER=1 to record state next time.`,\n );\n process.exit(1);\n }\n }\n }\n\n const candidates = new Set<number>();\n if (pidfilePid) candidates.add(pidfilePid);\n for (const pid of portPids) candidates.add(pid);\n\n if (candidates.size === 0) {\n p.log.error(\n `Could not locate engine process. Try:\\n ${IS_WINDOWS ? \"netstat -ano | findstr :\" + port : \"lsof -i :\" + port + \" -t | xargs kill -9\"}`,\n );\n process.exit(1);\n }\n\n let allStopped = true;\n for (const pid of candidates) {\n const s = p.spinner();\n s.start(`Stopping iii-engine (pid ${pid})...`);\n const ok = await signalAndWait(pid, \"SIGTERM\", 3000);\n s.stop(ok ? `Stopped pid ${pid}` : `Failed to stop pid ${pid}`);\n if (!ok) allStopped = false;\n }\n\n clearEnginePidfile();\n clearEngineState();\n if (!allStopped) {\n p.log.error(\"One or more engine processes survived SIGKILL. Investigate with `ps`.\");\n process.exit(1);\n }\n p.outro(\"Stopped. Memories persisted to disk; restart anytime with: npx @agentmemory/agentmemory\");\n}\n\nasync function runMcp(): Promise<void> {\n await import(\"./mcp/standalone.js\");\n}\n\nasync function runConnectCmd(): Promise<void> {\n const { runConnect } = await import(\"./cli/connect/index.js\");\n await runConnect(args.slice(1));\n}\n\nasync function runImportJsonl(): Promise<void> {\n // Long-form flags that take a value. Their value tokens must be\n // consumed alongside the flag so they don't leak into positional\n // args (e.g. `--port 3112 import-jsonl` would otherwise turn\n // 3112 into pathArg).\n const VALUE_FLAGS = new Set([\"--port\", \"--tools\"]);\n let maxFiles: number | undefined;\n const tail = args.slice(1);\n const positional: string[] = [];\n for (let i = 0; i < tail.length; i++) {\n const a = tail[i]!;\n if (a === \"--max-files\") {\n const raw = tail[i + 1];\n const parsed = raw !== undefined ? parseInt(raw, 10) : NaN;\n if (Number.isInteger(parsed) && parsed > 0) {\n maxFiles = parsed;\n } else if (raw !== undefined) {\n p.log.warn(`Ignoring --max-files ${raw}: expected a positive integer.`);\n }\n i++;\n continue;\n }\n if (a.startsWith(\"--max-files=\")) {\n const raw = a.slice(\"--max-files=\".length);\n const parsed = parseInt(raw, 10);\n if (Number.isInteger(parsed) && parsed > 0) {\n maxFiles = parsed;\n } else {\n p.log.warn(`Ignoring --max-files=${raw}: expected a positive integer.`);\n }\n continue;\n }\n if (VALUE_FLAGS.has(a)) {\n i++;\n continue;\n }\n if (a.startsWith(\"-\")) continue;\n positional.push(a);\n }\n const pathArg = positional[0];\n\n const port = getRestPort();\n const base = `http://localhost:${port}`;\n\n let probeOk = false;\n let probeDetail = \"\";\n try {\n const probe = await fetch(`${base}/agentmemory/livez`, {\n signal: AbortSignal.timeout(2000),\n });\n probeOk = probe.ok;\n if (!probeOk) {\n const probeBody = await probe.text().catch(() => \"\");\n probeDetail = `reachable but unhealthy (HTTP ${probe.status}${probeBody ? `: ${probeBody.slice(0, 200)}` : \"\"})`;\n }\n } catch (err) {\n probeOk = false;\n const msg = err instanceof Error ? err.message : String(err);\n probeDetail = `unreachable (${msg})`;\n }\n if (!probeOk) {\n p.log.error(\n `agentmemory livez probe failed on port ${port}: ${probeDetail}. Start it with \\`npx @agentmemory/agentmemory\\` in another terminal, then re-run this command.`,\n );\n process.exit(1);\n }\n\n const body: Record<string, unknown> = {};\n if (pathArg) body[\"path\"] = pathArg;\n if (maxFiles !== undefined) body[\"maxFiles\"] = maxFiles;\n\n const headers: Record<string, string> = { \"content-type\": \"application/json\" };\n const secret = process.env[\"AGENTMEMORY_SECRET\"];\n if (secret) headers[\"authorization\"] = `Bearer ${secret}`;\n\n p.log.info(`Importing JSONL from ${pathArg || \"~/.claude/projects\"}…`);\n const spinner = p.spinner();\n spinner.start(\"scanning files\");\n\n try {\n const res = await fetch(`${base}/agentmemory/replay/import-jsonl`, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n signal: AbortSignal.timeout(120_000),\n });\n const text = await res.text();\n let json: {\n success?: boolean;\n error?: string;\n imported?: number;\n sessionIds?: string[];\n observations?: number;\n discovered?: number;\n truncated?: boolean;\n traversalCapped?: boolean;\n maxFiles?: number;\n maxFilesUpperBound?: number;\n } = {};\n if (text.length > 0) {\n try {\n json = JSON.parse(text);\n } catch {\n spinner.stop(\"failed\");\n p.log.error(\n `server returned non-JSON response (HTTP ${res.status}): ${text.slice(0, 200)}`,\n );\n process.exit(1);\n }\n }\n if (!res.ok || json.success !== true) {\n spinner.stop(\"failed\");\n const detail =\n json.error ||\n (text.length === 0\n ? \"empty response body\"\n : json.success === undefined\n ? `HTTP ${res.status} (response missing success field)`\n : `HTTP ${res.status}`);\n if (res.status === 401) {\n p.log.error(\n `${detail}. Set AGENTMEMORY_SECRET to match the server's secret and re-run.`,\n );\n } else if (res.status === 404) {\n p.log.error(\n `${detail}. The running agentmemory server does not expose /agentmemory/replay/import-jsonl — upgrade to v0.8.13 or later.`,\n );\n } else {\n p.log.error(detail);\n }\n process.exit(1);\n }\n spinner.stop(\n `imported ${json.imported ?? 0} file(s), ${json.observations ?? 0} observation(s) across ${json.sessionIds?.length || 0} session(s)`,\n );\n if (json.truncated) {\n const cap = json.maxFiles ?? 200;\n const upper = json.maxFilesUpperBound ?? 1000;\n const discovered = json.discovered ?? 0;\n const skipped = discovered - (json.imported ?? 0);\n const discoveredLabel = json.traversalCapped\n ? `${discovered}+ (traversal halted at safety cap)`\n : String(discovered);\n const baseMsg = `Hit the ${cap}-file scan cap; ${skipped} of ${discoveredLabel} discovered file(s) were skipped.`;\n // If we already saw more than the server's hard cap (or the\n // walker stopped early), bumping --max-files won't help on its\n // own — recommend batching by subdirectory.\n if (discovered > upper || json.traversalCapped) {\n p.log.warn(\n `${baseMsg} Tree exceeds the server's --max-files limit of ${upper}; ` +\n `batch by subdirectory (run import-jsonl once per project under ~/.claude/projects).`,\n );\n } else {\n const suggested = Math.min(\n Math.max((discovered || cap) + 100, cap * 2),\n upper,\n );\n p.log.warn(\n `${baseMsg} Re-run with --max-files=${suggested} (max ${upper}) or batch by subdirectory.`,\n );\n }\n }\n if (json.sessionIds && json.sessionIds.length > 0) {\n p.log.info(`View at ${getViewerUrl()} → Replay tab`);\n }\n } catch (err) {\n spinner.stop(\"failed\");\n if (err instanceof Error && err.name === \"TimeoutError\") {\n p.log.error(\"import timed out after 2 minutes\");\n } else {\n p.log.error(err instanceof Error ? err.message : String(err));\n }\n process.exit(1);\n }\n}\n\n// ---------------------------------------------------------------------------\n// `agentmemory remove` — clean uninstall.\n//\n// Planning logic lives in src/cli/remove-plan.ts so it's testable without\n// touching $HOME. This function loads the manifest, builds the plan,\n// double-confirms, then executes step by step.\n\nfunction loadConnectManifest(home: string): ConnectManifest | null {\n const path = join(home, \".agentmemory\", \"backups\", \"connect-manifest.json\");\n try {\n const raw = readFileSync(path, \"utf-8\");\n const parsed = JSON.parse(raw) as Partial<ConnectManifest>;\n if (Array.isArray(parsed?.installed)) {\n return { installed: parsed.installed };\n }\n return null;\n } catch {\n return null;\n }\n}\n\nfunction probeLocalBinIiiVersion(home: string): string | null {\n const path = localBinIii(home);\n if (!existsSync(path)) return null;\n return iiiBinVersion(path);\n}\n\nfunction safeDelete(path: string): { ok: boolean; message: string } {\n try {\n if (!existsSync(path)) return { ok: true, message: `not present (${path})` };\n const st = statSync(path);\n if (st.isDirectory()) {\n rmSync(path, { recursive: true, force: true });\n } else {\n unlinkSync(path);\n }\n return { ok: true, message: `deleted ${path}` };\n } catch (err) {\n return {\n ok: false,\n message: `failed ${path}: ${err instanceof Error ? err.message : String(err)}`,\n };\n }\n}\n\nasync function runRemove(): Promise<void> {\n p.intro(\"agentmemory remove\");\n const force = args.includes(\"--force\");\n const keepData = args.includes(\"--keep-data\");\n\n const home = homedir();\n const connectManifest = loadConnectManifest(home);\n const localBinIiiVersion = probeLocalBinIiiVersion(home);\n\n const options: RemoveOptions = { force, keepData };\n const plan = buildRemovePlan(\n {\n home,\n pinnedVersion: IIPINNED_VERSION,\n localBinIiiVersion,\n connectManifest,\n },\n options,\n );\n\n const applicable = plan.filter((it) => it.applicable);\n if (applicable.length === 0) {\n p.outro(\"Nothing to remove. agentmemory is already gone.\");\n return;\n }\n\n p.note(formatPlan(plan), \"destruction plan\");\n\n if (!force) {\n const proceed = await p.confirm({\n message: \"Proceed with these deletions?\",\n initialValue: false,\n });\n if (p.isCancel(proceed) || proceed !== true) {\n p.cancel(\"Cancelled. Nothing was deleted.\");\n return;\n }\n const sure = await p.confirm({\n message: \"This is irreversible. Continue?\",\n initialValue: false,\n });\n if (p.isCancel(sure) || sure !== true) {\n p.cancel(\"Cancelled. Nothing was deleted.\");\n return;\n }\n }\n\n for (const item of plan) {\n if (!item.applicable) continue;\n\n // alwaysAsk items get a per-item confirmation even with --force.\n if (item.alwaysAsk) {\n const ok = await p.confirm({\n message: `${item.description} — really delete${item.path ? ` ${item.path}` : \"\"}?`,\n initialValue: false,\n });\n if (p.isCancel(ok) || ok !== true) {\n p.log.info(`skipped: ${item.id}`);\n continue;\n }\n }\n\n if (item.id === \"stop-engine\") {\n try {\n const port = getRestPort();\n const portPids = findEnginePidsByPort(port);\n const pidfilePid = readEnginePidfile();\n const cands = new Set<number>();\n if (pidfilePid) cands.add(pidfilePid);\n for (const pid of portPids) cands.add(pid);\n for (const pid of cands) await signalAndWait(pid, \"SIGTERM\", 3000);\n clearEnginePidfile();\n clearEngineState();\n p.log.success(\n cands.size > 0\n ? `stopped engine (${cands.size} pid${cands.size === 1 ? \"\" : \"s\"})`\n : \"no engine running\",\n );\n } catch (err) {\n p.log.warn(\n `engine stop best-effort: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n continue;\n }\n\n if (!item.path) continue;\n const r = safeDelete(item.path);\n if (r.ok) p.log.success(r.message);\n else p.log.error(r.message);\n }\n\n p.outro(\n \"Done. agentmemory cleanly removed. The npm package itself: npm uninstall -g @agentmemory/agentmemory\",\n );\n}\n\nconst commands: Record<string, () => Promise<void>> = {\n init: runInit,\n connect: runConnectCmd,\n status: runStatus,\n doctor: runDoctor,\n demo: runDemo,\n upgrade: runUpgrade,\n stop: runStop,\n remove: runRemove,\n mcp: runMcp,\n \"import-jsonl\": runImportJsonl,\n};\n\nconst handler = commands[args[0] ?? \"\"] ?? main;\nhandler().catch((err) => {\n p.log.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\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;CACZ,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;CACV;AAED,MAAa,SAAS;CACpB,MAAM;CACN,QAAQ,cAAsB;CAC9B,aAAa;CACd;AAED,SAAgB,WAAW,QAAwB;AAGjD,QAAO,GAAG,OAAO,GAFN,KAAK,KAAK,CAAC,SAAS,GAAG,CAEX,GADV,OAAO,YAAY,CAAC,QAAQ,MAAM,GAAG,CAAC,MAAM,GAAG,GAAG;;AAIjE,SAAgB,cAAc,QAAgB,SAAyB;AAErE,QAAO,GAAG,OAAO,GADJ,WAAW,SAAS,CAAC,OAAO,QAAQ,CAAC,OAAO,MAAM,CACtC,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;;;;;;ACCjD,MAAM,qBAAqB,IAAI,IAAI;CACjC;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;AAEF,MAAM,qBAAqB;CACzB;CACA;CACA;CACA;CACA;CACA;CACD;AAED,SAAgB,aAAa,SAAyC;CACpE,MAAM,MAA8B,EAAE;AACtC,MAAK,MAAM,WAAW,QAAQ,MAAM,QAAQ,EAAE;EAC5C,MAAM,OAAO,QAAQ,MAAM;AAC3B,MAAI,CAAC,QAAQ,KAAK,WAAW,IAAI,CAAE;EACnC,MAAM,KAAK,KAAK,QAAQ,IAAI;AAC5B,MAAI,KAAK,EAAG;EACZ,MAAM,MAAM,KAAK,MAAM,GAAG,GAAG,CAAC,MAAM;EACpC,IAAI,QAAQ,KAAK,MAAM,KAAK,EAAE,CAAC,MAAM;AAErC,MACG,MAAM,WAAW,KAAI,IAAI,MAAM,SAAS,KAAI,IAC5C,MAAM,WAAW,IAAI,IAAI,MAAM,SAAS,IAAI,CAE7C,SAAQ,MAAM,MAAM,GAAG,GAAG;AAE5B,MAAI,OAAO;;AAEb,QAAO;;;AAIT,SAAgB,iBAAiB,KAAuC;AACtE,QAAO,mBAAmB,QAAQ,MAAM;EACtC,MAAM,KAAK,IAAI,MAAM,IAAI,MAAM;AAC/B,MAAI,CAAC,EAAG,QAAO;AACf,MAAI,mBAAmB,IAAI,EAAE,aAAa,CAAC,CAAE,QAAO;AAEpD,MAAI,QAAQ,KAAK,EAAE,QAAQ,SAAS,GAAG,CAAC,CAAE,QAAO;AACjD,SAAO;GACP;;;AAIJ,SAAgB,wBAAwB,KAAuC;AAC7E,QAAO,mBAAmB,QAAQ,MAAM;EACtC,MAAM,KAAK,IAAI,MAAM,IAAI,MAAM;AAC/B,MAAI,CAAC,EAAG,QAAO;AACf,MAAI,mBAAmB,IAAI,EAAE,aAAa,CAAC,CAAE,QAAO;AACpD,MAAI,QAAQ,KAAK,EAAE,QAAQ,SAAS,GAAG,CAAC,CAAE,QAAO;AACjD,SAAO;GACP;;AAyCJ,SAAgB,iBAAiB,SAAsC;AACrE,QAAO;EACL;GACE,IAAI;GACJ,SAAS;GACT,YAAY;GACZ,UACE;GAEF,OAAO,aAAa;IAClB,IAAI,QAAQ,eAAe;IAC3B,QAAQ,QAAQ,eAAe,GAAG,SAAY;IAC/C;GACD,WAAW,QAAQ,SAAS;GAC7B;EACD;GACE,IAAI;GACJ,SAAS;GACT,YAAY;GACZ,UACE;GAGF,OAAO,YAAY;AACjB,QAAI,CAAC,QAAQ,eAAe,CAC1B,QAAO;KAAE,IAAI;KAAO,QAAQ;KAAgD;IAG9E,MAAM,OAAO,iBADD,QAAQ,aAAa,CACC;AAClC,WAAO;KACL,IAAI,KAAK,SAAS;KAClB,QAAQ,KAAK,SAAS,IAAI,UAAU,KAAK,KAAK,KAAK,KAAK;KACzD;;GAEH,MAAM,QAAQ,QAAQ,WAAW,IAAI,QAAQ;GAC9C;EACD;GACE,IAAI;GACJ,SAAS;GACT,YACE;GACF,UACE;GAGF,OAAO,OAAO,QAAQ;IACpB,MAAM,MAAM,QAAQ,eAAe;AACnC,QAAI,CAAC,IAAK,QAAO;KAAE,IAAI;KAAO,QAAQ;KAAmB;IACzD,MAAM,IAAI,QAAQ,iBAAiB,IAAI;AACvC,QAAI,CAAC,EAAG,QAAO;KAAE,IAAI;KAAO,QAAQ;KAAoC;AACxE,WAAO;KACL,IAAI,MAAM,IAAI;KACd,QAAQ,GAAG,EAAE,WAAW,IAAI,cAAc;KAC3C;;GAEH,KAAK,YAAY;IACf,MAAM,IAAI,MAAM,QAAQ,iBAAiB;AACzC,QAAI,CAAC,EAAE,GAAI,QAAO;AAElB,UAAM,QAAQ,SAAS;AACvB,WAAO,QAAQ,UAAU;;GAE5B;EACD;GACE,IAAI;GACJ,SAAS;GACT,YAAY;GACZ,UACE;GAIF,OAAO,aAAa;IAClB,IAAI,MAAM,QAAQ,iBAAiB;IACnC,QAAQ;IACT;GACD,KAAK,YAAY;IACf,MAAM,UAAU,MAAM,QAAQ,SAAS;AACvC,QAAI,CAAC,QAAQ,GAAI,QAAO;AACxB,WAAO,QAAQ,UAAU;;GAE5B;EACD;GACE,IAAI;GACJ,SAAS;GACT,YAAY;GACZ,UACE;GAGF,OAAO,YAAY;AACjB,QAAI,CAAC,QAAQ,eAAe,CAAE,QAAO;KAAE,IAAI;KAAM,QAAQ;KAAc;IACvE,MAAM,QAAQ,QAAQ,mBAAmB;AACzC,QAAI,UAAU,KAAM,QAAO;KAAE,IAAI;KAAM,QAAQ;KAAsB;AACrE,WAAO;KACL,IAAI;KACJ,QAAQ,QAAQ,iBAAiB;KAClC;;GAEH,KAAK,YAAY;AACf,YAAQ,wBAAwB;AAChC,WAAO,QAAQ,UAAU;;GAE5B;EACD;GACE,IAAI;GACJ,SAAS;GACT,YAAY;GACZ,UACE;GAGF,OAAO,YAAY;AACjB,QAAI,CAAC,QAAQ,eAAe,CAC1B,QAAO;KAAE,IAAI;KAAM,QAAQ;KAA6C;IAG1E,MAAM,eAAe,wBADT,QAAQ,aAAa,CACgB;AACjD,WAAO;KACL,IAAI,aAAa,WAAW;KAC5B,QACE,aAAa,WAAW,IACpB,SACA,gBAAgB,aAAa,KAAK,KAAK;KAC9C;;GAEH,MAAM,QAAQ,QAAQ,WAAW,IAAI,QAAQ;GAC9C;EACD;GACE,IAAI;GACJ,SACE;GACF,YACE;GACF,UACE;GAGF,YAAY;GACZ,OAAO,YAAY;IACjB,MAAM,MAAM,QAAQ,eAAe;AACnC,QAAI,CAAC,IAAK,QAAO;KAAE,IAAI;KAAM,QAAQ;KAAuC;IAC5E,MAAM,WAAW,QAAQ,iBAAiB;AAC1C,WAAO;KACL,IAAI,QAAQ;KACZ,QAAQ,QAAQ,WAAW,SAAY,WAAW;KACnD;;GAEH,KAAK,YACH,QAAQ,iBAAiB,CAAC,MAAM,OAAO;IACrC,IAAI,EAAE;IACN,SACE,EAAE,WACF;IACH,EAAE;GACN;EACF;;;;;;AAyBH,SAAgB,WACd,KACA,SACU;CACV,MAAM,QAAkB,EAAE;CAC1B,IAAI,IAAI;AACR,MAAK,MAAM,EAAE,YAAY,YAAY,SAAS;AAC5C,MAAI,OAAO,GAAI;AACf;AACA,QAAM,KAAK,GAAG,EAAE,KAAK,WAAW,GAAG,IAAI,WAAW,UAAU;AAC5D,QAAM,KAAK,iBAAiB,WAAW,aAAa;AACpD,MAAI,OAAO,OAAQ,OAAM,KAAK,cAAc,OAAO,SAAS;;AAE9D,KAAI,MAAM,WAAW,EACnB,OAAM,KAAK,0BAA0B,IAAI,QAAQ,qBAAqB;AAExE,QAAO;;;;;ACpTT,SAAgB,YAAY,MAAsB;AAChD,QAAO,KAAK,MAAM,gBAAgB,UAAU;;AAG9C,SAAgB,WAAW,MAAsB;AAC/C,QAAO,KAAK,MAAM,gBAAgB,oBAAoB;;AAGxD,SAAgB,QAAQ,MAAsB;AAC5C,QAAO,KAAK,MAAM,gBAAgB,OAAO;;AAG3C,SAAgB,gBAAgB,MAAsB;AACpD,QAAO,KAAK,MAAM,gBAAgB,mBAAmB;;AAGvD,SAAgBA,aAAW,MAAsB;AAC/C,QAAO,KAAK,MAAM,gBAAgB,UAAU;;AAG9C,SAAgB,QAAQ,MAAsB;AAC5C,QAAO,KAAK,MAAM,gBAAgB,OAAO;;AAG3C,SAAgB,YAAY,MAAsB;AAChD,QAAO,KAAK,MAAM,UAAU,OAAO,MAAM;;AAG3C,SAAS,SAAS,MAAsB;AACtC,KAAI;AACF,SAAO,SAAS,KAAK,CAAC;SAChB;AACN,SAAO;;;AAIX,SAAS,WAAW,MAAuB;AACzC,KAAI;AACF,SAAO,WAAW,KAAK;SACjB;AACN,SAAO;;;;;;;;;;AAWX,SAAgB,gBACd,KACA,SACkB;CAClB,MAAM,EAAE,MAAM,eAAe,oBAAoB,oBAAoB;CACrE,MAAM,OAAyB,EAAE;AAEjC,MAAK,KAAK;EACR,IAAI;EACJ,aAAa;EACb,MAAM;EACN,WAAW;EACX,YAAY,WAAW,YAAY,KAAK,CAAC,IAAI,WAAW,WAAW,KAAK,CAAC;EACzE,WAAW;EACZ,CAAC;AAEF,MAAK,KAAK;EACR,IAAI;EACJ,aAAa;EACb,MAAM,YAAY,KAAK;EACvB,WAAW;EACX,YAAY,WAAW,YAAY,KAAK,CAAC;EACzC,WAAW,SAAS,YAAY,KAAK,CAAC;EACvC,CAAC;AAEF,MAAK,KAAK;EACR,IAAI;EACJ,aAAa;EACb,MAAM,WAAW,KAAK;EACtB,WAAW;EACX,YAAY,WAAW,WAAW,KAAK,CAAC;EACxC,WAAW,SAAS,WAAW,KAAK,CAAC;EACtC,CAAC;AAIF,MAAK,KAAK;EACR,IAAI;EACJ,aAAa;EACb,MAAM,QAAQ,KAAK;EACnB,WAAW;EACX,YAAY,CAAC,QAAQ,YAAY,WAAW,QAAQ,KAAK,CAAC;EAC1D,WAAW,SAAS,QAAQ,KAAK,CAAC;EACnC,CAAC;AAEF,MAAK,KAAK;EACR,IAAI;EACJ,aAAa;EACb,MAAM,gBAAgB,KAAK;EAC3B,WAAW;EACX,YAAY,CAAC,QAAQ,YAAY,WAAW,gBAAgB,KAAK,CAAC;EAClE,WAAW,SAAS,gBAAgB,KAAK,CAAC;EAC3C,CAAC;AAEF,MAAK,KAAK;EACR,IAAI;EACJ,aAAa;EACb,MAAMA,aAAW,KAAK;EACtB,WAAW;EACX,YAAY,CAAC,QAAQ,YAAY,WAAWA,aAAW,KAAK,CAAC;EAC7D,WAAW;EACZ,CAAC;AAIF,KAAI,iBAAiB,WAAW,OAC9B,MAAK,MAAM,SAAS,gBAAgB,UAClC,MAAK,KAAK;EACR,IAAI,WAAW,MAAM;EACrB,aAAa,4BAA4B,MAAM,SAAS,UAAU;EAClE,MAAM,MAAM;EACZ,WAAW;EACX,YAAY,WAAW,MAAM,OAAO;EACpC,WAAW,SAAS,MAAM,OAAO;EAClC,CAAC;CAON,MAAM,WAAW,YAAY,KAAK;AAClC,KAAI,WAAW,SAAS,EAAE;EACxB,MAAM,UAAU,uBAAuB;AACvC,OAAK,KAAK;GACR,IAAI;GACJ,aAAa,UACT,4CAA4C,cAAc,KAC1D,oCAAoC,sBAAsB,UAAU,cAAc,cAAc;GACpG,MAAM;GACN,WAAW,CAAC;GACZ,YAAY;GACZ,WAAW,SAAS,SAAS;GAC9B,CAAC;;AAKJ,MAAK,KAAK;EACR,IAAI;EACJ,aACE;EACF,MAAM,QAAQ,KAAK;EACnB,WAAW;EACX,YAAY,CAAC,QAAQ,YAAY,WAAW,QAAQ,KAAK,CAAC;EAC1D,WAAW;EACZ,CAAC;AAEF,QAAO;;;AAIT,SAAgB,WAAW,MAAgC;AACzD,QAAO,KACJ,QAAQ,MAAM,EAAE,WAAW,CAC3B,KAAK,GAAG,MAAM;EACb,MAAM,MAAM,EAAE,YAAY,YAAY;EACtC,MAAM,KACJ,EAAE,YAAY,IAAI,KAAK,WAAW,EAAE,UAAU,CAAC,KAAK;AACtD,SAAO,KAAK,IAAI,EAAE,IAAI,EAAE,cAAc,MAAM,KAAK,EAAE,OAAO,UAAU,EAAE,SAAS;GAC/E,CACD,KAAK,KAAK;;AAGf,SAAS,WAAW,GAAmB;AACrC,KAAI,IAAI,KAAM,QAAO,GAAG,EAAE;AAC1B,KAAI,IAAI,OAAO,KAAM,QAAO,IAAI,IAAI,MAAM,QAAQ,EAAE,CAAC;AACrD,QAAO,IAAI,KAAK,OAAO,OAAO,QAAQ,EAAE,CAAC;;;;;ACnO3C,MAAM,eAAe,CAAC,CAAC,QAAQ,OAAO,SAAS,CAAC,QAAQ,IAAI;AAE5D,SAAS,OAAO,GAAmB;AAKjC,QAAO,eAAe,iBAAiB,EAAE,WAAW;;AAGtD,SAAS,IAAI,GAAmB;AAC9B,QAAO,eAAe,UAAU,EAAE,YAAY;;AAGhD,SAAS,KAAK,GAAmB;AAC/B,QAAO,eAAe,UAAU,EAAE,YAAY;;AAGhD,SAAS,mBAA2B;CAClC,MAAM,IAAI,QAAQ,OAAO;AACzB,QAAO,OAAO,MAAM,YAAY,IAAI,IAAI,IAAI;;AAG9C,MAAM,UAAU;AAMhB,SAAS,WAAW,SAAyB;CAS3C,MAAM,QAAkB,CAAC,IAAI,GARhB;EACX;EACA;EACA;EACA;EACA;EACA;EACD,CACoC,KAAK,SAAS,OAAO,OAAO,KAAK,CAAC,CAAC;AACxE,OAAM,KAAK,GAAG;AACd,OAAM,KAAK,OAAO,KAAK,QAAQ,GAAG,OAAO,IAAI,IAAI,UAAU,CAAC;AAC5D,OAAM,KAAK,GAAG;AACd,QAAO,MAAM,KAAK,KAAK;;AAGzB,SAAS,cAAc,SAAyB;AAG9C,QAAO;EAAC;EAFM,OAAO,KAAK,OAAO,cAAc,CAAC;EACnC,OAAO,IAAI,IAAI,QAAQ,KAAK,UAAU;EAC1B;EAAG,CAAC,KAAK,KAAK;;AAGzC,SAAS,cAAc,SAAyB;AAC9C,QAAO,GAAG,OAAO,cAAc,CAAC,GAAG,IAAI,IAAI,UAAU;;AAGvD,SAAgB,aAAa,SAAuB;CAClD,MAAM,QAAQ,kBAAkB;CAChC,IAAI;AACJ,KAAI,SAAS,IACX,OAAM,WAAW,QAAQ;UAChB,SAAS,GAClB,OAAM,cAAc,QAAQ;KAE5B,OAAM,cAAc,QAAQ;AAE9B,SAAQ,OAAO,MAAM,MAAM,KAAK;;;;;ACvBlC,MAAM,WAAkB;CACtB,eAAe;CACf,WAAW;CACX,YAAY,EAAE;CACd,cAAc;CACd,YAAY;CACZ,aAAa;CACb,mBAAmB;CACnB,oBAAoB;CACpB,YAAY;CACb;AAED,SAAgB,WAAmB;AACjC,QAAO,KAAK,SAAS,EAAE,eAAe;;AAGxC,SAAgB,YAAoB;AAClC,QAAO,KAAK,UAAU,EAAE,mBAAmB;;AAG7C,SAAgB,YAAmB;AACjC,KAAI;AACF,MAAI,CAAC,WAAW,WAAW,CAAC,CAAE,QAAO,EAAE,GAAG,UAAU;EACpD,MAAM,MAAM,aAAa,WAAW,EAAE,QAAQ;EAC9C,MAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,SAAO;GAAE,GAAG;GAAU,GAAG;GAAQ,eAAe;GAAG;SAC7C;AACN,SAAO,EAAE,GAAG,UAAU;;;AAI1B,SAAgB,WAAW,GAAyB;AAClD,KAAI;AAEF,YADY,UAAU,EACP,EAAE,WAAW,MAAM,CAAC;EAEnC,MAAM,OAAc;GAAE,GADN,WAAW;GACO,GAAG;GAAG,eAAe;GAAG;EAC1D,MAAM,SAAS,WAAW;EAC1B,MAAM,MAAM,SAAS;EAMrB,MAAM,KAAK,SAAS,KAAK,KAAK,IAAM;AACpC,MAAI;AACF,aAAU,IAAI,KAAK,UAAU,MAAM,MAAM,EAAE,GAAG,KAAK;AACnD,OAAI;AACF,cAAU,GAAG;WACP;YAKA;AACR,aAAU,GAAG;;AAEf,aAAW,KAAK,OAAO;SACjB;;AAKV,SAAgB,aAAmB;AACjC,KAAI;AACF,aAAW,WAAW,CAAC;SACjB;;AAKV,SAAgB,aAAsB;AAKpC,KAAI,CAAC,WAAW,WAAW,CAAC,CAAE,QAAO;AACrC,QAAO,WAAW,CAAC,eAAe;;;;;ACvHpC,MAAa,wBAAwB;CACnC,SAAS;CACT,MAAM,CAAC,MAAM,mBAAmB;CAChC,KAAK;EACH,iBAAiB;EACjB,oBAAoB;EACrB;CACF;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;;;;;AChEjC,MAAM,aAAa,KAAK,SAAS,EAAE,UAAU;AAC7C,MAAM,cAAc,KAAK,SAAS,EAAE,eAAe;AAQnD,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,YAA0B;CACrC,MAAM;CACN,aAAa;CACb,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;AAC3C,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,YAAY,EAC5B,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;AACD,SAAO;GAAE,MAAM;GAAa,aAAa;GAAa;GAAY;;CAErE;;;;AC9ED,MAAM,YAAY,KAAK,SAAS,EAAE,SAAS;AAC3C,MAAM,aAAa,KAAK,WAAW,cAAc;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,YAA0B;CACrC,MAAM;CACN,aAAa;CACb,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,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,YADD,GAAG,UADD,QAAQ,WAAW,KAAK,QAAQ,SAAS,KAAK,GAAG,KAAK,OAClC,QAAQ,SAAS,IAAI,OAAO,KAAK,cACpC,QAAQ;AAGxC,MAAI,CAAC,YADU,aAAa,YAAY,QAAQ,CACxB,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,uKACD;AACD,SAAO;GACL,MAAM;GACN,aAAa;GACb,GAAI,eAAe,UAAa,EAAE,YAAY;GAC/C;;CAEJ;;;;ACpFD,SAAS,aAAa,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;AAChB,QAAO;EACL,MAAM,OAAO;EACb,aAAa,OAAO;EACpB,GAAI,OAAO,SAAS,UAAa,EAAE,MAAM,OAAO,MAAM;EACtD,GAAI,OAAO,iBAAiB,UAAa,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,cAA2C,EAAE,EACxD;GAED,MAAM,aAAa,aAAa,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,6BAA6B,OAAO,aACzF;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;AACzB,QAAK,aAAa;AAClB,mBAAgB,OAAO,YAAY,KAAK;AAGxC,OAAI,CAAC,aADU,aAAwB,OAAO,WAAW,EAC/B,aAAa,eAAe,EAAE;AACtD,MAAE,IAAI,MACJ,wBAAwB,OAAO,WAAW,sDAC3C;AACD,WAAO;KAAE,MAAM;KAAW,QAAQ;KAAuB;;AAG3D,gBAAa,OAAO,aAAa,OAAO,WAAW;AACnD,UAAO;IACL,MAAM;IACN,aAAa,OAAO;IACpB,GAAI,eAAe,UAAa,EAAE,YAAY;IAC/C;;EAEJ;;;;;AC/FH,MAAaC,YAAU,qBAAqB;CAC1C,MAAM;CACN,aAAa;CACb,WAAW,KAAK,SAAS,EAAE,UAAU;CACrC,YAAY,KAAK,SAAS,EAAE,WAAW,WAAW;CAClD,MAAM;CACN,cACE;CACH,CAAC;;;;ACRF,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,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;;;;AC1CD,MAAaE,YAAU,qBAAqB;CAC1C,MAAM;CACN,aAAa;CACb,WAAW,KAAK,SAAS,EAAE,YAAY;CACvC,YAAY,KAAK,SAAS,EAAE,aAAa,gBAAgB;CACzD,MAAM;CACN,cACE;CACH,CAAC;;;;ACNF,MAAM,gBAAgB,KAAK,SAAS,EAAE,aAAa;AACnD,MAAMC,SAAO;AAEb,MAAaC,YAA0B;CACrC,MAAM;CACN,aAAa;CACb,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;;;;AClCD,MAAM,SAAS,KAAK,SAAS,EAAE,MAAM;AACrC,MAAM,aAAa,KAAK,QAAQ,SAAS,cAAc,cAAc;AACrE,MAAM,OAAO;AAEb,MAAa,UAA0B;CACrC,MAAM;CACN,aAAa;CACb,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;;;;;;;;;;;ACjCD,MAAa,WAAsC;CACjDE;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,MAKlB;CACA,MAAM,aAAuB,EAAE;CAC/B,IAAI,SAAS;CACb,IAAI,QAAQ;CACZ,IAAI,MAAM;AACV,MAAK,MAAM,KAAK,KACd,KAAI,MAAM,YAAa,UAAS;UACvB,MAAM,UAAW,SAAQ;UACzB,MAAM,QAAS,OAAM;UACrB,CAAC,EAAE,WAAW,IAAI,CAAE,YAAW,KAAK,EAAE;AAEjD,QAAO;EAAE;EAAQ;EAAO;EAAK;EAAY;;AAG3C,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;AAC9D,KAAI,UAAU,KAAK,SAAS;AAC1B,IAAE,MAAM,sBAAsB;AAC9B,IAAE,IAAI,KACJ,wIACD;AACD,IAAE,MAAM,8CAA8C;AACtD;;CAGF,MAAM,EAAE,QAAQ,OAAO,KAAK,eAAe,WAAW,KAAK;CAC3D,MAAM,OAAuB;EAAE;EAAQ;EAAO;AAE9C,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,OAAO,OAAO,OAAO,cAAc,MAAM,OAAO,gBAAgB;GACzE,KAAK,gBACH,QAAO,OAAO,KAAK;GACrB,KAAK,OACH,QAAO,OAAO,KAAK,6BAA6B,OAAO,OAAO;GAChE,KAAK,UACH,QAAO,OAAO,KAAK,aAAa,OAAO,OAAO;;GAElD;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;AAEH,GAAE,MAAM,0EAA0E;;;;;AC5IpF,MAAMC,cAAY,QAAQ,cAAc,OAAO,KAAK,IAAI,CAAC;AAKzD,MAAM,gBAAmE;CACvE;EAAE,OAAO;EAAe,OAAO;EAAe,OAAO;EAAK;CAC1D;EAAE,OAAO;EAAS,OAAO;EAAS,OAAO;EAAK;CAC9C;EAAE,OAAO;EAAa,OAAO;EAAa,OAAO;EAAK;CACtD;EAAE,OAAO;EAAY,OAAO;EAAY,OAAO;EAAK;CACpD;EAAE,OAAO;EAAU,OAAO;EAAU,OAAO;EAAK;CAChD;EAAE,OAAO;EAAM,OAAO;EAAM,OAAO;EAAK;CACxC;EAAE,OAAO;EAAU,OAAO;EAAU,OAAO;EAAK;CAChD;EAAE,OAAO;EAAc,OAAO;EAAc,OAAO;EAAK;CACzD;AAID,MAAM,aAAgE;CACpE;EAAE,OAAO;EAAY,OAAO;EAAY,OAAO;EAAK;CACpD;EAAE,OAAO;EAAS,OAAO;EAAS,OAAO;EAAK;CAC9C;EAAE,OAAO;EAAS,OAAO;EAAS,OAAO;EAAK;CAC9C;EAAE,OAAO;EAAQ,OAAO;EAAQ,OAAO;EAAK;CAC5C;EAAE,OAAO;EAAS,OAAO;EAAS,OAAO;EAAK;CAC9C;EAAE,OAAO;EAAkB,OAAO;EAAkB,OAAO;EAAK;CAChE;EAAE,OAAO;EAAY,OAAO;EAAY,OAAO;EAAK;CACpD;EAAE,OAAO;EAAO,OAAO;EAAO,OAAO;EAAK;CAC3C;AAED,MAAM,YAAuE;CAC3E;EAAE,OAAO;EAAa,OAAO;EAAsB,QAAQ;EAAqB;CAChF;EAAE,OAAO;EAAU,OAAO;EAAgB,QAAQ;EAAkB;CACpE;EAAE,OAAO;EAAU,OAAO;EAAmB,QAAQ;EAAkB;CACvE;EAAE,OAAO;EAAc,OAAO;EAA4B,QAAQ;EAAsB;CACxF;EAAE,OAAO;EAAW,OAAO;EAAwB,QAAQ;EAAmB;CAC9E;EAAE,OAAO;EAAQ,OAAO;EAAsC,QAAQ;EAAM;CAC7E;AAED,SAAS,oBAAuE;AAC9E,QAAO,CACL,GAAG,cAAc,KAAK,OAAO;EAC3B,OAAO,EAAE;EACT,OAAO,GAAG,EAAE,MAAM,GAAG,EAAE;EACvB,MAAM;EACP,EAAE,EACH,GAAG,WAAW,KAAK,OAAO;EACxB,OAAO,EAAE;EACT,OAAO,GAAG,EAAE,MAAM,GAAG,EAAE;EACvB,MAAM;EACP,EAAE,CACJ;;AAOH,SAASC,mBAAgC;CACvC,MAAM,aAAa;EACjB,KAAKD,aAAW,MAAM,MAAM,eAAe;EAC3C,KAAKA,aAAW,MAAM,eAAe;EACrC,KAAKA,aAAW,eAAe;EAC/B,KAAK,QAAQ,KAAK,EAAE,eAAe;EACpC;AACD,MAAK,MAAM,KAAK,WACd,KAAI,WAAW,EAAE,CAAE,QAAO;AAE5B,QAAO;;AAGT,eAAe,YAAY,UAAiD;CAC1E,MAAM,SAAS,KAAK,SAAS,EAAE,gBAAgB,OAAO;AAEtD,OAAM,MADM,QAAQ,OAAO,EACV,EAAE,WAAW,MAAM,CAAC;CAErC,MAAM,WAAWC,kBAAgB;AACjC,KAAI,YAAY,CAAC,WAAW,OAAO,CACjC,KAAI;AACF,QAAM,SAAS,UAAU,QAAQC,UAAY,cAAc;UACpD,KAAK;AACZ,MAAK,KAA+B,SAAS,SAC3C,QAAO;;UAGF,CAAC,YAAY,CAAC,WAAW,OAAO,EAAE;EAI3C,MAAM,QAAQ;GACZ;GACA;GACA;GACD;EACD,MAAM,SAAS,UAAU,MAAM,MAAM,EAAE,UAAU,SAAS,EAAE;AAC5D,MAAI,OACF,OAAM,KAAK,KAAK,OAAO,GAAG;AAE5B,gBAAc,QAAQ,MAAM,KAAK,KAAK,EAAE,EAAE,MAAM,KAAO,CAAC;;AAG1D,QAAO;;AAQT,eAAsB,gBAA2C;AAC/D,GAAE,KACA;EACE;EACA;EACA;EACA;EACA;EACD,CAAC,KAAK,KAAK,EACZ,kBACD;CAED,MAAM,eAAe,MAAM,EAAE,YAAoB;EAC/C,SAAS;EACT,SAAS,mBAAmB;EAC5B,UAAU;EACV,eAAe,CAAC,cAAc;EAC/B,CAAC;AACF,KAAI,EAAE,SAAS,aAAa,EAAE;AAC5B,IAAE,OAAO,6DAA6D;AACtE,UAAQ,KAAK,EAAE;;AAIjB,MAD0B,gBAA6B,EAAE,EACpC,SAAS,EAC5B,GAAE,KACA;EACE;EACA;EACA;EACA;EACD,CAAC,KAAK,KAAK,CACb;CAGH,MAAM,iBAAiB,MAAM,EAAE,OAAe;EAC5C,SAAS;EACT,SAAS,UAAU,KAAK,EAAE,OAAO,aAAa;GAAE;GAAO;GAAO,EAAE;EAChE,cAAc;EACf,CAAC;AACF,KAAI,EAAE,SAAS,eAAe,EAAE;AAC9B,IAAE,OAAO,6DAA6D;AACtE,UAAQ,KAAK,EAAE;;CAGjB,MAAM,WAAW,mBAAmB,SAAS,OAAO;CACpD,MAAM,SAAU,gBAA6B,EAAE;CAE/C,MAAM,UAAU,MAAM,YAAY,SAAS;AAE3C,YAAW;EACT,WAAW,OAAO,MAAM;EACxB,YAAY;EACZ,cAAc;EACd,YAAY;EACZ,6BAAY,IAAI,MAAM,EAAC,aAAa;EACrC,CAAC;CAGF,MAAM,QAAQ,CAAC,0BADO,KAAK,SAAS,EAAE,gBAAgB,mBAAmB,GAChB;AACzD,KAAI,QACF,OAAM,KAAK,WAAW,QAAQ,6BAA6B;KAE3D,OAAM,KAAK,yFAAyF;AAEtG,KAAI,UAAU;EACZ,MAAM,SAAS,UAAU,MAAM,MAAM,EAAE,UAAU,SAAS,EAAE;AAC5D,MAAI,OACF,OAAM,KAAK,eAAe,OAAO,2BAA2B,SAAS,GAAG;OAG1E,OAAM,KAAK,iEAAiE;AAE9E,GAAE,KAAK,MAAM,KAAK,KAAK,EAAE,QAAQ;AAEjC,KAAI,OAAO,SAAS,EAClB,OAAM,mBAAmB,OAAO;AAGlC,QAAO;EAAE;EAAQ;EAAU;;AAG7B,eAAe,mBAAmB,QAAiC;AACjE,GAAE,KAAK,6BAA6B,YAAY;CAChD,MAAM,YAAY,MAAM,EAAE,QAAQ;EAChC,SAAS;EACT,cAAc;EACf,CAAC;AAEF,KAAI,EAAE,SAAS,UAAU,IAAI,cAAc,OAAO;EAChD,MAAM,OAAO,OAAO,KAAK,MAAM,yBAAyB,IAAI;AAC5D,IAAE,KAAK,CAAC,oBAAoB,GAAG,KAAK,CAAC,KAAK,KAAK,EAAE,QAAQ;AACzD;;CAGF,MAAM,QAAkB,EAAE;CAC1B,MAAM,SAA4C,EAAE;CACpD,MAAM,SAA6C,EAAE;AAErD,MAAK,MAAM,QAAQ,QAAQ;EACzB,MAAM,UAAU,eAAe,KAAK;AACpC,MAAI,CAAC,SAAS;AACZ,UAAO,KAAK;IAAE;IAAM,QAAQ;IAAwB,CAAC;AACrD,KAAE,IAAI,KAAK,UAAU,KAAK,mCAAmC;AAC7D;;AAEF,IAAE,IAAI,KAAK,UAAU,KAAK,KAAK;EAC/B,IAAI;AACJ,MAAI;AACF,YAAS,MAAM,WAAW,SAAS;IAAE,QAAQ;IAAO,OAAO;IAAO,CAAC;WAC5D,KAAK;GACZ,MAAM,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;AAC/D,UAAO,KAAK;IAAE;IAAM;IAAQ,CAAC;AAC7B,KAAE,IAAI,MAAM,GAAG,KAAK,IAAI,SAAS;AACjC;;AAEF,UAAQ,OAAO,MAAf;GACE,KAAK;GACL,KAAK;AACH,UAAM,KAAK,KAAK;AAChB;GACF,KAAK;AACH,WAAO,KAAK;KAAE;KAAM,MAAM,QAAQ;KAAM,CAAC;AACzC;GACF,KAAK;AACH,WAAO,KAAK;KAAE;KAAM,QAAQ,OAAO;KAAQ,CAAC;AAC5C;;;CAIN,MAAM,UAAoB,EAAE;AAC5B,KAAI,MAAM,SAAS,EACjB,SAAQ,KAAK,UAAU,MAAM,KAAK,KAAK,CAAC,GAAG;AAE7C,KAAI,OAAO,SAAS,KAAK,OAAO,SAAS,GAAG;EAC1C,MAAM,QAAkB,EAAE;AAC1B,OAAK,MAAM,KAAK,OACd,OAAM,KAAK,GAAG,EAAE,KAAK,2BAA2B,EAAE,OAAO,UAAU,EAAE,SAAS,GAAG,GAAG;AAEtF,OAAK,MAAM,KAAK,OACd,OAAM,KAAK,GAAG,EAAE,KAAK,IAAI,EAAE,OAAO,GAAG;AAEvC,UAAQ,KAAK,mBAAmB,MAAM,KAAK,KAAK,CAAC,GAAG;;AAEtD,KAAI,QAAQ,WAAW,EACrB,SAAQ,KAAK,wBAAwB;AAEvC,GAAE,KAAK,QAAQ,KAAK,KAAK,EAAE,eAAe;;;;;AClQ5C,SAAS,IAAI,OAAe,KAAa,QAAwB;AAC/D,KAAI,CAAC,UAAU,OAAO,KAAK,OAAO,CAAC,WAAW,EAC5C,QAAO,iBAAiB,MAAM,GAAG;AAEnC,KAAI;AACF,SAAO,iBAAiB,MAAM,GAAG,IAAI,GAAG,KAAK,UAAU,OAAO;SACxD;AAGN,SAAO,iBAAiB,MAAM,GAAG;;;AAIrC,SAAS,KAAK,OAAe,KAAa,QAAsB;AAC9D,KAAI;AACF,UAAQ,OAAO,MAAM,IAAI,OAAO,KAAK,OAAO,GAAG,KAAK;SAC9C;;AAMV,MAAa,SAAS;CACpB,KAAK,KAAa,QAAuB;AACvC,OAAK,QAAQ,KAAK,OAAO;;CAE3B,KAAK,KAAa,QAAuB;AACvC,OAAK,QAAQ,KAAK,OAAO;;CAE3B,MAAM,KAAa,QAAuB;AACxC,OAAK,SAAS,KAAK,OAAO;;CAE7B;AAaD,IAAI,cACF,QAAQ,IAAI,2BAA2B,OACvC,QAAQ,IAAI,2BAA2B;AAEzC,MAAM,aAAuB,EAAE;AAE/B,SAAgB,eAAe,SAAwB;AACrD,eAAc;;AAOhB,SAAgB,QAAQ,KAAmB;AACzC,KAAI,aAAa;AACf,MAAI;AACF,WAAQ,OAAO,MAAM,iBAAiB,IAAI,IAAI;UACxC;AAGR;;AAEF,KAAI,WAAW,SAAS,IAAK,YAAW,KAAK,IAAI;;;;;AChGnD,MAAa,UAAU;;;;AC8CvB,MAAM,YAAY,QAAQ,cAAc,OAAO,KAAK,IAAI,CAAC;AACzD,MAAM,OAAO,QAAQ,KAAK,MAAM,EAAE;AAClC,MAAM,aAAa,UAAU,KAAK;AAClC,MAAM,aACJ,KAAK,SAAS,YAAY,IAC1B,KAAK,SAAS,KAAK,IACnB,QAAQ,IAAI,2BAA2B,OACvC,QAAQ,IAAI,2BAA2B;AAMzC,eAAe,WAAW;AAE1B,MAAM,WAAW,KAAK,SAAS,UAAU;AAYzC,MAAM,mBACJ,QAAQ,IAAI,8BAA8B;AAI5C,SAAS,kBAAiC;CACxC,MAAM,IAAI,UAAU;CACpB,MAAM,IAAI,QAAQ;AAClB,KAAI,MAAM,YAAY,MAAM,QAC1B,QAAO;AACT,KAAI,MAAM,YAAY,MAAM,MAC1B,QAAO;AACT,KAAI,MAAM,WAAW,MAAM,MACzB,QAAO;AACT,KAAI,MAAM,WAAW,MAAM,QACzB,QAAO;AACT,KAAI,MAAM,WAAW,MAAM,MACzB,QAAO;AACT,KAAI,MAAM,WAAW,MAAM,MACzB,QAAO;AACT,KAAI,MAAM,WAAW,MAAM,QACzB,QAAO;AACT,QAAO;;AAGT,SAAS,gBAA+B;CACtC,MAAM,QAAQ,iBAAiB;AAC/B,KAAI,CAAC,MAAO,QAAO;AAGnB,QAAO,wDAAwD,iBAAiB,GAAG;;AAGrF,SAAS,KAAK,KAAmB;AAC/B,KAAI,WAAY,GAAE,IAAI,KAAK,aAAa,MAAM;;AAGhD,IAAI,KAAK,SAAS,SAAS,IAAI,KAAK,SAAS,KAAK,EAAE;AAClD,SAAQ,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6EA2C+D,iBAAiB;;;;;;;;;;EAU5F;AACA,SAAQ,KAAK,EAAE;;AAGjB,MAAM,WAAW,KAAK,QAAQ,UAAU;AACxC,IAAI,aAAa,MAAM,KAAK,WAAW,GACrC,SAAQ,IAAI,uBAAuB,KAAK,WAAW;AAGrD,MAAM,UAAU,KAAK,QAAQ,SAAS;AACtC,IAAI,YAAY,MAAM,KAAK,UAAU,GACnC,SAAQ,IAAI,mBAAmB,KAAK,UAAU;AAGhD,MAAM,aAAa,KAAK,SAAS,cAAc;AAE/C,SAAS,cAAsB;CAC7B,MAAM,MAAM,QAAQ,IAAI;AACxB,KAAI,IACF,KAAI;EACF,MAAM,SAAS,IAAI,IAAI,IAAI,CAAC;AAC5B,MAAI,OAAQ,QAAO,SAAS,QAAQ,GAAG;SACjC;AAEV,QAAO,SAAS,QAAQ,IAAI,oBAAoB,QAAQ,GAAG,IAAI;;AAGjE,SAAS,aAAqB;CAC5B,MAAM,MAAM,QAAQ,IAAI;AACxB,KAAI,IAAK,QAAO,IAAI,QAAQ,QAAQ,GAAG;AACvC,QAAO,oBAAoB,aAAa;;AAG1C,SAAS,eAAuB;CAC9B,MAAM,SAAS,QAAQ,IAAI;AAC3B,KAAI,OAAQ,QAAO,OAAO,QAAQ,QAAQ,GAAG;AAC7C,KAAI;EACF,MAAM,IAAI,IAAI,IAAI,YAAY,CAAC;EAC/B,MAAM,QACJ,SAAS,QAAQ,IAAI,sBAAsB,IAAI,GAAG,KACjD,SAAS,EAAE,QAAQ,QAAQ,GAAG,IAAI,QAAQ;AAC7C,SAAO,GAAG,EAAE,SAAS,IAAI,EAAE,SAAS,GAAG;SACjC;AAIN,SAAO,oBAFL,SAAS,QAAQ,IAAI,sBAAsB,IAAI,GAAG,IAClD,aAAa,GAAG;;;AAUtB,SAAS,gBAAwB;AAC/B,QACE,SAAS,QAAQ,IAAI,sBAAsB,IAAI,GAAG,IAClD,SAAS,QAAQ,IAAI,uBAAuB,IAAI,GAAG,IACnD;;AAOJ,SAAS,gBAAwB;CAC/B,MAAM,WAAW,SAAS,QAAQ,IAAI,sBAAsB,IAAI,GAAG;AACnE,KAAI,SAAU,QAAO;CACrB,MAAM,MAAM,QAAQ,IAAI;AACxB,KAAI,IACF,KAAI;EACF,MAAM,SAAS,IAAI,IAAI,IAAI,CAAC;AAC5B,MAAI,OAAQ,QAAO,SAAS,QAAQ,GAAG;SACjC;AAEV,QAAO;;AAGT,eAAe,kBAAoC;AACjD,KAAI;AACF,QAAM,MAAM,GAAG,YAAY,CAAC,IAAI,EAC9B,QAAQ,YAAY,QAAQ,IAAK,EAClC,CAAC;AACF,SAAO;SACD;AACN,SAAO;;;AAIX,eAAe,qBAAuC;AACpD,KAAI;AAIF,UAHY,MAAM,MAAM,GAAG,YAAY,CAAC,qBAAqB,EAC3D,QAAQ,YAAY,QAAQ,IAAK,EAClC,CAAC,EACS;SACL;AACN,SAAO;;;AAIX,SAAS,gBAAwB;CAC/B,MAAM,aAAa;EACjB,KAAK,WAAW,kBAAkB;EAClC,KAAK,WAAW,MAAM,kBAAkB;EACxC,KAAK,QAAQ,KAAK,EAAE,kBAAkB;EACvC;AACD,MAAK,MAAM,KAAK,WACd,KAAI,WAAW,EAAE,CAAE,QAAO;AAE5B,QAAO;;AAGT,SAAS,YAAY,MAA6B;CAChD,MAAM,MAAM,aAAa,UAAU;AACnC,KAAI;AASF,SARY,aAAa,KAAK,CAAC,KAAK,EAAE;GACpC,UAAU;GACV,OAAO;IAAC;IAAU;IAAQ;IAAO;GAClC,CAAC,CAEC,MAAM,QAAQ,CACd,KAAK,SAAS,KAAK,MAAM,CAAC,CAC1B,MAAM,SAAS,KAAK,SAAS,EAAE,IAClB;SACV;AACN,SAAO;;;AAIX,SAAS,mBAA6B;AACpC,KAAI,YAAY;EACd,MAAM,cAAc,QAAQ,IAAI;AAChC,MAAI,CAAC,YAAa,QAAO,EAAE;AAC3B,SAAO,CACL,KAAK,aAAa,UAAU,OAAO,UAAU,EAC7C,KAAK,aAAa,OAAO,UAAU,CACpC;;CAEH,MAAM,OAAO,QAAQ,IAAI;AACzB,KAAI,CAAC,KAAM,QAAO,CAAC,qBAAqB;AACxC,QAAO,CAAC,KAAK,MAAM,UAAU,OAAO,MAAM,EAAE,qBAAqB;;AAGnE,SAAS,cAAc,SAAgC;AACrD,KAAI;EAMF,MAAM,QALM,aAAa,SAAS,CAAC,YAAY,EAAE;GAC/C,UAAU;GACV,OAAO;IAAC;IAAU;IAAQ;IAAS;GACnC,SAAS;GACV,CAAC,CACgB,MAAM,iCAAiC;AACzD,SAAO,QAAQ,MAAM,KAAM;SACrB;AACN,SAAO;;;AAIX,IAAI,wBAAwB;AAC5B,SAAS,4BAA4B,YAA6C;AAChF,KAAI,CAAC,cAAc,sBAAuB;CAC1C,MAAM,WAAW,cAAc,WAAW;AAC1C,KAAI,CAAC,YAAY,aAAa,iBAAkB;AAChD,yBAAwB;CACxB,MAAM,QAAQ,iBAAiB;CAC/B,MAAM,eAAe,QACjB,mEAAmE,iBAAiB,GAAG,MAAM,8BAC7F,aAAa,iBAAiB,0DAA0D;AAC5F,GAAE,IAAI,KACJ,0BAA0B,SAAS,oBAAoB,QAAQ,SAAS,iBAAiB,gCAAgC,SAAS,oCAAoC,aAAa,IACpL;;AAGH,SAAS,oBAA4B;AACnC,QAAO,KAAK,SAAS,EAAE,gBAAgB,UAAU;;AAGnD,SAAS,kBAA0B;AACjC,QAAO,KAAK,SAAS,EAAE,gBAAgB,oBAAoB;;AAO7D,SAAS,mBAAmB,KAAmB;AAC7C,KAAI;EACF,MAAM,UAAU,mBAAmB;AACnC,YAAU,QAAQ,QAAQ,EAAE,EAAE,WAAW,MAAM,CAAC;AAChD,gBAAc,SAAS,GAAG,IAAI,KAAK,EAAE,UAAU,SAAS,CAAC;UAClD,KAAK;AACZ,OAAK,uBAAuB,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,GAAG;;;AAInF,SAAS,oBAAmC;AAC1C,KAAI;EACF,MAAM,SAAS,aAAa,mBAAmB,EAAE,QAAQ,CAAC,MAAM;EAChE,MAAM,MAAM,SAAS,QAAQ,GAAG;AAChC,SAAO,OAAO,SAAS,IAAI,IAAI,MAAM,IAAI,MAAM;SACzC;AACN,SAAO;;;AAIX,SAAS,qBAA2B;AAClC,KAAI;AACF,aAAW,mBAAmB,CAAC;SACzB;;AAGV,SAAS,iBAAiB,OAA0B;AAClD,KAAI;EACF,MAAM,YAAY,iBAAiB;AACnC,YAAU,QAAQ,UAAU,EAAE,EAAE,WAAW,MAAM,CAAC;AAClD,gBAAc,WAAW,GAAG,KAAK,UAAU,MAAM,CAAC,KAAK,EAAE,UAAU,SAAS,CAAC;UACtE,KAAK;AACZ,OAAK,qBAAqB,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,GAAG;;;AAIjF,SAAS,kBAAsC;AAC7C,KAAI;EACF,MAAM,MAAM,aAAa,iBAAiB,EAAE,QAAQ;EACpD,MAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,MAAI,WAAW,OAAO,SAAS,YAAY,OAAO,SAAS,UACzD,QAAO;AAET,SAAO;SACD;AACN,SAAO;;;AAIX,SAAS,mBAAyB;AAChC,KAAI;AACF,aAAW,iBAAiB,CAAC;SACvB;;AAGV,SAAS,sBAAqC;AAM5C,QALmB;EACjB,KAAK,WAAW,MAAM,qBAAqB;EAC3C,KAAK,WAAW,qBAAqB;EACrC,KAAK,QAAQ,KAAK,EAAE,qBAAqB;EAC1C,CACiB,MAAM,MAAM,WAAW,EAAE,CAAC,IAAI;;AAGlD,SAAS,kBAA2B;AAClC,KAAI,QAAQ,IAAI,2BAA2B,MAAO,QAAO;AAEzD,MADc,QAAQ,KAAK,MAAM,IACvB,SAAS,OAAO,CAAE,QAAO;CACnC,MAAM,KAAK,QAAQ,IAAI,4BAA4B;AACnD,KAAI,GAAG,WAAW,OAAO,IAAI,GAAG,SAAS,QAAQ,CAAE,QAAO;AAC1D,QAAO;;AAOT,eAAe,0BAAyC;AACtD,KAAI,CAAC,iBAAiB,CAAE;AACxB,KAAI,CAAC,QAAQ,MAAM,MAAO;AAC1B,KAAI,QAAQ,IAAI,MAAO;CACvB,MAAM,QAAQ,WAAW;AACzB,KAAI,MAAM,qBAAqB,MAAM,YAAa;CAElD,MAAM,SAAS,MAAM,EAAE,QAAQ;EAC7B,SACE;EACF,cAAc;EACf,CAAC;AACF,KAAI,EAAE,SAAS,OAAO,CAEpB;AAEF,KAAI,WAAW,OAAO;AACpB,aAAW,EAAE,mBAAmB,MAAM,CAAC;AACvC,IAAE,IAAI,KACJ,oHACD;AACD;;CAGF,MAAM,SAAS,YAAY,MAAM;AACjC,KAAI,CAAC,QAAQ;AACX,IAAE,IAAI,KACJ,mFACD;AACD;;AAOF,KALW,WACT,QACA;EAAC;EAAW;EAAM,4BAA4B;EAAU,EACxD,EAAE,OAAO,uCAAuC,QAAQ,YAAY,CACrE,EACO;AACN,IAAE,IAAI,QACJ,2EACD;AAGD,aAAW,EAAE,mBAAmB,MAAM,CAAC;OAEvC,GAAE,IAAI,KACJ,+EACD;;AAeL,SAAS,mBAAoC;CAC3C,MAAM,SAAS,YAAY,cAAc;AACzC,KAAI,OAAQ,QAAO;EAAE,MAAM;EAAa,SAAS;EAAQ;CACzD,MAAM,WAAW,aACb,KAAK,QAAQ,IAAI,kBAAkB,IAAI,UAAU,OAAO,kBAAkB,GAC1E,KAAK,SAAS,EAAE,UAAU,OAAO,cAAc;AACnD,KAAI,YAAY,WAAW,SAAS,CAClC,QAAO;EAAE,MAAM;EAAa,SAAS;EAAU;AAEjD,QAAO,EAAE,MAAM,WAAW;;AAY5B,MAAM,0BACJ;AAEF,eAAe,mBAA6C;CAC1D,MAAM,QAAQ,kBAAkB;AAChC,KAAI,MAAM,SAAS,YAAa,QAAO;AAGvC,KAAI,CAAC,QAAQ,MAAM,SAAS,QAAQ,IAAI,MAAO,QAAO;AAEtD,KADc,WAAW,CACf,mBAAoB,QAAO;CAErC,MAAM,SAAS,MAAM,EAAE,QAAQ;EAC7B,SACE;EACF,cAAc;EACf,CAAC;AACF,KAAI,EAAE,SAAS,OAAO,CAAE,QAAO;AAC/B,KAAI,WAAW,OAAO;AACpB,aAAW,EAAE,oBAAoB,MAAM,CAAC;AACxC,SAAO;;CAGT,MAAM,QAAQ,YAAY,KAAK;CAC/B,MAAM,UAAU,YAAY,OAAO;AACnC,KAAI,CAAC,SAAS,CAAC,SAAS;AACtB,IAAE,IAAI,KACJ,8CAA8C,0BAC/C;AACD,SAAO;;AAKT,KAAI,CAHO,WAAW,OAAO,CAAC,MAAM,wBAAwB,EAAE,EAC5D,OAAO,0BACR,CAAC,EACO;AACP,IAAE,IAAI,KACJ,mDAAmD,0BACpD;AACD,SAAO;;AAGT,QAAO,kBAAkB;;AAG3B,SAAS,qBAA2B;AAClC,KAAI;EACF,MAAM,gBAAgB,iBAAiB;EACvC,MAAM,cAAc,mBAAmB;AACvC,MAAI,iBAAiB,YAAa;EAGlC,MAAM,YADO,qBAAqB,aAAa,CAAC,CACzB;AACvB,MAAI,aAAa,CAAC,YAChB,oBAAmB,UAAU;AAE/B,MAAI,CAAC,cACH,kBAAiB;GACf,MAAM;GACN,YAAY,eAAe,IAAI;GAC/B,UAAU;GACX,CAAC;AAEJ,MAAI,aAAa,CAAC,YAChB,GAAE,IAAI,KAAK,wCAAwC,UAAU,GAAG;UAE3D,KAAK;AACZ,OAAK,uBAAuB,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,GAAG;;;AAInF,eAAe,kBAAoE;CACjF,MAAM,aAAa,eAAe;CAClC,MAAM,QAAQ,iBAAiB;CAC/B,MAAM,aAAa,OAAO,SAAS,OAAO,KAAK;AAE/C,KAAI,CAAC,YAAY;AACf,IAAE,IAAI,KACJ,uCAAuC,UAAU,CAAC,GAAG,QAAQ,KAAK,yCAAyC,iBAAiB,kFAAkF,iBAAiB,GAChO;AACD,SAAO;GAAE,IAAI;GAAO,SAAS;GAAM;;AAGrC,KAAI,cAAc,YAAY;AAC5B,IAAE,IAAI,KACJ,+BAA+B,UAAU,CAAC,KAAK,MAAM,0DAClC,WAAW,uHAEa,mBAC5C;AACD,SAAO;GAAE,IAAI;GAAO,SAAS;GAAM;;CAGrC,MAAM,QAAQ,YAAY,KAAK;CAC/B,MAAM,UAAU,YAAY,OAAO;AACnC,KAAI,CAAC,SAAS,CAAC,SAAS;AACtB,IAAE,IAAI,KAAK,wDAAwD;AACnE,SAAO;GAAE,IAAI;GAAO,SAAS;GAAM;;CAGrC,MAAM,SAAS,KAAK,SAAS,EAAE,UAAU,MAAM;CAC/C,MAAM,UAAU,KAAK,QAAQ,MAAM;AAUnC,KAAI,CAJgB,WAAW,OAAO,CAAC,MALpB;EACjB,aAAa,OAAO;EACpB,eAAe,WAAW,kBAAkB,OAAO;EACnD,aAAa,QAAQ;EACtB,CAAC,KAAK,OAAO,CAC0C,EAAE;EACxD,OAAO,0BAA0B,iBAAiB;EAClD,UAAU;EACX,CAAC,EACgB;AAChB,IAAE,IAAI,KACJ,4EAA4E,iBAAiB,kFAAkF,iBAAiB,GACjM;AACD,SAAO;GAAE,IAAI;GAAO,SAAS;GAAM;;AAErC,QAAO;EAAE,IAAI;EAAM;EAAS;;AAS9B,IAAI,iBAAwC;AAM5C,SAAS,sBACP,KACA,WACA,OACc;AACd,MAAK,UAAU,IAAI,GAAG,UAAU,KAAK,IAAI,GAAG;CAC5C,MAAM,QAAQ,MAAM,KAAK,WAAW;EAClC,UAAU;EACV,OAAO;GAAC;GAAU;GAAU;GAAO;EACnC,aAAa;EACd,CAAC;CACF,MAAM,WAAW,MAAM,SAAS,SAAS;AACzC,KAAI,CAAC,YAAY,OAAO,MAAM,QAAQ,SACpC,oBAAmB,MAAM,IAAI;CAE/B,MAAM,eAAyB,EAAE;CACjC,IAAI,cAAc;CAClB,MAAM,qBAAqB,KAAK;AAChC,OAAM,QAAQ,GAAG,SAAS,UAAkB;AAC1C,MAAI,eAAe,mBAAoB;EACvC,MAAM,QAAQ,MAAM,SAAS,GAAG,qBAAqB,YAAY;AACjE,eAAa,KAAK,MAAM;AACxB,iBAAe,MAAM;GACrB;AACF,OAAM,GAAG,SAAS,MAAM,WAAW;AAGjC,MADG,SAAS,QAAQ,SAAS,KAAO,SAAS,QAAQ,WAAW,MAClD;GACZ,MAAM,SAAS,OAAO,OAAO,aAAa,CAAC,SAAS,QAAQ;AAC5D,oBAAiB;IACf,MAAM,WAAW,mBAAmB;IACpC,QACE,OAAO,MAAM,KACZ,SACG,4BAA4B,WAC5B,4BAA4B;IAClC,QAAQ;IACT;AACD,QAAK,6BAA6B,KAAK,UAAU,SAAS;AAC1D,OAAI,cAAc,OAAO,MAAM,CAC7B,GAAE,IAAI,MAAM,mBAAmB,SAAS;AAE1C,OAAI,CAAC,SAAU,qBAAoB;AACnC,qBAAkB;;GAEpB;AACF,OAAM,OAAO;AACb,QAAO;;AAGT,SAAS,YAAY,QAAgB,YAA6B;AAChE,6BAA4B,OAAO;CACnC,MAAM,IAAI,EAAE,SAAS;AACrB,GAAE,MAAM,wBAAwB,SAAS;AACzC,kBAAiB;EAAE,MAAM;EAAU;EAAY,CAAC;AAChD,uBAAsB,QAAQ,CAAC,YAAY,WAAW,EAAE,aAAa;AACrE,GAAE,KAAK,6BAA6B;AACpC,QAAO;;AAGT,eAAe,cAAgC;CAC7C,MAAM,aAAa,eAAe;CAClC,IAAI,SAAS,YAAY,MAAM;AAC/B,MAAK,eAAe,UAAU,gBAAgB,YAAY,cAAc,gBAAgB;AAExF,KAAI,UAAU,WAAY,QAAO,YAAY,QAAQ,WAAW;AAEhE,MAAK,MAAM,WAAW,kBAAkB,CACtC,KAAI,WAAW,QAAQ,EAAE;EACvB,MAAM,IAAI,cAAc,QAAQ;AAChC,OAAK,mBAAmB,QAAQ,oBAAoB,KAAK,YAAY;AACrE,IAAE,IAAI,KAAK,iBAAiB,UAAU,IAAI,MAAM,EAAE,KAAK,KAAK;AAC5D,UAAQ,IAAI,UAAU,GAAG,QAAQ,QAAQ,GAAGC,YAAiB,QAAQ,IAAI,WAAW;AACpF,WAAS;AACT;;AAIJ,KAAI,UAAU,WAAY,QAAO,YAAY,QAAQ,WAAW;AAEhE,KAAI,CAAC,YAAY;AACf,mBAAiB,EAAE,MAAM,aAAa;AACtC,SAAO;;CAGT,MAAM,YAAY,YAAY,SAAS;AACvC,MAAK,kBAAkB,aAAa,kBAAkB;CAMtD,MAAM,cAL0B;EAC9B,KAAK,WAAW,MAAM,qBAAqB;EAC3C,KAAK,WAAW,qBAAqB;EACrC,KAAK,QAAQ,KAAK,EAAE,qBAAqB;EAC1C,CAC2C,MAAM,MAAM,WAAW,EAAE,CAAC;AACtE,MAAK,uBAAuB,eAAe,gBAAgB;CAE3D,MAAM,cACJ,QAAQ,IAAI,8BAA8B,OAC1C,QAAQ,IAAI,8BAA8B;CAC5C,MAAM,cAAc,CAAC,CAAC,QAAQ,MAAM,SAAS,CAAC,QAAQ,IAAI;CAG1D,IAAI;AAEJ,KAAI,eAAe,aAAa,YAC9B,UAAS;UACA,CAAC,aAAa;AACvB,WAAS;AACT,IAAE,IAAI,KAAK,qEAAqE;QAC3E;AACL,IAAE,IAAI,KAAK,uCAAuC;EAClD,MAAM,UAA6D,CACjE;GACE,OAAO;GACP,OAAO,gBAAgB,iBAAiB;GACxC,MAAM;GACP,CACF;AACD,MAAI,aAAa,YACf,SAAQ,KAAK;GAAE,OAAO;GAAU,OAAO;GAAsB,MAAM;GAAY,CAAC;AAElF,UAAQ,KAAK;GAAE,OAAO;GAAU,OAAO;GAAsC,CAAC;EAE9E,MAAM,SAAS,MAAM,EAAE,OAAe;GACpC,SAAS;GACT;GACA,cAAc;GACf,CAAC;AACF,MAAI,EAAE,SAAS,OAAO,EAAE;AACtB,oBAAiB,EAAE,MAAM,aAAa;AACtC,UAAO;;AAET,WAAS;;AAGX,KAAI,WAAW,UAAU;AACvB,mBAAiB,EAAE,MAAM,aAAa;AACtC,SAAO;;AAGT,KAAI,WAAW,WAAW;EACxB,MAAM,SAAS,MAAM,iBAAiB;AACtC,MAAI,OAAO,MAAM,OAAO,SAAS;AAC/B,WAAQ,IAAI,UAAU,GAAG,QAAQ,OAAO,QAAQ,GAAGA,YAAiB,QAAQ,IAAI,WAAW;AAC3F,YAAS,OAAO;AAChB,UAAO,YAAY,QAAQ,WAAW;;AAExC,MAAI,aAAa,eAAe,aAAa;GAC3C,MAAM,WAAW,MAAM,EAAE,QAAQ;IAC/B,SAAS;IACT,cAAc;IACf,CAAC;AACF,OAAI,EAAE,SAAS,SAAS,IAAI,aAAa,MAAM;AAC7C,qBAAiB,EAAE,MAAM,aAAa;AACtC,WAAO;;AAET,YAAS;SACJ;AACL,oBAAiB,EAAE,MAAM,aAAa;AACtC,UAAO;;;AAIX,KAAI,WAAW,YAAY,aAAa,aAAa;EACnD,MAAM,IAAI,EAAE,SAAS;AACrB,IAAE,MAAM,oCAAoC;AAC5C,mBAAiB;GAAE,MAAM;GAAU;GAAa,CAAC;AACjD,wBACE,WACA;GAAC;GAAW;GAAM;GAAa;GAAM;GAAK,EAC1C,wBACD;AACD,IAAE,KAAK,yBAAyB;AAChC,SAAO;;AAGT,KAAI,CAAC,eAAe,UAClB,kBAAiB,EAAE,MAAM,qBAAqB;KAE9C,kBAAiB,EAAE,MAAM,aAAa;AAExC,QAAO;;AAGT,eAAe,cAAc,WAAqC;CAChE,MAAM,QAAQ,KAAK,KAAK;AACxB,QAAO,KAAK,KAAK,GAAG,QAAQ,WAAW;AACrC,MAAI,MAAM,iBAAiB,CAAE,QAAO;AACpC,QAAM,IAAI,SAAS,MAAM,WAAW,GAAG,IAAI,CAAC;;AAE9C,QAAO;;AAGT,SAAS,sBAAgC;CACvC,MAAM,aAAa,eAAe;AAClC,KAAI,WACF,QAAO;EACL,iCAAiC,iBAAiB;EAClD;EACA;EACA,kEAAkE;EAClE;EACA;EACA;EACA;EACA,uCAAuC;EACvC;EACA;EACA;EACA;EACA;EACD;CAEH,MAAM,eAAe,aACjB,oBAAoB,WAAW,4DAC/B,2EAA2E;AAC/E,QAAO;EACL,iCAAiC,iBAAiB;EAClD;EACA;EACA;EACA;EACA,uCAAuC;EACvC;EACA;EACA;EACA;EACA;EACD;;AAGH,SAAS,oBAAoB,MAAsB;AACjD,QAAO,aACH,6BAA6B,SAC7B,cAAc,KAAK,4BAA4B;;AAGrD,eAAe,wBAAwB,WAAqC;CAC1E,MAAM,QAAQ,KAAK,KAAK;AACxB,QAAO,KAAK,KAAK,GAAG,QAAQ,WAAW;AACrC,MAAI,MAAM,oBAAoB,CAAE,QAAO;AACvC,QAAM,IAAI,SAAS,MAAM,WAAW,GAAG,IAAI,CAAC;;AAE9C,QAAO;;AAQT,SAAS,gBAAwB;AAC/B,MAAK,MAAM,UAAU,CAAC,kBAAkB,kBAAkB,EAAE;EAC1D,MAAM,MAAM,QAAQ,IAAI;AACxB,MAAI,CAAC,IAAK;AACV,MAAI;GACF,MAAM,SAAS,IAAI,IAAI,IAAI;AAC3B,OAAI,OAAO,SAAU,QAAO,OAAO;UAC7B;;AAEV,QAAO;;AAGT,SAAS,eAAe,cAAqC;CAI3D,MAAM,UAAU,YAAY;CAC5B,MAAM,YAAY,cAAc;CAChC,MAAM,aAAa,eAAe;CAClC,MAAM,YAAY,QAAQ,WAAW,GAAG,eAAe;CACvD,MAAM,YAAY,QAAQ,WAAW,GAAG,eAAe;CAEvD,MAAM,cACJ,aAAa,SAAS,cAOlB,gBAAgB,aAAa,QAAQ,UAAU,aAAa,QAAQ,eACpE,0BAA0B,wBAAwB;CAExD,MAAM,QAAQ;EACZ,gBAAgB;EAChB,gBAAgB;EAChB,gBAAgB;EAChB,gBAAgB;EAChB;EACD;AAID,GAAE,KAAK,MAAM,KAAK,KAAK,EAAE,gBAAgB,UAAU;CAOnD,MAAM,cAAc,iBAAiB,GACjC,sCACA;AACJ,SAAQ,OAAO,MAAM,UAAU,YAAY,IAAI;;AAGjD,eAAe,OAAO;AAGpB,KAAI,SACF,aAAY;CAGd,MAAM,WAAW,YAAY;CAC7B,MAAM,QAAQ,WAAW;AAKzB,KAAI,YAAY,YAAY,cAAc,CAAC,MAAM,WAC/C,cAAa,QAAQ;AAGvB,KAAI,YAAY,SACd,OAAM,eAAe;AAGvB,KAAI,YAAY;AACd,MAAI,WAAY,GAAE,IAAI,KAAK,sCAAsC;AACjE,QAAM,OAAO;AACb,MAAI,MAAM,wBAAwB,KAAM,EAAE;GACxC,MAAM,eAAe,MAAM,kBAAkB;AAC7C,SAAM,yBAAyB;AAC/B,kBAAe,aAAa;;AAE9B;;AAGF,KAAI,MAAM,iBAAiB,EAAE;AAC3B,MAAI,WAAY,GAAE,IAAI,QAAQ,wBAAwB;AAGtD,8BADE,YAAY,MAAM,IAAI,kBAAkB,CAAC,MAAM,MAAM,WAAW,EAAE,CAAC,IAAI,KACjC;AACxC,sBAAoB;AACpB,QAAM,OAAO;AACb,MAAI,MAAM,wBAAwB,KAAM,EAAE;GACxC,MAAM,eAAe,MAAM,kBAAkB;AAC7C,SAAM,yBAAyB;AAC/B,kBAAe,aAAa;;AAE9B;;AAIF,KAAI,CADY,MAAM,aAAa,EACrB;AACZ,IAAE,IAAI,MAAM,8BAA8B;EAC1C,MAAM,QAAQ,qBAAqB;AACnC,MAAI,gBAAgB,SAAS,oBAC3B,OAAM,QACJ,mEACA,qEACA,GACD;AAEH,IAAE,KAAK,MAAM,KAAK,KAAK,EAAE,iBAAiB;AAC1C,UAAQ,KAAK,EAAE;;CAGjB,MAAM,IAAI,EAAE,SAAS;AACrB,GAAE,MAAM,wCAAwC;AAGhD,KAAI,CADU,MAAM,cAAc,KAAM,EAC5B;EACV,MAAM,OAAO,aAAa;AAC1B,IAAE,KAAK,6CAA6C;AAEpD,MAAI,gBAAgB,SAAS,oBAAoB,gBAAgB,SAAS,kBAAkB;AAC1F,KAAE,IAAI,MAAM,6CAA6C;AACzD,OAAI,eAAe,OACjB,GAAE,IAAI,KAAK,WAAW,eAAe,SAAS;AAEhD,OAAI,eAAe,OACjB,GAAE,KAAK,eAAe,QAAQ,gBAAgB;OAE9C,GAAE,IAAI,KAAK,iEAAiE;AAE9E,KAAE,KACA;IACE;IACA;IACA;IACA;IACA;IACA;IACA;IACD,CAAC,KAAK,KAAK,EACZ,kBACD;SACI;AACL,KAAE,IAAI,MAAM,+DAA+D;AAC3E,KAAE,KACA;IACE,sBAAsB,KAAK;IAC3B,oBAAoB,KAAK;IACzB;IACA;IACA;IACA,uDAAuD,OAAO;IAC9D;IACD,CAAC,KAAK,KAAK,EACZ,kBACD;;AAEH,UAAQ,KAAK,EAAE;;AAGjB,GAAE,KAAK,sBAAsB;AAC7B,OAAM,OAAO;AACb,KAAI,MAAM,wBAAwB,KAAM,EAAE;EACxC,MAAM,eAAe,MAAM,kBAAkB;AAC7C,QAAM,yBAAyB;AAC/B,iBAAe,aAAa;;AAI9B,YAAW,EAAE,YAAY,MAAM,CAAC;;AAGlC,eAAe,SAAsB,MAAc,MAAc,YAAY,KAAyB;AACpG,KAAI;EACF,MAAM,UAAkC,EAAE;EAC1C,MAAM,SAAS,QAAQ,IAAI;AAC3B,MAAI,OAAQ,SAAQ,mBAAmB,UAAU;AAKjD,SAAQ,OAJI,MAAM,MAAM,GAAG,KAAK,eAAe,QAAQ;GACrD,QAAQ,YAAY,QAAQ,UAAU;GACtC;GACD,CAAC,EACgB,MAAM;SAClB;AACN,SAAO;;;AAIX,eAAe,YAAY;AACZ,cAAa;CAC1B,MAAM,OAAO,YAAY;AACzB,GAAE,MAAM,qBAAqB;AAG7B,KAAI,CADO,MAAM,iBAAiB,EACzB;AACP,IAAE,IAAI,MAAM,gCAAgC,OAAO;AACnD,IAAE,IAAI,KAAK,2CAA2C;AACtD,UAAQ,KAAK,EAAE;;AAGjB,KAAI;EACF,MAAM,CAAC,WAAW,aAAa,UAAU,aAAa,YAAY,MAAM,QAAQ,IAAI;GAClF,SAAc,MAAM,SAAS;GAC7B,SAAc,MAAM,WAAW;GAC/B,SAAc,MAAM,cAAc;GAClC,SAAc,MAAM,SAAS;GAC7B,SAAc,MAAM,eAAe;GACpC,CAAC;EAEF,MAAM,IAAI,WAAW;EACrB,MAAM,SAAS,WAAW,UAAU;EACpC,MAAM,UAAU,WAAW,WAAW;EACtC,MAAM,WAAW,MAAM,QAAQ,aAAa,SAAS,GAAG,YAAY,SAAS,SAAS;EACtF,MAAM,QAAQ,OAAO,UAAU,cAAc,UAAU,SAAS,UAAU,aAAa,EAAE;EACzF,MAAM,QAAQ,OAAO,UAAU,cAAc,UAAU,SAAS,UAAU,aAAa,EAAE;EACzF,MAAM,KAAK,WAAW,gBAAgB,SAAS;EAC/C,MAAM,SAAS,GAAG,SAAS,KAAK,MAAM,EAAE,OAAO,WAAW,QAAQ,GAAG;EACrE,MAAM,SAAS,GAAG,gBAAgB,KAAK,MAAM,EAAE,cAAc,GAAG;EAEhE,MAAM,WAAW,aAAa,cAAc,UAAU;EACtD,MAAM,WAAW,aAAa,UAAU,UAAU;EAClD,MAAM,gBAAgB,WAAW;EACjC,MAAM,oBAAoB,KAAK,IAAI,UAAU,GAAG,GAAG;EACnD,MAAM,cAAc,gBAAgB;EACpC,MAAM,WAAW,gBAAgB,IAAI,KAAK,MAAO,cAAc,gBAAiB,IAAI,GAAG;AAEvF,IAAE,IAAI,QAAQ,gBAAgB,QAAQ,MAAM,OAAO;EAEnD,MAAM,QAAQ;GACZ,iBAAiB,WAAW,YAAY,cAAc;GACtD,iBAAiB;GACjB,iBAAiB;GACjB,iBAAiB;GACjB,iBAAiB,MAAM,UAAU,MAAM;GACvC,iBAAiB;GACjB,iBAAiB,OAAO;GACxB,iBAAiB,OAAO;GACxB,iBAAiB,cAAc;GAChC;AAED,MAAI,WAAW,GAAG;AAChB,SAAM,KAAK,GAAG;AACd,SAAM,KAAK,mBAAmB,YAAY,gBAAgB,CAAC,iBAAiB,SAAS,cAAc;AACnG,SAAM,KAAK,oBAAoB,cAAc,gBAAgB,CAAC,SAAS;AACvE,SAAM,KAAK,oBAAoB,kBAAkB,gBAAgB,CAAC,SAAS;;AAG7E,MAAI,UAAU;GACZ,MAAM,WAAW,SAAS,aAAa,QAAQ,UAAU;GACzD,MAAM,QAAQ,SAAS,sBAAsB,eAAe,iBAAiB;GAC7E,MAAM,YAAY,SAAS,SAAS,EAAE,EAAE,KAAK,MAC3C,KAAK,EAAE,UAAU,MAAM,IAAI,GAAG,EAAE,IAAI,OAAO,GAAG,CAAC,GAAG,EAAE,QACrD;AACD,SAAM,KAAK,GAAG;AACd,SAAM,KAAK,iBAAiB,WAAW;AACvC,SAAM,KAAK,iBAAiB,QAAQ;AACpC,SAAM,KAAK,SAAS;AACpB,YAAS,SAAS,MAAc,MAAM,KAAK,EAAE,CAAC;;AAGhD,IAAE,KAAK,MAAM,KAAK,KAAK,EAAE,cAAc;UAChC,KAAK;AACZ,IAAE,IAAI,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,CAAC;AAC7D,UAAQ,KAAK,EAAE;;;AAMnB,SAAS,aAAa,QAA+B;AACnD,QAAO,OACJ,KAAK,MAAM,GAAG,EAAE,KAAK,MAAM,IAAI,GAAG,EAAE,OAAO,EAAE,OAAO,QAAQ,EAAE,SAAS,KAAK,CAC5E,KAAK,KAAK;;AASf,SAAS,mBAAmB,UAAsC;CAChE,MAAM,aAAa,KAAK,UAAU,SAAS;AAC3C,KAAI;AACF,MAAI,WAAW,WAAW,EAAE;GAC1B,MAAM,SAAS,aAAa,WAAW;GACvC,MAAM,WAAW,OAAO,WAAW,IAAI,GAAG,SAAS,KAAK,UAAU,OAAO;AACzE,OAAI,WAAW,SAAS,CAAE,QAAO;;SAE7B;AAER,KAAI;EACF,MAAM,SAAS,YAAY,SAAS,CACjC,QAAQ,MAAM,EAAE,SAAS,OAAO,CAAC,CACjC,KAAK,OAAO;GAAE;GAAG,GAAG,SAAS,KAAK,UAAU,EAAE,CAAC,CAAC;GAAS,EAAE,CAC3D,MAAM,GAAG,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC;AAC7B,MAAI,OAAQ,QAAO,KAAK,UAAU,OAAO,EAAE;SACrC;;AAKV,SAAS,uBAAqC;CAC5C,MAAM,WAAW,KAAK,SAAS,EAAE,WAAW,QAAQ;AACpD,KAAI,CAAC,WAAW,SAAS,CAAE,QAAO,EAAE,OAAO,aAAa;CAExD,MAAM,UAAU,mBAAmB,SAAS;AAC5C,KAAI,CAAC,QAAS,QAAO,EAAE,OAAO,gBAAgB;CAE9C,IAAI;AACJ,KAAI;AACF,YAAU,aAAa,SAAS,OAAO;SACjC;AACN,SAAO,EAAE,OAAO,gBAAgB;;CAGlC,MAAM,QAAQ,QAAQ,MACpB,sEACD;AACD,KAAI,MAAO,QAAO;EAAE,OAAO;EAAU,cAAc,MAAM;EAAI;AAC7D,KAAI,QAAQ,SAAS,yCAAyC,CAAE,QAAO,EAAE,OAAO,UAAU;AAC1F,QAAO,EAAE,OAAO,cAAc;;AAahC,SAAS,qBAAoC;AAC3C,QAAO;EACL,SAAS,YAAY;EACrB,WAAW,cAAc;EACzB,SAAS,KAAK,SAAS,EAAE,gBAAgB,OAAO;EAChD,aAAa,mBAAmB;EAChC,YAAY,iBAAiB;EAC7B,eAAe;EAChB;;AAGH,SAAS,qBAAoC;AAC3C,QAAO;EACL,qBAAqB,WAAW,KAAK,SAAS,EAAE,gBAAgB,OAAO,CAAC;EACxE,mBAAmB;AACjB,OAAI;AACF,WAAO,aACL,aAAa,KAAK,SAAS,EAAE,gBAAgB,OAAO,EAAE,QAAQ,CAC/D;WACK;AACN,WAAO,EAAE;;;EAGb,qBAAqB,WAAW,mBAAmB,CAAC;EACpD,yBAAyB;GACvB,MAAM,MAAM,mBAAmB;AAC/B,OAAI,QAAQ,KAAM,QAAO;AACzB,UAAO,SAAS,IAAI;;EAEtB,qBAAqB,YAAY,MAAM;EACvC,uBAAuB,KAAK,SAAS,EAAE,UAAU,OAAO,aAAa,YAAY,MAAM;EACvF,mBAAmB,YAAoB,cAAc,QAAQ;EAC7D,iBAAiB,OAAO,YAAY,QAAS;AAC3C,OAAI;AAIF,YAHY,MAAM,MAAM,cAAc,EAAE,EACtC,QAAQ,YAAY,QAAQ,UAAU,EACvC,CAAC,EACS;WACL;AACN,WAAO;;;EAGX,SAAS,YAAY;AACnB,OAAI;AACF,UAAM,SAAS;AACf,WAAO;KAAE,IAAI;KAAM,SAAS;KAA6B;YAClD,KAAK;AACZ,WAAO;KACL,IAAI;KACJ,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;KAC1D;;;EAGL,YAAY,OAAO,SAAiB;GAClC,MAAM,SAAS,QAAQ,IAAI,aAAa,QAAQ,IAAI,aAAa;AACjE,KAAE,IAAI,KAAK,WAAW,KAAK,MAAM,OAAO,GAAG;AAC3C,OAAI;IAEF,MAAM,SAAS,UAAU,QAAQ,CAAC,KAAK,EAAE,EAAE,OAAO,WAAW,CAAC;AAC9D,QAAI,OAAO,MACT,QAAO;KACL,IAAI;KACJ,SAAS,oBAAoB,OAAO,IAAI,OAAO,MAAM;KACtD;AAEH,SAAK,OAAO,UAAU,OAAO,EAC3B,QAAO;KACL,IAAI;KACJ,SAAS,GAAG,OAAO,oBAAoB,OAAO;KAC/C;AAEH,WAAO;KAAE,IAAI;KAAM,SAAS,SAAS;KAAQ;YACtC,KAAK;AACZ,WAAO;KACL,IAAI;KACJ,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;KAC1D;;;EAGL,iBAAiB,YAAY;GAC3B,MAAM,IAAI,MAAM,iBAAiB;AACjC,UAAO;IACL,IAAI,EAAE;IACN,SAAS,EAAE,KACP,kBAAkB,iBAAiB,MAAM,EAAE,YAC3C;IACL;;EAEH,SAAS,YAAY;AACnB,OAAI;IAIF,MAAM,WAAW,qBADJ,aAAa,CACiB;IAC3C,MAAM,aAAa,mBAAmB;AACtC,QAAI,SAAS,WAAW,KAAK,eAAe,MAAM;AAChD,yBAAoB;AACpB,uBAAkB;AAClB,YAAO;MAAE,IAAI;MAAM,SAAS;MAAoB;;IAElD,MAAM,6BAAa,IAAI,KAAa;AACpC,QAAI,WAAY,YAAW,IAAI,WAAW;AAC1C,SAAK,MAAM,OAAO,SAAU,YAAW,IAAI,IAAI;IAC/C,IAAI,aAAa;AACjB,SAAK,MAAM,OAAO,WAEhB,KAAI,CADO,MAAM,cAAc,KAAK,WAAW,IAAK,CAC3C,cAAa;AAExB,wBAAoB;AACpB,sBAAkB;AAClB,WAAO;KACL,IAAI;KACJ,SAAS,aAAa,oBAAoB;KAC3C;YACM,KAAK;AACZ,WAAO;KACL,IAAI;KACJ,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;KAC1D;;;EAGL,UAAU,YAAY;AACpB,OAAI;AAEF,QAAI,CADY,MAAM,aAAa,CACrB,QAAO;KAAE,IAAI;KAAO,SAAS;KAAgC;IAC3E,MAAM,QAAQ,MAAM,cAAc,KAAM;AACxC,WAAO;KACL,IAAI;KACJ,SAAS,QAAQ,iBAAiB;KACnC;YACM,KAAK;AACZ,WAAO;KACL,IAAI;KACJ,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;KAC1D;;;EAGL,8BAA8B;AAC5B,uBAAoB;AACpB,qBAAkB;;EAErB;;AAGH,eAAe,sBAA8C;CAC3D,MAAM,OAAO,YAAY;CACzB,MAAM,SAAwB,EAAE;CAEhC,MAAM,WAAW,MAAM,iBAAiB;AACxC,QAAO,KAAK;EACV,MAAM;EACN,IAAI;EACJ,MAAM,WACF,SACA,mDAAmD,KAAK;EAC7D,CAAC;AACF,KAAI,CAAC,SAAU,QAAO;CAEtB,MAAM,CAAC,QAAQ,OAAO,SAAS,MAAM,QAAQ,IAAI;EAC/C,SAAc,MAAM,UAAU,IAAK;EACnC,SAAc,MAAM,gBAAgB,IAAK;EACzC,SAAc,MAAM,eAAe,IAAK;EACzC,CAAC;CAEF,MAAM,SAAS,OAAO,aAAa;CACnC,MAAM,WAAW,OAAO,sBAAsB;CAI9C,MAAM,WAHiB,OACrB,OAAO,cAAc,OAAO,SAAS,OAAO,aAAa,EAC1D,GACiC;AAElC,QAAO,KACL;EACE,MAAM;EACN,IAAI,QAAQ,WAAW;EACvB,MACE,QAAQ,WAAW,YACf,SACA,WAAW,QAAQ,UAAU;EACpC,EACD;EACE,MAAM;EACN,IAAI;EACJ,MAAM,SAAS,SAAY;EAC5B,EACD;EACE,MAAM;EACN,IAAI;EACJ,MAAM,WACF,SACA;EACL,CACF;AAED,MAAK,MAAM,KAAM,OAAO,SAAS,EAAE,CAKjC,QAAO,KAAK;EACV,MAAM,EAAE;EACR,IAAI,EAAE;EACN,MAAM,EAAE,UAAU,SAAY,EAAE;EACjC,CAAC;CAGJ,MAAM,KAAK,sBAAsB;CACjC,MAAM,iBAAiB;AACrB,UAAQ,GAAG,OAAX;GACE,KAAK,SACH,QAAO;IACL,IAAI;IACJ,MAAM,GAAG,eAAe,aAAa,GAAG,iBAAiB;IAC1D;GACH,KAAK,aACH,QAAO;IACL,IAAI;IACJ,MACE;IACH;GACH,KAAK,eACH,QAAO;IACL,IAAI;IACJ,MACE;IACH;GACH,KAAK,YACH;;KAEF;AACJ,KAAI,QAAS,QAAO,KAAK;EAAE,MAAM;EAAuC,GAAG;EAAS,CAAC;AAErF,QAAO,KAAK;EACV,MAAM;EACN,IAAI;EACJ,MAAM,WACF,SACA;EACL,CAAC;AAEF,QAAO;;AAKT,eAAe,aAAa,GAAsC;CAChE,MAAM,SAAS,MAAM,EAAE,OAAqB;EAC1C,SAAS,IAAI,EAAE,GAAG,IAAI,EAAE;EACxB,SAAS;GACP;IAAE,OAAO;IAAO,OAAO;IAAU,MAAM,EAAE;IAAY;GACrD;IAAE,OAAO;IAAQ,OAAO;IAAW;GACnC;IAAE,OAAO;IAAQ,OAAO;IAAgB;GACxC;IAAE,OAAO;IAAQ,OAAO;IAAkB;GAC3C;EACD,cAAc;EACf,CAAC;AACF,KAAI,EAAE,SAAS,OAAO,CAAE,QAAO;AAC/B,QAAO;;AAGT,eAAe,mBACb,GACA,KACA,QAC8B;AAC9B,KAAI,QAAQ;AACV,IAAE,IAAI,KAAK,oBAAoB,EAAE,aAAa;AAC9C,SAAO;GAAE,IAAI;GAAM,SAAS;GAAa;;CAE3C,MAAM,SAAS,MAAM,EAAE,IAAI,IAAI;AAC/B,KAAI,OAAO,GACT,GAAE,IAAI,QAAQ,OAAO,WAAW,GAAG,EAAE,GAAG,SAAS;KAEjD,GAAE,IAAI,MAAM,OAAO,WAAW,GAAG,EAAE,GAAG,cAAc;AAEtD,QAAO;;AAGT,eAAe,YAAY;AACzB,GAAE,MAAM,qBAAqB;CAC7B,MAAM,WAAW,KAAK,SAAS,QAAQ;CACvC,MAAM,SAAS,KAAK,SAAS,YAAY;AACzC,KAAI,YAAY,QAAQ;AACtB,IAAE,IAAI,MAAM,sCAAsC;AAClD,UAAQ,KAAK,EAAE;;CAIjB,MAAM,UAAU,MAAM,qBAAqB;CAC3C,MAAM,gBAAgB,QAAQ,QAAQ,MAAM,EAAE,GAAG,CAAC;AAClD,GAAE,KAAK,aAAa,QAAQ,EAAE,WAAW,cAAc,GAAG,QAAQ,OAAO,UAAU;CAGnF,MAAM,MAAM,oBAAoB;CAEhC,MAAM,cAAc,iBADJ,oBAAoB,CACS;AAE7C,KAAI,QAAQ;EACV,MAAM,UAAuF,EAAE;AAC/F,OAAK,MAAM,KAAK,YAAa,SAAQ,KAAK;GAAE,YAAY;GAAG,QAAQ,MAAM,EAAE,MAAM,IAAI;GAAE,CAAC;EACxF,MAAM,QAAQ,WAAW,KAAK,QAAQ;AACtC,IAAE,KAAK,MAAM,KAAK,KAAK,EAAE,eAAe;AACxC,IAAE,MAAM,uDAAuD;AAC/D;;CAGF,IAAI,SAAS;CACb,IAAI,QAAQ;CACZ,IAAI,UAAU;CACd,IAAI,OAAO;AAEX,MAAK,MAAM,KAAK,aAAa;AAC3B,MAAI,MAAM;AACR;AACA;;EAEF,MAAM,SAAS,MAAM,EAAE,MAAM,IAAI;AACjC,MAAI,OAAO,IAAI;AACb,KAAE,IAAI,QAAQ,GAAG,EAAE,GAAG,IAAI,OAAO,SAAS,KAAK,OAAO,OAAO,KAAK,KAAK;AACvE;;AAEF;AACA,IAAE,IAAI,KAAK,GAAG,EAAE,GAAG,KAAK,OAAO,UAAU,KAAK,MAAM,CAAC;AACrD,IAAE,IAAI,KAAK,QAAQ,EAAE,aAAa;AAElC,MAAI,EAAE,WACJ,GAAE,IAAI,KAAK,2BAA2B,EAAE,GAAG,SAAS;AAGtD,MAAI,UAAU;AAEZ,QADU,MAAM,mBAAmB,GAAG,KAAK,MAAM,EAC3C,GAAI;AAGV,OAAI,EADU,MAAM,EAAE,MAAM,IAAI,EACrB,GAAI,GAAE,IAAI,KAAK,GAAG,EAAE,GAAG,2BAA2B;AAC7D;;AAIF,SAAO,MAAM;GACX,MAAM,SAAS,MAAM,aAAa,EAAE;AACpC,OAAI,WAAW,OAAO;AAEpB,SADU,MAAM,mBAAmB,GAAG,KAAK,MAAM,EAC3C,IAAI;KACR,MAAM,QAAQ,MAAM,EAAE,MAAM,IAAI;AAChC,SAAI,MAAM,GACR;SAEA,GAAE,IAAI,KAAK,GAAG,EAAE,GAAG,4BAA4B,MAAM,UAAU,KAAK;;AAGxE;;AAEF,OAAI,WAAW,QAAQ;AACrB;AACA;;AAEF,OAAI,WAAW,QAAQ;AACrB,MAAE,KAAK,EAAE,UAAU,IAAI,EAAE,GAAG,aAAa;AACzC;;AAEF,OAAI,WAAW,QAAQ;AACrB,WAAO;AACP;;;;CAKN,MAAM,UAAU,GAAG,YAAY,OAAO,YAAY,OAAO,aAAa,MAAM,WAAW,QAAQ;AAC/F,KAAI,MAAM;AACR,IAAE,MAAM,eAAe,UAAU;AACjC,UAAQ,KAAK,EAAE;;AAEjB,KAAI,WAAW,GAAG;AAChB,IAAE,MAAM,mDAAmD;AAC3D;;AAEF,KAAI,SAAS,UAAU,GAAG;AACxB,IAAE,MAAM,sBAAsB,UAAU;AACxC;;AAEF,GAAE,MAAM,QAAQ;AAChB,SAAQ,KAAK,EAAE;;AAiBjB,SAAS,oBAAmC;AAC1C,QAAO;EACL;GACE,IAAI,WAAW,OAAO;GACtB,OAAO;GACP,cAAc;IACZ;KACE,UAAU;KACV,WAAW,EAAE,WAAW,0BAA0B;KAClD,YACE;KACH;IACD;KACE,UAAU;KACV,WAAW,EAAE,WAAW,qBAAqB;KAC7C,YACE;KACH;IACD;KACE,UAAU;KACV,WAAW,EAAE,SAAS,YAAY;KAClC,YAAY;KACb;IACF;GACF;EACD;GACE,IAAI,WAAW,OAAO;GACtB,OAAO;GACP,cAAc,CACZ;IACE,UAAU;IACV,WAAW,EAAE,WAAW,wBAAwB;IAChD,YACE;IACH,EACD;IACE,UAAU;IACV,WAAW,EAAE,WAAW,oBAAoB;IAC5C,YACE;IACH,CACF;GACF;EACD;GACE,IAAI,WAAW,OAAO;GACtB,OAAO;GACP,cAAc,CACZ;IACE,UAAU;IACV,WAAW,EAAE,WAAW,+BAA+B;IACvD,YACE;IACH,CACF;GACF;EACF;;AAGH,eAAe,SACb,KACA,MACA,YAAY,KACO;AACnB,KAAI;EACF,MAAM,MAAM,MAAM,MAAM,KAAK;GAC3B,QAAQ;GACR,SAAS,EAAE,gBAAgB,oBAAoB;GAC/C,MAAM,KAAK,UAAU,KAAK;GAC1B,QAAQ,YAAY,QAAQ,UAAU;GACvC,CAAC;AACF,MAAI,CAAC,IAAI,GAAI,QAAO;AACpB,SAAQ,MAAM,IAAI,MAAM,CAAC,YAAY,KAAK;SACpC;AACN,SAAO;;;AAIX,eAAe,eACb,KACA,MACA,YAAY,KACO;CACnB,MAAM,MAAM,MAAM,MAAM,KAAK;EAC3B,QAAQ;EACR,SAAS,EAAE,gBAAgB,oBAAoB;EAC/C,MAAM,KAAK,UAAU,KAAK;EAC1B,QAAQ,YAAY,QAAQ,UAAU;EACvC,CAAC;AACF,KAAI,CAAC,IAAI,IAAI;EACX,MAAM,UAAU,MAAM,IAAI,MAAM,CAAC,YAAY,GAAG;EAChD,MAAM,SAAS,UAAU,MAAM,QAAQ,MAAM,GAAG,IAAI,KAAK;AACzD,QAAM,IAAI,MAAM,QAAQ,IAAI,WAAW,IAAI,OAAO,GAAG,IAAI,aAAa,SAAS;;AAEjF,QAAQ,MAAM,IAAI,MAAM,CAAC,YAAY,KAAK;;AAG5C,eAAe,gBACb,MACA,SACA,SACiB;AACjB,OAAM,eAAe,GAAG,KAAK,6BAA6B;EACxD,WAAW,QAAQ;EACnB;EACA,KAAK;EACN,CAAC;CAEF,IAAI,SAAS;AACb,MAAK,MAAM,OAAO,QAAQ,cAAc;EACtC,MAAM,MAAM,GAAG,KAAK;EACpB,MAAM,UAAU;GACd,UAAU;GACV,WAAW,QAAQ;GACnB;GACA,KAAK;GACL,4BAAW,IAAI,MAAM,EAAC,aAAa;GACnC,MAAM;IACJ,WAAW,IAAI;IACf,YAAY,IAAI;IAChB,aAAa,IAAI;IAClB;GACF;AAED,MAAI;GACF,MAAM,MAAM,MAAM,MAAM,KAAK;IAC3B,QAAQ;IACR,SAAS,EAAE,gBAAgB,oBAAoB;IAC/C,MAAM,KAAK,UAAU,QAAQ;IAC7B,QAAQ,YAAY,QAAQ,IAAK;IAClC,CAAC;AACF,OAAI,IAAI,GACN;QACK;IACL,MAAM,OAAO,MAAM,IAAI,MAAM,CAAC,YAAY,GAAG;AAC7C,MAAE,IAAI,KACJ,sBAAsB,IAAI,SAAS,IAAI,IAAI,OAAO,GAAG,IAAI,aAAa,OAAO,MAAM,KAAK,MAAM,GAAG,IAAI,KAAK,KAC3G;;WAEI,KAAK;AACZ,KAAE,IAAI,KACJ,8BAA8B,IAAI,SAAS,IAAI,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,GAChG;;;AAIL,OAAM,eAAe,GAAG,KAAK,2BAA2B,EAAE,WAAW,QAAQ,IAAI,CAAC;AAClF,QAAO;;AAGT,eAAe,cAAc,MAAc,OAAsC;CAM/E,MAAM,SALO,MAAM,SACjB,GAAG,KAAK,4BACR;EAAE;EAAO,OAAO;EAAG,EACnB,IACD,GACmB,WAAW,EAAE;AACjC,QAAO;EACL;EACA,MAAM,MAAM;EACZ,UAAU,MAAM,IAAI,SAAS;EAC9B;;AAKH,SAAS,iBAAgC;CACvC,MAAM,aAAa;EACjB,KAAK,WAAW,MAAM,eAAe;EACrC,KAAK,WAAW,eAAe;EAC/B,KAAK,QAAQ,KAAK,EAAE,eAAe;EACpC;AACD,MAAK,MAAM,KAAK,WACd,KAAI,WAAW,EAAE,CAAE,QAAO;AAE5B,QAAO;;AAGT,eAAe,UAAU;AACvB,GAAE,MAAM,mBAAmB;CAC3B,MAAM,SAAS,KAAK,SAAS,EAAE,gBAAgB,OAAO;CACtD,MAAM,WAAW,gBAAgB;AACjC,KAAI,CAAC,UAAU;AACb,IAAE,IAAI,MACJ,mGACD;AACD,UAAQ,KAAK,EAAE;;CAEjB,MAAM,MAAM,QAAQ,OAAO;CAC3B,MAAM,EAAE,OAAO,aAAa,MAAM,OAAO;CACzC,MAAM,EAAE,WAAW,gBAAgB,MAAM,OAAO;AAChD,KAAI;AACF,QAAM,MAAM,KAAK,EAAE,WAAW,MAAM,CAAC;AAOrC,QAAM,SAAS,UAAU,QAAQ,YAAY,cAAc;UACpD,KAAK;AACZ,MAAK,KAA+B,SAAS,UAAU;AACrD,KAAE,IAAI,KAAK,GAAG,OAAO,yCAAyC;AAC9D,KAAE,IAAI,KACJ,6CAA6C,OAAO,GAAG,WACxD;AACD,KAAE,MAAM,mBAAmB;AAC3B;;AAEF,IAAE,IAAI,MACJ,4BAA4B,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,GAC7E;AACD,UAAQ,KAAK,EAAE;;AAEjB,GAAE,IAAI,QAAQ,SAAS,SAAS;AAChC,GAAE,KACA;EACE;EACA;EACA;EACA;EACA;EACA;EACD,CAAC,KAAK,KAAK,EACZ,aACD;AACD,GAAE,MAAM,QAAQ,OAAO,kBAAkB;;AAG3C,eAAe,UAAU;CACvB,MAAM,OAAO,aAAa;CAC1B,MAAM,OAAO,oBAAoB;AACjC,GAAE,MAAM,mBAAmB;AAE3B,KAAI,CAAE,MAAM,oBAAoB,EAAG;AACjC,IAAE,IAAI,MACJ,4CAA4C,KAAK,0FAClD;AACD,IAAE,IAAI,KAAK,8CAA8C;AACzD,UAAQ,KAAK,EAAE;;CAGjB,MAAM,cAAc;CACpB,MAAM,WAAW,mBAAmB;CAEpC,MAAM,QAAQ,EAAE,SAAS;AACzB,OAAM,MAAM,yDAAyD;CAErE,IAAI,WAAW;AACf,MAAK,MAAM,WAAW,SACpB,aAAY,MAAM,gBAAgB,MAAM,aAAa,QAAQ;AAG/D,OAAM,KAAK,UAAU,SAAS,uBAAuB,SAAS,OAAO,WAAW;CAEhF,MAAM,UAAU;EACd;EACA;EACA;EACD;CAED,MAAM,SAAS,EAAE,SAAS;AAC1B,QAAO,MAAM,WAAW,QAAQ,OAAO,0BAA0B;CAEjE,MAAM,UAA0B,EAAE;AAClC,MAAK,MAAM,SAAS,QAClB,SAAQ,KAAK,MAAM,cAAc,MAAM,MAAM,CAAC;AAGhD,QAAO,KAAK,kBAAkB;CAE9B,MAAM,QAAQ;EACZ,kBAAkB;EAClB,kBAAkB,SAAS,OAAO,WAAW,SAAS;EACtD;EACA;EACA,GAAG,QAAQ,SAAS,MAAM,CACxB,MAAM,EAAE,MAAM,IACd,SAAS,EAAE,KAAK,gBAAgB,EAAE,SAAS,MAAM,GAAG,GAAG,GACxD,CAAC;EACF;EACA;EACA;EACA;EACA,kBAAkB,cAAc;EAChC,kCAAkC,KAAK,gCAAgC,YAAY;EACpF;AAED,GAAE,KAAK,MAAM,KAAK,KAAK,EAAE,gBAAgB;AACzC,GAAE,IAAI,QAAQ,yEAAyE;;AAGzF,SAAS,WACP,SACA,aACA,UAA+D,EAAE,OAAO,WAAW,EAC1E;CACT,MAAM,UAAU,EAAE,SAAS;AAC3B,SAAQ,MAAM,QAAQ,MAAM;CAC5B,MAAM,SAAS,UAAU,SAAS,aAAa;EAC7C,KAAK,QAAQ,OAAO,QAAQ,KAAK;EACjC,OAAO;EACP,UAAU;EACX,CAAC;AAEF,KAAI,OAAO,WAAW,GAAG;AACvB,UAAQ,KAAK,GAAG,QAAQ,MAAM,IAAI;AAClC,SAAO;;CAGT,MAAM,UAAU,OAAO,UAAU,IAAI,UAAU,CAAC,MAAM;CACtD,MAAM,UAAU,OAAO,UAAU,IAAI,UAAU,CAAC,MAAM;CACtD,MAAM,MAAM,UAAU,UAAU;AAEhC,KAAI,QAAQ,UAAU;AACpB,UAAQ,KAAK,GAAG,QAAQ,MAAM,YAAY;AAC1C,IAAE,IAAI,KAAK,IAAI,MAAM,GAAG,IAAI,CAAC;AAC7B,SAAO;;AAGT,SAAQ,KAAK,GAAG,QAAQ,MAAM,IAAI;AAClC,GAAE,IAAI,MAAM,IAAI,MAAM,GAAG,IAAI,CAAC;AAC9B,QAAO;;AAGT,eAAe,aAAa;AAC1B,GAAE,MAAM,sBAAsB;CAE9B,MAAM,MAAM,QAAQ,KAAK;CACzB,MAAM,iBAAiB,WAAW,KAAK,KAAK,eAAe,CAAC;CAC5D,MAAM,cAAc,WAAW,KAAK,KAAK,iBAAiB,CAAC;CAE3D,MAAM,UAAU,YAAY,OAAO;CACnC,MAAM,SAAS,YAAY,MAAM;CACjC,MAAM,YAAY,YAAY,SAAS;AAEvC,GAAE,IAAI,KAAK,sBAAsB,MAAM;CACvC,MAAM,kBAAkB,IAAa,UAAwB;AAC3D,MAAI,CAAC,IAAI;AACP,KAAE,IAAI,MAAM,oBAAoB,MAAM,UAAU;AAChD,WAAQ,KAAK,EAAE;;;AAInB,KAAI,eAEF,KADgB,CAAC,CAAC,WAAW,eACd,SAAS;AAItB,iBAHkB,WAAW,SAAS,CAAC,UAAU,EAAE,EACjD,OAAO,0CACR,CAAC,EACwB,eAAe;AACzC,aAAW,SAAS,CAAC,MAAM,iBAAiB,EAAE;GAC5C,OAAO;GACP,UAAU;GACX,CAAC;YACO,QAAQ;AAIjB,iBAHkB,WAAW,QAAQ,CAAC,UAAU,EAAE,EAChD,OAAO,yCACR,CAAC,EACwB,cAAc;AACxC,aAAW,QAAQ,CAAC,WAAW,iBAAiB,EAAE;GAChD,OAAO;GACP,UAAU;GACX,CAAC;OAEF,GAAE,IAAI,KAAK,uEAAuE;KAGpF,GAAE,IAAI,KAAK,wEAAwE;CAGrF,MAAM,gBAAgB,MAAM,EAAE,QAAQ;EACpC,SAAS;EACT,cAAc;EACf,CAAC;AACF,KAAI,EAAE,SAAS,cAAc,EAAE;AAC7B,IAAE,OAAO,aAAa;AACtB,SAAO,QAAQ,KAAK,EAAE;;AAExB,KAAI,kBAAkB,KACpB,OAAM,iBAAiB;KAEvB,GAAE,IAAI,KAAK,gCAAgC;AAG7C,KAAI,UACF,YAAW,WAAW,CAAC,QAAQ,cAAc,mBAAmB,EAAE;EAChE,OAAO,6BAA6B,iBAAiB;EACrD,UAAU;EACX,CAAC;KAEF,GAAE,IAAI,KAAK,mDAAmD;AAGhE,GAAE,KACA;EACE;EACA;EACA;EACA;EACA;EACA;EACD,CAAC,KAAK,KAAK,EACZ,sBACD;;AAGH,SAAS,SAAS,KAAsB;AACtC,KAAI;AACF,UAAQ,KAAK,KAAK,EAAE;AACpB,SAAO;UACA,KAAK;AACZ,SAAQ,KAA+B,SAAS;;;AAIpD,eAAe,cACb,KACA,eACA,WACkB;AAClB,KAAI;AACF,UAAQ,KAAK,KAAK,cAAc;UACzB,KAAK;EACZ,MAAM,OAAQ,KAA+B;AAC7C,MAAI,SAAS,QAAS,QAAO;AAC7B,MAAI,SAAS,SAAS;AACpB,KAAE,IAAI,KAAK,+BAA+B,IAAI,cAAc,MAAM;AAClE,UAAO;;AAET,OAAK,GAAG,cAAc,GAAG,IAAI,IAAI,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,GAAG;AACpF,SAAO;;CAET,MAAM,WAAW,KAAK,KAAK,GAAG;AAC9B,QAAO,KAAK,KAAK,GAAG,UAAU;AAC5B,MAAI,CAAC,SAAS,IAAI,CAAE,QAAO;AAC3B,QAAM,IAAI,SAAS,MAAM,WAAW,GAAG,IAAI,CAAC;;AAE9C,KAAI,CAAC,SAAS,IAAI,CAAE,QAAO;AAC3B,KAAI;AACF,UAAQ,KAAK,KAAK,UAAU;UACrB,KAAK;AACZ,MAAK,KAA+B,SAAS,QAAS,QAAO;AAC7D,OAAK,WAAW,IAAI,IAAI,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,GAAG;AAC3E,SAAO;;AAET,OAAM,IAAI,SAAS,MAAM,WAAW,GAAG,IAAI,CAAC;AAC5C,QAAO,CAAC,SAAS,IAAI;;AAGvB,SAAS,qBAAqB,MAAwB;AACpD,KAAI,WAAY,QAAO,EAAE;CACzB,MAAM,OAAO,YAAY,OAAO;AAChC,KAAI,CAAC,KAAM,QAAO,EAAE;CAMpB,MAAM,UAAU,QAAQ;AACxB,KAAI;AAKF,SAJY,aAAa,MAAM;GAAC;GAAM,IAAI;GAAQ;GAAgB;GAAK,EAAE;GACvE,UAAU;GACV,OAAO;IAAC;IAAU;IAAQ;IAAS;GACpC,CAAC,CAEC,MAAM,MAAM,CACZ,KAAK,MAAM,SAAS,GAAG,GAAG,CAAC,CAC3B,QAAQ,MAAM,OAAO,SAAS,EAAE,IAAI,IAAI,KAAK,MAAM,QAAQ;UACvD,KAAK;AACZ,OAAK,SAAS,KAAK,IAAI,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,GAAG;AAC1E,SAAO,EAAE;;;AAIb,eAAe,iBAAiB,aAAqB,MAA6B;CAChF,MAAM,YAAY,YAAY,SAAS;AACvC,KAAI,CAAC,WAAW;AACd,IAAE,IAAI,MACJ,sHAAsH,YAAY,OACnI;AACD,UAAQ,KAAK,EAAE;;AAEjB,KAAI,CAAC,WAAW,YAAY,EAAE;AAC5B,IAAE,IAAI,MACJ,2BAA2B,YAAY,0HACxC;AACD,UAAQ,KAAK,EAAE;;CAEjB,MAAM,KAAK,WAAW,WAAW;EAAC;EAAW;EAAM;EAAa;EAAO,EAAE,EACvE,OAAO,qBAAqB,YAAY,QACzC,CAAC;AACF,qBAAoB;AACpB,mBAAkB;AAClB,KAAI,CAAC,IAAI;AACP,IAAE,IAAI,MACJ,mEAAmE,KAAK,uCAAuC,YAAY,KAC5H;AACD,UAAQ,KAAK,EAAE;;AAEjB,GAAE,MAAM,0FAA0F;;AAGpG,eAAe,UAAyB;AACtC,GAAE,MAAM,mBAAmB;CAC3B,MAAM,OAAO,aAAa;CAC1B,MAAM,QAAQ,iBAAiB;CAC/B,MAAM,UAAU,MAAM,iBAAiB;CACvC,MAAM,QAAQ,KAAK,SAAS,UAAU;AAEtC,KAAI,OAAO,SAAS,UAAU;AAC5B,MAAI,CAAC,SAAS;AACZ,KAAE,IAAI,KAAK,gCAAgC,KAAK,GAAG;AACnD,uBAAoB;AACpB,qBAAkB;AAClB,KAAE,MAAM,mBAAmB;AAC3B;;AAEF,QAAM,iBAAiB,MAAM,aAAa,KAAK;AAC/C;;CAGF,MAAM,WAAW,qBAAqB,KAAK;CAC3C,MAAM,aAAa,mBAAmB;AAEtC,KAAI,CAAC,SAAS;AACZ,MAAI,SAAS,WAAW,KAAK,eAAe,MAAM;AAChD,uBAAoB;AACpB,qBAAkB;AAClB,KAAE,MAAM,mBAAmB;AAC3B;;EAEF,MAAM,YAAY,IAAI,IAAY,SAAS;AAC3C,MAAI,WAAY,WAAU,IAAI,WAAW;AACzC,IAAE,IAAI,KACJ,6BAA6B,KAAK,QAAQ,UAAU,KAAK,+CAA+C,CAAC,GAAG,UAAU,CAAC,KAAK,KAAK,GAClI;AACD,IAAE,IAAI,KACJ,kFAAkF,CAAC,GAAG,UAAU,CAAC,KAAK,IAAI,CAAC,6BAA6B,aAAa,6BAA6B,OAAO,cAAc,OACxM;AACD,UAAQ,KAAK,EAAE;;AAGjB,KAAI,CAAC,OAAO;EACV,MAAM,UAAU,qBAAqB;AACrC,MAAI,WAAW,eAAe,KAC5B,KAAI,MACF,GAAE,IAAI,KACJ,wFAAwF,KAAK,GAC9F;OACI;AACL,KAAE,IAAI,MACJ,yBAAyB,KAAK,kLAAkL,QAAQ,oEAAoE,KAAK,0DAClS;AACD,WAAQ,KAAK,EAAE;;;CAKrB,MAAM,6BAAa,IAAI,KAAa;AACpC,KAAI,WAAY,YAAW,IAAI,WAAW;AAC1C,MAAK,MAAM,OAAO,SAAU,YAAW,IAAI,IAAI;AAE/C,KAAI,WAAW,SAAS,GAAG;AACzB,IAAE,IAAI,MACJ,4CAA4C,aAAa,6BAA6B,OAAO,cAAc,OAAO,wBACnH;AACD,UAAQ,KAAK,EAAE;;CAGjB,IAAI,aAAa;AACjB,MAAK,MAAM,OAAO,YAAY;EAC5B,MAAM,IAAI,EAAE,SAAS;AACrB,IAAE,MAAM,4BAA4B,IAAI,MAAM;EAC9C,MAAM,KAAK,MAAM,cAAc,KAAK,WAAW,IAAK;AACpD,IAAE,KAAK,KAAK,eAAe,QAAQ,sBAAsB,MAAM;AAC/D,MAAI,CAAC,GAAI,cAAa;;AAGxB,qBAAoB;AACpB,mBAAkB;AAClB,KAAI,CAAC,YAAY;AACf,IAAE,IAAI,MAAM,wEAAwE;AACpF,UAAQ,KAAK,EAAE;;AAEjB,GAAE,MAAM,0FAA0F;;AAGpG,eAAe,SAAwB;AACrC,OAAM,OAAO;;AAGf,eAAe,gBAA+B;CAC5C,MAAM,EAAE,eAAe;AACvB,OAAM,WAAW,KAAK,MAAM,EAAE,CAAC;;AAGjC,eAAe,iBAAgC;CAK7C,MAAM,cAAc,IAAI,IAAI,CAAC,UAAU,UAAU,CAAC;CAClD,IAAI;CACJ,MAAM,OAAO,KAAK,MAAM,EAAE;CAC1B,MAAM,aAAuB,EAAE;AAC/B,MAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;EACpC,MAAM,IAAI,KAAK;AACf,MAAI,MAAM,eAAe;GACvB,MAAM,MAAM,KAAK,IAAI;GACrB,MAAM,SAAS,QAAQ,SAAY,SAAS,KAAK,GAAG,GAAG;AACvD,OAAI,OAAO,UAAU,OAAO,IAAI,SAAS,EACvC,YAAW;YACF,QAAQ,OACjB,GAAE,IAAI,KAAK,wBAAwB,IAAI,gCAAgC;AAEzE;AACA;;AAEF,MAAI,EAAE,WAAW,eAAe,EAAE;GAChC,MAAM,MAAM,EAAE,MAAM,GAAsB;GAC1C,MAAM,SAAS,SAAS,KAAK,GAAG;AAChC,OAAI,OAAO,UAAU,OAAO,IAAI,SAAS,EACvC,YAAW;OAEX,GAAE,IAAI,KAAK,wBAAwB,IAAI,gCAAgC;AAEzE;;AAEF,MAAI,YAAY,IAAI,EAAE,EAAE;AACtB;AACA;;AAEF,MAAI,EAAE,WAAW,IAAI,CAAE;AACvB,aAAW,KAAK,EAAE;;CAEpB,MAAM,UAAU,WAAW;CAE3B,MAAM,OAAO,aAAa;CAC1B,MAAM,OAAO,oBAAoB;CAEjC,IAAI,UAAU;CACd,IAAI,cAAc;AAClB,KAAI;EACF,MAAM,QAAQ,MAAM,MAAM,GAAG,KAAK,qBAAqB,EACrD,QAAQ,YAAY,QAAQ,IAAK,EAClC,CAAC;AACF,YAAU,MAAM;AAChB,MAAI,CAAC,SAAS;GACZ,MAAM,YAAY,MAAM,MAAM,MAAM,CAAC,YAAY,GAAG;AACpD,iBAAc,iCAAiC,MAAM,SAAS,YAAY,KAAK,UAAU,MAAM,GAAG,IAAI,KAAK,GAAG;;UAEzG,KAAK;AACZ,YAAU;AAEV,gBAAc,gBADF,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,CAC1B;;AAEpC,KAAI,CAAC,SAAS;AACZ,IAAE,IAAI,MACJ,0CAA0C,KAAK,IAAI,YAAY,iGAChE;AACD,UAAQ,KAAK,EAAE;;CAGjB,MAAM,OAAgC,EAAE;AACxC,KAAI,QAAS,MAAK,UAAU;AAC5B,KAAI,aAAa,OAAW,MAAK,cAAc;CAE/C,MAAM,UAAkC,EAAE,gBAAgB,oBAAoB;CAC9E,MAAM,SAAS,QAAQ,IAAI;AAC3B,KAAI,OAAQ,SAAQ,mBAAmB,UAAU;AAEjD,GAAE,IAAI,KAAK,wBAAwB,WAAW,qBAAqB,GAAG;CACtE,MAAM,UAAU,EAAE,SAAS;AAC3B,SAAQ,MAAM,iBAAiB;AAE/B,KAAI;EACF,MAAM,MAAM,MAAM,MAAM,GAAG,KAAK,mCAAmC;GACjE,QAAQ;GACR;GACA,MAAM,KAAK,UAAU,KAAK;GAC1B,QAAQ,YAAY,QAAQ,KAAQ;GACrC,CAAC;EACF,MAAM,OAAO,MAAM,IAAI,MAAM;EAC7B,IAAI,OAWA,EAAE;AACN,MAAI,KAAK,SAAS,EAChB,KAAI;AACF,UAAO,KAAK,MAAM,KAAK;UACjB;AACN,WAAQ,KAAK,SAAS;AACtB,KAAE,IAAI,MACJ,2CAA2C,IAAI,OAAO,KAAK,KAAK,MAAM,GAAG,IAAI,GAC9E;AACD,WAAQ,KAAK,EAAE;;AAGnB,MAAI,CAAC,IAAI,MAAM,KAAK,YAAY,MAAM;AACpC,WAAQ,KAAK,SAAS;GACtB,MAAM,SACJ,KAAK,UACJ,KAAK,WAAW,IACb,wBACA,KAAK,YAAY,SACf,QAAQ,IAAI,OAAO,qCACnB,QAAQ,IAAI;AACpB,OAAI,IAAI,WAAW,IACjB,GAAE,IAAI,MACJ,GAAG,OAAO,mEACX;YACQ,IAAI,WAAW,IACxB,GAAE,IAAI,MACJ,GAAG,OAAO,kHACX;OAED,GAAE,IAAI,MAAM,OAAO;AAErB,WAAQ,KAAK,EAAE;;AAEjB,UAAQ,KACN,YAAY,KAAK,YAAY,EAAE,YAAY,KAAK,gBAAgB,EAAE,yBAAyB,KAAK,YAAY,UAAU,EAAE,aACzH;AACD,MAAI,KAAK,WAAW;GAClB,MAAM,MAAM,KAAK,YAAY;GAC7B,MAAM,QAAQ,KAAK,sBAAsB;GACzC,MAAM,aAAa,KAAK,cAAc;GAKtC,MAAM,UAAU,WAAW,IAAI,kBAJf,cAAc,KAAK,YAAY,GAIU,MAHjC,KAAK,kBACzB,GAAG,WAAW,sCACd,OAAO,WAAW,CACyD;AAI/E,OAAI,aAAa,SAAS,KAAK,gBAC7B,GAAE,IAAI,KACJ,GAAG,QAAQ,kDAAkD,MAAM,uFAEpE;QACI;IACL,MAAM,YAAY,KAAK,IACrB,KAAK,KAAK,cAAc,OAAO,KAAK,MAAM,EAAE,EAC5C,MACD;AACD,MAAE,IAAI,KACJ,GAAG,QAAQ,2BAA2B,UAAU,QAAQ,MAAM,6BAC/D;;;AAGL,MAAI,KAAK,cAAc,KAAK,WAAW,SAAS,EAC9C,GAAE,IAAI,KAAK,WAAW,cAAc,CAAC,eAAe;UAE/C,KAAK;AACZ,UAAQ,KAAK,SAAS;AACtB,MAAI,eAAe,SAAS,IAAI,SAAS,eACvC,GAAE,IAAI,MAAM,mCAAmC;MAE/C,GAAE,IAAI,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,CAAC;AAE/D,UAAQ,KAAK,EAAE;;;AAWnB,SAAS,oBAAoB,MAAsC;CACjE,MAAM,OAAO,KAAK,MAAM,gBAAgB,WAAW,wBAAwB;AAC3E,KAAI;EACF,MAAM,MAAM,aAAa,MAAM,QAAQ;EACvC,MAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,MAAI,MAAM,QAAQ,QAAQ,UAAU,CAClC,QAAO,EAAE,WAAW,OAAO,WAAW;AAExC,SAAO;SACD;AACN,SAAO;;;AAIX,SAAS,wBAAwB,MAA6B;CAC5D,MAAM,OAAO,YAAY,KAAK;AAC9B,KAAI,CAAC,WAAW,KAAK,CAAE,QAAO;AAC9B,QAAO,cAAc,KAAK;;AAG5B,SAAS,WAAW,MAAgD;AAClE,KAAI;AACF,MAAI,CAAC,WAAW,KAAK,CAAE,QAAO;GAAE,IAAI;GAAM,SAAS,gBAAgB,KAAK;GAAI;AAE5E,MADW,SAAS,KAAK,CAClB,aAAa,CAClB,QAAO,MAAM;GAAE,WAAW;GAAM,OAAO;GAAM,CAAC;MAE9C,YAAW,KAAK;AAElB,SAAO;GAAE,IAAI;GAAM,SAAS,WAAW;GAAQ;UACxC,KAAK;AACZ,SAAO;GACL,IAAI;GACJ,SAAS,UAAU,KAAK,IAAI,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;GAC7E;;;AAIL,eAAe,YAA2B;AACxC,GAAE,MAAM,qBAAqB;CAC7B,MAAM,QAAQ,KAAK,SAAS,UAAU;CACtC,MAAM,WAAW,KAAK,SAAS,cAAc;CAE7C,MAAM,OAAO,SAAS;CACtB,MAAM,kBAAkB,oBAAoB,KAAK;CAIjD,MAAM,OAAO,gBACX;EACE;EACA,eAAe;EACf,oBAPuB,wBAAwB,KAAK;EAQpD;EACD,EAP4B;EAAE;EAAO;EAAU,CASjD;AAGD,KADmB,KAAK,QAAQ,OAAO,GAAG,WAAW,CACtC,WAAW,GAAG;AAC3B,IAAE,MAAM,kDAAkD;AAC1D;;AAGF,GAAE,KAAK,WAAW,KAAK,EAAE,mBAAmB;AAE5C,KAAI,CAAC,OAAO;EACV,MAAM,UAAU,MAAM,EAAE,QAAQ;GAC9B,SAAS;GACT,cAAc;GACf,CAAC;AACF,MAAI,EAAE,SAAS,QAAQ,IAAI,YAAY,MAAM;AAC3C,KAAE,OAAO,kCAAkC;AAC3C;;EAEF,MAAM,OAAO,MAAM,EAAE,QAAQ;GAC3B,SAAS;GACT,cAAc;GACf,CAAC;AACF,MAAI,EAAE,SAAS,KAAK,IAAI,SAAS,MAAM;AACrC,KAAE,OAAO,kCAAkC;AAC3C;;;AAIJ,MAAK,MAAM,QAAQ,MAAM;AACvB,MAAI,CAAC,KAAK,WAAY;AAGtB,MAAI,KAAK,WAAW;GAClB,MAAM,KAAK,MAAM,EAAE,QAAQ;IACzB,SAAS,GAAG,KAAK,YAAY,kBAAkB,KAAK,OAAO,IAAI,KAAK,SAAS,GAAG;IAChF,cAAc;IACf,CAAC;AACF,OAAI,EAAE,SAAS,GAAG,IAAI,OAAO,MAAM;AACjC,MAAE,IAAI,KAAK,YAAY,KAAK,KAAK;AACjC;;;AAIJ,MAAI,KAAK,OAAO,eAAe;AAC7B,OAAI;IAEF,MAAM,WAAW,qBADJ,aAAa,CACiB;IAC3C,MAAM,aAAa,mBAAmB;IACtC,MAAM,wBAAQ,IAAI,KAAa;AAC/B,QAAI,WAAY,OAAM,IAAI,WAAW;AACrC,SAAK,MAAM,OAAO,SAAU,OAAM,IAAI,IAAI;AAC1C,SAAK,MAAM,OAAO,MAAO,OAAM,cAAc,KAAK,WAAW,IAAK;AAClE,wBAAoB;AACpB,sBAAkB;AAClB,MAAE,IAAI,QACJ,MAAM,OAAO,IACT,mBAAmB,MAAM,KAAK,MAAM,MAAM,SAAS,IAAI,KAAK,IAAI,KAChE,oBACL;YACM,KAAK;AACZ,MAAE,IAAI,KACJ,4BAA4B,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,GAC7E;;AAEH;;AAGF,MAAI,CAAC,KAAK,KAAM;EAChB,MAAM,IAAI,WAAW,KAAK,KAAK;AAC/B,MAAI,EAAE,GAAI,GAAE,IAAI,QAAQ,EAAE,QAAQ;MAC7B,GAAE,IAAI,MAAM,EAAE,QAAQ;;AAG7B,GAAE,MACA,uGACD;;CAGmD;CACpD,MAAM;CACN,SAAS;CACT,QAAQ;CACR,QAAQ;CACR,MAAM;CACN,SAAS;CACT,MAAM;CACN,QAAQ;CACR,KAAK;CACL,gBAAgB;CACjB,CAEwB,KAAK,MAAM,OAAO,OAClC,CAAC,OAAO,QAAQ;AACvB,GAAE,IAAI,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,CAAC;AAC7D,SAAQ,KAAK,EAAE;EACf"}
|
|
1
|
+
{"version":3,"file":"cli.mjs","names":["backupsDir","entryMatches","adapter","adapter","adapter","adapter","DOCS","adapter","adapter","DOCS","adapter","claudeCode","codex","cursor","geminiCli","openclaw","hermes","pi","openhuman","__dirname","findEnvExample","fsConstants","PATH_DELIMITER"],"sources":["../src/state/schema.ts","../src/cli/doctor-diagnostics.ts","../src/cli/remove-plan.ts","../src/cli/splash.ts","../src/cli/preferences.ts","../src/cli/connect/util.ts","../src/cli/connect/claude-code.ts","../src/cli/connect/codex.ts","../src/cli/connect/json-mcp-adapter.ts","../src/cli/connect/cursor.ts","../src/cli/connect/gemini-cli.ts","../src/cli/connect/hermes.ts","../src/cli/connect/openclaw.ts","../src/cli/connect/openhuman.ts","../src/cli/connect/pi.ts","../src/cli/connect/index.ts","../src/cli/onboarding.ts","../src/logger.ts","../src/version.ts","../src/cli.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 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} 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","// Doctor v2 diagnostic catalog.\n//\n// Each entry is a self-describing diagnostic: a check function that returns\n// `{ ok, detail? }`, a human-readable message, an inline fix preview, and\n// an `apply` function that runs the fix. The list is exported as a pure\n// data structure so unit tests can assert on shape without bringing\n// @clack/prompts into the test harness.\n//\n// The runtime (src/cli.ts -> runDoctor) iterates the list, prompts the user\n// per check, and only re-runs the SAME diagnostic after a fix — never the\n// whole suite. Each fix returns `{ ok, message? }` so we can show a one-line\n// outcome before moving on.\n//\n// Doctor v2 surface:\n// agentmemory doctor # interactive: Fix/Skip/More/Quit per failed check\n// agentmemory doctor --all # apply every available fix without prompting (CI)\n// agentmemory doctor --dry-run # show what each fix WOULD do; execute nothing\n\nexport type DiagnosticStatus = {\n ok: boolean;\n /** Short status detail (one line). Shown alongside the check name. */\n detail?: string;\n};\n\nexport type DiagnosticFixResult = {\n ok: boolean;\n message?: string;\n};\n\nexport type DoctorContext = {\n /** Base URL for the running engine, e.g. http://localhost:3111 */\n baseUrl: string;\n /** Viewer URL, e.g. http://localhost:3113 */\n viewerUrl: string;\n /** Path to ~/.agentmemory/.env */\n envPath: string;\n /** Path to ~/.agentmemory/iii.pid */\n pidfilePath: string;\n /** Path to ~/.agentmemory/engine-state.json */\n enginePath: string;\n /** Pinned engine version (e.g. \"0.11.2\"). */\n pinnedVersion: string;\n};\n\nexport type Diagnostic = {\n /** Stable id. Used in --json and tests. */\n id: string;\n /** One-line problem statement shown to the user. */\n message: string;\n /** One-line description of WHAT the fix will do. Shown before the prompt. */\n fixPreview: string;\n /** Longer explanation shown when the user picks [?] More info. */\n moreInfo: string;\n /** Run the check; return ok=true if everything's fine, ok=false otherwise. */\n check: (ctx: DoctorContext) => Promise<DiagnosticStatus>;\n /** Apply the fix. Returns ok=true on success. */\n fix: (ctx: DoctorContext) => Promise<DiagnosticFixResult>;\n /** True when there's nothing to auto-fix (we only suggest). */\n manualOnly?: boolean;\n};\n\n// Diagnostic ids are stable for testing and machine-readable doctor output.\nexport const DIAGNOSTIC_IDS = [\n \"env-missing\",\n \"no-llm-provider-key\",\n \"engine-version-mismatch\",\n \"viewer-unreachable\",\n \"stale-pidfile\",\n \"env-placeholder-keys\",\n \"iii-on-path-not-local-bin\",\n] as const;\n\nexport type DiagnosticId = (typeof DIAGNOSTIC_IDS)[number];\n\n// Pure helpers (no I/O) — exported for direct unit testing.\n// ---------------------------------------------------------------------------\n\n/** Common placeholder values shipped in .env.example. */\nconst PLACEHOLDER_VALUES = new Set([\n \"\",\n \"your-key-here\",\n \"sk-ant-...\",\n \"sk-...\",\n \"changeme\",\n \"todo\",\n \"xxx\",\n]);\n\nconst PROVIDER_KEY_NAMES = [\n \"ANTHROPIC_API_KEY\",\n \"OPENAI_API_KEY\",\n \"GEMINI_API_KEY\",\n \"GOOGLE_API_KEY\",\n \"OPENROUTER_API_KEY\",\n \"MINIMAX_API_KEY\",\n] as const;\n\nexport function parseEnvFile(content: string): Record<string, string> {\n const out: Record<string, string> = {};\n for (const rawLine of content.split(/\\r?\\n/)) {\n const line = rawLine.trim();\n if (!line || line.startsWith(\"#\")) continue;\n const eq = line.indexOf(\"=\");\n if (eq < 0) continue;\n const key = line.slice(0, eq).trim();\n let value = line.slice(eq + 1).trim();\n // Strip surrounding quotes.\n if (\n (value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\n ) {\n value = value.slice(1, -1);\n }\n out[key] = value;\n }\n return out;\n}\n\n/** Returns the list of provider keys that look real (non-placeholder). */\nexport function realProviderKeys(env: Record<string, string>): string[] {\n return PROVIDER_KEY_NAMES.filter((k) => {\n const v = (env[k] ?? \"\").trim();\n if (!v) return false;\n if (PLACEHOLDER_VALUES.has(v.toLowerCase())) return false;\n // Reject values that are just dots/placeholders like \"xxxx-xxxx\".\n if (/^x+$/i.test(v.replace(/[-_]/g, \"\"))) return false;\n return true;\n });\n}\n\n/** Returns the list of provider key NAMES that exist but are placeholders. */\nexport function placeholderProviderKeys(env: Record<string, string>): string[] {\n return PROVIDER_KEY_NAMES.filter((k) => {\n const v = (env[k] ?? \"\").trim();\n if (!v) return false;\n if (PLACEHOLDER_VALUES.has(v.toLowerCase())) return true;\n if (/^x+$/i.test(v.replace(/[-_]/g, \"\"))) return true;\n return false;\n });\n}\n\n/**\n * Build the canonical diagnostic catalog.\n *\n * The factory takes the side-effect helpers as injected functions so tests\n * can swap them with stubs. Production callers pass real implementations\n * from src/cli.ts.\n */\nexport type DoctorEffects = {\n /** Does ~/.agentmemory/.env exist? */\n envFileExists: () => boolean;\n /** Read ~/.agentmemory/.env and return parsed key=value pairs. */\n readEnvFile: () => Record<string, string>;\n /** Is the iii engine PID in the pidfile still alive? */\n pidfilePidIsAlive: () => boolean | null;\n /** Does the pidfile exist on disk? */\n pidfileExists: () => boolean;\n /** Resolve the iii binary on PATH; return null if not found. */\n findIiiBinary: () => string | null;\n /** Path to ~/.local/bin/iii (the location we install to). */\n localBinIiiPath: () => string;\n /** Run `iii --version`; null if it fails. */\n iiiBinaryVersion: (binPath: string) => string | null;\n /** Probe the viewer URL; true if it returns OK within timeoutMs. */\n viewerReachable: (timeoutMs?: number) => Promise<boolean>;\n /** Run init logic (copies .env.example). */\n runInit: () => Promise<DiagnosticFixResult>;\n /** Open a file in $EDITOR (or fallback). Resolves when editor exits. */\n openEditor: (path: string) => Promise<DiagnosticFixResult>;\n /** Run the iii installer. */\n runIiiInstaller: () => Promise<DiagnosticFixResult>;\n /** Stop the running engine cleanly. */\n runStop: () => Promise<DiagnosticFixResult>;\n /** Start the engine (waits for /livez). */\n runStart: () => Promise<DiagnosticFixResult>;\n /** Clear pidfile + engine-state. */\n clearEnginePidAndState: () => void;\n};\n\nexport function buildDiagnostics(effects: DoctorEffects): Diagnostic[] {\n return [\n {\n id: \"env-missing\",\n message: \"~/.agentmemory/.env is missing.\",\n fixPreview: \"Copy .env.example into ~/.agentmemory/.env (your keys file).\",\n moreInfo:\n \"agentmemory reads provider API keys (Anthropic, OpenAI, Gemini, …) from ~/.agentmemory/.env. \" +\n \"Without this file the daemon falls back to BM25-only search and no LLM-backed enrichment runs.\",\n check: async () => ({\n ok: effects.envFileExists(),\n detail: effects.envFileExists() ? undefined : \"no env file\",\n }),\n fix: () => effects.runInit(),\n },\n {\n id: \"no-llm-provider-key\",\n message: \"No LLM provider API key found in ~/.agentmemory/.env.\",\n fixPreview: \"Open ~/.agentmemory/.env in $EDITOR and paste your key, then re-check.\",\n moreInfo:\n \"Set at least one of: ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, \" +\n \"OPENROUTER_API_KEY, MINIMAX_API_KEY. The daemon picks the first that resolves \" +\n \"to a real (non-placeholder) value at startup.\",\n check: async () => {\n if (!effects.envFileExists()) {\n return { ok: false, detail: \"env file missing (run env-missing fix first)\" };\n }\n const env = effects.readEnvFile();\n const real = realProviderKeys(env);\n return {\n ok: real.length > 0,\n detail: real.length > 0 ? `found: ${real.join(\", \")}` : \"no provider key set\",\n };\n },\n fix: (ctx) => effects.openEditor(ctx.envPath),\n },\n {\n id: \"engine-version-mismatch\",\n message: \"iii binary on PATH doesn't match the version agentmemory pins to.\",\n fixPreview:\n \"Re-run the iii installer for the pinned version and restart the engine.\",\n moreInfo:\n \"agentmemory pins the iii engine to a specific release because newer engines \" +\n \"use a different worker model. Running a mismatched binary surfaces as EPIPE \" +\n \"reconnect loops and empty search results.\",\n check: async (ctx) => {\n const bin = effects.findIiiBinary();\n if (!bin) return { ok: false, detail: \"iii not on PATH\" };\n const v = effects.iiiBinaryVersion(bin);\n if (!v) return { ok: false, detail: \"iii on PATH but --version failed\" };\n return {\n ok: v === ctx.pinnedVersion,\n detail: `${v} (pinned ${ctx.pinnedVersion})`,\n };\n },\n fix: async () => {\n const r = await effects.runIiiInstaller();\n if (!r.ok) return r;\n // Best-effort restart: stop then start.\n await effects.runStop();\n return effects.runStart();\n },\n },\n {\n id: \"viewer-unreachable\",\n message: \"Viewer port not reachable.\",\n fixPreview: \"Stop the engine, restart it, and retry the viewer probe.\",\n moreInfo:\n \"The viewer is served on REST port + 2 (default 3113). If it never came up \" +\n \"the most common cause is port collision; a sibling PR ships auto-bump for \" +\n \"this case. If that lands first this check just verifies; otherwise restart \" +\n \"the engine to retry binding.\",\n check: async () => ({\n ok: await effects.viewerReachable(),\n detail: undefined,\n }),\n fix: async () => {\n const stopped = await effects.runStop();\n if (!stopped.ok) return stopped;\n return effects.runStart();\n },\n },\n {\n id: \"stale-pidfile\",\n message: \"Stale pidfile: pid recorded but the process is gone.\",\n fixPreview: \"Clear ~/.agentmemory/iii.pid + engine-state.json, then restart.\",\n moreInfo:\n \"When the engine crashes hard (kill -9, OOM, host reboot) the pidfile sticks \" +\n \"around. agentmemory refuses to start a second engine on top of a stale pid, \" +\n \"so this state must be cleared explicitly.\",\n check: async () => {\n if (!effects.pidfileExists()) return { ok: true, detail: \"no pidfile\" };\n const alive = effects.pidfilePidIsAlive();\n if (alive === null) return { ok: true, detail: \"pidfile unreadable\" };\n return {\n ok: alive,\n detail: alive ? \"pid is alive\" : \"pid is gone\",\n };\n },\n fix: async () => {\n effects.clearEnginePidAndState();\n return effects.runStart();\n },\n },\n {\n id: \"env-placeholder-keys\",\n message: \"~/.agentmemory/.env contains placeholder/empty API keys.\",\n fixPreview: \"Open ~/.agentmemory/.env in $EDITOR to paste real values.\",\n moreInfo:\n \"Lines like ANTHROPIC_API_KEY=sk-ant-... or =your-key-here are treated as \" +\n \"absent. The daemon will fall back to BM25-only search. Replace placeholders \" +\n \"with real keys or comment the line out.\",\n check: async () => {\n if (!effects.envFileExists()) {\n return { ok: true, detail: \"env file missing (handled by env-missing)\" };\n }\n const env = effects.readEnvFile();\n const placeholders = placeholderProviderKeys(env);\n return {\n ok: placeholders.length === 0,\n detail:\n placeholders.length === 0\n ? undefined\n : `placeholder: ${placeholders.join(\", \")}`,\n };\n },\n fix: (ctx) => effects.openEditor(ctx.envPath),\n },\n {\n id: \"iii-on-path-not-local-bin\",\n message:\n \"iii is on PATH but not in ~/.local/bin/iii (where we install).\",\n fixPreview:\n \"Suggest re-installing the pinned version via the installer — won't touch your PATH.\",\n moreInfo:\n \"agentmemory's installer writes to ~/.local/bin/iii. When a user-managed iii \" +\n \"lives somewhere else (homebrew, cargo, $XDG_BIN) we don't auto-overwrite it. \" +\n \"If you want our pinned build, run the installer; otherwise this is informational.\",\n manualOnly: true,\n check: async () => {\n const bin = effects.findIiiBinary();\n if (!bin) return { ok: true, detail: \"iii not on PATH (handled elsewhere)\" };\n const localBin = effects.localBinIiiPath();\n return {\n ok: bin === localBin,\n detail: bin === localBin ? undefined : `iii at: ${bin}`,\n };\n },\n fix: async () =>\n effects.runIiiInstaller().then((r) => ({\n ok: r.ok,\n message:\n r.message ??\n \"Installer wrote to ~/.local/bin/iii. Your PATH wasn't modified — adjust it yourself if needed.\",\n })),\n },\n ];\n}\n\nexport type DoctorRunMode = \"interactive\" | \"all\" | \"dry-run\";\n\n/**\n * Run all diagnostics and return their initial status (no fixes applied).\n * Useful for tests and for `--dry-run` mode.\n */\nexport async function runAllChecks(\n ctx: DoctorContext,\n diagnostics: Diagnostic[],\n): Promise<Array<{ diagnostic: Diagnostic; status: DiagnosticStatus }>> {\n const results: Array<{ diagnostic: Diagnostic; status: DiagnosticStatus }> = [];\n for (const d of diagnostics) {\n const status = await d.check(ctx);\n results.push({ diagnostic: d, status });\n }\n return results;\n}\n\n/**\n * Dry-run output: each failing check's fix preview, prefixed by the diagnostic\n * message. Pure function so we can snapshot-test the format.\n */\nexport function dryRunPlan(\n ctx: DoctorContext,\n results: Array<{ diagnostic: Diagnostic; status: DiagnosticStatus }>,\n): string[] {\n const lines: string[] = [];\n let n = 0;\n for (const { diagnostic, status } of results) {\n if (status.ok) continue;\n n++;\n lines.push(`${n}. [${diagnostic.id}] ${diagnostic.message}`);\n lines.push(` would fix: ${diagnostic.fixPreview}`);\n if (status.detail) lines.push(` detail: ${status.detail}`);\n }\n if (lines.length === 0) {\n lines.push(`All checks passing for ${ctx.baseUrl} — no fixes to run.`);\n }\n return lines;\n}\n","// `agentmemory remove` — destruction plan.\n//\n// Generating the plan is a pure function of the on-disk state (which files\n// exist, whether ~/.local/bin/iii matches the version we installed, the\n// connect-manifest contents). All side effects live in src/cli.ts; this\n// module owns only the planning logic so it's unit-testable without\n// touching $HOME.\n//\n// CLI surface:\n// agentmemory remove # interactive, double-confirms\n// agentmemory remove --force # skip confirmations\n// agentmemory remove --keep-data # remove binaries+symlinks, keep memory data\n\nimport { existsSync, statSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nexport type RemovePlanItem = {\n /** Stable id, used in tests and CLI output. */\n id: string;\n /** Human-readable description of the action. */\n description: string;\n /** Absolute path being acted on (or null for non-fs actions). */\n path: string | null;\n /** Whether this item is `ask-again` even with --force (e.g. memory data). */\n alwaysAsk: boolean;\n /** Whether the file actually exists / action is meaningful. Plan-time hint. */\n applicable: boolean;\n /** Bytes (for files) or -1 (unknown / dir). Pure metadata. */\n sizeBytes: number;\n};\n\nexport type RemoveOptions = {\n /** Skip confirmations (still asks separately about always-ask items). */\n force: boolean;\n /** Keep ~/.agentmemory/* user data; only remove binaries/symlinks. */\n keepData: boolean;\n};\n\nexport type RemoveContext = {\n /** $HOME (so tests can sandbox). */\n home: string;\n /** Pinned engine version we expect ~/.local/bin/iii to match. */\n pinnedVersion: string;\n /**\n * `iii --version` result for ~/.local/bin/iii, or null if it's missing /\n * unreadable / not executable. Passed in so the plan module stays pure.\n */\n localBinIiiVersion: string | null;\n /** Loaded connect manifest, or null if missing. */\n connectManifest: ConnectManifest | null;\n};\n\n/**\n * The `agentmemory connect` PR writes this manifest at\n * ~/.agentmemory/backups/connect-manifest.json. We tolerate it being absent\n * (older versions, fresh installs) by treating it as `{ installed: [] }`.\n */\nexport type ConnectManifest = {\n installed: Array<{\n /** Target path the connect command wrote (symlink or file). */\n target: string;\n /** Agent label, e.g. \"claude-code\", \"cursor\". */\n agent?: string;\n /** Whether this was a symlink (true) or copy (false). */\n symlink?: boolean;\n }>;\n};\n\nexport function pidfilePath(home: string): string {\n return join(home, \".agentmemory\", \"iii.pid\");\n}\n\nexport function enginePath(home: string): string {\n return join(home, \".agentmemory\", \"engine-state.json\");\n}\n\nexport function envPath(home: string): string {\n return join(home, \".agentmemory\", \".env\");\n}\n\nexport function preferencesPath(home: string): string {\n return join(home, \".agentmemory\", \"preferences.json\");\n}\n\nexport function backupsDir(home: string): string {\n return join(home, \".agentmemory\", \"backups\");\n}\n\nexport function dataDir(home: string): string {\n return join(home, \".agentmemory\", \"data\");\n}\n\nexport function localBinIii(home: string): string {\n return join(home, \".local\", \"bin\", \"iii\");\n}\n\nfunction safeSize(path: string): number {\n try {\n return statSync(path).size;\n } catch {\n return -1;\n }\n}\n\nfunction pathExists(path: string): boolean {\n try {\n return existsSync(path);\n } catch {\n return false;\n }\n}\n\n/**\n * Build the destruction plan for `agentmemory remove`.\n *\n * Plan items are returned regardless of whether `applicable` is true — the\n * caller can decide whether to skip-and-log or hide entirely. This keeps\n * the structure stable for tests.\n */\nexport function buildRemovePlan(\n ctx: RemoveContext,\n options: RemoveOptions,\n): RemovePlanItem[] {\n const { home, pinnedVersion, localBinIiiVersion, connectManifest } = ctx;\n const plan: RemovePlanItem[] = [];\n\n plan.push({\n id: \"stop-engine\",\n description: \"Stop running iii-engine (if any) cleanly\",\n path: null,\n alwaysAsk: false,\n applicable: pathExists(pidfilePath(home)) || pathExists(enginePath(home)),\n sizeBytes: -1,\n });\n\n plan.push({\n id: \"pidfile\",\n description: \"Delete pidfile\",\n path: pidfilePath(home),\n alwaysAsk: false,\n applicable: pathExists(pidfilePath(home)),\n sizeBytes: safeSize(pidfilePath(home)),\n });\n\n plan.push({\n id: \"engine-state\",\n description: \"Delete engine-state.json\",\n path: enginePath(home),\n alwaysAsk: false,\n applicable: pathExists(enginePath(home)),\n sizeBytes: safeSize(enginePath(home)),\n });\n\n // .env holds the user's API keys. Always ask before deleting, even on\n // --force. --keep-data keeps it as part of \"user data\".\n plan.push({\n id: \"env\",\n description: \"Delete .env (your API keys) — will ask separately\",\n path: envPath(home),\n alwaysAsk: true,\n applicable: !options.keepData && pathExists(envPath(home)),\n sizeBytes: safeSize(envPath(home)),\n });\n\n plan.push({\n id: \"preferences\",\n description: \"Delete preferences.json\",\n path: preferencesPath(home),\n alwaysAsk: false,\n applicable: !options.keepData && pathExists(preferencesPath(home)),\n sizeBytes: safeSize(preferencesPath(home)),\n });\n\n plan.push({\n id: \"backups\",\n description: \"Delete backups/ directory (connect manifest + backups)\",\n path: backupsDir(home),\n alwaysAsk: false,\n applicable: !options.keepData && pathExists(backupsDir(home)),\n sizeBytes: -1,\n });\n\n // Iterate over connect-installed agent symlinks. We always honor these\n // (even with --keep-data, since they're outside ~/.agentmemory/).\n if (connectManifest?.installed?.length) {\n for (const entry of connectManifest.installed) {\n plan.push({\n id: `connect:${entry.target}`,\n description: `Remove agent connection (${entry.agent ?? \"unknown\"})`,\n path: entry.target,\n alwaysAsk: false,\n applicable: pathExists(entry.target),\n sizeBytes: safeSize(entry.target),\n });\n }\n }\n\n // ~/.local/bin/iii — only remove if it matches the version we installed.\n // Heuristic: spawn `iii --version`; if it returns pinnedVersion, safe to\n // remove. Otherwise mark `alwaysAsk` so the operator confirms explicitly.\n const localIii = localBinIii(home);\n if (pathExists(localIii)) {\n const matches = localBinIiiVersion === pinnedVersion;\n plan.push({\n id: \"local-bin-iii\",\n description: matches\n ? `Delete ~/.local/bin/iii (matches pinned v${pinnedVersion})`\n : `Delete ~/.local/bin/iii (version ${localBinIiiVersion ?? \"unknown\"} != pinned v${pinnedVersion}) — will ask`,\n path: localIii,\n alwaysAsk: !matches,\n applicable: true,\n sizeBytes: safeSize(localIii),\n });\n }\n\n // Memory data dir — ALWAYS asks separately, even with --force. Default\n // behavior is keep.\n plan.push({\n id: \"data-dir\",\n description:\n \"Delete memory data directory (~/.agentmemory/data/) — will ask separately\",\n path: dataDir(home),\n alwaysAsk: true,\n applicable: !options.keepData && pathExists(dataDir(home)),\n sizeBytes: -1,\n });\n\n return plan;\n}\n\n/** Format a plan for the user — one line per item. */\nexport function formatPlan(plan: RemovePlanItem[]): string {\n return plan\n .filter((p) => p.applicable)\n .map((p, i) => {\n const tag = p.alwaysAsk ? \" [asks]\" : \"\";\n const sz =\n p.sizeBytes > 0 ? ` (${humanBytes(p.sizeBytes)})` : \"\";\n return ` ${i + 1}. ${p.description}${tag}${sz}${p.path ? `\\n ${p.path}` : \"\"}`;\n })\n .join(\"\\n\");\n}\n\nfunction humanBytes(n: number): string {\n if (n < 1024) return `${n} B`;\n if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;\n return `${(n / (1024 * 1024)).toFixed(1)} MB`;\n}\n","// Terminal-width-aware splash banner for the agentmemory CLI.\n//\n// Three render tiers, picked from `process.stdout.columns`:\n//\n// >= 120 cols: full block-art logo + tagline.\n// 80–119 cols: compact monospace title + tagline.\n// < 80 cols: single-line `agentmemory v<VERSION>`.\n//\n// The brand accent is the orange `#FF6B35` we already use in the README\n// and viewer; we render it through ANSI 38;5;208 (the closest xterm-256\n// match) when stdout is a TTY, and fall back to plain text otherwise.\n// No colour bytes are hard-coded into the strings themselves so that\n// piping the banner to a file (`agentmemory > log`) stays clean.\n//\n// We don't pull in chalk/picocolors — picocolors is a transitive dep but\n// we never want to depend on transitives directly. The two ANSI escape\n// helpers below are the entire colour surface and they degrade to\n// no-ops automatically.\n\nconst IS_COLOR_TTY = !!process.stdout.isTTY && !process.env[\"NO_COLOR\"];\n\nfunction accent(s: string): string {\n // 256-colour orange that visually matches #FF6B35 in most modern\n // terminal palettes. We pick 208 (a true orange) over the closer-but-\n // pinker 209 because it reads as the brand colour on both dark and\n // light backgrounds.\n return IS_COLOR_TTY ? `\\x1b[38;5;208m${s}\\x1b[0m` : s;\n}\n\nfunction dim(s: string): string {\n return IS_COLOR_TTY ? `\\x1b[2m${s}\\x1b[22m` : s;\n}\n\nfunction bold(s: string): string {\n return IS_COLOR_TTY ? `\\x1b[1m${s}\\x1b[22m` : s;\n}\n\nfunction getTerminalWidth(): number {\n const w = process.stdout.columns;\n return typeof w === \"number\" && w > 0 ? w : 80;\n}\n\nconst TAGLINE = \"Persistent memory for AI coding agents\";\n\n// \"agentmemory\" rendered in figlet's standard font (verified output —\n// regenerate via `figlet agentmemory` if you change the wordmark). Each\n// row is exactly 70 columns wide so the banner aligns cleanly inside\n// the 2-col left margin we add below.\nfunction fullBanner(version: string): string {\n const logo = [\n \" _ \",\n \" __ _ __ _ ___ _ __ | |_ _ __ ___ ___ _ __ ___ ___ _ __ _ _ \",\n \" / _` |/ _` |/ _ \\\\ '_ \\\\| __| '_ ` _ \\\\ / _ \\\\ '_ ` _ \\\\ / _ \\\\| '__| | | |\",\n \"| (_| | (_| | __/ | | | |_| | | | | | __/ | | | | | (_) | | | |_| |\",\n \" \\\\__,_|\\\\__, |\\\\___|_| |_|\\\\__|_| |_| |_|\\\\___|_| |_| |_|\\\\___/|_| \\\\__, |\",\n \" |___/ |___/ \",\n ];\n const lines: string[] = [\"\", ...logo.map((line) => \" \" + accent(line))];\n lines.push(\"\");\n lines.push(\" \" + bold(TAGLINE) + \" \" + dim(`v${version}`));\n lines.push(\"\");\n return lines.join(\"\\n\");\n}\n\nfunction compactBanner(version: string): string {\n const title = \" \" + bold(accent(\"agentmemory\"));\n const meta = \" \" + dim(`v${version} · ${TAGLINE}`);\n return [\"\", title, meta, \"\"].join(\"\\n\");\n}\n\nfunction minimalBanner(version: string): string {\n return `${accent(\"agentmemory\")} ${dim(`v${version}`)}`;\n}\n\nexport function renderSplash(version: string): void {\n const width = getTerminalWidth();\n let out: string;\n if (width >= 120) {\n out = fullBanner(version);\n } else if (width >= 80) {\n out = compactBanner(version);\n } else {\n out = minimalBanner(version);\n }\n process.stdout.write(out + \"\\n\");\n}\n","// JSON-backed CLI preferences.\n//\n// Lives at `~/.agentmemory/preferences.json`. The agentmemory daemon\n// already owns `~/.agentmemory/.env`, `iii.pid`, `engine-state.json` —\n// adding one more sibling here keeps the install-state surface in one\n// place.\n//\n// All functions are synchronous, mirroring the pidfile / engine-state\n// helpers in src/cli.ts. We never throw: read failures collapse to\n// defaults; write failures swallow silently. Preferences are a UX\n// nicety, not data — corrupting `iii.pid` matters, corrupting this\n// file does not.\n//\n// Writes are atomic via tmp + rename so a Ctrl+C between the open and\n// the final write can't leave a half-written JSON blob on disk that\n// the next read would refuse to parse.\n\nimport {\n closeSync,\n existsSync,\n fsyncSync,\n mkdirSync,\n openSync,\n readFileSync,\n renameSync,\n unlinkSync,\n writeSync,\n} from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nexport interface Prefs {\n schemaVersion: 1;\n // Most recently picked single agent (for \"use last agent\" style flows).\n lastAgent: string | null;\n // The full multi-select set from the last onboarding run.\n lastAgents: string[];\n // Most recently picked LLM provider; `null` means BM25-only mode.\n lastProvider: string | null;\n // Once true, splash is rendered only on first run / explicit --reset.\n // The first onboarding sets this to true so the second invocation\n // skips the banner.\n skipSplash: boolean;\n // Reserved for a later \"do not nag me about the npx vs install\n // tradeoff\" toggle. Kept on the schema so we don't have to bump\n // schemaVersion when we ship the flag.\n skipNpxHint: boolean;\n // Set to true when the user declines the \"install agentmemory\n // globally?\" prompt on first npx run. We never ask again on this\n // machine so the prompt stays a one-time DX nudge, not a nag.\n skipGlobalInstall: boolean;\n // Set to true when the user declines the \"install iii console?\"\n // prompt. iii console is first-class engine UI but optional at the\n // install step — once the user says no, we stop asking.\n skipConsoleInstall: boolean;\n // ISO timestamp of the first time onboarding completed. Set once,\n // never updated, so we can show \"you joined agentmemory N days ago\"\n // copy in /status later without keeping a separate file.\n firstRunAt: string | null;\n}\n\nconst DEFAULTS: Prefs = {\n schemaVersion: 1,\n lastAgent: null,\n lastAgents: [],\n lastProvider: null,\n skipSplash: false,\n skipNpxHint: false,\n skipGlobalInstall: false,\n skipConsoleInstall: false,\n firstRunAt: null,\n};\n\nexport function prefsDir(): string {\n return join(homedir(), \".agentmemory\");\n}\n\nexport function prefsPath(): string {\n return join(prefsDir(), \"preferences.json\");\n}\n\nexport function readPrefs(): Prefs {\n try {\n if (!existsSync(prefsPath())) return { ...DEFAULTS };\n const raw = readFileSync(prefsPath(), \"utf-8\");\n const parsed = JSON.parse(raw) as Partial<Prefs>;\n return { ...DEFAULTS, ...parsed, schemaVersion: 1 };\n } catch {\n return { ...DEFAULTS };\n }\n}\n\nexport function writePrefs(p: Partial<Prefs>): void {\n try {\n const dir = prefsDir();\n mkdirSync(dir, { recursive: true });\n const current = readPrefs();\n const next: Prefs = { ...current, ...p, schemaVersion: 1 };\n const target = prefsPath();\n const tmp = target + \".tmp\";\n // Open + write + fsync + rename ensures a Ctrl+C between any two\n // syscalls either leaves the old file intact (rename is atomic on\n // POSIX) or leaves only a .tmp behind that the next writePrefs\n // overwrites. We never end up with a truncated `preferences.json`\n // that readPrefs would have to discard.\n const fd = openSync(tmp, \"w\", 0o600);\n try {\n writeSync(fd, JSON.stringify(next, null, 2) + \"\\n\");\n try {\n fsyncSync(fd);\n } catch {\n // fsync isn't available on every filesystem (e.g. some Docker\n // overlays). The rename below is still atomic; we just can't\n // guarantee durability against a power loss.\n }\n } finally {\n closeSync(fd);\n }\n renameSync(tmp, target);\n } catch {\n // Preferences are best-effort. Don't crash the CLI for them.\n }\n}\n\nexport function resetPrefs(): void {\n try {\n unlinkSync(prefsPath());\n } catch {\n // Already gone — that's exactly the state we wanted.\n }\n}\n\nexport function isFirstRun(): boolean {\n // \"First run\" means: the preferences file doesn't exist OR exists\n // but `firstRunAt` was never recorded. The latter handles users who\n // had `.agentmemory/preferences.json` from a much older agentmemory\n // build that wrote a different schema — we treat them as new.\n if (!existsSync(prefsPath())) return true;\n return readPrefs().firstRunAt === null;\n}\n","import {\n existsSync,\n mkdirSync,\n readFileSync,\n writeFileSync,\n copyFileSync,\n renameSync,\n} from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport * as p from \"@clack/prompts\";\n\n// Env values use ${VAR} expansion so the wired MCP entry inherits\n// AGENTMEMORY_URL / AGENTMEMORY_SECRET from the user's shell. When the\n// vars are unset, the host (Claude Code, Cursor, etc.) substitutes an\n// empty string; the standalone shim treats empty as missing and falls\n// back to http://localhost:3111. This lets a single wired entry serve\n// both local and remote (Kubernetes / reverse-proxied) deployments\n// without doctor-warning duplicates (#375).\nexport const AGENTMEMORY_MCP_BLOCK = {\n command: \"npx\",\n args: [\"-y\", \"@agentmemory/mcp\"],\n env: {\n AGENTMEMORY_URL: \"${AGENTMEMORY_URL}\",\n AGENTMEMORY_SECRET: \"${AGENTMEMORY_SECRET}\",\n },\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, 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\";\n\nconst CLAUDE_DIR = join(homedir(), \".claude\");\nconst CLAUDE_JSON = join(homedir(), \".claude.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 docs: \"https://github.com/rohitg00/agentmemory#claude-code-one-block-paste-it\",\n protocolNote:\n \"→ Using MCP. Hooks are also available — see docs/claude-code.md.\",\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 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 return { kind: \"installed\", mutatedPath: CLAUDE_JSON, backupPath };\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} from \"./util.js\";\n\nconst CODEX_DIR = join(homedir(), \".codex\");\nconst CODEX_TOML = join(CODEX_DIR, \"config.toml\");\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 docs: \"https://github.com/rohitg00/agentmemory#codex-cli-codex-plugin-platform\",\n protocolNote:\n \"→ Using MCP. Hooks are also available — see docs/codex.md.\",\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 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 install agentmemory\",\n );\n return {\n kind: \"installed\",\n mutatedPath: CODEX_TOML,\n ...(backupPath !== undefined && { backupPath }),\n };\n },\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};\n\ntype McpEntry = typeof AGENTMEMORY_MCP_BLOCK;\ntype McpConfig = {\n mcpServers?: Record<string, McpEntry>;\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 function createJsonMcpAdapter(\n config: JsonMcpAdapterConfig,\n): ConnectAdapter {\n return {\n name: config.name,\n displayName: config.displayName,\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.mcpServers 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\"} mcpServers.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\"] = AGENTMEMORY_MCP_BLOCK;\n next.mcpServers = servers;\n writeJsonAtomic(config.configPath, next);\n\n const verify = readJsonSafe<McpConfig>(config.configPath);\n if (!entryMatches(verify?.mcpServers?.[\"agentmemory\"])) {\n p.log.error(\n `Verification failed: ${config.configPath} did not contain mcpServers.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 } 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\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 docs: DOCS,\n protocolNote:\n \"→ Using MCP. Hooks are also available — see docs/hermes.md.\",\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\nexport const adapter = createJsonMcpAdapter({\n name: \"openclaw\",\n displayName: \"OpenClaw\",\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 docs/openclaw.md.\",\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 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 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 { platform } from \"node:os\";\nimport * as p from \"@clack/prompts\";\nimport type { ConnectAdapter, ConnectOptions, ConnectResult } from \"./types.js\";\nimport { adapter as claudeCode } from \"./claude-code.js\";\nimport { adapter as codex } from \"./codex.js\";\nimport { adapter as cursor } from \"./cursor.js\";\nimport { adapter as geminiCli } from \"./gemini-cli.js\";\nimport { adapter as hermes } from \"./hermes.js\";\nimport { adapter as openclaw } from \"./openclaw.js\";\nimport { adapter as openhuman } from \"./openhuman.js\";\nimport { adapter as pi } from \"./pi.js\";\n\nexport const ADAPTERS: readonly ConnectAdapter[] = [\n claudeCode,\n codex,\n cursor,\n geminiCli,\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 positional: string[];\n} {\n const positional: string[] = [];\n let dryRun = false;\n let force = false;\n let all = 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.startsWith(\"-\")) positional.push(a);\n }\n return { dryRun, force, all, 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 if (platform() === \"win32\") {\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 { dryRun, force, all, positional } = parseFlags(args);\n const opts: ConnectOptions = { dryRun, force };\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 ` ✓ ${name}${result.mutatedPath ? ` → ${result.mutatedPath}` : \"\"}`;\n case \"already-wired\":\n return ` ✓ ${name} (already wired)`;\n case \"stub\":\n return ` ⚠ ${name} (manual install required: ${result.reason})`;\n case \"skipped\":\n return ` ✗ ${name} (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 p.outro(\"Restart any wired agent (or open a new session) to pick up agentmemory.\");\n}\n","// First-run interactive onboarding flow.\n//\n// Wakes up only when `isFirstRun()` is true (preferences are missing or\n// have never recorded a `firstRunAt`) or when the user passes\n// `--reset`. The flow asks for:\n//\n// 1. Which agents will be wired to agentmemory (multi-select). Each\n// option carries a small glyph that we reuse in /status output so\n// the user recognises them later. The label mirrors README row 1\n// (native plugins) and row 2 (MCP-only).\n// 2. Which LLM provider to use for compress / consolidate / graph.\n// \"skip — BM25-only mode\" is a real first-class option; lots of\n// users want agentmemory purely as a hybrid keyword + vector\n// memory layer without granting LLM API keys.\n//\n// We then write `~/.agentmemory/preferences.json` and seed\n// `~/.agentmemory/.env` with a commented-out `*_API_KEY=` line for the\n// chosen provider. This matches the existing `agentmemory init` flow\n// closely so users who skip onboarding still get the same file via\n// `agentmemory init`.\n\nimport { copyFile, mkdir } from \"node:fs/promises\";\nimport { constants as fsConstants, existsSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport * as p from \"@clack/prompts\";\nimport { writePrefs } from \"./preferences.js\";\nimport { resolveAdapter, runAdapter } from \"./connect/index.js\";\nimport type { ConnectResult } from \"./connect/types.js\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\n// Native plugin row — these agents ship an agentmemory plugin or\n// first-party integration. Glyphs match SkillKit's published set\n// where they overlap; the rest fall back to the generic `◇`.\nconst NATIVE_AGENTS: { value: string; label: string; glyph: string }[] = [\n { value: \"claude-code\", label: \"Claude Code\", glyph: \"⟁\" },\n { value: \"codex\", label: \"Codex\", glyph: \"◎\" },\n { value: \"openhuman\", label: \"OpenHuman\", glyph: \"◇\" },\n { value: \"openclaw\", label: \"OpenClaw\", glyph: \"◇\" },\n { value: \"hermes\", label: \"Hermes\", glyph: \"◇\" },\n { value: \"pi\", label: \"Pi\", glyph: \"◇\" },\n { value: \"cursor\", label: \"Cursor\", glyph: \"◫\" },\n { value: \"gemini-cli\", label: \"Gemini CLI\", glyph: \"✦\" },\n];\n\n// MCP-only row — these agents use the MCP server we ship rather than\n// a native plugin.\nconst MCP_AGENTS: { value: string; label: string; glyph: string }[] = [\n { value: \"opencode\", label: \"OpenCode\", glyph: \"⬡\" },\n { value: \"cline\", label: \"Cline\", glyph: \"◇\" },\n { value: \"goose\", label: \"Goose\", glyph: \"◇\" },\n { value: \"kilo\", label: \"Kilo\", glyph: \"◇\" },\n { value: \"aider\", label: \"Aider\", glyph: \"◇\" },\n { value: \"claude-desktop\", label: \"Claude Desktop\", glyph: \"⟁\" },\n { value: \"windsurf\", label: \"Windsurf\", glyph: \"◇\" },\n { value: \"roo\", label: \"Roo\", glyph: \"◇\" },\n];\n\nconst PROVIDERS: { value: string; label: string; envKey: string | null }[] = [\n { value: \"anthropic\", label: \"Anthropic — claude\", envKey: \"ANTHROPIC_API_KEY\" },\n { value: \"openai\", label: \"OpenAI — gpt\", envKey: \"OPENAI_API_KEY\" },\n { value: \"gemini\", label: \"Google — gemini\", envKey: \"GEMINI_API_KEY\" },\n { value: \"openrouter\", label: \"OpenRouter — multi-model\", envKey: \"OPENROUTER_API_KEY\" },\n { value: \"minimax\", label: \"MiniMax — minimax-m1\", envKey: \"MINIMAX_API_KEY\" },\n { value: \"skip\", label: \"Skip — BM25-only mode (no LLM key)\", envKey: null },\n];\n\nfunction buildAgentOptions(): { value: string; label: string; hint?: string }[] {\n return [\n ...NATIVE_AGENTS.map((a) => ({\n value: a.value,\n label: `${a.glyph} ${a.label}`,\n hint: \"native plugin\",\n })),\n ...MCP_AGENTS.map((a) => ({\n value: a.value,\n label: `${a.glyph} ${a.label}`,\n hint: \"MCP server\",\n })),\n ];\n}\n\n// Mirror src/cli.ts findEnvExample so onboarding ships the same .env\n// skeleton whether called directly or via `agentmemory init`. We\n// duplicate (rather than import) so the onboarding module doesn't\n// pull cli.ts's top-level side effects into the test runner.\nfunction findEnvExample(): string | null {\n const candidates = [\n join(__dirname, \"..\", \"..\", \".env.example\"),\n join(__dirname, \"..\", \".env.example\"),\n join(__dirname, \".env.example\"),\n join(process.cwd(), \".env.example\"),\n ];\n for (const c of candidates) {\n if (existsSync(c)) return c;\n }\n return null;\n}\n\nasync function seedEnvFile(provider: string | null): Promise<string | null> {\n const target = join(homedir(), \".agentmemory\", \".env\");\n const dir = dirname(target);\n await mkdir(dir, { recursive: true });\n\n const template = findEnvExample();\n if (template && !existsSync(target)) {\n try {\n await copyFile(template, target, fsConstants.COPYFILE_EXCL);\n } catch (err) {\n if ((err as NodeJS.ErrnoException)?.code !== \"EEXIST\") {\n return null;\n }\n }\n } else if (!template && !existsSync(target)) {\n // Fall back to a minimal skeleton so users always get a `.env` to\n // edit. This matches the shape of the bundled `.env.example`\n // without forcing us to keep two copies in sync.\n const lines = [\n \"# agentmemory environment — uncomment what you need\",\n \"# AGENTMEMORY_URL=http://localhost:3111\",\n \"\",\n ];\n const envKey = PROVIDERS.find((x) => x.value === provider)?.envKey;\n if (envKey) {\n lines.push(`# ${envKey}=`);\n }\n writeFileSync(target, lines.join(\"\\n\"), { mode: 0o600 });\n }\n\n return target;\n}\n\nexport interface OnboardingResult {\n agents: string[];\n provider: string | null;\n}\n\nexport async function runOnboarding(): Promise<OnboardingResult> {\n p.note(\n [\n \"Welcome to agentmemory.\",\n \"\",\n \"Persistent memory for your AI coding agents. We'll pick which\",\n \"agents to wire up and which provider (if any) handles compression\",\n \"and consolidation. Either step can be changed later in ~/.agentmemory/.env.\",\n ].join(\"\\n\"),\n \"first-run setup\",\n );\n\n const agentsPicked = await p.multiselect<string>({\n message: \"Which agents will use agentmemory? (space to toggle, enter to confirm)\",\n options: buildAgentOptions(),\n required: false,\n initialValues: [\"claude-code\"],\n });\n if (p.isCancel(agentsPicked)) {\n p.cancel(\"Setup cancelled. Re-run any time with: agentmemory --reset\");\n process.exit(0);\n }\n\n const pickedAgentsList = (agentsPicked as string[]) ?? [];\n if (pickedAgentsList.length > 0) {\n p.note(\n [\n \"━ how this works ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\",\n \"All selected agents share the same memory at :3111.\",\n \"A memory saved by Claude Code is visible to Codex + Cursor instantly.\",\n \"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\",\n ].join(\"\\n\"),\n );\n }\n\n const providerPicked = await p.select<string>({\n message: \"Which LLM provider should agentmemory use for compress/consolidate?\",\n options: PROVIDERS.map(({ value, label }) => ({ value, label })),\n initialValue: \"anthropic\",\n });\n if (p.isCancel(providerPicked)) {\n p.cancel(\"Setup cancelled. Re-run any time with: agentmemory --reset\");\n process.exit(0);\n }\n\n const provider = providerPicked === \"skip\" ? null : providerPicked;\n const agents = (agentsPicked as string[]) ?? [];\n\n const envPath = await seedEnvFile(provider);\n\n writePrefs({\n lastAgent: agents[0] ?? null,\n lastAgents: agents,\n lastProvider: provider,\n skipSplash: true,\n firstRunAt: new Date().toISOString(),\n });\n\n const prefsLocation = join(homedir(), \".agentmemory\", \"preferences.json\");\n const lines = [`✓ Saved preferences to ${prefsLocation}`];\n if (envPath) {\n lines.push(`✓ Wrote ${envPath} (edit to add your API key)`);\n } else {\n lines.push(`! Could not write ~/.agentmemory/.env — run \\`agentmemory init\\` after this completes.`);\n }\n if (provider) {\n const envKey = PROVIDERS.find((x) => x.value === provider)?.envKey;\n if (envKey) {\n lines.push(` Uncomment ${envKey}= in that file to enable ${provider}.`);\n }\n } else {\n lines.push(\" No provider chosen — agentmemory will run in BM25-only mode.\");\n }\n p.note(lines.join(\"\\n\"), \"ready\");\n\n if (agents.length > 0) {\n await wireSelectedAgents(agents);\n }\n\n return { agents, provider };\n}\n\nasync function wireSelectedAgents(agents: string[]): Promise<void> {\n p.note(\"Wire selected agents now?\", \"next step\");\n const confirmed = await p.confirm({\n message: \"Run `agentmemory connect <agent>` for each selected agent now? [Y/n]\",\n initialValue: true,\n });\n\n if (p.isCancel(confirmed) || confirmed === false) {\n const cmds = agents.map((a) => ` agentmemory connect ${a}`);\n p.note([\"Wire later with:\", ...cmds].join(\"\\n\"), \"later\");\n return;\n }\n\n const wired: string[] = [];\n const manual: { name: string; docs?: string }[] = [];\n const failed: { name: string; reason: string }[] = [];\n\n for (const name of agents) {\n const adapter = resolveAdapter(name);\n if (!adapter) {\n failed.push({ name, reason: \"no adapter available\" });\n p.log.warn(`Wiring ${name}… no adapter available (skipped).`);\n continue;\n }\n p.log.step(`Wiring ${name}...`);\n let result: ConnectResult;\n try {\n result = await runAdapter(adapter, { dryRun: false, force: false });\n } catch (err) {\n const reason = err instanceof Error ? err.message : String(err);\n failed.push({ name, reason });\n p.log.error(`${name}: ${reason}`);\n continue;\n }\n switch (result.kind) {\n case \"installed\":\n case \"already-wired\":\n wired.push(name);\n break;\n case \"stub\":\n manual.push({ name, docs: adapter.docs });\n break;\n case \"skipped\":\n failed.push({ name, reason: result.reason });\n break;\n }\n }\n\n const summary: string[] = [];\n if (wired.length > 0) {\n summary.push(`Wired: ${wired.join(\", \")}.`);\n }\n if (manual.length > 0 || failed.length > 0) {\n const parts: string[] = [];\n for (const m of manual) {\n parts.push(`${m.name} (manual install required${m.docs ? ` — see ${m.docs}` : \"\"})`);\n }\n for (const f of failed) {\n parts.push(`${f.name} (${f.reason})`);\n }\n summary.push(`Skipped/failed: ${parts.join(\", \")}.`);\n }\n if (summary.length === 0) {\n summary.push(\"No agents were wired.\");\n }\n p.note(summary.join(\"\\n\"), \"wire summary\");\n}\n","// Thin logging shim for agentmemory.\n//\n// iii-sdk v0.11 dropped `getContext()`, which had been the source of a\n// contextual logger in every function handler (`getContext().logger`).\n// Migrating directly to the v0.11 OTEL-based `getLogger()` would force\n// every call site to care about the OTEL Logger API shape (`emit(...)`\n// with severity numbers and attributes maps). Instead, this module\n// exposes a single `logger` singleton with the same `.info/.warn/.error`\n// signature the old code used, so the mechanical replacement across\n// 30+ function files is: drop the `getContext` import, drop the\n// `const ctx = getContext();` line, and rename `ctx.logger.*` to\n// `logger.*`. Nothing else changes.\n//\n// Output goes to stderr as `[agentmemory] <level> <msg> <json-fields>`.\n// The iii-engine's `iii-exec` worker runs the agentmemory binary as a\n// child process and forwards stderr into `docker logs\n// agentmemory-iii-engine-1`, so these lines end up next to the engine's\n// own output without needing any OTEL wiring. If we later want\n// structured OTEL logs, this file is the only thing that changes.\n//\n// See rohitg00/agentmemory#143 follow-up — the #116 migration updated\n// test mocks but left the real `getContext()` imports in place, which\n// passed `npm test` (tests mock iii-sdk) and `npm run build` (tsdown\n// doesn't type-check) but crashed `node dist/index.mjs` on first\n// import.\n\ntype Fields = Record<string, unknown> | undefined;\n\nfunction fmt(level: string, msg: string, fields: Fields): string {\n if (!fields || Object.keys(fields).length === 0) {\n return `[agentmemory] ${level} ${msg}`;\n }\n try {\n return `[agentmemory] ${level} ${msg} ${JSON.stringify(fields)}`;\n } catch {\n // Fields contained a circular reference or a BigInt — fall back\n // to the plain message so a log line never throws.\n return `[agentmemory] ${level} ${msg}`;\n }\n}\n\nfunction emit(level: string, msg: string, fields: Fields): void {\n try {\n process.stderr.write(fmt(level, msg, fields) + \"\\n\");\n } catch {\n // stderr is unavailable in some weird test/worker contexts — swallow\n // so no log line can ever crash a handler.\n }\n}\n\nexport const logger = {\n info(msg: string, fields?: Fields): void {\n emit(\"info\", msg, fields);\n },\n warn(msg: string, fields?: Fields): void {\n emit(\"warn\", msg, fields);\n },\n error(msg: string, fields?: Fields): void {\n emit(\"error\", msg, fields);\n },\n};\n\n// ---------- boot log ----------\n//\n// `bootLog` is for the one-shot status lines that every register-*\n// function used to dump via `console.log` during engine startup. On a\n// fresh install that's ~25 lines of `[agentmemory] X enabled` noise\n// before the user can see a prompt. In quiet mode (default), each\n// line is captured into a buffer and discarded; the CLI surfaces a\n// single compressed summary instead. In verbose mode (set by\n// `--verbose` or `AGENTMEMORY_VERBOSE=1`) the lines pass straight\n// through to stderr exactly like the old console.log calls.\n\nlet bootVerbose =\n process.env[\"AGENTMEMORY_VERBOSE\"] === \"1\" ||\n process.env[\"AGENTMEMORY_VERBOSE\"] === \"true\";\n\nconst bootBuffer: string[] = [];\n\nexport function setBootVerbose(enabled: boolean): void {\n bootVerbose = enabled;\n}\n\nexport function isBootVerbose(): boolean {\n return bootVerbose;\n}\n\nexport function bootLog(msg: string): void {\n if (bootVerbose) {\n try {\n process.stderr.write(`[agentmemory] ${msg}\\n`);\n } catch {\n // stderr unavailable — drop.\n }\n return;\n }\n if (bootBuffer.length < 500) bootBuffer.push(msg);\n}\n\nexport function bootWarn(msg: string): void {\n // Warnings always surface; they're rare and the user needs to see\n // them even when the rest of the boot log is suppressed.\n try {\n process.stderr.write(`[agentmemory] warn ${msg}\\n`);\n } catch {}\n}\n\nexport function getBootBuffer(): readonly string[] {\n return bootBuffer;\n}\n","export const VERSION = \"0.9.20\";\n","#!/usr/bin/env node\n\nimport {\n spawn,\n execFileSync,\n spawnSync,\n type ChildProcess,\n} from \"node:child_process\";\nimport {\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n readlinkSync,\n rmSync,\n statSync,\n unlinkSync,\n writeFileSync,\n} from \"node:fs\";\nimport { join, dirname, delimiter as PATH_DELIMITER } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { homedir, platform } from \"node:os\";\nimport * as p from \"@clack/prompts\";\nimport { generateId } from \"./state/schema.js\";\nimport {\n buildDiagnostics,\n dryRunPlan,\n parseEnvFile,\n type Diagnostic,\n type DiagnosticFixResult,\n type DoctorContext,\n type DoctorEffects,\n} from \"./cli/doctor-diagnostics.js\";\nimport {\n buildRemovePlan,\n formatPlan,\n localBinIii,\n type ConnectManifest,\n type RemoveOptions,\n} from \"./cli/remove-plan.js\";\nimport { renderSplash } from \"./cli/splash.js\";\nimport { isFirstRun, readPrefs, resetPrefs, writePrefs } from \"./cli/preferences.js\";\nimport { runOnboarding } from \"./cli/onboarding.js\";\nimport { setBootVerbose } from \"./logger.js\";\nimport { VERSION } from \"./version.js\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst args = process.argv.slice(2);\nconst IS_WINDOWS = platform() === \"win32\";\nconst IS_VERBOSE =\n args.includes(\"--verbose\") ||\n args.includes(\"-v\") ||\n process.env[\"AGENTMEMORY_VERBOSE\"] === \"1\" ||\n process.env[\"AGENTMEMORY_VERBOSE\"] === \"true\";\n\n// Propagate the resolved verbosity to the worker's boot logger so the\n// 25-line `[agentmemory] X registered` stream is either dropped or\n// printed verbatim. Without this the worker's default (env-only) would\n// disagree with the CLI flag.\nsetBootVerbose(IS_VERBOSE);\n\nconst IS_RESET = args.includes(\"--reset\");\n\n// Pinned iii-engine version. The unpinned `install.iii.dev/iii/main/install.sh`\n// script tracks `latest`, which made every fresh agentmemory install pull\n// engine 0.11.6 — and 0.11.6 introduces a new sandbox-everything-via-\n// `iii worker add` worker model that agentmemory hasn't been refactored\n// for yet (we still use the old `iii-exec watch` config-file model). The\n// architectural mismatch surfaces as EPIPE reconnect loops and empty\n// search results after save. Pin to v0.11.2 — the last engine that runs\n// agentmemory's current worker model cleanly — until the refactor lands.\n// Override env var AGENTMEMORY_III_VERSION lets users on the sandbox\n// model already point at a newer engine without us cutting a release.\nconst IIPINNED_VERSION =\n process.env[\"AGENTMEMORY_III_VERSION\"] || \"0.11.2\";\n\n// Map Node platform/arch → the asset name iii-hq/iii ships under\n// https://github.com/iii-hq/iii/releases/download/iii/v<version>/<asset>\nfunction iiiReleaseAsset(): string | null {\n const p = platform();\n const a = process.arch;\n if (p === \"darwin\" && a === \"arm64\")\n return \"iii-aarch64-apple-darwin.tar.gz\";\n if (p === \"darwin\" && a === \"x64\")\n return \"iii-x86_64-apple-darwin.tar.gz\";\n if (p === \"linux\" && a === \"x64\")\n return \"iii-x86_64-unknown-linux-gnu.tar.gz\";\n if (p === \"linux\" && a === \"arm64\")\n return \"iii-aarch64-unknown-linux-gnu.tar.gz\";\n if (p === \"linux\" && a === \"arm\")\n return \"iii-armv7-unknown-linux-gnueabihf.tar.gz\";\n if (p === \"win32\" && a === \"x64\")\n return \"iii-x86_64-pc-windows-msvc.zip\";\n if (p === \"win32\" && a === \"arm64\")\n return \"iii-aarch64-pc-windows-msvc.zip\";\n return null;\n}\n\nfunction iiiReleaseUrl(): string | null {\n const asset = iiiReleaseAsset();\n if (!asset) return null;\n // Tag name is monorepo-prefixed: `iii/v0.11.2`. Slash is URL-encoded\n // by GitHub when serving the download path, hence `iii/v...` not `iii%2Fv...`.\n return `https://github.com/iii-hq/iii/releases/download/iii/v${IIPINNED_VERSION}/${asset}`;\n}\n\nfunction vlog(msg: string): void {\n if (IS_VERBOSE) p.log.info(`[verbose] ${msg}`);\n}\n\nif (args.includes(\"--help\") || args.includes(\"-h\")) {\n console.log(`\nagentmemory — persistent memory for AI coding agents\n\nUsage: agentmemory [command] [options]\n\nCommands:\n (default) Start agentmemory worker\n init Copy bundled .env.example to ~/.agentmemory/.env if absent\n connect [agent] Wire agentmemory into an installed agent (claude-code, codex,\n cursor, gemini-cli, openclaw, hermes, pi, openhuman).\n No arg = interactive picker. --all wires every detected agent.\n --dry-run shows what would change. --force re-installs.\n status Show connection status, memory count, flags, and health\n doctor Interactive diagnostic + fixer. [F]ix · [S]kip · [?]more · [Q]uit\n --all: apply every fix without prompting (CI)\n --dry-run: show what each fix would do, don't execute\n remove Cleanly uninstall agentmemory (pidfile, state, .env, binaries).\n --force: skip confirmations · --keep-data: keep memory data\n demo Seed sample sessions and show recall in action\n upgrade Upgrade local deps + iii runtime (best effort)\n stop [--force] Stop the running iii-engine started by this CLI.\n --force bypasses the Docker-heuristic guard and signals\n whatever pidfile+lsof report on the REST port (use when\n the engine was started natively but state file is missing).\n mcp Start standalone MCP shim — opt-in surface for MCP-only clients\n (Cursor, Gemini CLI, etc). REST always available at :3111.\n import-jsonl [p] Import Claude Code JSONL transcripts (default: ~/.claude/projects)\n --max-files <N> | --max-files=<N>: override scan cap (default 200, max 1000;\n out-of-range is rejected; for trees >1000 files, batch by subdirectory)\n\nOptions:\n --help, -h Show this help\n --verbose, -v Show engine stderr, boot log, and diagnostic info\n --reset Wipe ~/.agentmemory/preferences.json and re-run onboarding\n --tools all|core Tool visibility (default: core = 7 tools)\n --no-engine Skip auto-starting iii-engine\n --port <N> Override REST port (default: 3111)\n\nEnvironment:\n AGENTMEMORY_URL Full REST base URL (e.g. http://localhost:3111).\n Honored by status, doctor, and MCP shim commands.\n AGENTMEMORY_USE_DOCKER=1 Prefer the bundled docker-compose path over the\n native iii-engine binary on first run.\n AGENTMEMORY_III_VERSION Override pinned iii-engine version (default ${IIPINNED_VERSION}).\n\nQuick start:\n npx @agentmemory/agentmemory # start with local iii-engine or Docker\n npx @agentmemory/agentmemory demo # see semantic recall in 30 seconds\n npx @agentmemory/agentmemory doctor # diagnose config + feature flags\n npx @agentmemory/agentmemory status # health + memory count + flags\n npx @agentmemory/agentmemory upgrade # upgrade agentmemory + iii runtime\n npx @agentmemory/agentmemory mcp # standalone MCP server (no engine)\n npx @agentmemory/mcp # same as above (shim package)\n`);\n process.exit(0);\n}\n\nconst toolsIdx = args.indexOf(\"--tools\");\nif (toolsIdx !== -1 && args[toolsIdx + 1]) {\n process.env[\"AGENTMEMORY_TOOLS\"] = args[toolsIdx + 1];\n}\n\nconst portIdx = args.indexOf(\"--port\");\nif (portIdx !== -1 && args[portIdx + 1]) {\n process.env[\"III_REST_PORT\"] = args[portIdx + 1];\n}\n\nconst skipEngine = args.includes(\"--no-engine\");\n\nfunction getRestPort(): number {\n const url = process.env[\"AGENTMEMORY_URL\"];\n if (url) {\n try {\n const parsed = new URL(url).port;\n if (parsed) return parseInt(parsed, 10);\n } catch {}\n }\n return parseInt(process.env[\"III_REST_PORT\"] || \"3111\", 10) || 3111;\n}\n\nfunction getBaseUrl(): string {\n const url = process.env[\"AGENTMEMORY_URL\"];\n if (url) return url.replace(/\\/+$/, \"\");\n return `http://localhost:${getRestPort()}`;\n}\n\nfunction getViewerUrl(): string {\n const envUrl = process.env[\"AGENTMEMORY_VIEWER_URL\"];\n if (envUrl) return envUrl.replace(/\\/+$/, \"\");\n try {\n const u = new URL(getBaseUrl());\n const vPort =\n parseInt(process.env[\"III_VIEWER_PORT\"] || \"\", 10) ||\n (parseInt(u.port || \"3111\", 10) || 3111) + 2;\n return `${u.protocol}//${u.hostname}:${vPort}`;\n } catch {\n const vPort =\n parseInt(process.env[\"III_VIEWER_PORT\"] || \"\", 10) ||\n getRestPort() + 2;\n return `http://localhost:${vPort}`;\n }\n}\n\n// WebSocket streams port. Engine writes here; the SDK and viewer\n// subscribe. Honors both `III_STREAM_PORT` (the singular name the\n// engine docs use post-0.11) and `III_STREAMS_PORT` (the name our\n// own config.ts has used since 0.7) so a single source of truth in\n// either form lights up the ready panel.\nfunction getStreamPort(): number {\n return (\n parseInt(process.env[\"III_STREAM_PORT\"] || \"\", 10) ||\n parseInt(process.env[\"III_STREAMS_PORT\"] || \"\", 10) ||\n 3112\n );\n}\n\n// Bridge WebSocket port — the iii engine's internal worker bus.\n// Defaults to 49134 (engine convention) and is overridable via\n// `III_ENGINE_PORT` or the legacy `III_ENGINE_URL=ws://host:port`.\nfunction getEnginePort(): number {\n const explicit = parseInt(process.env[\"III_ENGINE_PORT\"] || \"\", 10);\n if (explicit) return explicit;\n const url = process.env[\"III_ENGINE_URL\"];\n if (url) {\n try {\n const parsed = new URL(url).port;\n if (parsed) return parseInt(parsed, 10);\n } catch {}\n }\n return 49134;\n}\n\nasync function isEngineRunning(): Promise<boolean> {\n try {\n await fetch(`${getBaseUrl()}/`, {\n signal: AbortSignal.timeout(2000),\n });\n return true;\n } catch {\n return false;\n }\n}\n\nasync function isAgentmemoryReady(): Promise<boolean> {\n try {\n const res = await fetch(`${getBaseUrl()}/agentmemory/livez`, {\n signal: AbortSignal.timeout(2000),\n });\n return res.ok;\n } catch {\n return false;\n }\n}\n\nfunction findIiiConfig(): string {\n const candidates = [\n join(__dirname, \"iii-config.yaml\"),\n join(__dirname, \"..\", \"iii-config.yaml\"),\n join(process.cwd(), \"iii-config.yaml\"),\n ];\n for (const c of candidates) {\n if (existsSync(c)) return c;\n }\n return \"\";\n}\n\nfunction whichBinary(name: string): string | null {\n const cmd = IS_WINDOWS ? \"where\" : \"which\";\n try {\n const out = execFileSync(cmd, [name], {\n encoding: \"utf-8\",\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n const first = out\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .find((line) => line.length > 0);\n return first ?? null;\n } catch {\n return null;\n }\n}\n\nfunction fallbackIiiPaths(): string[] {\n if (IS_WINDOWS) {\n const userProfile = process.env[\"USERPROFILE\"];\n if (!userProfile) return [];\n return [\n join(userProfile, \".local\", \"bin\", \"iii.exe\"),\n join(userProfile, \"bin\", \"iii.exe\"),\n ];\n }\n const home = process.env[\"HOME\"];\n if (!home) return [\"/usr/local/bin/iii\"];\n return [join(home, \".local\", \"bin\", \"iii\"), \"/usr/local/bin/iii\"];\n}\n\nfunction iiiBinVersion(binPath: string): string | null {\n try {\n const out = execFileSync(binPath, [\"--version\"], {\n encoding: \"utf-8\",\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n timeout: 3000,\n });\n const match = out.match(/(\\d+\\.\\d+\\.\\d+(?:[-+][\\w.]+)?)/);\n return match ? match[1]! : null;\n } catch {\n return null;\n }\n}\n\nlet warnedVersionMismatch = false;\nfunction warnIfEngineVersionMismatch(iiiBinPath: string | null | undefined): void {\n if (!iiiBinPath || warnedVersionMismatch) return;\n const detected = iiiBinVersion(iiiBinPath);\n if (!detected || detected === IIPINNED_VERSION) return;\n warnedVersionMismatch = true;\n const asset = iiiReleaseAsset();\n const downloadHint = asset\n ? `curl -fsSL https://github.com/iii-hq/iii/releases/download/iii/v${IIPINNED_VERSION}/${asset} | tar -xz -C ~/.local/bin`\n : `download v${IIPINNED_VERSION} from https://github.com/iii-hq/iii/releases/tag/iii%2Fv${IIPINNED_VERSION}`;\n p.log.warn(\n `iii-engine on PATH is v${detected} but agentmemory v${VERSION} pins v${IIPINNED_VERSION}. Set AGENTMEMORY_III_VERSION=${detected} to silence, or downgrade with: \\`${downloadHint}\\``,\n );\n}\n\nfunction enginePidfilePath(): string {\n return join(homedir(), \".agentmemory\", \"iii.pid\");\n}\n\nfunction engineStatePath(): string {\n return join(homedir(), \".agentmemory\", \"engine-state.json\");\n}\n\ntype EngineState =\n | { kind: \"native\"; configPath: string; attached?: boolean }\n | { kind: \"docker\"; composeFile: string };\n\nfunction writeEnginePidfile(pid: number): void {\n try {\n const pidPath = enginePidfilePath();\n mkdirSync(dirname(pidPath), { recursive: true });\n writeFileSync(pidPath, `${pid}\\n`, { encoding: \"utf-8\" });\n } catch (err) {\n vlog(`writeEnginePidfile: ${err instanceof Error ? err.message : String(err)}`);\n }\n}\n\nfunction readEnginePidfile(): number | null {\n try {\n const pidStr = readFileSync(enginePidfilePath(), \"utf-8\").trim();\n const pid = parseInt(pidStr, 10);\n return Number.isFinite(pid) && pid > 0 ? pid : null;\n } catch {\n return null;\n }\n}\n\nfunction clearEnginePidfile(): void {\n try {\n unlinkSync(enginePidfilePath());\n } catch {}\n}\n\nfunction writeEngineState(state: EngineState): void {\n try {\n const statePath = engineStatePath();\n mkdirSync(dirname(statePath), { recursive: true });\n writeFileSync(statePath, `${JSON.stringify(state)}\\n`, { encoding: \"utf-8\" });\n } catch (err) {\n vlog(`writeEngineState: ${err instanceof Error ? err.message : String(err)}`);\n }\n}\n\nfunction readEngineState(): EngineState | null {\n try {\n const raw = readFileSync(engineStatePath(), \"utf-8\");\n const parsed = JSON.parse(raw) as Partial<EngineState>;\n if (parsed && (parsed.kind === \"native\" || parsed.kind === \"docker\")) {\n return parsed as EngineState;\n }\n return null;\n } catch {\n return null;\n }\n}\n\nfunction clearEngineState(): void {\n try {\n unlinkSync(engineStatePath());\n } catch {}\n}\n\nfunction discoverComposeFile(): string | null {\n const candidates = [\n join(__dirname, \"..\", \"docker-compose.yml\"),\n join(__dirname, \"docker-compose.yml\"),\n join(process.cwd(), \"docker-compose.yml\"),\n ];\n return candidates.find((c) => existsSync(c)) ?? null;\n}\n\nfunction isInvokedViaNpx(): boolean {\n if (process.env[\"npm_lifecycle_event\"] === \"npx\") return true;\n const argv1 = process.argv[1] ?? \"\";\n if (argv1.includes(\"_npx\")) return true;\n const ua = process.env[\"npm_config_user_agent\"] ?? \"\";\n if (ua.startsWith(\"npm/\") || ua.includes(\" npm/\")) return true;\n return false;\n}\n\n// First-run global-install prompt. Replaces the previous passive\n// `p.log.info` hint that users ignored — typing `agentmemory stop`\n// in a new shell would then 404 with `command not found`. We now\n// ask once, persist the answer in preferences, and never ask again.\nasync function maybeOfferGlobalInstall(): Promise<void> {\n if (!isInvokedViaNpx()) return;\n if (!process.stdin.isTTY) return;\n if (process.env[\"CI\"]) return;\n const prefs = readPrefs();\n if (prefs.skipGlobalInstall || prefs.skipNpxHint) return;\n\n const answer = await p.confirm({\n message:\n \"Install agentmemory globally so the bare `agentmemory` command works in any shell? [Y/n]\",\n initialValue: true,\n });\n if (p.isCancel(answer)) {\n // Treat Ctrl+C as \"not now\" rather than \"never\". Don't persist.\n return;\n }\n if (answer === false) {\n writePrefs({ skipGlobalInstall: true });\n p.log.info(\n \"Skipped. Re-run via `npx @agentmemory/agentmemory` or install later with: npm install -g @agentmemory/agentmemory\",\n );\n return;\n }\n\n const npmBin = whichBinary(\"npm\");\n if (!npmBin) {\n p.log.warn(\n \"npm not found on PATH. Install manually: npm install -g @agentmemory/agentmemory\",\n );\n return;\n }\n const ok = runCommand(\n npmBin,\n [\"install\", \"-g\", `@agentmemory/agentmemory@${VERSION}`],\n { label: `Installing @agentmemory/agentmemory@${VERSION} globally` },\n );\n if (ok) {\n p.log.success(\n \"Installed globally. `agentmemory stop` etc. will now work in new shells.\",\n );\n // Persist so we never re-prompt even if the user happens to npx\n // again from a CI-less TTY.\n writePrefs({ skipGlobalInstall: true });\n } else {\n p.log.warn(\n \"Global install failed. Try manually: npm install -g @agentmemory/agentmemory\",\n );\n }\n}\n\n// iii-console install state.\n// \"installed\" — `iii-console` is on PATH or at `~/.local/bin/iii-console`\n// \"missing\" — binary not found anywhere we look\n// We deliberately do NOT probe the console's HTTP port: the binary\n// being on disk is the signal we care about (it's not auto-started by\n// agentmemory and its default port 3113 collides with our viewer, so\n// \"is it listening?\" is the wrong question at boot time).\ntype IiiConsoleState =\n | { kind: \"installed\"; binPath: string }\n | { kind: \"missing\" };\n\nfunction detectIiiConsole(): IiiConsoleState {\n const onPath = whichBinary(\"iii-console\");\n if (onPath) return { kind: \"installed\", binPath: onPath };\n const fallback = IS_WINDOWS\n ? join(process.env[\"USERPROFILE\"] ?? \"\", \".local\", \"bin\", \"iii-console.exe\")\n : join(homedir(), \".local\", \"bin\", \"iii-console\");\n if (fallback && existsSync(fallback)) {\n return { kind: \"installed\", binPath: fallback };\n }\n return { kind: \"missing\" };\n}\n\n// install.iii.dev/console/main/install.sh has a bug in its release-tag\n// filter that rejects every stable release for iii-hq/iii: the jq\n// predicate uses `startswith(\"v\")` while the actual tags are\n// `iii/v0.12.0` (slash-prefixed). The `--next` path uses a regex\n// without the startswith constraint and therefore works today,\n// installing the most recent prerelease (e.g. iii/v0.14.0-next.1).\n//\n// Pass `--next` until the upstream fix lands (iii-hq/iii#1652).\n// Switch back to the bare invocation once the script is patched.\nconst III_CONSOLE_INSTALL_CMD =\n \"curl -fsSL https://install.iii.dev/console/main/install.sh | bash -s -- --next\";\n\nasync function ensureIiiConsole(): Promise<IiiConsoleState> {\n const state = detectIiiConsole();\n if (state.kind === \"installed\") return state;\n\n // Non-interactive contexts get the panel hint but no prompt.\n if (!process.stdin.isTTY || process.env[\"CI\"]) return state;\n const prefs = readPrefs();\n if (prefs.skipConsoleInstall) return state;\n\n const answer = await p.confirm({\n message:\n \"iii console gives engine-level visibility (workers, functions, queues, traces). Install now?\",\n initialValue: true,\n });\n if (p.isCancel(answer)) return state;\n if (answer === false) {\n writePrefs({ skipConsoleInstall: true });\n return state;\n }\n\n const shBin = whichBinary(\"sh\");\n const curlBin = whichBinary(\"curl\");\n if (!shBin || !curlBin) {\n p.log.warn(\n `curl or sh not found. Install manually:\\n ${III_CONSOLE_INSTALL_CMD}`,\n );\n return state;\n }\n const ok = runCommand(shBin, [\"-c\", III_CONSOLE_INSTALL_CMD], {\n label: \"Installing iii console\",\n });\n if (!ok) {\n p.log.warn(\n `iii console install failed. Re-run manually:\\n ${III_CONSOLE_INSTALL_CMD}`,\n );\n return state;\n }\n // Re-detect rather than trust install-script output paths.\n return detectIiiConsole();\n}\n\nfunction adoptRunningEngine(): void {\n try {\n const existingState = readEngineState();\n const existingPid = readEnginePidfile();\n if (existingState && existingPid) return;\n\n const pids = findEnginePidsByPort(getRestPort());\n const enginePid = pids[0];\n if (enginePid && !existingPid) {\n writeEnginePidfile(enginePid);\n }\n if (!existingState) {\n writeEngineState({\n kind: \"native\",\n configPath: findIiiConfig() || \"\",\n attached: true,\n });\n }\n if (enginePid && !existingPid) {\n p.log.info(`Attached to existing iii-engine (pid ${enginePid})`);\n }\n } catch (err) {\n vlog(`adoptRunningEngine: ${err instanceof Error ? err.message : String(err)}`);\n }\n}\n\nasync function runIiiInstaller(): Promise<{ ok: boolean; binPath: string | null }> {\n const releaseUrl = iiiReleaseUrl();\n const asset = iiiReleaseAsset();\n const isZipAsset = asset?.endsWith(\".zip\") === true;\n\n if (!releaseUrl) {\n p.log.warn(\n `iii-engine binary not available for ${platform()}/${process.arch}. Use Docker (\\`docker pull iiidev/iii:${IIPINNED_VERSION}\\`) or download manually from https://github.com/iii-hq/iii/releases/tag/iii%2Fv${IIPINNED_VERSION}.`,\n );\n return { ok: false, binPath: null };\n }\n\n if (IS_WINDOWS || isZipAsset) {\n p.log.info(\n `Auto-install unavailable on ${platform()} — ${asset} isn't tar-compatible. Install manually:\\n` +\n ` 1. Download ${releaseUrl}\\n` +\n ` 2. Extract iii.exe and place it on PATH (e.g. %USERPROFILE%\\\\.local\\\\bin)\\n` +\n `Or use Docker: docker pull iiidev/iii:${IIPINNED_VERSION}`,\n );\n return { ok: false, binPath: null };\n }\n\n const shBin = whichBinary(\"sh\");\n const curlBin = whichBinary(\"curl\");\n if (!shBin || !curlBin) {\n p.log.warn(\"curl or sh not found. Cannot auto-install iii-engine.\");\n return { ok: false, binPath: null };\n }\n\n const binDir = join(homedir(), \".local\", \"bin\");\n const binPath = join(binDir, \"iii\");\n const installCmd = [\n `mkdir -p \"${binDir}\"`,\n `curl -fsSL \"${releaseUrl}\" | tar -xz -C \"${binDir}\"`,\n `chmod +x \"${binPath}\"`,\n ].join(\" && \");\n const installerOk = runCommand(shBin, [\"-c\", installCmd], {\n label: `Installing iii-engine v${IIPINNED_VERSION} (pinned)`,\n optional: true,\n });\n if (!installerOk) {\n p.log.warn(\n `iii-engine installer failed. Fallbacks: Docker (\\`docker pull iiidev/iii:${IIPINNED_VERSION}\\`) or download manually from https://github.com/iii-hq/iii/releases/tag/iii%2Fv${IIPINNED_VERSION}.`,\n );\n return { ok: false, binPath: null };\n }\n return { ok: true, binPath };\n}\n\ntype StartupFailure = {\n kind: \"no-engine\" | \"no-docker-compose\" | \"engine-crashed\" | \"docker-crashed\";\n stderr?: string;\n binary?: string;\n};\n\nlet startupFailure: StartupFailure | null = null;\n\n// Spawn a background engine and collect any startup stderr for a short\n// window. The process is unref'd so the CLI parent can exit cleanly; we\n// only care about stderr that shows up BEFORE the health check succeeds,\n// which is what surfaces early crash/config-parse errors on all platforms.\nfunction spawnEngineBackground(\n bin: string,\n spawnArgs: string[],\n label: string,\n): ChildProcess {\n vlog(`spawn: ${bin} ${spawnArgs.join(\" \")}`);\n const child = spawn(bin, spawnArgs, {\n detached: true,\n stdio: [\"ignore\", \"ignore\", \"pipe\"],\n windowsHide: true,\n });\n const isDocker = label.includes(\"Docker\");\n if (!isDocker && typeof child.pid === \"number\") {\n writeEnginePidfile(child.pid);\n }\n const stderrChunks: Buffer[] = [];\n let stderrBytes = 0;\n const MAX_STDERR_CAPTURE = 16 * 1024;\n child.stderr?.on(\"data\", (chunk: Buffer) => {\n if (stderrBytes >= MAX_STDERR_CAPTURE) return;\n const slice = chunk.subarray(0, MAX_STDERR_CAPTURE - stderrBytes);\n stderrChunks.push(slice);\n stderrBytes += slice.length;\n });\n child.on(\"exit\", (code, signal) => {\n const abnormal =\n (code !== null && code !== 0) || (code === null && signal !== null);\n if (abnormal) {\n const stderr = Buffer.concat(stderrChunks).toString(\"utf-8\");\n startupFailure = {\n kind: isDocker ? \"docker-crashed\" : \"engine-crashed\",\n stderr:\n stderr.trim() ||\n (signal\n ? `process killed by signal ${signal}`\n : `process exited with code ${code}`),\n binary: bin,\n };\n vlog(`engine exited early: code=${code} signal=${signal}`);\n if (IS_VERBOSE && stderr.trim()) {\n p.log.error(`engine stderr:\\n${stderr}`);\n }\n if (!isDocker) clearEnginePidfile();\n clearEngineState();\n }\n });\n child.unref();\n return child;\n}\n\nfunction startIiiBin(iiiBin: string, configPath: string): boolean {\n warnIfEngineVersionMismatch(iiiBin);\n const s = p.spinner();\n s.start(`Starting iii-engine: ${iiiBin}`);\n writeEngineState({ kind: \"native\", configPath });\n spawnEngineBackground(iiiBin, [\"--config\", configPath], \"iii-engine\");\n s.stop(\"iii-engine process started\");\n return true;\n}\n\nasync function startEngine(): Promise<boolean> {\n const configPath = findIiiConfig();\n let iiiBin = whichBinary(\"iii\");\n vlog(`iii binary: ${iiiBin ?? \"(not on PATH)\"}, config: ${configPath || \"(not found)\"}`);\n\n if (iiiBin && configPath) return startIiiBin(iiiBin, configPath);\n\n for (const iiiPath of fallbackIiiPaths()) {\n if (existsSync(iiiPath)) {\n const v = iiiBinVersion(iiiPath);\n vlog(`fallback iii at ${iiiPath} reports version: ${v ?? \"unknown\"}`);\n p.log.info(`Found iii at: ${iiiPath}${v ? ` (v${v})` : \"\"}`);\n process.env[\"PATH\"] = `${dirname(iiiPath)}${PATH_DELIMITER}${process.env[\"PATH\"] ?? \"\"}`;\n iiiBin = iiiPath;\n break;\n }\n }\n\n if (iiiBin && configPath) return startIiiBin(iiiBin, configPath);\n\n if (!configPath) {\n startupFailure = { kind: \"no-engine\" };\n return false;\n }\n\n const dockerBin = whichBinary(\"docker\");\n vlog(`docker binary: ${dockerBin ?? \"(not on PATH)\"}`);\n const dockerComposeCandidates = [\n join(__dirname, \"..\", \"docker-compose.yml\"),\n join(__dirname, \"docker-compose.yml\"),\n join(process.cwd(), \"docker-compose.yml\"),\n ];\n const composeFile = dockerComposeCandidates.find((c) => existsSync(c));\n vlog(`docker-compose.yml: ${composeFile ?? \"(not found)\"}`);\n\n const dockerOptIn =\n process.env[\"AGENTMEMORY_USE_DOCKER\"] === \"1\" ||\n process.env[\"AGENTMEMORY_USE_DOCKER\"] === \"true\";\n const interactive = !!process.stdin.isTTY && !process.env[\"CI\"];\n\n type Choice = \"install\" | \"docker\" | \"manual\";\n let choice: Choice;\n\n if (dockerOptIn && dockerBin && composeFile) {\n choice = \"docker\";\n } else if (!interactive) {\n choice = \"install\";\n p.log.info(\"Non-interactive environment detected — auto-installing iii-engine.\");\n } else {\n p.log.warn(`iii-engine binary not found locally.`);\n const options: { value: Choice; label: string; hint?: string }[] = [\n {\n value: \"install\",\n label: `Install iii v${IIPINNED_VERSION} to ~/.local/bin (~6MB, ~5s)`,\n hint: \"recommended\",\n },\n ];\n if (dockerBin && composeFile) {\n options.push({ value: \"docker\", label: \"Use Docker compose\", hint: \"advanced\" });\n }\n options.push({ value: \"manual\", label: \"Show manual install steps and exit\" });\n\n const picked = await p.select<Choice>({\n message: \"How would you like to start iii-engine?\",\n options,\n initialValue: \"install\",\n });\n if (p.isCancel(picked)) {\n startupFailure = { kind: \"no-engine\" };\n return false;\n }\n choice = picked;\n }\n\n if (choice === \"manual\") {\n startupFailure = { kind: \"no-engine\" };\n return false;\n }\n\n if (choice === \"install\") {\n const result = await runIiiInstaller();\n if (result.ok && result.binPath) {\n process.env[\"PATH\"] = `${dirname(result.binPath)}${PATH_DELIMITER}${process.env[\"PATH\"] ?? \"\"}`;\n iiiBin = result.binPath;\n return startIiiBin(iiiBin, configPath);\n }\n if (dockerBin && composeFile && interactive) {\n const fallback = await p.confirm({\n message: \"Auto-install failed. Try Docker compose instead?\",\n initialValue: true,\n });\n if (p.isCancel(fallback) || fallback !== true) {\n startupFailure = { kind: \"no-engine\" };\n return false;\n }\n choice = \"docker\";\n } else {\n startupFailure = { kind: \"no-engine\" };\n return false;\n }\n }\n\n if (choice === \"docker\" && dockerBin && composeFile) {\n const s = p.spinner();\n s.start(\"Starting iii-engine via Docker...\");\n writeEngineState({ kind: \"docker\", composeFile });\n spawnEngineBackground(\n dockerBin,\n [\"compose\", \"-f\", composeFile, \"up\", \"-d\"],\n \"iii-engine via Docker\",\n );\n s.stop(\"Docker compose started\");\n return true;\n }\n\n if (!composeFile && dockerBin) {\n startupFailure = { kind: \"no-docker-compose\" };\n } else {\n startupFailure = { kind: \"no-engine\" };\n }\n return false;\n}\n\nasync function waitForEngine(timeoutMs: number): Promise<boolean> {\n const start = Date.now();\n while (Date.now() - start < timeoutMs) {\n if (await isEngineRunning()) return true;\n await new Promise((r) => setTimeout(r, 500));\n }\n return false;\n}\n\nfunction installInstructions(): string[] {\n const releaseUrl = iiiReleaseUrl();\n if (IS_WINDOWS) {\n return [\n `agentmemory needs iii-engine v${IIPINNED_VERSION}. Pick one:`,\n \"\",\n \" A) Download the prebuilt Windows binary:\",\n ` 1. Open https://github.com/iii-hq/iii/releases/tag/iii%2Fv${IIPINNED_VERSION}`,\n ` 2. Download iii-x86_64-pc-windows-msvc.zip (or iii-aarch64-pc-windows-msvc.zip on ARM)`,\n \" 3. Extract iii.exe to %USERPROFILE%\\\\.local\\\\bin\\\\iii.exe (or add to PATH)\",\n \" 4. Re-run: npx @agentmemory/agentmemory\",\n \"\",\n ` B) Docker: docker pull iiidev/iii:${IIPINNED_VERSION}`,\n \" Re-run with AGENTMEMORY_USE_DOCKER=1 npx @agentmemory/agentmemory\",\n \"\",\n \"Or skip the engine entirely (standalone MCP): npx @agentmemory/agentmemory mcp\",\n \"\",\n \"Docs: https://iii.dev/docs\",\n ];\n }\n const linuxInstall = releaseUrl\n ? ` A) curl -fsSL \"${releaseUrl}\" | tar -xz -C ~/.local/bin && chmod +x ~/.local/bin/iii`\n : ` A) Manual download: https://github.com/iii-hq/iii/releases/tag/iii%2Fv${IIPINNED_VERSION}`;\n return [\n `agentmemory needs iii-engine v${IIPINNED_VERSION}. Pick one:`,\n \"\",\n linuxInstall,\n \" Then re-run: npx @agentmemory/agentmemory\",\n \"\",\n ` B) Docker: docker pull iiidev/iii:${IIPINNED_VERSION}`,\n \" Re-run with AGENTMEMORY_USE_DOCKER=1 npx @agentmemory/agentmemory\",\n \"\",\n \"Or skip the engine entirely (standalone MCP): npx @agentmemory/agentmemory mcp\",\n \"\",\n \"Docs: https://iii.dev/docs\",\n ];\n}\n\nfunction portInUseDiagnostic(port: number): string {\n return IS_WINDOWS\n ? ` netstat -ano | findstr :${port}`\n : ` lsof -i :${port} # or: ss -tlnp | grep :${port}`;\n}\n\nasync function waitForAgentmemoryReady(timeoutMs: number): Promise<boolean> {\n const start = Date.now();\n while (Date.now() - start < timeoutMs) {\n if (await isAgentmemoryReady()) return true;\n await new Promise((r) => setTimeout(r, 250));\n }\n return false;\n}\n\n// Derive a host string for the streams/engine WebSocket lines from\n// the configured engine URL (`III_ENGINE_URL`) or REST base\n// (`AGENTMEMORY_URL`) so a remote-bind setup like\n// `III_ENGINE_URL=ws://my-host:49134` doesn't print misleading\n// localhost addresses. Falls back to localhost.\nfunction getEngineHost(): string {\n for (const envKey of [\"III_ENGINE_URL\", \"AGENTMEMORY_URL\"]) {\n const raw = process.env[envKey];\n if (!raw) continue;\n try {\n const parsed = new URL(raw);\n if (parsed.hostname) return parsed.hostname;\n } catch {}\n }\n return \"localhost\";\n}\n\nfunction printReadyHint(consoleState: IiiConsoleState): void {\n // REST goes through getBaseUrl which already honors AGENTMEMORY_URL\n // for full host+protocol overrides. Streams/Engine are derived from\n // III_ENGINE_URL so a remote bind reads correctly in the panel.\n const restUrl = getBaseUrl();\n const viewerUrl = getViewerUrl();\n const engineHost = getEngineHost();\n const streamUrl = `ws://${engineHost}:${getStreamPort()}`;\n const engineUrl = `ws://${engineHost}:${getEnginePort()}`;\n\n const consoleLine =\n consoleState.kind === \"installed\"\n ? // We can't safely probe iii-console's port (default 3113\n // collides with our viewer) so we surface the binary location\n // and let the user start it on a port of their choice. Use\n // the detected binary path so `(run: ...)` is executable as-\n // is, even when the binary isn't on PATH under the bare\n // name `iii-console`.\n `iii console ${consoleState.binPath} (run: ${consoleState.binPath} -p <port>)`\n : `iii console (install: ${III_CONSOLE_INSTALL_CMD})`;\n\n const lines = [\n `REST API ${restUrl}`,\n `Viewer ${viewerUrl}`,\n `Streams ${streamUrl}`,\n `Engine ${engineUrl}`,\n consoleLine,\n ];\n // p.note renders a bordered panel with a title — same affordance\n // used elsewhere in this CLI for \"Troubleshooting\" / \"Setup\n // required\" blocks, so the visual language stays consistent.\n p.note(lines.join(\"\\n\"), `agentmemory v${VERSION}`);\n\n // Pick a runnable form for the suggested next-step. Users invoked\n // via `npx` don't have the bare `agentmemory` command on PATH yet\n // (unless they accepted the global-install prompt and the npm bin\n // dir was already on PATH in this shell), so we suggest the npx\n // form for them; everyone else gets the global form.\n const demoCommand = isInvokedViaNpx()\n ? \"npx @agentmemory/agentmemory demo\"\n : \"agentmemory demo\";\n process.stdout.write(`\\nTry: ${demoCommand}\\n`);\n}\n\nasync function main() {\n // `--reset` wipes preferences before anything else so the onboarding\n // flow below always runs fresh.\n if (IS_RESET) {\n resetPrefs();\n }\n\n const firstRun = isFirstRun();\n const prefs = readPrefs();\n // Show the splash on the first run, on --reset, or whenever the user\n // hasn't yet opted out via the schema (we set `skipSplash: true`\n // after onboarding completes). Verbose runs always splash since the\n // user explicitly asked for the chatty experience.\n if (firstRun || IS_RESET || IS_VERBOSE || !prefs.skipSplash) {\n renderSplash(VERSION);\n }\n\n if (firstRun || IS_RESET) {\n await runOnboarding();\n }\n\n if (skipEngine) {\n if (IS_VERBOSE) p.log.info(\"Skipping engine check (--no-engine)\");\n await import(\"./index.js\");\n if (await waitForAgentmemoryReady(15000)) {\n const consoleState = await ensureIiiConsole();\n await maybeOfferGlobalInstall();\n printReadyHint(consoleState);\n }\n return;\n }\n\n if (await isEngineRunning()) {\n if (IS_VERBOSE) p.log.success(\"iii-engine is running\");\n const attachedBin =\n whichBinary(\"iii\") ?? fallbackIiiPaths().find((p) => existsSync(p)) ?? null;\n warnIfEngineVersionMismatch(attachedBin);\n adoptRunningEngine();\n await import(\"./index.js\");\n if (await waitForAgentmemoryReady(15000)) {\n const consoleState = await ensureIiiConsole();\n await maybeOfferGlobalInstall();\n printReadyHint(consoleState);\n }\n return;\n }\n\n const started = await startEngine();\n if (!started) {\n p.log.error(\"Could not start iii-engine.\");\n const lines = installInstructions();\n if (startupFailure?.kind === \"no-docker-compose\") {\n lines.unshift(\n \"Docker is installed but docker-compose.yml is missing from this\",\n \"install. Re-install with: npm install -g @agentmemory/agentmemory\",\n \"\",\n );\n }\n p.note(lines.join(\"\\n\"), \"Setup required\");\n process.exit(1);\n }\n\n const s = p.spinner();\n s.start(\"Waiting for iii-engine to be ready...\");\n\n const ready = await waitForEngine(15000);\n if (!ready) {\n const port = getRestPort();\n s.stop(\"iii-engine did not become ready within 15s\");\n\n if (startupFailure?.kind === \"engine-crashed\" || startupFailure?.kind === \"docker-crashed\") {\n p.log.error(\"The iii-engine process crashed on startup.\");\n if (startupFailure.binary) {\n p.log.info(`Binary: ${startupFailure.binary}`);\n }\n if (startupFailure.stderr) {\n p.note(startupFailure.stderr, \"engine stderr\");\n } else {\n p.log.info(\"No stderr was captured. Re-run with --verbose for more detail.\");\n }\n p.note(\n [\n \"Common causes:\",\n \" - iii-engine version mismatch — reinstall the latest binary\",\n \" (sh script on macOS/Linux, GitHub release zip on Windows)\",\n \" - Docker Desktop not running (if you're using the Docker path)\",\n \" - Port already in use (see below)\",\n \"\",\n \"See https://iii.dev/docs for current install instructions.\",\n ].join(\"\\n\"),\n \"Troubleshooting\",\n );\n } else {\n p.log.error(\"The engine process started but the REST API never responded.\");\n p.note(\n [\n `Check whether port ${port} is already bound by another process:`,\n portInUseDiagnostic(port),\n \"\",\n \"If it is, free the port or override: agentmemory --port <N>\",\n \"\",\n \"If it isn't, a firewall may be blocking 127.0.0.1:\" + port + \".\",\n \"Re-run with --verbose to see engine stderr.\",\n ].join(\"\\n\"),\n \"Troubleshooting\",\n );\n }\n process.exit(1);\n }\n\n s.stop(\"iii-engine is ready\");\n await import(\"./index.js\");\n if (await waitForAgentmemoryReady(15000)) {\n const consoleState = await ensureIiiConsole();\n await maybeOfferGlobalInstall();\n printReadyHint(consoleState);\n }\n // Mark splash as something to skip on subsequent runs. This is a\n // no-op if onboarding already flipped the flag (idempotent merge).\n writePrefs({ skipSplash: true });\n}\n\nasync function apiFetch<T = unknown>(base: string, path: string, timeoutMs = 5000): Promise<T | null> {\n try {\n const headers: Record<string, string> = {};\n const secret = process.env[\"AGENTMEMORY_SECRET\"];\n if (secret) headers[\"Authorization\"] = `Bearer ${secret}`;\n const res = await fetch(`${base}/agentmemory/${path}`, {\n signal: AbortSignal.timeout(timeoutMs),\n headers,\n });\n return (await res.json()) as T;\n } catch {\n return null;\n }\n}\n\nasync function runStatus() {\n const port = getRestPort();\n const base = getBaseUrl();\n p.intro(\"agentmemory status\");\n\n const up = await isEngineRunning();\n if (!up) {\n p.log.error(`Not running — no response at ${base}`);\n p.log.info(\"Start with: npx @agentmemory/agentmemory\");\n process.exit(1);\n }\n\n try {\n const [healthRes, sessionsRes, graphRes, memoriesRes, flagsRes] = await Promise.all([\n apiFetch<any>(base, \"health\"),\n apiFetch<any>(base, \"sessions\"),\n apiFetch<any>(base, \"graph/stats\"),\n apiFetch<any>(base, \"export\"),\n apiFetch<any>(base, \"config/flags\"),\n ]);\n\n const h = healthRes?.health;\n const status = healthRes?.status || \"unknown\";\n const version = healthRes?.version || \"?\";\n const sessions = Array.isArray(sessionsRes?.sessions) ? sessionsRes.sessions.length : 0;\n const nodes = Number(graphRes?.totalNodes ?? graphRes?.nodes ?? graphRes?.nodeCount ?? 0);\n const edges = Number(graphRes?.totalEdges ?? graphRes?.edges ?? graphRes?.edgeCount ?? 0);\n const cb = healthRes?.circuitBreaker?.state || \"closed\";\n const heapMB = h?.memory ? Math.round(h.memory.heapUsed / 1048576) : 0;\n const uptime = h?.uptimeSeconds ? Math.round(h.uptimeSeconds) : 0;\n\n const obsCount = memoriesRes?.observations?.length || 0;\n const memCount = memoriesRes?.memories?.length || 0;\n const estFullTokens = obsCount * 80;\n const estInjectedTokens = Math.min(obsCount, 50) * 38;\n const tokensSaved = estFullTokens - estInjectedTokens;\n const pctSaved = estFullTokens > 0 ? Math.round((tokensSaved / estFullTokens) * 100) : 0;\n\n p.log.success(`Connected — v${version} at ${base}`);\n\n const lines = [\n `Health: ${status === \"healthy\" ? \"✓ healthy\" : status}`,\n `Sessions: ${sessions}`,\n `Observations: ${obsCount}`,\n `Memories: ${memCount}`,\n `Graph: ${nodes} nodes, ${edges} edges`,\n `Circuit: ${cb}`,\n `Heap: ${heapMB} MB`,\n `Uptime: ${uptime}s`,\n `Viewer: ${getViewerUrl()}`,\n ];\n\n if (obsCount > 0) {\n lines.push(\"\");\n lines.push(`Token savings: ~${tokensSaved.toLocaleString()} tokens saved (${pctSaved}% reduction)`);\n lines.push(` Full context: ~${estFullTokens.toLocaleString()} tokens`);\n lines.push(` Injected: ~${estInjectedTokens.toLocaleString()} tokens`);\n }\n\n if (flagsRes) {\n const provider = flagsRes.provider === \"llm\" ? \"✓ llm\" : \"✗ noop (no key)\";\n const embed = flagsRes.embeddingProvider === \"embeddings\" ? \"✓ embeddings\" : \"bm25-only\";\n const flagRows = (flagsRes.flags || []).map((f: { key: string; enabled: boolean; label: string }) =>\n ` ${f.enabled ? \"✓\" : \"✗\"} ${f.key.padEnd(32)} ${f.label}`\n );\n lines.push(\"\");\n lines.push(`Provider: ${provider}`);\n lines.push(`Embeddings: ${embed}`);\n lines.push(`Flags:`);\n flagRows.forEach((r: string) => lines.push(r));\n }\n\n p.note(lines.join(\"\\n\"), \"agentmemory\");\n } catch (err) {\n p.log.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n}\n\ntype DoctorCheck = { name: string; ok: boolean; hint?: string };\n\nfunction formatChecks(checks: DoctorCheck[]): string {\n return checks\n .map((c) => `${c.ok ? \"✓\" : \"✗\"} ${c.name}${c.hint ? `\\n ${c.hint}` : \"\"}`)\n .join(\"\\n\");\n}\n\ntype CCHooksCheck =\n | { state: \"loaded\"; manifestPath?: string }\n | { state: \"not-loaded\" }\n | { state: \"no-debug-log\" }\n | { state: \"no-cc-dir\" };\n\nfunction findLatestDebugLog(debugDir: string): string | undefined {\n const latestLink = join(debugDir, \"latest\");\n try {\n if (existsSync(latestLink)) {\n const target = readlinkSync(latestLink);\n const resolved = target.startsWith(\"/\") ? target : join(debugDir, target);\n if (existsSync(resolved)) return resolved;\n }\n } catch {}\n\n try {\n const newest = readdirSync(debugDir)\n .filter((f) => f.endsWith(\".txt\"))\n .map((f) => ({ f, m: statSync(join(debugDir, f)).mtimeMs }))\n .sort((a, b) => b.m - a.m)[0];\n if (newest) return join(debugDir, newest.f);\n } catch {}\n\n return undefined;\n}\n\nfunction checkClaudeCodeHooks(): CCHooksCheck {\n const debugDir = join(homedir(), \".claude\", \"debug\");\n if (!existsSync(debugDir)) return { state: \"no-cc-dir\" };\n\n const logPath = findLatestDebugLog(debugDir);\n if (!logPath) return { state: \"no-debug-log\" };\n\n let content: string;\n try {\n content = readFileSync(logPath, \"utf8\");\n } catch {\n return { state: \"no-debug-log\" };\n }\n\n const match = content.match(\n /Loaded hooks from standard location for plugin agentmemory:\\s*(\\S+)/\n );\n if (match) return { state: \"loaded\", manifestPath: match[1] };\n if (content.includes(\"Loading hooks from plugin: agentmemory\")) return { state: \"loaded\" };\n return { state: \"not-loaded\" };\n}\n\n// ---------------------------------------------------------------------------\n// Doctor v2 — interactive fixer.\n//\n// The legacy passive check-list (server reachable, flags, knowledge-graph,\n// Claude Code hooks) still runs first as an informational summary because\n// those checks need a live engine and don't have a one-shot inline fix.\n// Then we drive the new diagnostic catalog (see src/cli/doctor-diagnostics.ts)\n// which prompts Fix/Skip/More/Quit per failing check, applies the fix\n// inline, and re-checks only the affected diagnostic.\n\nfunction buildDoctorContext(): DoctorContext {\n return {\n baseUrl: getBaseUrl(),\n viewerUrl: getViewerUrl(),\n envPath: join(homedir(), \".agentmemory\", \".env\"),\n pidfilePath: enginePidfilePath(),\n enginePath: engineStatePath(),\n pinnedVersion: IIPINNED_VERSION,\n };\n}\n\nfunction buildDoctorEffects(): DoctorEffects {\n return {\n envFileExists: () => existsSync(join(homedir(), \".agentmemory\", \".env\")),\n readEnvFile: () => {\n try {\n return parseEnvFile(\n readFileSync(join(homedir(), \".agentmemory\", \".env\"), \"utf-8\"),\n );\n } catch {\n return {};\n }\n },\n pidfileExists: () => existsSync(enginePidfilePath()),\n pidfilePidIsAlive: () => {\n const pid = readEnginePidfile();\n if (pid === null) return null;\n return pidAlive(pid);\n },\n findIiiBinary: () => whichBinary(\"iii\"),\n localBinIiiPath: () => join(homedir(), \".local\", \"bin\", IS_WINDOWS ? \"iii.exe\" : \"iii\"),\n iiiBinaryVersion: (binPath: string) => iiiBinVersion(binPath),\n viewerReachable: async (timeoutMs = 2000) => {\n try {\n const res = await fetch(getViewerUrl(), {\n signal: AbortSignal.timeout(timeoutMs),\n });\n return res.ok;\n } catch {\n return false;\n }\n },\n runInit: async () => {\n try {\n await runInit();\n return { ok: true, message: \"Wrote ~/.agentmemory/.env\" };\n } catch (err) {\n return {\n ok: false,\n message: err instanceof Error ? err.message : String(err),\n };\n }\n },\n openEditor: async (path: string) => {\n const editor = process.env[\"EDITOR\"] || process.env[\"VISUAL\"] || \"nano\";\n p.log.info(`Opening ${path} in ${editor}…`);\n try {\n // Inherit stdio so the user actually sees the editor.\n const result = spawnSync(editor, [path], { stdio: \"inherit\" });\n if (result.error) {\n return {\n ok: false,\n message: `Failed to launch ${editor}: ${result.error.message}`,\n };\n }\n if ((result.status ?? 0) !== 0) {\n return {\n ok: false,\n message: `${editor} exited with code ${result.status}`,\n };\n }\n return { ok: true, message: `Saved ${path}` };\n } catch (err) {\n return {\n ok: false,\n message: err instanceof Error ? err.message : String(err),\n };\n }\n },\n runIiiInstaller: async () => {\n const r = await runIiiInstaller();\n return {\n ok: r.ok,\n message: r.ok\n ? `Installed iii v${IIPINNED_VERSION} to ${r.binPath}`\n : \"iii installer failed (see warnings above)\",\n };\n },\n runStop: async () => {\n try {\n // runStop calls process.exit on its own — guard against that here\n // by short-circuiting when there's nothing to stop.\n const port = getRestPort();\n const portPids = findEnginePidsByPort(port);\n const pidfilePid = readEnginePidfile();\n if (portPids.length === 0 && pidfilePid === null) {\n clearEnginePidfile();\n clearEngineState();\n return { ok: true, message: \"Nothing to stop.\" };\n }\n const candidates = new Set<number>();\n if (pidfilePid) candidates.add(pidfilePid);\n for (const pid of portPids) candidates.add(pid);\n let allStopped = true;\n for (const pid of candidates) {\n const ok = await signalAndWait(pid, \"SIGTERM\", 3000);\n if (!ok) allStopped = false;\n }\n clearEnginePidfile();\n clearEngineState();\n return {\n ok: allStopped,\n message: allStopped ? \"Engine stopped.\" : \"Some engine pids survived.\",\n };\n } catch (err) {\n return {\n ok: false,\n message: err instanceof Error ? err.message : String(err),\n };\n }\n },\n runStart: async () => {\n try {\n const started = await startEngine();\n if (!started) return { ok: false, message: \"startEngine() returned false\" };\n const ready = await waitForEngine(15000);\n return {\n ok: ready,\n message: ready ? \"Engine ready\" : \"Engine did not become ready within 15s\",\n };\n } catch (err) {\n return {\n ok: false,\n message: err instanceof Error ? err.message : String(err),\n };\n }\n },\n clearEnginePidAndState: () => {\n clearEnginePidfile();\n clearEngineState();\n },\n };\n}\n\nasync function passiveServerChecks(): Promise<DoctorCheck[]> {\n const base = getBaseUrl();\n const checks: DoctorCheck[] = [];\n\n const serverUp = await isEngineRunning();\n checks.push({\n name: \"Server reachable\",\n ok: serverUp,\n hint: serverUp\n ? undefined\n : `Start with: npx @agentmemory/agentmemory (tried ${base})`,\n });\n if (!serverUp) return checks;\n\n const [health, flags, graph] = await Promise.all([\n apiFetch<any>(base, \"health\", 3000),\n apiFetch<any>(base, \"config/flags\", 3000),\n apiFetch<any>(base, \"graph/stats\", 3000),\n ]);\n\n const hasLlm = flags?.provider === \"llm\";\n const hasEmbed = flags?.embeddingProvider === \"embeddings\";\n const graphNodeCount = Number(\n graph?.totalNodes ?? graph?.nodes ?? graph?.nodeCount ?? 0,\n );\n const graphHas = graphNodeCount > 0;\n\n checks.push(\n {\n name: \"Health status\",\n ok: health?.status === \"healthy\",\n hint:\n health?.status === \"healthy\"\n ? undefined\n : `Status: ${health?.status || \"unknown\"}`,\n },\n {\n name: \"LLM provider\",\n ok: hasLlm,\n hint: hasLlm ? undefined : \"set ANTHROPIC_API_KEY (or GEMINI/OPENROUTER/MINIMAX) in ~/.agentmemory/.env\",\n },\n {\n name: \"Embedding provider\",\n ok: hasEmbed,\n hint: hasEmbed\n ? undefined\n : \"Running BM25-only. Add OPENAI_API_KEY / VOYAGE_API_KEY / COHERE_API_KEY / OLLAMA_HOST\",\n },\n );\n\n for (const f of (flags?.flags || []) as {\n label: string;\n enabled: boolean;\n enableHow: string;\n }[]) {\n checks.push({\n name: f.label,\n ok: f.enabled,\n hint: f.enabled ? undefined : f.enableHow,\n });\n }\n\n const cc = checkClaudeCodeHooks();\n const ccCheck = (() => {\n switch (cc.state) {\n case \"loaded\":\n return {\n ok: true,\n hint: cc.manifestPath ? `manifest: ${cc.manifestPath}` : undefined,\n };\n case \"not-loaded\":\n return {\n ok: false,\n hint:\n \"Plugin enabled but hooks not loaded by Claude Code. Try: /plugin uninstall agentmemory@agentmemory && /plugin install agentmemory@agentmemory, then restart the session.\",\n };\n case \"no-debug-log\":\n return {\n ok: false,\n hint:\n 'Cannot verify — no Claude Code debug log found. Run once with `claude --debug -p \"x\"`, then re-run doctor.',\n };\n case \"no-cc-dir\":\n return undefined;\n }\n })();\n if (ccCheck) checks.push({ name: \"Claude Code plugin hooks registered\", ...ccCheck });\n\n checks.push({\n name: \"Knowledge graph populated\",\n ok: graphHas,\n hint: graphHas\n ? undefined\n : \"Graph is empty. Run a session with GRAPH_EXTRACTION_ENABLED=true.\",\n });\n\n return checks;\n}\n\ntype DoctorAction = \"fix\" | \"skip\" | \"more\" | \"quit\";\n\nasync function askFixAction(d: Diagnostic): Promise<DoctorAction> {\n const choice = await p.select<DoctorAction>({\n message: `[${d.id}] ${d.message}`,\n options: [\n { value: \"fix\", label: \"F Fix\", hint: d.fixPreview },\n { value: \"skip\", label: \"S Skip\" },\n { value: \"more\", label: \"? More info\" },\n { value: \"quit\", label: \"Q Quit doctor\" },\n ],\n initialValue: \"fix\",\n });\n if (p.isCancel(choice)) return \"quit\";\n return choice;\n}\n\nasync function applyFixWithReport(\n d: Diagnostic,\n ctx: DoctorContext,\n dryRun: boolean,\n): Promise<DiagnosticFixResult> {\n if (dryRun) {\n p.log.info(`[dry-run] would: ${d.fixPreview}`);\n return { ok: true, message: \"(dry-run)\" };\n }\n const result = await d.fix(ctx);\n if (result.ok) {\n p.log.success(result.message ?? `${d.id} fixed.`);\n } else {\n p.log.error(result.message ?? `${d.id} fix failed.`);\n }\n return result;\n}\n\nasync function runDoctor() {\n p.intro(\"agentmemory doctor\");\n const applyAll = args.includes(\"--all\");\n const dryRun = args.includes(\"--dry-run\");\n if (applyAll && dryRun) {\n p.log.error(\"Cannot combine --all and --dry-run.\");\n process.exit(2);\n }\n\n // Passive server checks (informational).\n const passive = await passiveServerChecks();\n const passivePassed = passive.filter((c) => c.ok).length;\n p.note(formatChecks(passive), `server: ${passivePassed}/${passive.length} passing`);\n\n // Doctor v2 interactive catalog.\n const ctx = buildDoctorContext();\n const effects = buildDoctorEffects();\n const diagnostics = buildDiagnostics(effects);\n\n if (dryRun) {\n const results: Array<{ diagnostic: Diagnostic; status: { ok: boolean; detail?: string } }> = [];\n for (const d of diagnostics) results.push({ diagnostic: d, status: await d.check(ctx) });\n const lines = dryRunPlan(ctx, results);\n p.note(lines.join(\"\\n\"), \"dry-run plan\");\n p.outro(\"Dry-run complete. Re-run without --dry-run to apply.\");\n return;\n }\n\n let failed = 0;\n let fixed = 0;\n let skipped = 0;\n let quit = false;\n\n for (const d of diagnostics) {\n if (quit) {\n skipped++;\n continue;\n }\n const status = await d.check(ctx);\n if (status.ok) {\n p.log.success(`${d.id} ✓${status.detail ? ` (${status.detail})` : \"\"}`);\n continue;\n }\n failed++;\n p.log.warn(`${d.id} ✗ ${status.detail ?? \"\"}`.trim());\n p.log.info(`why: ${d.fixPreview}`);\n\n if (d.manualOnly) {\n p.log.info(`(manual fix only — see \"${d.id}\" docs)`);\n }\n\n if (applyAll) {\n const r = await applyFixWithReport(d, ctx, false);\n if (r.ok) fixed++;\n // Re-check only this diagnostic.\n const after = await d.check(ctx);\n if (!after.ok) p.log.warn(`${d.id} still failing after fix.`);\n continue;\n }\n\n // Interactive prompt loop — allow [?] More info without leaving the check.\n while (true) {\n const action = await askFixAction(d);\n if (action === \"fix\") {\n const r = await applyFixWithReport(d, ctx, false);\n if (r.ok) {\n const after = await d.check(ctx);\n if (after.ok) {\n fixed++;\n } else {\n p.log.warn(`${d.id} still failing after fix: ${after.detail ?? \"\"}`);\n }\n }\n break;\n }\n if (action === \"skip\") {\n skipped++;\n break;\n }\n if (action === \"more\") {\n p.note(d.moreInfo, `[${d.id}] more info`);\n continue;\n }\n if (action === \"quit\") {\n quit = true;\n break;\n }\n }\n }\n\n const summary = `${diagnostics.length} checks · ${failed} failing · ${fixed} fixed · ${skipped} skipped`;\n if (quit) {\n p.outro(`Quit early. ${summary}`);\n process.exit(1);\n }\n if (failed === 0) {\n p.outro(\"All diagnostics passing. agentmemory is healthy.\");\n return;\n }\n if (failed - fixed === 0) {\n p.outro(`All fixes applied. ${summary}`);\n return;\n }\n p.outro(summary);\n process.exit(1);\n}\n\ntype DemoObservation = {\n toolName: string;\n toolInput: Record<string, string>;\n toolOutput: string;\n};\n\ntype DemoSession = {\n id: string;\n title: string;\n observations: DemoObservation[];\n};\n\ntype SearchResult = { query: string; hits: number; topTitle: string };\n\nfunction buildDemoSessions(): DemoSession[] {\n return [\n {\n id: generateId(\"demo\"),\n title: \"Session 1: JWT auth setup\",\n observations: [\n {\n toolName: \"Write\",\n toolInput: { file_path: \"src/middleware/auth.ts\" },\n toolOutput:\n \"Created JWT middleware using jose library. Tokens expire after 30 days. Chose jose over jsonwebtoken for Edge compatibility.\",\n },\n {\n toolName: \"Write\",\n toolInput: { file_path: \"test/auth.test.ts\" },\n toolOutput:\n \"Added token validation tests covering expired, malformed, and valid cases.\",\n },\n {\n toolName: \"Bash\",\n toolInput: { command: \"npm test\" },\n toolOutput: \"All 12 auth tests passing.\",\n },\n ],\n },\n {\n id: generateId(\"demo\"),\n title: \"Session 2: Database migration debugging\",\n observations: [\n {\n toolName: \"Read\",\n toolInput: { file_path: \"prisma/schema.prisma\" },\n toolOutput:\n \"Found N+1 query issue in user relations. Need to add include on posts query.\",\n },\n {\n toolName: \"Edit\",\n toolInput: { file_path: \"src/api/users.ts\" },\n toolOutput:\n \"Fixed N+1 by adding Prisma include. Query time dropped from 450ms to 28ms.\",\n },\n ],\n },\n {\n id: generateId(\"demo\"),\n title: \"Session 3: Rate limiting\",\n observations: [\n {\n toolName: \"Write\",\n toolInput: { file_path: \"src/middleware/ratelimit.ts\" },\n toolOutput:\n \"Added rate limiting middleware with 100 req/min default. Uses in-memory store for dev, Redis for prod.\",\n },\n ],\n },\n ];\n}\n\nasync function postJson<T = unknown>(\n url: string,\n body: unknown,\n timeoutMs = 5000,\n): Promise<T | null> {\n try {\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n signal: AbortSignal.timeout(timeoutMs),\n });\n if (!res.ok) return null;\n return (await res.json().catch(() => null)) as T | null;\n } catch {\n return null;\n }\n}\n\nasync function postJsonStrict<T = unknown>(\n url: string,\n body: unknown,\n timeoutMs = 5000,\n): Promise<T | null> {\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n signal: AbortSignal.timeout(timeoutMs),\n });\n if (!res.ok) {\n const errBody = await res.text().catch(() => \"\");\n const suffix = errBody ? ` — ${errBody.slice(0, 200)}` : \"\";\n throw new Error(`POST ${url} failed: ${res.status} ${res.statusText}${suffix}`);\n }\n return (await res.json().catch(() => null)) as T | null;\n}\n\nasync function seedDemoSession(\n base: string,\n project: string,\n session: DemoSession,\n): Promise<number> {\n await postJsonStrict(`${base}/agentmemory/session/start`, {\n sessionId: session.id,\n project,\n cwd: project,\n });\n\n let stored = 0;\n for (const obs of session.observations) {\n const url = `${base}/agentmemory/observe`;\n const payload = {\n hookType: \"post_tool_use\",\n sessionId: session.id,\n project,\n cwd: project,\n timestamp: new Date().toISOString(),\n data: {\n tool_name: obs.toolName,\n tool_input: obs.toolInput,\n tool_output: obs.toolOutput,\n },\n };\n\n try {\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(payload),\n signal: AbortSignal.timeout(5000),\n });\n if (res.ok) {\n stored++;\n } else {\n const body = await res.text().catch(() => \"\");\n p.log.warn(\n `observe failed for ${obs.toolName}: ${res.status} ${res.statusText}${body ? ` — ${body.slice(0, 160)}` : \"\"}`,\n );\n }\n } catch (err) {\n p.log.warn(\n `observe request failed for ${obs.toolName}: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n await postJsonStrict(`${base}/agentmemory/session/end`, { sessionId: session.id });\n return stored;\n}\n\nasync function runDemoSearch(base: string, query: string): Promise<SearchResult> {\n const data = await postJson<{ results?: Array<{ title?: string }> }>(\n `${base}/agentmemory/smart-search`,\n { query, limit: 5 },\n 10000,\n );\n const items = data?.results ?? [];\n return {\n query,\n hits: items.length,\n topTitle: items[0]?.title ?? \"(no results)\",\n };\n}\n\n// Prefer the packaged `.env.example` (next to `dist/cli.mjs`); fall back to\n// the repo root when running from a source checkout.\nfunction findEnvExample(): string | null {\n const candidates = [\n join(__dirname, \"..\", \".env.example\"),\n join(__dirname, \".env.example\"),\n join(process.cwd(), \".env.example\"),\n ];\n for (const c of candidates) {\n if (existsSync(c)) return c;\n }\n return null;\n}\n\nasync function runInit() {\n p.intro(\"agentmemory init\");\n const target = join(homedir(), \".agentmemory\", \".env\");\n const template = findEnvExample();\n if (!template) {\n p.log.error(\n \"Could not locate .env.example in the package. Re-install with: npm i -g @agentmemory/agentmemory\",\n );\n process.exit(1);\n }\n const dir = dirname(target);\n const { mkdir, copyFile } = await import(\"node:fs/promises\");\n const { constants: fsConstants } = await import(\"node:fs\");\n try {\n await mkdir(dir, { recursive: true });\n // COPYFILE_EXCL collapses the exists-check + copy into one syscall —\n // an existsSync(target) + copyFile() pair races with a parallel init\n // (or any other process touching ~/.agentmemory/.env between the two\n // calls) and would silently overwrite a config the operator just\n // wrote. EEXIST out of copyFile is the only \"already configured\"\n // signal we trust.\n await copyFile(template, target, fsConstants.COPYFILE_EXCL);\n } catch (err) {\n if ((err as NodeJS.ErrnoException)?.code === \"EEXIST\") {\n p.log.warn(`${target} already exists — leaving it untouched.`);\n p.log.info(\n `Compare against the latest template: diff ${target} ${template}`,\n );\n p.outro(\"Nothing changed.\");\n return;\n }\n p.log.error(\n `Failed to copy template: ${err instanceof Error ? err.message : String(err)}`,\n );\n process.exit(1);\n }\n p.log.success(`Wrote ${target}`);\n p.note(\n [\n \"All keys are commented out by default. Uncomment the ones you want.\",\n \"\",\n \"Common next steps:\",\n \" 1. Pick an LLM provider key (ANTHROPIC_API_KEY / OPENAI_API_KEY / GEMINI_API_KEY / etc.)\",\n \" 2. Run `npx @agentmemory/agentmemory doctor` to verify the daemon sees them\",\n \" 3. Run `npx @agentmemory/agentmemory` to start the worker\",\n ].join(\"\\n\"),\n \"Next steps\",\n );\n p.outro(`Edit ${target} and you're set.`);\n}\n\nasync function runDemo() {\n const port = getRestPort();\n const base = `http://localhost:${port}`;\n p.intro(\"agentmemory demo\");\n\n if (!(await isAgentmemoryReady())) {\n p.log.error(\n `agentmemory worker not reachable on port ${port} (livez probe failed). Something may be on the port but it isn't serving /agentmemory/*.`,\n );\n p.log.info(\"Start it with: npx @agentmemory/agentmemory\");\n process.exit(1);\n }\n\n const demoProject = \"/tmp/agentmemory-demo\";\n const sessions = buildDemoSessions();\n\n const sSeed = p.spinner();\n sSeed.start(\"Seeding 3 demo sessions with realistic observations...\");\n\n let totalObs = 0;\n for (const session of sessions) {\n totalObs += await seedDemoSession(base, demoProject, session);\n }\n\n sSeed.stop(`Seeded ${totalObs} observations across ${sessions.length} sessions`);\n\n const queries = [\n \"jwt auth middleware\",\n \"database performance optimization\",\n \"rate limiting\",\n ];\n\n const sQuery = p.spinner();\n sQuery.start(`Running ${queries.length} smart-search queries...`);\n\n const results: SearchResult[] = [];\n for (const query of queries) {\n results.push(await runDemoSearch(base, query));\n }\n\n sQuery.stop(\"Search complete\");\n\n const lines = [\n `Project: ${demoProject}`,\n `Sessions: ${sessions.length} seeded (${totalObs} observations)`,\n \"\",\n \"Search results:\",\n ...results.flatMap((r) => [\n ` \"${r.query}\"`,\n ` → ${r.hits} hit(s), top: ${r.topTitle.slice(0, 60)}`,\n ]),\n \"\",\n `Notice: searching \"database performance optimization\"`,\n `found the N+1 query fix — keyword matching can't do that.`,\n \"\",\n `Viewer: ${getViewerUrl()}`,\n `Clean up with: curl -X DELETE \"${base}/agentmemory/sessions?project=${demoProject}\"`,\n ];\n\n p.note(lines.join(\"\\n\"), \"demo complete\");\n p.log.success(\"agentmemory is working. Point your agent at it and get back to coding.\");\n}\n\nfunction runCommand(\n command: string,\n commandArgs: string[],\n options: { cwd?: string; label: string; optional?: boolean } = { label: \"command\" },\n): boolean {\n const spinner = p.spinner();\n spinner.start(options.label);\n const result = spawnSync(command, commandArgs, {\n cwd: options.cwd || process.cwd(),\n stdio: \"pipe\",\n encoding: \"utf-8\",\n });\n\n if (result.status === 0) {\n spinner.stop(`${options.label} ✓`);\n return true;\n }\n\n const stderr = (result.stderr || \"\").toString().trim();\n const stdout = (result.stdout || \"\").toString().trim();\n const msg = stderr || stdout || \"unknown error\";\n\n if (options.optional) {\n spinner.stop(`${options.label} (skipped)`);\n p.log.warn(msg.slice(0, 300));\n return false;\n }\n\n spinner.stop(`${options.label} ✗`);\n p.log.error(msg.slice(0, 300));\n return false;\n}\n\nasync function runUpgrade() {\n p.intro(\"agentmemory upgrade\");\n\n const cwd = process.cwd();\n const hasPackageJson = existsSync(join(cwd, \"package.json\"));\n const hasPnpmLock = existsSync(join(cwd, \"pnpm-lock.yaml\"));\n\n const pnpmBin = whichBinary(\"pnpm\");\n const npmBin = whichBinary(\"npm\");\n const dockerBin = whichBinary(\"docker\");\n\n p.log.info(`Working directory: ${cwd}`);\n const requireSuccess = (ok: boolean, label: string): void => {\n if (!ok) {\n p.log.error(`Upgrade aborted: ${label} failed.`);\n process.exit(1);\n }\n };\n\n if (hasPackageJson) {\n const usePnpm = !!pnpmBin && hasPnpmLock;\n if (usePnpm && pnpmBin) {\n const installOk = runCommand(pnpmBin, [\"install\"], {\n label: \"Refreshing dependencies (pnpm install)\",\n });\n requireSuccess(installOk, \"pnpm install\");\n runCommand(pnpmBin, [\"up\", \"iii-sdk@latest\"], {\n label: \"Upgrading iii-sdk to latest\",\n optional: true,\n });\n } else if (npmBin) {\n const installOk = runCommand(npmBin, [\"install\"], {\n label: \"Refreshing dependencies (npm install)\",\n });\n requireSuccess(installOk, \"npm install\");\n runCommand(npmBin, [\"install\", \"iii-sdk@latest\"], {\n label: \"Upgrading iii-sdk to latest\",\n optional: true,\n });\n } else {\n p.log.warn(\"No package manager found (pnpm/npm). Skipping JS dependency upgrade.\");\n }\n } else {\n p.log.warn(\"No package.json in current directory. Skipping JS dependency upgrade.\");\n }\n\n const upgradeEngine = await p.confirm({\n message: \"Re-run the iii-engine install script (curl | sh)?\",\n initialValue: true,\n });\n if (p.isCancel(upgradeEngine)) {\n p.cancel(\"Cancelled.\");\n return process.exit(0);\n }\n if (upgradeEngine === true) {\n await runIiiInstaller();\n } else {\n p.log.info(\"Skipped iii-engine installer.\");\n }\n\n if (dockerBin) {\n runCommand(dockerBin, [\"pull\", `iiidev/iii:${IIPINNED_VERSION}`], {\n label: `Pulling iii Docker image v${IIPINNED_VERSION} (pinned)`,\n optional: true,\n });\n } else {\n p.log.info(\"Docker not found. Skipping Docker image refresh.\");\n }\n\n p.note(\n [\n \"Upgrade flow completed.\",\n \"\",\n \"Recommended next steps:\",\n \" 1) agentmemory status\",\n \" 2) npm/pnpm test\",\n \" 3) restart agentmemory process\",\n ].join(\"\\n\"),\n \"agentmemory upgrade\",\n );\n}\n\nfunction pidAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch (err) {\n return (err as NodeJS.ErrnoException)?.code === \"EPERM\";\n }\n}\n\nasync function signalAndWait(\n pid: number,\n initialSignal: NodeJS.Signals,\n timeoutMs: number,\n): Promise<boolean> {\n try {\n process.kill(pid, initialSignal);\n } catch (err) {\n const code = (err as NodeJS.ErrnoException)?.code;\n if (code === \"ESRCH\") return true;\n if (code === \"EPERM\") {\n p.log.warn(`No permission to signal pid ${pid}. Try: kill ${pid}`);\n return false;\n }\n vlog(`${initialSignal} ${pid}: ${err instanceof Error ? err.message : String(err)}`);\n return false;\n }\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n if (!pidAlive(pid)) return true;\n await new Promise((r) => setTimeout(r, 200));\n }\n if (!pidAlive(pid)) return true;\n try {\n process.kill(pid, \"SIGKILL\");\n } catch (err) {\n if ((err as NodeJS.ErrnoException)?.code === \"ESRCH\") return true;\n vlog(`SIGKILL ${pid}: ${err instanceof Error ? err.message : String(err)}`);\n return false;\n }\n await new Promise((r) => setTimeout(r, 200));\n return !pidAlive(pid);\n}\n\nfunction findEnginePidsByPort(port: number): number[] {\n if (IS_WINDOWS) return [];\n const lsof = whichBinary(\"lsof\");\n if (!lsof) return [];\n // -sTCP:LISTEN restricts to listening server sockets only. Without\n // this, lsof also returns client-side PIDs (any process with an\n // active TCP connection to :port), which includes the agentmemory\n // CLI itself thanks to the keep-alive fetch in isEngineRunning().\n // signalAndWait would then SIGKILL its own parent — exit code 137.\n const selfPid = process.pid;\n try {\n const out = execFileSync(lsof, [\"-i\", `:${port}`, \"-sTCP:LISTEN\", \"-t\"], {\n encoding: \"utf-8\",\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n });\n return out\n .split(/\\s+/)\n .map((s) => parseInt(s, 10))\n .filter((n) => Number.isFinite(n) && n > 0 && n !== selfPid);\n } catch (err) {\n vlog(`lsof :${port}: ${err instanceof Error ? err.message : String(err)}`);\n return [];\n }\n}\n\nasync function stopDockerEngine(composeFile: string, port: number): Promise<void> {\n const dockerBin = whichBinary(\"docker\");\n if (!dockerBin) {\n p.log.error(\n `Engine was started via Docker compose, but \\`docker\\` is no longer on PATH. Stop it manually:\\n docker compose -f ${composeFile} down`,\n );\n process.exit(1);\n }\n if (!existsSync(composeFile)) {\n p.log.error(\n `Engine state references ${composeFile}, but the file is gone. Stop it manually:\\n docker compose down (from the dir holding the original docker-compose.yml)`,\n );\n process.exit(1);\n }\n const ok = runCommand(dockerBin, [\"compose\", \"-f\", composeFile, \"down\"], {\n label: `docker compose -f ${composeFile} down`,\n });\n clearEnginePidfile();\n clearEngineState();\n if (!ok) {\n p.log.error(\n `docker compose down failed. The engine may still be running on :${port}. Inspect with:\\n docker compose -f ${composeFile} ps`,\n );\n process.exit(1);\n }\n p.outro(\"Stopped. Memories persisted to disk; restart anytime with: npx @agentmemory/agentmemory\");\n}\n\nasync function runStop(): Promise<void> {\n p.intro(\"agentmemory stop\");\n const port = getRestPort();\n const state = readEngineState();\n const running = await isEngineRunning();\n const force = args.includes(\"--force\");\n\n if (state?.kind === \"docker\") {\n if (!running) {\n p.log.info(`No engine responding on port ${port}.`);\n clearEnginePidfile();\n clearEngineState();\n p.outro(\"Nothing to stop.\");\n return;\n }\n await stopDockerEngine(state.composeFile, port);\n return;\n }\n\n const portPids = findEnginePidsByPort(port);\n const pidfilePid = readEnginePidfile();\n\n if (!running) {\n if (portPids.length === 0 && pidfilePid === null) {\n clearEnginePidfile();\n clearEngineState();\n p.outro(\"Nothing to stop.\");\n return;\n }\n const survivors = new Set<number>(portPids);\n if (pidfilePid) survivors.add(pidfilePid);\n p.log.warn(\n `Engine not responding on :${port}, but ${survivors.size} process(es) still hold the port or pidfile: ${[...survivors].join(\", \")}`,\n );\n p.log.info(\n `Preserving ~/.agentmemory/iii.pid. Investigate before manual cleanup:\\n ps -p ${[...survivors].join(\",\")} -o pid,ppid,comm,etime\\n ${IS_WINDOWS ? \"netstat -ano | findstr :\" + port : \"lsof -i :\" + port}`,\n );\n process.exit(1);\n }\n\n if (!state) {\n const compose = discoverComposeFile();\n if (compose && pidfilePid === null) {\n if (force) {\n p.log.warn(\n `--force: bypassing Docker-heuristic guard. Falling back to native pidfile + lsof on :${port}.`,\n );\n } else {\n p.log.error(\n `Engine is running on :${port} but no pidfile or state file is present. It may have been started via Docker compose by a different shell. Refusing to signal host PIDs.\\n\\nStop it with:\\n docker compose -f ${compose} down\\n\\nOr re-run with --force to signal whatever lsof finds on :${port}, or AGENTMEMORY_USE_DOCKER=1 to record state next time.`,\n );\n process.exit(1);\n }\n }\n }\n\n const candidates = new Set<number>();\n if (pidfilePid) candidates.add(pidfilePid);\n for (const pid of portPids) candidates.add(pid);\n\n if (candidates.size === 0) {\n p.log.error(\n `Could not locate engine process. Try:\\n ${IS_WINDOWS ? \"netstat -ano | findstr :\" + port : \"lsof -i :\" + port + \" -t | xargs kill -9\"}`,\n );\n process.exit(1);\n }\n\n let allStopped = true;\n for (const pid of candidates) {\n const s = p.spinner();\n s.start(`Stopping iii-engine (pid ${pid})...`);\n const ok = await signalAndWait(pid, \"SIGTERM\", 3000);\n s.stop(ok ? `Stopped pid ${pid}` : `Failed to stop pid ${pid}`);\n if (!ok) allStopped = false;\n }\n\n clearEnginePidfile();\n clearEngineState();\n if (!allStopped) {\n p.log.error(\"One or more engine processes survived SIGKILL. Investigate with `ps`.\");\n process.exit(1);\n }\n p.outro(\"Stopped. Memories persisted to disk; restart anytime with: npx @agentmemory/agentmemory\");\n}\n\nasync function runMcp(): Promise<void> {\n await import(\"./mcp/standalone.js\");\n}\n\nasync function runConnectCmd(): Promise<void> {\n const { runConnect } = await import(\"./cli/connect/index.js\");\n await runConnect(args.slice(1));\n}\n\nasync function runImportJsonl(): Promise<void> {\n // Long-form flags that take a value. Their value tokens must be\n // consumed alongside the flag so they don't leak into positional\n // args (e.g. `--port 3112 import-jsonl` would otherwise turn\n // 3112 into pathArg).\n const VALUE_FLAGS = new Set([\"--port\", \"--tools\"]);\n let maxFiles: number | undefined;\n const tail = args.slice(1);\n const positional: string[] = [];\n for (let i = 0; i < tail.length; i++) {\n const a = tail[i]!;\n if (a === \"--max-files\") {\n const raw = tail[i + 1];\n const parsed = raw !== undefined ? parseInt(raw, 10) : NaN;\n if (Number.isInteger(parsed) && parsed > 0) {\n maxFiles = parsed;\n } else if (raw !== undefined) {\n p.log.warn(`Ignoring --max-files ${raw}: expected a positive integer.`);\n }\n i++;\n continue;\n }\n if (a.startsWith(\"--max-files=\")) {\n const raw = a.slice(\"--max-files=\".length);\n const parsed = parseInt(raw, 10);\n if (Number.isInteger(parsed) && parsed > 0) {\n maxFiles = parsed;\n } else {\n p.log.warn(`Ignoring --max-files=${raw}: expected a positive integer.`);\n }\n continue;\n }\n if (VALUE_FLAGS.has(a)) {\n i++;\n continue;\n }\n if (a.startsWith(\"-\")) continue;\n positional.push(a);\n }\n const pathArg = positional[0];\n\n const port = getRestPort();\n const base = `http://localhost:${port}`;\n\n let probeOk = false;\n let probeDetail = \"\";\n try {\n const probe = await fetch(`${base}/agentmemory/livez`, {\n signal: AbortSignal.timeout(2000),\n });\n probeOk = probe.ok;\n if (!probeOk) {\n const probeBody = await probe.text().catch(() => \"\");\n probeDetail = `reachable but unhealthy (HTTP ${probe.status}${probeBody ? `: ${probeBody.slice(0, 200)}` : \"\"})`;\n }\n } catch (err) {\n probeOk = false;\n const msg = err instanceof Error ? err.message : String(err);\n probeDetail = `unreachable (${msg})`;\n }\n if (!probeOk) {\n p.log.error(\n `agentmemory livez probe failed on port ${port}: ${probeDetail}. Start it with \\`npx @agentmemory/agentmemory\\` in another terminal, then re-run this command.`,\n );\n process.exit(1);\n }\n\n const body: Record<string, unknown> = {};\n if (pathArg) body[\"path\"] = pathArg;\n if (maxFiles !== undefined) body[\"maxFiles\"] = maxFiles;\n\n const headers: Record<string, string> = { \"content-type\": \"application/json\" };\n const secret = process.env[\"AGENTMEMORY_SECRET\"];\n if (secret) headers[\"authorization\"] = `Bearer ${secret}`;\n\n p.log.info(`Importing JSONL from ${pathArg || \"~/.claude/projects\"}…`);\n const spinner = p.spinner();\n spinner.start(\"scanning files\");\n\n try {\n const res = await fetch(`${base}/agentmemory/replay/import-jsonl`, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n signal: AbortSignal.timeout(120_000),\n });\n const text = await res.text();\n let json: {\n success?: boolean;\n error?: string;\n imported?: number;\n sessionIds?: string[];\n observations?: number;\n discovered?: number;\n truncated?: boolean;\n traversalCapped?: boolean;\n maxFiles?: number;\n maxFilesUpperBound?: number;\n } = {};\n if (text.length > 0) {\n try {\n json = JSON.parse(text);\n } catch {\n spinner.stop(\"failed\");\n p.log.error(\n `server returned non-JSON response (HTTP ${res.status}): ${text.slice(0, 200)}`,\n );\n process.exit(1);\n }\n }\n if (!res.ok || json.success !== true) {\n spinner.stop(\"failed\");\n const detail =\n json.error ||\n (text.length === 0\n ? \"empty response body\"\n : json.success === undefined\n ? `HTTP ${res.status} (response missing success field)`\n : `HTTP ${res.status}`);\n if (res.status === 401) {\n p.log.error(\n `${detail}. Set AGENTMEMORY_SECRET to match the server's secret and re-run.`,\n );\n } else if (res.status === 404) {\n p.log.error(\n `${detail}. The running agentmemory server does not expose /agentmemory/replay/import-jsonl — upgrade to v0.8.13 or later.`,\n );\n } else {\n p.log.error(detail);\n }\n process.exit(1);\n }\n spinner.stop(\n `imported ${json.imported ?? 0} file(s), ${json.observations ?? 0} observation(s) across ${json.sessionIds?.length || 0} session(s)`,\n );\n if (json.truncated) {\n const cap = json.maxFiles ?? 200;\n const upper = json.maxFilesUpperBound ?? 1000;\n const discovered = json.discovered ?? 0;\n const skipped = discovered - (json.imported ?? 0);\n const discoveredLabel = json.traversalCapped\n ? `${discovered}+ (traversal halted at safety cap)`\n : String(discovered);\n const baseMsg = `Hit the ${cap}-file scan cap; ${skipped} of ${discoveredLabel} discovered file(s) were skipped.`;\n // If we already saw more than the server's hard cap (or the\n // walker stopped early), bumping --max-files won't help on its\n // own — recommend batching by subdirectory.\n if (discovered > upper || json.traversalCapped) {\n p.log.warn(\n `${baseMsg} Tree exceeds the server's --max-files limit of ${upper}; ` +\n `batch by subdirectory (run import-jsonl once per project under ~/.claude/projects).`,\n );\n } else {\n const suggested = Math.min(\n Math.max((discovered || cap) + 100, cap * 2),\n upper,\n );\n p.log.warn(\n `${baseMsg} Re-run with --max-files=${suggested} (max ${upper}) or batch by subdirectory.`,\n );\n }\n }\n if (json.sessionIds && json.sessionIds.length > 0) {\n p.log.info(`View at ${getViewerUrl()} → Replay tab`);\n }\n } catch (err) {\n spinner.stop(\"failed\");\n if (err instanceof Error && err.name === \"TimeoutError\") {\n p.log.error(\"import timed out after 2 minutes\");\n } else {\n p.log.error(err instanceof Error ? err.message : String(err));\n }\n process.exit(1);\n }\n}\n\n// ---------------------------------------------------------------------------\n// `agentmemory remove` — clean uninstall.\n//\n// Planning logic lives in src/cli/remove-plan.ts so it's testable without\n// touching $HOME. This function loads the manifest, builds the plan,\n// double-confirms, then executes step by step.\n\nfunction loadConnectManifest(home: string): ConnectManifest | null {\n const path = join(home, \".agentmemory\", \"backups\", \"connect-manifest.json\");\n try {\n const raw = readFileSync(path, \"utf-8\");\n const parsed = JSON.parse(raw) as Partial<ConnectManifest>;\n if (Array.isArray(parsed?.installed)) {\n return { installed: parsed.installed };\n }\n return null;\n } catch {\n return null;\n }\n}\n\nfunction probeLocalBinIiiVersion(home: string): string | null {\n const path = localBinIii(home);\n if (!existsSync(path)) return null;\n return iiiBinVersion(path);\n}\n\nfunction safeDelete(path: string): { ok: boolean; message: string } {\n try {\n if (!existsSync(path)) return { ok: true, message: `not present (${path})` };\n const st = statSync(path);\n if (st.isDirectory()) {\n rmSync(path, { recursive: true, force: true });\n } else {\n unlinkSync(path);\n }\n return { ok: true, message: `deleted ${path}` };\n } catch (err) {\n return {\n ok: false,\n message: `failed ${path}: ${err instanceof Error ? err.message : String(err)}`,\n };\n }\n}\n\nasync function runRemove(): Promise<void> {\n p.intro(\"agentmemory remove\");\n const force = args.includes(\"--force\");\n const keepData = args.includes(\"--keep-data\");\n\n const home = homedir();\n const connectManifest = loadConnectManifest(home);\n const localBinIiiVersion = probeLocalBinIiiVersion(home);\n\n const options: RemoveOptions = { force, keepData };\n const plan = buildRemovePlan(\n {\n home,\n pinnedVersion: IIPINNED_VERSION,\n localBinIiiVersion,\n connectManifest,\n },\n options,\n );\n\n const applicable = plan.filter((it) => it.applicable);\n if (applicable.length === 0) {\n p.outro(\"Nothing to remove. agentmemory is already gone.\");\n return;\n }\n\n p.note(formatPlan(plan), \"destruction plan\");\n\n if (!force) {\n const proceed = await p.confirm({\n message: \"Proceed with these deletions?\",\n initialValue: false,\n });\n if (p.isCancel(proceed) || proceed !== true) {\n p.cancel(\"Cancelled. Nothing was deleted.\");\n return;\n }\n const sure = await p.confirm({\n message: \"This is irreversible. Continue?\",\n initialValue: false,\n });\n if (p.isCancel(sure) || sure !== true) {\n p.cancel(\"Cancelled. Nothing was deleted.\");\n return;\n }\n }\n\n for (const item of plan) {\n if (!item.applicable) continue;\n\n // alwaysAsk items get a per-item confirmation even with --force.\n if (item.alwaysAsk) {\n const ok = await p.confirm({\n message: `${item.description} — really delete${item.path ? ` ${item.path}` : \"\"}?`,\n initialValue: false,\n });\n if (p.isCancel(ok) || ok !== true) {\n p.log.info(`skipped: ${item.id}`);\n continue;\n }\n }\n\n if (item.id === \"stop-engine\") {\n try {\n const port = getRestPort();\n const portPids = findEnginePidsByPort(port);\n const pidfilePid = readEnginePidfile();\n const cands = new Set<number>();\n if (pidfilePid) cands.add(pidfilePid);\n for (const pid of portPids) cands.add(pid);\n for (const pid of cands) await signalAndWait(pid, \"SIGTERM\", 3000);\n clearEnginePidfile();\n clearEngineState();\n p.log.success(\n cands.size > 0\n ? `stopped engine (${cands.size} pid${cands.size === 1 ? \"\" : \"s\"})`\n : \"no engine running\",\n );\n } catch (err) {\n p.log.warn(\n `engine stop best-effort: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n continue;\n }\n\n if (!item.path) continue;\n const r = safeDelete(item.path);\n if (r.ok) p.log.success(r.message);\n else p.log.error(r.message);\n }\n\n p.outro(\n \"Done. agentmemory cleanly removed. The npm package itself: npm uninstall -g @agentmemory/agentmemory\",\n );\n}\n\nconst commands: Record<string, () => Promise<void>> = {\n init: runInit,\n connect: runConnectCmd,\n status: runStatus,\n doctor: runDoctor,\n demo: runDemo,\n upgrade: runUpgrade,\n stop: runStop,\n remove: runRemove,\n mcp: runMcp,\n \"import-jsonl\": runImportJsonl,\n};\n\nconst handler = commands[args[0] ?? \"\"] ?? main;\nhandler().catch((err) => {\n p.log.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n});\n"],"mappings":"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"}
|