@agentmemory/agentmemory 0.8.1 → 0.8.6

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.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.mjs","names":[],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { spawn, execFileSync, execSync } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport * as p from \"@clack/prompts\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst args = process.argv.slice(2);\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 status Show connection status, memory count, and health\n\nOptions:\n --help, -h Show this help\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\nQuick start:\n npx @agentmemory/agentmemory # start everything\n npx @agentmemory/agentmemory status # check health\n npx agentmemory-mcp # standalone MCP (no engine)\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 return parseInt(process.env[\"III_REST_PORT\"] || \"3111\", 10) || 3111;\n}\n\nasync function isEngineRunning(): Promise<boolean> {\n try {\n await fetch(`http://localhost:${getRestPort()}/`, {\n signal: AbortSignal.timeout(2000),\n });\n return true;\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 = process.platform === \"win32\" ? \"where\" : \"which\";\n try {\n return execFileSync(cmd, [name], { encoding: \"utf-8\" }).trim().split(\"\\n\")[0];\n } catch {\n return null;\n }\n}\n\nasync function installIii(): Promise<boolean> {\n if (process.platform === \"win32\") {\n p.log.warn(\"Automatic iii-engine install is not supported on Windows.\");\n p.log.info(\"Install manually: https://iii.dev/docs\");\n return false;\n }\n\n const curlBin = whichBinary(\"curl\");\n if (!curlBin) {\n p.log.warn(\"curl not found — cannot auto-install iii-engine.\");\n return false;\n }\n\n const shouldInstall = await p.confirm({\n message: \"iii-engine is not installed. Install it now?\",\n initialValue: true,\n });\n\n if (p.isCancel(shouldInstall) || !shouldInstall) {\n return false;\n }\n\n const s = p.spinner();\n s.start(\"Installing iii-engine...\");\n\n try {\n execSync(\"curl -fsSL https://install.iii.dev/iii/main/install.sh | sh\", {\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n timeout: 120000,\n });\n\n const installed = whichBinary(\"iii\");\n if (installed) {\n s.stop(\"iii-engine installed successfully\");\n return true;\n }\n\n s.stop(\"Installation completed but iii not found in PATH\");\n p.log.warn(\"You may need to restart your shell or add iii to your PATH.\");\n\n const iiiPaths = [\n join(process.env[\"HOME\"] || \"\", \".local\", \"bin\", \"iii\"),\n \"/usr/local/bin/iii\",\n ];\n for (const iiiPath of iiiPaths) {\n if (existsSync(iiiPath)) {\n p.log.info(`Found iii at: ${iiiPath}`);\n process.env[\"PATH\"] = `${dirname(iiiPath)}:${process.env[\"PATH\"]}`;\n return true;\n }\n }\n\n return false;\n } catch (err) {\n s.stop(\"Failed to install iii-engine\");\n p.log.error(err instanceof Error ? err.message : String(err));\n return false;\n }\n}\n\nasync function startEngine(): Promise<boolean> {\n const configPath = findIiiConfig();\n let iiiBin = whichBinary(\"iii\");\n\n if (!iiiBin) {\n const installed = await installIii();\n if (installed) {\n iiiBin = whichBinary(\"iii\");\n }\n }\n\n if (iiiBin && configPath) {\n const s = p.spinner();\n s.start(`Starting iii-engine: ${iiiBin}`);\n const child = spawn(iiiBin, [\"--config\", configPath], {\n detached: true,\n stdio: \"ignore\",\n });\n child.unref();\n s.stop(\"iii-engine process started\");\n return true;\n }\n\n const dockerBin = whichBinary(\"docker\");\n const dockerCompose = join(__dirname, \"..\", \"docker-compose.yml\");\n const dcExists = existsSync(dockerCompose) || existsSync(join(process.cwd(), \"docker-compose.yml\"));\n\n if (dockerBin && dcExists) {\n const composeFile = existsSync(dockerCompose) ? dockerCompose : join(process.cwd(), \"docker-compose.yml\");\n const s = p.spinner();\n s.start(\"Starting iii-engine via Docker...\");\n const child = spawn(dockerBin, [\"compose\", \"-f\", composeFile, \"up\", \"-d\"], {\n detached: true,\n stdio: \"ignore\",\n });\n child.unref();\n s.stop(\"Docker compose started\");\n return true;\n }\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\nasync function main() {\n p.intro(\"agentmemory\");\n\n if (skipEngine) {\n p.log.info(\"Skipping engine check (--no-engine)\");\n await import(\"./index.js\");\n return;\n }\n\n if (await isEngineRunning()) {\n p.log.success(\"iii-engine is running\");\n await import(\"./index.js\");\n return;\n }\n\n const started = await startEngine();\n if (!started) {\n p.log.error(\"Could not start iii-engine.\");\n p.note(\n [\n \"Install iii-engine (pick one):\",\n \" curl -fsSL https://install.iii.dev/iii/main/install.sh | sh\",\n \" cargo install iii-engine\",\n \"\",\n \"Or use Docker:\",\n \" docker pull iiidev/iii:latest\",\n \"\",\n \"Docs: https://iii.dev/docs\",\n \"\",\n \"Or skip with: agentmemory --no-engine\",\n ].join(\"\\n\"),\n \"Setup required\",\n );\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 p.log.error(`Check that ports ${port}, ${port + 1}, 49134 are available.`);\n process.exit(1);\n }\n\n s.stop(\"iii-engine is ready\");\n await import(\"./index.js\");\n}\n\nasync function runStatus() {\n const port = getRestPort();\n const base = `http://localhost:${port}`;\n p.intro(\"agentmemory status\");\n\n const up = await isEngineRunning();\n if (!up) {\n p.log.error(`Not running — no response on port ${port}`);\n p.log.info(\"Start with: npx @agentmemory/agentmemory\");\n process.exit(1);\n }\n\n try {\n const [healthRes, sessionsRes, graphRes] = await Promise.all([\n fetch(`${base}/agentmemory/health`, { signal: AbortSignal.timeout(5000) }).then((r) => r.json()).catch(() => null),\n fetch(`${base}/agentmemory/sessions`, { signal: AbortSignal.timeout(5000) }).then((r) => r.json()).catch(() => null),\n fetch(`${base}/agentmemory/graph/stats`, { signal: AbortSignal.timeout(5000) }).then((r) => r.json()).catch(() => null),\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 memories = h?.workers?.[0]?.function_count || 0;\n const nodes = graphRes?.nodes || 0;\n const edges = graphRes?.edges || 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 p.log.success(`Connected — v${version} on port ${port}`);\n\n const lines = [\n `Health: ${status === \"healthy\" ? \"healthy\" : status}`,\n `Sessions: ${sessions}`,\n `Graph: ${nodes} nodes, ${edges} edges`,\n `Circuit: ${cb}`,\n `Heap: ${heapMB} MB`,\n `Uptime: ${uptime}s`,\n `Viewer: http://localhost:${port + 2}`,\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\nif (args[0] === \"status\") {\n runStatus().catch((err) => {\n p.log.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n });\n} else {\n main().catch((err) => {\n p.log.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"cli.mjs","names":["PATH_DELIMITER"],"sources":["../src/state/schema.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} 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","#!/usr/bin/env node\n\nimport { spawn, execFileSync, type ChildProcess } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { join, dirname, delimiter as PATH_DELIMITER } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { platform } from \"node:os\";\nimport * as p from \"@clack/prompts\";\nimport { generateId } from \"./state/schema.js\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst args = process.argv.slice(2);\nconst IS_WINDOWS = platform() === \"win32\";\nconst IS_VERBOSE = args.includes(\"--verbose\") || args.includes(\"-v\");\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 status Show connection status, memory count, and health\n demo Seed sample sessions and show recall in action\n mcp Start standalone MCP server (no engine required)\n\nOptions:\n --help, -h Show this help\n --verbose, -v Show engine stderr and diagnostic info on startup\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\nQuick start:\n npx @agentmemory/agentmemory # start with local iii-engine or Docker\n npx @agentmemory/agentmemory status # check health\n npx @agentmemory/agentmemory demo # try it in 30 seconds (needs server running)\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 return parseInt(process.env[\"III_REST_PORT\"] || \"3111\", 10) || 3111;\n}\n\nasync function isEngineRunning(): Promise<boolean> {\n try {\n await fetch(`http://localhost:${getRestPort()}/`, {\n signal: AbortSignal.timeout(2000),\n });\n return true;\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], { encoding: \"utf-8\" });\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\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 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: label.includes(\"Docker\") ? \"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 }\n });\n child.unref();\n return child;\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) {\n const s = p.spinner();\n s.start(`Starting iii-engine: ${iiiBin}`);\n spawnEngineBackground(iiiBin, [\"--config\", configPath], \"iii-engine\");\n s.stop(\"iii-engine process started\");\n return true;\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 if (dockerBin && composeFile) {\n const s = p.spinner();\n s.start(\"Starting iii-engine via Docker...\");\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 for (const iiiPath of fallbackIiiPaths()) {\n if (existsSync(iiiPath)) {\n p.log.info(`Found iii at: ${iiiPath}`);\n process.env[\"PATH\"] = `${dirname(iiiPath)}${PATH_DELIMITER}${process.env[\"PATH\"] ?? \"\"}`;\n iiiBin = iiiPath;\n break;\n }\n }\n\n if (iiiBin && configPath) {\n const s = p.spinner();\n s.start(`Starting iii-engine: ${iiiBin}`);\n spawnEngineBackground(iiiBin, [\"--config\", configPath], \"iii-engine\");\n s.stop(\"iii-engine process started\");\n return true;\n }\n\n if (!iiiBin && (!dockerBin || !composeFile)) {\n startupFailure = { kind: \"no-engine\" };\n } else if (!composeFile && dockerBin) {\n startupFailure = { kind: \"no-docker-compose\" };\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 if (IS_WINDOWS) {\n return [\n \"agentmemory requires the `iii-engine` runtime. Pick one:\",\n \"\",\n \" A) Download the prebuilt Windows binary:\",\n \" 1. Open https://github.com/iii-hq/iii/releases/latest\",\n \" 2. Download iii-x86_64-pc-windows-msvc.zip\",\n \" (or iii-aarch64-pc-windows-msvc.zip on ARM)\",\n \" 3. Extract iii.exe and either add its folder to PATH\",\n \" or move it to %USERPROFILE%\\\\.local\\\\bin\\\\iii.exe\",\n \" 4. Re-run: npx @agentmemory/agentmemory\",\n \"\",\n \" B) Docker Desktop:\",\n \" 1. Install Docker Desktop for Windows\",\n \" 2. Start Docker Desktop (engine must be running)\",\n \" 3. Re-run: npx @agentmemory/agentmemory\",\n \"\",\n \"Or skip the engine entirely for standalone MCP:\",\n \" npx @agentmemory/agentmemory mcp\",\n ];\n }\n return [\n \"agentmemory requires the `iii-engine` runtime. Pick one:\",\n \"\",\n \" A) curl -fsSL https://install.iii.dev/iii/main/install.sh | sh\",\n \" (installs the prebuilt iii binary into ~/.local/bin/iii)\",\n \"\",\n \" B) Docker: install Docker Desktop or docker-ce, then re-run\",\n \"\",\n \"Or skip the engine entirely for standalone MCP:\",\n \" 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 main() {\n p.intro(\"agentmemory\");\n\n if (skipEngine) {\n p.log.info(\"Skipping engine check (--no-engine)\");\n await import(\"./index.js\");\n return;\n }\n\n if (await isEngineRunning()) {\n p.log.success(\"iii-engine is running\");\n await import(\"./index.js\");\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}\n\nasync function runStatus() {\n const port = getRestPort();\n const base = `http://localhost:${port}`;\n p.intro(\"agentmemory status\");\n\n const up = await isEngineRunning();\n if (!up) {\n p.log.error(`Not running — no response on port ${port}`);\n p.log.info(\"Start with: npx @agentmemory/agentmemory\");\n process.exit(1);\n }\n\n try {\n const [healthRes, sessionsRes, graphRes, memoriesRes] = await Promise.all([\n fetch(`${base}/agentmemory/health`, { signal: AbortSignal.timeout(5000) }).then((r) => r.json()).catch(() => null),\n fetch(`${base}/agentmemory/sessions`, { signal: AbortSignal.timeout(5000) }).then((r) => r.json()).catch(() => null),\n fetch(`${base}/agentmemory/graph/stats`, { signal: AbortSignal.timeout(5000) }).then((r) => r.json()).catch(() => null),\n fetch(`${base}/agentmemory/export`, { signal: AbortSignal.timeout(5000) }).then((r) => r.json()).catch(() => null),\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 = graphRes?.nodes || 0;\n const edges = graphRes?.edges || 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} on port ${port}`);\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: http://localhost:${port + 2}`,\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 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 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 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\nasync function runDemo() {\n const port = getRestPort();\n const base = `http://localhost:${port}`;\n p.intro(\"agentmemory demo\");\n\n if (!(await isEngineRunning())) {\n p.log.error(`Not running — no response on port ${port}`);\n p.log.info(\"Start the server first: 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: http://localhost:${port + 2}`,\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\nasync function runMcp(): Promise<void> {\n await import(\"./mcp/standalone.js\");\n}\n\nconst commands: Record<string, () => Promise<void>> = {\n status: runStatus,\n demo: runDemo,\n mcp: runMcp,\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;CACZ;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;;;;;AC7DjD,MAAM,YAAY,QAAQ,cAAc,OAAO,KAAK,IAAI,CAAC;AACzD,MAAM,OAAO,QAAQ,KAAK,MAAM,EAAE;AAClC,MAAM,aAAa,UAAU,KAAK;AAClC,MAAM,aAAa,KAAK,SAAS,YAAY,IAAI,KAAK,SAAS,KAAK;AAEpE,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;;;;;;;;;;;;;;;;;;;;;;;;EAwBZ;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;AAC7B,QAAO,SAAS,QAAQ,IAAI,oBAAoB,QAAQ,GAAG,IAAI;;AAGjE,eAAe,kBAAoC;AACjD,KAAI;AACF,QAAM,MAAM,oBAAoB,aAAa,CAAC,IAAI,EAChD,QAAQ,YAAY,QAAQ,IAAK,EAClC,CAAC;AACF,SAAO;SACD;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;AAMF,SALY,aAAa,KAAK,CAAC,KAAK,EAAE,EAAE,UAAU,SAAS,CAAC,CAEzD,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;;AASnE,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,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,MAAM,SAAS,SAAS,GAAG,mBAAmB;IACpD,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;;GAG5C;AACF,OAAM,OAAO;AACb,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,YAAY;EACxB,MAAM,IAAI,EAAE,SAAS;AACrB,IAAE,MAAM,wBAAwB,SAAS;AACzC,wBAAsB,QAAQ,CAAC,YAAY,WAAW,EAAE,aAAa;AACrE,IAAE,KAAK,6BAA6B;AACpC,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;AAE3D,KAAI,aAAa,aAAa;EAC5B,MAAM,IAAI,EAAE,SAAS;AACrB,IAAE,MAAM,oCAAoC;AAC5C,wBACE,WACA;GAAC;GAAW;GAAM;GAAa;GAAM;GAAK,EAC1C,wBACD;AACD,IAAE,KAAK,yBAAyB;AAChC,SAAO;;AAGT,MAAK,MAAM,WAAW,kBAAkB,CACtC,KAAI,WAAW,QAAQ,EAAE;AACvB,IAAE,IAAI,KAAK,iBAAiB,UAAU;AACtC,UAAQ,IAAI,UAAU,GAAG,QAAQ,QAAQ,GAAGA,YAAiB,QAAQ,IAAI,WAAW;AACpF,WAAS;AACT;;AAIJ,KAAI,UAAU,YAAY;EACxB,MAAM,IAAI,EAAE,SAAS;AACrB,IAAE,MAAM,wBAAwB,SAAS;AACzC,wBAAsB,QAAQ,CAAC,YAAY,WAAW,EAAE,aAAa;AACrE,IAAE,KAAK,6BAA6B;AACpC,SAAO;;AAGT,KAAI,CAAC,WAAW,CAAC,aAAa,CAAC,aAC7B,kBAAiB,EAAE,MAAM,aAAa;UAC7B,CAAC,eAAe,UACzB,kBAAiB,EAAE,MAAM,qBAAqB;AAEhD,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;AACvC,KAAI,WACF,QAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;AAEH,QAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;;AAGH,SAAS,oBAAoB,MAAsB;AACjD,QAAO,aACH,6BAA6B,SAC7B,cAAc,KAAK,4BAA4B;;AAGrD,eAAe,OAAO;AACpB,GAAE,MAAM,cAAc;AAEtB,KAAI,YAAY;AACd,IAAE,IAAI,KAAK,sCAAsC;AACjD,QAAM,OAAO;AACb;;AAGF,KAAI,MAAM,iBAAiB,EAAE;AAC3B,IAAE,IAAI,QAAQ,wBAAwB;AACtC,QAAM,OAAO;AACb;;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;;AAGf,eAAe,YAAY;CACzB,MAAM,OAAO,aAAa;CAC1B,MAAM,OAAO,oBAAoB;AACjC,GAAE,MAAM,qBAAqB;AAG7B,KAAI,CADO,MAAM,iBAAiB,EACzB;AACP,IAAE,IAAI,MAAM,qCAAqC,OAAO;AACxD,IAAE,IAAI,KAAK,2CAA2C;AACtD,UAAQ,KAAK,EAAE;;AAGjB,KAAI;EACF,MAAM,CAAC,WAAW,aAAa,UAAU,eAAe,MAAM,QAAQ,IAAI;GACxE,MAAM,GAAG,KAAK,sBAAsB,EAAE,QAAQ,YAAY,QAAQ,IAAK,EAAE,CAAC,CAAC,MAAM,MAAM,EAAE,MAAM,CAAC,CAAC,YAAY,KAAK;GAClH,MAAM,GAAG,KAAK,wBAAwB,EAAE,QAAQ,YAAY,QAAQ,IAAK,EAAE,CAAC,CAAC,MAAM,MAAM,EAAE,MAAM,CAAC,CAAC,YAAY,KAAK;GACpH,MAAM,GAAG,KAAK,2BAA2B,EAAE,QAAQ,YAAY,QAAQ,IAAK,EAAE,CAAC,CAAC,MAAM,MAAM,EAAE,MAAM,CAAC,CAAC,YAAY,KAAK;GACvH,MAAM,GAAG,KAAK,sBAAsB,EAAE,QAAQ,YAAY,QAAQ,IAAK,EAAE,CAAC,CAAC,MAAM,MAAM,EAAE,MAAM,CAAC,CAAC,YAAY,KAAK;GACnH,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,UAAU,SAAS;EACjC,MAAM,QAAQ,UAAU,SAAS;EACjC,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,WAAW,OAAO;EAExD,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,kCAAkC,OAAO;GAC1C;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,IAAE,KAAK,MAAM,KAAK,KAAK,EAAE,cAAc;UAChC,KAAK;AACZ,IAAE,IAAI,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,CAAC;AAC7D,UAAQ,KAAK,EAAE;;;AAkBnB,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,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;;AAGH,eAAe,UAAU;CACvB,MAAM,OAAO,aAAa;CAC1B,MAAM,OAAO,oBAAoB;AACjC,GAAE,MAAM,mBAAmB;AAE3B,KAAI,CAAE,MAAM,iBAAiB,EAAG;AAC9B,IAAE,IAAI,MAAM,qCAAqC,OAAO;AACxD,IAAE,IAAI,KAAK,uDAAuD;AAClE,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,mCAAmC,OAAO;EAC1C,kCAAkC,KAAK,gCAAgC,YAAY;EACpF;AAED,GAAE,KAAK,MAAM,KAAK,KAAK,EAAE,gBAAgB;AACzC,GAAE,IAAI,QAAQ,yEAAyE;;AAGzF,eAAe,SAAwB;AACrC,OAAM,OAAO;;CAGuC;CACpD,QAAQ;CACR,MAAM;CACN,KAAK;CACN,CAEwB,KAAK,MAAM,OAAO,OAClC,CAAC,OAAO,QAAQ;AACvB,GAAE,IAAI,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,CAAC;AAC7D,SAAQ,KAAK,EAAE;EACf"}
@@ -2,13 +2,13 @@ services:
2
2
  iii-engine:
3
3
  image: iiidev/iii:latest
4
4
  ports:
5
- - "49134:49134"
6
- - "3111:3111"
7
- - "3112:3112"
8
- - "9464:9464"
5
+ - "127.0.0.1:49134:49134"
6
+ - "127.0.0.1:3111:3111"
7
+ - "127.0.0.1:3112:3112"
8
+ - "127.0.0.1:9464:9464"
9
9
  volumes:
10
10
  - iii-data:/data
11
- - ./iii-config.yaml:/app/config.yaml:ro
11
+ - ./iii-config.docker.yaml:/app/config.yaml:ro
12
12
  restart: unless-stopped
13
13
 
14
14
  volumes:
@@ -0,0 +1,51 @@
1
+ modules:
2
+ - class: modules::state::StateModule
3
+ config:
4
+ adapter:
5
+ class: modules::state::adapters::KvStore
6
+ config:
7
+ store_method: file_based
8
+ file_path: ./data/state_store.db
9
+
10
+ - class: modules::api::RestApiModule
11
+ config:
12
+ port: 3111
13
+ host: 0.0.0.0
14
+ default_timeout: 180000
15
+ cors:
16
+ allowed_origins: ["http://localhost:3111", "http://localhost:3113", "http://127.0.0.1:3111", "http://127.0.0.1:3113"]
17
+ allowed_methods: [GET, POST, PUT, DELETE, OPTIONS]
18
+
19
+ - class: modules::queue::QueueModule
20
+ config:
21
+ adapter:
22
+ class: modules::queue::BuiltinQueueAdapter
23
+
24
+ - class: modules::pubsub::PubSubModule
25
+ config:
26
+ adapter:
27
+ class: modules::pubsub::LocalAdapter
28
+
29
+ - class: modules::cron::CronModule
30
+ config:
31
+ adapter:
32
+ class: modules::cron::KvCronAdapter
33
+
34
+ - class: modules::stream::StreamModule
35
+ config:
36
+ port: 3112
37
+ host: 0.0.0.0
38
+
39
+ - class: modules::observability::OtelModule
40
+ config:
41
+ enabled: true
42
+ service_name: agentmemory
43
+ exporter: memory
44
+ logs_enabled: true
45
+
46
+ - class: modules::shell::ExecModule
47
+ config:
48
+ watch:
49
+ - src/**/*.ts
50
+ exec:
51
+ - node dist/index.mjs
@@ -10,7 +10,7 @@ modules:
10
10
  - class: modules::api::RestApiModule
11
11
  config:
12
12
  port: 3111
13
- host: 0.0.0.0
13
+ host: 127.0.0.1
14
14
  default_timeout: 180000
15
15
  cors:
16
16
  allowed_origins: ["http://localhost:3111", "http://localhost:3113", "http://127.0.0.1:3111", "http://127.0.0.1:3113"]
@@ -34,7 +34,7 @@ modules:
34
34
  - class: modules::stream::StreamModule
35
35
  config:
36
36
  port: 3112
37
- host: 0.0.0.0
37
+ host: 127.0.0.1
38
38
 
39
39
  - class: modules::observability::OtelModule
40
40
  config: