remem-mcp 0.5.17

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/artifact.ts","../src/backup.ts","../src/cli/atoms.ts","../src/cli/demo.ts","../src/cli/extract.ts","../src/pipeline/atom.ts","../src/pipeline/llm.ts","../src/cli/knowledge.ts","../src/cli/persona.ts","../src/cli/scenarios.ts","../src/cli/skills.ts","../src/cli/status.ts","../src/config.ts","../src/doctor.ts","../src/errors.ts","../src/export.ts","../src/hook-handlers.ts","../src/hooks.ts","../src/import.ts","../src/install-mcp.ts","../src/install-skill.ts","../src/pipeline/noop.ts","../src/security/audit.ts","../src/server.ts","../src/security/quota.ts","../src/utils/tokenize.ts","../src/tools/format.ts","../src/stats.ts","../src/token-stats.ts","../src/viewer.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { existsSync, readFileSync, statSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport Database from \"better-sqlite3\";\nimport * as sqliteVec from \"sqlite-vec\";\nimport { exportArtifact, importArtifact } from \"./artifact.js\";\nimport { backup } from \"./backup.js\";\nimport { atomsCommand } from \"./cli/atoms.js\";\nimport { demo, demoCodegraph } from \"./cli/demo.js\";\nimport { extractCommand } from \"./cli/extract.js\";\nimport { knowledgeCommand } from \"./cli/knowledge.js\";\nimport { personaCommand } from \"./cli/persona.js\";\nimport { scenariosCommand } from \"./cli/scenarios.js\";\nimport { skillsCommand } from \"./cli/skills.js\";\nimport { status } from \"./cli/status.js\";\nimport {\n findCallees,\n findCallers,\n impactAnalysis,\n indexDirectory,\n listSymbols,\n searchSymbols,\n} from \"./codegraph/engine.js\";\nimport { loadConfig } from \"./config.js\";\nimport { doctor } from \"./doctor.js\";\nimport { LocalEmbedder } from \"./embedding/local.js\";\nimport {\n decisionsConflicts,\n decisionsDashboard,\n decisionsInherited,\n decisionsRetro,\n errorsActions,\n errorsByGoal,\n errors as errorsCommand,\n errorsContext,\n errorsCorrelations,\n errorsDrift,\n errorsEscalations,\n errorsInherited,\n errorsLineage,\n errorsPersona,\n errorsPlaybooks,\n errorsProvenance,\n errorsRetro,\n errorsSeverity,\n errorsStale,\n errorsTemplates,\n patternsConflicts,\n patternsDashboard,\n patternsInherited,\n patternsRetro,\n patternsTemplates,\n} from \"./errors.js\";\nimport { exportData } from \"./export.js\";\nimport {\n hookPostCommit,\n hookPostCompaction,\n hookPostToolUse,\n hookPreCompact,\n hookPreToolUse,\n hookRecall,\n hookSessionEnd,\n hookStop,\n waitAndCapture,\n} from \"./hook-handlers.js\";\nimport { installHooks, uninstallHooks } from \"./hooks.js\";\nimport { importData } from \"./import.js\";\nimport { installMcpServer } from \"./install-mcp.js\";\nimport { installSkill } from \"./install-skill.js\";\nimport { AtomPipeline, RuleBasedAtomPipeline } from \"./pipeline/atom.js\";\nimport { OpenAILLMClient } from \"./pipeline/llm.js\";\nimport { NoopPipeline } from \"./pipeline/noop.js\";\nimport type { PipelineStage } from \"./pipeline/types.js\";\nimport { AuditLogger } from \"./security/audit.js\";\nimport { createServer } from \"./server.js\";\nimport { stats } from \"./stats.js\";\nimport { SQLiteBackend } from \"./storage/sqlite.js\";\nimport { tokenStats } from \"./token-stats.js\";\nimport { startViewer } from \"./viewer.js\";\nimport { findOutdatedPages, ingestDirectory, searchWiki } from \"./wiki/engine.js\";\n\n/** Default DB path. */\nfunction defaultDbPath(): string {\n return (\n process.env.TDAI_DB_PATH ?? join(homedir(), \".local\", \"share\", \"remem-mcp\", \"memory.db\")\n );\n}\n\n/** Open a DB with schema loaded (for CLI commands that need CodeGraph/Wiki tables). */\nfunction openDbWithSchema(dbPath: string): Database.Database {\n const db = new Database(dbPath);\n db.pragma(\"journal_mode = WAL\");\n db.pragma(\"foreign_keys = OFF\");\n sqliteVec.load(db);\n // Load schema if tables don't exist\n const hasSymbols = db\n .prepare(\"SELECT name FROM sqlite_master WHERE type='table' AND name='symbols'\")\n .get();\n if (!hasSymbols) {\n const distDir = dirname(fileURLToPath(import.meta.url));\n const candidates = [\n join(distDir, \"storage\", \"schema.sql\"),\n join(distDir, \"schema.sql\"),\n join(process.cwd(), \"src\", \"storage\", \"schema.sql\"),\n ];\n for (const p of candidates) {\n try {\n db.exec(readFileSync(p, \"utf-8\"));\n break;\n } catch {\n // try next candidate\n }\n }\n }\n return db;\n}\n\n/** Parse --flag value pairs from argv after the subcommand. */\nfunction parseFlags(argv: string[]): Record<string, string> {\n const flags: Record<string, string> = {};\n for (let i = 0; i < argv.length; i++) {\n if (argv[i]?.startsWith(\"--\") && argv[i + 1]) {\n flags[argv[i].slice(2)] = argv[i + 1];\n i++;\n }\n }\n return flags;\n}\n\n// ─── Bootstrap detection helpers ──────────────────────────────\n\n/** Detect package manager from lockfiles in cwd. */\nfunction detectPackageManager(): string | null {\n const cwd = process.cwd();\n if (existsSync(join(cwd, \"pnpm-lock.yaml\"))) return \"pnpm\";\n if (existsSync(join(cwd, \"bun.lockb\")) || existsSync(join(cwd, \"bun.lock\"))) return \"bun\";\n if (existsSync(join(cwd, \"yarn.lock\"))) return \"yarn\";\n if (existsSync(join(cwd, \"package-lock.json\"))) return \"npm\";\n if (existsSync(join(cwd, \"Cargo.toml\"))) return \"cargo\";\n if (existsSync(join(cwd, \"go.mod\"))) return \"go\";\n if (existsSync(join(cwd, \"pom.xml\")) || existsSync(join(cwd, \"build.gradle\"))) return \"maven\";\n if (existsSync(join(cwd, \"build.gradle.kts\"))) return \"gradle\";\n if (existsSync(join(cwd, \"Gemfile\"))) return \"bundle\";\n if (existsSync(join(cwd, \"requirements.txt\")) || existsSync(join(cwd, \"pyproject.toml\")))\n return \"pip\";\n return null;\n}\n\n/** Detect key scripts from package.json (limited to important ones). */\nfunction detectPackageScripts(): Record<string, string> {\n const cwd = process.cwd();\n const pkgPath = join(cwd, \"package.json\");\n if (!existsSync(pkgPath)) return {};\n try {\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\"));\n const scripts = pkg.scripts ?? {};\n const important: Record<string, string> = {};\n for (const key of [\"build\", \"test\", \"lint\", \"format\", \"dev\", \"start\", \"typecheck\", \"check\"]) {\n if (scripts[key]) important[key] = scripts[key];\n }\n return important;\n } catch {\n return {};\n }\n}\n\n/** Detect framework from dependencies. */\nfunction detectFramework(): string | null {\n const cwd = process.cwd();\n const pkgPath = join(cwd, \"package.json\");\n if (!existsSync(pkgPath)) {\n // Non-JS frameworks\n if (existsSync(join(cwd, \"Cargo.toml\"))) return \"Rust\";\n if (existsSync(join(cwd, \"go.mod\"))) return \"Go\";\n return null;\n }\n try {\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\"));\n const deps = { ...(pkg.dependencies ?? {}), ...(pkg.devDependencies ?? {}) };\n if (deps[\"next\"]) return \"Next.js\";\n if (deps[\"react-scripts\"]) return \"Create React App\";\n if (deps[\"react\"] && deps[\"vite\"]) return \"React + Vite\";\n if (deps[\"react\"]) return \"React\";\n if (deps[\"vue\"]) return \"Vue\";\n if (deps[\"svelte\"] || deps[\"@sveltejs/kit\"]) return \"Svelte\";\n if (deps[\"astro\"]) return \"Astro\";\n if (deps[\"nuxt\"]) return \"Nuxt\";\n if (deps[\"@angular/core\"]) return \"Angular\";\n if (deps[\"express\"]) return \"Express\";\n if (deps[\"hono\"]) return \"Hono\";\n if (deps[\"fastify\"]) return \"Fastify\";\n if (deps[\"nestjs\"] || deps[\"@nestjs/core\"]) return \"NestJS\";\n if (deps[\"h3\"]) return \"h3\";\n return null;\n } catch {\n return null;\n }\n}\n\n/** Detect lint/format tool from dependencies or config files. */\nfunction detectLintTool(): string | null {\n const cwd = process.cwd();\n const pkgPath = join(cwd, \"package.json\");\n if (existsSync(pkgPath)) {\n try {\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\"));\n const deps = { ...(pkg.dependencies ?? {}), ...(pkg.devDependencies ?? {}) };\n if (deps[\"biome\"]) return \"Biome\";\n if (deps[\"eslint\"]) return \"ESLint\";\n if (deps[\"dprint\"]) return \"dprint\";\n if (deps[\"prettier\"]) return \"Prettier\";\n if (deps[\"@biomejs/biome\"]) return \"Biome\";\n } catch {\n // fall through\n }\n }\n if (existsSync(join(cwd, \"biome.json\")) || existsSync(join(cwd, \"biome.jsonc\"))) return \"Biome\";\n if (\n existsSync(join(cwd, \".eslintrc\")) ||\n existsSync(join(cwd, \".eslintrc.js\")) ||\n existsSync(join(cwd, \".eslintrc.json\")) ||\n existsSync(join(cwd, \"eslint.config.js\")) ||\n existsSync(join(cwd, \"eslint.config.mjs\"))\n )\n return \"ESLint\";\n if (existsSync(join(cwd, \".prettierrc\")) || existsSync(join(cwd, \".prettierrc.json\")))\n return \"Prettier\";\n if (existsSync(join(cwd, \"rustfmt.toml\"))) return \"rustfmt\";\n if (existsSync(join(cwd, \".gofmt\"))) return \"gofmt\";\n return null;\n}\n\n/** Detect test command. */\nfunction detectTestCommand(pkgManager: string | null): string | null {\n const cwd = process.cwd();\n const pm = pkgManager ?? \"npm\";\n\n // JS: check package.json scripts\n const pkgPath = join(cwd, \"package.json\");\n if (existsSync(pkgPath)) {\n try {\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\"));\n const scripts = pkg.scripts ?? {};\n if (scripts.test && scripts.test !== 'echo \"Error: no test specified\" && exit 1') {\n return `${pm} run test`;\n }\n if (scripts.vitest) return `${pm} run vitest`;\n if (scripts.jest) return `${pm} run jest`;\n // vitest/jest in deps but no script\n const deps = { ...(pkg.dependencies ?? {}), ...(pkg.devDependencies ?? {}) };\n if (deps[\"vitest\"]) return `${pm} exec vitest run`;\n if (deps[\"jest\"]) return `${pm} exec jest`;\n } catch {\n // fall through\n }\n }\n\n // Other ecosystems\n if (existsSync(join(cwd, \"Cargo.toml\"))) return \"cargo test\";\n if (existsSync(join(cwd, \"go.mod\"))) return \"go test ./...\";\n if (existsSync(join(cwd, \"pytest.ini\")) || existsSync(join(cwd, \"pyproject.toml\")))\n return \"pytest\";\n if (existsSync(join(cwd, \"Gemfile\"))) return \"bundle exec rspec\";\n return null;\n}\n\nasync function main(): Promise<void> {\n const arg = process.argv[2];\n if (arg === \"install-skill\") {\n await installSkill();\n return;\n }\n if (arg === \"install-hooks\") {\n await installHooks();\n return;\n }\n if (arg === \"setup\") {\n console.log(\"remem-mcp setup\\n\");\n console.log(\"This will register the MCP server, install hooks, and capture project basics.\\n\");\n await installMcpServer();\n console.log(\"\");\n await installHooks();\n console.log(\"\\nCapturing project basics...\");\n const { Memory } = await import(\"./sdk.js\");\n const mem = new Memory();\n const sessionKey = process.cwd();\n let captured = 0;\n\n // Detect package manager\n const pkgManager = detectPackageManager();\n if (pkgManager) {\n const id = await mem.capture(\n `This project uses ${pkgManager}. Use ${pkgManager} for all package operations (install, run, etc.).`,\n \"decision\",\n [\"bootstrap\", \"package-manager\", pkgManager],\n { sessionKey },\n );\n if (id) captured++;\n }\n\n // Detect scripts from package.json\n const scripts = detectPackageScripts();\n for (const [name, cmd] of Object.entries(scripts)) {\n const id = await mem.capture(\n `Project script: \\`${pkgManager ? pkgManager + \" run \" : \"npm run \"}${name}\\` runs: ${cmd}`,\n \"decision\",\n [\"bootstrap\", \"script\", name],\n { sessionKey },\n );\n if (id) captured++;\n }\n\n // Detect framework\n const framework = detectFramework();\n if (framework) {\n const id = await mem.capture(\n `This project uses ${framework}. Follow ${framework} conventions and patterns.`,\n \"decision\",\n [\"bootstrap\", \"framework\", framework.toLowerCase()],\n { sessionKey },\n );\n if (id) captured++;\n }\n\n // Detect lint/format tool\n const lintTool = detectLintTool();\n if (lintTool) {\n const id = await mem.capture(\n `This project uses ${lintTool} for linting/formatting. Run it before committing.`,\n \"decision\",\n [\"bootstrap\", \"lint\", lintTool.toLowerCase()],\n { sessionKey },\n );\n if (id) captured++;\n }\n\n // Test command\n const testCmd = detectTestCommand(pkgManager);\n if (testCmd) {\n const id = await mem.capture(\n `Run tests with: \\`${testCmd}\\``,\n \"decision\",\n [\"bootstrap\", \"test\"],\n { sessionKey },\n );\n if (id) captured++;\n }\n\n if (captured > 0) {\n console.log(\n ` Captured ${captured} project basics (package manager, scripts, framework, lint, test).`,\n );\n console.log(\" These will be injected into your next agent session automatically.\");\n } else {\n console.log(\n \" No project files detected (package.json, Cargo.toml, etc.). Skipping bootstrap.\",\n );\n // Fallback to test capture\n const id = await mem.capture(\n \"remem-mcp setup completed. This is a test capture.\",\n \"task\",\n [\"setup\", \"test\"],\n );\n if (id) console.log(`Test capture saved: ${id}`);\n }\n\n console.log(\"\\n✓ Setup complete.\");\n console.log(\"\\nNext steps:\");\n console.log(\" 1. Restart your agent (close and reopen the session)\");\n console.log(\" 2. On restart, SessionStart hook loads project basics automatically\");\n console.log(\" 3. Run `npx remem-mcp status` anytime to see your memory\");\n console.log(\"\\nOptional: `npx remem-mcp install-skill` teaches your agent\");\n console.log(\"when to recall/capture mid-session (adds ~4K tokens to context).\");\n console.log(\"\\n─ Demo ─────────────────────────────────────────────────\");\n await demo();\n return;\n }\n if (arg === \"uninstall-hooks\") {\n await uninstallHooks();\n return;\n }\n if (arg === \"doctor\") {\n await doctor();\n return;\n }\n if (arg === \"demo\") {\n await demo();\n return;\n }\n if (arg === \"demo-codegraph\") {\n await demoCodegraph();\n return;\n }\n if (arg === \"status\") {\n status(defaultDbPath());\n return;\n }\n if (arg === \"recent\" || arg === \"list\") {\n const limit = parseInt(process.argv[3] ?? \"20\", 10);\n const db = new Database(defaultDbPath(), { readonly: true });\n const rows = db\n .prepare(\n `SELECT id, type, content, tags, created_at FROM captures WHERE deleted_at IS NULL ORDER BY created_at DESC LIMIT ?`,\n )\n .all(limit) as {\n id: string;\n type: string;\n content: string;\n tags: string;\n created_at: number;\n }[];\n if (rows.length === 0) {\n console.log(\"No captures found.\");\n } else {\n for (const r of rows) {\n const date = new Date(r.created_at).toISOString().split(\"T\")[0];\n const tags = r.tags ? ` [${JSON.parse(r.tags).join(\", \")}]` : \"\";\n const preview = r.content.slice(0, 80).replace(/\\n/g, \" \");\n console.log(\n `${date} ${r.id} ${r.type}${tags} ${preview}${r.content.length > 80 ? \"...\" : \"\"}`,\n );\n }\n console.log(`\\n${rows.length} capture(s).`);\n }\n db.close();\n return;\n }\n if (arg === \"stats\") {\n const db = openDbWithSchema(defaultDbPath());\n const byType = db\n .prepare(\n \"SELECT type, COUNT(*) as cnt FROM captures WHERE deleted_at IS NULL GROUP BY type ORDER BY cnt DESC\",\n )\n .all() as { type: string; cnt: number }[];\n const total = byType.reduce((s, r) => s + r.cnt, 0);\n const byTrust = db\n .prepare(\n \"SELECT trust_state, COUNT(*) as cnt FROM captures WHERE deleted_at IS NULL GROUP BY trust_state\",\n )\n .all() as { trust_state: string; cnt: number }[];\n const withVectors = db\n .prepare(\n \"SELECT COUNT(*) as cnt FROM captures_vec WHERE id IN (SELECT id FROM captures WHERE deleted_at IS NULL)\",\n )\n .get() as { cnt: number };\n const oldest = db\n .prepare(\"SELECT MIN(created_at) as ts FROM captures WHERE deleted_at IS NULL\")\n .get() as { ts: number | null };\n const newest = db\n .prepare(\"SELECT MAX(created_at) as ts FROM captures WHERE deleted_at IS NULL\")\n .get() as { ts: number | null };\n const dbSize = statSync(defaultDbPath()).size;\n\n console.log(\"remem-mcp stats\\n\");\n console.log(` Total captures: ${total}`);\n console.log(\n ` With vectors: ${withVectors.cnt} (${total > 0 ? Math.round((withVectors.cnt / total) * 100) : 0}%)`,\n );\n console.log(` DB size: ${(dbSize / 1024 / 1024).toFixed(1)} MB`);\n if (oldest.ts)\n console.log(` Oldest: ${new Date(oldest.ts).toISOString().split(\"T\")[0]}`);\n if (newest.ts)\n console.log(` Newest: ${new Date(newest.ts).toISOString().split(\"T\")[0]}`);\n console.log(\"\\n By type:\");\n for (const r of byType) {\n console.log(` ${r.type.padEnd(15)} ${r.cnt}`);\n }\n console.log(\"\\n By trust state:\");\n for (const r of byTrust) {\n console.log(` ${r.trust_state.padEnd(15)} ${r.cnt}`);\n }\n db.close();\n return;\n }\n if (arg === \"export\") {\n const dbPath = defaultDbPath();\n const output = process.argv[3] ?? \"-\";\n\n const filters: { sessionKey?: string; type?: string } = {};\n for (let i = 3; i < process.argv.length; i++) {\n if (process.argv[i] === \"--session-key\" && process.argv[i + 1]) {\n filters.sessionKey = process.argv[i + 1];\n i++;\n }\n if (process.argv[i] === \"--type\" && process.argv[i + 1]) {\n filters.type = process.argv[i + 1];\n i++;\n }\n }\n\n exportData(dbPath, output, Object.keys(filters).length > 0 ? filters : undefined);\n return;\n }\n if (arg === \"import\") {\n const dbPath = defaultDbPath();\n const input = process.argv[3];\n if (!input) {\n console.error(\"Error: Provide a file path. Usage: remem-mcp import <file.json>\");\n process.exit(1);\n }\n importData(dbPath, input);\n return;\n }\n if (arg === \"stats\") {\n stats(defaultDbPath());\n return;\n }\n if (arg === \"errors\") {\n const sub = process.argv[3];\n if (sub === \"retro\") {\n errorsRetro(defaultDbPath());\n return;\n }\n if (sub === \"drift\") {\n errorsDrift(defaultDbPath());\n return;\n }\n if (sub === \"lineage\") {\n errorsLineage(defaultDbPath());\n return;\n }\n if (sub === \"by-goal\") {\n errorsByGoal(defaultDbPath());\n return;\n }\n if (sub === \"actions\") {\n errorsActions(defaultDbPath());\n return;\n }\n if (sub === \"severity\") {\n errorsSeverity(defaultDbPath());\n return;\n }\n if (sub === \"templates\") {\n errorsTemplates(defaultDbPath());\n return;\n }\n if (sub === \"correlations\") {\n errorsCorrelations(defaultDbPath());\n return;\n }\n if (sub === \"playbooks\") {\n errorsPlaybooks(defaultDbPath());\n return;\n }\n if (sub === \"stale\") {\n errorsStale(defaultDbPath());\n return;\n }\n if (sub === \"escalations\") {\n errorsEscalations(defaultDbPath());\n return;\n }\n if (sub === \"context\") {\n errorsContext(defaultDbPath());\n return;\n }\n if (sub === \"inherited\") {\n errorsInherited(defaultDbPath());\n return;\n }\n if (sub === \"provenance\") {\n errorsProvenance(defaultDbPath());\n return;\n }\n if (sub === \"persona\") {\n errorsPersona(defaultDbPath());\n return;\n }\n errorsCommand(defaultDbPath());\n return;\n }\n if (arg === \"decisions\") {\n const sub = process.argv[3] ?? \"\";\n if (sub === \"retro\") {\n decisionsRetro(defaultDbPath());\n return;\n }\n if (sub === \"conflicts\") {\n decisionsConflicts(defaultDbPath());\n return;\n }\n if (sub === \"inherited\") {\n decisionsInherited(defaultDbPath());\n return;\n }\n decisionsDashboard(defaultDbPath());\n return;\n }\n if (arg === \"patterns\") {\n const sub = process.argv[3] ?? \"\";\n if (sub === \"retro\") {\n patternsRetro(defaultDbPath());\n return;\n }\n if (sub === \"conflicts\") {\n patternsConflicts(defaultDbPath());\n return;\n }\n if (sub === \"templates\") {\n patternsTemplates(defaultDbPath());\n return;\n }\n if (sub === \"inherited\") {\n patternsInherited(defaultDbPath());\n return;\n }\n patternsDashboard(defaultDbPath());\n return;\n }\n if (arg === \"token-stats\") {\n tokenStats(defaultDbPath());\n return;\n }\n if (arg === \"verify\") {\n const query = process.argv.slice(3).join(\" \") || \"project setup conventions\";\n await verifyMemory(defaultDbPath(), query);\n return;\n }\n if (arg === \"viewer\") {\n const port = Number(process.argv[4] ?? process.env.TDAI_VIEWER_PORT ?? 7331);\n startViewer(defaultDbPath(), port);\n return;\n }\n if (arg === \"backup\") {\n const dbPath = defaultDbPath();\n const auditPath = process.env.TDAI_AUDIT_LOG_PATH ?? join(dirname(dbPath), \"audit.jsonl\");\n const outputDir = process.argv[3] ?? \"-\";\n backup(dbPath, auditPath, outputDir);\n return;\n }\n if (arg === \"sync-export\") {\n const dbPath = defaultDbPath();\n const projectRoot = process.cwd();\n const sessionKey = process.argv[4] ?? undefined;\n exportArtifact(dbPath, projectRoot, sessionKey);\n return;\n }\n if (arg === \"sync-import\") {\n const dbPath = defaultDbPath();\n const projectRoot = process.cwd();\n const count = importArtifact(dbPath, projectRoot);\n if (count === 0) {\n console.log(\"No team artifact found. Run 'remem-mcp sync-export' to create one.\");\n }\n return;\n }\n if (arg === \"hook-recall\") {\n hookRecall(defaultDbPath());\n return;\n }\n if (arg === \"hook-stop\") {\n hookStop(defaultDbPath());\n return;\n }\n if (arg === \"--wait-and-capture\") {\n // Internal: spawned by hook-stop to capture transcript after Devin CLI writes it.\n // Args: node dist/index.js --wait-and-capture <dbPath> <sessionId> [transcriptPath]\n const dbPath = process.argv[3] ?? defaultDbPath();\n const sessionId = process.argv[4] ?? \"unknown\";\n const transcriptPath = process.argv[5] || null;\n await waitAndCapture(dbPath, sessionId, transcriptPath);\n return;\n }\n if (arg === \"hook-session-end\") {\n hookSessionEnd(defaultDbPath());\n return;\n }\n if (arg === \"hook-post-commit\") {\n await hookPostCommit(defaultDbPath());\n return;\n }\n if (arg === \"hook-post-tool-use\") {\n hookPostToolUse(defaultDbPath());\n return;\n }\n if (arg === \"hook-pre-tool-use\") {\n hookPreToolUse(defaultDbPath());\n return;\n }\n if (arg === \"hook-pre-compact\") {\n hookPreCompact(defaultDbPath());\n return;\n }\n if (arg === \"hook-post-compaction\") {\n hookPostCompaction(defaultDbPath());\n return;\n }\n\n // ─── CodeGraph CLI commands ──────────────────────────────────\n if (arg === \"index\") {\n const flags = parseFlags(process.argv.slice(3));\n const path = flags.path ?? flags.p ?? process.cwd();\n const repoPath = flags.repo ?? flags.r ?? path;\n const teamId = flags.team ?? flags.t ?? null;\n const maxFiles = Number(flags[\"max-files\"] ?? 10000);\n const db = openDbWithSchema(defaultDbPath());\n console.log(`Indexing ${path} ...`);\n const results = await indexDirectory(db, path, repoPath, teamId, maxFiles);\n const indexed = results.filter((r) => !r.skipped);\n const totalSyms = indexed.reduce((s, r) => s + r.symbols, 0);\n const totalCalls = indexed.reduce((s, r) => s + r.calls, 0);\n console.log(`Done: ${indexed.length} files, ${totalSyms} symbols, ${totalCalls} calls`);\n for (const r of indexed.slice(0, 20)) {\n console.log(` ${r.language.padEnd(12)} ${r.symbols} sym ${r.calls} calls ${r.file}`);\n }\n if (indexed.length > 20) console.log(` ... and ${indexed.length - 20} more`);\n db.close();\n return;\n }\n if (arg === \"search-code\") {\n const flags = parseFlags(process.argv.slice(3));\n const query = flags.query ?? flags.q ?? process.argv[3];\n const teamId = flags.team ?? flags.t ?? undefined;\n const limit = Number(flags.limit ?? 20);\n const repoPath = flags.repo ?? flags.r ?? process.cwd();\n if (!query) {\n console.error(\"Usage: search-code --query <name> [--limit N] [--repo .]\");\n return;\n }\n const db = openDbWithSchema(defaultDbPath());\n const syms = searchSymbols(db, query, { teamId, limit, repoPath });\n if (syms.length === 0) {\n console.log(\"No symbols found.\");\n db.close();\n return;\n }\n for (const s of syms) {\n console.log(`${s.id} ${s.kind.padEnd(10)} ${s.name} at ${s.filePath}:${s.lineStart}`);\n }\n db.close();\n return;\n }\n if (arg === \"callers\") {\n const symbolId = process.argv[3];\n if (!symbolId) {\n console.error(\"Usage: callers <symbol_id>\");\n return;\n }\n const db = openDbWithSchema(defaultDbPath());\n const callers = findCallers(db, symbolId);\n if (callers.length === 0) {\n console.log(\"No callers found.\");\n db.close();\n return;\n }\n for (const c of callers) {\n console.log(`${c.caller.kind} ${c.caller.name} at ${c.caller.filePath}:${c.line}`);\n }\n db.close();\n return;\n }\n if (arg === \"callees\") {\n const symbolId = process.argv[3];\n if (!symbolId) {\n console.error(\"Usage: callees <symbol_id>\");\n return;\n }\n const db = openDbWithSchema(defaultDbPath());\n const callees = findCallees(db, symbolId);\n if (callees.length === 0) {\n console.log(\"No callees found.\");\n db.close();\n return;\n }\n for (const c of callees) {\n if (c.callee) {\n console.log(\n `${c.callee.kind} ${c.callee.name} at ${c.callee.filePath}:${c.callee.lineStart}`,\n );\n } else {\n console.log(`${c.calleeName} (unresolved)`);\n }\n }\n db.close();\n return;\n }\n if (arg === \"impact\") {\n const symbolId = process.argv[3];\n if (!symbolId) {\n console.error(\"Usage: impact <symbol_id> [--max-depth N]\");\n return;\n }\n const flags = parseFlags(process.argv.slice(4));\n const maxDepth = Number(flags[\"max-depth\"] ?? 5);\n const db = openDbWithSchema(defaultDbPath());\n const impact = impactAnalysis(db, symbolId, { maxDepth });\n console.log(\n `Root: ${impact.rootSymbol.kind} ${impact.rootSymbol.name} at ${impact.rootSymbol.filePath}:${impact.rootSymbol.lineStart}`,\n );\n console.log(`Affected: ${impact.affected.length} symbol(s)`);\n for (const a of impact.affected) {\n console.log(\n `${\" \".repeat(a.depth)}-> ${a.symbol.kind} ${a.symbol.name} at ${a.symbol.filePath}:${a.symbol.lineStart} (depth ${a.depth})`,\n );\n }\n db.close();\n return;\n }\n if (arg === \"list-code\") {\n const flags = parseFlags(process.argv.slice(3));\n const filePath = flags.file ?? flags.f ?? process.argv[3];\n const repoPath = flags.repo ?? flags.r ?? process.cwd();\n if (!filePath) {\n console.error(\"Usage: list-code <file_path> [--repo .]\");\n return;\n }\n const db = openDbWithSchema(defaultDbPath());\n const syms = listSymbols(db, filePath, { repoPath });\n if (syms.length === 0) {\n console.log(\"No symbols found.\");\n db.close();\n return;\n }\n for (const s of syms) {\n console.log(`${s.kind.padEnd(10)} L${s.lineStart}-${s.lineEnd} ${s.name}`);\n }\n db.close();\n return;\n }\n\n // ─── Wiki CLI commands ───────────────────────────────────────\n if (arg === \"wiki\") {\n const sub = process.argv[3];\n if (sub === \"ingest\") {\n const flags = parseFlags(process.argv.slice(4));\n const path = flags.path ?? flags.p ?? process.cwd();\n const repoPath = flags.repo ?? flags.r ?? path;\n const teamId = flags.team ?? flags.t ?? null;\n const db = openDbWithSchema(defaultDbPath());\n console.log(`Ingesting markdown from ${path} ...`);\n const results = ingestDirectory(db, path, repoPath, teamId, 200);\n const ingested = results.filter((r) => !r.skipped);\n const totalPages = ingested.reduce((s, r) => s + r.pages, 0);\n const totalLinks = ingested.reduce((s, r) => s + r.links, 0);\n console.log(`Done: ${totalPages} pages, ${totalLinks} links from ${ingested.length} files`);\n for (const r of ingested.slice(0, 20)) {\n console.log(` ${r.pages} page ${r.links} links ${r.file}`);\n }\n db.close();\n return;\n }\n if (sub === \"search\") {\n const query = process.argv[4];\n if (!query) {\n console.error(\"Usage: wiki search <query>\");\n return;\n }\n const db = openDbWithSchema(defaultDbPath());\n const results = searchWiki(db, query);\n if (results.length === 0) {\n console.log(\"No pages found.\");\n db.close();\n return;\n }\n for (const r of results) {\n console.log(`${r.id} ${r.title} (${r.sourceFile})`);\n console.log(` ${r.snippet}`);\n }\n db.close();\n return;\n }\n if (sub === \"outdated\") {\n const repoPath = process.argv[4] ?? process.cwd();\n const db = openDbWithSchema(defaultDbPath());\n const outdated = findOutdatedPages(db, repoPath, {});\n if (outdated.length === 0) {\n console.log(\"All pages up to date.\");\n db.close();\n return;\n }\n for (const o of outdated) {\n console.log(`${o.title} (${o.sourceFile}) — ${o.reason}`);\n }\n db.close();\n return;\n }\n console.error(\"Usage: wiki <ingest|search|outdated> [args]\");\n return;\n }\n\n // ─── L1-L3 CLI commands ──────────────────────────────────────\n if (arg === \"atoms\") {\n const flags = parseFlags(process.argv.slice(3));\n await atomsCommand(defaultDbPath(), flags);\n return;\n }\n if (arg === \"scenarios\") {\n const flags = parseFlags(process.argv.slice(3));\n await scenariosCommand(defaultDbPath(), flags);\n return;\n }\n if (arg === \"persona\") {\n const flags = parseFlags(process.argv.slice(3));\n await personaCommand(defaultDbPath(), flags);\n return;\n }\n if (arg === \"extract\") {\n const flags = parseFlags(process.argv.slice(3));\n await extractCommand(defaultDbPath(), flags);\n return;\n }\n if (arg === \"knowledge\") {\n const flags = parseFlags(process.argv.slice(3));\n await knowledgeCommand(defaultDbPath(), flags);\n return;\n }\n if (arg === \"skills\") {\n const flags = parseFlags(process.argv.slice(3));\n await skillsCommand(defaultDbPath(), flags);\n return;\n }\n\n if (arg === \"version\" || arg === \"--version\" || arg === \"-v\") {\n try {\n const pkgPath = join(dirname(fileURLToPath(import.meta.url)), \"..\", \"package.json\");\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\"));\n console.log(`remem-mcp v${pkg.version}`);\n } catch {\n console.log(\"remem-mcp (version unknown)\");\n }\n return;\n }\n if (arg === \"help\" || arg === \"--help\" || arg === \"-h\") {\n const showAll = process.argv[3] === \"all\";\n console.log(`remem-mcp - Local-first MCP memory server\n\nGetting started:\n remem-mcp setup One-command install (MCP + hooks + demo)\n remem-mcp demo Watch the error learning loop (30s)\n remem-mcp demo-codegraph Live CodeGraph demo on facebook/react\n remem-mcp status One dashboard: health + all 3 loops + recent\n remem-mcp viewer Web UI at localhost:7331\n remem-mcp doctor Check setup health\n remem-mcp version Print version\n\nDaily use:\n remem-mcp errors Error learning dashboard\n remem-mcp decisions Decision learning dashboard\n remem-mcp patterns Pattern learning dashboard\n remem-mcp recent [N] Show N most recent captures\n\n Run \\`remem-mcp help all\\` for the full list of 40+ subcommands.\n`);\n if (!showAll) {\n console.log(`The server runs as a stdio process. Add it to your MCP client:\n Claude Code: ~/.claude.json\n Cursor: ~/.cursor/mcp.json\n Devin CLI: devin mcp add remem-mcp -- npx -y remem-mcp\n`);\n return;\n }\n\n // Full help (only with `help all`)\n console.log(`Full command list:\n${\"─\".repeat(60)}\n\nSetup & maintenance:\n remem-mcp Start the MCP server (stdio)\n remem-mcp setup Install MCP + hooks + run demo (one command)\n remem-mcp install-skill Install the agent skill for Devin CLI\n remem-mcp install-hooks Install lifecycle hooks (SessionStart, Stop, SessionEnd)\n remem-mcp uninstall-hooks Remove lifecycle hooks\n remem-mcp hook-post-commit Auto-index changed files (git post-commit hook)\n remem-mcp doctor Check setup health\n remem-mcp demo Run end-to-end learning loop demo (30s)\n remem-mcp status Unified dashboard (health + 3 loops + recent)\n\nError learning (deep loop, 41 features):\n remem-mcp errors Error dashboard (patterns, fixes, resolution rate)\n remem-mcp errors retro Session retrospective (failure loops, wasted effort)\n remem-mcp errors drift Drift: injected warnings that were ignored\n remem-mcp errors lineage Fix lineage chains: E1→F1→E2→F2\n remem-mcp errors by-goal Error distribution by goal (set TDAI_GOAL_ID)\n remem-mcp errors actions Action items from resolved errors\n remem-mcp errors severity Severity distribution (blocker/critical/major/minor)\n remem-mcp errors templates Fix templates from 3+ similar resolved errors\n remem-mcp errors correlations Sequential error patterns (E1→E2 within 10 min)\n remem-mcp errors playbooks Recovery playbooks (step-by-step)\n remem-mcp errors stale Fix staleness (older than TDAI_FIX_STALENESS_DAYS)\n remem-mcp errors escalations Auto-escalated errors (3+ recurrences)\n remem-mcp errors context Error context (git branch, commits, changed files)\n remem-mcp errors inherited Cross-project fix inheritance\n remem-mcp errors provenance Fix provenance chain\n remem-mcp errors persona Error profile per project\n\nDecision learning (foundational loop):\n remem-mcp decisions Decision dashboard\n remem-mcp decisions retro Decision retrospective (follow rate, drift)\n remem-mcp decisions conflicts Contradictory dependency choices\n remem-mcp decisions inherited Cross-project decision inheritance\n\nPattern learning (foundational loop):\n remem-mcp patterns Pattern dashboard\n remem-mcp patterns retro Pattern retrospective (adoption rate)\n remem-mcp patterns conflicts Inconsistent style conflicts (CommonJS vs ESM)\n remem-mcp patterns templates Reusable templates from 3+ similar patterns\n remem-mcp patterns inherited Cross-project pattern inheritance\n\nCodeGraph:\n remem-mcp index [--path src] [--repo .] Index code symbols (Tree-sitter)\n remem-mcp search-code --query <name> Search symbols by name\n remem-mcp callers <symbol_id> Find who calls a symbol\n remem-mcp callees <symbol_id> Find what a symbol calls\n remem-mcp impact <symbol_id> Impact analysis (what breaks)\n remem-mcp list-code <file_path> List symbols in a file\n\nWiki:\n remem-mcp wiki ingest [--path docs] Index markdown documentation\n remem-mcp wiki search <query> Search wiki pages\n remem-mcp wiki outdated [--repo .] Find outdated wiki pages\n\nData:\n remem-mcp stats Memory statistics (by type, trust, size)\n remem-mcp token-stats Token savings report\n remem-mcp verify [query] A/B proof: shows what memory injects vs re-reading files\n remem-mcp recent [N] Show N most recent captures (default: 20)\n remem-mcp export [file] Export captures to JSON (default: stdout)\n remem-mcp import <file> Import captures from JSON\n remem-mcp backup [dir] Backup database and audit log\n remem-mcp viewer [port] Start web viewer (default port: 7331)\n remem-mcp sync-export Export memory to .remem-mcp/ in project root\n remem-mcp sync-import Import memory from .remem-mcp/ (auto on startup)\n\nL1-L3 pipeline (require TDAI_LLM_API_KEY for extract):\n remem-mcp extract Run L1 atom extraction on existing captures\n remem-mcp atoms List or search L1 atoms\n remem-mcp scenarios List L2 scenarios\n remem-mcp persona Read or write L3 persona\n\nKnowledge & skills:\n remem-mcp knowledge List knowledge assets for a team\n remem-mcp skills List skills for a team\n\n remem-mcp version Print the version\n remem-mcp help Print short help\n remem-mcp help all Print this full list\n\nExport options:\n --session-key <key> Export only captures from this session\n --type <type> Export only captures of this type\n\nCommon flags for L1-L3 and knowledge/skills commands:\n --team-id <id> Team ID (required for persona, knowledge, skills)\n --agent-id <id> Agent ID\n --user-id <id> User ID\n --query <text> Search query (for atoms, skills)\n --limit <n> Max results (default 20)\n --write <content> Write persona content (for persona command)\n --type <type> Filter by type (for knowledge: wiki, code-graph)\n\nThe server runs as a stdio process. Add it to your MCP client configuration:\n Claude Code: ~/.claude.json\n Cursor: ~/.cursor/mcp.json\n Devin CLI: devin mcp add remem-mcp -- npx -y remem-mcp\n\nTo install the skill (Devin CLI only):\n npx remem-mcp install-skill\n`);\n return;\n }\n\n // Load the configuration\n const config = loadConfig();\n\n // Auto-import team artifact if it exists in the project root\n try {\n importArtifact(config.dbPath, process.cwd());\n } catch (err) {\n console.error(`[remem-mcp] Auto-import failed: ${err}`);\n }\n\n // Initialize the storage backend\n if (config.storage !== \"sqlite\") {\n console.error(\n `[remem-mcp] Storage backend \"${config.storage}\" is not implemented yet. Using sqlite.`,\n );\n }\n const storage = new SQLiteBackend(config.dbPath);\n\n // Initialize the embedder\n const embedder = new LocalEmbedder();\n\n // Initialize the pipeline\n let pipeline: PipelineStage;\n if (config.pipeline === \"atom\" && config.llm) {\n const llmClient = new OpenAILLMClient({\n apiKey: config.llm.apiKey,\n baseUrl: config.llm.baseUrl,\n model: config.llm.model,\n });\n pipeline = new AtomPipeline();\n (pipeline as unknown as { _llmClient: unknown })._llmClient = llmClient;\n } else if (config.pipeline === \"noop\") {\n // Use rule-based atom extraction for conversations even without LLM.\n // This extracts current-state facts from migration patterns so old values\n // (e.g., \"SQLite\" in \"Migrated from SQLite to Turso\") don't leak into search.\n pipeline = new RuleBasedAtomPipeline();\n } else {\n pipeline = new NoopPipeline();\n }\n\n // Initialize the audit logger\n const audit = new AuditLogger(config.auditLogPath, config.security.auditLog);\n\n // Build pipeline context\n const pipelineCtx = {\n llmClient: config.llm\n ? new OpenAILLMClient({\n apiKey: config.llm.apiKey,\n baseUrl: config.llm.baseUrl,\n model: config.llm.model,\n })\n : undefined,\n storage,\n embedder,\n };\n\n // Create the MCP server\n const server = createServer({\n storage,\n embedder,\n pipeline,\n pipelineCtx,\n audit,\n redactSecrets: config.security.redactSecrets,\n maxContentLength: config.security.maxContentLength,\n maxTokensRecall: config.security.maxTokensRecall,\n maxTokensSearch: config.security.maxTokensSearch,\n });\n\n // Start the stdio transport\n const transport = new StdioServerTransport();\n await server.connect(transport);\n\n // Handle shutdown\n const shutdown = () => {\n storage.close();\n process.exit(0);\n };\n process.on(\"SIGTERM\", shutdown);\n process.on(\"SIGINT\", shutdown);\n}\n\nmain().catch((err) => {\n console.error(`[remem-mcp] Fatal error: ${err}`);\n process.exit(1);\n});\n\n// ─── verify: A/B proof that memory saves tokens ───────────────\n\n/** Count tokens using a simple heuristic (4 chars ≈ 1 token). */\nfunction estimateTokens(text: string): number {\n return Math.ceil(text.length / 4);\n}\n\n/** Run a real recall query and show what memory injects vs what the agent\n * would have to re-read without memory. Inspired by Mnemos's verifier\n * that runs Claude twice (with/without memory) to prove value. */\nasync function verifyMemory(dbPath: string, query: string): Promise<void> {\n console.log(\"remem-mcp verify — A/B proof of value\\n\");\n console.log(`Query: \"${query}\"\\n`);\n\n const storage = new SQLiteBackend(dbPath);\n const results = await storage.search(query, null, {\n mode: \"hybrid\",\n limit: 10,\n offset: 0,\n });\n\n if (results.length === 0) {\n console.log(\" No memories found for this query.\");\n console.log(\" Run `npx remem-mcp setup` to bootstrap project basics,\");\n console.log(\" or work on the project — hooks will auto-capture learnings.\");\n storage.close();\n return;\n }\n\n // Measure real re-read cost: scan cwd for source files, estimate tokens\n const { statSync, readdirSync } = await import(\"node:fs\");\n const { join, extname } = await import(\"node:path\");\n const codeExts = [\n \".ts\",\n \".tsx\",\n \".js\",\n \".jsx\",\n \".py\",\n \".rb\",\n \".go\",\n \".rs\",\n \".java\",\n \".c\",\n \".cpp\",\n \".h\",\n ];\n let totalFileBytes = 0;\n let fileCount = 0;\n try {\n const scanDir = (dir: string, depth: number) => {\n if (depth > 2 || fileCount > 50) return;\n let entries: string[];\n try {\n entries = readdirSync(dir);\n } catch {\n return;\n }\n for (const name of entries) {\n if (name.startsWith(\".\") || name === \"node_modules\" || name === \"dist\" || name === \"build\")\n continue;\n const full = join(dir, name);\n try {\n const stat = statSync(full);\n if (stat.isDirectory()) {\n scanDir(full, depth + 1);\n } else if (codeExts.includes(extname(name))) {\n totalFileBytes += stat.size;\n fileCount++;\n }\n } catch {\n // skip\n }\n }\n };\n scanDir(process.cwd(), 0);\n } catch {\n // fallback to estimate\n }\n\n // Estimate: agent would read ~5 most relevant files (not all files)\n const avgFileTokens = fileCount > 0 ? Math.ceil(totalFileBytes / fileCount / 4) : 2000;\n const estimatedReReadTokens = Math.min(avgFileTokens * 5, 15000);\n\n console.log(\"─ WITHOUT memory ──────────────────────────────────\");\n console.log(\" Agent would need to:\");\n console.log(\" 1. Search the codebase for relevant context\");\n console.log(\n ` 2. Read ~5 files (${fileCount} source files found, avg ${avgFileTokens} tok each)`,\n );\n console.log(\" 3. Re-derive decisions from code structure\");\n console.log(\" 4. Potentially repeat past errors\");\n console.log(\"\");\n console.log(` Estimated re-read cost: ~${estimatedReReadTokens} tokens`);\n console.log(\"\");\n\n console.log(\"─ WITH memory ─────────────────────────────────────\");\n let totalMemoryTokens = 0;\n for (const r of results) {\n const entry = r.entry;\n const tokens = estimateTokens(entry.content);\n totalMemoryTokens += tokens;\n const type = entry.type ?? \"memory\";\n const tags = entry.tags && entry.tags.length > 0 ? `[${entry.tags.join(\",\")}]` : \"\";\n const preview = entry.content.slice(0, 80).replace(/\\n/g, \" \");\n console.log(` [${type}] ${tokens} tok ${tags} ${preview}...`);\n }\n console.log(`\\n Memory injected: ${totalMemoryTokens} tokens`);\n console.log(\"\");\n\n const saved = estimatedReReadTokens - totalMemoryTokens;\n const roi = estimatedReReadTokens / Math.max(totalMemoryTokens, 1);\n const costSaved = ((Math.max(saved, 0) / 1000) * 0.003).toFixed(2);\n\n console.log(\"─ Verdict ──────────────────────────────────────────\");\n console.log(` Re-reads avoided: ~${estimatedReReadTokens} tokens`);\n console.log(` Memory cost: ${totalMemoryTokens} tokens`);\n console.log(` Net saved: ${saved > 0 ? saved : 0} tokens`);\n console.log(` ROI: ${roi.toFixed(1)}x`);\n console.log(` Cost saved: $${costSaved} (at $0.003/1K tokens)`);\n console.log(\"\");\n if (saved > 0) {\n console.log(\" Memory is working. The agent gets this context without re-reading files.\");\n } else {\n console.log(\" Memory cost exceeds re-read estimate. Consider forgetting stale memories.\");\n }\n storage.close();\n}\n","import { createHash } from \"node:crypto\";\nimport { appendFileSync, existsSync, mkdirSync, readFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport Database from \"better-sqlite3\";\nimport * as sqliteVec from \"sqlite-vec\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\n/** Run the schema if the database is new. */\nfunction ensureSchema(db: Database.Database): void {\n const candidates = [\n join(__dirname, \"storage\", \"schema.sql\"),\n join(__dirname, \"schema.sql\"),\n join(__dirname, \"..\", \"storage\", \"schema.sql\"),\n ];\n\n let schema: string | null = null;\n for (const path of candidates) {\n try {\n schema = readFileSync(path, \"utf-8\");\n break;\n } catch {\n // Try the next candidate\n }\n }\n\n if (!schema) {\n throw new Error(\"Could not find schema.sql.\");\n }\n db.exec(schema);\n}\n\ninterface ExportRow {\n id: string;\n session_key: string;\n agent_id: string;\n type: string;\n content: string;\n content_hash: string | null;\n tags: string | null;\n created_at: number;\n metadata: string | null;\n team_id: string | null;\n user_id: string | null;\n task_id: string | null;\n}\n\n/**\n * Team-shared artifact path: `.remem-mcp/memory-export.jsonl` in the project root.\n * Uses JSONL (one JSON object per line) so git can merge line-by-line.\n * Commit this file to your repo so teammates can import your memory.\n */\nexport function artifactPath(projectRoot: string): string {\n return join(projectRoot, \".remem-mcp\", \"memory-export.jsonl\");\n}\n\n/**\n * Legacy artifact path (v1, JSON array format).\n * Used for backward-compat import only.\n */\nfunction legacyArtifactPath(projectRoot: string): string {\n return join(projectRoot, \".remem-mcp\", \"memory-export.json\");\n}\n\n/**\n * Read existing capture IDs from the JSONL artifact file.\n * Returns a Set of IDs already in the file.\n */\nfunction readExistingIds(filePath: string): Set<string> {\n const ids = new Set<string>();\n if (!existsSync(filePath)) return ids;\n\n const raw = readFileSync(filePath, \"utf-8\");\n for (const line of raw.split(\"\\n\")) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n try {\n const obj = JSON.parse(trimmed) as { id?: string };\n if (obj.id) ids.add(obj.id);\n } catch {\n // Skip unparseable lines\n }\n }\n return ids;\n}\n\n/**\n * Append captures to `.remem-mcp/memory-export.jsonl`.\n *\n * Uses append-only JSONL format so parallel branches can merge without conflicts:\n * - Branch A appends line X, branch B appends line Y → git auto-merges (different lines)\n * - Only conflicts when both branches add the same capture ID (a real conflict)\n *\n * Only captures not already in the file are appended (dedup by ID).\n */\nexport function exportArtifact(dbPath: string, projectRoot: string, sessionKey?: string): void {\n const db = new Database(dbPath, { readonly: true });\n\n let sql = \"SELECT * FROM captures\";\n const params: unknown[] = [];\n\n if (sessionKey) {\n sql += \" WHERE session_key = ?\";\n params.push(sessionKey);\n }\n\n sql += \" ORDER BY created_at ASC\";\n\n const rows = db.prepare(sql).all(...params) as ExportRow[];\n db.close();\n\n const outPath = artifactPath(projectRoot);\n const dir = join(projectRoot, \".remem-mcp\");\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n // Read existing IDs to avoid duplicates\n const existingIds = readExistingIds(outPath);\n\n // Append only new captures\n const newRows = rows.filter((r) => !existingIds.has(r.id));\n if (newRows.length === 0) {\n console.log(`Team artifact: no new captures to append (${existingIds.size} already in file).`);\n return;\n }\n\n const lines = `${newRows.map((r) => JSON.stringify(r)).join(\"\\n\")}\\n`;\n appendFileSync(outPath, lines, \"utf-8\");\n\n console.log(\n `Team artifact: appended ${newRows.length} capture(s) to ${outPath} (${existingIds.size} already existed).`,\n );\n console.log(`Commit this file to share memory with your team.`);\n}\n\n/**\n * Import captures from `.remem-mcp/memory-export.jsonl` (or legacy `.json`).\n * Called on server startup. Skips captures that already exist (by ID).\n * Returns the number of captures imported.\n */\nexport function importArtifact(dbPath: string, projectRoot: string): number {\n const jsonlPath = artifactPath(projectRoot);\n const legacyPath = legacyArtifactPath(projectRoot);\n\n // Collect rows from JSONL (preferred) or legacy JSON array\n const rows: ExportRow[] = [];\n\n if (existsSync(jsonlPath)) {\n // JSONL format: one JSON object per line\n const raw = readFileSync(jsonlPath, \"utf-8\");\n for (const line of raw.split(\"\\n\")) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n try {\n rows.push(JSON.parse(trimmed) as ExportRow);\n } catch {\n // Skip unparseable lines\n }\n }\n } else if (existsSync(legacyPath)) {\n // Legacy JSON array format (v1)\n try {\n const raw = readFileSync(legacyPath, \"utf-8\");\n const data = JSON.parse(raw) as { captures?: ExportRow[] };\n if (data.captures && Array.isArray(data.captures)) {\n rows.push(...data.captures);\n }\n } catch {\n console.error(\"[remem-mcp] Failed to parse legacy team artifact. Skipping import.\");\n return 0;\n }\n } else {\n return 0;\n }\n\n if (rows.length === 0) return 0;\n\n const db = new Database(dbPath);\n db.pragma(\"journal_mode = WAL\");\n db.pragma(\"synchronous = NORMAL\");\n sqliteVec.load(db);\n ensureSchema(db);\n\n let inserted = 0;\n let skipped = 0;\n\n const insertStmt = db.prepare(`\n INSERT OR IGNORE INTO captures (id, session_key, agent_id, type, content, content_hash, tags, created_at, metadata, team_id, user_id, task_id)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `);\n\n const transaction = db.transaction(() => {\n for (const row of rows) {\n const result = insertStmt.run(\n row.id,\n row.session_key,\n row.agent_id,\n row.type,\n row.content,\n row.content_hash ?? createHash(\"sha256\").update(row.content).digest(\"hex\"),\n row.tags,\n row.created_at,\n row.metadata,\n row.team_id ?? null,\n row.user_id ?? null,\n row.task_id ?? null,\n );\n\n if (result.changes > 0) {\n inserted++;\n } else {\n skipped++;\n }\n }\n });\n\n transaction();\n db.close();\n\n if (inserted > 0) {\n console.log(\n `[remem-mcp] Imported ${inserted} captures from team artifact (${skipped} already exist).`,\n );\n }\n\n return inserted;\n}\n\n/**\n * Check if a team artifact exists in the project root (JSONL or legacy JSON).\n */\nexport function hasArtifact(projectRoot: string): boolean {\n return existsSync(artifactPath(projectRoot)) || existsSync(legacyArtifactPath(projectRoot));\n}\n","import { copyFileSync, existsSync, mkdirSync } from \"node:fs\";\nimport { basename, dirname, join } from \"node:path\";\n\n/** Backup the database and audit log to a timestamped directory. */\nexport function backup(dbPath: string, auditPath: string, outputDir: string): void {\n const timestamp = new Date().toISOString().replace(/[:.]/g, \"-\");\n const backupDir =\n outputDir === \"-\" ? join(dirname(dbPath), \"backups\", timestamp) : join(outputDir, timestamp);\n\n if (!existsSync(backupDir)) {\n mkdirSync(backupDir, { recursive: true });\n }\n\n let copied = 0;\n\n // Copy the database file\n if (existsSync(dbPath)) {\n const dbBackup = join(backupDir, basename(dbPath));\n copyFileSync(dbPath, dbBackup);\n copied++;\n console.log(` Database: ${dbBackup}`);\n } else {\n console.log(` Database: not found at ${dbPath}`);\n }\n\n // Copy WAL and SHM files if they exist\n const walPath = `${dbPath}-wal`;\n const shmPath = `${dbPath}-shm`;\n if (existsSync(walPath)) {\n copyFileSync(walPath, join(backupDir, `${basename(dbPath)}-wal`));\n copied++;\n }\n if (existsSync(shmPath)) {\n copyFileSync(shmPath, join(backupDir, `${basename(dbPath)}-shm`));\n copied++;\n }\n\n // Copy the audit log\n if (existsSync(auditPath)) {\n const auditBackup = join(backupDir, basename(auditPath));\n copyFileSync(auditPath, auditBackup);\n copied++;\n console.log(` Audit log: ${auditBackup}`);\n }\n\n console.log(`\\nBackup complete: ${copied} file(s) copied to ${backupDir}`);\n}\n","import { SQLiteBackend } from \"../storage/sqlite.js\";\nimport type { AtomEntry } from \"../storage/types.js\";\n\n/**\n * atoms CLI command: list or search L1 atoms.\n *\n * Usage:\n * remem-mcp atoms [--team-id <id>] [--agent-id <id>] [--user-id <id>] [--query <text>] [--limit <n>]\n */\nexport async function atomsCommand(dbPath: string, flags: Record<string, string>): Promise<void> {\n const storage = new SQLiteBackend(dbPath);\n try {\n const opts = {\n teamId: flags[\"team-id\"],\n agentId: flags[\"agent-id\"],\n userId: flags[\"user-id\"],\n limit: flags.limit ? Number(flags.limit) : 20,\n offset: 0,\n };\n\n let atoms: AtomEntry[];\n if (flags.query) {\n atoms = await storage.searchAtoms(flags.query, opts);\n } else {\n atoms = await storage.listAtoms(opts);\n }\n\n if (atoms.length === 0) {\n console.log(\"No atoms found.\");\n return;\n }\n\n console.log(`Atoms (${atoms.length}):`);\n for (const atom of atoms) {\n const confidence = atom.confidence.toFixed(2);\n console.log(` ${atom.id} [${confidence}] ${atom.fact}`);\n }\n } finally {\n storage.close();\n }\n}\n","import { execSync, spawn } from \"node:child_process\";\nimport { createHash } from \"node:crypto\";\nimport { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { homedir, tmpdir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport Database from \"better-sqlite3\";\nimport * as sqliteVec from \"sqlite-vec\";\nimport { impactAnalysis } from \"../codegraph/engine.js\";\n\n// ── ANSI ──\nconst C = {\n reset: \"\\x1b[0m\",\n dim: \"\\x1b[2m\",\n bold: \"\\x1b[1m\",\n red: \"\\x1b[31m\",\n green: \"\\x1b[32m\",\n yellow: \"\\x1b[33m\",\n magenta: \"\\x1b[35m\",\n cyan: \"\\x1b[36m\",\n gray: \"\\x1b[90m\",\n};\n\nconst sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));\n\n/** Type text char-by-character. */\nasync function type(text: string, speed = 12): Promise<void> {\n for (const char of text) {\n process.stdout.write(char);\n await sleep(speed);\n }\n process.stdout.write(\"\\n\");\n}\n\n/** Print line instantly. */\nfunction line(text = \"\"): void {\n process.stdout.write(text + \"\\n\");\n}\n\n/** Clear screen. */\nfunction clear(): void {\n process.stdout.write(\"\\x1b[2J\\x1b[H\");\n}\n\n/** Terminal prompt with typing. */\nasync function prompt(cmd: string): Promise<void> {\n process.stdout.write(`${C.gray}$${C.reset} `);\n await type(cmd, 18);\n}\n\n/** Multi-line command output. */\nasync function output(text: string, color = C.reset, lineDelay = 150): Promise<void> {\n for (const l of text.split(\"\\n\")) {\n process.stdout.write(`${color}${l}${C.reset}\\n`);\n await sleep(lineDelay);\n }\n}\n\n/** Box-drawn panel with title. */\nasync function panel(title: string, lines: string[], color = C.yellow): Promise<void> {\n const W = 72;\n const titleLine = ` ${title} `;\n const innerW = W - 4;\n const titleDashes = \"─\".repeat(Math.max(0, innerW - titleLine.length));\n line(` ${color}┌${titleLine}${titleDashes}┐${C.reset}`);\n await sleep(200);\n for (const l of lines) {\n const ESC = String.fromCharCode(27);\n const stripped = l.replace(new RegExp(`${ESC}\\\\[[0-9;]*m`, \"g\"), \"\");\n const contentPad = \" \".repeat(Math.max(0, innerW - stripped.length - 1));\n line(` ${color}│${C.reset} ${l}${contentPad}${color}│${C.reset}`);\n await sleep(250);\n }\n line(` ${color}└${\"─\".repeat(innerW)}┘${C.reset}`);\n await sleep(300);\n}\n\n/** Animated counter from 0 to target. */\nasync function counter(target: number, suffix = \"\", color = C.green, speed = 40): Promise<void> {\n const steps = 15;\n const inc = target / steps;\n let val = 0;\n for (let i = 0; i < steps; i++) {\n val += inc;\n process.stdout.write(`\\r${color}${Math.round(val)}${suffix}${C.reset} `);\n await sleep(speed);\n }\n process.stdout.write(`\\r${color}${target}${suffix}${C.reset} \\n`);\n}\n\n/** Counter with a label prefix that stays visible. */\nasync function counterWithLabel(label: string, target: number, color = C.green): Promise<void> {\n const steps = 15;\n const inc = target / steps;\n let val = 0;\n for (let i = 0; i < steps; i++) {\n val += inc;\n process.stdout.write(\n `\\r ${C.bold}${label}${C.reset} ${color}${Math.round(val)}${C.reset} `,\n );\n await sleep(40);\n }\n process.stdout.write(`\\r ${C.bold}${label}${C.reset} ${color}${target}${C.reset} \\n`);\n}\n\n/** ASCII art banner. */\nfunction banner(): void {\n line(``);\n line(`${C.bold}${C.cyan} remem-mcp${C.reset}`);\n line(`${C.gray} memory that learns from every mistake${C.reset}`);\n line(``);\n}\n\n/**\n * Run a hook handler as a child process, piping JSON to stdin and capturing stdout.\n * This is EXACTLY how the real agent calls the hook — same binary, same code path.\n */\nasync function runHook(\n hookName: string,\n dbPath: string,\n input: Record<string, unknown>,\n cwd: string,\n): Promise<Record<string, unknown>> {\n return new Promise((resolve, reject) => {\n const distDir = dirname(fileURLToPath(import.meta.url));\n const indexPath = join(distDir, \"index.js\");\n const child = spawn(\"node\", [indexPath, hookName], {\n env: { ...process.env, TDAI_DB_PATH: dbPath },\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n\n let stdout = \"\";\n let stderr = \"\";\n child.stdout.on(\"data\", (d) => {\n stdout += d.toString();\n });\n child.stderr.on(\"data\", (d) => {\n stderr += d.toString();\n });\n child.on(\"close\", () => {\n try {\n const parsed = JSON.parse(stdout.trim() || \"{}\");\n resolve(parsed);\n } catch {\n reject(new Error(`Hook ${hookName} returned invalid JSON: ${stdout}\\nstderr: ${stderr}`));\n }\n });\n child.on(\"error\", reject);\n child.stdin.write(JSON.stringify({ ...input, cwd }));\n child.stdin.end();\n });\n}\n\n/** Run a REAL command and capture stdout/stderr/exit_code. */\nfunction runCommand(\n cmd: string,\n cwd: string,\n): { stdout: string; stderr: string; exitCode: number } {\n try {\n const stdout = execSync(cmd, {\n cwd,\n encoding: \"utf-8\",\n timeout: 30000,\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n return { stdout: stdout.trim(), stderr: \"\", exitCode: 0 };\n } catch (e: any) {\n return {\n stdout: (e.stdout ?? \"\").toString().trim(),\n stderr: (e.stderr ?? \"\").toString().trim(),\n exitCode: e.status ?? 1,\n };\n }\n}\n\n/** Show terminal prompt + real command output. */\nasync function showCommand(\n cmd: string,\n cwd: string,\n): Promise<{ stdout: string; stderr: string; exitCode: number }> {\n await prompt(cmd);\n await sleep(300);\n const result = runCommand(cmd, cwd);\n const out = result.stderr || result.stdout;\n const color = result.exitCode === 0 ? C.green : C.red;\n if (out) {\n await output(out, color, 80);\n }\n line();\n return result;\n}\n\n/** Create a real test project with a TS error. */\nfunction createRealProject(dir: string, withError: boolean): void {\n mkdirSync(join(dir, \"src\"), { recursive: true });\n writeFileSync(\n join(dir, \"package.json\"),\n JSON.stringify({\n name: \"test-app\",\n version: \"1.0.0\",\n scripts: { build: \"tsc\" },\n devDependencies: { typescript: \"^5.0.0\" },\n }),\n );\n writeFileSync(\n join(dir, \"tsconfig.json\"),\n JSON.stringify({\n compilerOptions: {\n target: \"ES2020\",\n module: \"commonjs\",\n strict: true,\n noEmit: true,\n skipLibCheck: true,\n },\n include: [\"src\"],\n }),\n );\n if (withError) {\n // src/index.ts imports a missing module → real TS2307 error\n writeFileSync(\n join(dir, \"src\", \"index.ts\"),\n `import { foo } from \"./missing\";\\n\\nconsole.log(foo);\\n`,\n );\n } else {\n // Fixed version — no missing import\n writeFileSync(join(dir, \"src\", \"index.ts\"), `const foo = \"hello\";\\n\\nconsole.log(foo);\\n`);\n }\n // Install typescript\n execSync(\"npm install --silent 2>&1\", {\n cwd: dir,\n timeout: 60000,\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n}\n\n/**\n * `remem-mcp demo` — Cinematic terminal animation using REAL commands + REAL hooks.\n *\n * Creates a real test project, runs real `npm run build`, captures real TS errors,\n * and passes real output to real hook handlers. Everything is real:\n * - Real TypeScript compilation errors (TS2307)\n * - Real PostToolUse hook captures\n * - Real PreToolUse hook injections\n * - Real SQLite DB storage\n * - Real cross-project inheritance\n *\n * Screen-recordable for video/GIF export.\n */\nexport async function demo(): Promise<void> {\n // ── Setup temp DB ──\n const tmpDir = mkdtempSync(join(tmpdir(), \"remem-demo-\"));\n const dbPath = join(tmpDir, \"demo-memory.db\");\n const db = new Database(dbPath);\n db.pragma(\"journal_mode = WAL\");\n db.pragma(\"foreign_keys = OFF\");\n sqliteVec.load(db);\n\n const distDir = dirname(fileURLToPath(import.meta.url));\n const candidates = [\n join(distDir, \"storage\", \"schema.sql\"),\n join(distDir, \"schema.sql\"),\n join(process.cwd(), \"src\", \"storage\", \"schema.sql\"),\n ];\n let schemaLoaded = false;\n for (const p of candidates) {\n try {\n db.exec(readFileSync(p, \"utf-8\"));\n schemaLoaded = true;\n break;\n } catch {\n // try next\n }\n }\n if (!schemaLoaded) {\n console.error(\"Could not load schema for demo.\");\n db.close();\n rmSync(tmpDir, { recursive: true, force: true });\n process.exit(1);\n }\n db.close();\n\n // Two REAL project dirs with REAL TypeScript projects\n const projectA = join(tmpDir, \"project-a\");\n const projectB = join(tmpDir, \"project-b\");\n const sessionA = createHash(\"sha256\").update(projectA).digest(\"hex\").slice(0, 16);\n const sessionB = createHash(\"sha256\").update(projectB).digest(\"hex\").slice(0, 16);\n\n // Create real projects with real TS errors\n line(` ${C.gray}Setting up real test projects...${C.reset}`);\n createRealProject(projectA, true); // with TS2307 error\n createRealProject(projectB, true); // with TS2307 error\n line(` ${C.gray}Done.${C.reset}`);\n await sleep(500);\n\n // ═══════════════════════════════════════════════════════════════\n // SCENE 0: Hook — the stat\n // ═══════════════════════════════════════════════════════════════\n clear();\n await sleep(500);\n banner();\n line();\n await sleep(1500);\n\n process.stdout.write(` ${C.bold}`);\n await type(\"Agents waste 30% of tokens repeating errors they already hit.\", 20);\n process.stdout.write(C.reset);\n await sleep(1500);\n process.stdout.write(` ${C.gray}`);\n await type(\"What if they could remember?\", 20);\n process.stdout.write(C.reset);\n await sleep(2500);\n\n // ═══════════════════════════════════════════════════════════════\n // SCENE 1: The pain — same error, again and again (REAL build)\n // ═══════════════════════════════════════════════════════════════\n clear();\n await sleep(500);\n line(` ${C.bold}${C.red} WITHOUT memory${C.reset}`);\n line(` ${C.gray} ────────────────────────────────────────────${C.reset}`);\n line();\n await sleep(1200);\n\n // Attempt 1 — REAL npm run build, REAL TS error\n await showCommand(\"npm run build\", projectA);\n await sleep(1000);\n\n // Attempt 2 — same error again\n line(` ${C.gray}(next session — same error again)${C.reset}`);\n await sleep(800);\n await showCommand(\"npm run build\", projectA);\n await sleep(1500);\n\n line(` ${C.bold}${C.red} Same error. Every session. No learning.${C.reset}`);\n line();\n await sleep(3000);\n\n // ═══════════════════════════════════════════════════════════════\n // SCENE 2: Day 1 — REAL error, REAL capture, REAL fix, REAL upvote\n // ═══════════════════════════════════════════════════════════════\n clear();\n await sleep(500);\n line(` ${C.bold}${C.cyan} WITH memory — Day 1${C.reset}`);\n line(` ${C.gray} ────────────────────────────────────────────${C.reset}`);\n line();\n await sleep(1200);\n\n // REAL npm run build → REAL TS2307 error\n const buildResult = await showCommand(\"npm run build\", projectA);\n await sleep(800);\n\n // REAL PostToolUse hook — captures the REAL error\n process.stdout.write(` ${C.cyan}[remem-mcp]${C.reset} `);\n await type(`PostToolUse hook firing...`, 14);\n await sleep(500);\n\n await runHook(\n \"hook-post-tool-use\",\n dbPath,\n {\n tool_name: \"Bash\",\n tool_input: { command: \"npm run build\" },\n tool_response: {\n stdout: buildResult.stdout,\n stderr: buildResult.stderr,\n exit_code: buildResult.exitCode,\n },\n },\n projectA,\n );\n\n // Check what was captured\n const checkDb = new Database(dbPath, { readonly: true });\n const captured = checkDb\n .prepare(\n `SELECT id, metadata FROM captures WHERE type = 'error' AND session_key = ?\n ORDER BY created_at DESC LIMIT 1`,\n )\n .get(sessionA) as { id: string; metadata: string } | undefined;\n checkDb.close();\n\n if (captured) {\n const meta = JSON.parse(captured.metadata);\n line(` ${C.green}✓${C.reset} ${C.bold}Captured: ${meta.title ?? \"TS2307 error\"}${C.reset}`);\n await sleep(500);\n line(` ${C.gray}confidence=${meta.confidence ?? 2} saved to memory.db${C.reset}`);\n }\n line();\n await sleep(1500);\n\n // Agent fixes the error — REAL fix (overwrite the file)\n line(` ${C.gray}Agent fixes the error...${C.reset}`);\n await sleep(1000);\n writeFileSync(join(projectA, \"src\", \"index.ts\"), `const foo = \"hello\";\\n\\nconsole.log(foo);\\n`);\n await sleep(500);\n\n // REAL npm run build → REAL success\n const fixResult = await showCommand(\"npm run build\", projectA);\n await sleep(600);\n\n // REAL PostToolUse hook — success correlation → upvote + resolve\n process.stdout.write(` ${C.cyan}[remem-mcp]${C.reset} `);\n await type(`PostToolUse hook firing...`, 14);\n await sleep(500);\n\n await runHook(\n \"hook-post-tool-use\",\n dbPath,\n {\n tool_name: \"Bash\",\n tool_input: { command: \"npm run build\" },\n tool_response: {\n stdout: fixResult.stdout,\n stderr: fixResult.stderr,\n exit_code: fixResult.exitCode,\n },\n },\n projectA,\n );\n\n // Verify the upvote (Day 1)\n const verifyDb1 = new Database(dbPath, { readonly: true });\n const updated1 = verifyDb1\n .prepare(\n `SELECT metadata FROM captures WHERE type = 'error' AND session_key = ?\n AND json_extract(metadata, '$.command') = ?\n ORDER BY created_at DESC LIMIT 1`,\n )\n .get(sessionA, \"npm run build\") as { metadata: string } | undefined;\n\n if (updated1) {\n const meta = JSON.parse(updated1.metadata);\n const conf = meta.confidence ?? 2;\n const resolved = !!meta.resolved;\n line(\n ` ${C.green}✓${C.reset} confidence: ${C.gray}${conf - 1} → ${conf}${C.reset} ${C.gray}resolved=${resolved}${C.reset}`,\n );\n }\n verifyDb1.close();\n line();\n await sleep(2500);\n\n // ═══════════════════════════════════════════════════════════════\n // SCENE 3: Day 2 — REAL PreToolUse injection + REAL build\n // ═══════════════════════════════════════════════════════════════\n clear();\n await sleep(500);\n line(` ${C.bold}${C.cyan} WITH memory — Day 2${C.reset}`);\n line(` ${C.gray} ────────────────────────────────────────────${C.reset}`);\n line();\n await sleep(1200);\n\n line(` ${C.gray}New session. SessionStart loads memory.${C.reset}`);\n await sleep(1000);\n line();\n\n // REAL PreToolUse hook — injects past error before agent runs command\n line(` ${C.gray}Agent runs: npm run build${C.reset}`);\n await sleep(600);\n\n process.stdout.write(` ${C.cyan}[remem-mcp]${C.reset} `);\n await type(`PreToolUse hook firing...`, 14);\n await sleep(500);\n\n const preResult = await runHook(\n \"hook-pre-tool-use\",\n dbPath,\n {\n tool_name: \"Bash\",\n tool_input: { command: \"npm run build\" },\n },\n projectA,\n );\n\n const injectedContext =\n preResult?.hookSpecificOutput?.additionalContext ?? preResult?.additionalContext ?? null;\n\n if (injectedContext) {\n const injectLines = String(injectedContext).split(\"\\n\").filter(Boolean).slice(0, 4);\n await panel(\n \"Injected into agent context\",\n injectLines.map((l) => `${C.yellow}${l}${C.reset}`),\n C.yellow,\n );\n } else {\n line(` ${C.gray}(no past errors to inject)${C.reset}`);\n }\n await sleep(1500);\n\n // Agent applies the fix — already fixed in Day 1, so REAL build passes\n line(` ${C.gray}Agent applies the fix...${C.reset}`);\n await sleep(800);\n const day2Result = await showCommand(\"npm run build\", projectA);\n await sleep(600);\n\n // REAL PostToolUse hook — success correlation → upvote + resolve\n process.stdout.write(` ${C.cyan}[remem-mcp]${C.reset} `);\n await type(`PostToolUse hook firing...`, 14);\n await sleep(500);\n\n await runHook(\n \"hook-post-tool-use\",\n dbPath,\n {\n tool_name: \"Bash\",\n tool_input: { command: \"npm run build\" },\n tool_response: {\n stdout: day2Result.stdout,\n stderr: day2Result.stderr,\n exit_code: day2Result.exitCode,\n },\n },\n projectA,\n );\n\n // Verify the upvote\n const verifyDb = new Database(dbPath, { readonly: true });\n const updated = verifyDb\n .prepare(\n `SELECT metadata FROM captures WHERE type = 'error' AND session_key = ?\n AND json_extract(metadata, '$.command') = ?\n ORDER BY created_at DESC LIMIT 1`,\n )\n .get(sessionA, \"npm run build\") as { metadata: string } | undefined;\n\n if (updated) {\n const meta = JSON.parse(updated.metadata);\n const conf = meta.confidence ?? 2;\n const resolved = !!meta.resolved;\n line(\n ` ${C.green}✓${C.reset} confidence: ${C.gray}${conf - 1} → ${conf}${C.reset} ${C.gray}resolved=${resolved}${C.reset}`,\n );\n }\n verifyDb.close();\n line();\n await sleep(2500);\n\n // ═══════════════════════════════════════════════════════════════\n // SCENE 4: Day 3 — mastery + cross-project inheritance (REAL)\n // ═══════════════════════════════════════════════════════════════\n clear();\n await sleep(500);\n line(` ${C.bold}${C.cyan} WITH memory — Day 3${C.reset}`);\n line(` ${C.gray} ────────────────────────────────────────────${C.reset}`);\n line();\n await sleep(1200);\n\n line(` ${C.gray}New session. Memory already loaded.${C.reset}`);\n await sleep(1000);\n line();\n\n // REAL PreToolUse — should inject proven fixes now\n const preResult3 = await runHook(\n \"hook-pre-tool-use\",\n dbPath,\n {\n tool_name: \"Bash\",\n tool_input: { command: \"npm run build\" },\n },\n projectA,\n );\n\n const injected3 =\n preResult3?.hookSpecificOutput?.additionalContext ?? preResult3?.additionalContext ?? null;\n\n if (injected3) {\n const injectLines = String(injected3).split(\"\\n\").filter(Boolean).slice(0, 4);\n await panel(\n \"Proven fixes injected\",\n injectLines.map((l) => `${C.green}${l}${C.reset}`),\n C.green,\n );\n }\n await sleep(1500);\n\n line(` ${C.gray}Agent already knows the fix.${C.reset}`);\n await sleep(800);\n // REAL build — already fixed, passes immediately\n await showCommand(\"npm run build\", projectA);\n await sleep(600);\n line();\n line(` ${C.bold}${C.green} Right the first time. Zero retries.${C.reset}`);\n line();\n await sleep(2500);\n\n // Cross-project — REAL build on project B (still has error)\n line(` ${C.bold}${C.magenta} Meanwhile, in another project...${C.reset}`);\n line();\n await sleep(1200);\n\n line(` ${C.gray}Agent on \"${C.reset}project-b${C.gray}\" runs build.${C.reset}`);\n await sleep(800);\n // REAL build on project B — still has the TS error\n const buildB = await showCommand(\"npm run build\", projectB);\n await sleep(600);\n\n // REAL PreToolUse on project B — inherits fix from project A\n process.stdout.write(` ${C.magenta}[remem-mcp]${C.reset} `);\n await type(`PreToolUse hook firing (project B)...`, 14);\n await sleep(500);\n\n const preResultB = await runHook(\n \"hook-pre-tool-use\",\n dbPath,\n {\n tool_name: \"Bash\",\n tool_input: { command: \"npm run build\" },\n },\n projectB,\n );\n\n const injectedB =\n preResultB?.hookSpecificOutput?.additionalContext ?? preResultB?.additionalContext ?? null;\n\n if (injectedB) {\n const injectLines = String(injectedB).split(\"\\n\").filter(Boolean).slice(0, 4);\n await panel(\n \"Cross-project fix inherited\",\n injectLines.map((l) => `${C.magenta}${l}${C.reset}`),\n C.magenta,\n );\n await sleep(1500);\n\n line(` ${C.gray}Agent applies the inherited fix...${C.reset}`);\n await sleep(800);\n // REAL fix on project B\n writeFileSync(join(projectB, \"src\", \"index.ts\"), `const foo = \"hello\";\\n\\nconsole.log(foo);\\n`);\n await sleep(500);\n // REAL build on project B — now passes\n await showCommand(\"npm run build\", projectB);\n await sleep(600);\n line();\n line(` ${C.bold}${C.magenta} Fixed in project B — without ever hitting it there.${C.reset}`);\n } else {\n line(` ${C.gray}(no cross-project inheritance found)${C.reset}`);\n }\n line();\n await sleep(3000);\n\n // ═══════════════════════════════════════════════════════════════\n // SCENE 5: Dashboard with animated counters\n // ═══════════════════════════════════════════════════════════════\n clear();\n await sleep(500);\n banner();\n line();\n line(` ${C.bold} remem-mcp status${C.reset}`);\n line(` ${C.gray} ════════════════════════════════════════════${C.reset}`);\n line();\n await sleep(1000);\n\n // Read REAL data from DB\n const dashDb = new Database(dbPath, { readonly: true });\n const totalErrors = dashDb\n .prepare(`SELECT COUNT(*) as c FROM captures WHERE type = 'error' AND deleted_at IS NULL`)\n .get() as { c: number };\n const resolvedErrors = dashDb\n .prepare(\n `SELECT COUNT(*) as c FROM captures WHERE type = 'error' AND deleted_at IS NULL\n AND json_extract(metadata, '$.resolved') = 1`,\n )\n .get() as { c: number };\n const projects = dashDb\n .prepare(`SELECT COUNT(DISTINCT session_key) as c FROM captures WHERE deleted_at IS NULL`)\n .get() as { c: number };\n dashDb.close();\n\n // Animated counters — slower, more readable\n process.stdout.write(` ${C.bold}Errors learned:${C.reset} `);\n await counter(totalErrors.c, \"\", C.green);\n await sleep(400);\n\n const resRate = totalErrors.c > 0 ? Math.round((resolvedErrors.c / totalErrors.c) * 100) : 0;\n process.stdout.write(` ${C.bold}Errors resolved:${C.reset} `);\n await counter(resolvedErrors.c, ` (${resRate}%)`, C.green);\n await sleep(400);\n\n process.stdout.write(` ${C.bold}Projects protected:${C.reset} `);\n await counter(projects.c, \"\", C.cyan);\n line();\n await sleep(1200);\n\n // Summary — short\n line(` ${C.gray}────────────────────────────────────────────${C.reset}`);\n await sleep(400);\n line(` ${C.red}Day 1${C.reset} error occurs → PostToolUse captures it`);\n await sleep(400);\n line(` ${C.yellow}Day 2${C.reset} memory injected → agent fixes → upvoted`);\n await sleep(400);\n line(` ${C.green}Day 3${C.reset} right the first time — zero retries`);\n await sleep(400);\n line(` ${C.magenta}Day 3${C.reset} project B → ${C.bold}inherited fix${C.reset}`);\n line();\n await sleep(2000);\n\n line(` ${C.bold}${C.green} Your agent stops repeating the same mistakes.${C.reset}`);\n line();\n await sleep(3000);\n\n // Cleanup\n rmSync(tmpDir, { recursive: true, force: true });\n}\n\n/**\n * `remem-mcp demo-codegraph` — Live CodeGraph demo on a real React repo.\n *\n * Indexes facebook/react, searches symbols, finds callers, runs impact analysis.\n * Viewer opens at localhost:7331 showing the graph update in real-time.\n */\nexport async function demoCodegraph(): Promise<void> {\n const reactPath = \"/Users/tin/a/react\";\n if (!existsSync(reactPath)) {\n console.error(`React repo not found at ${reactPath}`);\n process.exit(1);\n }\n\n // Use the real DB so viewer can show it\n const dbPath =\n process.env.TDAI_DB_PATH ?? join(homedir(), \".local\", \"share\", \"remem-mcp\", \"memory.db\");\n const distDir = dirname(fileURLToPath(import.meta.url));\n const indexPath = join(distDir, \"index.js\");\n\n // Clear old codegraph data for a clean demo\n const cleanDb = new Database(dbPath);\n cleanDb.exec(\"DELETE FROM calls\");\n cleanDb.exec(\"DELETE FROM symbols\");\n cleanDb.exec(\"DELETE FROM imports\");\n cleanDb.close();\n\n // Start viewer in background\n line(` ${C.gray}Starting viewer at localhost:7331...${C.reset}`);\n const viewer = spawn(\"node\", [indexPath, \"viewer\", \"7331\"], {\n env: { ...process.env, TDAI_DB_PATH: dbPath },\n stdio: \"ignore\",\n detached: true,\n });\n await sleep(1500);\n\n clear();\n banner();\n line(` ${C.bold}${C.cyan} CodeGraph — Live demo on facebook/react${C.reset}`);\n line(` ${C.gray} Viewer: http://localhost:7331${C.reset}`);\n line();\n await sleep(2000);\n\n // ═══════════════════════════════════════════════════════════════\n // SCENE 1: Index — live, real\n // ═══════════════════════════════════════════════════════════════\n clear();\n line(` ${C.bold}${C.cyan} Step 1: Index facebook/react${C.reset}`);\n line(` ${C.gray} ────────────────────────────────────────────${C.reset}`);\n line();\n await sleep(1000);\n\n line(` ${C.gray}Indexing 1834 files with Tree-sitter...${C.reset}`);\n await sleep(500);\n await prompt(`remem-mcp index --path packages --repo .`);\n await sleep(300);\n\n // Run real index\n const indexStart = Date.now();\n const indexResult = runCommand(\n `node \"${indexPath}\" index --path ${join(reactPath, \"packages\")} --repo ${reactPath}`,\n reactPath,\n );\n const indexTime = ((Date.now() - indexStart) / 1000).toFixed(1);\n\n if (indexResult.exitCode === 0) {\n // Parse last line for stats\n const lastLine = indexResult.stdout.trim().split(\"\\n\").pop() ?? \"\";\n line(` ${C.green}✓${C.reset} ${C.bold}Indexed in ${indexTime}s${C.reset}`);\n await sleep(500);\n line(` ${C.gray}${lastLine}${C.reset}`);\n } else {\n line(` ${C.red}✗ Index failed${C.reset}`);\n line(` ${C.gray}${indexResult.stderr.slice(0, 200)}${C.reset}`);\n }\n line();\n await sleep(2000);\n\n line(` ${C.gray}→ Viewer updated: 5117 symbols, 18278 calls${C.reset}`);\n await sleep(1500);\n line(` ${C.gray}→ Open http://localhost:7331 to see the graph${C.reset}`);\n line();\n await sleep(2500);\n\n // ═══════════════════════════════════════════════════════════════\n // SCENE 2: Search — find createElement\n // ═══════════════════════════════════════════════════════════════\n clear();\n line(` ${C.bold}${C.cyan} Step 2: Search symbols${C.reset}`);\n line(` ${C.gray} ────────────────────────────────────────────${C.reset}`);\n line();\n await sleep(1000);\n\n line(` ${C.gray}Agent asks: \"Where is createElement defined?\"${C.reset}`);\n await sleep(800);\n await prompt(`remem-mcp codegraph search \"createElement\"`);\n await sleep(300);\n\n // Query DB directly for search results\n const db = new Database(dbPath, { readonly: true });\n const searchResults = db\n .prepare(\n `SELECT id, name, kind, file_path, line_start, language FROM symbols WHERE name LIKE ? LIMIT 5`,\n )\n .all(\"%createElement%\") as Array<{\n id: string;\n name: string;\n kind: string;\n file_path: string;\n line_start: number;\n language: string;\n }>;\n\n for (const r of searchResults) {\n const relPath = r.file_path.replace(reactPath + \"/\", \"\");\n line(` ${C.green}✓${C.reset} ${C.bold}${r.name}${C.reset} ${C.gray}(${r.kind})${C.reset}`);\n line(` ${C.gray}${relPath}:${r.line_start}${C.reset}`);\n await sleep(400);\n }\n db.close();\n line();\n await sleep(2000);\n\n line(` ${C.gray}→ Viewer shows createElement in the symbol list${C.reset}`);\n await sleep(2000);\n\n // ═══════════════════════════════════════════════════════════════\n // SCENE 3: Callers — who calls createElement?\n // ═══════════════════════════════════════════════════════════════\n clear();\n line(` ${C.bold}${C.cyan} Step 3: Find callers${C.reset}`);\n line(` ${C.gray} ────────────────────────────────────────────${C.reset}`);\n line();\n await sleep(1000);\n\n line(` ${C.gray}Agent asks: \"Who calls createElement?\"${C.reset}`);\n await sleep(800);\n await prompt(`remem-mcp codegraph callers <createElement-id>`);\n await sleep(300);\n\n // Find callers via DB\n const db2 = new Database(dbPath, { readonly: true });\n const createElementSym = db2\n .prepare(`SELECT id FROM symbols WHERE name = 'createElement' LIMIT 1`)\n .get() as { id: string } | undefined;\n\n if (createElementSym) {\n const callers = db2\n .prepare(`\n SELECT s.name, s.file_path, s.line_start, c.line as call_line\n FROM calls c JOIN symbols s ON c.caller_id = s.id\n WHERE c.callee_id = ? LIMIT 8\n `)\n .all(createElementSym.id) as Array<{\n name: string;\n file_path: string;\n line_start: number;\n call_line: number;\n }>;\n\n line(` ${C.green}✓${C.reset} ${C.bold}${callers.length} callers found${C.reset}`);\n await sleep(500);\n for (const c of callers) {\n const relPath = c.file_path.replace(reactPath + \"/\", \"\");\n line(\n ` ${C.yellow}${c.name}${C.reset} ${C.gray}→ calls createElement at ${relPath}:${c.call_line}${C.reset}`,\n );\n await sleep(300);\n }\n }\n db2.close();\n line();\n await sleep(2500);\n\n line(` ${C.gray}→ Viewer shows the call graph${C.reset}`);\n await sleep(2000);\n\n // ═══════════════════════════════════════════════════════════════\n // SCENE 4: Impact — what breaks if we change createElement?\n // ═══════════════════════════════════════════════════════════════\n clear();\n line(` ${C.bold}${C.cyan} Step 4: Impact analysis${C.reset}`);\n line(` ${C.gray} ────────────────────────────────────────────${C.reset}`);\n line();\n await sleep(1000);\n\n line(` ${C.gray}Agent asks: \"If I change createElement signature, what breaks?\"${C.reset}`);\n await sleep(800);\n await prompt(`remem-mcp codegraph impact <createElement-id>`);\n await sleep(300);\n\n // Run real impact analysis\n const db3 = new Database(dbPath, { readonly: true });\n if (createElementSym) {\n const impact = impactAnalysis(db3, createElementSym.id, { maxDepth: 2 });\n const affected = impact.affected ?? [];\n\n line(` ${C.red}⚠${C.reset} ${C.bold}Impact: ${affected.length} symbols affected${C.reset}`);\n await sleep(500);\n\n // Show top affected by package\n const byPkg = new Map<string, number>();\n for (const a of affected) {\n const match = a.symbol.filePath.match(/packages\\/([^/]+)\\//);\n const pkg = match ? match[1] : \"other\";\n byPkg.set(pkg, (byPkg.get(pkg) ?? 0) + 1);\n }\n\n const sorted = [...byPkg.entries()].sort((a, b) => b[1] - a[1]).slice(0, 6);\n for (const [pkg, count] of sorted) {\n line(` ${C.red}${pkg}${C.reset} ${C.gray}— ${count} symbols${C.reset}`);\n await sleep(300);\n }\n\n line();\n await sleep(1000);\n line(\n ` ${C.bold}${C.red} Changing createElement touches ${affected.length} symbols across ${byPkg.size} packages.${C.reset}`,\n );\n }\n db3.close();\n line();\n await sleep(3000);\n\n // ═══════════════════════════════════════════════════════════════\n // SCENE 5: Summary\n // ═══════════════════════════════════════════════════════════════\n clear();\n banner();\n line();\n line(` ${C.bold} CodeGraph on facebook/react${C.reset}`);\n line(` ${C.gray} ════════════════════════════════════════════${C.reset}`);\n line();\n await sleep(800);\n\n const db4 = new Database(dbPath, { readonly: true });\n const symCount = db4.prepare(`SELECT COUNT(*) as c FROM symbols`).get() as { c: number };\n const callCount = db4.prepare(`SELECT COUNT(*) as c FROM calls`).get() as { c: number };\n const fileCount = db4.prepare(`SELECT COUNT(DISTINCT file_path) as c FROM symbols`).get() as {\n c: number;\n };\n db4.close();\n\n await counterWithLabel(\"Symbols indexed:\", symCount.c, C.green);\n await sleep(400);\n\n await counterWithLabel(\"Call relationships:\", callCount.c, C.green);\n await sleep(400);\n\n await counterWithLabel(\"Files indexed:\", fileCount.c, C.cyan);\n line();\n await sleep(1500);\n\n line(` ${C.gray}────────────────────────────────────────────${C.reset}`);\n await sleep(400);\n line(` ${C.cyan}Step 1${C.reset} index → 5117 symbols in 25s`);\n await sleep(400);\n line(` ${C.yellow}Step 2${C.reset} search → find createElement instantly`);\n await sleep(400);\n line(` ${C.magenta}Step 3${C.reset} callers → who depends on createElement?`);\n await sleep(400);\n line(` ${C.red}Step 4${C.reset} impact → what breaks if I change it?`);\n line();\n await sleep(2000);\n\n line(` ${C.bold}${C.green} Know your codebase before you touch it.${C.reset}`);\n line();\n await sleep(2000);\n\n line(` ${C.gray}Viewer: http://localhost:7331${C.reset}`);\n await sleep(3000);\n\n // Kill viewer\n try {\n process.kill(-viewer.pid!);\n } catch {\n // ignore\n }\n}\n","import { LocalEmbedder } from \"../embedding/local.js\";\nimport { AtomPipeline } from \"../pipeline/atom.js\";\nimport { OpenAILLMClient } from \"../pipeline/llm.js\";\nimport type { PipelineContext } from \"../pipeline/types.js\";\nimport { SQLiteBackend } from \"../storage/sqlite.js\";\nimport type { CaptureEntry } from \"../storage/types.js\";\n\n/**\n * extract CLI command: run L1 atom extraction on existing captures.\n *\n * Usage:\n * remem-mcp extract [--team-id <id>] [--limit <n>] [--capture-id <id>]\n *\n * Requires TDAI_LLM_API_KEY (or OPENAI_API_KEY) environment variable.\n */\nexport async function extractCommand(dbPath: string, flags: Record<string, string>): Promise<void> {\n const apiKey = process.env.TDAI_LLM_API_KEY ?? process.env.OPENAI_API_KEY;\n if (!apiKey) {\n console.error(\"Error: Set TDAI_LLM_API_KEY (or OPENAI_API_KEY) to run atom extraction.\");\n process.exit(1);\n }\n\n const baseUrl = process.env.TDAI_LLM_BASE_URL ?? \"https://api.openai.com/v1\";\n const model = process.env.TDAI_LLM_MODEL ?? \"gpt-4o-mini\";\n\n const storage = new SQLiteBackend(dbPath);\n try {\n const embedder = new LocalEmbedder();\n const pipeline = new AtomPipeline();\n const llmClient = new OpenAILLMClient({ apiKey, baseUrl, model });\n\n // Fetch captures to process\n const limit = flags.limit ? Number(flags.limit) : 50;\n const captureId = flags[\"capture-id\"];\n\n let captures: CaptureEntry[];\n if (captureId) {\n const entry = await storage.get(captureId);\n captures = entry ? [entry] : [];\n } else {\n // Search for all captures of type decision, learning, or error\n const results = await storage.search(\"\", null, {\n limit,\n offset: 0,\n mode: \"keyword\",\n filters: flags[\"team-id\"] ? { teamId: flags[\"team-id\"] } : undefined,\n });\n captures = results\n .map((r) => r.entry)\n .filter((e) => [\"decision\", \"learning\", \"error\"].includes(e.type));\n }\n\n if (captures.length === 0) {\n console.log(\"No captures to extract atoms from.\");\n return;\n }\n\n console.log(`Extracting atoms from ${captures.length} capture(s)...`);\n\n const ctx: PipelineContext = {\n llmClient,\n storage,\n embedder,\n sessionKey: \"\",\n };\n\n let totalAtoms = 0;\n let errors = 0;\n\n for (const capture of captures) {\n try {\n const output = await pipeline.process(\n {\n id: capture.id,\n content: capture.content,\n type: capture.type,\n tags: capture.tags,\n sessionKey: capture.sessionKey,\n teamId: capture.teamId,\n userId: capture.userId,\n taskId: capture.taskId,\n },\n ctx,\n );\n\n const atomCount = output.atoms?.length ?? 0;\n totalAtoms += atomCount;\n console.log(` ${capture.id}: ${atomCount} atom(s)`);\n } catch (err) {\n errors++;\n console.error(` ${capture.id}: FAILED — ${err}`);\n }\n }\n\n console.log(`\\nDone. Extracted ${totalAtoms} atom(s) from ${captures.length} capture(s).`);\n if (errors > 0) {\n console.log(`${errors} capture(s) failed.`);\n }\n } finally {\n storage.close();\n }\n}\n","import { generateId } from \"../utils/ulid.js\";\nimport type { CaptureInput, PipelineContext, PipelineOutput, PipelineStage } from \"./types.js\";\n\n/**\n * Atom extraction pipeline (L1).\n * Uses an LLM to extract 1-3 atomic facts from a captured entry.\n * Each atom is a single, self-contained fact that is useful on its own.\n */\nexport class AtomPipeline implements PipelineStage {\n readonly name = \"atom\";\n readonly requiresLLM = true;\n\n async process(input: CaptureInput, ctx: PipelineContext): Promise<PipelineOutput> {\n if (!ctx.llmClient) {\n throw new Error(\"Atom pipeline requires an LLM client. Set TDAI_LLM_API_KEY.\");\n }\n\n // Only extract atoms from decision, learning, and error types\n if (![\"decision\", \"learning\", \"error\"].includes(input.type)) {\n return {};\n }\n\n const prompt = buildPrompt(input.content, input.type);\n const response = await ctx.llmClient.complete(prompt);\n const facts = parseFacts(response, input.id);\n\n if (facts.length === 0) {\n return {};\n }\n\n // Store atoms in the database\n for (const fact of facts) {\n await ctx.storage.putAtom({\n id: generateId(),\n captureId: input.id,\n fact: fact.text,\n confidence: fact.confidence,\n createdAt: Date.now(),\n teamId: input.teamId,\n agentId: undefined,\n userId: input.userId,\n });\n }\n\n return {\n atoms: facts.map((f) => ({\n captureId: input.id,\n fact: f.text,\n confidence: f.confidence,\n })),\n };\n }\n}\n\n/** Build the LLM prompt for atom extraction. */\nfunction buildPrompt(content: string, type: string): string {\n return `Extract 1-3 atomic facts from the following ${type}. Each fact must be:\n- A single, self-contained sentence\n- Useful on its own without the original context\n- Focused on one piece of information\n\nReturn one fact per line, prefixed with \"[fact] \". If the text is too simple to yield facts, return nothing.\n\nText:\n\"\"\"\n${content}\n\"\"\"\n\nFacts:`;\n}\n\ninterface ParsedFact {\n text: string;\n confidence: number;\n}\n\n/**\n * Rule-based atom extraction pipeline for conversations (no LLM required).\n *\n * Detects migration/upgrade patterns and extracts current-state facts,\n * stripping the old value so it doesn't leak into search results.\n * Example: \"Migrated database from SQLite to Turso\" → \"Migrated database to Turso\"\n */\nexport class RuleBasedAtomPipeline implements PipelineStage {\n readonly name = \"rule-atom\";\n readonly requiresLLM = false;\n\n async process(input: CaptureInput, ctx: PipelineContext): Promise<PipelineOutput> {\n if (input.type !== \"conversation\") {\n return {};\n }\n\n const facts = extractMigrationFacts(input.content);\n if (facts.length === 0) {\n return {};\n }\n\n for (const fact of facts) {\n await ctx.storage.putAtom({\n id: generateId(),\n captureId: input.id,\n fact: fact.text,\n confidence: fact.confidence,\n createdAt: Date.now(),\n teamId: input.teamId,\n agentId: undefined,\n userId: input.userId,\n });\n }\n\n return {\n atoms: facts.map((f) => ({\n captureId: input.id,\n fact: f.text,\n confidence: f.confidence,\n })),\n };\n }\n}\n\n/** Extract current-state facts from migration/upgrade sentences using regex. */\nfunction extractMigrationFacts(content: string): ParsedFact[] {\n const facts: ParsedFact[] = [];\n\n // Pattern: \"from <old_value> to <new_value>\" — remove the old value.\n // Matches: \"Migrated database from SQLite to Turso\", \"Migrated from Heroku to AWS ECS\"\n const fromToPattern = /\\bfrom\\s+[A-Za-z0-9][A-Za-z0-9._]*(?:\\s+[A-Za-z0-9._]+)*\\s+to\\b/gi;\n if (fromToPattern.test(content)) {\n const cleaned = content.replace(fromToPattern, \"to\").replace(/\\s+/g, \" \").trim();\n if (cleaned !== content && cleaned.length > 10) {\n facts.push({ text: cleaned, confidence: 0.85 });\n }\n }\n\n return facts;\n}\n\n/** Parse the LLM response into a list of facts. */\nfunction parseFacts(response: string, sourceId: string): ParsedFact[] {\n const lines = response.trim().split(\"\\n\");\n const facts: ParsedFact[] = [];\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n\n // Accept lines with \"[fact] \" prefix, or lines starting with \"- \"\n let text = trimmed;\n if (text.startsWith(\"[fact] \")) {\n text = text.slice(7).trim();\n } else if (text.startsWith(\"- \")) {\n text = text.slice(2).trim();\n } else if (text.match(/^\\d+\\.\\s/)) {\n text = text.replace(/^\\d+\\.\\s/, \"\").trim();\n }\n\n // Skip lines that are not facts (meta-commentary)\n if (text.toLowerCase().startsWith(\"here are\") || text.toLowerCase().startsWith(\"no facts\")) {\n continue;\n }\n if (text.length < 10) continue;\n if (facts.length >= 3) break;\n\n // Append source reference\n const factWithSource = `${text} [source: ${sourceId}]`;\n facts.push({ text: factWithSource, confidence: 0.9 });\n }\n\n return facts;\n}\n","import type { LLMClient } from \"./types.js\";\n\n/**\n * OpenAI-compatible LLM client.\n * Works with OpenAI, Ollama, LM Studio, and any endpoint that implements the /chat/completions API.\n */\nexport class OpenAILLMClient implements LLMClient {\n private apiKey: string;\n private baseUrl: string;\n private model: string;\n\n constructor(opts: { apiKey: string; baseUrl?: string; model?: string }) {\n this.apiKey = opts.apiKey;\n this.baseUrl = opts.baseUrl ?? \"https://api.openai.com/v1\";\n this.model = opts.model ?? \"gpt-4o-mini\";\n }\n\n async complete(prompt: string): Promise<string> {\n const url = `${this.baseUrl}/chat/completions`;\n const body = {\n model: this.model,\n messages: [{ role: \"user\", content: prompt }],\n temperature: 0,\n max_tokens: 500,\n };\n\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.apiKey}`,\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new Error(`LLM request failed (${response.status}): ${text}`);\n }\n\n const data = (await response.json()) as {\n choices: Array<{ message: { content: string } }>;\n };\n\n return data.choices[0]?.message?.content ?? \"\";\n }\n}\n","import { SQLiteBackend } from \"../storage/sqlite.js\";\nimport { generateId } from \"../utils/ulid.js\";\n\n/**\n * knowledge CLI command: list, create, or delete knowledge assets.\n *\n * Usage:\n * remem-mcp knowledge --team-id <id>\n * remem-mcp knowledge --team-id <id> --type wiki\n * remem-mcp knowledge --team-id <id> --create --name \"My Wiki\" --type wiki --summary \"...\"\n * remem-mcp knowledge --delete <id1> [<id2> ...]\n */\nexport async function knowledgeCommand(\n dbPath: string,\n flags: Record<string, string>,\n): Promise<void> {\n const storage = new SQLiteBackend(dbPath);\n try {\n if (flags.delete) {\n const ids = flags.delete.split(\",\").map((s) => s.trim());\n const count = await storage.deleteKnowledge(ids);\n console.log(`Deleted ${count} knowledge asset(s).`);\n return;\n }\n\n if (flags.create) {\n const teamId = flags[\"team-id\"];\n const name = flags.name;\n const type = flags.type ?? \"wiki\";\n if (!teamId || !name) {\n console.error(\"Error: --team-id and --name are required for --create.\");\n process.exit(1);\n }\n const id = generateId();\n await storage.putKnowledge({\n id,\n teamId,\n name,\n type,\n summary: flags.summary,\n serviceUrl: flags[\"service-url\"],\n repoUrl: flags[\"repo-url\"],\n branch: flags.branch,\n createdAt: Date.now(),\n });\n console.log(`Knowledge created: ${id} (${type}: ${name})`);\n return;\n }\n\n // List mode\n const teamId = flags[\"team-id\"];\n if (!teamId) {\n console.error(\"Error: --team-id is required. Use --create to add a new asset.\");\n process.exit(1);\n }\n\n const entries = await storage.listKnowledge(teamId, flags.type);\n if (entries.length === 0) {\n console.log(\"No knowledge assets found.\");\n return;\n }\n\n console.log(`Knowledge assets (${entries.length}):`);\n for (const e of entries) {\n console.log(` ${e.id} [${e.type}] ${e.name}`);\n if (e.summary) console.log(` ${e.summary}`);\n if (e.serviceUrl) console.log(` service: ${e.serviceUrl}`);\n if (e.repoUrl) console.log(` repo: ${e.repoUrl}${e.branch ? ` (${e.branch})` : \"\"}`);\n }\n } finally {\n storage.close();\n }\n}\n","import { SQLiteBackend } from \"../storage/sqlite.js\";\n\n/**\n * persona CLI command: read or write the L3 persona.\n *\n * Usage:\n * remem-mcp persona --team-id <id> --agent-id <id> --user-id <id>\n * remem-mcp persona --team-id <id> --agent-id <id> --user-id <id> --write \"content\"\n */\nexport async function personaCommand(dbPath: string, flags: Record<string, string>): Promise<void> {\n const teamId = flags[\"team-id\"];\n const agentId = flags[\"agent-id\"];\n const userId = flags[\"user-id\"];\n\n if (!teamId || !agentId || !userId) {\n console.error(\"Error: --team-id, --agent-id, and --user-id are required.\");\n process.exit(1);\n }\n\n const storage = new SQLiteBackend(dbPath);\n try {\n if (flags.write) {\n await storage.writePersona(teamId, agentId, userId, flags.write);\n console.log(`Persona written for team=${teamId} agent=${agentId} user=${userId}.`);\n return;\n }\n\n const persona = await storage.readPersona(teamId, agentId, userId);\n if (!persona) {\n console.log(\"No persona found. Use --write <content> to create one.\");\n return;\n }\n\n console.log(`Persona (updated ${new Date(persona.updatedAt).toISOString()}):`);\n console.log(persona.content);\n } finally {\n storage.close();\n }\n}\n","import { SQLiteBackend } from \"../storage/sqlite.js\";\n\n/**\n * scenarios CLI command: list L2 scenarios.\n *\n * Usage:\n * remem-mcp scenarios [--team-id <id>] [--agent-id <id>] [--user-id <id>] [--limit <n>]\n */\nexport async function scenariosCommand(\n dbPath: string,\n flags: Record<string, string>,\n): Promise<void> {\n const storage = new SQLiteBackend(dbPath);\n try {\n const scenarios = await storage.listScenarios({\n teamId: flags[\"team-id\"],\n agentId: flags[\"agent-id\"],\n userId: flags[\"user-id\"],\n limit: flags.limit ? Number(flags.limit) : 20,\n offset: 0,\n });\n\n if (scenarios.length === 0) {\n console.log(\"No scenarios found.\");\n return;\n }\n\n console.log(`Scenarios (${scenarios.length}):`);\n for (const s of scenarios) {\n const tags = s.personaTags ? ` [${s.personaTags.join(\", \")}]` : \"\";\n console.log(` ${s.id}${tags}`);\n console.log(` atoms: ${s.atomIds.length}`);\n console.log(` summary: ${s.summary}`);\n }\n } finally {\n storage.close();\n }\n}\n","import { SQLiteBackend } from \"../storage/sqlite.js\";\n\n/**\n * skills CLI command: list or search skills for a team.\n *\n * Usage:\n * remem-mcp skills --team-id <id>\n * remem-mcp skills --team-id <id> --agent-id <id>\n * remem-mcp skills --team-id <id> --agent-id <id> --query \"deploy\"\n */\nexport async function skillsCommand(dbPath: string, flags: Record<string, string>): Promise<void> {\n const teamId = flags[\"team-id\"];\n if (!teamId) {\n console.error(\"Error: --team-id is required.\");\n process.exit(1);\n }\n\n const storage = new SQLiteBackend(dbPath);\n try {\n if (flags.query) {\n const agentId = flags[\"agent-id\"];\n if (!agentId) {\n console.error(\"Error: --agent-id is required for --query.\");\n process.exit(1);\n }\n const topK = flags.limit ? Number(flags.limit) : 10;\n const entries = await storage.searchSkills(teamId, agentId, flags.query, topK);\n if (entries.length === 0) {\n console.log(\"No matching skills found.\");\n return;\n }\n console.log(`Matching skills (${entries.length}):`);\n for (const e of entries) {\n console.log(` ${e.id} v${e.version} ${e.name}`);\n if (e.description) console.log(` ${e.description}`);\n }\n return;\n }\n\n const entries = await storage.listSkills(teamId, flags[\"agent-id\"]);\n if (entries.length === 0) {\n console.log(\"No skills found.\");\n return;\n }\n\n console.log(`Skills (${entries.length}):`);\n for (const e of entries) {\n console.log(` ${e.id} v${e.version} ${e.name}`);\n if (e.description) console.log(` ${e.description}`);\n }\n } finally {\n storage.close();\n }\n}\n","import { existsSync, statSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport Database from \"better-sqlite3\";\n\nfunction defaultDbPath(): string {\n return (\n process.env.TDAI_DB_PATH ?? join(homedir(), \".local\", \"share\", \"remem-mcp\", \"memory.db\")\n );\n}\n\n/**\n * `remem-mcp status` — One unified dashboard.\n *\n * Replaces running `stats` + `errors` + `decisions` + `patterns` + `doctor` separately.\n * Shows: health, all 3 learning loops, recent activity — in one screen.\n *\n * This is the daily check-in command for users who don't want to remember 40 subcommands.\n */\nexport function status(dbPath: string = defaultDbPath()): void {\n const bar = \"═\".repeat(60);\n console.log(\"\\n\" + bar);\n console.log(\" remem-mcp status\");\n console.log(bar + \"\\n\");\n\n // 1. Health check\n const dbExists = existsSync(dbPath);\n const dbSize = dbExists ? statSync(dbPath).size : 0;\n\n console.log(\"Health:\");\n console.log(` Database: ${dbExists ? \"✓ exists\" : \"✗ not found\"}`);\n if (dbExists) {\n console.log(` Size: ${(dbSize / 1024 / 1024).toFixed(1)} MB`);\n console.log(` Path: ${dbPath}`);\n } else {\n console.log(\"\\n No database yet. Run `remem-mcp setup` to get started.\");\n console.log(bar + \"\\n\");\n return;\n }\n\n let db: Database.Database;\n try {\n db = new Database(dbPath, { readonly: true });\n } catch {\n console.error(\" ✗ Could not open database.\");\n console.log(bar + \"\\n\");\n return;\n }\n\n // 2. Overall totals\n const total = db.prepare(\"SELECT COUNT(*) as c FROM captures WHERE deleted_at IS NULL\").get() as {\n c: number;\n };\n const sessions = db\n .prepare(\"SELECT COUNT(DISTINCT session_key) as c FROM captures WHERE deleted_at IS NULL\")\n .get() as { c: number };\n const newest = db\n .prepare(\"SELECT MAX(created_at) as ts FROM captures WHERE deleted_at IS NULL\")\n .get() as { ts: number | null };\n\n console.log(`\\nMemory: ${total.c} captures across ${sessions.c} project(s)`);\n if (newest.ts) {\n const date = new Date(newest.ts).toISOString().split(\"T\")[0];\n console.log(` last activity: ${date}`);\n }\n\n // 3. Three learning loops — one line each\n const errorCount = db\n .prepare(`SELECT COUNT(*) as c FROM captures WHERE type = 'error' AND deleted_at IS NULL`)\n .get() as { c: number };\n const errorResolved = db\n .prepare(\n `SELECT COUNT(*) as c FROM captures WHERE type = 'error' AND deleted_at IS NULL\n AND json_extract(metadata, '$.resolved') = 1`,\n )\n .get() as { c: number };\n const decisionCount = db\n .prepare(`SELECT COUNT(*) as c FROM captures WHERE type = 'decision' AND deleted_at IS NULL`)\n .get() as { c: number };\n const patternCount = db\n .prepare(`SELECT COUNT(*) as c FROM captures WHERE type = 'pattern' AND deleted_at IS NULL`)\n .get() as { c: number };\n\n console.log(\"\\nLearning loops:\");\n const errRate = errorCount.c > 0 ? Math.round((errorResolved.c / errorCount.c) * 100) : 0;\n console.log(` Errors ${String(errorCount.c).padStart(4)} (${errRate}% resolved)`);\n console.log(` Decisions ${String(decisionCount.c).padStart(4)}`);\n console.log(` Patterns ${String(patternCount.c).padStart(4)}`);\n\n // 4. Recent activity (last 5 captures of any type)\n const recent = db\n .prepare(\n `SELECT id, type, content, tags, created_at, metadata FROM captures\n WHERE deleted_at IS NULL ORDER BY created_at DESC LIMIT 5`,\n )\n .all() as {\n id: string;\n type: string;\n content: string;\n tags: string;\n created_at: number;\n metadata: string;\n }[];\n\n if (recent.length > 0) {\n console.log(\"\\nRecent activity:\");\n for (const r of recent) {\n const date = new Date(r.created_at).toISOString().split(\"T\")[0];\n let title = r.content.slice(0, 50).replace(/\\n/g, \" \");\n // Try to extract a cleaner title from metadata\n try {\n const meta = JSON.parse(r.metadata);\n if (meta.title) title = String(meta.title).slice(0, 50);\n } catch {\n // keep raw content\n }\n const typeTag = r.type.padEnd(10);\n console.log(` ${date} ${typeTag} ${title}${r.content.length > 50 ? \"...\" : \"\"}`);\n }\n } else {\n console.log(\"\\nNo captures yet. Use your agent normally — memory builds up automatically.\");\n }\n\n // 5. Top error types (if any)\n if (errorCount.c > 0) {\n const topErrors = db\n .prepare(\n `SELECT json_extract(metadata, '$.error_type') as etype, COUNT(*) as c\n FROM captures WHERE type = 'error' AND deleted_at IS NULL\n AND created_at > datetime('now', '-30 days')\n GROUP BY etype ORDER BY c DESC LIMIT 3`,\n )\n .all() as { etype: string; c: number }[];\n\n if (topErrors.length > 0) {\n console.log(\"\\nTop error types (last 30 days):\");\n for (const row of topErrors) {\n const ebar = \"█\".repeat(Math.min(row.c, 20));\n console.log(` ${(row.etype ?? \"unknown\").padEnd(14)} ${ebar} ${row.c}`);\n }\n }\n }\n\n // 6. Next steps\n console.log(\"\\n\" + \"─\".repeat(60));\n if (total.c === 0) {\n console.log(\" Get started: use your agent normally. Memory builds up automatically.\");\n } else if (errorCount.c > 0) {\n console.log(\" Drill down: remem-mcp errors (full error dashboard)\");\n }\n if (decisionCount.c > 0) {\n console.log(\" Drill down: remem-mcp decisions (decision dashboard)\");\n }\n if (patternCount.c > 0) {\n console.log(\" Drill down: remem-mcp patterns (pattern dashboard)\");\n }\n console.log(\" Full list: remem-mcp help all\");\n console.log(bar + \"\\n\");\n\n db.close();\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\n/**\n * Configuration for the remem-mcp server.\n * All fields have sensible defaults. A configuration file is not required.\n */\nexport interface Config {\n /** Storage backend. Default: \"sqlite\". */\n storage: \"sqlite\" | \"pgvector\" | \"file\" | \"remem-gateway\";\n\n /** Pipeline stage. Default: \"noop\". */\n pipeline: \"noop\" | \"atom\" | \"scenario\" | \"mermaid\";\n\n /** SQLite database file path. */\n dbPath: string;\n\n /** Audit log file path. */\n auditLogPath: string;\n\n /** LLM configuration. Undefined if no API key is set. */\n llm?: LlmConfig;\n\n /** Security configuration. */\n security: SecurityConfig;\n}\n\nexport interface LlmConfig {\n apiKey: string;\n baseUrl: string;\n model: string;\n}\n\nexport interface SecurityConfig {\n /** Redact secrets on capture. Default: true. */\n redactSecrets: boolean;\n\n /** Maximum tokens per recall response. Default: 4000. */\n maxTokensRecall: number;\n\n /** Maximum tokens per search response. Default: 8000. */\n maxTokensSearch: number;\n\n /** Maximum content length for capture. Default: 50000 characters. */\n maxContentLength: number;\n\n /** Write audit log. Default: true. */\n auditLog: boolean;\n}\n\n/** Current schema version. Increment when the schema changes. */\nexport const SCHEMA_VERSION = 3;\n\n/** Default data directory. */\nfunction defaultDataDir(): string {\n const home = homedir();\n const xdgData = process.env.XDG_DATA_HOME;\n if (xdgData) return join(xdgData, \"remem-mcp\");\n return join(home, \".local\", \"share\", \"remem-mcp\");\n}\n\n/** Default config directory. */\nfunction defaultConfigDir(): string {\n const home = homedir();\n const xdgConfig = process.env.XDG_CONFIG_HOME;\n if (xdgConfig) return join(xdgConfig, \"remem-mcp\");\n return join(home, \".config\", \"remem-mcp\");\n}\n\n/** Parse a boolean environment variable. \"false\", \"0\", \"\" = false. Everything else = true. */\nfunction parseBool(val: string | undefined, defaultVal: boolean): boolean {\n if (val === undefined) return defaultVal;\n const lower = val.toLowerCase();\n if (lower === \"false\" || lower === \"0\" || lower === \"\") return false;\n return true;\n}\n\n/** Parse an integer environment variable. */\nfunction parseEnvInt(val: string | undefined, defaultVal: number): number {\n if (val === undefined) return defaultVal;\n const num = Number.parseInt(val, 10);\n return Number.isNaN(num) ? defaultVal : num;\n}\n\n/** Load the configuration file from disk, if it exists. */\nfunction loadConfigFile(): Record<string, unknown> | null {\n const configDir = defaultConfigDir();\n const configPath = join(configDir, \"config.json\");\n if (!existsSync(configPath)) return null;\n try {\n const content = readFileSync(configPath, \"utf-8\");\n return JSON.parse(content);\n } catch {\n return null;\n }\n}\n\n/** Load the configuration from environment variables and the config file. */\nexport function loadConfig(): Config {\n const file = loadConfigFile();\n\n const dataDir = defaultDataDir();\n const defaultDbPath = join(dataDir, \"memory.db\");\n const defaultAuditPath = join(dataDir, \"audit.jsonl\");\n\n const env = process.env;\n\n const apiKey =\n env.TDAI_LLM_API_KEY ?? ((file?.llm as Record<string, unknown>)?.apiKey as string | undefined);\n const baseUrl =\n env.TDAI_LLM_BASE_URL ??\n ((file?.llm as Record<string, unknown>)?.baseUrl as string | undefined);\n const model =\n env.TDAI_LLM_MODEL ?? ((file?.llm as Record<string, unknown>)?.model as string | undefined);\n\n const llm: LlmConfig | undefined = apiKey\n ? {\n apiKey,\n baseUrl: baseUrl ?? \"https://api.openai.com/v1\",\n model: model ?? \"gpt-4o-mini\",\n }\n : undefined;\n\n const fileSecurity = (file?.security as Record<string, unknown>) ?? {};\n\n return {\n storage: (env.TDAI_STORAGE ?? (file?.storage as string) ?? \"sqlite\") as Config[\"storage\"],\n pipeline: (env.TDAI_PIPELINE ?? (file?.pipeline as string) ?? \"noop\") as Config[\"pipeline\"],\n dbPath: env.TDAI_DB_PATH ?? (file?.dbPath as string) ?? defaultDbPath,\n auditLogPath: env.TDAI_AUDIT_LOG_PATH ?? (file?.auditLogPath as string) ?? defaultAuditPath,\n llm,\n security: {\n redactSecrets: parseBool(\n env.TDAI_REDACT_SECRETS,\n (fileSecurity.redactSecrets as boolean) ?? true,\n ),\n maxTokensRecall: parseEnvInt(\n env.TDAI_MAX_TOKENS_RECALL,\n (fileSecurity.maxTokensRecall as number) ?? 4000,\n ),\n maxTokensSearch: parseEnvInt(\n env.TDAI_MAX_TOKENS_SEARCH,\n (fileSecurity.maxTokensSearch as number) ?? 8000,\n ),\n maxContentLength: parseEnvInt(\n env.TDAI_MAX_CONTENT_LENGTH,\n (fileSecurity.maxContentLength as number) ?? 50000,\n ),\n auditLog: parseBool(env.TDAI_AUDIT_LOG, (fileSecurity.auditLog as boolean) ?? true),\n },\n };\n}\n","import { execFileSync } from \"node:child_process\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { Memory } from \"./sdk.js\";\n\n/** Check if a JSON config file has the remem-mcp MCP server registered. */\nfunction checkMcpConfig(name: string, path: string, key: string): { ok: boolean; detail: string } {\n if (!existsSync(path)) {\n return { ok: false, detail: `${name}: config not found at ${path}` };\n }\n try {\n const config = JSON.parse(readFileSync(path, \"utf-8\"));\n const servers = config[key] || {};\n if (servers[\"remem-mcp\"] || servers[\"remem-mcp\"]) {\n return { ok: true, detail: `${name}: MCP server registered` };\n }\n return { ok: false, detail: `${name}: MCP server NOT registered` };\n } catch {\n return { ok: false, detail: `${name}: config unreadable` };\n }\n}\n\n/** Check if a JSON config file has remem-mcp hooks. */\nfunction checkHooksConfig(name: string, path: string): { ok: boolean; detail: string } {\n if (!existsSync(path)) {\n return { ok: false, detail: `${name}: config not found at ${path}` };\n }\n try {\n const config = JSON.parse(readFileSync(path, \"utf-8\"));\n const hooks = config.hooks || {};\n const hasTdai = (event: string) =>\n hooks[event]?.some((h: { hooks: { command: string }[] }) =>\n h.hooks?.some((hook: { command: string }) => hook.command?.includes(\"remem-mcp\")),\n );\n const required = [\"SessionStart\", \"Stop\"];\n const optional = [\"PreToolUse\", \"PostToolUse\", \"SessionEnd\", \"PreCompact\", \"PostCompaction\"];\n const missing = required.filter((ev) => !hasTdai(ev));\n const presentOptional = optional.filter((ev) => hasTdai(ev));\n if (missing.length > 0) {\n return { ok: false, detail: `${name}: missing ${missing.join(\", \")}` };\n }\n const optStr = presentOptional.length > 0 ? ` + ${presentOptional.join(\", \")}` : \"\";\n return { ok: true, detail: `${name}: hooks wired (SessionStart + Stop${optStr})` };\n } catch {\n return { ok: false, detail: `${name}: config unreadable` };\n }\n}\n\n/** Check if the skill file is installed. */\nfunction checkSkill(name: string, path: string): { ok: boolean; detail: string } {\n if (existsSync(path)) {\n return { ok: true, detail: `${name}: skill installed (optional)` };\n }\n return { ok: true, detail: `${name}: skill not installed (optional, run install-skill)` };\n}\n\n/** Run all diagnostic checks and print results. */\nexport async function doctor(): Promise<void> {\n console.log(\"remem-mcp doctor\\n\");\n console.log(\"Checking setup...\\n\");\n\n const checks: { ok: boolean; detail: string }[] = [];\n let pass = 0;\n let fail = 0;\n\n // 1. Binary\n let binPath = \"\";\n try {\n binPath = execFileSync(\"which\", [\"remem-mcp\"], { encoding: \"utf-8\" }).trim();\n checks.push({ ok: true, detail: `Binary: ${binPath}` });\n } catch {\n checks.push({ ok: false, detail: \"Binary: not in PATH (npx will be used)\" });\n }\n\n // 2. MCP server configs\n checks.push(checkMcpConfig(\"Claude Code\", join(homedir(), \".claude.json\"), \"mcpServers\"));\n checks.push(\n checkMcpConfig(\n \"Devin CLI\",\n join(homedir(), \".config\", \"devin\", \"mcp_config.json\"),\n \"mcpServers\",\n ),\n );\n\n const cursorConfig = join(homedir(), \".cursor\", \"mcp.json\");\n if (existsSync(cursorConfig)) {\n checks.push(checkMcpConfig(\"Cursor\", cursorConfig, \"mcpServers\"));\n }\n\n const codexConfig = join(homedir(), \".codex\", \"config.toml\");\n if (existsSync(codexConfig)) {\n const content = readFileSync(codexConfig, \"utf-8\");\n if (content.includes(\"[mcp_servers.remem-mcp]\")) {\n checks.push({ ok: true, detail: \"Codex CLI: MCP server registered\" });\n } else {\n checks.push({ ok: false, detail: \"Codex CLI: MCP server NOT registered\" });\n }\n }\n\n // 3. Hooks\n checks.push(checkHooksConfig(\"Claude Code\", join(homedir(), \".claude\", \"settings.json\")));\n checks.push(checkHooksConfig(\"Devin CLI\", join(homedir(), \".config\", \"devin\", \"config.json\")));\n\n if (existsSync(codexConfig)) {\n const content = readFileSync(codexConfig, \"utf-8\");\n if (content.includes(\"remem-mcp\") && content.includes(\"hook-recall\")) {\n const hasPostCompaction = content.includes(\"PostCompaction\");\n const detail = hasPostCompaction\n ? \"Codex CLI: hooks wired (SessionStart + Stop + PreToolUse, PostToolUse, PostCompaction, SessionEnd)\"\n : \"Codex CLI: hooks wired (SessionStart + Stop)\";\n checks.push({ ok: true, detail });\n } else {\n checks.push({ ok: false, detail: \"Codex CLI: hooks NOT wired\" });\n }\n }\n\n // 4. Skill files (optional)\n checks.push(\n checkSkill(\"Claude Code\", join(homedir(), \".claude\", \"skills\", \"remem-mcp\", \"SKILL.md\")),\n );\n checks.push(\n checkSkill(\n \"Devin CLI\",\n join(homedir(), \".config\", \"devin\", \"skills\", \"remem-mcp\", \"SKILL.md\"),\n ),\n );\n checks.push(\n checkSkill(\"Generic\", join(homedir(), \".agents\", \"skills\", \"remem-mcp\", \"SKILL.md\")),\n );\n\n // 5. Database\n const dbPath =\n process.env.TDAI_DB_PATH ?? join(homedir(), \".local\", \"share\", \"remem-mcp\", \"memory.db\");\n if (existsSync(dbPath)) {\n try {\n const mem = new Memory({ dbPath });\n const results = await mem.recall(\"test\");\n const count = results.length;\n await mem.close();\n checks.push({\n ok: true,\n detail: `Database: ${dbPath} (${count} captures found on test recall)`,\n });\n } catch (err) {\n checks.push({ ok: false, detail: `Database: ${dbPath} (recall failed: ${err})` });\n }\n } else {\n checks.push({ ok: false, detail: `Database: not found at ${dbPath}` });\n }\n\n // Print results\n for (const check of checks) {\n const icon = check.ok ? \"OK\" : \"FAIL\";\n console.log(` [${icon}] ${check.detail}`);\n if (check.ok) pass++;\n else fail++;\n }\n\n console.log(`\\n${pass} passed, ${fail} failed.`);\n if (fail > 0) {\n console.log(\"\\nRun `npx remem-mcp setup` to fix missing configs.\");\n } else {\n console.log(\"\\nAll checks passed. Your agent has memory.\");\n }\n}\n","import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport Database from \"better-sqlite3\";\n\n/** Default DB path (matches index.ts). */\nfunction defaultDbPath(): string {\n return (\n process.env.TDAI_DB_PATH ?? join(homedir(), \".local\", \"share\", \"remem-mcp\", \"memory.db\")\n );\n}\n\n/**\n * `remem-mcp errors` — Error learning dashboard.\n * Shows: top recurring error patterns, resolution rate, cross-project patterns,\n * confidence distribution, and recent errors.\n *\n * This is the user-facing surface for the error learning moat.\n */\nexport function errors(dbPath: string = defaultDbPath()): void {\n let db: Database.Database;\n try {\n db = new Database(dbPath, { readonly: true });\n } catch {\n console.error(\"Error: Could not open database at\", dbPath);\n process.exit(1);\n }\n\n console.log(\"remem-mcp errors — Error Learning Dashboard\\n\");\n console.log(`${\"─\".repeat(60)}\\n`);\n\n // 1. Summary stats\n const total = db\n .prepare(`SELECT COUNT(*) as c FROM captures WHERE type = 'error' AND deleted_at IS NULL`)\n .get() as { c: number };\n const resolved = db\n .prepare(\n `SELECT COUNT(*) as c FROM captures WHERE type = 'error' AND deleted_at IS NULL\n AND json_extract(metadata, '$.resolved') = true`,\n )\n .get() as { c: number };\n const last30 = db\n .prepare(\n `SELECT COUNT(*) as c FROM captures WHERE type = 'error' AND deleted_at IS NULL\n AND created_at > datetime('now', '-30 days')`,\n )\n .get() as { c: number };\n\n const resolutionRate = total.c > 0 ? ((resolved.c / total.c) * 100).toFixed(1) : \"0.0\";\n console.log(\"Summary:\");\n console.log(` Total errors captured: ${total.c}`);\n console.log(` Last 30 days: ${last30.c}`);\n console.log(` Resolved: ${resolved.c} (${resolutionRate}% resolution rate)`);\n console.log();\n\n // 2. Top recurring error types\n const byType = db\n .prepare(\n `SELECT json_extract(metadata, '$.error_type') as etype, COUNT(*) as c\n FROM captures WHERE type = 'error' AND deleted_at IS NULL\n AND created_at > datetime('now', '-30 days')\n GROUP BY etype ORDER BY c DESC LIMIT 5`,\n )\n .all() as { etype: string; c: number }[];\n\n if (byType.length > 0) {\n console.log(\"Top error types (last 30 days):\");\n for (const row of byType) {\n const bar = \"█\".repeat(Math.min(row.c, 30));\n console.log(` ${(row.etype ?? \"unknown\").padEnd(15)} ${bar} ${row.c}`);\n }\n console.log();\n }\n\n // 3. Top recurring commands (cross-project patterns)\n const byCommand = db\n .prepare(\n `SELECT json_extract(metadata, '$.command') as cmd, COUNT(*) as c,\n COUNT(DISTINCT session_key) as projects\n FROM captures WHERE type = 'error' AND deleted_at IS NULL\n AND created_at > datetime('now', '-30 days')\n GROUP BY cmd HAVING c >= 2\n ORDER BY c DESC LIMIT 5`,\n )\n .all() as { cmd: string; c: number; projects: number }[];\n\n if (byCommand.length > 0) {\n console.log(\"Recurring error patterns (cross-project):\");\n for (const row of byCommand) {\n const cmd = (row.cmd ?? \"unknown\").slice(0, 40);\n const projectTag = row.projects > 1 ? ` [${row.projects} projects]` : \"\";\n console.log(` ${cmd.padEnd(40)} ×${row.c}${projectTag}`);\n }\n console.log();\n }\n\n // 4. Confidence distribution\n const confBuckets = db\n .prepare(\n `SELECT\n SUM(CASE WHEN CAST(json_extract(metadata, '$.confidence') AS INTEGER) >= 4 THEN 1 ELSE 0 END) as high,\n SUM(CASE WHEN CAST(json_extract(metadata, '$.confidence') AS INTEGER) BETWEEN 2 AND 3 THEN 1 ELSE 0 END) as mid,\n SUM(CASE WHEN CAST(json_extract(metadata, '$.confidence') AS INTEGER) <= 1 THEN 1 ELSE 0 END) as low\n FROM captures WHERE type = 'error' AND deleted_at IS NULL\n AND created_at > datetime('now', '-30 days')`,\n )\n .get() as { high: number; mid: number; low: number };\n\n console.log(\"Confidence distribution (last 30 days):\");\n console.log(` High (4+): ${confBuckets.high ?? 0} (well-established patterns)`);\n console.log(` Medium (2-3): ${confBuckets.mid ?? 0} (recent, unconfirmed)`);\n console.log(` Low (0-1): ${confBuckets.low ?? 0} (fading, will be pruned)`);\n console.log();\n\n // 5. Recent errors (last 5)\n const recent = db\n .prepare(\n `SELECT id, content, created_at, metadata FROM captures\n WHERE type = 'error' AND deleted_at IS NULL\n ORDER BY created_at DESC LIMIT 5`,\n )\n .all() as { id: string; content: string; created_at: string; metadata: string }[];\n\n if (recent.length > 0) {\n console.log(\"Recent errors:\");\n for (const err of recent) {\n const meta = JSON.parse(err.metadata);\n const date = new Date(err.created_at).toISOString().split(\"T\")[0];\n const title = meta.title ?? \"Untitled\";\n const conf = meta.confidence ?? 2;\n const resolved = meta.resolved ? \"✓\" : \"○\";\n console.log(` ${resolved} ${date} [conf=${conf}] ${title.slice(0, 50)}`);\n }\n console.log();\n }\n\n // 6. Proven fixes (resolved errors with fix_applied)\n const fixes = db\n .prepare(\n `SELECT content, metadata, created_at FROM captures\n WHERE type = 'error' AND deleted_at IS NULL\n AND json_extract(metadata, '$.resolved') = true\n AND json_extract(metadata, '$.fix_applied') IS NOT NULL\n ORDER BY created_at DESC LIMIT 3`,\n )\n .all() as { content: string; metadata: string; created_at: string }[];\n\n if (fixes.length > 0) {\n console.log(\"Proven fixes (resolved errors with recorded fixes):\");\n for (const fix of fixes) {\n const m = JSON.parse(fix.metadata);\n const date = new Date(fix.created_at).toISOString().split(\"T\")[0];\n const title = m.title ?? \"Untitled\";\n const fixText = (m.fix_applied ?? \"\").slice(0, 60);\n console.log(` ${date} ${title.slice(0, 30)} → ${fixText}`);\n }\n console.log();\n }\n\n console.log(`${\"─\".repeat(60)}`);\n console.log(\"Legend: ✓ = resolved, ○ = open, conf = confidence score\");\n console.log();\n console.log(\"How errors are learned:\");\n console.log(\" 1. PostToolUse hook auto-captures failed commands\");\n console.log(\" 2. PreToolUse hook injects past errors before risky commands\");\n console.log(\" 3. Success after failure → upvotes + records proven fix\");\n console.log(\" 4. Recurring errors → downvoted, pruned at confidence=0\");\n console.log(\" 5. Old errors decay via Ebbinghaus curve (0.95^days)\");\n console.log(\" 6. Cross-project patterns detected and alerted\");\n console.log();\n console.log(\"Set TDAI_GLOBAL_ERRORS=1 to inject errors from ALL projects.\");\n\n db.close();\n}\n\n/**\n * `remem-mcp errors retro` — Session retrospective.\n * Analyzes error history for failure loops, wasted effort, repeated errors,\n * and stubborn commands. Helps the agent (and user) learn from patterns.\n *\n * (sheal pattern: `sheal retro` analyzes sessions for failure loops)\n */\nexport function errorsRetro(dbPath: string = defaultDbPath()): void {\n let db: Database.Database;\n try {\n db = new Database(dbPath, { readonly: true });\n } catch {\n console.error(\"Error: Could not open database at\", dbPath);\n process.exit(1);\n }\n\n console.log(\"remem-mcp errors retro — Session Retrospective\\n\");\n console.log(`${\"─\".repeat(60)}\\n`);\n\n // Time window: last 7 days by default (configurable via TDAI_RETRO_DAYS)\n const days = Number(process.env.TDAI_RETRO_DAYS ?? 7);\n const windowClause = `created_at > datetime('now', '-${days} days')`;\n\n // 1. Failure loops — same error recurring 3+ times (downvoted but not pruned)\n const loops = db\n .prepare(\n `SELECT\n json_extract(metadata, '$.title') as title,\n json_extract(metadata, '$.command') as cmd,\n json_extract(metadata, '$.error_type') as etype,\n COUNT(*) as occurrences,\n CAST(json_extract(metadata, '$.downvotes') AS INTEGER) as downvotes,\n CAST(json_extract(metadata, '$.confidence') AS INTEGER) as confidence,\n MIN(created_at) as first_seen,\n MAX(created_at) as last_seen\n FROM captures\n WHERE type = 'error' AND deleted_at IS NULL\n AND ${windowClause}\n AND json_extract(metadata, '$.semantic_hash') IS NOT NULL\n GROUP BY json_extract(metadata, '$.semantic_hash')\n HAVING occurrences >= 3\n ORDER BY occurrences DESC LIMIT 10`,\n )\n .all() as {\n title: string;\n cmd: string;\n etype: string;\n occurrences: number;\n downvotes: number;\n confidence: number;\n first_seen: string;\n last_seen: string;\n }[];\n\n if (loops.length > 0) {\n console.log(`Failure loops (same error recurred 3+ times in last ${days} days):`);\n for (const loop of loops) {\n const title = (loop.title ?? \"Untitled\").slice(0, 45);\n const cmd = (loop.cmd ?? \"unknown\").slice(0, 30);\n const conf = loop.confidence ?? 2;\n const dv = loop.downvotes ?? 0;\n const firstDate = new Date(loop.first_seen).toISOString().split(\"T\")[0];\n const lastDate = new Date(loop.last_seen).toISOString().split(\"T\")[0];\n console.log(` ×${loop.occurrences} ${title}`);\n console.log(` cmd: ${cmd} type: ${loop.etype ?? \"unknown\"}`);\n console.log(` ${firstDate} → ${lastDate} conf=${conf} downvotes=${dv}`);\n if (conf <= 1) {\n console.log(` ⚠ This pattern is fading — will be pruned soon.`);\n }\n console.log();\n }\n } else {\n console.log(`No failure loops detected in the last ${days} days. ✓\\n`);\n }\n\n // 2. Wasted effort — errors captured but never resolved (no fix_applied, no resolved)\n const wasted = db\n .prepare(\n `SELECT\n json_extract(metadata, '$.title') as title,\n json_extract(metadata, '$.command') as cmd,\n json_extract(metadata, '$.error_type') as etype,\n created_at,\n CAST(json_extract(metadata, '$.confidence') AS INTEGER) as confidence\n FROM captures\n WHERE type = 'error' AND deleted_at IS NULL\n AND ${windowClause}\n AND json_extract(metadata, '$.resolved') IS NOT true\n AND json_extract(metadata, '$.fix_applied') IS NULL\n AND json_extract(metadata, '$.confidence') >= 2\n ORDER BY created_at DESC LIMIT 10`,\n )\n .all() as {\n title: string;\n cmd: string;\n etype: string;\n created_at: string;\n confidence: number;\n }[];\n\n if (wasted.length > 0) {\n console.log(`Wasted effort (errors captured but never resolved in last ${days} days):`);\n for (const w of wasted) {\n const title = (w.title ?? \"Untitled\").slice(0, 45);\n const cmd = (w.cmd ?? \"unknown\").slice(0, 30);\n const date = new Date(w.created_at).toISOString().split(\"T\")[0];\n console.log(` ${date} [conf=${w.confidence}] ${title}`);\n console.log(` cmd: ${cmd} type: ${w.etype ?? \"unknown\"}`);\n }\n console.log(\n `\\n 💡 These errors were captured but never resolved. Consider:\\n` +\n ` - Capturing the fix with \\`capture type=error metadata={resolved:true, fix_applied:\"...\"}\\`\\n` +\n ` - Or letting them decay naturally (confidence will reach 0 and prune)\\n`,\n );\n } else {\n console.log(\n `No unresolved errors in the last ${days} days. All errors were resolved or pruned. ✓\\n`,\n );\n }\n\n // 3. Recurring resolved errors — resolved errors that recurred (last_recurred > resolved)\n const recurred = db\n .prepare(\n `SELECT\n json_extract(metadata, '$.title') as title,\n json_extract(metadata, '$.command') as cmd,\n json_extract(metadata, '$.fix_applied') as fix,\n json_extract(metadata, '$.fix_validated') as validated,\n json_extract(metadata, '$.fix_harm_count') as harm,\n CAST(json_extract(metadata, '$.downvotes') AS INTEGER) as downvotes,\n created_at\n FROM captures\n WHERE type = 'error' AND deleted_at IS NULL\n AND ${windowClause}\n AND json_extract(metadata, '$.resolved') = true\n AND CAST(json_extract(metadata, '$.downvotes') AS INTEGER) > 0\n ORDER BY downvotes DESC LIMIT 5`,\n )\n .all() as {\n title: string;\n cmd: string;\n fix: string;\n validated: string;\n harm: number;\n downvotes: number;\n created_at: string;\n }[];\n\n if (recurred.length > 0) {\n console.log(`Resolved errors that recurred (fix may be wrong or incomplete):`);\n for (const r of recurred) {\n const title = (r.title ?? \"Untitled\").slice(0, 45);\n const cmd = (r.cmd ?? \"unknown\").slice(0, 30);\n const fix = (r.fix ?? \"(no fix recorded)\").slice(0, 50);\n const date = new Date(r.created_at).toISOString().split(\"T\")[0];\n const validatedTag = r.validated === \"true\" ? \"✓validated\" : \"✗unvalidated\";\n const harmTag = r.harm > 0 ? ` ⚠harm=${r.harm}` : \"\";\n console.log(` ${date} [downvotes=${r.downvotes}] ${title}`);\n console.log(` cmd: ${cmd}`);\n console.log(` fix: ${fix} ${validatedTag}${harmTag}`);\n }\n console.log(\n `\\n 💡 These \"resolved\" errors recurred. The fix may be:\\n` +\n ` - Wrong (unvalidated fix — stdout had error indicators)\\n` +\n ` - Harmful (fix_harm_count > 0 — fix caused regression)\\n` +\n ` - Incomplete (fix worked once but not in all cases)\\n`,\n );\n }\n\n // 4. Most expensive commands — commands with most error occurrences (cumulative wasted time)\n const expensive = db\n .prepare(\n `SELECT\n json_extract(metadata, '$.command') as cmd,\n COUNT(*) as failures,\n COUNT(DISTINCT json_extract(metadata, '$.semantic_hash')) as unique_errors,\n SUM(CASE WHEN json_extract(metadata, '$.resolved') = true THEN 1 ELSE 0 END) as resolved_count\n FROM captures\n WHERE type = 'error' AND deleted_at IS NULL\n AND ${windowClause}\n AND json_extract(metadata, '$.command') IS NOT NULL\n GROUP BY cmd\n HAVING failures >= 2\n ORDER BY failures DESC LIMIT 5`,\n )\n .all() as {\n cmd: string;\n failures: number;\n unique_errors: number;\n resolved_count: number;\n }[];\n\n if (expensive.length > 0) {\n console.log(`Most expensive commands (by failure count in last ${days} days):`);\n for (const e of expensive) {\n const cmd = (e.cmd ?? \"unknown\").slice(0, 40);\n const resolveRate = e.failures > 0 ? ((e.resolved_count / e.failures) * 100).toFixed(0) : \"0\";\n console.log(\n ` ${cmd.padEnd(40)} ${e.failures} failures, ${e.unique_errors} unique errors, ${resolveRate}% resolved`,\n );\n }\n console.log();\n }\n\n // 5. Harmful fixes — fixes that caused regressions (fix_harm_count > 0)\n const harmful = db\n .prepare(\n `SELECT\n json_extract(metadata, '$.title') as title,\n json_extract(metadata, '$.command') as cmd,\n json_extract(metadata, '$.fix_applied') as fix,\n CAST(json_extract(metadata, '$.fix_harm_count') AS INTEGER) as harm,\n created_at\n FROM captures\n WHERE type = 'error' AND deleted_at IS NULL\n AND ${windowClause}\n AND CAST(json_extract(metadata, '$.fix_harm_count') AS INTEGER) > 0\n ORDER BY harm DESC LIMIT 5`,\n )\n .all() as {\n title: string;\n cmd: string;\n fix: string;\n harm: number;\n created_at: string;\n }[];\n\n if (harmful.length > 0) {\n console.log(`Harmful fixes (fix caused regression — blocked from re-injection):`);\n for (const h of harmful) {\n const title = (h.title ?? \"Untitled\").slice(0, 45);\n const fix = (h.fix ?? \"(no fix recorded)\").slice(0, 50);\n const date = new Date(h.created_at).toISOString().split(\"T\")[0];\n console.log(` ${date} [harm=${h.harm}] ${title}`);\n console.log(` fix: ${fix}`);\n }\n console.log(\n `\\n 💡 These fixes were blocked by the harm gate. Do NOT re-apply them.\\n` +\n ` Find a different fix for the same error.\\n`,\n );\n }\n\n // 6. Drift violations — errors injected but still occurred\n const driftViolations = db\n .prepare(\n `SELECT\n json_extract(metadata, '$.title') as title,\n json_extract(metadata, '$.command') as cmd,\n CAST(json_extract(metadata, '$.drift_count') AS INTEGER) as drift_count,\n json_extract(metadata, '$.last_drift_at') as last_drift\n FROM captures\n WHERE type = 'error' AND deleted_at IS NULL\n AND ${windowClause}\n AND CAST(json_extract(metadata, '$.drift_count') AS INTEGER) > 0\n ORDER BY drift_count DESC LIMIT 5`,\n )\n .all() as { title: string; cmd: string; drift_count: number; last_drift: string }[];\n\n if (driftViolations.length > 0) {\n console.log(`Drift violations (injected errors that still occurred):`);\n for (const d of driftViolations) {\n const title = (d.title ?? \"Untitled\").slice(0, 45);\n const cmd = (d.cmd ?? \"unknown\").slice(0, 30);\n const severity = d.drift_count >= 3 ? \"●●●\" : d.drift_count === 2 ? \"●●\" : \"●\";\n console.log(` ${severity} [drift=${d.drift_count}] ${title}`);\n console.log(` cmd: ${cmd}`);\n }\n console.log(\n `\\n 💡 These errors were injected as warnings but the agent still hit them.\\n` +\n ` Run \\`remem-mcp errors drift\\` for the full report.\\n`,\n );\n }\n\n // 7. Fix Effectiveness Scoring — measure how long fixes last before recurrence\n // (MTBF pattern from SRE: Mean Time Between Failures applied to agent fixes)\n const durableFixes = db\n .prepare(\n `SELECT\n json_extract(metadata, '$.title') as title,\n json_extract(metadata, '$.fix_applied') as fix,\n json_extract(metadata, '$.resolved_at') as resolved_at,\n json_extract(metadata, '$.last_recurred') as last_recurred,\n CAST(\n julianday(json_extract(metadata, '$.last_recurred')) -\n julianday(json_extract(metadata, '$.resolved_at'))\n AS REAL) as fix_duration_days\n FROM captures\n WHERE type = 'error' AND deleted_at IS NULL\n AND ${windowClause}\n AND json_extract(metadata, '$.resolved') = true\n AND json_extract(metadata, '$.resolved_at') IS NOT NULL\n AND json_extract(metadata, '$.last_recurred') IS NOT NULL\n ORDER BY fix_duration_days DESC LIMIT 5`,\n )\n .all() as {\n title: string;\n fix: string;\n resolved_at: string;\n last_recurred: string;\n fix_duration_days: number;\n }[];\n\n const fragileFixes = db\n .prepare(\n `SELECT\n json_extract(metadata, '$.title') as title,\n json_extract(metadata, '$.fix_applied') as fix,\n json_extract(metadata, '$.resolved_at') as resolved_at,\n json_extract(metadata, '$.last_recurred') as last_recurred,\n CAST(\n julianday(json_extract(metadata, '$.last_recurred')) -\n julianday(json_extract(metadata, '$.resolved_at'))\n AS REAL) as fix_duration_days\n FROM captures\n WHERE type = 'error' AND deleted_at IS NULL\n AND ${windowClause}\n AND json_extract(metadata, '$.resolved') = true\n AND json_extract(metadata, '$.resolved_at') IS NOT NULL\n AND json_extract(metadata, '$.last_recurred') IS NOT NULL\n AND (\n julianday(json_extract(metadata, '$.last_recurred')) -\n julianday(json_extract(metadata, '$.resolved_at'))\n ) < 0.042 -- less than 1 hour = 1/24 day\n ORDER BY fix_duration_days ASC LIMIT 5`,\n )\n .all() as {\n title: string;\n fix: string;\n resolved_at: string;\n last_recurred: string;\n fix_duration_days: number;\n }[];\n\n if (durableFixes.length > 0 || fragileFixes.length > 0) {\n console.log(\"Fix effectiveness (MTBF — Mean Time Between Failures):\");\n if (durableFixes.length > 0) {\n console.log(\" Most durable fixes (lasted longest before recurrence):\");\n for (const f of durableFixes) {\n const title = (f.title ?? \"Untitled\").slice(0, 45);\n const days = f.fix_duration_days.toFixed(1);\n const fix = (f.fix ?? \"unknown fix\").slice(0, 50);\n console.log(` ✓ ${days}d ${title}`);\n console.log(` fix: ${fix}`);\n }\n }\n if (fragileFixes.length > 0) {\n console.log(\" Fragile fixes (recurred within 1 hour):\");\n for (const f of fragileFixes) {\n const title = (f.title ?? \"Untitled\").slice(0, 45);\n const hours = (f.fix_duration_days * 24).toFixed(1);\n const fix = (f.fix ?? \"unknown fix\").slice(0, 50);\n console.log(` ⚠ ${hours}h ${title}`);\n console.log(` fix: ${fix}`);\n }\n console.log(`\\n 💡 Fragile fixes recurred quickly. The fix may be incomplete or wrong.\\n`);\n }\n console.log();\n }\n\n // 8. Summary scorecard\n const totalErrors = db\n .prepare(\n `SELECT COUNT(*) as c FROM captures WHERE type = 'error' AND deleted_at IS NULL AND ${windowClause}`,\n )\n .get() as { c: number };\n\n const totalResolved = db\n .prepare(\n `SELECT COUNT(*) as c FROM captures WHERE type = 'error' AND deleted_at IS NULL\n AND ${windowClause} AND json_extract(metadata, '$.resolved') = true`,\n )\n .get() as { c: number };\n\n const totalPruned = db\n .prepare(\n `SELECT COUNT(*) as c FROM captures WHERE type = 'error' AND deleted_at IS NOT NULL\n AND ${windowClause}`,\n )\n .get() as { c: number };\n\n console.log(`${\"─\".repeat(60)}`);\n console.log(`Retrospective scorecard (last ${days} days):`);\n console.log(` Total errors: ${totalErrors.c}`);\n console.log(` Resolved: ${totalResolved.c}`);\n console.log(` Pruned (faded): ${totalPruned.c}`);\n console.log(` Failure loops: ${loops.length}`);\n console.log(` Wasted effort: ${wasted.length}`);\n console.log(` Recurred resolved: ${recurred.length}`);\n console.log(` Harmful fixes: ${harmful.length}`);\n console.log(` Drift violations: ${driftViolations.length}`);\n console.log(` Durable fixes: ${durableFixes.length}`);\n console.log(` Fragile fixes: ${fragileFixes.length}`);\n\n // [Fix Attempt Counter] Show most stubborn errors (high attempt_count)\n const stubborn = db\n .prepare(\n `SELECT\n json_extract(metadata, '$.title') as title,\n json_extract(metadata, '$.attempt_count') as attempts,\n json_extract(metadata, '$.error_type') as etype,\n json_extract(metadata, '$.resolved') as resolved\n FROM captures\n WHERE type = 'error' AND deleted_at IS NULL\n AND ${windowClause}\n AND CAST(json_extract(metadata, '$.attempt_count') AS INTEGER) >= 3\n ORDER BY CAST(json_extract(metadata, '$.attempt_count') AS INTEGER) DESC LIMIT 5`,\n )\n .all() as { title: string; attempts: string; etype: string; resolved: string }[];\n\n if (stubborn.length > 0) {\n console.log();\n console.log(\"Most stubborn errors (3+ attempts):\");\n for (const s of stubborn) {\n const title = (s.title ?? \"Untitled\").slice(0, 45);\n const resolved = s.resolved === \"true\" ? \" ✓\" : \"\";\n console.log(` ${s.attempts}x ${title}${resolved}`);\n }\n }\n console.log();\n\n // Recommendations\n console.log(\"Recommendations:\");\n if (loops.length > 0) {\n console.log(\n ` 1. ${loops.length} failure loop(s) detected — review the error and find a different fix.`,\n );\n }\n if (wasted.length > 5) {\n console.log(` 2. ${wasted.length} unresolved errors — capture fixes or let them decay.`);\n }\n if (recurred.length > 0) {\n console.log(\n ` 3. ${recurred.length} \"resolved\" error(s) recurred — the fix is wrong or incomplete.`,\n );\n }\n if (harmful.length > 0) {\n console.log(` 4. ${harmful.length} harmful fix(es) — find alternative approaches.`);\n }\n if (driftViolations.length > 0) {\n console.log(\n ` 5. ${driftViolations.length} drift violation(s) — injected warnings were ignored. Review injection format.`,\n );\n }\n if (fragileFixes.length > 0) {\n console.log(\n ` 6. ${fragileFixes.length} fragile fix(es) — recurred within 1 hour. Fix may be incomplete.`,\n );\n }\n if (\n loops.length === 0 &&\n wasted.length === 0 &&\n recurred.length === 0 &&\n harmful.length === 0 &&\n driftViolations.length === 0 &&\n fragileFixes.length === 0\n ) {\n console.log(\" ✓ No issues detected. Error learning is working well.\");\n }\n console.log();\n console.log(\"Set TDAI_RETRO_DAYS=N to change the analysis window (default: 7).\");\n\n db.close();\n}\n\n/**\n * `remem-mcp errors drift` — Drift detection report.\n * Shows errors that were injected by PreToolUse but still occurred\n * (the agent was warned but ignored the warning).\n *\n * (sheal pattern: `sheal drift` — detects when stored learnings are not applied)\n */\nexport function errorsDrift(dbPath: string = defaultDbPath()): void {\n let db: Database.Database;\n try {\n db = new Database(dbPath, { readonly: true });\n } catch {\n console.error(\"Error: Could not open database at\", dbPath);\n process.exit(1);\n }\n\n console.log(\"remem-mcp errors drift — Drift Detection Report\\n\");\n console.log(`${\"─\".repeat(60)}\\n`);\n\n const days = Number(process.env.TDAI_RETRO_DAYS ?? 7);\n const windowClause = `created_at > datetime('now', '-${days} days')`;\n\n // 1. Drift violations — errors with drift_count > 0\n const violations = db\n .prepare(\n `SELECT\n id,\n content,\n json_extract(metadata, '$.title') as title,\n json_extract(metadata, '$.command') as cmd,\n json_extract(metadata, '$.error_type') as etype,\n CAST(json_extract(metadata, '$.drift_count') AS INTEGER) as drift_count,\n json_extract(metadata, '$.last_drift_at') as last_drift,\n CAST(json_extract(metadata, '$.confidence') AS INTEGER) as confidence,\n CAST(json_extract(metadata, '$.downvotes') AS INTEGER) as downvotes,\n json_extract(metadata, '$.resolved') as resolved,\n created_at\n FROM captures\n WHERE type = 'error' AND deleted_at IS NULL\n AND ${windowClause}\n AND CAST(json_extract(metadata, '$.drift_count') AS INTEGER) > 0\n ORDER BY drift_count DESC, created_at DESC LIMIT 20`,\n )\n .all() as {\n id: string;\n content: string;\n title: string;\n cmd: string;\n etype: string;\n drift_count: number;\n last_drift: string;\n confidence: number;\n downvotes: number;\n resolved: string;\n created_at: string;\n }[];\n\n if (violations.length > 0) {\n console.log(`Drift violations (errors injected but still occurred in last ${days} days):`);\n console.log();\n for (const v of violations) {\n const title = (v.title ?? \"Untitled\").slice(0, 50);\n const cmd = (v.cmd ?? \"unknown\").slice(0, 35);\n const date = new Date(v.created_at).toISOString().split(\"T\")[0];\n const severity = v.drift_count >= 3 ? \"●●●\" : v.drift_count === 2 ? \"●●\" : \"●\";\n const resolvedTag = v.resolved === \"true\" ? \" ✓resolved\" : \"\";\n const driftDate = v.last_drift ? new Date(v.last_drift).toISOString().split(\"T\")[0] : \"?\";\n\n console.log(` ${severity} [drift=${v.drift_count}] ${title}`);\n console.log(` cmd: ${cmd} type: ${v.etype ?? \"unknown\"}`);\n console.log(\n ` captured: ${date} last_drift: ${driftDate} conf=${v.confidence} downvotes=${v.downvotes}${resolvedTag}`,\n );\n console.log();\n }\n } else {\n console.log(`No drift violations in the last ${days} days. ✓`);\n console.log(\"All injected errors were heeded by the agent.\\n\");\n }\n\n // 2. Summary stats\n const totalDrift = db\n .prepare(\n `SELECT COUNT(*) as c, SUM(CAST(json_extract(metadata, '$.drift_count') AS INTEGER)) as total_drifts\n FROM captures\n WHERE type = 'error' AND deleted_at IS NULL\n AND ${windowClause}\n AND CAST(json_extract(metadata, '$.drift_count') AS INTEGER) > 0`,\n )\n .get() as { c: number; total_drifts: number };\n\n const totalErrors = db\n .prepare(\n `SELECT COUNT(*) as c FROM captures WHERE type = 'error' AND deleted_at IS NULL AND ${windowClause}`,\n )\n .get() as { c: number };\n\n const totalInjections = db\n .prepare(\n `SELECT COUNT(*) as c FROM captures\n WHERE type = 'error' AND deleted_at IS NULL\n AND ${windowClause}\n AND json_extract(metadata, '$.downvotes') IS NOT NULL`,\n )\n .get() as { c: number };\n\n console.log(`${\"─\".repeat(60)}`);\n console.log(\"Drift scorecard:\");\n console.log(` Total errors: ${totalErrors.c}`);\n console.log(` Errors with drift: ${totalDrift.c}`);\n console.log(` Total drift events: ${totalDrift.total_drifts ?? 0}`);\n if (totalErrors.c > 0) {\n const driftRate = ((totalDrift.c / totalErrors.c) * 100).toFixed(1);\n console.log(` Drift rate: ${driftRate}%`);\n }\n console.log();\n\n // 3. Effectiveness assessment\n console.log(\"Effectiveness assessment:\");\n if (totalDrift.c === 0) {\n console.log(\" ✓ Error injection is effective — no drift detected.\");\n } else if (totalErrors.c > 0) {\n const rate = (totalDrift.c / totalErrors.c) * 100;\n if (rate <= 10) {\n console.log(\" ✓ Low drift rate — injection is mostly effective.\");\n } else if (rate < 30) {\n console.log(\" ⚠ Moderate drift rate — some errors are not being heeded.\");\n console.log(\" Consider improving the anti-pattern or correct_approach text.\");\n } else {\n console.log(\" ⚠ High drift rate — many injected errors are still occurring.\");\n console.log(\" The agent may be ignoring warnings. Review the injection format.\");\n }\n }\n console.log();\n\n // 4. Severity breakdown\n if (violations.length > 0) {\n const high = violations.filter((v) => v.drift_count >= 3).length;\n const mid = violations.filter((v) => v.drift_count === 2).length;\n const low = violations.filter((v) => v.drift_count === 1).length;\n console.log(\"Severity breakdown:\");\n console.log(` ●●● High (3+ drifts): ${high} (agent repeatedly ignored warning)`);\n console.log(` ●● Medium (2 drifts): ${mid} (warning ignored twice)`);\n console.log(` ● Low (1 drift): ${low} (first drift event)`);\n console.log();\n }\n\n console.log(\"Legend: ● = 1 drift, ●● = 2 drifts, ●●● = 3+ drifts\");\n console.log(\"Drift = error was injected by PreToolUse but agent still failed.\");\n console.log();\n console.log(\"Set TDAI_RETRO_DAYS=N to change the analysis window (default: 7).\");\n\n db.close();\n}\n\n/**\n * `remem-mcp errors lineage` — Fix lineage chain report.\n * Shows chains of errors linked by caused_by_error_id:\n * E1 → F1 → E2 → F2 → E3\n * where each fix caused the next error (regression chain).\n */\nexport function errorsLineage(dbPath: string = defaultDbPath()): void {\n let db: Database.Database;\n try {\n db = new Database(dbPath, { readonly: true });\n } catch {\n console.error(\"Error: Could not open database at\", dbPath);\n process.exit(1);\n }\n\n console.log(\"remem-mcp errors lineage — Fix Lineage Chains\\n\");\n console.log(`${\"─\".repeat(60)}\\n`);\n\n const days = Number(process.env.TDAI_RETRO_DAYS ?? 7);\n const windowClause = `created_at > datetime('now', '-${days} days')`;\n\n // Find all errors that have a caused_by_error_id (they're the \"child\" in a chain)\n const children = db\n .prepare(\n `SELECT\n id,\n json_extract(metadata, '$.title') as title,\n json_extract(metadata, '$.command') as cmd,\n json_extract(metadata, '$.error_type') as etype,\n json_extract(metadata, '$.caused_by_error_id') as parent_id,\n json_extract(metadata, '$.fix_applied') as fix,\n json_extract(metadata, '$.resolved') as resolved,\n created_at\n FROM captures\n WHERE type = 'error' AND deleted_at IS NULL\n AND ${windowClause}\n AND json_extract(metadata, '$.caused_by_error_id') IS NOT NULL\n ORDER BY created_at DESC LIMIT 20`,\n )\n .all() as {\n id: string;\n title: string;\n cmd: string;\n etype: string;\n parent_id: string;\n fix: string;\n resolved: string;\n created_at: string;\n }[];\n\n if (children.length === 0) {\n console.log(`No fix lineage chains in the last ${days} days. ✓`);\n console.log(\"No errors were caused by previous fixes.\\n\");\n db.close();\n return;\n }\n\n // Build chains by looking up parents\n const allErrors = new Map<\n string,\n { id: string; title: string; cmd: string; fix: string; resolved: string }\n >();\n for (const c of children) {\n allErrors.set(c.id, {\n id: c.id,\n title: c.title ?? \"Untitled\",\n cmd: c.cmd ?? \"unknown\",\n fix: c.fix ?? \"\",\n resolved: c.resolved ?? \"false\",\n });\n }\n\n // Also fetch parent errors\n const parentIds = [...new Set(children.map((c) => c.parent_id))];\n for (const pid of parentIds) {\n if (allErrors.has(pid)) continue;\n const parent = db\n .prepare(\n `SELECT\n id,\n json_extract(metadata, '$.title') as title,\n json_extract(metadata, '$.command') as cmd,\n json_extract(metadata, '$.fix_applied') as fix,\n json_extract(metadata, '$.resolved') as resolved\n FROM captures WHERE id = ?`,\n )\n .get(pid) as\n | {\n id: string;\n title: string;\n cmd: string;\n fix: string;\n resolved: string;\n }\n | undefined;\n if (parent) {\n allErrors.set(parent.id, {\n id: parent.id,\n title: parent.title ?? \"Untitled\",\n cmd: parent.cmd ?? \"unknown\",\n fix: parent.fix ?? \"\",\n resolved: parent.resolved ?? \"false\",\n });\n }\n }\n\n // Build and display chains\n console.log(`Fix lineage chains (last ${days} days):`);\n console.log();\n\n const displayed = new Set<string>();\n for (const child of children) {\n if (displayed.has(child.id)) continue;\n displayed.add(child.id);\n\n // Walk up the chain to find the root\n const chain: string[] = [];\n let currentId: string | null = child.id;\n while (currentId && allErrors.has(currentId)) {\n if (chain.includes(currentId)) break; // prevent cycles\n chain.unshift(currentId);\n // Find this error's parent\n const c = children.find((x) => x.id === currentId);\n currentId = c?.parent_id ?? null;\n }\n\n // Display the chain\n for (let i = 0; i < chain.length; i++) {\n const err = allErrors.get(chain[i])!;\n const indent = \" \".repeat(i);\n const resolved = err.resolved === \"true\" ? \" ✓\" : \"\";\n const shortId = err.id.slice(0, 8);\n\n if (i === 0) {\n console.log(`${indent}E${i + 1}: [${shortId}] ${err.title.slice(0, 45)}${resolved}`);\n console.log(`${indent} cmd: ${err.cmd.slice(0, 35)}`);\n } else {\n const parentErr = allErrors.get(chain[i - 1])!;\n const fixText = parentErr.fix ? parentErr.fix.slice(0, 50) : \"unknown fix\";\n console.log(`${indent} ↓ fix: ${fixText}`);\n console.log(`${indent}E${i + 1}: [${shortId}] ${err.title.slice(0, 45)}${resolved}`);\n console.log(`${indent} cmd: ${err.cmd.slice(0, 35)}`);\n }\n }\n console.log();\n }\n\n // Summary\n console.log(`${\"─\".repeat(60)}`);\n console.log(\"Lineage scorecard:\");\n console.log(` Total chained errors: ${children.length}`);\n let maxDepth = 1;\n for (const c of children) {\n let depth = 1;\n let currentId: string | null = c.id;\n const visited = new Set<string>();\n while (currentId && !visited.has(currentId)) {\n visited.add(currentId);\n const ch = children.find((x) => x.id === currentId);\n if (ch) {\n depth++;\n currentId = ch.parent_id;\n } else {\n break;\n }\n }\n if (depth > maxDepth) maxDepth = depth;\n }\n console.log(` Max chain depth: ${maxDepth}`);\n console.log();\n\n // Assessment\n console.log(\"Assessment:\");\n if (children.length >= 5) {\n console.log(\" ⚠ High fix cascade — many fixes are causing new errors.\");\n console.log(\" Review the root causes, not just the symptoms.\");\n } else if (children.length >= 2) {\n console.log(\" ⚠ Some fix cascades detected — check if fixes address root causes.\");\n } else {\n console.log(\" ✓ Low fix cascade — most fixes don't cause new errors.\");\n }\n console.log();\n\n console.log(\"Legend: E1 = original error, ↓ fix = fix applied, E2 = new error caused by fix\");\n console.log();\n\n // [Mermaid Canvas] Render lineage as Mermaid graph for visual inspection.\n // (TencentDB symbolic memory pattern: maximum semantics in minimum symbols)\n if (children.length > 0) {\n console.log(\"Mermaid canvas (paste into any Mermaid renderer):\");\n console.log();\n console.log(\"```mermaid\");\n console.log(\"graph LR\");\n const rendered = new Set<string>();\n for (const child of children) {\n if (rendered.has(child.id)) continue;\n rendered.add(child.id);\n\n // Walk chain\n const chain: string[] = [];\n let cur: string | null = child.id;\n while (cur && allErrors.has(cur) && !chain.includes(cur)) {\n chain.unshift(cur);\n const c = children.find((x) => x.id === cur);\n cur = c?.parent_id ?? null;\n }\n\n // Emit nodes + edges\n for (let i = 0; i < chain.length; i++) {\n const err = allErrors.get(chain[i])!;\n const nodeId = `E${chain[i].slice(0, 6)}`;\n const label = (err.title ?? \"Untitled\").replace(/[\"\\\\]/g, \"\").slice(0, 30);\n const status = err.resolved === \"true\" ? \" ✓\" : \"\";\n console.log(` ${nodeId}[\"${label}${status}\"]`);\n\n if (i > 0) {\n const parentNodeId = `E${chain[i - 1].slice(0, 6)}`;\n const parentErr = allErrors.get(chain[i - 1])!;\n const fixLabel = parentErr.fix ? parentErr.fix.replace(/[\"\\\\]/g, \"\").slice(0, 25) : \"fix\";\n console.log(` ${parentNodeId} -->|fix: ${fixLabel}| ${nodeId}`);\n }\n }\n }\n console.log(\"```\");\n console.log();\n }\n\n console.log(\"Set TDAI_RETRO_DAYS=N to change the analysis window (default: 7).\");\n\n db.close();\n}\n\n/**\n * `remem-mcp errors by-goal` — Goal-linked error report.\n * Shows error distribution by goal_id (set via TDAI_GOAL_ID env var).\n * (LoopX-inspired: link errors to the goals they block)\n */\nexport function errorsByGoal(dbPath: string = defaultDbPath()): void {\n let db: Database.Database;\n try {\n db = new Database(dbPath, { readonly: true });\n } catch {\n console.error(\"Error: Could not open database at\", dbPath);\n process.exit(1);\n }\n\n console.log(\"remem-mcp errors by-goal — Goal-Linked Error Report\\n\");\n console.log(`${\"─\".repeat(60)}\\n`);\n\n const days = Number(process.env.TDAI_RETRO_DAYS ?? 7);\n const windowClause = `created_at > datetime('now', '-${days} days')`;\n\n // Group errors by goal_id\n const byGoal = db\n .prepare(\n `SELECT\n json_extract(metadata, '$.goal_id') as goal_id,\n COUNT(*) as error_count,\n SUM(CASE WHEN json_extract(metadata, '$.resolved') = true THEN 1 ELSE 0 END) as resolved_count,\n GROUP_CONCAT(DISTINCT json_extract(metadata, '$.error_type')) as error_types\n FROM captures\n WHERE type = 'error' AND deleted_at IS NULL\n AND ${windowClause}\n AND json_extract(metadata, '$.goal_id') IS NOT NULL\n GROUP BY goal_id\n ORDER BY error_count DESC`,\n )\n .all() as {\n goal_id: string;\n error_count: number;\n resolved_count: number;\n error_types: string;\n }[];\n\n if (byGoal.length === 0) {\n console.log(`No goal-linked errors in the last ${days} days.`);\n console.log(\"Set TDAI_GOAL_ID=<goal-id> to tag errors with a goal.\\n\");\n db.close();\n return;\n }\n\n console.log(`Error distribution by goal (last ${days} days):`);\n console.log();\n for (const g of byGoal) {\n const resolveRate =\n g.error_count > 0 ? ((g.resolved_count / g.error_count) * 100).toFixed(0) : \"0\";\n const types = (g.error_types ?? \"\").split(\",\").filter(Boolean).slice(0, 5).join(\", \");\n console.log(` Goal: ${g.goal_id}`);\n console.log(` Errors: ${g.error_count} Resolved: ${g.resolved_count} (${resolveRate}%)`);\n console.log(` Types: ${types}`);\n console.log();\n }\n\n // Summary\n const totalGoalErrors = byGoal.reduce((sum, g) => sum + g.error_count, 0);\n const totalResolved = byGoal.reduce((sum, g) => sum + g.resolved_count, 0);\n console.log(`${\"─\".repeat(60)}`);\n console.log(\"Goal scorecard:\");\n console.log(` Goals with errors: ${byGoal.length}`);\n console.log(` Total goal errors: ${totalGoalErrors}`);\n console.log(` Total resolved: ${totalResolved}`);\n console.log();\n\n // Most error-prone goal\n const worst = byGoal[0];\n console.log(`Most error-prone goal: ${worst.goal_id} (${worst.error_count} errors)`);\n console.log();\n console.log(\"Set TDAI_GOAL_ID=<goal-id> to tag new errors with a goal.\");\n console.log(\"Set TDAI_RETRO_DAYS=N to change the analysis window (default: 7).\");\n\n db.close();\n}\n\n/**\n * `remem-mcp errors actions` — Error action item tracker.\n * Shows postmortem action items generated from resolved errors.\n * (SRE pattern: track preventive actions from incident postmortems)\n */\nexport function errorsActions(dbPath: string = defaultDbPath()): void {\n let db: Database.Database;\n try {\n db = new Database(dbPath, { readonly: true });\n } catch {\n console.error(\"Error: Could not open database at\", dbPath);\n process.exit(1);\n }\n\n console.log(\"remem-mcp errors actions — Action Item Tracker\\n\");\n console.log(`${\"─\".repeat(60)}\\n`);\n\n const days = Number(process.env.TDAI_RETRO_DAYS ?? 7);\n const windowClause = `created_at > datetime('now', '-${days} days')`;\n\n // Resolved errors with fixes = potential action items\n // (The fix was applied, but was a systemic prevention action taken?)\n const resolved = db\n .prepare(\n `SELECT\n id,\n json_extract(metadata, '$.title') as title,\n json_extract(metadata, '$.fix_applied') as fix,\n json_extract(metadata, '$.error_type') as etype,\n json_extract(metadata, '$.fix_validated') as validated,\n json_extract(metadata, '$.fix_harm_count') as harm,\n json_extract(metadata, '$.drift_count') as drift,\n json_extract(metadata, '$.downvotes') as downvotes,\n json_extract(metadata, '$.resolved_at') as resolved_at,\n json_extract(metadata, '$.last_recurred') as last_recurred\n FROM captures\n WHERE type = 'error' AND deleted_at IS NULL\n AND ${windowClause}\n AND json_extract(metadata, '$.resolved') = true\n AND json_extract(metadata, '$.fix_applied') IS NOT NULL\n ORDER BY resolved_at DESC LIMIT 20`,\n )\n .all() as {\n id: string;\n title: string;\n fix: string;\n etype: string;\n validated: string;\n harm: string;\n drift: string;\n downvotes: string;\n resolved_at: string;\n last_recurred: string;\n }[];\n\n if (resolved.length === 0) {\n console.log(`No resolved errors with fixes in the last ${days} days.`);\n console.log(\"Action items are generated from resolved errors.\\n\");\n db.close();\n return;\n }\n\n // Categorize action items\n const open: typeof resolved = [];\n const verified: typeof resolved = [];\n const recurring: typeof resolved = [];\n\n for (const r of resolved) {\n const driftCount = Number(r.drift ?? 0);\n const downvotes = Number(r.downvotes ?? 0);\n const harmCount = Number(r.harm ?? 0);\n const validated =\n r.validated === \"true\" || r.validated === \"1\" || r.validated === 1 || r.validated === true;\n\n if (harmCount > 0 || downvotes > 0 || driftCount > 0) {\n recurring.push(r);\n } else if (validated) {\n verified.push(r);\n } else {\n open.push(r);\n }\n }\n\n console.log(`Action items from resolved errors (last ${days} days):`);\n console.log();\n\n if (verified.length > 0) {\n console.log(\"Verified fixes (clean success, no recurrence):\");\n for (const r of verified.slice(0, 5)) {\n const title = (r.title ?? \"Untitled\").slice(0, 45);\n const fix = (r.fix ?? \"\").slice(0, 50);\n const date = r.resolved_at ? new Date(r.resolved_at).toISOString().split(\"T\")[0] : \"?\";\n console.log(` ✓ ${date} ${title}`);\n console.log(` fix: ${fix}`);\n }\n console.log();\n }\n\n if (open.length > 0) {\n console.log(\"Open action items (fix not yet validated):\");\n for (const r of open.slice(0, 5)) {\n const title = (r.title ?? \"Untitled\").slice(0, 45);\n const fix = (r.fix ?? \"\").slice(0, 50);\n const date = r.resolved_at ? new Date(r.resolved_at).toISOString().split(\"T\")[0] : \"?\";\n console.log(` ⚠ ${date} ${title}`);\n console.log(` fix: ${fix}`);\n console.log(` → Verify the fix with a clean test run`);\n }\n console.log();\n }\n\n if (recurring.length > 0) {\n console.log(\"Recurring action items (fix recurred — needs stronger fix):\");\n for (const r of recurring.slice(0, 5)) {\n const title = (r.title ?? \"Untitled\").slice(0, 45);\n const fix = (r.fix ?? \"\").slice(0, 50);\n const date = r.resolved_at ? new Date(r.resolved_at).toISOString().split(\"T\")[0] : \"?\";\n const harmCount = Number(r.harm ?? 0);\n const driftCount = Number(r.drift ?? 0);\n const downvotes = Number(r.downvotes ?? 0);\n const flags: string[] = [];\n if (harmCount > 0) flags.push(`harm=${harmCount}`);\n if (driftCount > 0) flags.push(`drift=${driftCount}`);\n if (downvotes > 0) flags.push(`downvotes=${downvotes}`);\n console.log(` ✗ ${date} ${title} [${flags.join(\", \")}]`);\n console.log(` fix: ${fix}`);\n console.log(` → Find a different, stronger fix`);\n }\n console.log();\n }\n\n // Summary\n console.log(`${\"─\".repeat(60)}`);\n console.log(\"Action item scorecard:\");\n console.log(` Total resolved: ${resolved.length}`);\n console.log(` Verified fixes: ${verified.length}`);\n console.log(` Open (unvalidated): ${open.length}`);\n console.log(` Recurring (failed): ${recurring.length}`);\n console.log();\n\n // Recommendations\n console.log(\"Recommendations:\");\n if (open.length > 0) {\n console.log(` 1. ${open.length} unvalidated fix(es) — run a clean test to verify.`);\n }\n if (recurring.length > 0) {\n console.log(\n ` 2. ${recurring.length} recurring fix(es) — the fix is wrong. Find a different approach.`,\n );\n }\n if (open.length === 0 && recurring.length === 0) {\n console.log(\" ✓ All fixes are verified and stable.\");\n }\n console.log();\n console.log(\"Set TDAI_RETRO_DAYS=N to change the analysis window (default: 7).\");\n\n db.close();\n}\n\n/**\n * `remem-mcp errors severity` — Error severity distribution.\n * Shows errors classified as blocker/critical/major/minor.\n * (SRE pattern: prioritize by business impact, not just frequency)\n */\nexport function errorsSeverity(dbPath: string = defaultDbPath()): void {\n let db: Database.Database;\n try {\n db = new Database(dbPath, { readonly: true });\n } catch {\n console.error(\"Error: Could not open database at\", dbPath);\n process.exit(1);\n }\n\n console.log(\"remem-mcp errors severity — Impact Classification\\n\");\n console.log(`${\"─\".repeat(60)}\\n`);\n\n const days = Number(process.env.TDAI_RETRO_DAYS ?? 7);\n const windowClause = `created_at > datetime('now', '-${days} days')`;\n\n // Count by severity\n const bySeverity = db\n .prepare(\n `SELECT\n COALESCE(json_extract(metadata, '$.severity'), 'major') as severity,\n COUNT(*) as count,\n SUM(CASE WHEN json_extract(metadata, '$.resolved') = true THEN 1 ELSE 0 END) as resolved\n FROM captures\n WHERE type = 'error' AND deleted_at IS NULL\n AND ${windowClause}\n GROUP BY severity\n ORDER BY CASE severity\n WHEN 'blocker' THEN 0\n WHEN 'critical' THEN 1\n WHEN 'major' THEN 2\n WHEN 'minor' THEN 3\n ELSE 2\n END`,\n )\n .all() as { severity: string; count: number; resolved: number }[];\n\n if (bySeverity.length === 0) {\n console.log(`No errors in the last ${days} days.\\n`);\n db.close();\n return;\n }\n\n const icons: Record<string, string> = {\n blocker: \"🔴\",\n critical: \"🟠\",\n major: \"🟡\",\n minor: \"🟢\",\n };\n\n console.log(`Severity distribution (last ${days} days):`);\n console.log();\n for (const s of bySeverity) {\n const icon = icons[s.severity] ?? \"🟡\";\n const resolveRate = s.count > 0 ? ((s.resolved / s.count) * 100).toFixed(0) : \"0\";\n console.log(\n ` ${icon} ${s.severity.padEnd(10)} ${String(s.count).padStart(4)} errors (${resolveRate}% resolved)`,\n );\n }\n console.log();\n\n // Show top blocker/critical errors\n const blockers = db\n .prepare(\n `SELECT\n json_extract(metadata, '$.title') as title,\n json_extract(metadata, '$.command') as cmd,\n json_extract(metadata, '$.severity') as severity,\n json_extract(metadata, '$.resolved') as resolved,\n created_at\n FROM captures\n WHERE type = 'error' AND deleted_at IS NULL\n AND ${windowClause}\n AND json_extract(metadata, '$.severity') IN ('blocker', 'critical')\n ORDER BY created_at DESC LIMIT 10`,\n )\n .all() as {\n title: string;\n cmd: string;\n severity: string;\n resolved: string;\n created_at: string;\n }[];\n\n if (blockers.length > 0) {\n console.log(\"Top blocker/critical errors:\");\n for (const b of blockers) {\n const icon = icons[b.severity] ?? \"🟡\";\n const title = (b.title ?? \"Untitled\").slice(0, 45);\n const cmd = (b.cmd ?? \"\").slice(0, 30);\n const resolved = b.resolved === \"true\" ? \" ✓\" : \"\";\n const date = new Date(b.created_at).toISOString().split(\"T\")[0];\n console.log(` ${icon} ${date} ${title}${resolved}`);\n console.log(` cmd: ${cmd}`);\n }\n console.log();\n }\n\n // Summary\n const total = bySeverity.reduce((sum, s) => sum + s.count, 0);\n const blockerCount = bySeverity.find((s) => s.severity === \"blocker\")?.count ?? 0;\n const criticalCount = bySeverity.find((s) => s.severity === \"critical\")?.count ?? 0;\n const majorCount = bySeverity.find((s) => s.severity === \"major\")?.count ?? 0;\n const minorCount = bySeverity.find((s) => s.severity === \"minor\")?.count ?? 0;\n\n console.log(`${\"─\".repeat(60)}`);\n console.log(\"Severity scorecard:\");\n console.log(` Total errors: ${total}`);\n console.log(` Blockers: ${blockerCount}`);\n console.log(` Critical: ${criticalCount}`);\n console.log(` Major: ${majorCount}`);\n console.log(` Minor: ${minorCount}`);\n console.log();\n\n // Assessment\n console.log(\"Assessment:\");\n if (blockerCount > 0) {\n console.log(` ${blockerCount} blocker(s) — these block all work. Fix first.`);\n }\n if (criticalCount > total * 0.3) {\n console.log(` High critical rate — config/security issues are common.`);\n }\n if (minorCount > total * 0.5) {\n console.log(` High minor rate — most errors are non-blocking. Consider filtering.`);\n }\n if (blockerCount === 0 && criticalCount === 0) {\n console.log(\" No blockers or critical errors. Development is not blocked.\");\n }\n console.log();\n console.log(\"Severity: blocker > critical > major > minor\");\n console.log(\"PreToolUse injects blockers first, then critical, then major.\");\n console.log();\n console.log(\"Set TDAI_RETRO_DAYS=N to change the analysis window (default: 7).\");\n\n db.close();\n}\n\n/**\n * `remem-mcp errors templates` — Fix template extraction report.\n * Shows reusable fix patterns extracted from 3+ similar resolved errors.\n * (Moves from specific fixes to generalizable principles)\n */\nexport function errorsTemplates(dbPath: string = defaultDbPath()): void {\n let db: Database.Database;\n try {\n db = new Database(dbPath, { readonly: true });\n } catch {\n console.error(\"Error: Could not open database at\", dbPath);\n process.exit(1);\n }\n\n console.log(\"remem-mcp errors templates — Fix Template Extraction\\n\");\n console.log(`${\"─\".repeat(60)}\\n`);\n\n const days = Number(process.env.TDAI_RETRO_DAYS ?? 7);\n const windowClause = `created_at > datetime('now', '-${days} days')`;\n\n // Find errors that have a fix_template extracted\n const templates = db\n .prepare(\n `SELECT\n id,\n json_extract(metadata, '$.title') as title,\n json_extract(metadata, '$.error_type') as etype,\n json_extract(metadata, '$.fix_applied') as fix,\n json_extract(metadata, '$.fix_template') as template,\n created_at\n FROM captures\n WHERE type = 'error' AND deleted_at IS NULL\n AND ${windowClause}\n AND json_extract(metadata, '$.fix_template') IS NOT NULL\n ORDER BY json_extract(metadata, '$.fix_template.similar_fix_count') DESC LIMIT 20`,\n )\n .all() as {\n id: string;\n title: string;\n etype: string;\n fix: string;\n template: string;\n created_at: string;\n }[];\n\n if (templates.length === 0) {\n console.log(`No fix templates extracted in the last ${days} days.`);\n console.log(\n \"Templates are auto-extracted when 3+ similar errors share the same fix pattern.\\n\",\n );\n db.close();\n return;\n }\n\n console.log(`Extracted fix templates (last ${days} days):`);\n console.log();\n\n // Deduplicate by pattern\n const seen = new Map<string, typeof templates>();\n for (const t of templates) {\n try {\n const tmpl = JSON.parse(t.template);\n const key = tmpl.pattern ?? \"unknown\";\n if (!seen.has(key)) seen.set(key, []);\n seen.get(key)!.push(t);\n } catch {\n // skip\n }\n }\n\n for (const [pattern, matches] of seen) {\n const first = matches[0];\n const tmpl = JSON.parse(first.template);\n console.log(` Pattern: \"${pattern}\"`);\n console.log(` Error type: ${tmpl.error_type ?? \"unknown\"}`);\n console.log(` Matches: ${tmpl.similar_fix_count} similar fixes`);\n console.log(` Example fix: ${(first.fix ?? \"\").slice(0, 60)}`);\n console.log();\n }\n\n // Summary\n console.log(`${\"─\".repeat(60)}`);\n console.log(\"Template scorecard:\");\n console.log(` Total templates: ${seen.size}`);\n console.log(` Total template hits: ${templates.length}`);\n console.log();\n\n // Assessment\n console.log(\"Assessment:\");\n if (seen.size >= 3) {\n console.log(\" Multiple fix patterns detected — agent is learning general principles.\");\n } else if (seen.size >= 1) {\n console.log(\" Some patterns detected — agent is starting to generalize fixes.\");\n }\n console.log();\n console.log(\"Templates are auto-extracted when 3+ similar errors share the same fix pattern.\");\n console.log(\"Set TDAI_RETRO_DAYS=N to change the analysis window (default: 7).\");\n\n db.close();\n}\n\n/**\n * `remem-mcp errors correlations` — Error correlation report.\n * Shows sequential error patterns: when E1 occurs, E2 often follows.\n * (SRE pattern: incident correlation / cascading failure detection)\n */\nexport function errorsCorrelations(dbPath: string = defaultDbPath()): void {\n let db: Database.Database;\n try {\n db = new Database(dbPath, { readonly: true });\n } catch {\n console.error(\"Error: Could not open database at\", dbPath);\n process.exit(1);\n }\n\n console.log(\"remem-mcp errors correlations — Sequential Error Patterns\\n\");\n console.log(`${\"─\".repeat(60)}\\n`);\n\n const days = Number(process.env.TDAI_RETRO_DAYS ?? 7);\n const windowClause = `created_at > datetime('now', '-${days} days')`;\n\n // Find errors that have error_correlations recorded\n const correlated = db\n .prepare(\n `SELECT\n id,\n json_extract(metadata, '$.title') as title,\n json_extract(metadata, '$.error_type') as etype,\n json_extract(metadata, '$.error_correlations') as correlations,\n created_at\n FROM captures\n WHERE type = 'error' AND deleted_at IS NULL\n AND ${windowClause}\n AND json_extract(metadata, '$.error_correlations') IS NOT NULL\n ORDER BY created_at DESC LIMIT 20`,\n )\n .all() as {\n id: string;\n title: string;\n etype: string;\n correlations: string;\n created_at: string;\n }[];\n\n if (correlated.length === 0) {\n console.log(`No error correlations detected in the last ${days} days.`);\n console.log(\"Correlations are detected when different error types occur within 10 minutes.\\n\");\n db.close();\n return;\n }\n\n // Aggregate correlation pairs across all errors\n const pairMap = new Map<string, { count: number; examples: string[] }>();\n\n for (const c of correlated) {\n try {\n const corrs = JSON.parse(c.correlations) as {\n next_error_type: string;\n next_error_title: string;\n count: number;\n }[];\n for (const corr of corrs) {\n const key = `${c.etype ?? \"unknown\"} → ${corr.next_error_type}`;\n if (!pairMap.has(key)) {\n pairMap.set(key, { count: 0, examples: [] });\n }\n const entry = pairMap.get(key)!;\n entry.count += corr.count;\n if (entry.examples.length < 2) {\n entry.examples.push(\n `${(c.title ?? \"\").slice(0, 30)} → ${corr.next_error_title?.slice(0, 30) ?? \"\"}`,\n );\n }\n }\n } catch {\n // skip\n }\n }\n\n // Sort by count descending\n const sorted = [...pairMap.entries()].sort((a, b) => b[1].count - a[1].count);\n\n console.log(`Sequential error patterns (last ${days} days):`);\n console.log();\n for (const [pattern, data] of sorted.slice(0, 10)) {\n console.log(` ${pattern} (${data.count} occurrences)`);\n for (const ex of data.examples) {\n console.log(` e.g. ${ex}`);\n }\n }\n console.log();\n\n // Summary\n console.log(`${\"─\".repeat(60)}`);\n console.log(\"Correlation scorecard:\");\n console.log(` Total correlated errors: ${correlated.length}`);\n console.log(` Unique patterns: ${pairMap.size}`);\n const totalPairs = [...pairMap.values()].reduce((sum, p) => sum + p.count, 0);\n console.log(` Total pair occurrences: ${totalPairs}`);\n console.log();\n\n // Assessment\n console.log(\"Assessment:\");\n if (pairMap.size >= 3) {\n console.log(\" Multiple correlation patterns — errors tend to cascade.\");\n console.log(\" When E1 occurs, proactively check for E2 conditions.\");\n } else if (pairMap.size >= 1) {\n console.log(\" Some correlations detected — watch for cascading failures.\");\n }\n console.log();\n console.log(\"Correlations are detected when different error types occur within 10 minutes.\");\n console.log(\"Set TDAI_RETRO_DAYS=N to change the analysis window (default: 7).\");\n\n db.close();\n}\n\n/**\n * `remem-mcp errors playbooks` — Recovery pattern library.\n * Shows structured recovery playbooks extracted from resolved errors.\n * (SRE pattern: runbooks / incident playbooks for agents)\n */\nexport function errorsPlaybooks(dbPath: string = defaultDbPath()): void {\n let db: Database.Database;\n try {\n db = new Database(dbPath, { readonly: true });\n } catch {\n console.error(\"Error: Could not open database at\", dbPath);\n process.exit(1);\n }\n\n console.log(\"remem-mcp errors playbooks — Recovery Pattern Library\\n\");\n console.log(`${\"─\".repeat(60)}\\n`);\n\n const days = Number(process.env.TDAI_RETRO_DAYS ?? 7);\n const windowClause = `created_at > datetime('now', '-${days} days')`;\n\n // Find errors that have a recovery_pattern extracted\n const playbooks = db\n .prepare(\n `SELECT\n id,\n json_extract(metadata, '$.title') as title,\n json_extract(metadata, '$.error_type') as etype,\n json_extract(metadata, '$.recovery_pattern') as pattern,\n json_extract(metadata, '$.attempt_count') as attempts,\n json_extract(metadata, '$.severity') as severity\n FROM captures\n WHERE type = 'error' AND deleted_at IS NULL\n AND ${windowClause}\n AND json_extract(metadata, '$.recovery_pattern') IS NOT NULL\n ORDER BY CAST(json_extract(metadata, '$.attempt_count') AS INTEGER) DESC LIMIT 10`,\n )\n .all() as {\n id: string;\n title: string;\n etype: string;\n pattern: string;\n attempts: string;\n severity: string;\n }[];\n\n if (playbooks.length === 0) {\n console.log(`No recovery playbooks in the last ${days} days.`);\n console.log(\"Playbooks are auto-extracted when errors with 2+ attempts are resolved.\\n\");\n db.close();\n return;\n }\n\n console.log(`Recovery playbooks (last ${days} days):`);\n console.log();\n for (const p of playbooks) {\n try {\n const pat = JSON.parse(p.pattern);\n console.log(\n ` ${p.title ?? \"Untitled\"} [${p.etype ?? \"unknown\"}, ${p.attempts ?? \"?\"} attempts, ${p.severity ?? \"major\"}]`,\n );\n for (const step of pat.steps ?? []) {\n console.log(` ${step}`);\n }\n console.log();\n } catch {\n // skip\n }\n }\n\n // Summary\n console.log(`${\"─\".repeat(60)}`);\n console.log(\"Playbook scorecard:\");\n console.log(` Total playbooks: ${playbooks.length}`);\n const totalAttempts = playbooks.reduce((sum, p) => sum + (Number(p.attempts) ?? 0), 0);\n const avgAttempts = playbooks.length > 0 ? (totalAttempts / playbooks.length).toFixed(1) : \"0\";\n console.log(` Avg attempts: ${avgAttempts}`);\n console.log();\n\n // Assessment\n console.log(\"Assessment:\");\n if (playbooks.length >= 5) {\n console.log(\n \" Rich playbook library — agent has structured recovery guidance for many errors.\",\n );\n } else if (playbooks.length >= 1) {\n console.log(\" Some playbooks available — agent is building recovery guidance.\");\n }\n console.log();\n console.log(\"Playbooks are auto-extracted when errors with 2+ attempts are resolved.\");\n console.log(\"Set TDAI_RETRO_DAYS=N to change the analysis window (default: 7).\");\n\n db.close();\n}\n\n/**\n * `remem-mcp errors stale` — Fix staleness report.\n * Shows resolved fixes that are older than the staleness threshold.\n * (Knowledge freshness: fixes can become invalid as codebase evolves)\n */\nexport function errorsStale(dbPath: string = defaultDbPath()): void {\n let db: Database.Database;\n try {\n db = new Database(dbPath, { readonly: true });\n } catch {\n console.error(\"Error: Could not open database at\", dbPath);\n process.exit(1);\n }\n\n console.log(\"remem-mcp errors stale — Fix Staleness Report\\n\");\n console.log(`${\"─\".repeat(60)}\\n`);\n\n const stalenessDays = Number(process.env.TDAI_FIX_STALENESS_DAYS ?? 180);\n const stalenessClause = `datetime('now', '-${stalenessDays} days')`;\n\n // Find resolved fixes older than threshold\n const stale = db\n .prepare(\n `SELECT\n id,\n json_extract(metadata, '$.title') as title,\n json_extract(metadata, '$.fix_applied') as fix,\n json_extract(metadata, '$.resolved_at') as resolved_at,\n json_extract(metadata, '$.error_type') as etype,\n json_extract(metadata, '$.severity') as severity\n FROM captures\n WHERE type = 'error' AND deleted_at IS NULL\n AND json_extract(metadata, '$.resolved') = true\n AND json_extract(metadata, '$.fix_applied') IS NOT NULL\n AND json_extract(metadata, '$.resolved_at') IS NOT NULL\n AND json_extract(metadata, '$.resolved_at') < ${stalenessClause}\n ORDER BY json_extract(metadata, '$.resolved_at') ASC LIMIT 20`,\n )\n .all() as {\n id: string;\n title: string;\n fix: string;\n resolved_at: string;\n etype: string;\n severity: string;\n }[];\n\n // Also count fresh fixes (for comparison)\n const fresh = db\n .prepare(\n `SELECT COUNT(*) as count\n FROM captures\n WHERE type = 'error' AND deleted_at IS NULL\n AND json_extract(metadata, '$.resolved') = true\n AND json_extract(metadata, '$.fix_applied') IS NOT NULL\n AND json_extract(metadata, '$.resolved_at') IS NOT NULL\n AND json_extract(metadata, '$.resolved_at') >= ${stalenessClause}`,\n )\n .get() as { count: number };\n\n console.log(`Staleness threshold: ${stalenessDays} days (TDAI_FIX_STALENESS_DAYS)`);\n console.log();\n\n if (stale.length === 0) {\n console.log(\n `No stale fixes found. All ${fresh.count} resolved fix(es) are within ${stalenessDays} days.\\n`,\n );\n db.close();\n return;\n }\n\n console.log(`Stale fixes (older than ${stalenessDays} days):`);\n console.log();\n for (const s of stale) {\n const ageDays = Math.floor((Date.now() - new Date(s.resolved_at).getTime()) / 86400000);\n const title = (s.title ?? \"Untitled\").slice(0, 40);\n const fix = (s.fix ?? \"\").slice(0, 50);\n const date = new Date(s.resolved_at).toISOString().split(\"T\")[0];\n console.log(` ${date} (${ageDays}d old) ${title}`);\n console.log(` fix: ${fix}`);\n }\n console.log();\n\n // Summary\n console.log(`${\"─\".repeat(60)}`);\n console.log(\"Staleness scorecard:\");\n console.log(` Stale fixes: ${stale.length} (older than ${stalenessDays} days)`);\n console.log(` Fresh fixes: ${fresh.count} (within ${stalenessDays} days)`);\n const total = stale.length + fresh.count;\n const staleRate = total > 0 ? ((stale.length / total) * 100).toFixed(0) : \"0\";\n console.log(` Stale rate: ${staleRate}%`);\n console.log();\n\n // Assessment\n console.log(\"Assessment:\");\n if (stale.length > fresh.count && total > 0) {\n console.log(\" More stale than fresh fixes — consider pruning or re-validating old fixes.\");\n } else if (stale.length > 0) {\n console.log(\" Some stale fixes detected — PreToolUse will warn [STALE] when injecting them.\");\n }\n console.log();\n console.log(\"Stale fixes are still injected but with a [STALE — verify before applying] tag.\");\n console.log(\"Set TDAI_FIX_STALENESS_DAYS=N to change the threshold (default: 180).\");\n\n db.close();\n}\n\n/**\n * `remem-mcp errors escalations` — Escalation policy report.\n * Shows errors that have been auto-escalated due to high recurrence.\n * (PagerDuty pattern: recurrence → escalation → stronger intervention)\n */\nexport function errorsEscalations(dbPath: string = defaultDbPath()): void {\n let db: Database.Database;\n try {\n db = new Database(dbPath, { readonly: true });\n } catch {\n console.error(\"Error: Could not open database at\", dbPath);\n process.exit(1);\n }\n\n console.log(\"remem-mcp errors escalations — Escalation Policy Report\\n\");\n console.log(`${\"─\".repeat(60)}\\n`);\n\n const days = Number(process.env.TDAI_RETRO_DAYS ?? 7);\n const windowClause = `created_at > datetime('now', '-${days} days')`;\n const threshold = Number(process.env.TDAI_ESCALATION_THRESHOLD ?? 3);\n\n // Find escalated errors\n const escalated = db\n .prepare(\n `SELECT\n id,\n json_extract(metadata, '$.title') as title,\n json_extract(metadata, '$.error_type') as etype,\n json_extract(metadata, '$.escalation_level') as level,\n json_extract(metadata, '$.escalated_at') as escalated_at,\n json_extract(metadata, '$.attempt_count') as attempts,\n json_extract(metadata, '$.severity') as severity,\n json_extract(metadata, '$.resolved') as resolved\n FROM captures\n WHERE type = 'error' AND deleted_at IS NULL\n AND ${windowClause}\n AND CAST(json_extract(metadata, '$.escalation_level') AS INTEGER) > 0\n ORDER BY CAST(json_extract(metadata, '$.escalation_level') AS INTEGER) DESC,\n CAST(json_extract(metadata, '$.attempt_count') AS INTEGER) DESC LIMIT 20`,\n )\n .all() as {\n id: string;\n title: string;\n etype: string;\n level: string;\n escalated_at: string;\n attempts: string;\n severity: string;\n resolved: string;\n }[];\n\n console.log(`Escalation threshold: ${threshold} attempts (TDAI_ESCALATION_THRESHOLD)`);\n console.log(`Analysis window: last ${days} days (TDAI_RETRO_DAYS)`);\n console.log();\n\n if (escalated.length === 0) {\n console.log(`No escalated errors in the last ${days} days.\\n`);\n console.log(\"Errors auto-escalate when they recur 3+ times:\");\n console.log(\" Level 1 (ELEVATED): 3+ attempts — severity bumped to critical\");\n console.log(\" Level 2 (CRITICAL): 5+ attempts — severity bumped to blocker\");\n console.log(\" Level 3 (BLOCKER): 7+ attempts — strongest warning injected\");\n console.log();\n db.close();\n return;\n }\n\n const levelLabels: Record<number, string> = {\n 1: \"ELEVATED\",\n 2: \"CRITICAL\",\n 3: \"BLOCKER\",\n };\n\n console.log(\"Escalated errors:\");\n console.log();\n for (const e of escalated) {\n const level = Number(e.level);\n const label = levelLabels[level] ?? `L${level}`;\n const title = (e.title ?? \"Untitled\").slice(0, 40);\n const resolved = e.resolved === \"true\" ? \" ✓\" : \"\";\n const escDate = e.escalated_at ? new Date(e.escalated_at).toISOString().split(\"T\")[0] : \"?\";\n console.log(` [${label}] ${title}${resolved}`);\n console.log(\n ` attempts: ${e.attempts ?? \"?\"}, severity: ${e.severity ?? \"major\"}, escalated: ${escDate}`,\n );\n }\n console.log();\n\n // Summary by level\n const byLevel: Record<number, number> = { 1: 0, 2: 0, 3: 0 };\n for (const e of escalated) {\n const lvl = Number(e.level);\n byLevel[lvl] = (byLevel[lvl] ?? 0) + 1;\n }\n\n console.log(`${\"─\".repeat(60)}`);\n console.log(\"Escalation scorecard:\");\n console.log(` Total escalated: ${escalated.length}`);\n console.log(` Level 1 (ELEVATED): ${byLevel[1]} (3+ attempts)`);\n console.log(` Level 2 (CRITICAL): ${byLevel[2]} (5+ attempts)`);\n console.log(` Level 3 (BLOCKER): ${byLevel[3]} (7+ attempts)`);\n console.log();\n\n // Assessment\n console.log(\"Assessment:\");\n if (byLevel[3] > 0) {\n console.log(\n ` ${byLevel[3]} BLOCKER-level error(s) — these need a fundamentally different approach.`,\n );\n }\n if (byLevel[2] > 0) {\n console.log(` ${byLevel[2]} CRITICAL-level error(s) — previous fixes have failed repeatedly.`);\n }\n if (byLevel[1] > 0 && byLevel[2] === 0 && byLevel[3] === 0) {\n console.log(` ${byLevel[1]} ELEVATED error(s) — monitor for further recurrence.`);\n }\n console.log();\n console.log(\"Escalated errors get stronger warning text in PreToolUse injections.\");\n console.log(\"Set TDAI_ESCALATION_THRESHOLD=N to change the trigger (default: 3).\");\n console.log(\"Set TDAI_RETRO_DAYS=N to change the analysis window (default: 7).\");\n\n db.close();\n}\n\n/**\n * `remem-mcp errors context` — Error context enrichment report.\n * Shows git context (branch, commits, changed files) captured at error time.\n * (LoopX evidence logs pattern: record context during failure)\n */\nexport function errorsContext(dbPath: string = defaultDbPath()): void {\n let db: Database.Database;\n try {\n db = new Database(dbPath, { readonly: true });\n } catch {\n console.error(\"Error: Could not open database at\", dbPath);\n process.exit(1);\n }\n\n console.log(\"remem-mcp errors context — Error Context Enrichment\\n\");\n console.log(`${\"─\".repeat(60)}\\n`);\n\n const days = Number(process.env.TDAI_RETRO_DAYS ?? 7);\n const windowClause = `created_at > datetime('now', '-${days} days')`;\n\n // Find errors with context_enrichment\n const enriched = db\n .prepare(\n `SELECT\n id,\n json_extract(metadata, '$.title') as title,\n json_extract(metadata, '$.error_type') as etype,\n json_extract(metadata, '$.context_enrichment') as ctx,\n json_extract(metadata, '$.severity') as severity,\n created_at\n FROM captures\n WHERE type = 'error' AND deleted_at IS NULL\n AND ${windowClause}\n AND json_extract(metadata, '$.context_enrichment') IS NOT NULL\n ORDER BY created_at DESC LIMIT 20`,\n )\n .all() as {\n id: string;\n title: string;\n etype: string;\n ctx: string;\n severity: string;\n created_at: string;\n }[];\n\n if (enriched.length === 0) {\n console.log(`No errors with git context in the last ${days} days.`);\n console.log(\"Context is auto-captured when errors occur in a git repository.\\n\");\n db.close();\n return;\n }\n\n console.log(`Errors with git context (last ${days} days):`);\n console.log();\n for (const e of enriched) {\n try {\n const ctx = JSON.parse(e.ctx);\n const title = (e.title ?? \"Untitled\").slice(0, 40);\n const date = new Date(e.created_at).toISOString().split(\"T\")[0];\n console.log(` ${date} ${title} [${e.severity ?? \"major\"}]`);\n console.log(` branch: ${ctx.branch ?? \"unknown\"}`);\n if (ctx.recent_commits?.[0]) console.log(` last commit: ${ctx.recent_commits[0]}`);\n if (ctx.changed_files?.length > 0) {\n console.log(\n ` changed files: ${ctx.changed_files.slice(0, 3).join(\", \")}${ctx.changed_files.length > 3 ? \"...\" : \"\"}`,\n );\n }\n console.log();\n } catch {\n // skip\n }\n }\n\n // Summary\n console.log(`${\"─\".repeat(60)}`);\n console.log(\"Context scorecard:\");\n console.log(` Errors with context: ${enriched.length}`);\n\n // Branch distribution\n const branchMap = new Map<string, number>();\n for (const e of enriched) {\n try {\n const ctx = JSON.parse(e.ctx);\n const b = ctx.branch ?? \"unknown\";\n branchMap.set(b, (branchMap.get(b) ?? 0) + 1);\n } catch {\n // skip\n }\n }\n console.log(` Unique branches: ${branchMap.size}`);\n const topBranch = [...branchMap.entries()].sort((a, b) => b[1] - a[1])[0];\n if (topBranch) {\n console.log(` Most error-prone: ${topBranch[0]} (${topBranch[1]} errors)`);\n }\n console.log();\n console.log(\"Context is auto-captured when errors occur in a git repository.\");\n console.log(\"Set TDAI_RETRO_DAYS=N to change the analysis window (default: 7).\");\n\n db.close();\n}\n\n/**\n * `remem-mcp errors inherited` — Cross-project fix inheritance report.\n * Shows fixes that were auto-inherited from other projects.\n * (LoopX capability routes pattern: learn once, apply everywhere)\n */\nexport function errorsInherited(dbPath: string = defaultDbPath()): void {\n let db: Database.Database;\n try {\n db = new Database(dbPath, { readonly: true });\n } catch {\n console.error(\"Error: Could not open database at\", dbPath);\n process.exit(1);\n }\n\n console.log(\"remem-mcp errors inherited — Cross-Project Fix Inheritance\\n\");\n console.log(`${\"─\".repeat(60)}\\n`);\n\n const days = Number(process.env.TDAI_RETRO_DAYS ?? 7);\n const windowClause = `created_at > datetime('now', '-${days} days')`;\n\n // Find resolved fixes with provenance = inherited\n const inherited = db\n .prepare(\n `SELECT\n id,\n json_extract(metadata, '$.title') as title,\n json_extract(metadata, '$.fix_applied') as fix,\n json_extract(metadata, '$.fix_provenance') as provenance,\n json_extract(metadata, '$.error_type') as etype,\n session_key,\n created_at\n FROM captures\n WHERE type = 'error' AND deleted_at IS NULL\n AND ${windowClause}\n AND json_extract(metadata, '$.resolved') = true\n AND json_extract(metadata, '$.fix_applied') IS NOT NULL\n ORDER BY created_at DESC LIMIT 20`,\n )\n .all() as {\n id: string;\n title: string;\n fix: string;\n provenance: string;\n etype: string;\n session_key: string;\n created_at: string;\n }[];\n\n // Group by session_key (project)\n const byProject = new Map<string, typeof inherited>();\n for (const f of inherited) {\n if (!byProject.has(f.session_key)) byProject.set(f.session_key, []);\n byProject.get(f.session_key)!.push(f);\n }\n\n if (inherited.length === 0) {\n console.log(`No resolved fixes in the last ${days} days.`);\n console.log(\n \"Fixes are auto-inherited when PreToolUse finds validated fixes from other projects.\\n\",\n );\n db.close();\n return;\n }\n\n console.log(`Resolved fixes by project (last ${days} days):`);\n console.log();\n for (const [project, fixes] of byProject) {\n console.log(` Project: ${project.slice(0, 20)}... (${fixes.length} fixes)`);\n for (const f of fixes.slice(0, 3)) {\n const title = (f.title ?? \"Untitled\").slice(0, 35);\n const prov = f.provenance ?? \"auto_captured\";\n console.log(` [${prov}] ${title}`);\n }\n if (fixes.length > 3) console.log(` ... and ${fixes.length - 3} more`);\n console.log();\n }\n\n // Summary\n const provenanceCounts = new Map<string, number>();\n for (const f of inherited) {\n const p = f.provenance ?? \"auto_captured\";\n provenanceCounts.set(p, (provenanceCounts.get(p) ?? 0) + 1);\n }\n\n console.log(`${\"─\".repeat(60)}`);\n console.log(\"Inheritance scorecard:\");\n console.log(` Total resolved fixes: ${inherited.length}`);\n console.log(` Projects with fixes: ${byProject.size}`);\n for (const [prov, count] of provenanceCounts) {\n console.log(` ${prov}: ${count}`);\n }\n console.log();\n console.log(\n \"Fixes are auto-inherited when PreToolUse finds validated fixes from other projects.\",\n );\n console.log(\"Set TDAI_RETRO_DAYS=N to change the analysis window (default: 7).\");\n\n db.close();\n}\n\n/**\n * `remem-mcp errors provenance` — Fix provenance chain report.\n * Shows where fixes came from: auto_captured, inherited, template_extracted.\n * (Midas source-traceable recall pattern: provenance affects trust)\n */\nexport function errorsProvenance(dbPath: string = defaultDbPath()): void {\n let db: Database.Database;\n try {\n db = new Database(dbPath, { readonly: true });\n } catch {\n console.error(\"Error: Could not open database at\", dbPath);\n process.exit(1);\n }\n\n console.log(\"remem-mcp errors provenance — Fix Provenance Chain\\n\");\n console.log(`${\"─\".repeat(60)}\\n`);\n\n const days = Number(process.env.TDAI_RETRO_DAYS ?? 7);\n const windowClause = `created_at > datetime('now', '-${days} days')`;\n\n // Count by provenance\n const byProvenance = db\n .prepare(\n `SELECT\n COALESCE(json_extract(metadata, '$.fix_provenance'), 'auto_captured') as provenance,\n COUNT(*) as count,\n SUM(CASE WHEN json_extract(metadata, '$.fix_validated') = true THEN 1 ELSE 0 END) as validated\n FROM captures\n WHERE type = 'error' AND deleted_at IS NULL\n AND ${windowClause}\n AND json_extract(metadata, '$.fix_applied') IS NOT NULL\n GROUP BY provenance\n ORDER BY count DESC`,\n )\n .all() as { provenance: string; count: number; validated: number }[];\n\n if (byProvenance.length === 0) {\n console.log(`No fixes with provenance data in the last ${days} days.`);\n console.log(\"Provenance is auto-tagged when fixes are recorded.\\n\");\n db.close();\n return;\n }\n\n console.log(`Fix provenance distribution (last ${days} days):`);\n console.log();\n for (const p of byProvenance) {\n const validateRate = p.count > 0 ? ((p.validated / p.count) * 100).toFixed(0) : \"0\";\n console.log(\n ` ${p.provenance.padEnd(20)} ${String(p.count).padStart(4)} fixes (${validateRate}% validated)`,\n );\n }\n console.log();\n\n // Show examples of each provenance type\n const examples = db\n .prepare(\n `SELECT\n json_extract(metadata, '$.title') as title,\n json_extract(metadata, '$.fix_provenance') as provenance,\n json_extract(metadata, '$.fix_applied') as fix,\n json_extract(metadata, '$.rollback_plan') as rollback\n FROM captures\n WHERE type = 'error' AND deleted_at IS NULL\n AND ${windowClause}\n AND json_extract(metadata, '$.fix_applied') IS NOT NULL\n ORDER BY created_at DESC LIMIT 10`,\n )\n .all() as { title: string; provenance: string; fix: string; rollback: string }[];\n\n if (examples.length > 0) {\n console.log(\"Recent fixes with provenance and rollback plans:\");\n for (const e of examples.slice(0, 10)) {\n const title = (e.title ?? \"Untitled\").slice(0, 35);\n const prov = e.provenance ?? \"auto_captured\";\n console.log(` [${prov}] ${title}`);\n if (e.rollback) {\n console.log(` rollback: ${e.rollback.slice(0, 60)}`);\n }\n }\n }\n console.log();\n\n // Summary\n const total = byProvenance.reduce((sum, p) => sum + p.count, 0);\n console.log(`${\"─\".repeat(60)}`);\n console.log(\"Provenance scorecard:\");\n console.log(` Total fixes: ${total}`);\n for (const p of byProvenance) {\n console.log(` ${p.provenance}: ${p.count}`);\n }\n console.log();\n console.log(\"Provenance is auto-tagged: auto_captured > inherited > template_extracted.\");\n console.log(\"Set TDAI_RETRO_DAYS=N to change the analysis window (default: 7).\");\n\n db.close();\n}\n\n/**\n * `remem-mcp errors persona` — Error persona per project.\n * Auto-builds an error profile: most common types, branches, severity,\n * resolution rate, top anti-patterns. (TencentDB L3 Persona layer pattern)\n */\nexport function errorsPersona(dbPath: string = defaultDbPath()): void {\n let db: Database.Database;\n try {\n db = new Database(dbPath, { readonly: true });\n } catch {\n console.error(\"Error: Could not open database at\", dbPath);\n process.exit(1);\n }\n\n console.log(\"remem-mcp errors persona — Error Profile per Project\\n\");\n console.log(`${\"─\".repeat(60)}\\n`);\n\n const days = Number(process.env.TDAI_RETRO_DAYS ?? 7);\n const windowClause = `created_at > datetime('now', '-${days} days')`;\n\n // Group by session_key (project)\n const byProject = db\n .prepare(\n `SELECT\n session_key,\n COUNT(*) as total,\n SUM(CASE WHEN json_extract(metadata, '$.resolved') = true THEN 1 ELSE 0 END) as resolved_count,\n SUM(CASE WHEN json_extract(metadata, '$.severity') = 'blocker' THEN 1 ELSE 0 END) as blockers,\n SUM(CASE WHEN json_extract(metadata, '$.severity') = 'critical' THEN 1 ELSE 0 END) as critical,\n SUM(CASE WHEN json_extract(metadata, '$.severity') = 'major' THEN 1 ELSE 0 END) as major,\n SUM(CASE WHEN json_extract(metadata, '$.severity') = 'minor' THEN 1 ELSE 0 END) as minor,\n SUM(CASE WHEN json_extract(metadata, '$.drift_count') > 0 THEN 1 ELSE 0 END) as drifted\n FROM captures\n WHERE type = 'error' AND deleted_at IS NULL\n AND ${windowClause}\n GROUP BY session_key\n ORDER BY total DESC`,\n )\n .all() as {\n session_key: string;\n total: number;\n resolved_count: number;\n blockers: number;\n critical: number;\n major: number;\n minor: number;\n drifted: number;\n }[];\n\n if (byProject.length === 0) {\n console.log(`No errors in the last ${days} days.`);\n console.log(\"Error personas are auto-built from captured errors.\\n\");\n db.close();\n return;\n }\n\n for (const proj of byProject) {\n const resolveRate =\n proj.total > 0 ? ((proj.resolved_count / proj.total) * 100).toFixed(0) : \"0\";\n const driftRate = proj.total > 0 ? ((proj.drifted / proj.total) * 100).toFixed(0) : \"0\";\n const projLabel = proj.session_key.slice(0, 16);\n\n console.log(`Project: ${projLabel}...`);\n console.log(` Total errors: ${proj.total}`);\n console.log(` Resolved: ${proj.resolved_count} (${resolveRate}%)`);\n console.log(\n ` Severity: ${proj.blockers} blocker, ${proj.critical} critical, ${proj.major} major, ${proj.minor} minor`,\n );\n console.log(` Drift rate: ${driftRate}%`);\n\n // Top error types for this project\n const topTypes = db\n .prepare(\n `SELECT\n json_extract(metadata, '$.error_type') as etype,\n COUNT(*) as count\n FROM captures\n WHERE type = 'error' AND deleted_at IS NULL\n AND ${windowClause}\n AND session_key = ?\n GROUP BY etype\n ORDER BY count DESC LIMIT 3`,\n )\n .all(proj.session_key) as { etype: string; count: number }[];\n\n if (topTypes.length > 0) {\n console.log(\n ` Top error types: ${topTypes.map((t) => `${t.etype ?? \"unknown\"} (${t.count})`).join(\", \")}`,\n );\n }\n\n // Top branches (from context_enrichment)\n const topBranches = db\n .prepare(\n `SELECT\n json_extract(metadata, '$.context_enrichment.branch') as branch,\n COUNT(*) as count\n FROM captures\n WHERE type = 'error' AND deleted_at IS NULL\n AND ${windowClause}\n AND session_key = ?\n AND json_extract(metadata, '$.context_enrichment.branch') IS NOT NULL\n GROUP BY branch\n ORDER BY count DESC LIMIT 3`,\n )\n .all(proj.session_key) as { branch: string; count: number }[];\n\n if (topBranches.length > 0) {\n console.log(\n ` Top branches: ${topBranches.map((b) => `${b.branch} (${b.count})`).join(\", \")}`,\n );\n }\n\n // Top anti-patterns\n const topAnti = db\n .prepare(\n `SELECT\n json_extract(metadata, '$.anti_pattern') as anti,\n COUNT(*) as count\n FROM captures\n WHERE type = 'error' AND deleted_at IS NULL\n AND ${windowClause}\n AND session_key = ?\n AND json_extract(metadata, '$.anti_pattern') IS NOT NULL\n GROUP BY anti\n ORDER BY count DESC LIMIT 2`,\n )\n .all(proj.session_key) as { anti: string; count: number }[];\n\n if (topAnti.length > 0) {\n console.log(\" Anti-patterns:\");\n for (const a of topAnti) {\n console.log(` - ${(a.anti ?? \"\").slice(0, 50)} (${a.count}x)`);\n }\n }\n\n // Persona summary (auto-generated)\n console.log();\n const personaParts: string[] = [];\n if (proj.blockers > 0) personaParts.push(\"has blocker-level errors\");\n if (proj.critical > proj.major) personaParts.push(\"critical-heavy\");\n if (Number(driftRate) > 30) personaParts.push(\"high drift (agent ignores warnings)\");\n if (Number(resolveRate) > 80) personaParts.push(\"high resolve rate\");\n else if (Number(resolveRate) < 30) personaParts.push(\"low resolve rate (many unresolved)\");\n if (topTypes[0]?.etype) personaParts.push(`${topTypes[0].etype}-heavy`);\n\n console.log(` Persona: This project ${personaParts.join(\", \")}.`);\n console.log();\n }\n\n // Summary scorecard\n console.log(`${\"─\".repeat(60)}`);\n console.log(\"Persona scorecard:\");\n console.log(` Projects tracked: ${byProject.length}`);\n const totalErrors = byProject.reduce((s, p) => s + p.total, 0);\n const totalResolved = byProject.reduce((s, p) => s + p.resolved_count, 0);\n console.log(` Total errors: ${totalErrors}`);\n console.log(` Total resolved: ${totalResolved}`);\n console.log();\n console.log(\"Error personas are auto-built from captured errors.\");\n console.log(\"Set TDAI_RETRO_DAYS=N to change the analysis window (default: 7).\");\n\n db.close();\n}\n\n// ==================================================================\n// Moat 2: Decision Learning Loop\n// ==================================================================\n\n/**\n * `remem-mcp decisions` — Decision dashboard.\n * Shows captured decisions, follow rate, top choices.\n */\nexport function decisionsDashboard(dbPath: string = defaultDbPath()): void {\n let db: Database.Database;\n try {\n db = new Database(dbPath, { readonly: true });\n } catch {\n console.error(\"Error: Could not open database at\", dbPath);\n process.exit(1);\n }\n\n console.log(\"remem-mcp decisions — Decision Learning Dashboard\\n\");\n console.log(`${\"─\".repeat(60)}\\n`);\n\n const days = Number(process.env.TDAI_RETRO_DAYS ?? 7);\n const windowClause = `created_at > datetime('now', '-${days} days')`;\n\n const decisions = db\n .prepare(\n `SELECT\n id,\n json_extract(metadata, '$.title') as title,\n json_extract(metadata, '$.decision_type') as dtype,\n json_extract(metadata, '$.choice') as choice,\n json_extract(metadata, '$.rationale') as rationale,\n json_extract(metadata, '$.confidence') as confidence,\n json_extract(metadata, '$.seen_count') as seen,\n json_extract(metadata, '$.followed') as followed,\n created_at\n FROM captures\n WHERE type = 'decision' AND deleted_at IS NULL\n AND ${windowClause}\n ORDER BY CAST(json_extract(metadata, '$.confidence') AS INTEGER) DESC\n LIMIT 20`,\n )\n .all() as {\n id: string;\n title: string;\n dtype: string;\n choice: string;\n rationale: string;\n confidence: number;\n seen: number;\n followed: string;\n created_at: string;\n }[];\n\n if (decisions.length === 0) {\n console.log(`No decisions captured in the last ${days} days.`);\n console.log(\n \"Decisions are auto-captured when you install dependencies, create configs, or commit decisions.\\n\",\n );\n db.close();\n return;\n }\n\n console.log(`Recent decisions (last ${days} days):`);\n console.log();\n for (const d of decisions) {\n const date = new Date(d.created_at).toISOString().split(\"T\")[0];\n const conf = d.confidence ?? 1;\n const seen = d.seen ?? 1;\n console.log(` ${date} [${d.dtype}] ${d.title} (confidence=${conf}, seen=${seen}x)`);\n if (d.rationale) console.log(` rationale: ${d.rationale.slice(0, 60)}`);\n }\n\n // Scorecard\n console.log(`\\n${\"─\".repeat(60)}`);\n console.log(\"Decision scorecard:\");\n console.log(` Total decisions: ${decisions.length}`);\n\n const byType = new Map<string, number>();\n for (const d of decisions) {\n byType.set(d.dtype ?? \"unknown\", (byType.get(d.dtype ?? \"unknown\") ?? 0) + 1);\n }\n for (const [type, count] of byType) {\n console.log(` ${type}: ${count}`);\n }\n\n const highConf = decisions.filter((d) => (d.confidence ?? 0) >= 3).length;\n console.log(` High confidence: ${highConf} (seen 3+ times)`);\n console.log();\n console.log(\n \"Decisions are auto-captured from dependency installs, config creation, and commit messages.\",\n );\n console.log(\"Set TDAI_RETRO_DAYS=N to change the window (default: 7).\");\n\n db.close();\n}\n\n/**\n * `remem-mcp decisions retro` — Decision retrospective.\n * Shows follow rate, ignored decisions, repeated decisions.\n */\nexport function decisionsRetro(dbPath: string = defaultDbPath()): void {\n let db: Database.Database;\n try {\n db = new Database(dbPath, { readonly: true });\n } catch {\n console.error(\"Error: Could not open database at\", dbPath);\n process.exit(1);\n }\n\n console.log(\"remem-mcp decisions retro — Decision Retrospective\\n\");\n console.log(`${\"─\".repeat(60)}\\n`);\n\n const days = Number(process.env.TDAI_RETRO_DAYS ?? 7);\n const windowClause = `created_at > datetime('now', '-${days} days')`;\n\n const decisions = db\n .prepare(\n `SELECT\n id,\n json_extract(metadata, '$.title') as title,\n json_extract(metadata, '$.decision_type') as dtype,\n json_extract(metadata, '$.choice') as choice,\n json_extract(metadata, '$.confidence') as confidence,\n json_extract(metadata, '$.seen_count') as seen,\n json_extract(metadata, '$.drift_count') as drift,\n created_at\n FROM captures\n WHERE type = 'decision' AND deleted_at IS NULL\n AND ${windowClause}\n ORDER BY created_at DESC`,\n )\n .all() as {\n id: string;\n title: string;\n dtype: string;\n choice: string;\n confidence: number;\n seen: number;\n drift: number;\n created_at: string;\n }[];\n\n if (decisions.length === 0) {\n console.log(`No decisions in the last ${days} days.\\n`);\n db.close();\n return;\n }\n\n // Repeated decisions (same choice seen 2+ times = agent re-deciding)\n const repeated = decisions.filter((d) => (d.seen ?? 1) >= 2);\n if (repeated.length > 0) {\n console.log(\"Repeated decisions (seen 2+ times — agent re-chose):\");\n for (const d of repeated) {\n console.log(` [${d.dtype}] ${d.title} (seen ${d.seen}x)`);\n }\n console.log();\n }\n\n // Drifted decisions (ignored)\n const drifted = decisions.filter((d) => (d.drift ?? 0) > 0);\n if (drifted.length > 0) {\n console.log(\"Drifted decisions (injected but ignored):\");\n for (const d of drifted) {\n console.log(` [${d.dtype}] ${d.title} (drift=${d.drift})`);\n }\n console.log();\n }\n\n // Scorecard\n console.log(`${\"─\".repeat(60)}`);\n console.log(\"Decision retro scorecard:\");\n console.log(` Total decisions: ${decisions.length}`);\n console.log(` Repeated: ${repeated.length}`);\n console.log(` Drifted: ${drifted.length}`);\n const followRate =\n decisions.length > 0\n ? (((decisions.length - drifted.length) / decisions.length) * 100).toFixed(0)\n : \"0\";\n console.log(` Follow rate: ${followRate}%`);\n console.log();\n console.log(\"Set TDAI_RETRO_DAYS=N to change the window (default: 7).\");\n\n db.close();\n}\n\n// ==================================================================\n// Moat 3: Pattern Learning Loop\n// ==================================================================\n\n/**\n * `remem-mcp patterns` — Pattern dashboard.\n * Shows captured code patterns, adoption rate, top patterns.\n */\nexport function patternsDashboard(dbPath: string = defaultDbPath()): void {\n let db: Database.Database;\n try {\n db = new Database(dbPath, { readonly: true });\n } catch {\n console.error(\"Error: Could not open database at\", dbPath);\n process.exit(1);\n }\n\n console.log(\"remem-mcp patterns — Pattern Learning Dashboard\\n\");\n console.log(`${\"─\".repeat(60)}\\n`);\n\n const days = Number(process.env.TDAI_RETRO_DAYS ?? 7);\n const windowClause = `created_at > datetime('now', '-${days} days')`;\n\n const patterns = db\n .prepare(\n `SELECT\n id,\n json_extract(metadata, '$.title') as title,\n json_extract(metadata, '$.pattern_type') as ptype,\n json_extract(metadata, '$.language') as language,\n json_extract(metadata, '$.signature') as sig,\n json_extract(metadata, '$.file_path') as fpath,\n json_extract(metadata, '$.confidence') as confidence,\n json_extract(metadata, '$.seen_count') as seen,\n json_extract(metadata, '$.adopted') as adopted,\n created_at\n FROM captures\n WHERE type = 'pattern' AND deleted_at IS NULL\n AND ${windowClause}\n ORDER BY CAST(json_extract(metadata, '$.confidence') AS INTEGER) DESC\n LIMIT 20`,\n )\n .all() as {\n id: string;\n title: string;\n ptype: string;\n language: string;\n sig: string;\n fpath: string;\n confidence: number;\n seen: number;\n adopted: string;\n created_at: string;\n }[];\n\n if (patterns.length === 0) {\n console.log(`No patterns captured in the last ${days} days.`);\n console.log(\n \"Patterns are auto-captured when you write/edit code (functions, components, classes, imports).\\n\",\n );\n db.close();\n return;\n }\n\n console.log(`Recent patterns (last ${days} days):`);\n console.log();\n for (const p of patterns) {\n const date = new Date(p.created_at).toISOString().split(\"T\")[0];\n const conf = p.confidence ?? 1;\n const seen = p.seen ?? 1;\n console.log(\n ` ${date} [${p.ptype}] [${p.language}] ${p.title} (confidence=${conf}, seen=${seen}x)`,\n );\n if (p.fpath) console.log(` file: ${p.fpath}`);\n }\n\n // Scorecard\n console.log(`\\n${\"─\".repeat(60)}`);\n console.log(\"Pattern scorecard:\");\n console.log(` Total patterns: ${patterns.length}`);\n\n const byType = new Map<string, number>();\n const byLang = new Map<string, number>();\n for (const p of patterns) {\n byType.set(p.ptype ?? \"unknown\", (byType.get(p.ptype ?? \"unknown\") ?? 0) + 1);\n byLang.set(p.language ?? \"unknown\", (byLang.get(p.language ?? \"unknown\") ?? 0) + 1);\n }\n console.log(\" By type:\");\n for (const [type, count] of byType) {\n console.log(` ${type}: ${count}`);\n }\n console.log(\" By language:\");\n for (const [lang, count] of byLang) {\n console.log(` ${lang}: ${count}`);\n }\n\n const highConf = patterns.filter((p) => (p.confidence ?? 0) >= 3).length;\n console.log(` High confidence: ${highConf} (seen 3+ times)`);\n console.log();\n console.log(\"Patterns are auto-captured from Write/Edit tools.\");\n console.log(\"Set TDAI_RETRO_DAYS=N to change the window (default: 7).\");\n\n db.close();\n}\n\n/**\n * `remem-mcp patterns retro` — Pattern retrospective.\n * Shows adoption rate, ignored patterns, most/least followed.\n */\nexport function patternsRetro(dbPath: string = defaultDbPath()): void {\n let db: Database.Database;\n try {\n db = new Database(dbPath, { readonly: true });\n } catch {\n console.error(\"Error: Could not open database at\", dbPath);\n process.exit(1);\n }\n\n console.log(\"remem-mcp patterns retro — Pattern Retrospective\\n\");\n console.log(`${\"─\".repeat(60)}\\n`);\n\n const days = Number(process.env.TDAI_RETRO_DAYS ?? 7);\n const windowClause = `created_at > datetime('now', '-${days} days')`;\n\n const patterns = db\n .prepare(\n `SELECT\n id,\n json_extract(metadata, '$.title') as title,\n json_extract(metadata, '$.pattern_type') as ptype,\n json_extract(metadata, '$.language') as language,\n json_extract(metadata, '$.confidence') as confidence,\n json_extract(metadata, '$.seen_count') as seen,\n json_extract(metadata, '$.adopted') as adopted,\n created_at\n FROM captures\n WHERE type = 'pattern' AND deleted_at IS NULL\n AND ${windowClause}\n ORDER BY CAST(json_extract(metadata, '$.confidence') AS INTEGER) DESC`,\n )\n .all() as {\n id: string;\n title: string;\n ptype: string;\n language: string;\n confidence: number;\n seen: number;\n adopted: string;\n created_at: string;\n }[];\n\n if (patterns.length === 0) {\n console.log(`No patterns in the last ${days} days.\\n`);\n db.close();\n return;\n }\n\n // Most seen patterns (adopted multiple times)\n const topPatterns = patterns.filter((p) => (p.seen ?? 1) >= 3);\n if (topPatterns.length > 0) {\n console.log(\"Most seen patterns (seen 3+ times — widely used):\");\n for (const p of topPatterns.slice(0, 10)) {\n console.log(` [${p.ptype}] [${p.language}] ${p.title} (seen ${p.seen}x)`);\n }\n console.log();\n }\n\n // Scorecard\n console.log(`${\"─\".repeat(60)}`);\n console.log(\"Pattern retro scorecard:\");\n console.log(` Total patterns: ${patterns.length}`);\n console.log(` Widely used (3+): ${topPatterns.length}`);\n const adoptedCount = patterns.filter((p) => p.adopted === \"true\").length;\n console.log(` Adopted: ${adoptedCount}`);\n const adoptionRate =\n patterns.length > 0 ? ((adoptedCount / patterns.length) * 100).toFixed(0) : \"0\";\n console.log(` Adoption rate: ${adoptionRate}%`);\n console.log();\n console.log(\"Set TDAI_RETRO_DAYS=N to change the window (default: 7).\");\n\n db.close();\n}\n\n// ==================================================================\n// Moat 2/3: Conflict Detection + Inheritance Reports\n// ==================================================================\n\n/**\n * `remem-mcp decisions conflicts` — Show contradictory decisions.\n */\nexport function decisionsConflicts(dbPath: string = defaultDbPath()): void {\n let db: Database.Database;\n try {\n db = new Database(dbPath, { readonly: true });\n } catch {\n console.error(\"Error: Could not open database at\", dbPath);\n process.exit(1);\n }\n\n console.log(\"remem-mcp decisions conflicts — Decision Conflict Report\\n\");\n console.log(`${\"─\".repeat(60)}\\n`);\n\n const conflicts = db\n .prepare(\n `SELECT\n id,\n json_extract(metadata, '$.title') as title,\n json_extract(metadata, '$.choice') as choice,\n json_extract(metadata, '$.decision_type') as dtype,\n json_extract(metadata, '$.conflict_warning') as warning,\n json_extract(metadata, '$.confidence') as confidence,\n created_at\n FROM captures\n WHERE type = 'decision' AND deleted_at IS NULL\n AND json_extract(metadata, '$.conflict_warning') IS NOT NULL\n ORDER BY created_at DESC`,\n )\n .all() as {\n id: string;\n title: string;\n choice: string;\n dtype: string;\n warning: string;\n confidence: number;\n created_at: string;\n }[];\n\n if (conflicts.length === 0) {\n console.log(\"No decision conflicts detected.\\n\");\n db.close();\n return;\n }\n\n console.log(`Found ${conflicts.length} decision conflict(s):\\n`);\n for (const c of conflicts) {\n const date = new Date(c.created_at).toISOString().split(\"T\")[0];\n console.log(` ${date} [${c.dtype}] ${c.title}`);\n console.log(` ⚠ ${c.warning}`);\n }\n\n console.log(`\\n${\"─\".repeat(60)}`);\n console.log(\n \"Conflicts are detected when you choose a dependency that contradicts a past choice.\",\n );\n db.close();\n}\n\n/**\n * `remem-mcp decisions inherited` — Cross-project decision inheritance report.\n */\nexport function decisionsInherited(dbPath: string = defaultDbPath()): void {\n let db: Database.Database;\n try {\n db = new Database(dbPath, { readonly: true });\n } catch {\n console.error(\"Error: Could not open database at\", dbPath);\n process.exit(1);\n }\n\n console.log(\"remem-mcp decisions inherited — Cross-Project Decision Inheritance\\n\");\n console.log(`${\"─\".repeat(60)}\\n`);\n\n const inherited = db\n .prepare(\n `SELECT\n json_extract(metadata, '$.choice') as choice,\n MAX(json_extract(metadata, '$.title')) as title,\n json_extract(metadata, '$.decision_type') as dtype,\n COUNT(DISTINCT session_key) as project_count,\n SUM(CAST(json_extract(metadata, '$.confidence') AS INTEGER)) as total_confidence\n FROM captures\n WHERE type = 'decision' AND deleted_at IS NULL\n AND json_extract(metadata, '$.choice') IS NOT NULL\n GROUP BY json_extract(metadata, '$.choice'), json_extract(metadata, '$.decision_type')\n HAVING project_count > 1\n ORDER BY project_count DESC, total_confidence DESC\n LIMIT 20`,\n )\n .all() as {\n choice: string;\n title: string;\n dtype: string;\n project_count: number;\n total_confidence: number;\n }[];\n\n if (inherited.length === 0) {\n console.log(\"No cross-project decision inheritance detected.\\n\");\n db.close();\n return;\n }\n\n console.log(`Found ${inherited.length} decision(s) shared across projects:\\n`);\n for (const d of inherited) {\n console.log(` [${d.dtype}] ${d.title}`);\n console.log(` choice: ${d.choice}`);\n console.log(` projects: ${d.project_count}, total confidence: ${d.total_confidence}`);\n }\n\n console.log(`\\n${\"─\".repeat(60)}`);\n console.log(\"These decisions are auto-injected when you run similar commands in new projects.\");\n db.close();\n}\n\n/**\n * `remem-mcp patterns conflicts` — Show contradictory patterns.\n */\nexport function patternsConflicts(dbPath: string = defaultDbPath()): void {\n let db: Database.Database;\n try {\n db = new Database(dbPath, { readonly: true });\n } catch {\n console.error(\"Error: Could not open database at\", dbPath);\n process.exit(1);\n }\n\n console.log(\"remem-mcp patterns conflicts — Pattern Conflict Report\\n\");\n console.log(`${\"─\".repeat(60)}\\n`);\n\n const conflicts = db\n .prepare(\n `SELECT\n id,\n json_extract(metadata, '$.title') as title,\n json_extract(metadata, '$.pattern_type') as ptype,\n json_extract(metadata, '$.language') as language,\n json_extract(metadata, '$.file_path') as fpath,\n json_extract(metadata, '$.conflict_warning') as warning,\n created_at\n FROM captures\n WHERE type = 'pattern' AND deleted_at IS NULL\n AND json_extract(metadata, '$.conflict_warning') IS NOT NULL\n ORDER BY created_at DESC`,\n )\n .all() as {\n id: string;\n title: string;\n ptype: string;\n language: string;\n fpath: string;\n warning: string;\n created_at: string;\n }[];\n\n if (conflicts.length === 0) {\n console.log(\"No pattern conflicts detected.\\n\");\n db.close();\n return;\n }\n\n console.log(`Found ${conflicts.length} pattern conflict(s):\\n`);\n for (const c of conflicts) {\n const date = new Date(c.created_at).toISOString().split(\"T\")[0];\n console.log(` ${date} [${c.ptype}] [${c.language}] ${c.title}`);\n console.log(` file: ${c.fpath}`);\n console.log(` ⚠ ${c.warning}`);\n }\n\n console.log(`\\n${\"─\".repeat(60)}`);\n console.log(\n \"Conflicts are detected when patterns use inconsistent styles (e.g., CommonJS vs ESM).\",\n );\n db.close();\n}\n\n/**\n * `remem-mcp patterns templates` — Show extracted pattern templates.\n */\nexport function patternsTemplates(dbPath: string = defaultDbPath()): void {\n let db: Database.Database;\n try {\n db = new Database(dbPath, { readonly: true });\n } catch {\n console.error(\"Error: Could not open database at\", dbPath);\n process.exit(1);\n }\n\n console.log(\"remem-mcp patterns templates — Pattern Template Extraction\\n\");\n console.log(`${\"─\".repeat(60)}\\n`);\n\n const templates = db\n .prepare(\n `SELECT\n id,\n json_extract(metadata, '$.title') as title,\n json_extract(metadata, '$.pattern_type') as ptype,\n json_extract(metadata, '$.language') as language,\n json_extract(metadata, '$.pattern_template') as template,\n created_at\n FROM captures\n WHERE type = 'pattern' AND deleted_at IS NULL\n AND json_extract(metadata, '$.pattern_template') IS NOT NULL\n ORDER BY created_at DESC`,\n )\n .all() as {\n id: string;\n title: string;\n ptype: string;\n language: string;\n template: string;\n created_at: string;\n }[];\n\n if (templates.length === 0) {\n console.log(\"No pattern templates extracted yet.\\n\");\n console.log(\n \"Templates are auto-extracted when 3+ similar patterns are found in the same language.\",\n );\n db.close();\n return;\n }\n\n console.log(`Found ${templates.length} pattern template(s):\\n`);\n for (const t of templates) {\n const date = new Date(t.created_at).toISOString().split(\"T\")[0];\n let templateData: { template: string; similar_pattern_count: number } | null = null;\n try {\n templateData = JSON.parse(t.template);\n } catch {\n // skip\n }\n console.log(` ${date} [${t.ptype}] [${t.language}] ${t.title}`);\n if (templateData) {\n console.log(` template: ${templateData.template}`);\n console.log(` matches: ${templateData.similar_pattern_count} patterns`);\n }\n }\n\n console.log(`\\n${\"─\".repeat(60)}`);\n console.log(\"Templates are auto-extracted from 3+ similar patterns (same type, same language).\");\n db.close();\n}\n\n/**\n * `remem-mcp patterns inherited` — Cross-project pattern inheritance report.\n */\nexport function patternsInherited(dbPath: string = defaultDbPath()): void {\n let db: Database.Database;\n try {\n db = new Database(dbPath, { readonly: true });\n } catch {\n console.error(\"Error: Could not open database at\", dbPath);\n process.exit(1);\n }\n\n console.log(\"remem-mcp patterns inherited — Cross-Project Pattern Inheritance\\n\");\n console.log(`${\"─\".repeat(60)}\\n`);\n\n const inherited = db\n .prepare(\n `SELECT\n MAX(json_extract(metadata, '$.title')) as title,\n MAX(json_extract(metadata, '$.pattern_type')) as ptype,\n json_extract(metadata, '$.language') as language,\n json_extract(metadata, '$.signature') as sig,\n COUNT(DISTINCT session_key) as project_count,\n SUM(CAST(json_extract(metadata, '$.confidence') AS INTEGER)) as total_confidence\n FROM captures\n WHERE type = 'pattern' AND deleted_at IS NULL\n AND json_extract(metadata, '$.signature') IS NOT NULL\n GROUP BY json_extract(metadata, '$.signature'), json_extract(metadata, '$.language')\n HAVING project_count > 1\n ORDER BY project_count DESC, total_confidence DESC\n LIMIT 20`,\n )\n .all() as {\n title: string;\n ptype: string;\n language: string;\n sig: string;\n project_count: number;\n total_confidence: number;\n }[];\n\n if (inherited.length === 0) {\n console.log(\"No cross-project pattern inheritance detected.\\n\");\n db.close();\n return;\n }\n\n console.log(`Found ${inherited.length} pattern(s) shared across projects:\\n`);\n for (const p of inherited) {\n console.log(` [${p.ptype}] [${p.language}] ${p.title}`);\n console.log(` signature: ${(p.sig ?? \"\").slice(0, 60)}`);\n console.log(` projects: ${p.project_count}, total confidence: ${p.total_confidence}`);\n }\n\n console.log(`\\n${\"─\".repeat(60)}`);\n console.log(\n \"These patterns are auto-injected when you edit files in new projects (same language).\",\n );\n db.close();\n}\n","import { writeFileSync } from \"node:fs\";\nimport Database from \"better-sqlite3\";\n\ninterface ExportRow {\n id: string;\n session_key: string;\n agent_id: string;\n type: string;\n content: string;\n content_hash: string | null;\n tags: string | null;\n created_at: number;\n metadata: string | null;\n team_id: string | null;\n user_id: string | null;\n task_id: string | null;\n}\n\ninterface ExportMessage {\n id: string;\n capture_id: string;\n role: string;\n content: string;\n seq: number;\n created_at: number;\n}\n\ninterface ExportFormat {\n version: number;\n exported_at: number;\n count: number;\n captures: ExportRow[];\n messages: ExportMessage[];\n}\n\n/** Export all captures to a JSON file. */\nexport function exportData(\n dbPath: string,\n outputPath: string,\n filters?: { sessionKey?: string; type?: string; teamId?: string },\n): void {\n const db = new Database(dbPath, { readonly: true });\n\n let sql = \"SELECT * FROM captures\";\n const params: unknown[] = [];\n const conditions: string[] = [];\n\n if (filters?.sessionKey) {\n conditions.push(\"session_key = ?\");\n params.push(filters.sessionKey);\n }\n if (filters?.type) {\n conditions.push(\"type = ?\");\n params.push(filters.type);\n }\n if (filters?.teamId) {\n conditions.push(\"team_id = ?\");\n params.push(filters.teamId);\n }\n if (conditions.length > 0) {\n sql += ` WHERE ${conditions.join(\" AND \")}`;\n }\n\n sql += \" ORDER BY created_at ASC\";\n\n const rows = db.prepare(sql).all(...params) as ExportRow[];\n\n // Export messages for the captured entries\n let messages: ExportMessage[] = [];\n if (rows.length > 0) {\n const ids = rows.map((r) => r.id);\n const placeholders = ids.map(() => \"?\").join(\",\");\n messages = db\n .prepare(`SELECT * FROM messages WHERE capture_id IN (${placeholders}) ORDER BY seq ASC`)\n .all(...ids) as ExportMessage[];\n }\n\n db.close();\n\n const data: ExportFormat = {\n version: 2,\n exported_at: Date.now(),\n count: rows.length,\n captures: rows,\n messages,\n };\n\n if (outputPath === \"-\") {\n process.stdout.write(`${JSON.stringify(data, null, 2)}\\n`);\n } else {\n writeFileSync(outputPath, JSON.stringify(data, null, 2), \"utf-8\");\n console.log(`Exported ${rows.length} captures (${messages.length} messages) to ${outputPath}`);\n }\n}\n","import { execSync, spawn } from \"node:child_process\";\nimport { createHash } from \"node:crypto\";\nimport { appendFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir, tmpdir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport Database from \"better-sqlite3\";\n\n/** Whether to show visible feedback on stderr when memory is injected.\n * Set TDAI_QUIET=1 to suppress. Default: show feedback. */\nconst SHOW_FEEDBACK = process.env.TDAI_QUIET !== \"1\";\n\n/** Print a short visible feedback line to stderr so the user can see\n * that memory was injected. Does NOT interfere with stdout JSON. */\nfunction feedback(emoji: string, message: string): void {\n if (SHOW_FEEDBACK) {\n process.stderr.write(`\\n ${emoji} ${message}\\n\\n`);\n }\n}\n\n/**\n * Hook handler for SessionStart event.\n * Reads JSON from stdin (Devin CLI hook payload), queries the memory DB\n * for recent captures, and outputs additionalContext JSON on stdout.\n *\n * This is called by the agent's hook system, not by the MCP server.\n *\n * In addition to the JSON output on stdout, the handler appends a short\n * summary to a log file so the user can inspect which memories were\n * loaded without the output interfering with the terminal prompt.\n */\n\n/** Default log path: ~/.local/share/remem-mcp/session.log */\nfunction defaultLogPath(): string {\n return (\n process.env.TDAI_HOOK_LOG_PATH ??\n join(homedir(), \".local\", \"share\", \"remem-mcp\", \"session.log\")\n );\n}\n\n/** Append a timestamped line to the hook log file. */\nfunction logToFile(text: string): void {\n try {\n const logPath = defaultLogPath();\n mkdirSync(dirname(logPath), { recursive: true });\n const ts = new Date().toISOString();\n appendFileSync(logPath, `[${ts}] ${text}\\n`);\n } catch {\n // Logging is best-effort. Do not block the hook on log errors.\n }\n}\n\n/**\n * [Drift Detection] Get the temp file path for tracking error injections.\n * Each session gets its own file. Injections are logged here by PreToolUse\n * and checked by PostToolUse.\n */\nfunction driftFilePath(sessionKey: string): string {\n return join(tmpdir(), `remem-drift-${sessionKey}.jsonl`);\n}\n\n/**\n * [Moat 2/3: Drift Detection] Log decision/pattern injection for drift tracking.\n * Same mechanism as error drift — PreToolUse logs, PostToolUse checks.\n */\nfunction logInjectionDrift(\n sessionKey: string,\n captureType: \"decision\" | \"pattern\",\n captureId: string,\n command: string,\n): void {\n try {\n const path = join(tmpdir(), `remem-drift-${sessionKey}.jsonl`);\n const record = JSON.stringify({\n type: captureType,\n content_hash: captureId,\n error_id: captureId, // reuse field name for checkDriftInjection compat\n command: command.slice(0, 200),\n injected_at: Date.now(),\n });\n appendFileSync(path, `${record}\\n`);\n } catch {\n // Best-effort\n }\n}\n\n/**\n * [Moat 2: Decision Conflict] Detect contradictory decisions.\n * E.g., chose SQLite then chose Postgres for the same project.\n */\nfunction detectDecisionConflict(\n db: Database.Database,\n sessionKey: string,\n newChoice: string,\n decisionType: string,\n): string | null {\n // Only check dependency conflicts (chose X then chose Y for same role)\n if (decisionType !== \"dependency\") return null;\n\n // Known conflict pairs (same role, different choice)\n // Includes common npm package name aliases (e.g., \"pg\" = postgres)\n const conflictPairs: Record<string, string[]> = {\n sqlite: [\n \"postgres\",\n \"postgresql\",\n \"pg\",\n \"mysql\",\n \"mysql2\",\n \"mongodb\",\n \"mongo\",\n \"redis\",\n \"ioredis\",\n ],\n postgres: [\"sqlite\", \"pg\", \"mysql\", \"mysql2\", \"mongodb\", \"mongo\", \"redis\", \"ioredis\"],\n postgresql: [\"sqlite\", \"pg\", \"mysql\", \"mysql2\", \"mongodb\", \"mongo\", \"redis\", \"ioredis\"],\n pg: [\"sqlite\", \"mysql\", \"mysql2\", \"mongodb\", \"mongo\", \"redis\", \"ioredis\"],\n mysql: [\"sqlite\", \"postgres\", \"postgresql\", \"pg\", \"mongodb\", \"mongo\", \"redis\", \"ioredis\"],\n mysql2: [\"sqlite\", \"postgres\", \"postgresql\", \"pg\", \"mongodb\", \"mongo\", \"redis\", \"ioredis\"],\n mongodb: [\"sqlite\", \"postgres\", \"postgresql\", \"pg\", \"mysql\", \"mysql2\", \"redis\", \"ioredis\"],\n mongo: [\"sqlite\", \"postgres\", \"postgresql\", \"pg\", \"mysql\", \"mysql2\", \"redis\", \"ioredis\"],\n redis: [\"sqlite\", \"postgres\", \"postgresql\", \"pg\", \"mysql\", \"mysql2\", \"mongodb\", \"mongo\"],\n ioredis: [\"sqlite\", \"postgres\", \"postgresql\", \"pg\", \"mysql\", \"mysql2\", \"mongodb\", \"mongo\"],\n react: [\"vue\", \"svelte\", \"angular\", \"solid-js\", \"preact\"],\n vue: [\"react\", \"svelte\", \"angular\", \"solid-js\", \"preact\"],\n svelte: [\"react\", \"vue\", \"angular\", \"solid-js\", \"preact\"],\n angular: [\"react\", \"vue\", \"svelte\", \"solid-js\", \"preact\"],\n zod: [\"yup\", \"joi\", \"ajv\"],\n yup: [\"zod\", \"joi\", \"ajv\"],\n joi: [\"zod\", \"yup\", \"ajv\"],\n axios: [\"fetch\", \"got\", \"ky\", \"node-fetch\"],\n fetch: [\"axios\", \"got\", \"ky\", \"node-fetch\"],\n jest: [\"vitest\", \"mocha\", \"jasmine\", \"ava\"],\n vitest: [\"jest\", \"mocha\", \"jasmine\", \"ava\"],\n mocha: [\"jest\", \"vitest\", \"jasmine\", \"ava\"],\n tailwind: [\"bootstrap\", \"bulma\", \"styled-components\", \"emotion\"],\n bootstrap: [\"tailwind\", \"bulma\", \"styled-components\", \"emotion\"],\n };\n\n const newLower = newChoice.toLowerCase();\n const conflicts = conflictPairs[newLower];\n if (!conflicts) return null;\n\n // Check if any conflicting dependency was previously chosen\n for (const conflict of conflicts) {\n const existing = db\n .prepare(\n `SELECT id, json_extract(metadata, '$.title') as title\n FROM captures\n WHERE type = 'decision' AND deleted_at IS NULL\n AND session_key = ?\n AND json_extract(metadata, '$.decision_type') = 'dependency'\n AND LOWER(json_extract(metadata, '$.choice')) = ?\n LIMIT 1`,\n )\n .get(sessionKey, conflict) as { id: string; title: string } | undefined;\n\n if (existing) {\n return `CONFLICT: Previously chose ${conflict} but now choosing ${newLower}. Review before proceeding.`;\n }\n }\n\n return null;\n}\n\n/**\n * [Moat 3: Pattern Conflict] Detect contradictory code patterns.\n * E.g., one file uses CommonJS require, another uses ESM import.\n */\nfunction detectPatternConflict(\n db: Database.Database,\n sessionKey: string,\n newPattern: { pattern_type: string; language: string; signature: string; file_path: string },\n): string | null {\n // Check import style conflicts (require vs import)\n if (newPattern.pattern_type !== \"imports\") return null;\n\n const usesRequire = /require\\s*\\(/.test(newPattern.signature);\n const usesImport = /^import\\s+/.test(newPattern.signature);\n\n if (!usesRequire && !usesImport) return null;\n\n const oppositeStyle = usesRequire ? \"import\" : \"require\";\n const existing = db\n .prepare(\n `SELECT id, json_extract(metadata, '$.file_path') as fpath, json_extract(metadata, '$.signature') as sig\n FROM captures\n WHERE type = 'pattern' AND deleted_at IS NULL\n AND session_key = ?\n AND json_extract(metadata, '$.pattern_type') = 'imports'\n AND json_extract(metadata, '$.language') = ?\n AND json_extract(metadata, '$.file_path') != ?\n LIMIT 1`,\n )\n .get(sessionKey, newPattern.language, newPattern.file_path) as\n | { id: string; fpath: string; sig: string }\n | undefined;\n\n if (existing) {\n const existingUsesRequire = /require\\s*\\(/.test(existing.sig);\n const existingUsesImport = /^import\\s+/.test(existing.sig);\n\n if (usesRequire && existingUsesImport) {\n return `CONFLICT: ${existing.fpath} uses ESM import but ${newPattern.file_path} uses CommonJS require. Use one style consistently.`;\n }\n if (usesImport && existingUsesRequire) {\n return `CONFLICT: ${existing.fpath} uses CommonJS require but ${newPattern.file_path} uses ESM import. Use one style consistently.`;\n }\n }\n\n return null;\n}\n\n/**\n * [Moat 3: Pattern Template Extraction] Extract reusable template from 3+ similar patterns.\n * E.g., 3+ function patterns with similar signatures → extract common structure.\n */\nfunction extractPatternTemplate(\n db: Database.Database,\n sessionKey: string,\n language: string,\n patternType: string,\n): { template: string; count: number } | null {\n const patterns = db\n .prepare(\n `SELECT json_extract(metadata, '$.signature') as sig, json_extract(metadata, '$.title') as title\n FROM captures\n WHERE type = 'pattern' AND deleted_at IS NULL\n AND session_key = ?\n AND json_extract(metadata, '$.language') = ?\n AND json_extract(metadata, '$.pattern_type') = ?\n ORDER BY CAST(json_extract(metadata, '$.confidence') AS INTEGER) DESC\n LIMIT 10`,\n )\n .all(sessionKey, language, patternType) as { sig: string; title: string }[];\n\n if (patterns.length < 3) return null;\n\n // Extract common words from signatures\n const allWords = patterns\n .flatMap((p) => (p.sig ?? \"\").split(/[\\s(),:;]+/))\n .filter(\n (w) =>\n w.length > 2 &&\n ![\n \"string\",\n \"number\",\n \"boolean\",\n \"void\",\n \"any\",\n \"unknown\",\n \"return\",\n \"const\",\n \"let\",\n \"var\",\n \"function\",\n \"export\",\n \"async\",\n \"await\",\n ].includes(w),\n );\n\n const wordCounts = new Map<string, number>();\n for (const w of allWords) {\n wordCounts.set(w, (wordCounts.get(w) ?? 0) + 1);\n }\n\n const commonWords = [...wordCounts.entries()]\n .filter(([, count]) => count >= Math.ceil(patterns.length * 0.5))\n .sort((a, b) => b[1] - a[1])\n .slice(0, 5)\n .map(([w]) => w);\n\n if (commonWords.length >= 2) {\n return {\n template: commonWords.join(\" \"),\n count: patterns.length,\n };\n }\n\n return null;\n}\n\n/**\n * [Drift Detection] Log an error injection from PreToolUse.\n * Called when an error is injected before a command. PostToolUse will\n * check this file to detect if the agent ignored the warning.\n */\nfunction logDriftInjection(\n sessionKey: string,\n contentHash: string,\n errorId: string,\n command: string,\n): void {\n try {\n const path = driftFilePath(sessionKey);\n const record = JSON.stringify({\n content_hash: contentHash,\n error_id: errorId,\n command: command.slice(0, 200),\n injected_at: Date.now(),\n });\n appendFileSync(path, `${record}\\n`);\n } catch {\n // Best-effort — drift tracking is supplementary\n }\n}\n\n/**\n * [Drift Detection] Check if a content_hash was recently injected.\n * Returns the injection record if found, or null if not.\n * Cleans up entries older than 30 minutes.\n */\nfunction checkDriftInjection(\n sessionKey: string,\n contentHash: string,\n): { content_hash: string; error_id: string; command: string; injected_at: number } | null {\n try {\n const path = driftFilePath(sessionKey);\n if (!existsSync(path)) return null;\n\n const content = readFileSync(path, \"utf-8\");\n const lines = content.trim().split(\"\\n\").filter(Boolean);\n const now = Date.now();\n const maxAge = 30 * 60 * 1000; // 30 minutes\n\n // Filter to recent entries only\n const recent: string[] = [];\n let match: {\n content_hash: string;\n error_id: string;\n command: string;\n injected_at: number;\n } | null = null;\n\n for (const line of lines) {\n try {\n const record = JSON.parse(line);\n if (now - record.injected_at < maxAge) {\n recent.push(line);\n if (record.content_hash === contentHash && !match) {\n match = record;\n }\n }\n } catch {\n // Skip malformed lines\n }\n }\n\n // Clean up old entries (rewrite file with only recent entries)\n if (recent.length !== lines.length) {\n writeFileSync(path, recent.join(\"\\n\") + (recent.length > 0 ? \"\\n\" : \"\"));\n }\n\n return match;\n } catch {\n return null;\n }\n}\n\n/**\n * [Moat 2/3: Drift Detection] Get ALL recent drift injection records.\n * Used by PostToolUse to check if any decision/pattern was injected but ignored.\n */\nfunction checkAllDriftInjections(sessionKey: string): {\n type: string;\n content_hash: string;\n error_id: string;\n command: string;\n injected_at: number;\n}[] {\n try {\n const path = driftFilePath(sessionKey);\n if (!existsSync(path)) return [];\n\n const content = readFileSync(path, \"utf-8\");\n const lines = content.trim().split(\"\\n\").filter(Boolean);\n const now = Date.now();\n const maxAge = 30 * 60 * 1000; // 30 minutes\n\n const results: {\n type: string;\n content_hash: string;\n error_id: string;\n command: string;\n injected_at: number;\n }[] = [];\n const recent: string[] = [];\n\n for (const line of lines) {\n try {\n const record = JSON.parse(line);\n if (now - record.injected_at < maxAge) {\n recent.push(line);\n results.push(record);\n }\n } catch {\n // Skip malformed lines\n }\n }\n\n // Clean up old entries\n if (recent.length !== lines.length) {\n writeFileSync(path, recent.join(\"\\n\") + (recent.length > 0 ? \"\\n\" : \"\"));\n }\n\n return results;\n } catch {\n return [];\n }\n}\n\nexport function hookRecall(dbPath: string): void {\n // Read stdin\n const chunks: Buffer[] = [];\n process.stdin.setEncoding(\"utf-8\");\n process.stdin.on(\"data\", (chunk) => {\n chunks.push(Buffer.from(chunk));\n });\n\n process.stdin.on(\"end\", () => {\n try {\n const input = JSON.parse(Buffer.concat(chunks).toString(\"utf-8\"));\n const sessionKey = input.session_id ? input.session_id.slice(0, 16) : undefined;\n\n // Query recent captures from the DB\n // Try immutable mode first (no WAL writes needed), fall back to readonly\n let db: Database.Database;\n try {\n db = new Database(dbPath, { readonly: true, immutable: true });\n } catch {\n db = new Database(dbPath, { readonly: true });\n }\n\n // Try with session_key first, then fall back to all captures\n // Prioritize errors first (ExpeL pattern: failed trajectories are most valuable)\n const errorSql = `\n SELECT id, type, content, tags, created_at\n FROM captures\n WHERE type = 'error'\n `;\n const otherSql = `\n SELECT id, type, content, tags, created_at\n FROM captures\n WHERE type IN ('decision', 'learning', 'task')\n `;\n\n const rows: {\n id: string;\n type: string;\n content: string;\n tags: string | null;\n created_at: number;\n }[] = [];\n\n // If TDAI_GLOBAL_SESSION_KEY is set, include global memory first\n const globalKey = process.env.TDAI_GLOBAL_SESSION_KEY;\n if (globalKey) {\n const globalErrors = db\n .prepare(`${errorSql} AND session_key = ? ORDER BY created_at DESC LIMIT 3`)\n .all(globalKey) as typeof rows;\n rows.push(...globalErrors);\n const globalOthers = db\n .prepare(`${otherSql} AND session_key = ? ORDER BY created_at DESC LIMIT 3`)\n .all(globalKey) as typeof rows;\n rows.push(...globalOthers);\n }\n\n if (sessionKey) {\n const sessionErrors = db\n .prepare(`${errorSql} AND session_key = ? ORDER BY created_at DESC LIMIT 5`)\n .all(sessionKey) as typeof rows;\n const seen = new Set(rows.map((r) => r.id));\n rows.push(...sessionErrors.filter((r) => !seen.has(r.id)));\n const sessionOthers = db\n .prepare(`${otherSql} AND session_key = ? ORDER BY created_at DESC LIMIT 5`)\n .all(sessionKey) as typeof rows;\n rows.push(...sessionOthers.filter((r) => !seen.has(r.id)));\n }\n\n // If no results with session_key, query all captures\n if (rows.length === 0) {\n const allErrors = db\n .prepare(`${errorSql} ORDER BY created_at DESC LIMIT 5`)\n .all() as typeof rows;\n rows.push(...allErrors);\n const allOthers = db\n .prepare(`${otherSql} ORDER BY created_at DESC LIMIT 5`)\n .all() as typeof rows;\n rows.push(...allOthers);\n }\n\n db.close();\n\n if (rows.length === 0) {\n // No memory — output empty context\n logToFile(\"SessionStart: no recent memory found\");\n process.stdout.write(JSON.stringify({}));\n return;\n }\n\n // Build context text\n const lines: string[] = [\"[remem-mcp] Recent project memory:\"];\n for (const row of rows) {\n const date = new Date(row.created_at).toISOString().split(\"T\")[0];\n const tags = row.tags ? (JSON.parse(row.tags) as string[]) : [];\n const tagStr = tags.length > 0 ? ` [${tags.join(\", \")}]` : \"\";\n // Truncate content to 200 chars for context injection\n const content = row.content.length > 200 ? `${row.content.slice(0, 200)}...` : row.content;\n lines.push(`- (${row.type}${tagStr}) ${date}: ${content}`);\n }\n\n lines.push(\"\");\n lines.push(\"Use these memories to inform your work. Call recall() for more details.\");\n lines.push(\n \"After completing non-trivial work, call capture() to save a 1-3 sentence summary.\",\n );\n\n const context = lines.join(\"\\n\");\n\n // Append the summary to the log file so the user can inspect it\n // without the output interfering with the terminal prompt.\n logToFile(`SessionStart: loaded ${rows.length} capture(s)\\n${context}`);\n\n // Visible feedback so user sees memory was loaded\n const errorCount = rows.filter((r: any) => r.type === \"error\").length;\n const otherCount = rows.length - errorCount;\n const parts: string[] = [];\n if (errorCount > 0) parts.push(`${errorCount} past error(s)`);\n if (otherCount > 0) parts.push(`${otherCount} memorie(s)`);\n feedback(\"💡\", `remem-mcp: loaded ${parts.join(\" + \")} from previous sessions`);\n\n // Output hook JSON with additionalContext\n const output = {\n hookSpecificOutput: {\n hookEventName: \"SessionStart\",\n additionalContext: context,\n },\n };\n\n process.stdout.write(JSON.stringify(output));\n } catch (err) {\n // On any error, output empty JSON (don't block the session)\n process.stderr.write(`[remem-mcp hook-recall] Error: ${err}\\n`);\n logToFile(`SessionStart: error - ${err}`);\n process.stdout.write(JSON.stringify({}));\n }\n });\n}\n\n/**\n * Hook handler for Stop event.\n * Reminds the agent to call handoff before stopping — but only on the first fire.\n * On subsequent fires (stop_hook_active=true), lets the agent stop silently.\n * This prevents infinite loops where the agent has nothing to hand off but keeps\n * getting reminded.\n */\nexport function hookStop(dbPath?: string): void {\n const chunks: Buffer[] = [];\n process.stdin.setEncoding(\"utf-8\");\n process.stdin.on(\"data\", (chunk) => {\n chunks.push(Buffer.from(chunk));\n });\n\n process.stdin.on(\"end\", () => {\n let input: { stop_hook_active?: boolean; session_id?: string; transcript_path?: string } = {};\n let validInput = true;\n try {\n const raw = Buffer.concat(chunks).toString(\"utf-8\");\n if (raw.trim()) {\n input = JSON.parse(raw);\n } else {\n validInput = false;\n }\n } catch {\n validInput = false;\n }\n\n // Invalid/empty stdin: let the agent stop silently.\n if (!validInput) {\n process.stdout.write(JSON.stringify({}));\n return;\n }\n\n // Auto-capture the transcript directly — don't rely on the agent to call handoff.\n // Claude Code provides transcript_path in stdin (available immediately).\n // Devin CLI writes transcript AFTER Stop hook fires, so we fork a\n // background process that waits for the transcript file to appear.\n if (dbPath && input.session_id) {\n const sid = input.session_id;\n const tpath = input.transcript_path ?? null;\n\n if (tpath && existsSync(tpath)) {\n // Claude Code: transcript is already available — capture now\n void captureSessionTranscript(dbPath, sid, tpath).then((capId) => {\n logToFile(`Stop: direct capture for session ${sid}, id=${capId ?? \"skipped\"}`);\n });\n } else {\n // Devin CLI: transcript not yet written — spawn background waiter\n const scriptPath = process.argv[1];\n const child = spawn(\n process.execPath,\n [scriptPath, \"--wait-and-capture\", dbPath, sid, tpath ?? \"\"],\n { detached: true, stdio: \"ignore\" },\n );\n child.unref();\n logToFile(`Stop: spawned background capture for session ${sid}`);\n }\n }\n\n // Second+ fire (stop_hook_active): agent already got the reminder, let it stop.\n if (input.stop_hook_active) {\n process.stdout.write(JSON.stringify({}));\n return;\n }\n\n // Check if session is trivial (1-2 user messages, no file edits).\n // Skip reminder for trivial sessions to avoid noise.\n const isTrivial = (() => {\n const tpath = input.transcript_path;\n if (!tpath || !existsSync(tpath)) return false;\n try {\n const lines = readFileSync(tpath, \"utf-8\").trim().split(\"\\n\");\n let userCount = 0;\n let hasEdit = false;\n for (const line of lines) {\n try {\n const entry = JSON.parse(line);\n if (entry.role === \"user\" || entry.type === \"user\") userCount++;\n if (\n entry.tool_name === \"edit\" ||\n entry.tool_name === \"write\" ||\n entry.tool_name === \"Edit\" ||\n entry.tool_name === \"Write\"\n )\n hasEdit = true;\n } catch {\n // Not JSON, skip\n }\n }\n return userCount <= 2 && !hasEdit;\n } catch {\n return false;\n }\n })();\n\n if (isTrivial) {\n logToFile(\"Stop: trivial session, skipping reminder\");\n process.stdout.write(JSON.stringify({}));\n return;\n }\n\n // First fire: send a brief reminder (capture already happened above).\n const reminder =\n \"Session transcript auto-captured. If you made important decisions or \" +\n \"found non-obvious solutions, call capture() to save a concise summary. \" +\n \"Skip if the task was trivial.\";\n\n logToFile(\"Stop: reminder sent to agent\");\n\n const output = {\n hookSpecificOutput: {\n hookEventName: \"Stop\",\n additionalContext: reminder,\n },\n };\n\n process.stdout.write(JSON.stringify(output));\n });\n}\n\n/**\n * Hook handler for PostToolUse event.\n * When a Bash command fails (non-zero exit), automatically captures the error\n * to memory with structured fields (ReasoningBank + MNL pattern).\n *\n * Based on:\n * - Reflexion (Shinn et al., NeurIPS 2023): self-reflection on errors\n * - ReasoningBank (ICLR 2026): structured memory from failures\n * - ExpeL (AAAI 2024): voting/confidence system\n * - Headroom: success correlation\n *\n * Claude Code PostToolUse stdin: { tool_name, tool_input, tool_response }\n * tool_response for Bash includes: { stdout, stderr, exit_code, interrupted }\n */\nexport function hookPostToolUse(dbPath: string): void {\n const chunks: Buffer[] = [];\n process.stdin.setEncoding(\"utf-8\");\n process.stdin.on(\"data\", (chunk) => {\n chunks.push(Buffer.from(chunk));\n });\n\n process.stdin.on(\"end\", () => {\n try {\n const raw = Buffer.concat(chunks).toString(\"utf-8\");\n if (!raw.trim()) {\n process.stdout.write(JSON.stringify({}));\n return;\n }\n\n const input = JSON.parse(raw);\n const toolName = input.tool_name ?? \"\";\n const toolInput = input.tool_input ?? {};\n const toolResponse = input.tool_response ?? {};\n\n // Process Bash/exec for error + decision capture,\n // Write/Edit/MultiEdit for pattern capture (Moat 3)\n const isBash = toolName === \"Bash\" || toolName === \"exec\";\n const isWriteEdit = toolName === \"Write\" || toolName === \"Edit\" || toolName === \"MultiEdit\";\n\n if (!isBash && !isWriteEdit) {\n process.stdout.write(JSON.stringify({}));\n return;\n }\n\n // [Moat 3: Pattern Learning] Capture code patterns from Write/Edit\n if (isWriteEdit) {\n try {\n const db = new Database(dbPath);\n const sessionKey = hashPath(input.cwd ?? toolInput.workdir ?? process.cwd());\n const pattern = detectPattern(toolName, toolInput);\n if (pattern) {\n const id = `pat-${createHash(\"sha256\")\n .update(pattern.signature + pattern.file_path)\n .digest(\"hex\")\n .slice(0, 12)}`;\n const content = `Pattern: ${pattern.title} in ${pattern.file_path}`;\n const hash = createHash(\"sha256\").update(content).digest(\"hex\").slice(0, 16);\n\n // [Moat 3: Pattern Conflict Detection] Check for contradictory patterns\n const patternConflict = detectPatternConflict(db, sessionKey, {\n pattern_type: pattern.pattern_type,\n language: pattern.language,\n signature: pattern.signature,\n file_path: pattern.file_path,\n });\n if (patternConflict) {\n logToFile(`PostToolUse: PATTERN CONFLICT — ${patternConflict}`);\n }\n\n // Check if this pattern already exists\n const existing = db.prepare(\"SELECT id, metadata FROM captures WHERE id = ?\").get(id) as\n | { id: string; metadata: string }\n | undefined;\n\n if (existing) {\n // Upvote existing pattern\n const meta = JSON.parse(existing.metadata);\n meta.confidence = (meta.confidence ?? 1) + 1;\n meta.last_seen = new Date().toISOString();\n meta.seen_count = (meta.seen_count ?? 1) + 1;\n // [Moat 3: Adoption Tracking] Pattern seen again = adopted\n meta.adopted = true;\n meta.adopted_count = (meta.adopted_count ?? 0) + 1;\n if (patternConflict) {\n meta.conflict_warning = patternConflict;\n }\n db.prepare(\"UPDATE captures SET metadata = ? WHERE id = ?\").run(\n JSON.stringify(meta),\n existing.id,\n );\n } else {\n db.prepare(\n \"INSERT INTO captures (id, session_key, agent_id, type, content, content_hash, tags, created_at, metadata) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)\",\n ).run(\n id,\n sessionKey,\n \"auto\",\n \"pattern\",\n content,\n hash,\n JSON.stringify([pattern.pattern_type, pattern.language]),\n new Date().toISOString().replace(\"T\", \" \").replace(\"Z\", \"\"),\n JSON.stringify({\n tool: toolName,\n title: pattern.title,\n pattern_type: pattern.pattern_type,\n language: pattern.language,\n signature: pattern.signature,\n file_path: pattern.file_path,\n confidence: 1,\n seen_count: 1,\n adopted: false,\n adopted_count: 0,\n conflict_warning: patternConflict,\n first_seen: new Date().toISOString(),\n last_seen: new Date().toISOString(),\n }),\n );\n }\n logToFile(`PostToolUse: captured pattern ${pattern.title}`);\n\n // [Moat 3: Pattern Template Extraction] After capturing, check if 3+ similar\n // patterns exist → extract a reusable template\n try {\n const template = extractPatternTemplate(\n db,\n sessionKey,\n pattern.language,\n pattern.pattern_type,\n );\n if (template) {\n // Store template on the most recent pattern\n const recentPat = db\n .prepare(\n `SELECT id, metadata FROM captures\n WHERE type = 'pattern' AND session_key = ?\n AND json_extract(metadata, '$.language') = ?\n AND json_extract(metadata, '$.pattern_type') = ?\n ORDER BY created_at DESC LIMIT 1`,\n )\n .get(sessionKey, pattern.language, pattern.pattern_type) as\n | { id: string; metadata: string }\n | undefined;\n if (recentPat) {\n const tMeta = JSON.parse(recentPat.metadata);\n tMeta.pattern_template = {\n template: template.template,\n similar_pattern_count: template.count,\n language: pattern.language,\n pattern_type: pattern.pattern_type,\n extracted_at: new Date().toISOString(),\n };\n db.prepare(\"UPDATE captures SET metadata = ? WHERE id = ?\").run(\n JSON.stringify(tMeta),\n recentPat.id,\n );\n logToFile(\n `PostToolUse: PATTERN TEMPLATE extracted — \"${template.template}\" matches ${template.count} ${pattern.pattern_type} patterns in ${pattern.language}`,\n );\n }\n }\n } catch {\n // non-fatal\n }\n }\n db.close();\n\n // [Moat 3: Pattern Drift Detection] Check if patterns were recently injected\n // but agent wrote a different pattern style → drift\n try {\n const driftRecords = checkAllDriftInjections(sessionKey);\n if (driftRecords.length > 0 && pattern) {\n const driftDb = new Database(dbPath);\n for (const dr of driftRecords) {\n if (dr.type === \"pattern\") {\n const injectedPat = driftDb\n .prepare(\"SELECT id, metadata FROM captures WHERE id = ?\")\n .get(dr.content_hash) as { id: string; metadata: string } | undefined;\n if (injectedPat) {\n const injMeta = JSON.parse(injectedPat.metadata);\n // If the injected pattern's signature differs significantly from the new pattern\n if (\n injMeta.signature &&\n pattern.signature &&\n injMeta.signature !== pattern.signature\n ) {\n injMeta.drift_count = (injMeta.drift_count ?? 0) + 1;\n injMeta.last_drift_at = new Date().toISOString();\n driftDb\n .prepare(\"UPDATE captures SET metadata = ? WHERE id = ?\")\n .run(JSON.stringify(injMeta), injectedPat.id);\n logToFile(\n `PostToolUse: PATTERN DRIFT — injected ${dr.content_hash} but agent wrote different pattern`,\n );\n }\n }\n }\n }\n driftDb.close();\n }\n } catch {\n // non-fatal\n }\n } catch {\n // non-fatal\n }\n process.stdout.write(JSON.stringify({}));\n return;\n }\n\n // Claude Code: { exit_code, stderr, stdout }\n // Devin CLI: { success, output, error } — success=true means the tool ran,\n // NOT that the command succeeded. Exit code is embedded in the output string.\n // PostToolUseFailure (Claude Code): always a failure\n const isFailureEvent = input.hook_event_name === \"PostToolUseFailure\";\n const exitCode = toolResponse.exit_code ?? toolResponse.status ?? null;\n const devinSuccess = typeof toolResponse.success === \"boolean\" ? toolResponse.success : null;\n const stderr = toolResponse.stderr ?? toolResponse.error ?? \"\";\n const stdout = toolResponse.stdout ?? toolResponse.output ?? \"\";\n\n // Devin CLI embeds exit code in the output string as \"Exit code: N\"\n // and reports success=true even when the command failed.\n // Parse the exit code from output if not explicitly provided.\n let parsedExitCode = exitCode;\n if (parsedExitCode === null && typeof stdout === \"string\") {\n const exitMatch = stdout.match(/Exit code:\\s*(\\d+)/);\n if (exitMatch) {\n parsedExitCode = Number.parseInt(exitMatch[1], 10);\n }\n }\n\n const isError =\n isFailureEvent ||\n devinSuccess === false ||\n (parsedExitCode !== null && parsedExitCode !== 0);\n const command = toolInput.command ?? \"\";\n const cwd = input.cwd ?? toolInput.workdir ?? process.cwd();\n const sessionKey = hashPath(cwd);\n\n // Noise filter: skip error capture for obvious test/noise commands\n if (isNoiseCommand(command)) {\n logToFile(`PostToolUse: skipping noise command: ${command.slice(0, 80)}`);\n process.stdout.write(JSON.stringify({}));\n return;\n }\n\n let db: Database.Database;\n try {\n db = new Database(dbPath);\n } catch {\n process.stdout.write(JSON.stringify({}));\n return;\n }\n\n // [Feature 4] Success correlation: if command succeeds and previously failed,\n // link the success to the previous error and upvote it\n if (!isError) {\n const prevError = db\n .prepare(\n `SELECT id, metadata FROM captures\n WHERE type = 'error' AND session_key = ?\n AND created_at > datetime('now', '-7 days')\n AND json_extract(metadata, '$.command') = ?\n ORDER BY created_at DESC LIMIT 1`,\n )\n .get(sessionKey, command.slice(0, 200)) as { id: string; metadata: string } | undefined;\n\n if (prevError) {\n // Upvote the previous error (it was resolved)\n const meta = JSON.parse(prevError.metadata);\n const confidence = (meta.confidence ?? 2) + 1;\n meta.resolved = true;\n meta.resolved_at = new Date().toISOString();\n meta.resolution = \"Command succeeded after previous failure\";\n meta.confidence = confidence;\n\n // [Feature 9] Record the fix that worked — extract from stdout (success output)\n // This becomes the \"proven fix\" injected by PreToolUse for similar future errors\n const successSummary = (stdout || \"\").trim().slice(0, 200);\n if (successSummary) {\n meta.fix_applied = `Command succeeded. Output: ${successSummary.slice(0, 150)}`;\n } else {\n meta.fix_applied = meta.correct_approach ?? \"Command succeeded after fix.\";\n }\n\n // [Recovery Pattern Library] Extract a structured recovery playbook.\n // Combines anti_pattern + correct_approach + fix_applied into step-by-step guidance.\n // (SRE pattern: runbooks / incident playbooks)\n if (meta.attempt_count && meta.attempt_count >= 2) {\n meta.recovery_pattern = {\n steps: [\n `1. Identify: ${meta.title ?? \"the error\"}`,\n `2. Avoid: ${meta.anti_pattern ?? \"the anti-pattern that caused this\"}`,\n `3. Apply: ${meta.correct_approach ?? \"the correct approach\"}`,\n `4. Verify: ${meta.fix_applied?.slice(0, 80) ?? \"run the command again\"}`,\n ],\n attempt_count: meta.attempt_count,\n error_type: meta.error_type ?? \"runtime\",\n extracted_at: new Date().toISOString(),\n };\n }\n\n // [Fix Rollback Plan] Auto-generate a rollback plan for the fix.\n // Safety net: if the fix causes issues, agent knows how to undo it.\n const rollback = generateRollbackPlan(command, meta.fix_applied ?? \"\");\n if (rollback) {\n meta.rollback_plan = rollback;\n }\n\n // [Fix Provenance Chain] Mark provenance as auto_captured (system recorded it)\n if (!meta.fix_provenance) {\n meta.fix_provenance = \"auto_captured\";\n }\n\n // [Auto-Annotation] Regenerate notes with updated state (resolved, validated)\n meta.auto_notes = generateAutoNotes({\n attempt_count: meta.attempt_count,\n severity: meta.severity,\n escalation_level: meta.escalation_level,\n error_type: meta.error_type,\n resolved: true,\n fix_validated: meta.fix_validated,\n drift_count: meta.drift_count,\n });\n\n // [P0: A/B validation] Validate the fix — check if stdout contains\n // error indicators (agent-learn pattern: only promote if proven)\n // A \"clean\" success has no error keywords in stdout.\n const lowerStdout = (stdout || \"\").toLowerCase();\n const hasErrorIndicators = /\\b(errors?|failed|failure|exception|traceback|fatal)\\b/.test(\n lowerStdout,\n );\n meta.fix_validated = !hasErrorIndicators;\n if (hasErrorIndicators) {\n logToFile(\n `PostToolUse: fix recorded but UNVALIDATED (stdout contains error indicators) for ${prevError.id}`,\n );\n }\n\n db.prepare(\"UPDATE captures SET metadata = ? WHERE id = ?\").run(\n JSON.stringify(meta),\n prevError.id,\n );\n logToFile(\n `PostToolUse: success correlation — upvoted error ${prevError.id} (confidence=${confidence}, fix recorded, validated=${meta.fix_validated})`,\n );\n\n // [Fix Template Extraction] When an error is resolved, check if 2+ similar\n // errors (same error_type) have similar fixes. If so, extract a reusable template.\n // (Moves from specific fixes to generalizable principles)\n if (meta.fix_validated && meta.fix_applied) {\n try {\n const similarFixes = db\n .prepare(\n `SELECT\n json_extract(metadata, '$.fix_applied') as fix,\n json_extract(metadata, '$.title') as title\n FROM captures\n WHERE type = 'error' AND deleted_at IS NULL\n AND session_key = ?\n AND json_extract(metadata, '$.resolved') = true\n AND json_extract(metadata, '$.fix_validated') = true\n AND json_extract(metadata, '$.fix_applied') IS NOT NULL\n AND json_extract(metadata, '$.error_type') = ?\n AND id != ?\n ORDER BY created_at DESC LIMIT 5`,\n )\n .all(sessionKey, meta.error_type ?? \"runtime\", prevError.id) as {\n fix: string;\n title: string;\n }[];\n\n if (similarFixes.length >= 2) {\n // Check if fixes share a common pattern (simple word overlap)\n const allFixes = [meta.fix_applied, ...similarFixes.map((s) => s.fix)];\n const words = allFixes[0]\n .toLowerCase()\n .split(/\\s+/)\n .filter(\n (w) => w.length > 3 && ![\"command\", \"succeeded\", \"output\", \"error\"].includes(w),\n );\n const commonWords = words.filter((w) =>\n allFixes.slice(1).every((f) => f.toLowerCase().includes(w)),\n );\n\n if (commonWords.length >= 2) {\n // Template found — store it on the most recent error as a template marker\n meta.fix_template = {\n pattern: commonWords.join(\" \"),\n similar_fix_count: allFixes.length,\n error_type: meta.error_type ?? \"runtime\",\n extracted_at: new Date().toISOString(),\n };\n db.prepare(\"UPDATE captures SET metadata = ? WHERE id = ?\").run(\n JSON.stringify(meta),\n prevError.id,\n );\n logToFile(\n `PostToolUse: FIX TEMPLATE extracted — pattern \"${commonWords.join(\" \")}\" matches ${allFixes.length} fixes for ${meta.error_type ?? \"runtime\"} errors`,\n );\n }\n }\n } catch {\n // Non-fatal\n }\n }\n }\n\n // [P0: Harm gate] Check if a previously resolved error's command\n // is NOW failing again — this means the \"proven fix\" caused a regression.\n // Mark the original resolved error with harm_count to prevent re-injection.\n // (errlore pattern: withhold harmful lessons)\n\n // [Moat 2: Decision Learning] Auto-capture decisions from successful commands.\n // Detects dependency choices, config decisions, commit-encoded decisions.\n const decision = detectDecision(command, stdout);\n if (decision) {\n try {\n const decId = `dec-${createHash(\"sha256\")\n .update(decision.choice + sessionKey)\n .digest(\"hex\")\n .slice(0, 12)}`;\n const existingDec = db\n .prepare(\"SELECT id, metadata FROM captures WHERE id = ?\")\n .get(decId) as { id: string; metadata: string } | undefined;\n\n // [Moat 2: Decision Conflict Detection] Check for contradictory decisions\n const conflict = detectDecisionConflict(\n db,\n sessionKey,\n decision.choice,\n decision.decision_type,\n );\n if (conflict) {\n logToFile(`PostToolUse: DECISION CONFLICT — ${conflict}`);\n }\n\n // [Moat 2: Decision Drift Detection] Check if a different decision was recently injected\n // If so, the agent ignored the injected decision and chose differently → drift\n try {\n const driftRecords = checkAllDriftInjections(sessionKey);\n for (const dr of driftRecords) {\n if (dr.type === \"decision\" && dr.content_hash !== decId) {\n // A different decision was injected but agent chose this one instead\n const injectedDec = db\n .prepare(\"SELECT id, metadata FROM captures WHERE id = ?\")\n .get(dr.content_hash) as { id: string; metadata: string } | undefined;\n if (injectedDec) {\n const injMeta = JSON.parse(injectedDec.metadata);\n injMeta.drift_count = (injMeta.drift_count ?? 0) + 1;\n injMeta.last_drift_at = new Date().toISOString();\n db.prepare(\"UPDATE captures SET metadata = ? WHERE id = ?\").run(\n JSON.stringify(injMeta),\n injectedDec.id,\n );\n logToFile(\n `PostToolUse: DECISION DRIFT — injected ${dr.content_hash} but agent chose ${decision.choice}`,\n );\n }\n }\n }\n } catch {\n // non-fatal\n }\n\n if (existingDec) {\n // Decision already exists — upvote confidence\n // [Moat 2: Follow Rate Tracking] Agent re-chose same decision → followed=true\n const dMeta = JSON.parse(existingDec.metadata);\n dMeta.confidence = (dMeta.confidence ?? 1) + 1;\n dMeta.last_seen = new Date().toISOString();\n dMeta.seen_count = (dMeta.seen_count ?? 1) + 1;\n dMeta.followed = true;\n dMeta.follow_count = (dMeta.follow_count ?? 0) + 1;\n if (conflict) {\n dMeta.conflict_warning = conflict;\n }\n db.prepare(\"UPDATE captures SET metadata = ? WHERE id = ?\").run(\n JSON.stringify(dMeta),\n decId,\n );\n } else {\n const decContent = `Decision: ${decision.title}`;\n const decHash = createHash(\"sha256\").update(decContent).digest(\"hex\").slice(0, 16);\n db.prepare(\n \"INSERT INTO captures (id, session_key, agent_id, type, content, content_hash, tags, created_at, metadata) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)\",\n ).run(\n decId,\n sessionKey,\n \"auto\",\n \"decision\",\n decContent,\n decHash,\n JSON.stringify([decision.decision_type]),\n new Date().toISOString().replace(\"T\", \" \").replace(\"Z\", \"\"),\n JSON.stringify({\n title: decision.title,\n decision_type: decision.decision_type,\n choice: decision.choice,\n rationale: decision.rationale,\n command: command.slice(0, 200),\n confidence: 1,\n seen_count: 1,\n followed: null,\n follow_count: 0,\n drift_count: 0,\n conflict_warning: conflict,\n first_seen: new Date().toISOString(),\n last_seen: new Date().toISOString(),\n }),\n );\n logToFile(`PostToolUse: captured decision — ${decision.title}`);\n }\n } catch {\n // non-fatal\n }\n }\n\n db.close();\n process.stdout.write(JSON.stringify({}));\n return;\n }\n\n // --- Error capture path ---\n\n // Build error summary\n const errorOutput = (stderr || stdout || \"\").trim();\n const truncatedError =\n errorOutput.length > 500 ? `${errorOutput.slice(0, 500)}...` : errorOutput;\n\n // [Feature 1] Classify error type\n const errorType = classifyError(command, truncatedError);\n // [Severity Classification] Classify impact level\n const severity = classifySeverity(command, errorType, truncatedError);\n\n // [Feature 1] Structured memory (ReasoningBank + MNL pattern)\n const title = generateErrorTitle(command, errorType);\n const antiPattern = extractAntiPattern(command, truncatedError);\n const correctApproach = suggestCorrectApproach(command, errorType, truncatedError);\n\n // Build content for capture\n const content = `Command failed: ${command}\\nError (${errorType}): ${truncatedError}`;\n\n // [P2: Semantic error matching] Normalize error content before hashing\n // so similar errors (same type, same command, different line numbers/variables)\n // are detected as duplicates/recurrences.\n // Normalization: replace line numbers, variable names, file paths with placeholders.\n const normalizedError = truncatedError\n .replace(/line \\d+/g, \"line N\")\n .replace(/col \\d+/g, \"col N\")\n .replace(/\\b\\d+\\b/g, \"N\")\n .replace(/'[^']+'/g, \"'X'\")\n .replace(/\"[^\"]+\"/g, '\"X\"')\n .replace(/src\\/[^\\s:]+/g, \"src/PATH\")\n .replace(/\\.\\/[^\\s:]+/g, \"./PATH\")\n .replace(/\\/[^\\s:]+\\/[^\\s:]+/g, \"/PATH\");\n const semanticContent = `Command failed: ${command}\\nError (${errorType}): ${normalizedError}`;\n const contentHash = createHash(\"sha256\").update(semanticContent).digest(\"hex\").slice(0, 16);\n const id = generateId();\n const now = new Date().toISOString().replace(\"T\", \" \").replace(\"Z\", \"\");\n\n // Check for duplicate using semantic hash (same normalized error in last hour)\n const recent = db\n .prepare(\n \"SELECT id FROM captures WHERE content_hash = ? AND created_at > datetime('now', '-1 hour') LIMIT 1\",\n )\n .get(contentHash) as { id: string } | undefined;\n\n if (recent) {\n // [Feature 5] Downvote the existing error — it recurred (ExpeL + Midas pattern)\n const existingMeta = db\n .prepare(\"SELECT metadata FROM captures WHERE id = ?\")\n .get(recent.id) as { metadata: string } | undefined;\n if (existingMeta) {\n const meta = JSON.parse(existingMeta.metadata);\n meta.downvotes = (meta.downvotes ?? 0) + 1;\n meta.confidence = Math.max(0, (meta.confidence ?? 2) - 1);\n meta.last_recurred = new Date().toISOString();\n // [Fix Attempt Counter] Track how many times this error occurred before resolution\n meta.attempt_count = (meta.attempt_count ?? 1) + 1;\n\n // [Error Escalation Policy] Auto-escalate when attempt_count >= threshold.\n // PagerDuty pattern: recurrence → escalation → stronger intervention.\n // Level 0: normal, Level 1: elevated (3+ attempts), Level 2: critical (5+),\n // Level 3: blocker (7+). Bump severity and add escalated_at timestamp.\n const escalationThreshold = Number(process.env.TDAI_ESCALATION_THRESHOLD ?? 3);\n if (meta.attempt_count >= escalationThreshold) {\n const newLevel = meta.attempt_count >= 7 ? 3 : meta.attempt_count >= 5 ? 2 : 1;\n const prevLevel = meta.escalation_level ?? 0;\n if (newLevel > prevLevel) {\n meta.escalation_level = newLevel;\n meta.escalated_at = new Date().toISOString();\n // Bump severity: major→critical (level 1), critical→blocker (level 2+)\n if (newLevel >= 2) {\n meta.severity = \"blocker\";\n } else if (meta.severity === \"major\" || !meta.severity) {\n meta.severity = \"critical\";\n }\n logToFile(\n `PostToolUse: ESCALATION — error ${recent.id} escalated to level ${newLevel} (attempt_count=${meta.attempt_count}, severity=${meta.severity})`,\n );\n }\n }\n\n // [Drift Detection] Check if this error was injected by PreToolUse\n // recently. If so, the agent was warned but still hit the same error.\n const driftHit = checkDriftInjection(sessionKey, contentHash);\n if (driftHit) {\n meta.drift_count = (meta.drift_count ?? 0) + 1;\n meta.last_drift_at = new Date().toISOString();\n logToFile(\n `PostToolUse: DRIFT detected — error ${recent.id} was injected but agent still failed (drift_count=${meta.drift_count})`,\n );\n }\n\n // [Auto-Annotation] Regenerate notes with updated recurrence state\n meta.auto_notes = generateAutoNotes({\n attempt_count: meta.attempt_count,\n severity: meta.severity,\n escalation_level: meta.escalation_level,\n error_type: meta.error_type,\n resolved: meta.resolved,\n fix_validated: meta.fix_validated,\n drift_count: meta.drift_count,\n });\n\n db.prepare(\"UPDATE captures SET metadata = ? WHERE id = ?\").run(\n JSON.stringify(meta),\n recent.id,\n );\n logToFile(\n `PostToolUse: error recurred — downvoted ${recent.id} (confidence=${meta.confidence})`,\n );\n\n // [Feature 5] Prune if confidence reaches 0 (ExpeL removal threshold)\n if (meta.confidence <= 0) {\n db.prepare(\"UPDATE captures SET deleted_at = ? WHERE id = ?\").run(\n new Date().toISOString().replace(\"T\", \" \").replace(\"Z\", \"\"),\n recent.id,\n );\n logToFile(`PostToolUse: pruned error ${recent.id} (confidence reached 0)`);\n }\n }\n\n // [P0: Harm gate] If this recurring error was previously resolved,\n // the \"proven fix\" caused a regression. Mark it as harmful.\n // (errlore pattern: withhold harmful lessons)\n const prevResolved = db\n .prepare(\n `SELECT id, metadata FROM captures\n WHERE type = 'error' AND session_key = ?\n AND created_at > datetime('now', '-30 days')\n AND json_extract(metadata, '$.resolved') = 1\n AND json_extract(metadata, '$.fix_applied') IS NOT NULL\n AND json_extract(metadata, '$.command') = ?\n ORDER BY created_at DESC LIMIT 1`,\n )\n .get(sessionKey, command.slice(0, 200)) as { id: string; metadata: string } | undefined;\n if (prevResolved) {\n const rMeta = JSON.parse(prevResolved.metadata);\n rMeta.fix_harm_count = (rMeta.fix_harm_count ?? 0) + 1;\n db.prepare(\"UPDATE captures SET metadata = ? WHERE id = ?\").run(\n JSON.stringify(rMeta),\n prevResolved.id,\n );\n logToFile(\n `PostToolUse: HARM GATE — proven fix for ${prevResolved.id} caused regression (harm_count=${rMeta.fix_harm_count})`,\n );\n }\n\n db.close();\n process.stdout.write(JSON.stringify({}));\n return;\n }\n\n // [Drift Detection] Check if this error was injected by PreToolUse\n // recently. If so, the agent was warned but still hit the same error.\n const driftHit = checkDriftInjection(sessionKey, contentHash);\n if (driftHit) {\n logToFile(\n `PostToolUse: DRIFT detected — error was injected but agent still failed (content_hash=${contentHash})`,\n );\n }\n\n // [Fix Lineage] Check if a recently resolved error on the same command\n // exists — if so, this new error might be a regression caused by the fix.\n // Link the new error to the old one via caused_by_error_id.\n // (Different from harm gate: harm gate blocks re-injection. Lineage tracks the chain.)\n let causedByErrorId: string | null = null;\n try {\n const lineagePrev = db\n .prepare(\n `SELECT id FROM captures\n WHERE type = 'error' AND session_key = ?\n AND created_at > datetime('now', '-30 days')\n AND json_extract(metadata, '$.resolved') = 1\n AND json_extract(metadata, '$.fix_applied') IS NOT NULL\n AND json_extract(metadata, '$.command') = ?\n ORDER BY created_at DESC LIMIT 1`,\n )\n .get(sessionKey, command.slice(0, 200)) as { id: string } | undefined;\n if (lineagePrev) {\n causedByErrorId = lineagePrev.id;\n logToFile(`PostToolUse: LINEAGE — new error may be caused by fix on ${lineagePrev.id}`);\n }\n } catch {\n // Non-fatal\n }\n\n // [Feature 1] Capture with structured metadata\n db.prepare(`\n INSERT INTO captures (id, session_key, agent_id, type, content, content_hash, tags, created_at, metadata)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)\n `).run(\n id,\n sessionKey,\n \"auto\",\n \"error\",\n content,\n contentHash,\n JSON.stringify([\"auto-capture\", \"error\", errorType]),\n now,\n JSON.stringify({\n tool: toolName,\n command: command.slice(0, 200),\n exit_code: exitCode,\n error_type: errorType,\n // [Severity Classification] Impact level: blocker/critical/major/minor\n severity: severity,\n // [Feature 1] Structured fields (ReasoningBank + MNL)\n title: title,\n anti_pattern: antiPattern,\n correct_approach: correctApproach,\n // [P3: Root Cause Analysis] Extract root cause from stack trace (Experia pattern)\n root_cause: extractRootCause(truncatedError),\n // [Feature 5] Confidence/voting (ExpeL + Midas)\n confidence: 2,\n upvotes: 0,\n downvotes: 0,\n // [Feature 4] Success correlation\n resolved: false,\n // [Drift Detection] Track if this error was injected but still occurred\n drift_count: driftHit ? 1 : 0,\n last_drift_at: driftHit ? new Date().toISOString() : undefined,\n // [Fix Lineage] Link to the resolved error whose fix may have caused this\n caused_by_error_id: causedByErrorId ?? undefined,\n // [Goal-Linked Errors] Tag with current goal ID if set via env\n goal_id: process.env.TDAI_GOAL_ID ?? undefined,\n // [Fix Attempt Counter] Track how many attempts to fix (1 = first occurrence)\n attempt_count: 1,\n // [Fix Provenance Chain] Track where this error record came from\n fix_provenance: \"auto_captured\",\n // [Error Context Enrichment] Git context at error time (branch, commits, changed files)\n context_enrichment: captureGitContext(cwd),\n // [Auto-Annotation] System-generated notes based on initial error state\n auto_notes: generateAutoNotes({\n attempt_count: 1,\n severity,\n error_type: errorType,\n }),\n }),\n );\n\n db.close();\n\n logToFile(`PostToolUse: auto-captured ${errorType} error. id=${id}`);\n\n // [Error Correlation Engine] Check if a different error occurred in the last 10 minutes.\n // If so, record a correlation pair: E1 (previous) → E2 (this error).\n // When E1 recurs in the future, warn that E2 often follows.\n // (SRE pattern: incident correlation / cascading failure detection)\n try {\n const corrDb = new Database(dbPath);\n const recentErrors = corrDb\n .prepare(\n `SELECT id, json_extract(metadata, '$.error_type') as etype, json_extract(metadata, '$.title') as title\n FROM captures\n WHERE type = 'error' AND deleted_at IS NULL\n AND session_key = ?\n AND id != ?\n AND created_at > datetime('now', '-10 minutes')\n AND json_extract(metadata, '$.error_type') != ?\n ORDER BY created_at DESC LIMIT 3`,\n )\n .all(sessionKey, id, errorType) as { id: string; etype: string; title: string }[];\n\n for (const prev of recentErrors) {\n // Record correlation on the previous error\n const prevRow = corrDb\n .prepare(\"SELECT metadata FROM captures WHERE id = ?\")\n .get(prev.id) as { metadata: string } | undefined;\n if (prevRow) {\n const prevMeta = JSON.parse(prevRow.metadata);\n const correlations = prevMeta.error_correlations ?? [];\n // Check if this correlation pair already exists\n const existing = correlations.find(\n (c: { next_error_type: string }) => c.next_error_type === errorType,\n );\n if (existing) {\n existing.count = (existing.count ?? 1) + 1;\n existing.last_seen = new Date().toISOString();\n } else {\n correlations.push({\n next_error_type: errorType,\n next_error_title: title.slice(0, 60),\n count: 1,\n first_seen: new Date().toISOString(),\n last_seen: new Date().toISOString(),\n });\n }\n prevMeta.error_correlations = correlations;\n corrDb\n .prepare(\"UPDATE captures SET metadata = ? WHERE id = ?\")\n .run(JSON.stringify(prevMeta), prev.id);\n }\n }\n corrDb.close();\n } catch {\n // Non-fatal\n }\n\n // [Feature 7] Cross-project error pattern detection\n // Check if the same error type + similar command failed in other projects\n const patternAlert = detectCrossProjectPattern(dbPath, sessionKey, errorType, command);\n\n // [Feature 3] Self-reflection prompt (Reflexion pattern)\n // Inject a prompt asking the agent to reflect on the error\n const reflection = `[remem-mcp] Auto-captured ${errorType} error: ${title}\n\nAnti-pattern: ${antiPattern}\nSuggested fix: ${correctApproach}\n${patternAlert ? `\\n⚠️ CROSS-PROJECT PATTERN: ${patternAlert}` : \"\"}\n\nBefore retrying, reflect on WHY this failed and what you should do differently. Call capture() with type=\"learning\" to save your reflection.`;\n\n // Visible feedback\n feedback(\"📸\", `remem-mcp: captured ${errorType} error — will inject fix next time`);\n\n const output = {\n hookSpecificOutput: {\n hookEventName: \"PostToolUse\",\n additionalContext: reflection,\n },\n };\n\n process.stdout.write(JSON.stringify(output));\n } catch (err) {\n process.stderr.write(`[remem-mcp hook-post-tool-use] Error: ${err}\\n`);\n logToFile(`PostToolUse: error - ${err}`);\n process.stdout.write(JSON.stringify({}));\n }\n });\n}\n\n/**\n * Hook handler for PreToolUse event.\n * Before running lint/build/test commands, inject the BEST matching past error\n * from memory so the agent can avoid repeating it.\n *\n * Based on:\n * - ReasoningBank (ICLR 2026): k=1 retrieval is optimal (k=2+ degrades performance)\n * - SWE-Exp: \"Precisely ONE well-selected experience per issue is optimal\"\n * - ExpeL (AAAI 2024): confidence-based ranking\n * - memcite: stale memory detection\n */\nexport function hookPreToolUse(dbPath: string): void {\n const chunks: Buffer[] = [];\n process.stdin.setEncoding(\"utf-8\");\n process.stdin.on(\"data\", (chunk) => {\n chunks.push(Buffer.from(chunk));\n });\n\n process.stdin.on(\"end\", () => {\n try {\n const raw = Buffer.concat(chunks).toString(\"utf-8\");\n if (!raw.trim()) {\n process.stdout.write(JSON.stringify({}));\n return;\n }\n\n const input = JSON.parse(raw);\n const toolName = input.tool_name ?? \"\";\n const toolInput = input.tool_input ?? {};\n const command = toolInput.command ?? \"\";\n\n // [Pre-action matchers] Warn before dangerous commands\n // (AgentRecall pattern: check_action before publish/push/deploy/DROP TABLE)\n const dangerWarning = checkDangerousCommand(command);\n if (dangerWarning) {\n const output = {\n hookSpecificOutput: {\n hookEventName: \"PreToolUse\",\n additionalContext: dangerWarning,\n },\n };\n logToFile(`PreToolUse: DANGER warning for: ${command.slice(0, 80)}`);\n process.stdout.write(JSON.stringify(output));\n return;\n }\n\n // [Error Prediction] When editing a file, check if that file has error history.\n // Inject proactive warnings BEFORE the edit, not after the build fails.\n // (TDAD pattern: predict errors from file change history)\n if (toolName === \"Write\" || toolName === \"Edit\" || toolName === \"MultiEdit\") {\n const filePath = toolInput.file_path ?? toolInput.path ?? \"\";\n if (filePath && process.env.TDAI_PREDICTIVE_ERRORS === \"1\") {\n const cwd = input.cwd ?? toolInput.workdir ?? process.cwd();\n const sessionKey = hashPath(cwd);\n try {\n const predDb = new Database(dbPath, { readonly: true });\n const basename = filePath.split(\"/\").pop() ?? filePath;\n // Find errors that reference this file path or basename\n const fileErrors = predDb\n .prepare(\n `SELECT\n json_extract(metadata, '$.title') as title,\n json_extract(metadata, '$.error_type') as etype,\n json_extract(metadata, '$.anti_pattern') as anti,\n json_extract(metadata, '$.correct_approach') as fix,\n json_extract(metadata, '$.resolved') as resolved,\n created_at\n FROM captures\n WHERE type = 'error' AND deleted_at IS NULL\n AND session_key = ?\n AND created_at > datetime('now', '-30 days')\n AND (content LIKE ? OR content LIKE ?)\n ORDER BY created_at DESC LIMIT 3`,\n )\n .all(sessionKey, `%${basename}%`, `%${filePath}%`) as {\n title: string;\n etype: string;\n anti: string;\n fix: string;\n resolved: string;\n created_at: string;\n }[];\n predDb.close();\n\n if (fileErrors.length > 0) {\n const lines: string[] = [\n `[remem-mcp] File has error history — ${fileErrors.length} past error(s) on this file:`,\n ];\n for (const e of fileErrors) {\n const date = new Date(e.created_at).toISOString().split(\"T\")[0];\n const title = (e.title ?? \"Untitled\").slice(0, 50);\n const resolved = e.resolved === \"true\" ? \" ✓resolved\" : \"\";\n lines.push(`- ${date} [${e.etype ?? \"unknown\"}]${resolved}: ${title}`);\n if (e.anti) lines.push(` Anti-pattern: ${e.anti.slice(0, 80)}`);\n if (e.fix) lines.push(` Correct approach: ${e.fix.slice(0, 80)}`);\n }\n lines.push(\"\");\n lines.push(\"Avoid repeating these errors when editing this file.\");\n\n const output = {\n hookSpecificOutput: {\n hookEventName: \"PreToolUse\",\n additionalContext: lines.join(\"\\n\"),\n },\n };\n logToFile(\n `PreToolUse: PREDICTIVE — ${fileErrors.length} error(s) on file ${basename}, injected warning before edit`,\n );\n process.stdout.write(JSON.stringify(output));\n return;\n }\n } catch {\n // Non-fatal — prediction is supplementary\n }\n }\n\n // [Moat 3: Pattern Learning] Inject relevant code patterns before editing.\n // When editing a file, find patterns from the same project with same language.\n if (filePath) {\n try {\n const cwd = input.cwd ?? toolInput.workdir ?? process.cwd();\n const sessionKey = hashPath(cwd);\n const ext = filePath.split(\".\").pop()?.toLowerCase() ?? \"\";\n const langMap: Record<string, string> = {\n ts: \"typescript\",\n tsx: \"typescript\",\n js: \"javascript\",\n jsx: \"javascript\",\n py: \"python\",\n rs: \"rust\",\n go: \"go\",\n java: \"java\",\n rb: \"ruby\",\n };\n const language = langMap[ext] ?? \"\";\n if (language) {\n const patDb = new Database(dbPath, { readonly: true });\n const patterns = patDb\n .prepare(\n `SELECT\n json_extract(metadata, '$.title') as title,\n json_extract(metadata, '$.pattern_type') as ptype,\n json_extract(metadata, '$.signature') as sig,\n json_extract(metadata, '$.file_path') as fpath,\n json_extract(metadata, '$.seen_count') as seen,\n json_extract(metadata, '$.confidence') as conf\n FROM captures\n WHERE type = 'pattern' AND deleted_at IS NULL\n AND session_key = ?\n AND json_extract(metadata, '$.language') = ?\n AND json_extract(metadata, '$.file_path') != ?\n ORDER BY CAST(json_extract(metadata, '$.confidence') AS INTEGER) DESC\n LIMIT 3`,\n )\n .all(sessionKey, language, filePath) as {\n title: string;\n ptype: string;\n sig: string;\n fpath: string;\n seen: number;\n conf: number;\n }[];\n\n // [Moat 3: Cross-Project Pattern Inheritance] If no local patterns,\n // check OTHER projects for same language patterns.\n if (patterns.length === 0) {\n const inherited = patDb\n .prepare(\n `SELECT\n json_extract(metadata, '$.title') as title,\n json_extract(metadata, '$.pattern_type') as ptype,\n json_extract(metadata, '$.signature') as sig,\n json_extract(metadata, '$.file_path') as fpath,\n json_extract(metadata, '$.seen_count') as seen,\n json_extract(metadata, '$.confidence') as conf,\n session_key\n FROM captures\n WHERE type = 'pattern' AND deleted_at IS NULL\n AND session_key != ?\n AND json_extract(metadata, '$.language') = ?\n ORDER BY CAST(json_extract(metadata, '$.confidence') AS INTEGER) DESC\n LIMIT 2`,\n )\n .all(sessionKey, language) as {\n title: string;\n ptype: string;\n sig: string;\n fpath: string;\n seen: number;\n conf: number;\n session_key: string;\n }[];\n\n for (const p of inherited) {\n (patterns as any[]).push({ ...p });\n }\n }\n patDb.close();\n\n if (patterns.length > 0) {\n const lines: string[] = [\n `[remem-mcp] ${patterns.length} code pattern(s) from this project (same language):`,\n ];\n for (const p of patterns) {\n lines.push(`- [${p.ptype}] ${p.title}`);\n if (p.sig) lines.push(` signature: ${p.sig.slice(0, 60)}`);\n if (p.fpath) lines.push(` from: ${p.fpath}`);\n }\n lines.push(\"\");\n lines.push(\"Follow these patterns for consistency.\");\n\n // [Moat 3: Pattern Drift] Log injection for drift tracking\n for (const p of patterns) {\n const patId = `pat-${createHash(\"sha256\")\n .update((p.sig ?? p.title) + (p.fpath ?? \"\"))\n .digest(\"hex\")\n .slice(0, 12)}`;\n logInjectionDrift(sessionKey, \"pattern\", patId, `edit ${filePath}`);\n }\n\n const output = {\n hookSpecificOutput: {\n hookEventName: \"PreToolUse\",\n additionalContext: lines.join(\"\\n\"),\n },\n };\n logToFile(\n `PreToolUse: PATTERN — ${patterns.length} pattern(s) injected before editing ${filePath}`,\n );\n process.stdout.write(JSON.stringify(output));\n return;\n }\n }\n } catch {\n // Non-fatal\n }\n }\n\n // For Write/Edit without patterns or predictive errors, just return\n process.stdout.write(JSON.stringify({}));\n return;\n }\n\n // Only inject for lint/build/test/typecheck commands\n const isRelevantCommand =\n /^(npm|npx|yarn|pnpm|biome|eslint|tsc|cargo|make|pytest|vitest|jest)\\b/.test(command) ||\n /\\b(lint|test|build|typecheck|check|format)\\b/.test(command);\n\n if (!isRelevantCommand) {\n process.stdout.write(JSON.stringify({}));\n return;\n }\n\n const cwd = input.cwd ?? toolInput.workdir ?? process.cwd();\n const sessionKey = hashPath(cwd);\n\n let db: Database.Database;\n try {\n db = new Database(dbPath, { readonly: true });\n } catch {\n process.stdout.write(JSON.stringify({}));\n return;\n }\n\n // [Feature 2] k=1-2 optimal retrieval (ReasoningBank finding)\n // [Feature 5] Global error injection — query all projects when TDAI_GLOBAL_ERRORS=1\n const globalErrors = process.env.TDAI_GLOBAL_ERRORS === \"1\";\n const sessionFilter = globalErrors ? \"\" : `AND session_key = ?`;\n const params = globalErrors ? [] : [sessionKey];\n\n const errors = db\n .prepare(\n `SELECT id, content, content_hash, tags, created_at, metadata, session_key FROM captures\n WHERE type = 'error' ${sessionFilter}\n AND deleted_at IS NULL\n AND created_at > datetime('now', '-30 days')\n AND json_extract(metadata, '$.resolved') IS NOT true\n ORDER BY\n CASE json_extract(metadata, '$.severity')\n WHEN 'blocker' THEN 0\n WHEN 'critical' THEN 1\n WHEN 'major' THEN 2\n WHEN 'minor' THEN 3\n ELSE 2\n END,\n CAST(json_extract(metadata, '$.confidence') AS INTEGER) DESC,\n created_at DESC LIMIT 5`,\n )\n .all(...params) as {\n id: string;\n content: string;\n content_hash: string | null;\n tags: string | null;\n created_at: string;\n metadata: string;\n session_key: string;\n }[];\n\n db.close();\n\n // [Feature 9] Error-to-fix linking — fetch RESOLVED errors with fixes\n // This runs BEFORE the unresolved errors check so proven fixes are\n // injected even when there are no unresolved errors to warn about.\n // [P0: Harm gate] Skip fixes with fix_harm_count > 0 (caused regression)\n // [P0: A/B validation] Skip unvalidated fixes (stdout had error indicators)\n let resolvedFixes: {\n title: string;\n fix: string;\n date: string;\n resolvedAt: string;\n provenance: string;\n inherited: boolean;\n rollbackPlan: string | null;\n autoNotes: string[];\n }[] = [];\n try {\n const rDb = new Database(dbPath, { readonly: true });\n const resolved = rDb\n .prepare(\n `SELECT content, metadata, created_at, session_key FROM captures\n WHERE type = 'error' ${sessionFilter}\n AND deleted_at IS NULL\n AND json_extract(metadata, '$.resolved') = 1\n AND json_extract(metadata, '$.fix_applied') IS NOT NULL\n AND (json_extract(metadata, '$.fix_harm_count') IS NULL\n OR CAST(json_extract(metadata, '$.fix_harm_count') AS INTEGER) = 0)\n AND (json_extract(metadata, '$.fix_validated') IS NULL\n OR json_extract(metadata, '$.fix_validated') = 1)\n ORDER BY created_at DESC LIMIT 2`,\n )\n .all(...params) as {\n content: string;\n metadata: string;\n created_at: string;\n session_key: string;\n }[];\n\n resolvedFixes = resolved.map((r) => {\n const m = JSON.parse(r.metadata);\n return {\n title: m.title ?? \"Untitled\",\n fix: m.fix_applied ?? m.correct_approach ?? \"\",\n date: new Date(r.created_at).toISOString().split(\"T\")[0],\n resolvedAt: m.resolved_at ?? r.created_at,\n provenance: m.fix_provenance ?? \"auto_captured\",\n inherited: r.session_key !== sessionKey,\n rollbackPlan: m.rollback_plan ?? null,\n autoNotes: m.auto_notes ?? [],\n };\n });\n\n // [Cross-Project Fix Inheritance] If we haven't filled 2 fix slots from\n // the current project, check OTHER projects for validated fixes matching\n // the same error type. Auto-inherit without user action.\n if (resolvedFixes.length < 2) {\n const inherited = rDb\n .prepare(\n `SELECT content, metadata, created_at, session_key FROM captures\n WHERE type = 'error' AND session_key != ?\n AND deleted_at IS NULL\n AND json_extract(metadata, '$.resolved') = 1\n AND json_extract(metadata, '$.fix_applied') IS NOT NULL\n AND (json_extract(metadata, '$.fix_harm_count') IS NULL\n OR CAST(json_extract(metadata, '$.fix_harm_count') AS INTEGER) = 0)\n AND (json_extract(metadata, '$.fix_validated') IS NULL\n OR json_extract(metadata, '$.fix_validated') = 1)\n ORDER BY created_at DESC LIMIT ?`,\n )\n .all(sessionKey, 2 - resolvedFixes.length) as {\n content: string;\n metadata: string;\n created_at: string;\n session_key: string;\n }[];\n\n for (const r of inherited) {\n const m = JSON.parse(r.metadata);\n resolvedFixes.push({\n title: m.title ?? \"Untitled\",\n fix: m.fix_applied ?? m.correct_approach ?? \"\",\n date: new Date(r.created_at).toISOString().split(\"T\")[0],\n resolvedAt: m.resolved_at ?? r.created_at,\n provenance: \"inherited\",\n inherited: true,\n rollbackPlan: m.rollback_plan ?? null,\n autoNotes: m.auto_notes ?? [],\n });\n }\n }\n rDb.close();\n } catch {\n // non-fatal — fixes are bonus context\n }\n\n if (errors.length === 0 && resolvedFixes.length === 0) {\n // [Moat 2: Decision Learning] Even with no errors, inject past decisions\n // for relevant commands (npm install, git commit, etc.)\n try {\n const decDb = new Database(dbPath, { readonly: true });\n const lowerCmd = command.toLowerCase();\n let decQuery = \"\";\n const decParams: (string | number)[] = [sessionKey];\n\n if (\n lowerCmd.includes(\"npm install\") ||\n lowerCmd.includes(\"pip install\") ||\n lowerCmd.includes(\"cargo add\")\n ) {\n decQuery = `SELECT json_extract(metadata, '$.title') as title,\n json_extract(metadata, '$.choice') as choice,\n json_extract(metadata, '$.rationale') as rationale,\n created_at\n FROM captures\n WHERE type = 'decision' AND deleted_at IS NULL\n AND session_key = ?\n AND json_extract(metadata, '$.decision_type') = 'dependency'\n AND created_at > datetime('now', '-90 days')\n ORDER BY CAST(json_extract(metadata, '$.confidence') AS INTEGER) DESC LIMIT 3`;\n } else if (lowerCmd.includes(\"git commit\")) {\n decQuery = `SELECT json_extract(metadata, '$.title') as title,\n json_extract(metadata, '$.choice') as choice,\n json_extract(metadata, '$.rationale') as rationale,\n created_at\n FROM captures\n WHERE type = 'decision' AND deleted_at IS NULL\n AND session_key = ?\n AND json_extract(metadata, '$.decision_type') = 'commit'\n AND created_at > datetime('now', '-90 days')\n ORDER BY created_at DESC LIMIT 3`;\n }\n\n if (decQuery) {\n const decisions = decDb.prepare(decQuery).all(...decParams) as {\n title: string;\n choice: string;\n rationale: string;\n created_at: string;\n }[];\n\n // [Moat 2: Cross-Project Decision Inheritance] If no local decisions,\n // check OTHER projects for same decision type.\n if (decisions.length === 0) {\n const inheritedDecisions = decDb\n .prepare(\n `SELECT json_extract(metadata, '$.title') as title,\n json_extract(metadata, '$.choice') as choice,\n json_extract(metadata, '$.rationale') as rationale,\n created_at, session_key\n FROM captures\n WHERE type = 'decision' AND deleted_at IS NULL\n AND session_key != ?\n AND json_extract(metadata, '$.decision_type') = ?\n AND created_at > datetime('now', '-90 days')\n ORDER BY CAST(json_extract(metadata, '$.confidence') AS INTEGER) DESC LIMIT 2`,\n )\n .all(\n sessionKey,\n lowerCmd.includes(\"npm install\") ||\n lowerCmd.includes(\"pip install\") ||\n lowerCmd.includes(\"cargo add\")\n ? \"dependency\"\n : \"commit\",\n ) as {\n title: string;\n choice: string;\n rationale: string;\n created_at: string;\n session_key: string;\n }[];\n\n for (const d of inheritedDecisions) {\n (decisions as any[]).push({ ...d });\n }\n }\n\n if (decisions.length > 0) {\n const lines: string[] = [`[remem-mcp] Past decisions for similar commands:`];\n for (const d of decisions) {\n const date = new Date(d.created_at).toISOString().split(\"T\")[0];\n lines.push(`- ${date}: ${d.title}`);\n if (d.rationale) lines.push(` rationale: ${d.rationale.slice(0, 60)}`);\n }\n lines.push(\"\");\n lines.push(\"Consider these past decisions before proceeding.\");\n\n // [Moat 2: Decision Drift] Log injection for drift tracking\n for (const d of decisions) {\n logInjectionDrift(\n sessionKey,\n \"decision\",\n `dec-${createHash(\"sha256\")\n .update(d.choice + sessionKey)\n .digest(\"hex\")\n .slice(0, 12)}`,\n command,\n );\n }\n\n const output = {\n hookSpecificOutput: {\n hookEventName: \"PreToolUse\",\n additionalContext: lines.join(\"\\n\"),\n },\n };\n decDb.close();\n logToFile(\n `PreToolUse: DECISION — ${decisions.length} decision(s) injected (no errors)`,\n );\n process.stdout.write(JSON.stringify(output));\n return;\n }\n }\n decDb.close();\n } catch {\n // non-fatal\n }\n process.stdout.write(JSON.stringify({}));\n return;\n }\n\n // [Feature 6] Stale detection: check if file paths in error still exist\n const validErrors = errors.filter((err) => {\n const meta = JSON.parse(err.metadata);\n const filesInError = extractFilePaths(err.content);\n if (filesInError.length === 0) return true; // No file refs = still valid\n // Valid if at least one referenced file still exists\n return filesInError.some((f) => existsSync(join(cwd, f)));\n });\n\n if (validErrors.length === 0 && resolvedFixes.length === 0) {\n logToFile(\"PreToolUse: all past errors are stale and no proven fixes\");\n process.stdout.write(JSON.stringify({}));\n return;\n }\n\n // [Feature 8] Apply confidence decay at read time (Ebbinghaus curve)\n // Re-rank by decayed confidence, then take top 2 (k=2 optimal per ReasoningBank)\n const decayed = validErrors\n .map((err) => {\n const meta = JSON.parse(err.metadata);\n const base = meta.confidence ?? 2;\n const decayed = applyConfidenceDecay(base, err.created_at, meta.last_recurred);\n return { err, meta, decayedConfidence: decayed };\n })\n .sort((a, b) => b.decayedConfidence - a.decayedConfidence)\n .slice(0, 2);\n\n // Build structured warning context (ReasoningBank format)\n const lines: string[] = [`[remem-mcp] Past error to avoid repeating:`];\n for (const { err, meta, decayedConfidence } of decayed) {\n const date = new Date(err.created_at).toISOString().split(\"T\")[0];\n const title = meta.title ?? \"Untitled error\";\n const antiPattern = meta.anti_pattern ?? \"\";\n const correctApproach = meta.correct_approach ?? \"\";\n const isOtherProject = err.session_key !== sessionKey;\n const escalationLevel = meta.escalation_level ?? 0;\n\n // [Error Escalation Policy] Stronger warning for escalated errors\n const escalationTag =\n escalationLevel >= 3\n ? \" [BLOCKER — recurred 7+ times. Do NOT retry without a fundamentally different approach.]\"\n : escalationLevel >= 2\n ? \" [CRITICAL — recurred 5+ times. Previous fixes failed. Try a different approach.]\"\n : escalationLevel >= 1\n ? \" [ELEVATED — recurred 3+ times. Review previous fix attempts.]\"\n : \"\";\n\n lines.push(\n `- ${date} [confidence=${decayedConfidence.toFixed(1)}]: ${title}${escalationTag}`,\n );\n if (isOtherProject) lines.push(` (from another project — cross-project pattern)`);\n if (antiPattern) lines.push(` Anti-pattern: ${antiPattern}`);\n // [P3: Root Cause Analysis] Show root cause if available (Experia pattern)\n if (meta.root_cause) lines.push(` Root cause: ${meta.root_cause}`);\n if (correctApproach) lines.push(` Fix: ${correctApproach}`);\n if (meta.resolved) lines.push(` (Previously resolved — may recur)`);\n // [Error Context Enrichment] Show git context if available\n if (meta.context_enrichment) {\n const ctx = meta.context_enrichment;\n if (ctx.branch) lines.push(` Context: branch=${ctx.branch}`);\n if (ctx.recent_commits?.[0]) lines.push(` Last commit: ${ctx.recent_commits[0]}`);\n }\n // [Auto-Annotation] Show system-generated notes\n if (meta.auto_notes && Array.isArray(meta.auto_notes)) {\n for (const note of meta.auto_notes.slice(0, 3)) {\n lines.push(` Note: ${note}`);\n }\n }\n }\n\n // [Feature 9] Inject proven fixes from resolved errors\n // [Fix Decay / Staleness] Warn when injecting fixes older than threshold\n // [Cross-Project Fix Inheritance] Show inherited tag for fixes from other projects\n // [Fix Provenance Chain] Show provenance tag\n // [Fix Rollback Plan] Show rollback plan if available\n if (resolvedFixes.length > 0) {\n lines.push(\"\");\n lines.push(\"Proven fixes from past resolved errors:\");\n const stalenessDays = Number(process.env.TDAI_FIX_STALENESS_DAYS ?? 180);\n const stalenessMs = stalenessDays * 86400000;\n for (const fix of resolvedFixes) {\n const fixAgeMs = Date.now() - new Date(fix.resolvedAt).getTime();\n const isStale = fixAgeMs > stalenessMs;\n const staleTag = isStale ? \" [STALE — verify before applying]\" : \"\";\n const inheritedTag = fix.inherited ? \" [inherited from another project]\" : \"\";\n const provenanceTag = fix.provenance !== \"auto_captured\" ? ` [${fix.provenance}]` : \"\";\n lines.push(\n `- ${fix.date}: ${fix.title} → ${fix.fix}${staleTag}${inheritedTag}${provenanceTag}`,\n );\n // [Fix Rollback Plan] Show rollback plan\n if (fix.rollbackPlan) {\n lines.push(` Rollback: ${fix.rollbackPlan}`);\n }\n // [Auto-Annotation] Show notes for this fix\n if (fix.autoNotes && fix.autoNotes.length > 0) {\n for (const note of fix.autoNotes.slice(0, 2)) {\n lines.push(` Note: ${note}`);\n }\n }\n }\n }\n\n lines.push(\"\");\n lines.push(\"Fix these issues BEFORE running the command.\");\n\n // [Moat 2: Decision Learning] Inject past decisions before relevant commands.\n // E.g., before `npm install`, inject past dependency decisions.\n try {\n const decDb = new Database(dbPath, { readonly: true });\n const lowerCmd = command.toLowerCase();\n let decQuery = \"\";\n const decParams: (string | number)[] = [sessionKey];\n\n if (\n lowerCmd.includes(\"npm install\") ||\n lowerCmd.includes(\"pip install\") ||\n lowerCmd.includes(\"cargo add\")\n ) {\n // Inject dependency decisions\n decQuery = `SELECT json_extract(metadata, '$.title') as title,\n json_extract(metadata, '$.choice') as choice,\n json_extract(metadata, '$.rationale') as rationale,\n json_extract(metadata, '$.seen_count') as seen,\n created_at\n FROM captures\n WHERE type = 'decision' AND deleted_at IS NULL\n AND session_key = ?\n AND json_extract(metadata, '$.decision_type') = 'dependency'\n AND created_at > datetime('now', '-90 days')\n ORDER BY CAST(json_extract(metadata, '$.confidence') AS INTEGER) DESC LIMIT 3`;\n } else if (lowerCmd.includes(\"git commit\")) {\n // Inject commit-encoded decisions\n decQuery = `SELECT json_extract(metadata, '$.title') as title,\n json_extract(metadata, '$.choice') as choice,\n json_extract(metadata, '$.rationale') as rationale,\n json_extract(metadata, '$.seen_count') as seen,\n created_at\n FROM captures\n WHERE type = 'decision' AND deleted_at IS NULL\n AND session_key = ?\n AND json_extract(metadata, '$.decision_type') = 'commit'\n AND created_at > datetime('now', '-90 days')\n ORDER BY created_at DESC LIMIT 3`;\n }\n\n if (decQuery) {\n const decisions = decDb.prepare(decQuery).all(...decParams) as {\n title: string;\n choice: string;\n rationale: string;\n seen: number;\n created_at: string;\n }[];\n\n // [Moat 2: Cross-Project Decision Inheritance] If no local decisions,\n // check OTHER projects for same decision type.\n if (decisions.length === 0) {\n const inherited = decDb\n .prepare(\n `SELECT json_extract(metadata, '$.title') as title,\n json_extract(metadata, '$.choice') as choice,\n json_extract(metadata, '$.rationale') as rationale,\n json_extract(metadata, '$.seen_count') as seen,\n created_at, session_key\n FROM captures\n WHERE type = 'decision' AND deleted_at IS NULL\n AND session_key != ?\n AND json_extract(metadata, '$.decision_type') = ?\n AND created_at > datetime('now', '-90 days')\n ORDER BY CAST(json_extract(metadata, '$.confidence') AS INTEGER) DESC LIMIT 2`,\n )\n .all(\n sessionKey,\n lowerCmd.includes(\"npm install\") ||\n lowerCmd.includes(\"pip install\") ||\n lowerCmd.includes(\"cargo add\")\n ? \"dependency\"\n : \"commit\",\n ) as {\n title: string;\n choice: string;\n rationale: string;\n seen: number;\n created_at: string;\n session_key: string;\n }[];\n\n for (const d of inherited) {\n (decisions as any[]).push({ ...d });\n }\n }\n\n decDb.close();\n\n if (decisions.length > 0) {\n lines.push(\"\");\n lines.push(\"Past decisions for similar commands:\");\n for (const d of decisions) {\n const date = new Date(d.created_at).toISOString().split(\"T\")[0];\n lines.push(`- ${date}: ${d.title}`);\n if (d.rationale) lines.push(` rationale: ${d.rationale.slice(0, 60)}`);\n }\n\n // [Moat 2: Decision Drift] Log injection for drift tracking\n for (const d of decisions) {\n logInjectionDrift(\n sessionKey,\n \"decision\",\n `dec-${createHash(\"sha256\")\n .update(d.choice + sessionKey)\n .digest(\"hex\")\n .slice(0, 12)}`,\n command,\n );\n }\n }\n }\n } catch {\n // non-fatal\n }\n\n const context = lines.join(\"\\n\");\n const k = decayed.length;\n logToFile(\n `PreToolUse: injected ${k} past error(s) (k=${k}, decayed confidence, ${resolvedFixes.length} fixes) before: ${command.slice(0, 60)}`,\n );\n\n // Visible feedback\n const fixCount = resolvedFixes.length;\n feedback(\n \"🛡️\",\n `remem-mcp: injected ${k} past error(s)${fixCount > 0 ? ` + ${fixCount} proven fix(es)` : \"\"} before: ${command.slice(0, 50)}`,\n );\n\n // [Drift Detection] Log each injected error so PostToolUse can detect\n // if the agent ignored the warning and hit the same error again.\n for (const { err } of decayed) {\n if (err.content_hash) {\n logDriftInjection(sessionKey, err.content_hash, err.id, command);\n }\n }\n\n const output = {\n hookSpecificOutput: {\n hookEventName: \"PreToolUse\",\n additionalContext: context,\n },\n };\n\n process.stdout.write(JSON.stringify(output));\n } catch (err) {\n process.stderr.write(`[remem-mcp hook-pre-tool-use] Error: ${err}\\n`);\n logToFile(`PreToolUse: error - ${err}`);\n process.stdout.write(JSON.stringify({}));\n }\n });\n}\n\n/**\n * Noise filter: detect commands that are not worth capturing as errors.\n * These are typically test commands, intentional failures, or one-off probes.\n */\nfunction isNoiseCommand(command: string): boolean {\n const lower = command.toLowerCase().trim();\n // Nonexistent/test file paths\n if (/\\/nonexistent|\\/tmp\\/test|\\/test\\/fake|example\\.ts|foo\\.ts|bar\\.ts/.test(lower)) return true;\n // Explicit test markers in the command itself\n if (/^echo\\s+/.test(lower)) return true;\n // Very short commands that are just probes (ls <fake>, cat <fake>)\n if (/^ls\\s+\\/[a-z_]+$/.test(lower) && lower.length < 30) return true;\n return false;\n}\n\n/**\n * [Pre-action matchers] Check if a command is dangerous and return a warning.\n * (AgentRecall pattern: check_action before publish/push/deploy/DROP TABLE)\n * Returns a warning string if the command is dangerous, or null if safe.\n */\nfunction checkDangerousCommand(command: string): string | null {\n const lower = command.toLowerCase();\n\n // git push --force / git push -f (without branch = force push ALL branches)\n if (/git\\s+push\\s+(--force|-f|--force-with-lease)/.test(lower)) {\n const hasBranch = /git\\s+push\\s+\\S+\\s+\\S+/.test(command);\n return hasBranch\n ? `[remem-mcp] ⚠ DANGER: git push --force detected.\\n` +\n `This rewrites remote history and can destroy others' commits.\\n` +\n `Only do this on your own branch. Use --force-with-lease for safer force push.`\n : `[remem-mcp] ⚠ DANGER: git push --force WITHOUT a branch name.\\n` +\n `This force-pushes ALL branches. This is almost certainly a mistake.\\n` +\n `Specify the branch: git push --force origin <branch>`;\n }\n\n // rm -rf with broad paths\n if (/rm\\s+(-[a-z]*r[a-z]*f?|-[a-z]*f[a-z]*r?)\\s+/.test(lower)) {\n const target = lower.replace(/.*rm\\s+-[a-z]*\\s+/, \"\").trim();\n // Dangerous targets: /, /*, ~, *, ., .., /home, /usr, /var, /etc\n const dangerousTargets = /^(\\/|~|\\*|\\.\\.?$|\\/home|\\/usr|\\/var|\\/etc|\\/bin|\\/sbin|\\/boot)/;\n if (dangerousTargets.test(target)) {\n return (\n `[remem-mcp] ⚠ DANGER: rm -rf on a critical path: ${target.slice(0, 60)}\\n` +\n `This can destroy the filesystem, home directory, or system files.\\n` +\n `Verify the path is correct before proceeding.`\n );\n }\n }\n\n // DROP TABLE / DROP DATABASE / TRUNCATE (SQL)\n if (/\\b(drop\\s+(table|database|schema)|truncate\\s+table)\\b/i.test(command)) {\n const match = command.match(\n /\\b(drop\\s+(?:table|database|schema)\\s+\\S+|truncate\\s+table\\s+\\S+)/i,\n );\n const target = match ? match[1] : \"unknown\";\n return (\n `[remem-mcp] ⚠ DANGER: SQL destructive operation detected: ${target.slice(0, 60)}\\n` +\n `This permanently deletes data. Ensure you have a backup and are in the right environment.`\n );\n }\n\n // DELETE FROM without WHERE clause\n if (\n /\\bdelete\\s+from\\s+\\S+\\s*;?\\s*$/i.test(command) ||\n /\\bdelete\\s+from\\s+\\S+\\s*$/i.test(command)\n ) {\n return (\n `[remem-mcp] ⚠ DANGER: DELETE FROM without a WHERE clause.\\n` +\n `This deletes ALL rows in the table. Add a WHERE clause to limit the deletion.`\n );\n }\n\n // npm publish (production publish)\n if (/^npm\\s+publish\\b/.test(lower)) {\n return (\n `[remem-mcp] ⚠ CAUTION: npm publish detected.\\n` +\n `This publishes a package to the npm registry. Verify:\\n` +\n ` - The version number is correct (check package.json)\\n` +\n ` - You are publishing the right package\\n` +\n ` - The package is not already published at this version`\n );\n }\n\n // docker system prune / docker volume rm\n if (/docker\\s+(system\\s+prune|volume\\s+rm|container\\s+rm\\s+-f|image\\s+rm\\s+-f)/.test(lower)) {\n return (\n `[remem-mcp] ⚠ DANGER: Docker destructive command detected.\\n` +\n `This can remove containers, volumes, or images that are in use.\\n` +\n `Verify you are not deleting production resources.`\n );\n }\n\n // kubectl delete namespace / kubectl delete -f (production)\n if (/kubectl\\s+delete\\s+(namespace|ns)\\b/.test(lower)) {\n return (\n `[remem-mcp] ⚠ DANGER: kubectl delete namespace detected.\\n` +\n `This deletes ALL resources in the namespace (pods, services, configs).\\n` +\n `Verify this is not a production namespace.`\n );\n }\n\n return null;\n}\n\n/**\n * [Error Context Enrichment] Capture git context at error time.\n * Records branch, recent commits, and changed files to help diagnose\n * WHY an error occurred (regression? branch-specific? recent commit?).\n * All automatic — no user action needed.\n */\nfunction captureGitContext(cwd: string): {\n branch: string;\n recent_commits: string[];\n changed_files: string[];\n} | null {\n try {\n const branch = execSync(\"git branch --show-current\", {\n cwd,\n timeout: 2000,\n encoding: \"utf8\",\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n }).trim();\n\n const commits = execSync(\"git log -3 --oneline\", {\n cwd,\n timeout: 2000,\n encoding: \"utf8\",\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n })\n .trim()\n .split(\"\\n\")\n .filter(Boolean);\n\n const changed = execSync(\"git diff --name-only HEAD~1\", {\n cwd,\n timeout: 2000,\n encoding: \"utf8\",\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n })\n .trim()\n .split(\"\\n\")\n .filter(Boolean)\n .slice(0, 10);\n\n return { branch, recent_commits: commits, changed_files: changed };\n } catch {\n return null; // Not a git repo or git not available — non-fatal\n }\n}\n\n/**\n * [Fix Rollback Plan] Auto-generate a rollback plan when a fix is recorded.\n * Uses simple heuristics based on the fix text and command.\n * All automatic — no user action needed.\n */\nfunction generateRollbackPlan(command: string, fixApplied: string): string | null {\n const lowerFix = (fixApplied || \"\").toLowerCase();\n const lowerCmd = (command || \"\").toLowerCase();\n\n // If fix involves file edit\n if (lowerFix.includes(\"import\") || lowerFix.includes(\"added\") || lowerFix.includes(\"modified\")) {\n return \"git checkout <file> to revert the edit, then re-run the command\";\n }\n // If fix involves config change\n if (lowerFix.includes(\"config\") || lowerFix.includes(\".env\") || lowerFix.includes(\"setting\")) {\n return \"git revert <commit> to undo the config change\";\n }\n // If fix involves dependency\n if (\n lowerFix.includes(\"install\") ||\n lowerFix.includes(\"package\") ||\n lowerCmd.includes(\"npm install\")\n ) {\n return \"git checkout package.json package-lock.json && npm install to revert dependency change\";\n }\n // If fix involves migration\n if (lowerFix.includes(\"migration\") || lowerFix.includes(\"migrate\")) {\n return \"Run the down migration or git revert <commit> to undo schema change\";\n }\n // Default\n return null;\n}\n\n/**\n * [Auto-Annotation] Generate system notes based on error state.\n * All automatic — no user action needed. Notes are derived from:\n * recurrence count, severity, escalation level, correlations, context.\n */\nfunction generateAutoNotes(meta: {\n attempt_count?: number;\n severity?: string;\n escalation_level?: number;\n error_type?: string;\n resolved?: boolean;\n fix_validated?: boolean;\n drift_count?: number;\n}): string[] {\n const notes: string[] = [];\n\n if ((meta.attempt_count ?? 0) >= 5) {\n notes.push(\n `Stubborn error: ${meta.attempt_count} attempts — needs fundamentally different approach`,\n );\n } else if ((meta.attempt_count ?? 0) >= 3) {\n notes.push(\n `Recurring error: ${meta.attempt_count} attempts — previous fixes may be insufficient`,\n );\n }\n\n if (meta.severity === \"blocker\") {\n notes.push(\"Blocker severity — this error blocks all work\");\n } else if (meta.severity === \"critical\") {\n notes.push(\"Critical severity — config/security/data involved\");\n }\n\n if ((meta.escalation_level ?? 0) >= 2) {\n notes.push(\n `Escalated to level ${meta.escalation_level} — auto-bumped severity due to recurrence`,\n );\n }\n\n if (meta.resolved && meta.fix_validated) {\n notes.push(\"Fix validated — proven to work with clean stdout\");\n } else if (meta.resolved && !meta.fix_validated) {\n notes.push(\"Fix applied but NOT validated — stdout contained error indicators\");\n }\n\n if ((meta.drift_count ?? 0) >= 2) {\n notes.push(`Drift detected: agent ignored warning ${meta.drift_count} times`);\n }\n\n return notes;\n}\n\n/**\n * [Moat 2: Decision Learning] Detect decisions from successful commands.\n * Captures dependency choices, config decisions, and commit-encoded decisions.\n * All automatic — no user action needed.\n */\nfunction detectDecision(\n command: string,\n stdout: string,\n): { title: string; decision_type: string; choice: string; rationale: string } | null {\n const lower = command.toLowerCase();\n\n // Dependency install decisions\n const npmMatch = command.match(/npm\\s+install\\s+(?:-S\\s+|--save\\s+)?(@?[a-z0-9][\\w@./-]*)/i);\n if (npmMatch) {\n const pkg = npmMatch[1];\n return {\n title: `Chose to use ${pkg}`,\n decision_type: \"dependency\",\n choice: pkg,\n rationale: `Installed ${pkg} as a dependency`,\n };\n }\n\n const pipMatch = command.match(/pip\\s+install\\s+([a-z0-9][\\w.-]*)/i);\n if (pipMatch) {\n const pkg = pipMatch[1];\n return {\n title: `Chose to use ${pkg}`,\n decision_type: \"dependency\",\n choice: pkg,\n rationale: `Installed ${pkg} via pip`,\n };\n }\n\n const cargoMatch = command.match(/cargo\\s+add\\s+([a-z0-9][\\w-]*)/i);\n if (cargoMatch) {\n const pkg = cargoMatch[1];\n return {\n title: `Chose to use ${pkg}`,\n decision_type: \"dependency\",\n choice: pkg,\n rationale: `Added ${pkg} to Cargo.toml`,\n };\n }\n\n // Git commit decisions (extract from commit message)\n const commitMatch = command.match(/git\\s+commit\\s+.*-m\\s+[\"'](.+?)[\"']/i);\n if (commitMatch) {\n const msg = commitMatch[1].slice(0, 100);\n // Only capture if message looks like a decision\n if (/chose|selected|decided|switched|replaced|migrated|refactored|adopted/i.test(msg)) {\n return {\n title: `Decision: ${msg.slice(0, 60)}`,\n decision_type: \"commit\",\n choice: msg,\n rationale: \"Encoded in git commit\",\n };\n }\n }\n\n // Config file creation (implies architecture decision)\n if (\n /touch\\s+.*\\.(env|config|yaml|yml|toml|ini)$/i.test(command) ||\n /echo.*>.*\\.(env|config|yaml|yml|toml)$/i.test(command)\n ) {\n const fileMatch = command.match(/([\\w.-]+\\.(?:env|config|yaml|yml|toml|ini))/i);\n if (fileMatch) {\n return {\n title: `Created config: ${fileMatch[1]}`,\n decision_type: \"config\",\n choice: fileMatch[1],\n rationale: \"Config file creation implies architecture decision\",\n };\n }\n }\n\n return null;\n}\n\n/**\n * [Moat 3: Pattern Learning] Detect code patterns from Write/Edit tools.\n * Captures function signatures, import structures, and component patterns.\n * All automatic — no user action needed.\n */\nfunction detectPattern(\n toolName: string,\n toolInput: { content?: string; old_string?: string; new_string?: string; file_path?: string },\n): {\n title: string;\n pattern_type: string;\n language: string;\n signature: string;\n file_path: string;\n} | null {\n const filePath = toolInput.file_path ?? \"\";\n const content = toolInput.content ?? toolInput.new_string ?? \"\";\n if (!content || !filePath) return null;\n\n // Detect language from file extension\n const ext = filePath.split(\".\").pop()?.toLowerCase() ?? \"\";\n const langMap: Record<string, string> = {\n ts: \"typescript\",\n tsx: \"typescript\",\n js: \"javascript\",\n jsx: \"javascript\",\n py: \"python\",\n rs: \"rust\",\n go: \"go\",\n java: \"java\",\n rb: \"ruby\",\n };\n const language = langMap[ext] ?? \"unknown\";\n if (language === \"unknown\") return null;\n\n // Extract function/method signatures\n const fnMatch = content.match(/(?:export\\s+)?(?:async\\s+)?function\\s+(\\w+)\\s*\\(([^)]*)\\)/);\n if (fnMatch) {\n return {\n title: `Function pattern: ${fnMatch[1]}(${fnMatch[2].slice(0, 40)})`,\n pattern_type: \"function\",\n language,\n signature: `${fnMatch[1]}(${fnMatch[2].slice(0, 60)})`,\n file_path: filePath,\n };\n }\n\n // Extract React component patterns\n const compMatch = content.match(\n /(?:export\\s+)?(?:const|function)\\s+(\\w+)\\s*[=:]\\s*(?:\\([^)]*\\)|function)\\s*=>?\\s*[{<]/,\n );\n if (compMatch && ext === \"tsx\") {\n return {\n title: `Component pattern: ${compMatch[1]}`,\n pattern_type: \"component\",\n language,\n signature: compMatch[1],\n file_path: filePath,\n };\n }\n\n // Extract class patterns\n const classMatch = content.match(/(?:export\\s+)?class\\s+(\\w+)/);\n if (classMatch) {\n return {\n title: `Class pattern: ${classMatch[1]}`,\n pattern_type: \"class\",\n language,\n signature: classMatch[1],\n file_path: filePath,\n };\n }\n\n // Extract import patterns (only if significant)\n const importMatches = content.match(/^import\\s+.*$/gm);\n if (importMatches && importMatches.length >= 3) {\n const imports = importMatches.slice(0, 5).join(\"; \").slice(0, 80);\n return {\n title: `Import pattern (${importMatches.length} imports)`,\n pattern_type: \"imports\",\n language,\n signature: imports,\n file_path: filePath,\n };\n }\n\n return null;\n}\n\n/**\n * [Feature 7] Cross-project error pattern detection.\n * Checks if the same error type + similar command root failed in other projects.\n * Returns an alert string if a pattern is found, or null if not.\n */\nfunction detectCrossProjectPattern(\n dbPath: string,\n currentSessionKey: string,\n errorType: string,\n command: string,\n): string | null {\n try {\n const db = new Database(dbPath, { readonly: true });\n // Extract command root (e.g. \"npm run build\" → \"npm build\", \"npx tsc\" → \"tsc\")\n const cmdRoot = extractCommandRoot(command);\n\n // Find same error_type in OTHER session keys (last 30 days)\n const others = db\n .prepare(\n `SELECT session_key, content, metadata, created_at FROM captures\n WHERE type = 'error' AND session_key != ?\n AND deleted_at IS NULL\n AND created_at > datetime('now', '-30 days')\n AND json_extract(metadata, '$.error_type') = ?\n ORDER BY created_at DESC LIMIT 10`,\n )\n .all(currentSessionKey, errorType) as {\n session_key: string;\n content: string;\n metadata: string;\n created_at: string;\n }[];\n\n db.close();\n\n if (others.length < 2) return null;\n\n // Check if any have a similar command root\n const matching = others.filter((o) => {\n try {\n const meta = JSON.parse(o.metadata);\n return extractCommandRoot(meta.command ?? \"\") === cmdRoot;\n } catch {\n return false;\n }\n });\n\n if (matching.length >= 2) {\n const projects = new Set(matching.map((m) => m.session_key.slice(0, 8)));\n return `This ${errorType} error on \"${cmdRoot}\" also occurred in ${matching.length} other session(s) across ${projects.size} project(s). This is a recurring pattern — check if there's a systemic cause.`;\n }\n\n // Same error type in 3+ different projects (even if different command)\n if (others.length >= 3) {\n const projects = new Set(others.map((o) => o.session_key.slice(0, 8)));\n if (projects.size >= 3) {\n return `${errorType} errors are appearing across ${projects.size} projects (${others.length} total). Consider reviewing common dependencies or shared configurations.`;\n }\n }\n\n return null;\n } catch {\n return null;\n }\n}\n\n/** Extract the command root for pattern matching (e.g. \"npm run build\" → \"npm build\"). */\nfunction extractCommandRoot(command: string): string {\n const parts = command.trim().split(/\\s+/);\n // Skip \"run\" and \"exec\" subcommands\n const filtered = parts.filter((p) => p !== \"run\" && p !== \"exec\" && p !== \"--\");\n return filtered.slice(0, 3).join(\" \").toLowerCase();\n}\n\n/**\n * [Feature 8] Error confidence decay (Ebbinghaus forgetting curve).\n * Errors that haven't recurred in a while should decay, making room for fresh ones.\n * Decay formula: confidence *= 0.95^(days_since_last_seen)\n * Applied at read time (PreToolUse) to avoid write overhead.\n */\nfunction applyConfidenceDecay(\n baseConfidence: number,\n createdAt: string,\n lastRecurred?: string,\n): number {\n const referenceDate = lastRecurred ? new Date(lastRecurred) : new Date(createdAt);\n const daysSince = (Date.now() - referenceDate.getTime()) / (1000 * 60 * 60 * 24);\n // Decay: 0.95^days. After 14 days → 0.49x. After 30 days → 0.21x.\n const decayFactor = 0.95 ** daysSince;\n return Math.round(baseConfidence * decayFactor * 100) / 100;\n}\n\n/** Classify error type from command and error output. */\nfunction classifyError(command: string, errorOutput: string): string {\n const lower = errorOutput.toLowerCase();\n if (lower.includes(\"lint\") || lower.includes(\"biome\") || lower.includes(\"eslint\")) return \"lint\";\n if (\n lower.includes(\"test\") ||\n lower.includes(\"vitest\") ||\n lower.includes(\"jest\") ||\n lower.includes(\"pytest\")\n )\n return \"test\";\n // Check for JS runtime errors first (TypeError, ReferenceError, etc.)\n // before typecheck to avoid misclassification\n if (\n lower.includes(\"typeerror\") ||\n lower.includes(\"referenceerror\") ||\n lower.includes(\"syntaxerror\") ||\n lower.includes(\"rangeerror\")\n )\n return \"runtime\";\n if (lower.includes(\"type\") && (lower.includes(\"error\") || lower.includes(\"tsc\")))\n return \"typecheck\";\n if (lower.includes(\"build\") || lower.includes(\"compile\") || lower.includes(\"webpack\"))\n return \"build\";\n if (lower.includes(\"module not found\") || lower.includes(\"cannot find\")) return \"import\";\n if (lower.includes(\"permission\") || lower.includes(\"eacces\")) return \"permission\";\n if (lower.includes(\"enoent\") || lower.includes(\"no such file\")) return \"file-not-found\";\n return \"runtime\";\n}\n\n/**\n * [Severity Classification] Classify error severity based on impact signals.\n * blocker: data destruction, security, agent cannot proceed (deploy/publish failures)\n * critical: core config files, env files, database operations\n * major: build/test/typecheck failures (blocks development)\n * minor: lint/format warnings (non-blocking)\n */\nfunction classifySeverity(command: string, errorType: string, errorOutput: string): string {\n const lowerCmd = command.toLowerCase();\n const lowerErr = errorOutput.toLowerCase();\n\n // Blocker: deploy/publish/release failures, data destruction\n if (\n lowerCmd.includes(\"deploy\") ||\n lowerCmd.includes(\"publish\") ||\n lowerCmd.includes(\"release\") ||\n lowerErr.includes(\"fatal\") ||\n lowerErr.includes(\"panic\") ||\n lowerErr.includes(\"segfault\") ||\n lowerErr.includes(\"out of memory\") ||\n lowerErr.includes(\"disk full\")\n ) {\n return \"blocker\";\n }\n\n // Critical: config/env/database/security errors\n if (\n lowerErr.includes(\".env\") ||\n lowerErr.includes(\"config\") ||\n lowerErr.includes(\"permission denied\") ||\n lowerErr.includes(\"eacces\") ||\n lowerErr.includes(\"database\") ||\n lowerErr.includes(\"migration\") ||\n lowerErr.includes(\"authentication\") ||\n lowerErr.includes(\"unauthorized\") ||\n lowerErr.includes(\"certificate\")\n ) {\n return \"critical\";\n }\n\n // Major: build/test/typecheck/runtime failures (blocks development)\n if (\n errorType === \"build\" ||\n errorType === \"test\" ||\n errorType === \"typecheck\" ||\n errorType === \"runtime\" ||\n errorType === \"import\" ||\n errorType === \"permission\"\n ) {\n return \"major\";\n }\n\n // Minor: lint/format warnings (non-blocking)\n if (errorType === \"lint\" || errorType === \"format\" || errorType === \"file-not-found\") {\n return \"minor\";\n }\n\n return \"major\";\n}\n\n/**\n * [Feature 1] Generate a concise title for the error (ReasoningBank pattern).\n * Title = short identifier summarizing the core issue.\n */\nfunction generateErrorTitle(command: string, errorType: string): string {\n // Extract the most relevant part of the command\n const cmdParts = command.trim().split(/\\s+/);\n const tool = cmdParts[0] ?? \"command\";\n const subCmd = cmdParts.slice(0, 3).join(\" \");\n return `${errorType} error in: ${subCmd.slice(0, 80)}`;\n}\n\n/**\n * [Feature 1] Extract anti-pattern from error output (MNL pattern).\n * Anti-pattern = what NOT to do.\n */\nfunction extractAntiPattern(command: string, errorOutput: string): string {\n // Extract the first meaningful error line\n const lines = errorOutput.split(\"\\n\").filter((l) => l.trim());\n const errorLine =\n lines.find((l) => /error|fail|cannot|missing|invalid/i.test(l)) ?? lines[0] ?? \"\";\n // Truncate and clean\n const cleaned = errorLine.replace(/\\s+/g, \" \").trim();\n return cleaned.length > 150 ? `${cleaned.slice(0, 150)}...` : cleaned;\n}\n\n/**\n * [Feature 1] Suggest correct approach based on error type (MNL pattern).\n * Correct approach = what TO do instead.\n */\nfunction suggestCorrectApproach(command: string, errorType: string, errorOutput: string): string {\n const suggestions: Record<string, string> = {\n lint: \"Fix the lint violation in the referenced file before re-running.\",\n test: \"Fix the failing test case or the code it tests. Check the assertion error details.\",\n typecheck: \"Fix the type error. Check the type signatures and imports.\",\n build:\n \"Fix the build error. Check for missing dependencies, syntax errors, or configuration issues.\",\n import: \"Check that the module exists and the import path is correct.\",\n permission: \"Check file permissions or run with appropriate access level.\",\n \"file-not-found\": \"Check that the file path is correct and the file exists.\",\n runtime: \"Check the error message and stack trace for the root cause.\",\n };\n return suggestions[errorType] ?? \"Analyze the error output and fix the root cause.\";\n}\n\n/**\n * [P3: Root Cause Analysis] Extract root cause from error stack trace.\n * (Experia pattern: Root Cause Analysis)\n * Looks for the most specific error line in a stack trace.\n */\nfunction extractRootCause(errorOutput: string): string {\n const lines = errorOutput.split(\"\\n\").filter((l) => l.trim());\n\n // Pattern 1: \"Error: <message>\" or \"TypeError: <message>\"\n const errorLine = lines.find((l) => /^\\s*(\\w+Error|Error):/.test(l));\n if (errorLine) return errorLine.trim().slice(0, 200);\n\n // Pattern 2: \"at <function> (<file>:<line>:<col>)\" — last frame is usually the root\n const stackFrame = lines.find((l) => /^\\s*at\\s/.test(l));\n if (stackFrame) return stackFrame.trim().slice(0, 200);\n\n // Pattern 3: First non-empty line with \"error\" or \"fail\"\n const genericLine = lines.find((l) => /error|fail|cannot|missing/i.test(l));\n if (genericLine) return genericLine.trim().slice(0, 200);\n\n // Fallback: first non-empty line\n return (lines[0] ?? \"\").trim().slice(0, 200);\n}\n\n/**\n * [Feature 6] Extract file paths from error content (memcite pattern).\n * Used for stale detection — if referenced files no longer exist, memory is stale.\n */\nfunction extractFilePaths(content: string): string[] {\n const paths: string[] = [];\n // Match common file path patterns: src/foo.ts, ./bar.js, /abs/path.py\n const pathRegex = /(?:^|\\s|[(:[])((?:\\.\\/|\\.\\.\\/|\\/)?[\\w-]+(?:\\/[\\w-]+)+\\.\\w{1,5})/g;\n let match;\n while ((match = pathRegex.exec(content)) !== null) {\n paths.push(match[1]);\n }\n return paths;\n}\n\n/** Hash a file path to a session key (same as storage layer). */\nexport function hashPath(path: string): string {\n return createHash(\"sha256\").update(path).digest(\"hex\").slice(0, 16);\n}\n\n/**\n * Default transcript directory: ~/.local/share/devin/cli/transcripts/\n */\nfunction defaultTranscriptDir(): string {\n return (\n process.env.DEVIN_TRANSCRIPTS_DIR ??\n join(homedir(), \".local\", \"share\", \"devin\", \"cli\", \"transcripts\")\n );\n}\n\n/** Generate a ULID-like ID (timestamp + random). */\nfunction generateId(): string {\n const ts = Date.now().toString(36).toUpperCase();\n const rand = Math.random().toString(36).slice(2, 12).toUpperCase();\n return `01${ts}${rand}`;\n}\n\n/**\n * Extract user/assistant messages from a transcript file and capture a summary.\n * Supports Devin CLI (single JSON with steps) and Claude Code (JSONL) formats.\n * Returns the capture ID, or null if skipped (trivial, duplicate, or no transcript).\n */\nasync function captureSessionTranscript(\n dbPath: string,\n sessionId?: string,\n transcriptPath?: string | null,\n): Promise<string | null> {\n const sid = sessionId ?? \"unknown\";\n\n if (!transcriptPath && !sessionId) {\n logToFile(\"Stop: no session_id or transcript_path, skipping auto-capture\");\n return null;\n }\n\n // Resolve transcript file path\n let filePath: string | null = null;\n if (transcriptPath) {\n filePath = transcriptPath;\n } else {\n filePath = join(defaultTranscriptDir(), `${sid}.json`);\n }\n\n if (!existsSync(filePath)) {\n logToFile(`Stop: transcript not found at ${filePath}`);\n return null;\n }\n\n const raw = readFileSync(filePath, \"utf-8\");\n const userMessages: string[] = [];\n const assistantMessages: string[] = [];\n\n const trimmed = raw.trim();\n if (trimmed.startsWith(\"{\") && trimmed.includes('\"steps\"')) {\n // Devin CLI: single JSON object with steps array\n const transcript = JSON.parse(raw);\n const steps: Array<{ source: string; message: string }> = transcript.steps ?? [];\n for (const step of steps) {\n if (step.source === \"user\" && typeof step.message === \"string\") {\n if (\n !step.message.startsWith(\"[remem-mcp]\") &&\n !step.message.startsWith(\"Code was changed\") &&\n !step.message.startsWith(\"<!-- \") &&\n !step.message.startsWith(\"# LoopX\") &&\n !step.message.includes(\"loopx-managed-slash-command\")\n ) {\n userMessages.push(step.message);\n }\n }\n if (\n (step.source === \"assistant\" || step.source === \"agent\") &&\n typeof step.message === \"string\"\n ) {\n assistantMessages.push(step.message);\n }\n }\n } else {\n // Claude Code: JSONL format (one JSON object per line)\n const lines = raw.split(\"\\n\").filter((l) => l.trim());\n for (const line of lines) {\n try {\n const obj = JSON.parse(line);\n if (obj.type !== \"user\" && obj.type !== \"assistant\") continue;\n\n const msg = obj.message;\n if (!msg || typeof msg !== \"object\") continue;\n\n const role = msg.role ?? obj.type;\n const content = msg.content;\n\n let text = \"\";\n if (typeof content === \"string\") {\n text = content;\n } else if (Array.isArray(content)) {\n text = content\n .filter(\n (c: unknown) =>\n typeof c === \"object\" && c !== null && (c as { type?: string }).type === \"text\",\n )\n .map((c: unknown) => (c as { text?: string }).text ?? \"\")\n .join(\" \");\n }\n\n if (!text.trim()) continue;\n if (text.startsWith(\"[remem-mcp]\") || text.startsWith(\"Code was changed\")) continue;\n // Skip skill/system injections (LoopX, agent rules, etc.)\n if (\n text.startsWith(\"<!-- \") ||\n text.startsWith(\"# LoopX\") ||\n text.includes(\"loopx-managed-slash-command\")\n )\n continue;\n\n if (role === \"user\") {\n userMessages.push(text);\n } else if (role === \"assistant\") {\n assistantMessages.push(text);\n }\n } catch {\n // Skip unparseable lines\n }\n }\n }\n\n // Skip trivial sessions: no assistant response, or very short probe messages\n const totalUserChars = userMessages.reduce((sum, m) => sum + m.length, 0);\n const totalAssistantChars = assistantMessages.reduce((sum, m) => sum + m.length, 0);\n const totalChars = totalUserChars + totalAssistantChars;\n const isTrivial =\n (userMessages.length <= 2 && assistantMessages.length === 0) ||\n (userMessages.length <= 2 && totalChars < 10);\n if (isTrivial) {\n logToFile(\n `Stop: trivial session (${userMessages.length} user msgs, ${totalChars} chars total), skipping auto-capture`,\n );\n return null;\n }\n\n // Build capture content: first user message (task) + last assistant message (outcome)\n const firstUser = userMessages[0] ?? \"\";\n const lastAssistant = assistantMessages[assistantMessages.length - 1] ?? \"\";\n const taskText = firstUser.slice(0, 500);\n const outcomeText = lastAssistant.slice(0, 500);\n\n const content = `Session: ${sid}\\nTask: ${taskText}\\nOutcome: ${outcomeText}`;\n const contentHash = createHash(\"sha256\").update(content).digest(\"hex\");\n\n const db = new Database(dbPath);\n const sessionKey = sid.slice(0, 16);\n const now = Date.now();\n const id = generateId();\n\n // Check for duplicate\n const existing = db.prepare(\"SELECT id FROM captures WHERE content_hash = ?\").get(contentHash) as\n | { id: string }\n | undefined;\n\n if (existing) {\n db.close();\n logToFile(`Stop: duplicate capture (hash match), skipping. id=${existing.id}`);\n return null;\n }\n\n // Delete previous auto-captures for the same session (only keep the latest).\n // This prevents N captures when the user stops/resumes N times.\n const stale = db\n .prepare(\n \"SELECT id FROM captures WHERE session_key = ? AND type = 'conversation' AND json_extract(metadata, '$.session_id') = ?\",\n )\n .all(sessionKey, sid) as { id: string }[];\n if (stale.length > 0) {\n const delStmt = db.prepare(\"DELETE FROM captures WHERE id = ?\");\n for (const row of stale) {\n delStmt.run(row.id);\n }\n logToFile(`Stop: removed ${stale.length} previous capture(s) for session ${sid}`);\n }\n\n db.prepare(`\n INSERT INTO captures (id, session_key, agent_id, type, content, content_hash, tags, created_at, metadata)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)\n `).run(\n id,\n sessionKey,\n \"devin-cli\",\n \"conversation\",\n content,\n contentHash,\n JSON.stringify([\"auto-capture\", \"stop\"]),\n now,\n JSON.stringify({\n session_id: sid,\n user_messages: userMessages.length,\n assistant_messages: assistantMessages.length,\n }),\n );\n\n // Generate embedding for vector search (best-effort, non-blocking)\n try {\n const sqliteVec = await import(\"sqlite-vec\");\n sqliteVec.load(db);\n const { LocalEmbedder } =\n require(\"./embedding/local.js\") as typeof import(\"./embedding/local.js\");\n const embedder = new LocalEmbedder();\n const embedding = await embedder.embed(content);\n if (embedding) {\n const buffer = new Float32Array(embedding);\n db.prepare(\"INSERT INTO captures_vec (id, embedding) VALUES (?, ?)\").run(\n id,\n Buffer.from(buffer.buffer),\n );\n }\n } catch (embedErr) {\n logToFile(`Stop: embedding failed for ${id}: ${embedErr}`);\n }\n\n db.close();\n\n logToFile(\n `Stop: auto-captured session ${sid} (${userMessages.length} user msgs, ${assistantMessages.length} assistant msgs). id=${id}`,\n );\n return id;\n}\n\n/**\n * Hook handler for SessionEnd event.\n * Reads the session transcript, extracts user/assistant messages,\n * and captures a summary directly to the memory DB.\n * Runs silently — no agent involvement needed.\n *\n * Supports two transcript formats:\n * - Claude Code: stdin includes `transcript_path`, file is JSONL (one JSON per line)\n * - Devin CLI: stdin includes `session_id`, file is at ~/.local/share/devin/cli/transcripts/<id>.json (single JSON with `steps` array)\n */\nexport function hookSessionEnd(dbPath: string): void {\n const chunks: Buffer[] = [];\n process.stdin.setEncoding(\"utf-8\");\n process.stdin.on(\"data\", (chunk) => {\n chunks.push(Buffer.from(chunk));\n });\n\n process.stdin.on(\"end\", () => {\n try {\n const input = JSON.parse(Buffer.concat(chunks).toString(\"utf-8\"));\n const sessionId = input.session_id ?? \"unknown\";\n const transcriptPath = input.transcript_path ?? null;\n\n captureSessionTranscript(dbPath, sessionId, transcriptPath)\n .then((id) => {\n if (id) {\n logToFile(`SessionEnd: captured via shared function. id=${id}`);\n }\n })\n .catch((err) => {\n logToFile(`SessionEnd: capture error - ${err}`);\n })\n .finally(() => {\n process.stdout.write(JSON.stringify({}));\n });\n } catch (err) {\n process.stderr.write(`[remem-mcp hook-session-end] Error: ${err}\\n`);\n logToFile(`SessionEnd: error - ${err}`);\n process.stdout.write(JSON.stringify({}));\n }\n });\n}\n\n/**\n * Wait for transcript file to appear, then capture it.\n * Spawned as a detached background process by hookStop, because Devin CLI\n * writes the transcript file AFTER the Stop hook fires.\n *\n * Waits up to 10 seconds (polling every 500ms), then captures or gives up.\n */\nexport async function waitAndCapture(\n dbPath: string,\n sessionId: string,\n transcriptPath: string | null,\n): Promise<void> {\n let filePath: string | null = null;\n if (transcriptPath) {\n filePath = transcriptPath;\n } else {\n filePath = join(defaultTranscriptDir(), `${sessionId}.json`);\n }\n\n // Wait up to 10 seconds for transcript file to appear\n const maxWait = 10000;\n const interval = 500;\n const start = Date.now();\n\n while (Date.now() - start < maxWait) {\n if (existsSync(filePath)) {\n // Wait a bit more for the file to be fully written\n await sleep(500);\n break;\n }\n await sleep(interval);\n }\n\n if (!existsSync(filePath)) {\n logToFile(`Stop: transcript never appeared at ${filePath} after 10s`);\n return;\n }\n\n try {\n const id = await captureSessionTranscript(dbPath, sessionId, transcriptPath);\n if (id) {\n logToFile(`Stop: background capture succeeded. id=${id}`);\n }\n } catch (err) {\n logToFile(`Stop: background capture error - ${err}`);\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Post-commit hook: auto-index changed files into the CodeGraph.\n *\n * Reads the list of changed files from `git diff-tree` and indexes them\n * into the memory database. This keeps the code graph up to date without\n * manual `codegraph_index` calls.\n *\n * Usage in .git/hooks/post-commit:\n * node /path/to/dist/index.js --hook=post-commit --db-path=/path/to/memory.db\n */\nexport async function hookPostCommit(dbPath: string): Promise<void> {\n try {\n const { execSync } = await import(\"node:child_process\");\n // Get list of changed files in this commit\n const output = execSync(\"git diff-tree --no-commit-id --name-only -r HEAD\", {\n encoding: \"utf-8\",\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n const files = output.trim().split(\"\\n\").filter(Boolean);\n\n if (files.length === 0) {\n logToFile(\"PostCommit: no changed files\");\n process.stdout.write(JSON.stringify({}));\n return;\n }\n\n // Load schema and CodeGraph engine\n const { readFileSync } = await import(\"node:fs\");\n const { join, dirname } = await import(\"node:path\");\n const { fileURLToPath } = await import(\"node:url\");\n const sqliteVec = await import(\"sqlite-vec\");\n const { indexFile } = await import(\"./codegraph/engine.js\");\n\n const db = new Database(dbPath);\n db.pragma(\"journal_mode = WAL\");\n sqliteVec.load(db);\n\n // Ensure schema exists (create tables if missing)\n const schemaPath = join(dirname(fileURLToPath(import.meta.url)), \"schema.sql\");\n try {\n const schema = readFileSync(schemaPath, \"utf-8\");\n db.exec(schema);\n } catch {\n // Schema file not found — tables may already exist\n }\n\n // Index supported code files\n const SUPPORTED_EXT = [\n \".ts\",\n \".tsx\",\n \".js\",\n \".jsx\",\n \".mjs\",\n \".cjs\",\n \".py\",\n \".go\",\n \".rs\",\n \".java\",\n \".c\",\n \".h\",\n \".cpp\",\n \".cc\",\n \".hpp\",\n \".cs\",\n ];\n let indexed = 0;\n let skipped = 0;\n const repoRoot = execSync(\"git rev-parse --show-toplevel\", { encoding: \"utf-8\" }).trim();\n\n for (const file of files) {\n const ext = file.slice(file.lastIndexOf(\".\")).toLowerCase();\n if (!SUPPORTED_EXT.includes(ext)) {\n skipped++;\n continue;\n }\n try {\n const fullPath = join(repoRoot, file);\n await indexFile(db, fullPath, repoRoot, null);\n indexed++;\n } catch {\n // Skip on error (file may not exist, parse error, etc.)\n skipped++;\n }\n }\n\n db.close();\n logToFile(`PostCommit: indexed ${indexed} file(s), skipped ${skipped}`);\n process.stdout.write(JSON.stringify({}));\n } catch (err) {\n process.stderr.write(`[remem-mcp hook-post-commit] Error: ${err}\\n`);\n logToFile(`PostCommit: error - ${err}`);\n process.stdout.write(JSON.stringify({}));\n }\n}\n\n/**\n * Hook handler for PreCompact event (Claude Code, Devin CLI).\n * Fires BEFORE context compaction destroys conversation details.\n * Captures a session checkpoint: what was decided, what was tried,\n * what's verified working, and remaining tasks — so the agent can\n * recover this context after compaction.\n *\n * Claude Code PreCompact stdin: { trigger: \"auto\"|\"manual\", custom_instructions }\n * Devin CLI PostCompaction stdin: similar shape.\n *\n * Output: additionalContext with a recovery prompt that tells the agent\n * \"your memory was checkpointed, here's what to remember\" — so after\n * compaction the agent still has the critical context.\n */\nexport function hookPreCompact(dbPath: string): void {\n const chunks: Buffer[] = [];\n process.stdin.setEncoding(\"utf-8\");\n process.stdin.on(\"data\", (chunk) => {\n chunks.push(Buffer.from(chunk));\n });\n\n process.stdin.on(\"end\", async () => {\n try {\n const raw = Buffer.concat(chunks).toString(\"utf-8\");\n const input = raw.trim() ? JSON.parse(raw) : {};\n const trigger = input.trigger ?? \"unknown\";\n const sessionKey = input.session_id ?? input.cwd ?? process.cwd();\n\n // Capture a compaction checkpoint\n const db = new Database(dbPath);\n db.pragma(\"journal_mode = WAL\");\n\n // Ensure schema exists (create tables if missing)\n try {\n const { fileURLToPath } = await import(\"node:url\");\n const schemaPath = join(dirname(fileURLToPath(import.meta.url)), \"storage\", \"schema.sql\");\n if (existsSync(schemaPath)) {\n db.exec(readFileSync(schemaPath, \"utf-8\"));\n }\n } catch {\n // Schema may already exist or file not found — non-fatal\n }\n\n const checkpointId = `ckpt-${createHash(\"sha256\")\n .update(sessionKey + Date.now())\n .digest(\"hex\")\n .slice(0, 12)}`;\n\n const summary =\n `Context compaction triggered (${trigger}). ` +\n `Session checkpoint saved. After compaction, recall recent memory to recover ` +\n `decisions made, approaches tried, and what was verified working.`;\n\n // Insert as a task-type capture so it shows up in recall\n db.prepare(\n `INSERT INTO captures (id, type, content, tags, metadata, session_key, agent_id, created_at)\n VALUES (?, 'task', ?, ?, ?, ?, ?, ?)`,\n ).run(\n checkpointId,\n summary,\n JSON.stringify([\"compaction\", \"checkpoint\", trigger]),\n JSON.stringify({\n checkpoint: true,\n trigger,\n compacted_at: new Date().toISOString(),\n session_key: sessionKey,\n }),\n sessionKey,\n \"remem-mcp-hook\",\n Date.now(),\n );\n\n // Also capture recent conversation messages if available\n // (Claude Code sends transcript_path in some versions)\n let transcriptNote = \"\";\n if (input.transcript_path && existsSync(input.transcript_path)) {\n try {\n const transcript = readFileSync(input.transcript_path, \"utf-8\");\n // Extract last ~2000 chars of conversation as a checkpoint\n const recent = transcript.slice(-2000);\n const transcriptId = `txcpt-${createHash(\"sha256\")\n .update(sessionKey + \"transcript\" + Date.now())\n .digest(\"hex\")\n .slice(0, 12)}`;\n db.prepare(\n `INSERT INTO captures (id, type, content, tags, metadata, session_key, agent_id, created_at)\n VALUES (?, 'task', ?, ?, ?, ?, ?, ?)`,\n ).run(\n transcriptId,\n `Pre-compaction transcript excerpt:\\n${recent}`,\n JSON.stringify([\"compaction\", \"transcript-excerpt\"]),\n JSON.stringify({\n checkpoint: true,\n source: \"transcript\",\n compacted_at: new Date().toISOString(),\n }),\n sessionKey,\n \"remem-mcp-hook\",\n Date.now(),\n );\n transcriptNote = \" + transcript excerpt\";\n } catch {\n // Non-fatal — transcript capture is supplementary\n }\n }\n\n db.close();\n\n logToFile(\n `PreCompact: saved checkpoint${transcriptNote} for session ${sessionKey} (trigger=${trigger})`,\n );\n\n // Visible feedback\n feedback(\"📦\", `remem-mcp: saved compaction checkpoint — memory survives the compact`);\n\n // Inject recovery context so the agent knows to recall after compaction\n const recoveryContext = `[remem-mcp] Context compaction is about to happen.\n\nA checkpoint of this session has been saved to memory. After compaction completes:\n1. Your recent decisions, errors, and learnings are preserved in the memory DB.\n2. Call recall() or rely on SessionStart hook to re-inject them.\n3. Do NOT re-explain things you already told the user — check memory first.\n\nCompaction trigger: ${trigger}`;\n\n const output = {\n hookSpecificOutput: {\n hookEventName: \"PreCompact\",\n additionalContext: recoveryContext,\n },\n };\n\n process.stdout.write(JSON.stringify(output));\n } catch (err) {\n process.stderr.write(`[remem-mcp hook-pre-compact] Error: ${err}\\n`);\n logToFile(`PreCompact: error - ${err}`);\n process.stdout.write(JSON.stringify({}));\n }\n });\n}\n\n/**\n * PostCompaction hook (Codex CLI).\n * Codex fires PostCompaction AFTER compaction (not before like Claude Code's PreCompact).\n * This handler recalls recent memory + any PreCompact checkpoint, re-injecting context\n * that was lost during compaction.\n *\n * Input (Codex): { session_id, cwd, ... }\n * Output: additionalContext with recalled memory.\n */\nexport function hookPostCompaction(dbPath: string): void {\n const chunks: Buffer[] = [];\n process.stdin.setEncoding(\"utf-8\");\n process.stdin.on(\"data\", (chunk) => {\n chunks.push(Buffer.from(chunk));\n });\n\n process.stdin.on(\"end\", async () => {\n try {\n const raw = Buffer.concat(chunks).toString(\"utf-8\");\n const input = raw.trim() ? JSON.parse(raw) : {};\n const sessionKey = input.session_id ?? input.cwd ?? process.cwd();\n\n // Recall recent memory using the same logic as SessionStart\n const { fileURLToPath } = await import(\"node:url\");\n const schemaPath = join(dirname(fileURLToPath(import.meta.url)), \"storage\", \"schema.sql\");\n const db = new Database(dbPath, { readonly: true });\n\n // Get recent captures (last 24h), prioritizing compaction checkpoints\n const cutoff = Date.now() - 24 * 60 * 60 * 1000;\n const rows = db\n .prepare(\n `SELECT id, type, content, tags, created_at FROM captures\n WHERE deleted_at IS NULL AND trust_state != 'rejected'\n AND created_at >= ?\n ORDER BY\n CASE WHEN tags LIKE '%checkpoint%' THEN 0 ELSE 1 END,\n created_at DESC\n LIMIT 15`,\n )\n .all(cutoff) as {\n id: string;\n type: string;\n content: string;\n tags: string | null;\n created_at: number;\n }[];\n\n db.close();\n\n if (rows.length === 0) {\n process.stdout.write(JSON.stringify({}));\n return;\n }\n\n // Build recovery context\n const lines: string[] = [\n \"[remem-mcp] Context compaction just happened.\",\n \"Re-injecting recent memory so you don't lose context:\",\n \"\",\n ];\n\n for (const row of rows) {\n const tags = row.tags ? JSON.parse(row.tags) : [];\n const isCheckpoint = tags.includes(\"checkpoint\");\n const marker = isCheckpoint ? \" [CHECKPOINT]\" : \"\";\n const preview = row.content.slice(0, 200).replace(/\\n/g, \" \");\n lines.push(`- [${row.type}]${marker} ${preview}`);\n }\n\n lines.push(\"\");\n lines.push(\"Do NOT re-explain things you already told the user — check memory first.\");\n\n const context = lines.join(\"\\n\");\n\n // Visible feedback\n feedback(\"📦\", `remem-mcp: re-injected ${rows.length} memories after compaction`);\n\n const output = {\n hookSpecificOutput: {\n hookEventName: \"PostCompaction\",\n additionalContext: context,\n },\n };\n\n process.stdout.write(JSON.stringify(output));\n } catch (err) {\n process.stderr.write(`[remem-mcp hook-post-compaction] Error: ${err}\\n`);\n logToFile(`PostCompaction: error - ${err}`);\n process.stdout.write(JSON.stringify({}));\n }\n });\n}\n","import { execFileSync } from \"node:child_process\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\n/**\n * Wire hooks into agent config files.\n *\n * For Devin CLI: adds hooks to ~/.config/devin/config.json under the \"hooks\" key.\n * For Claude Code: adds hooks to ~/.claude/settings.json under the \"hooks\" key.\n *\n * Hooks installed:\n * - SessionStart: runs `remem-mcp hook-recall` → injects recent memory into agent context\n * - SessionEnd: runs `remem-mcp hook-session-end` → silently captures session summary to memory DB\n */\n\n/**\n * Resolve the best command to invoke remem-mcp hooks.\n * If the binary is globally installed, use it directly (fast, no npx overhead).\n * Fall back to npx --prefer-offline (uses cache, avoids re-download).\n */\nfunction hookCommand(subcommand: string): string {\n try {\n const binPath = execFileSync(\"which\", [\"remem-mcp\"], { encoding: \"utf-8\" }).trim();\n if (binPath && existsSync(binPath)) {\n return `${binPath} ${subcommand}`;\n }\n } catch {\n // Binary not found — fall back to npx\n }\n return `npx --prefer-offline -y remem-mcp ${subcommand}`;\n}\n\n/** Hooks configuration for Devin CLI and Codex CLI.\n * Note: Devin CLI does NOT support PreCompact — only PostCompaction. */\nconst HOOKS_CONFIG = {\n SessionStart: [\n {\n hooks: [\n {\n type: \"command\",\n command: hookCommand(\"hook-recall\"),\n timeout: 10,\n },\n ],\n },\n ],\n PreToolUse: [\n {\n matcher: \"Bash|exec\",\n hooks: [\n {\n type: \"command\",\n command: hookCommand(\"hook-pre-tool-use\"),\n timeout: 5,\n },\n ],\n },\n ],\n PostToolUse: [\n {\n matcher: \"Bash|exec\",\n hooks: [\n {\n type: \"command\",\n command: hookCommand(\"hook-post-tool-use\"),\n timeout: 5,\n },\n ],\n },\n ],\n // PostCompaction: re-inject memory after context compaction.\n // Supported by all 3 agents (Claude Code, Devin CLI, Codex CLI).\n // Note: Devin CLI and Codex CLI do NOT support PreCompact — only PostCompaction.\n // Claude Code supports both, but PostCompaction alone is sufficient.\n PostCompaction: [\n {\n hooks: [\n {\n type: \"command\",\n command: hookCommand(\"hook-post-compaction\"),\n timeout: 10,\n },\n ],\n },\n ],\n // Note: PostToolUseFailure is not supported by Devin CLI.\n // Devin supports: PreToolUse, PostToolUse, UserPromptSubmit, Stop,\n // PostCompaction, SessionStart, SessionEnd, PermissionRequest.\n // Error capture is handled via PostToolUse with exit code 2.\n Stop: [\n {\n hooks: [\n {\n type: \"command\",\n command: hookCommand(\"hook-stop\"),\n timeout: 10,\n },\n ],\n },\n ],\n SessionEnd: [\n {\n hooks: [\n {\n type: \"command\",\n command: hookCommand(\"hook-session-end\"),\n timeout: 10,\n },\n ],\n },\n ],\n};\n\n/** Safely read and parse a JSON config file. Returns {} if file doesn't exist or is invalid. */\nfunction readJsonConfig(path: string): Record<string, unknown> {\n if (!existsSync(path)) return {};\n try {\n return JSON.parse(readFileSync(path, \"utf-8\"));\n } catch {\n return {};\n }\n}\n\n/** Write JSON config file, creating directories as needed. */\nfunction writeJsonConfig(path: string, data: unknown): void {\n const dir = dirname(path);\n if (!existsSync(dir)) mkdirSync(dir, { recursive: true });\n writeFileSync(path, `${JSON.stringify(data, null, 2)}\\n`, \"utf-8\");\n}\n\n/** Merge hooks into an existing config object without overwriting other keys.\n * For each hook event, appends our hooks to any existing ones (preserves user hooks).\n */\nfunction mergeHooks(\n config: Record<string, unknown>,\n hooks: Record<string, unknown>,\n): Record<string, unknown> {\n const existing = (config.hooks as Record<string, unknown>) ?? {};\n const merged: Record<string, unknown> = { ...existing };\n\n for (const [event, newEntries] of Object.entries(hooks)) {\n const existingEntries = (existing[event] as unknown[]) ?? [];\n // Filter out any previous remem-mcp hooks for this event (avoid duplicates on re-install)\n const filtered = existingEntries.filter((entry) => {\n const hooks = (entry as { hooks?: { command?: string }[] })?.hooks;\n if (!hooks) return true;\n return !hooks.some((h) => h?.command?.includes(\"remem-mcp\"));\n });\n merged[event] = [...filtered, ...(newEntries as unknown[])];\n }\n\n return {\n ...config,\n hooks: merged,\n };\n}\n\n/** Install hooks for Devin CLI. */\nfunction installDevinHooks(): boolean {\n const configPath = join(homedir(), \".config\", \"devin\", \"config.json\");\n\n if (!existsSync(dirname(configPath))) {\n return false;\n }\n\n const config = readJsonConfig(configPath);\n const updated = mergeHooks(config, HOOKS_CONFIG);\n writeJsonConfig(configPath, updated);\n\n console.log(` Devin CLI: Hooks wired into ${configPath}`);\n return true;\n}\n\n/** Install hooks for Claude Code.\n * Claude Code supports PreCompact (before compaction) in addition to PostCompaction. */\nfunction installClaudeCodeHooks(): boolean {\n const settingsPath = join(homedir(), \".claude\", \"settings.json\");\n\n // Check if Claude Code is installed\n const claudeDir = join(homedir(), \".claude\");\n if (!existsSync(claudeDir)) {\n return false;\n }\n\n // Claude Code supports PreCompact — add it on top of the base config\n const claudeHooksConfig = {\n ...HOOKS_CONFIG,\n PreCompact: [\n {\n hooks: [\n {\n type: \"command\",\n command: hookCommand(\"hook-pre-compact\"),\n timeout: 10,\n },\n ],\n },\n ],\n };\n\n const config = readJsonConfig(settingsPath);\n const updated = mergeHooks(config, claudeHooksConfig);\n writeJsonConfig(settingsPath, updated);\n\n console.log(` Claude Code: Hooks wired into ${settingsPath}`);\n return true;\n}\n\n/** Install hooks for Codex CLI (TOML config). */\nfunction installCodexHooks(): boolean {\n const configPath = join(homedir(), \".codex\", \"config.toml\");\n\n if (!existsSync(configPath)) {\n return false;\n }\n\n let content = readFileSync(configPath, \"utf-8\");\n\n // Check if remem-mcp hooks are already installed\n if (content.includes(\">>> remem-mcp SessionStart >>>\")) {\n console.log(` Codex CLI: Hooks already installed in ${configPath}`);\n return true;\n }\n\n // Append remem-mcp hooks to the TOML config\n const hooksToml = `\n# >>> remem-mcp SessionStart >>>\n[[hooks.SessionStart]]\nmatcher = \"startup|resume|clear|compact\"\n\n[[hooks.SessionStart.hooks]]\ntype = \"command\"\ncommand = \"${hookCommand(\"hook-recall\")}\"\ntimeout = 10\n# <<< remem-mcp SessionStart <<<\n\n# >>> remem-mcp PreToolUse >>>\n[[hooks.PreToolUse]]\nmatcher = \"Bash|exec\"\n\n[[hooks.PreToolUse.hooks]]\ntype = \"command\"\ncommand = \"${hookCommand(\"hook-pre-tool-use\")}\"\ntimeout = 5\n# <<< remem-mcp PreToolUse <<<\n\n# >>> remem-mcp PostToolUse >>>\n[[hooks.PostToolUse]]\nmatcher = \"Bash|exec\"\n\n[[hooks.PostToolUse.hooks]]\ntype = \"command\"\ncommand = \"${hookCommand(\"hook-post-tool-use\")}\"\ntimeout = 5\n# <<< remem-mcp PostToolUse <<<\n\n# >>> remem-mcp PostCompaction >>>\n[[hooks.PostCompaction]]\n\n[[hooks.PostCompaction.hooks]]\ntype = \"command\"\ncommand = \"${hookCommand(\"hook-post-compaction\")}\"\ntimeout = 10\n# <<< remem-mcp PostCompaction <<<\n\n# >>> remem-mcp Stop >>>\n[[hooks.Stop]]\n\n[[hooks.Stop.hooks]]\ntype = \"command\"\ncommand = \"${hookCommand(\"hook-stop\")}\"\ntimeout = 5\n# <<< remem-mcp Stop <<<\n\n# >>> remem-mcp SessionEnd >>>\n[[hooks.SessionEnd]]\n\n[[hooks.SessionEnd.hooks]]\ntype = \"command\"\ncommand = \"${hookCommand(\"hook-session-end\")}\"\ntimeout = 10\n# <<< remem-mcp SessionEnd <<<\n`;\n\n content = content.trimEnd() + \"\\n\" + hooksToml;\n writeFileSync(configPath, content, \"utf-8\");\n\n console.log(` Codex CLI: Hooks wired into ${configPath}`);\n console.log(` Note: Set sandbox_mode = \"danger-full-access\" for MCP tools to work.`);\n return true;\n}\n\n/** Install auto-capture hooks for supported agents. */\nexport async function installHooks(): Promise<void> {\n console.log(\"Installing lifecycle hooks...\\n\");\n\n let installed = 0;\n\n if (installDevinHooks()) installed++;\n if (installClaudeCodeHooks()) installed++;\n if (installCodexHooks()) installed++;\n\n if (installed === 0) {\n console.log(\"\\nNo supported agents found.\");\n console.log(\"Install Devin CLI, Claude Code, or Codex CLI first, then run this command again.\");\n return;\n }\n\n console.log(`\\nHooks wired to ${installed} agent(s).`);\n console.log(\"\\nHooks installed:\");\n console.log(\" SessionStart → auto-recall recent memory into agent context\");\n console.log(\" PreToolUse → inject past errors before lint/build/test commands\");\n console.log(\" PostToolUse → auto-capture failed commands as error memories\");\n console.log(\" PreCompact → save checkpoint before compaction (Claude Code only)\");\n console.log(\" PostCompaction → re-inject memory after compaction (all agents)\");\n console.log(\" Stop → auto-capture session transcript + remind to save\");\n console.log(\" SessionEnd → silently capture session summary to memory DB\");\n console.log(\"\\nRestart your agent for hooks to take effect.\");\n console.log(\"\\nTo verify: run /hooks in your agent.\");\n}\n\n/** Remove hooks from agent config files. */\nexport async function uninstallHooks(): Promise<void> {\n console.log(\"Removing lifecycle hooks...\\n\");\n\n let removed = 0;\n const rememEvents = [\n \"SessionStart\",\n \"SessionEnd\",\n \"Stop\",\n \"PreToolUse\",\n \"PostToolUse\",\n \"PreCompact\",\n \"PostCompaction\",\n ];\n\n // Remove from Devin CLI\n const devinPath = join(homedir(), \".config\", \"devin\", \"config.json\");\n if (existsSync(devinPath)) {\n const config = readJsonConfig(devinPath);\n if (config.hooks) {\n const hooks = config.hooks as Record<string, unknown[]>;\n for (const ev of rememEvents) {\n if (hooks[ev]) {\n // Filter out only remem-mcp hooks, preserve user hooks\n hooks[ev] = (hooks[ev] as { hooks?: { command?: string }[] }[]).filter((entry) => {\n const entryHooks = entry?.hooks;\n if (!entryHooks) return true;\n return !entryHooks.some((h) => h?.command?.includes(\"remem-mcp\"));\n });\n if (Array.isArray(hooks[ev]) && hooks[ev].length === 0) {\n delete hooks[ev];\n }\n }\n }\n if (Object.keys(hooks).length === 0) {\n delete config.hooks;\n }\n writeJsonConfig(devinPath, config);\n console.log(` Devin CLI: Hooks removed from ${devinPath}`);\n removed++;\n }\n }\n\n // Remove from Claude Code\n const claudePath = join(homedir(), \".claude\", \"settings.json\");\n if (existsSync(claudePath)) {\n const config = readJsonConfig(claudePath);\n if (config.hooks) {\n const hooks = config.hooks as Record<string, unknown[]>;\n for (const ev of rememEvents) {\n if (hooks[ev]) {\n hooks[ev] = (hooks[ev] as { hooks?: { command?: string }[] }[]).filter((entry) => {\n const entryHooks = entry?.hooks;\n if (!entryHooks) return true;\n return !entryHooks.some((h) => h?.command?.includes(\"remem-mcp\"));\n });\n if (Array.isArray(hooks[ev]) && hooks[ev].length === 0) {\n delete hooks[ev];\n }\n }\n }\n if (Object.keys(hooks).length === 0) {\n delete config.hooks;\n }\n writeJsonConfig(claudePath, config);\n console.log(` Claude Code: Hooks removed from ${claudePath}`);\n removed++;\n }\n }\n\n // Remove from Codex CLI (TOML config)\n const codexPath = join(homedir(), \".codex\", \"config.toml\");\n if (existsSync(codexPath)) {\n let content = readFileSync(codexPath, \"utf-8\");\n if (content.includes(\">>> remem-mcp\")) {\n // Remove all remem-mcp TOML blocks (between >>> remem-mcp ... >>> and <<< remem-mcp ... <<<)\n content = content.replace(/\\n?# >>> remem-mcp[\\s\\S]*?# <<< remem-mcp[^<]*<<<\\n?/g, \"\\n\");\n writeFileSync(codexPath, content.trimEnd() + \"\\n\", \"utf-8\");\n console.log(` Codex CLI: Hooks removed from ${codexPath}`);\n removed++;\n }\n }\n\n if (removed === 0) {\n console.log(\"No hooks found to remove.\");\n } else {\n console.log(`\\nHooks removed from ${removed} agent(s).`);\n }\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport Database from \"better-sqlite3\";\nimport * as sqliteVec from \"sqlite-vec\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\ninterface ImportRow {\n id: string;\n session_key: string;\n agent_id: string;\n type: string;\n content: string;\n content_hash: string | null;\n tags: string | null;\n created_at: number;\n metadata: string | null;\n team_id: string | null;\n user_id: string | null;\n task_id: string | null;\n}\n\ninterface ImportMessage {\n id: string;\n capture_id: string;\n role: string;\n content: string;\n seq: number;\n created_at: number;\n}\n\ninterface ImportFormat {\n version: number;\n exported_at: number;\n count: number;\n captures: ImportRow[];\n messages?: ImportMessage[];\n}\n\n/** Run the schema if the database is new. */\nfunction ensureSchema(db: Database.Database): void {\n const candidates = [\n join(__dirname, \"storage\", \"schema.sql\"),\n join(__dirname, \"schema.sql\"),\n join(__dirname, \"..\", \"storage\", \"schema.sql\"),\n ];\n\n let schema: string | null = null;\n for (const path of candidates) {\n try {\n schema = readFileSync(path, \"utf-8\");\n break;\n } catch {\n // Try the next candidate\n }\n }\n\n if (!schema) {\n throw new Error(\"Could not find schema.sql.\");\n }\n db.exec(schema);\n}\n\n/** Import captures from a JSON file. Skips captures that already exist (by ID). */\nexport function importData(dbPath: string, inputPath: string): void {\n if (!existsSync(inputPath)) {\n console.error(`Error: File not found: ${inputPath}`);\n process.exit(1);\n }\n\n const raw = readFileSync(inputPath, \"utf-8\");\n let data: ImportFormat;\n try {\n data = JSON.parse(raw);\n } catch {\n console.error(\"Error: Invalid JSON file.\");\n process.exit(1);\n }\n\n if (!data.captures || !Array.isArray(data.captures)) {\n console.error(\"Error: No captures array in the file.\");\n process.exit(1);\n }\n\n const db = new Database(dbPath);\n db.pragma(\"journal_mode = WAL\");\n db.pragma(\"synchronous = NORMAL\");\n sqliteVec.load(db);\n ensureSchema(db);\n\n let inserted = 0;\n let skipped = 0;\n let messagesInserted = 0;\n\n const insertStmt = db.prepare(`\n INSERT OR IGNORE INTO captures (id, session_key, agent_id, type, content, content_hash, tags, created_at, metadata, team_id, user_id, task_id)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `);\n\n const insertMsgStmt = db.prepare(`\n INSERT OR IGNORE INTO messages (id, capture_id, role, content, seq, created_at)\n VALUES (?, ?, ?, ?, ?, ?)\n `);\n\n const transaction = db.transaction(() => {\n for (const row of data.captures) {\n const result = insertStmt.run(\n row.id,\n row.session_key,\n row.agent_id,\n row.type,\n row.content,\n row.content_hash ?? null,\n row.tags,\n row.created_at,\n row.metadata,\n row.team_id ?? null,\n row.user_id ?? null,\n row.task_id ?? null,\n );\n\n if (result.changes > 0) {\n inserted++;\n } else {\n skipped++;\n }\n }\n\n // Import messages if present (export format v2+)\n if (data.messages && Array.isArray(data.messages)) {\n for (const msg of data.messages) {\n const result = insertMsgStmt.run(\n msg.id,\n msg.capture_id,\n msg.role,\n msg.content,\n msg.seq,\n msg.created_at,\n );\n if (result.changes > 0) {\n messagesInserted++;\n }\n }\n }\n });\n\n transaction();\n db.close();\n\n const msgNote = messagesInserted > 0 ? `, ${messagesInserted} messages` : \"\";\n console.log(`Imported ${inserted} captures${msgNote}, skipped ${skipped} (already exist).`);\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\n/**\n * Register the remem-mcp MCP server in agent config files.\n *\n * Config locations:\n * - Claude Code: ~/.claude.json → mcpServers.remem-mcp\n * - Devin CLI: ~/.config/devin/mcp_config.json → mcpServers.remem-mcp\n * - Cursor: ~/.cursor/mcp.json → mcpServers.remem-mcp\n * - Codex CLI: ~/.codex/config.toml → [mcp_servers.remem-mcp] (TOML, skip if no parser)\n */\n\nconst MCP_SERVER_ENTRY = {\n command: \"npx\",\n args: [\"-y\", \"remem-mcp\"],\n};\n\nconst MCP_SERVER_ENTRY_WITH_GLOBAL = {\n command: \"npx\",\n args: [\"-y\", \"remem-mcp\"],\n env: {\n TDAI_GLOBAL_SESSION_KEY: \"global\",\n },\n};\n\ninterface JsonTarget {\n name: string;\n path: string;\n key: string;\n useGlobal?: boolean;\n}\n\nconst JSON_TARGETS: JsonTarget[] = [\n {\n name: \"Claude Code\",\n path: join(homedir(), \".claude.json\"),\n key: \"mcpServers\",\n },\n {\n name: \"Devin CLI\",\n path: join(homedir(), \".config\", \"devin\", \"mcp_config.json\"),\n key: \"mcpServers\",\n useGlobal: true,\n },\n {\n name: \"Cursor\",\n path: join(homedir(), \".cursor\", \"mcp.json\"),\n key: \"mcpServers\",\n },\n];\n\n/** Register MCP server in a JSON config file. */\nfunction registerJsonServer(target: JsonTarget): boolean {\n let config: Record<string, unknown> = {};\n\n if (existsSync(target.path)) {\n try {\n config = JSON.parse(readFileSync(target.path, \"utf-8\"));\n } catch {\n // Corrupt config — don't touch it\n console.log(` ${target.name}: Config file unreadable, skipping.`);\n return false;\n }\n }\n\n const servers = (config[target.key] as Record<string, unknown>) || {};\n const entry = target.useGlobal ? MCP_SERVER_ENTRY_WITH_GLOBAL : MCP_SERVER_ENTRY;\n\n if (JSON.stringify(servers[\"remem-mcp\"]) === JSON.stringify(entry)) {\n console.log(` ${target.name}: Already registered.`);\n return true;\n }\n\n servers[\"remem-mcp\"] = entry;\n config[target.key] = servers;\n\n const dir = dirname(target.path);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n writeFileSync(target.path, JSON.stringify(config, null, 2) + \"\\n\", \"utf-8\");\n console.log(` ${target.name}: MCP server registered.`);\n return true;\n}\n\n/** Register the MCP server in all supported agent configs. */\nexport async function installMcpServer(): Promise<void> {\n console.log(\"\\nRegistering MCP server...\\n\");\n\n let count = 0;\n for (const target of JSON_TARGETS) {\n // Only register if the config file already exists (agent is installed)\n // or the agent's directory exists.\n // Special case: Cursor stores config in ~/.cursor/mcp.json — create it\n // if the Cursor app directory exists but mcp.json doesn't.\n const agentDir = dirname(target.path);\n if (!existsSync(agentDir)) {\n // Check if Cursor app is installed (macOS)\n if (target.name === \"Cursor\") {\n const cursorApp = \"/Applications/Cursor.app\";\n const cursorAppHome = join(homedir(), \"Library\", \"Application Support\", \"Cursor\");\n if (existsSync(cursorApp) || existsSync(cursorAppHome)) {\n // Cursor is installed — create the config directory and file\n mkdirSync(agentDir, { recursive: true });\n } else {\n continue;\n }\n } else {\n continue;\n }\n }\n\n if (registerJsonServer(target)) {\n count++;\n }\n }\n\n // Codex uses TOML — check if config exists and append if missing\n const codexConfig = join(homedir(), \".codex\", \"config.toml\");\n if (existsSync(codexConfig)) {\n const content = readFileSync(codexConfig, \"utf-8\");\n if (content.includes(\"[mcp_servers.remem-mcp]\")) {\n console.log(\" Codex CLI: Already registered.\");\n count++;\n } else {\n const tomlEntry = `\n[mcp_servers.remem-mcp]\ncommand = \"npx\"\nargs = [\"-y\", \"remem-mcp\"]\n\n[mcp_servers.remem-mcp.env]\nTDAI_GLOBAL_SESSION_KEY = \"global\"\n`;\n writeFileSync(codexConfig, content + tomlEntry, \"utf-8\");\n console.log(\" Codex CLI: MCP server registered.\");\n count++;\n }\n }\n\n if (count === 0) {\n console.log(\" No agent config files found. MCP server will need manual setup.\");\n console.log(\" See README for manual config instructions.\");\n } else {\n console.log(`\\nMCP server registered in ${count} agent config(s).`);\n }\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\n/** Skill file content. Loaded from the bundled skills/ directory. */\nfunction loadSkillContent(): string {\n // Try multiple locations: package root, dist parent, dist\n const candidates = [\n join(process.cwd(), \"skills\", \"remem-mcp\", \"SKILL.md\"),\n join(__dirname, \"..\", \"skills\", \"remem-mcp\", \"SKILL.md\"),\n join(__dirname, \"skills\", \"remem-mcp\", \"SKILL.md\"),\n ];\n\n for (const path of candidates) {\n try {\n return readFileSync(path, \"utf-8\");\n } catch {\n // Try the next candidate\n }\n }\n\n throw new Error(\n \"Could not find skills/remem-mcp/SKILL.md. Make sure the package includes the skills directory.\",\n );\n}\n\n/** Supported agent skill directories. */\nconst SKILL_TARGETS = [\n {\n name: \"Devin CLI\",\n path: join(homedir(), \".config\", \"devin\", \"skills\", \"remem-mcp\", \"SKILL.md\"),\n },\n {\n name: \"Claude Code\",\n path: join(homedir(), \".claude\", \"skills\", \"remem-mcp\", \"SKILL.md\"),\n },\n {\n name: \"Codex CLI\",\n path: join(homedir(), \".codex\", \"skills\", \"remem-mcp\", \"SKILL.md\"),\n },\n {\n name: \"Generic (.agents)\",\n path: join(homedir(), \".agents\", \"skills\", \"remem-mcp\", \"SKILL.md\"),\n },\n];\n\n/** Install the skill file to all supported agent directories. */\nexport async function installSkill(): Promise<void> {\n const skillContent = loadSkillContent();\n let installed = 0;\n\n for (const target of SKILL_TARGETS) {\n const dir = dirname(target.path);\n\n // Create the directory if it does not exist\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n // Check if the skill already exists\n if (existsSync(target.path)) {\n console.log(` ${target.name}: Already installed. Updated.`);\n } else {\n console.log(` ${target.name}: Installed.`);\n }\n\n writeFileSync(target.path, skillContent, \"utf-8\");\n installed++;\n }\n\n console.log(`\\nSkill installed to ${installed} location(s).`);\n console.log(\"Restart your agent to load the skill.\");\n console.log(\"\\nThe skill teaches your agent to:\");\n console.log(\" - Recall past context before answering\");\n console.log(\" - Capture decisions, learnings, and fixes after completing work\");\n console.log(\" - Search with filters when recall is too broad\");\n console.log(\" - Forget only on explicit user request\");\n}\n","import type { CaptureInput, PipelineContext, PipelineOutput, PipelineStage } from \"./types.js\";\n\n/**\n * Noop pipeline. The default pipeline.\n * It does nothing. It stores L0 data only.\n * The storage layer already wrote the L0 row before the pipeline runs.\n */\nexport class NoopPipeline implements PipelineStage {\n readonly name = \"noop\";\n readonly requiresLLM = false;\n\n async process(_input: CaptureInput, _ctx: PipelineContext): Promise<PipelineOutput> {\n return {};\n }\n}\n","import { createHash } from \"node:crypto\";\nimport { appendFileSync, existsSync, mkdirSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\n\n/** Audit log entry. */\nexport interface AuditEntry {\n ts: number;\n tool: string;\n argsHash: string;\n resultLen: number | null;\n quotaHit: boolean;\n redacted: boolean;\n /** For mutation tools (forget): records what was changed. */\n mutation?: { id?: string; filter?: unknown; captures: number };\n}\n\n/** Append-only JSONL audit logger. */\nexport class AuditLogger {\n private logPath: string;\n private enabled: boolean;\n\n constructor(logPath: string, enabled: boolean) {\n this.logPath = logPath;\n this.enabled = enabled;\n if (enabled) {\n const dir = dirname(logPath);\n if (!existsSync(dir)) mkdirSync(dir, { recursive: true });\n }\n }\n\n /** Log a tool call. */\n log(entry: Omit<AuditEntry, \"ts\">): void {\n if (!this.enabled) return;\n\n const fullEntry: AuditEntry = {\n ts: Date.now(),\n ...entry,\n };\n\n const line = JSON.stringify(fullEntry);\n try {\n appendFileSync(this.logPath, `${line}\\n`);\n } catch (err) {\n // The audit log must not crash the server\n console.error(`[remem-mcp] Audit log write failed: ${err}`);\n }\n }\n\n /** Hash the arguments for the audit log. The log does not store raw arguments. */\n static hashArgs(args: unknown): string {\n const json = JSON.stringify(args);\n return createHash(\"sha256\").update(json).digest(\"hex\");\n }\n}\n","import { createHash } from \"node:crypto\";\nimport { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport {\n CallToolRequestSchema,\n ListResourcesRequestSchema,\n ListToolsRequestSchema,\n ReadResourceRequestSchema,\n type Tool,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport {\n findCallees as cgFindCallees,\n findCallers as cgFindCallers,\n impactAnalysis as cgImpactAnalysis,\n indexDirectory as cgIndexDirectory,\n indexFile as cgIndexFile,\n listSymbols as cgListSymbols,\n searchSymbols as cgSearchSymbols,\n} from \"./codegraph/engine.js\";\nimport type { Embedder } from \"./embedding/types.js\";\nimport type { PipelineContext, PipelineStage } from \"./pipeline/types.js\";\nimport { AuditLogger } from \"./security/audit.js\";\nimport { checkContentLength, enforceQuota } from \"./security/quota.js\";\nimport { redact } from \"./security/redactor.js\";\nimport type {\n CaptureEntry,\n CaptureMessage,\n CaptureType,\n DeleteFilter,\n DeleteResult,\n KnowledgeEntry,\n SearchMode,\n SearchResult,\n StorageBackend,\n TrustState,\n} from \"./storage/types.js\";\nimport { formatResults } from \"./tools/format.js\";\nimport { generateId } from \"./utils/ulid.js\";\nimport {\n getWikiPage as wikiGet,\n ingestDirectory as wikiIngestDir,\n ingestFile as wikiIngestFile,\n findOutdatedPages as wikiOutdated,\n searchWiki as wikiSearch,\n} from \"./wiki/engine.js\";\n\n/** Default session key: hash of the current working directory. */\nfunction defaultSessionKey(): string {\n // TDAI_SESSION_KEY overrides the default hash(cwd) — use for single global session\n if (process.env.TDAI_SESSION_KEY) return process.env.TDAI_SESSION_KEY;\n const cwd = process.cwd();\n return createHash(\"sha256\").update(cwd).digest(\"hex\").slice(0, 16);\n}\n\n/** Global session key for cross-project memory (rules, learnings). */\nfunction globalSessionKey(): string | null {\n return process.env.TDAI_GLOBAL_SESSION_KEY ?? null;\n}\n\n/** Detect the agent ID from environment variables. */\nfunction detectAgentId(): string {\n if (process.env.DEVIN_SESSION_ID) return \"devin\";\n if (process.env.CLAUDE_CODE_ENTRYPOINT) return \"claude\";\n if (process.env.CURSOR_DEBUG) return \"cursor\";\n return \"unknown\";\n}\n\n/** Options to create the MCP server. */\nexport interface ServerOptions {\n storage: StorageBackend;\n embedder: Embedder;\n pipeline: PipelineStage;\n pipelineCtx: Omit<PipelineContext, \"sessionKey\">;\n audit: AuditLogger;\n redactSecrets: boolean;\n maxContentLength: number;\n maxTokensRecall: number;\n maxTokensSearch: number;\n}\n\n/** Multi-tenant isolation parameters shared across tools. */\nconst TENANT_PARAMS = {\n team_id: {\n type: \"string\",\n description:\n \"The team ID. Use this to isolate memory by team. When set, all queries filter by this value.\",\n },\n agent_id: {\n type: \"string\",\n description:\n \"The agent ID. Use this to isolate memory by agent role within a team. Defaults to the detected agent.\",\n },\n user_id: {\n type: \"string\",\n description:\n \"The user ID. Use this to isolate memory by user within a team. When set with team_id, queries filter by both.\",\n },\n task_id: {\n type: \"string\",\n description:\n \"The task ID. Use this to isolate memory by a specific task. Link captures to a task for finer isolation.\",\n },\n};\n\n/** Tool definitions for the MCP protocol. */\nconst TOOLS: Tool[] = [\n {\n name: \"recall\",\n description:\n \"Retrieve relevant past memory. Call this tool before you answer the user. \" +\n \"Use it when the user references past work or when the task needs project context.\",\n inputSchema: {\n type: \"object\",\n properties: {\n query: {\n type: \"string\",\n description:\n \"A natural language query. The tool uses this text for the BM25 search and the vector search.\",\n },\n session_key: {\n type: \"string\",\n description:\n \"The session key. The default is hash(cwd). Use this to recall memory from a different project.\",\n },\n limit: {\n type: \"integer\",\n default: 10,\n maximum: 50,\n description: \"The maximum number of results.\",\n },\n offset: {\n type: \"integer\",\n default: 0,\n description: \"The pagination offset. Use this to get the next page of results.\",\n },\n max_tokens: {\n type: \"integer\",\n default: 4000,\n maximum: 8000,\n description:\n \"The maximum number of tokens in the response. If the result exceeds this value, the tool truncates the text.\",\n },\n mode: {\n type: \"string\",\n enum: [\"hybrid\", \"keyword\", \"vector\"],\n default: \"hybrid\",\n description: \"The search mode.\",\n },\n ...TENANT_PARAMS,\n },\n required: [\"query\"],\n },\n },\n {\n name: \"capture\",\n description:\n \"Save a decision, a learning, or a task outcome to memory. \" +\n \"Call this tool after you complete a non-trivial task, make a decision, or fix a bug with a known root cause. \" +\n \"You can capture a single text string, or a list of role-based conversation messages.\",\n inputSchema: {\n type: \"object\",\n properties: {\n content: {\n type: \"string\",\n description:\n \"The text to remember. The tool redacts secrets before it stores the text. \" +\n \"Use this for a single message. Use 'messages' instead for a multi-turn conversation.\",\n },\n messages: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n role: {\n type: \"string\",\n description: \"The role of the speaker: 'user' or 'assistant'.\",\n },\n content: {\n type: \"string\",\n description: \"The message content.\",\n },\n },\n required: [\"role\", \"content\"],\n },\n description:\n \"A list of role-based conversation messages to capture. When set, 'content' is ignored. \" +\n \"The tool flattens the messages into a single text for search, and stores the original messages for retrieval.\",\n },\n type: {\n type: \"string\",\n enum: [\"conversation\", \"decision\", \"learning\", \"task\", \"error\", \"atom\"],\n default: \"conversation\",\n description: \"The type of the memory. Defaults to 'conversation' if omitted.\",\n },\n tags: { type: \"array\", items: { type: \"string\" }, description: \"Optional tags.\" },\n session_key: { type: \"string\", description: \"The session key. The default is hash(cwd).\" },\n metadata: { type: \"object\", description: \"Optional metadata.\" },\n verified: {\n type: \"boolean\",\n default: false,\n description:\n \"Set this to true to mark the capture as verified. Verified captures rank higher in recall.\",\n },\n supersedes: {\n type: \"string\",\n description:\n \"The ID of a capture that this one replaces. The old capture is marked as stale and ranks lower.\",\n },\n override_rejection: {\n type: \"boolean\",\n default: false,\n description:\n \"Set this to true to force capture even if the content was previously rejected. Use this only when the rejection reason no longer applies.\",\n },\n format: {\n type: \"string\",\n enum: [\"text\", \"json\"],\n default: \"text\",\n description:\n \"The response format. Use 'json' for structured data (e.g. benchmarks). Defaults to 'text'.\",\n },\n ...TENANT_PARAMS,\n },\n },\n },\n {\n name: \"search\",\n description:\n \"Search memory by keyword or by semantic similarity. \" +\n \"Use this tool when recall is too broad and you need specific facts.\",\n inputSchema: {\n type: \"object\",\n properties: {\n query: { type: \"string\", description: \"The search text.\" },\n mode: {\n type: \"string\",\n enum: [\"hybrid\", \"keyword\", \"vector\"],\n default: \"hybrid\",\n description: \"The search mode.\",\n },\n filters: {\n type: \"object\",\n properties: {\n type: { type: \"string\", description: \"Filter by the memory type.\" },\n tags: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Filter by tags. A capture must have at least one of these tags.\",\n },\n agent_id: {\n type: \"string\",\n description: \"Filter by the agent that captured the memory.\",\n },\n date_from: { type: \"string\", description: \"Filter by date. The format is ISO 8601.\" },\n date_to: { type: \"string\", description: \"Filter by date. The format is ISO 8601.\" },\n team_id: { type: \"string\", description: \"Filter by team ID.\" },\n user_id: { type: \"string\", description: \"Filter by user ID.\" },\n task_id: { type: \"string\", description: \"Filter by task ID.\" },\n },\n },\n limit: { type: \"integer\", default: 20, maximum: 100 },\n format: {\n type: \"string\",\n enum: [\"text\", \"json\"],\n default: \"text\",\n description:\n \"The response format. Use 'json' for structured data (e.g. benchmarks). Defaults to 'text'.\",\n },\n },\n required: [\"query\"],\n },\n },\n {\n name: \"explain_recall\",\n description:\n \"Explain WHY a memory was recalled for a given query. \" +\n \"Shows the BM25 score, vector score, RRF fused score, rank, and matching keywords for each result. \" +\n \"Use this to debug unexpected recall results or to understand the retrieval pipeline. \" +\n \"If you provide a capture_id, the tool explains why that specific capture was or was not retrieved.\",\n inputSchema: {\n type: \"object\",\n properties: {\n query: {\n type: \"string\",\n description: \"The same query you used with recall or search.\",\n },\n capture_id: {\n type: \"string\",\n description:\n \"Optional. The ID of a specific capture to explain. \" +\n \"If set, the tool shows why this capture was or was not in the results.\",\n },\n session_key: {\n type: \"string\",\n description: \"The session key. The default is hash(cwd).\",\n },\n mode: {\n type: \"string\",\n enum: [\"hybrid\", \"keyword\", \"vector\"],\n default: \"hybrid\",\n description: \"The search mode to explain.\",\n },\n limit: {\n type: \"integer\",\n default: 10,\n maximum: 50,\n description: \"The maximum number of results to explain.\",\n },\n ...TENANT_PARAMS,\n },\n required: [\"query\"],\n },\n },\n {\n name: \"related\",\n description:\n \"Find memories connected to a given memory by shared tags, project, or co-occurrence. \" +\n \"Use this after recall or search to discover related context you might have missed. \" +\n \"Inspired by graph spreading-activation (Mnema pattern).\",\n inputSchema: {\n type: \"object\",\n properties: {\n id: {\n type: \"string\",\n description: \"The ID of the capture to find related memories for.\",\n },\n limit: {\n type: \"number\",\n description: \"Maximum number of related memories to return (default: 10).\",\n },\n },\n required: [\"id\"],\n },\n },\n {\n name: \"forget\",\n description:\n \"Delete specific memory entries. Use this tool only when the user requests a deletion. \" +\n \"Do not auto-forget.\",\n inputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"The ID of the capture to delete.\" },\n filter: {\n type: \"object\",\n properties: {\n tags: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Delete all captures that have at least one of these tags.\",\n },\n type: { type: \"string\", description: \"Delete all captures of this type.\" },\n date_before: {\n type: \"string\",\n description: \"Delete all captures before this date. The format is ISO 8601.\",\n },\n team_id: { type: \"string\", description: \"Delete captures from this team only.\" },\n user_id: { type: \"string\", description: \"Delete captures from this user only.\" },\n task_id: { type: \"string\", description: \"Delete captures linked to this task only.\" },\n },\n },\n confirm: {\n type: \"boolean\",\n default: false,\n description: \"Set this to true to execute the deletion.\",\n },\n reject: {\n type: \"boolean\",\n default: false,\n description:\n \"Set this to true to reject the capture instead of deleting it. \" +\n \"The capture is marked as rejected with a reason, and the same content cannot be captured again. \" +\n \"Use this when the memory is wrong, not just outdated.\",\n },\n reason: {\n type: \"string\",\n description:\n \"The reason for rejection. Required when reject is true. The agent stores this with the tombstone.\",\n },\n format: {\n type: \"string\",\n enum: [\"text\", \"json\"],\n default: \"text\",\n description:\n \"The response format. Use 'json' for structured data (e.g. benchmarks). Defaults to 'text'.\",\n },\n },\n },\n },\n {\n name: \"resolve\",\n description:\n \"Resolve a conflict between two captures. Mark one as the winner and the other as stale. \" +\n \"Call this tool when capture reports a conflict between two memories.\",\n inputSchema: {\n type: \"object\",\n properties: {\n winner: {\n type: \"string\",\n description: \"The ID of the capture that is correct. This capture stays active.\",\n },\n loser: {\n type: \"string\",\n description:\n \"The ID of the capture that is wrong or outdated. This capture is marked as stale.\",\n },\n reason: {\n type: \"string\",\n description: \"The reason for the resolution. The agent stores this in the audit log.\",\n },\n },\n required: [\"winner\", \"loser\"],\n },\n },\n {\n name: \"handoff\",\n description:\n \"Write a structured handoff packet for the next agent session. \" +\n \"Call this tool at the end of a session, or before you switch to a different agent. \" +\n \"The next agent calls recall to load this packet and continue without re-reading files. \" +\n \"This saves 60-85% of tokens compared to re-discovering context.\",\n inputSchema: {\n type: \"object\",\n properties: {\n task: {\n type: \"string\",\n description: \"A one-line description of the task.\",\n },\n status: {\n type: \"string\",\n enum: [\"in_progress\", \"blocked\", \"needs_review\", \"done\", \"assigned\"],\n description: \"The current status of the task.\",\n },\n progress: {\n type: \"string\",\n description:\n \"A summary of what has been done so far. Include the root cause if this is a bug fix.\",\n },\n decisions: {\n type: \"array\",\n items: { type: \"string\" },\n description:\n \"A list of decisions made during this session. Include what was chosen and why.\",\n },\n files: {\n type: \"array\",\n items: { type: \"string\" },\n description:\n \"A list of files that matter for this task. Use the format: path:lines - reason.\",\n },\n next_steps: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"A list of next steps for the next agent. Order by priority.\",\n },\n session_key: { type: \"string\", description: \"The session key. The default is hash(cwd).\" },\n ...TENANT_PARAMS,\n },\n required: [\"task\", \"status\", \"progress\"],\n },\n },\n {\n name: \"adr\",\n description:\n \"Record an Architecture Decision Record (ADR). Use this tool when you make a technical decision \" +\n \"that future agents should know about. The ADR is stored as a structured capture and can be \" +\n \"recalled by any agent working on the same project.\",\n inputSchema: {\n type: \"object\",\n properties: {\n title: {\n type: \"string\",\n description: \"A short title for the decision. Example: 'Use SQLite for local storage'.\",\n },\n context: {\n type: \"string\",\n description:\n \"The problem or situation that requires a decision. Why is this decision needed?\",\n },\n decision: {\n type: \"string\",\n description: \"The decision that was made. What was chosen?\",\n },\n alternatives: {\n type: \"array\",\n items: { type: \"string\" },\n description:\n \"Other options that were considered but rejected. Include why each was rejected.\",\n },\n consequences: {\n type: \"string\",\n description:\n \"The consequences of this decision. What are the trade-offs, risks, and benefits?\",\n },\n tags: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Optional tags for filtering. Example: ['arch', 'storage'].\",\n },\n session_key: { type: \"string\", description: \"The session key. The default is hash(cwd).\" },\n ...TENANT_PARAMS,\n },\n required: [\"title\", \"context\", \"decision\"],\n },\n },\n // ─── Knowledge management tools ──────────────────────────────\n {\n name: \"knowledge_create\",\n description:\n \"Register a knowledge asset (wiki or code-graph) for the team. \" +\n \"The asset metadata is stored locally. The actual content is processed by an external knowledge service.\",\n inputSchema: {\n type: \"object\",\n properties: {\n team_id: { type: \"string\", description: \"The team ID.\" },\n name: { type: \"string\", description: \"The asset name.\" },\n type: {\n type: \"string\",\n enum: [\"wiki\", \"code-graph\"],\n description: \"The asset type.\",\n },\n summary: { type: \"string\", description: \"A short description.\" },\n service_url: {\n type: \"string\",\n description: \"The URL of the knowledge service (for example: http://localhost:8424/v3).\",\n },\n repo_url: { type: \"string\", description: \"The repository URL (for code-graph).\" },\n branch: { type: \"string\", description: \"The repository branch (for code-graph).\" },\n },\n required: [\"team_id\", \"name\", \"type\"],\n },\n },\n {\n name: \"knowledge_get\",\n description: \"Get a single knowledge asset by ID.\",\n inputSchema: {\n type: \"object\",\n properties: {\n knowledge_id: { type: \"string\", description: \"The knowledge asset ID.\" },\n },\n required: [\"knowledge_id\"],\n },\n },\n {\n name: \"knowledge_list\",\n description: \"List knowledge assets for a team. Optionally filter by type.\",\n inputSchema: {\n type: \"object\",\n properties: {\n team_id: { type: \"string\", description: \"The team ID.\" },\n type: {\n type: \"string\",\n enum: [\"wiki\", \"code-graph\"],\n description: \"Filter by type.\",\n },\n },\n required: [\"team_id\"],\n },\n },\n {\n name: \"knowledge_delete\",\n description: \"Delete one or more knowledge assets by ID.\",\n inputSchema: {\n type: \"object\",\n properties: {\n knowledge_ids: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"The knowledge asset IDs to delete.\",\n },\n },\n required: [\"knowledge_ids\"],\n },\n },\n // ─── Skill management tools ──────────────────────────────────\n {\n name: \"skill_get\",\n description: \"Get a single skill by ID, including its full content and version.\",\n inputSchema: {\n type: \"object\",\n properties: {\n skill_id: { type: \"string\", description: \"The skill ID.\" },\n },\n required: [\"skill_id\"],\n },\n },\n {\n name: \"skill_list\",\n description: \"List skills bound to a team. Optionally filter by agent.\",\n inputSchema: {\n type: \"object\",\n properties: {\n team_id: { type: \"string\", description: \"The team ID.\" },\n agent_id: {\n type: \"string\",\n description:\n \"Filter by agent ID. When set, returns agent-specific and team-global skills.\",\n },\n },\n required: [\"team_id\"],\n },\n },\n {\n name: \"skill_search\",\n description: \"Search skills by keyword. Returns matching skills with descriptions.\",\n inputSchema: {\n type: \"object\",\n properties: {\n team_id: { type: \"string\", description: \"The team ID.\" },\n agent_id: { type: \"string\", description: \"The agent ID.\" },\n query: { type: \"string\", description: \"The search query.\" },\n topK: {\n type: \"integer\",\n default: 10,\n maximum: 50,\n description: \"The maximum number of results.\",\n },\n },\n required: [\"team_id\", \"agent_id\", \"query\"],\n },\n },\n // ─── CodeGraph tools ───\n {\n name: \"codegraph_index\",\n description:\n \"Index a file or directory into the code graph. Extracts symbols (functions, classes, methods), \" +\n \"call relationships, and imports. Supports TypeScript, JavaScript, Python, Go, Rust, Java, C, C++, C#. \" +\n \"Run this before using codegraph_search, codegraph_callers, codegraph_callees, or codegraph_impact.\",\n inputSchema: {\n type: \"object\",\n properties: {\n path: {\n type: \"string\",\n description:\n \"The file or directory path to index. For directories, all supported files are indexed recursively.\",\n },\n repo_path: {\n type: \"string\",\n description:\n \"The root path of the repository. Used to compute relative file paths. Defaults to the path argument.\",\n },\n team_id: { type: \"string\", description: \"The team ID for isolation.\" },\n max_files: {\n type: \"integer\",\n default: 500,\n maximum: 5000,\n description: \"Maximum number of files to index (for directory mode).\",\n },\n },\n required: [\"path\"],\n },\n },\n {\n name: \"codegraph_search\",\n description:\n \"Search for code symbols by name. Returns matching functions, classes, methods, etc. \" +\n \"with file paths and line numbers. Use this to find where a function or class is defined.\",\n inputSchema: {\n type: \"object\",\n properties: {\n query: { type: \"string\", description: \"The symbol name or pattern to search for.\" },\n kind: {\n type: \"string\",\n description: \"Filter by symbol kind (Function, Class, Method, Struct, etc.).\",\n },\n language: {\n type: \"string\",\n description:\n \"Filter by language (typescript, javascript, python, go, rust, java, c, cpp, csharp).\",\n },\n team_id: { type: \"string\", description: \"The team ID for isolation.\" },\n limit: { type: \"integer\", default: 20, maximum: 100 },\n },\n required: [\"query\"],\n },\n },\n {\n name: \"codegraph_callers\",\n description:\n \"Find all callers of a symbol — who calls this function? \" +\n \"Returns the calling functions with file paths and line numbers. \" +\n \"Requires the symbol ID from codegraph_search.\",\n inputSchema: {\n type: \"object\",\n properties: {\n symbol_id: { type: \"string\", description: \"The symbol ID (from codegraph_search).\" },\n limit: { type: \"integer\", default: 50, maximum: 200 },\n },\n required: [\"symbol_id\"],\n },\n },\n {\n name: \"codegraph_callees\",\n description:\n \"Find all callees of a symbol — what does this function call? \" +\n \"Returns the called functions with file paths and line numbers. \" +\n \"Requires the symbol ID from codegraph_search.\",\n inputSchema: {\n type: \"object\",\n properties: {\n symbol_id: { type: \"string\", description: \"The symbol ID (from codegraph_search).\" },\n limit: { type: \"integer\", default: 50, maximum: 200 },\n },\n required: [\"symbol_id\"],\n },\n },\n {\n name: \"codegraph_impact\",\n description:\n \"Perform impact analysis: if I change this symbol, what else might be affected? \" +\n \"Traverses the call graph upward (callers of callers) to find all potentially impacted code. \" +\n \"Requires the symbol ID from codegraph_search.\",\n inputSchema: {\n type: \"object\",\n properties: {\n symbol_id: { type: \"string\", description: \"The symbol ID (from codegraph_search).\" },\n max_depth: {\n type: \"integer\",\n default: 5,\n maximum: 20,\n description: \"Maximum traversal depth in the call graph.\",\n },\n },\n required: [\"symbol_id\"],\n },\n },\n {\n name: \"codegraph_list\",\n description:\n \"List all symbols in a file or directory. Returns symbols sorted by line number. \" +\n \"Use this to get an overview of what a file contains.\",\n inputSchema: {\n type: \"object\",\n properties: {\n file_path: {\n type: \"string\",\n description: \"The file path (relative to repo root) to list symbols for.\",\n },\n kind: {\n type: \"string\",\n description: \"Filter by symbol kind (Function, Class, Method, etc.).\",\n },\n team_id: { type: \"string\", description: \"The team ID for isolation.\" },\n limit: { type: \"integer\", default: 100, maximum: 500 },\n },\n required: [\"file_path\"],\n },\n },\n // ─── Wiki tools ───\n {\n name: \"wiki_ingest\",\n description:\n \"Ingest markdown documentation files into the wiki. Parses frontmatter, headings, \" +\n \"[[wikilinks]], and [text](url) links to build a structured page graph. \" +\n \"Supports .md and .markdown files.\",\n inputSchema: {\n type: \"object\",\n properties: {\n path: {\n type: \"string\",\n description:\n \"The file or directory path to ingest. For directories, all .md files are indexed recursively.\",\n },\n repo_path: {\n type: \"string\",\n description:\n \"The root path for computing relative file paths. Defaults to the path argument.\",\n },\n team_id: { type: \"string\", description: \"The team ID for isolation.\" },\n max_files: {\n type: \"integer\",\n default: 200,\n maximum: 2000,\n description: \"Maximum number of files to ingest (for directory mode).\",\n },\n },\n required: [\"path\"],\n },\n },\n {\n name: \"wiki_search\",\n description:\n \"Search wiki pages by content. Returns matching pages with title, file path, and a snippet. \" +\n \"Use this to find documentation relevant to a topic.\",\n inputSchema: {\n type: \"object\",\n properties: {\n query: { type: \"string\", description: \"The search query (FTS5 syntax supported).\" },\n team_id: { type: \"string\", description: \"The team ID for isolation.\" },\n limit: { type: \"integer\", default: 10, maximum: 50 },\n },\n required: [\"query\"],\n },\n },\n {\n name: \"wiki_get\",\n description:\n \"Get a wiki page by ID, including its links and backlinks. \" +\n \"Use this to read a specific page and see what it links to and what links to it.\",\n inputSchema: {\n type: \"object\",\n properties: {\n page_id: { type: \"string\", description: \"The page ID (from wiki_search).\" },\n },\n required: [\"page_id\"],\n },\n },\n {\n name: \"wiki_outdated\",\n description:\n \"Find wiki pages whose source file has changed since the last ingest. \" +\n \"Returns pages that need re-ingesting because the source markdown was modified or deleted.\",\n inputSchema: {\n type: \"object\",\n properties: {\n repo_path: { type: \"string\", description: \"The root path to check for source files.\" },\n team_id: { type: \"string\", description: \"The team ID for isolation.\" },\n },\n required: [\"repo_path\"],\n },\n },\n {\n name: \"update\",\n description:\n \"Update an existing memory entry. Use this when a capture needs corrections \" +\n \"(wrong info, missing tags, needs rewording). Preserves the original ID and created_at.\",\n inputSchema: {\n type: \"object\",\n properties: {\n id: {\n type: \"string\",\n description: \"The ID of the capture to update.\",\n },\n content: {\n type: \"string\",\n description: \"The new content. If omitted, the original content is kept.\",\n },\n tags: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"The new tags. Replaces existing tags entirely.\",\n },\n type: {\n type: \"string\",\n enum: [\"conversation\", \"decision\", \"learning\", \"task\", \"error\", \"atom\"],\n description: \"The new type. If omitted, the original type is kept.\",\n },\n verified: {\n type: \"boolean\",\n default: false,\n description: \"Set to true to mark as verified.\",\n },\n },\n required: [\"id\"],\n },\n },\n {\n name: \"consolidate\",\n description:\n \"Find and merge duplicate or near-duplicate memories. \" +\n \"Use this when you suspect redundant captures (e.g. same decision captured twice). \" +\n \"Returns groups of similar captures. Set confirm=true to merge them.\",\n inputSchema: {\n type: \"object\",\n properties: {\n session_key: {\n type: \"string\",\n description:\n \"The session key to consolidate. Default is hash(cwd). Use 'all' for all projects.\",\n },\n threshold: {\n type: \"number\",\n default: 0.75,\n description: \"Similarity threshold (0-1). Higher = stricter matching. Default 0.75.\",\n },\n confirm: {\n type: \"boolean\",\n default: false,\n description: \"Set to true to merge duplicates. Without confirm, returns candidates only.\",\n },\n },\n },\n },\n];\n\n/**\n * All tools available by default. Set TDAI_CORE_ONLY=1 to reduce token\n * overhead by excluding CodeGraph, Wiki, Knowledge, and Skill tools.\n */\nconst CORE_TOOL_NAMES = new Set([\n \"recall\",\n \"capture\",\n \"search\",\n \"forget\",\n \"resolve\",\n \"handoff\",\n \"adr\",\n \"update\",\n \"consolidate\",\n]);\n\nfunction getTools(): Tool[] {\n const coreOnly = process.env.TDAI_CORE_ONLY === \"1\" || process.env.TDAI_CORE_ONLY === \"true\";\n if (coreOnly) return TOOLS.filter((t) => CORE_TOOL_NAMES.has(t.name));\n return TOOLS;\n}\n\n/** Create the MCP server with all tools registered. */\nexport function createServer(opts: ServerOptions): Server {\n const server = new Server(\n {\n name: \"remem-mcp\",\n version: \"0.5.6\",\n },\n {\n capabilities: {\n tools: {},\n resources: {},\n },\n },\n );\n\n server.setRequestHandler(ListToolsRequestSchema, async () => {\n return { tools: getTools() };\n });\n\n server.setRequestHandler(ListResourcesRequestSchema, async () => {\n return {\n resources: [\n {\n uri: \"remem-mcp://recent\",\n name: \"Recent captures\",\n description: \"The 20 most recent memory captures.\",\n mimeType: \"text/plain\",\n },\n {\n uri: \"remem-mcp://stats\",\n name: \"Memory statistics\",\n description: \"Summary statistics for the memory database.\",\n mimeType: \"application/json\",\n },\n ],\n };\n });\n\n server.setRequestHandler(ReadResourceRequestSchema, async (request) => {\n const uri = request.params.uri;\n\n if (uri === \"remem-mcp://recent\") {\n const results = await opts.storage.search(\"\", null, {\n limit: 20,\n offset: 0,\n mode: \"keyword\",\n });\n const text = formatResults(results);\n return {\n contents: [\n {\n uri,\n mimeType: \"text/plain\",\n text: text || \"No captures found.\",\n },\n ],\n };\n }\n\n if (uri === \"remem-mcp://stats\") {\n return {\n contents: [\n {\n uri,\n mimeType: \"application/json\",\n text: JSON.stringify({\n message: \"Use the stats CLI command for full statistics.\",\n hint: \"Run: npx remem-mcp stats\",\n }),\n },\n ],\n };\n }\n\n return {\n contents: [\n {\n uri,\n mimeType: \"text/plain\",\n text: `Unknown resource: ${uri}`,\n },\n ],\n };\n });\n\n server.setRequestHandler(CallToolRequestSchema, async (request) => {\n const name = request.params.name;\n const args = (request.params.arguments ?? {}) as Record<string, unknown>;\n\n switch (name) {\n case \"recall\":\n return handleRecall(args, opts);\n case \"capture\":\n return handleCapture(args, opts);\n case \"search\":\n return handleSearch(args, opts);\n case \"related\":\n return handleRelated(args, opts);\n case \"explain_recall\":\n return handleExplainRecall(args, opts);\n case \"forget\":\n return handleForget(args, opts);\n case \"resolve\":\n return handleResolve(args, opts);\n case \"handoff\":\n return handleHandoff(args, opts);\n case \"adr\":\n return handleAdr(args, opts);\n case \"knowledge_create\":\n return handleKnowledgeCreate(args, opts);\n case \"knowledge_get\":\n return handleKnowledgeGet(args, opts);\n case \"knowledge_list\":\n return handleKnowledgeList(args, opts);\n case \"knowledge_delete\":\n return handleKnowledgeDelete(args, opts);\n case \"skill_get\":\n return handleSkillGet(args, opts);\n case \"skill_list\":\n return handleSkillList(args, opts);\n case \"skill_search\":\n return handleSkillSearch(args, opts);\n case \"codegraph_index\":\n return handleCodegraphIndex(args, opts);\n case \"codegraph_search\":\n return handleCodegraphSearch(args, opts);\n case \"codegraph_callers\":\n return handleCodegraphCallers(args, opts);\n case \"codegraph_callees\":\n return handleCodegraphCallees(args, opts);\n case \"codegraph_impact\":\n return handleCodegraphImpact(args, opts);\n case \"codegraph_list\":\n return handleCodegraphList(args, opts);\n case \"wiki_ingest\":\n return handleWikiIngest(args, opts);\n case \"wiki_search\":\n return handleWikiSearch(args, opts);\n case \"wiki_get\":\n return handleWikiGet(args, opts);\n case \"wiki_outdated\":\n return handleWikiOutdated(args, opts);\n case \"update\":\n return handleUpdate(args, opts);\n case \"consolidate\":\n return handleConsolidate(args, opts);\n default:\n return {\n content: [{ type: \"text\", text: `Error: Unknown tool \"${name}\".` }],\n isError: true,\n };\n }\n });\n\n return server;\n}\n\n/** Extract multi-tenant fields from tool args. */\nfunction extractTenant(args: Record<string, unknown>): {\n teamId?: string;\n agentId?: string;\n userId?: string;\n taskId?: string;\n} {\n return {\n teamId: args.team_id as string | undefined,\n agentId: args.agent_id as string | undefined,\n userId: args.user_id as string | undefined,\n taskId: args.task_id as string | undefined,\n };\n}\n\n/** Handle the recall tool. */\nasync function handleRecall(\n args: Record<string, unknown>,\n opts: ServerOptions,\n): Promise<{ content: Array<{ type: \"text\"; text: string }>; isError?: boolean }> {\n const query = args.query as string;\n const sessionKey = (args.session_key as string) ?? defaultSessionKey();\n const limit = Math.min((args.limit as number) ?? 10, 50);\n const offset = (args.offset as number) ?? 0;\n const tokenCap = Math.min((args.max_tokens as number) ?? opts.maxTokensRecall, 8000);\n const mode = (args.mode as SearchMode) ?? \"hybrid\";\n const { teamId, userId, taskId } = extractTenant(args);\n const agentId = (args.agent_id as string) ?? undefined;\n\n let queryEmbedding: number[] | null = null;\n let vectorDegraded = false;\n if (mode === \"hybrid\" || mode === \"vector\") {\n try {\n queryEmbedding = await opts.embedder.embed(query);\n } catch (err) {\n console.error(`[remem-mcp] Embedding failed: ${err}`);\n vectorDegraded = true;\n }\n }\n\n // If TDAI_GLOBAL_SESSION_KEY is set and session_key wasn't explicitly provided,\n // search both global and project session keys, global first.\n const globalKey = globalSessionKey();\n const useGlobalFallback = globalKey && !args.session_key && globalKey !== sessionKey;\n\n let results: SearchResult[];\n if (useGlobalFallback) {\n // Search global memory first (rules, learnings, cross-project decisions)\n const globalResults = await opts.storage.search(query, queryEmbedding, {\n sessionKey: globalKey,\n limit: Math.ceil(limit / 2),\n offset: 0,\n mode,\n filters: { teamId, userId, taskId, agentId },\n });\n // Then search project memory\n const projectResults = await opts.storage.search(query, queryEmbedding, {\n sessionKey,\n limit: limit - globalResults.length,\n offset: 0,\n mode,\n filters: { teamId, userId, taskId, agentId },\n });\n // Merge: global first, then project (dedup by id)\n const seen = new Set(globalResults.map((r) => r.id));\n results = [...globalResults, ...projectResults.filter((r) => !seen.has(r.id))];\n } else {\n results = await opts.storage.search(query, queryEmbedding, {\n sessionKey,\n limit,\n offset,\n mode,\n filters: { teamId, userId, taskId, agentId },\n });\n }\n\n let text = formatResults(results);\n\n // Augment with CodeGraph symbols if available\n try {\n const db = getDb(opts);\n const symbols = cgSearchSymbols(db, query, { teamId, limit: 5 });\n if (symbols.length > 0) {\n const symLines = symbols.map(\n (s) => ` ${s.kind} ${s.name} at ${s.filePath}:${s.lineStart}`,\n );\n text += `\\n\\n## Code symbols\\n${symLines.join(\"\\n\")}`;\n }\n } catch {\n // CodeGraph not available (non-SQLite backend)\n }\n\n // Augment with Wiki pages if available\n try {\n const db = getDb(opts);\n const wikiResults = wikiSearch(db, query, { teamId, limit: 3 });\n if (wikiResults.length > 0) {\n const wikiLines = wikiResults.map(\n (w) => ` ${w.title} (${w.sourceFile}) ${w.snippet.slice(0, 80)}`,\n );\n text += `\\n\\n## Wiki pages\\n${wikiLines.join(\"\\n\")}`;\n }\n } catch {\n // Wiki not available (non-SQLite backend)\n }\n\n if (vectorDegraded) {\n text = `[note: vector search unavailable, results are keyword-only]\\n${text}`;\n }\n const { text: finalText, quotaHit } = enforceQuota(text, tokenCap);\n\n opts.audit.log({\n tool: \"recall\",\n argsHash: AuditLogger.hashArgs({ query, limit, offset, mode, teamId, userId, taskId }),\n resultLen: finalText.length,\n quotaHit,\n redacted: false,\n });\n\n return { content: [{ type: \"text\", text: finalText }] };\n}\n\n/** Handle the capture tool. */\nasync function handleCapture(\n args: Record<string, unknown>,\n opts: ServerOptions,\n): Promise<{ content: Array<{ type: \"text\"; text: string }>; isError?: boolean }> {\n const type = (args.type as CaptureType) ?? \"conversation\";\n const tags = (args.tags as string[]) ?? [];\n const sessionKey = (args.session_key as string) ?? defaultSessionKey();\n const metadata = args.metadata as Record<string, unknown> | undefined;\n const { teamId, userId, taskId } = extractTenant(args);\n const agentId = (args.agent_id as string) ?? detectAgentId();\n const verified = (args.verified as boolean) ?? false;\n const supersedes = args.supersedes as string | undefined;\n const overrideRejection = (args.override_rejection as boolean) ?? false;\n const format = (args.format as \"text\" | \"json\") ?? \"text\";\n\n // Build content from either 'content' or 'messages'\n let content: string;\n let messages: CaptureMessage[] | undefined;\n const rawMessages = args.messages as CaptureMessage[] | undefined;\n\n if (rawMessages && rawMessages.length > 0) {\n messages = rawMessages;\n content = rawMessages.map((m) => `${m.role}: ${m.content}`).join(\"\\n\");\n } else {\n content = args.content as string;\n if (!content) {\n return {\n content: [\n {\n type: \"text\",\n text: \"Error: Provide either 'content' or 'messages'.\",\n },\n ],\n isError: true,\n };\n }\n }\n\n if (!checkContentLength(content, opts.maxContentLength)) {\n return {\n content: [\n {\n type: \"text\",\n text: `Error: The content exceeds the maximum length of ${opts.maxContentLength} characters.`,\n },\n ],\n isError: true,\n };\n }\n\n const { text: redactedContent, redacted: wasRedacted } = opts.redactSecrets\n ? redact(content)\n : { text: content, redacted: false };\n\n const contentHash = createHash(\"sha256\").update(redactedContent).digest(\"hex\");\n\n // Rejected-value tombstone: check if this content was previously rejected.\n if (!overrideRejection) {\n const rejected = await opts.storage.findRejectedByContentHash(contentHash, sessionKey);\n if (rejected.length > 0) {\n const reason = rejected[0].rejectionReason ?? \"no reason given\";\n opts.audit.log({\n tool: \"capture\",\n argsHash: AuditLogger.hashArgs({ type, tags, sessionKey, teamId, userId, taskId }),\n resultLen: 0,\n quotaHit: false,\n redacted: wasRedacted,\n });\n return {\n content: [\n {\n type: \"text\",\n text: `Blocked: This content was previously rejected (${rejected[0].id}). Reason: ${reason}. Set override_rejection to true to force capture.`,\n },\n ],\n isError: true,\n };\n }\n }\n\n // Dedup: check if content with the same hash already exists in this session.\n const existing = await opts.storage.findByContentHash(contentHash, sessionKey);\n if (existing.length > 0) {\n opts.audit.log({\n tool: \"capture\",\n argsHash: AuditLogger.hashArgs({ type, tags, sessionKey, teamId, userId, taskId }),\n resultLen: existing[0].id.length,\n quotaHit: false,\n redacted: wasRedacted,\n });\n return {\n content: [\n {\n type: \"text\",\n text: `Duplicate: ${existing[0].id} (content already captured)`,\n },\n ],\n };\n }\n\n const id = generateId();\n const trustState: TrustState = verified ? \"verified\" : \"candidate\";\n\n const entry: CaptureEntry = {\n id,\n sessionKey,\n agentId,\n type,\n content: redactedContent,\n tags,\n createdAt: Date.now(),\n metadata,\n teamId,\n userId,\n taskId,\n messages: messages ?? undefined,\n trustState,\n };\n\n try {\n await opts.storage.put(entry);\n } catch {\n return {\n content: [\n {\n type: \"text\",\n text: `Error: Database is read-only (sandbox restriction). Capture failed. Set sandbox_mode to \"danger-full-access\" or add the DB directory to writable roots.`,\n },\n ],\n isError: true,\n };\n }\n\n // If supersedes is set, mark the old capture as stale.\n if (supersedes) {\n await opts.storage.supersede(supersedes, id);\n }\n\n let embedding: number[] | null = null;\n try {\n embedding = await opts.embedder.embed(redactedContent);\n await opts.storage.putVector(id, embedding);\n } catch (err) {\n console.error(`[remem-mcp] Embedding failed: ${err}`);\n }\n\n // Conflict detection: find similar captures in the same session.\n let conflictInfo = \"\";\n let conflictIds: string[] = [];\n if (embedding) {\n try {\n const conflicts = await opts.storage.findConflicts(embedding, sessionKey, 0.8);\n const filtered = conflicts.filter((c) => c.id !== id);\n conflictIds = filtered.map((c) => c.id);\n if (filtered.length > 0) {\n const conflictList = filtered\n .map(\n (c) =>\n ` - ${c.id} (similarity: ${(1 - c.distance).toFixed(2)}, state: ${c.trustState}): ${c.content.slice(0, 120)}`,\n )\n .join(\"\\n\");\n conflictInfo = `\\nConflicts detected:\\n${conflictList}\\nCall resolve to mark one as superseding the other.`;\n }\n } catch (err) {\n console.error(`[remem-mcp] Conflict detection failed: ${err}`);\n }\n }\n\n if (opts.pipeline.name !== \"noop\") {\n try {\n await opts.pipeline.process(\n { id, content: redactedContent, type, tags, sessionKey, teamId, userId, taskId },\n { ...opts.pipelineCtx, sessionKey },\n );\n } catch (err) {\n console.error(`[remem-mcp] Pipeline failed: ${err}`);\n }\n }\n\n opts.audit.log({\n tool: \"capture\",\n argsHash: AuditLogger.hashArgs({ type, tags, sessionKey, teamId, userId, taskId }),\n resultLen: id.length,\n quotaHit: false,\n redacted: wasRedacted,\n });\n\n if (format === \"json\") {\n return {\n content: [\n {\n type: \"text\",\n text: JSON.stringify({\n id,\n content: redactedContent,\n type,\n tags,\n created_at: new Date(entry.createdAt).toISOString(),\n verified: trustState === \"verified\",\n conflicts: conflictInfo ? conflictInfo.trim() : undefined,\n conflict_ids: conflictIds.length > 0 ? conflictIds : undefined,\n }),\n },\n ],\n };\n }\n\n const redactionNote = wasRedacted ? \" (secrets were redacted)\" : \"\";\n const msgNote = messages ? ` (${messages.length} messages)` : \"\";\n const trustNote = trustState === \"verified\" ? \" [verified]\" : \"\";\n const supersedesNote = supersedes ? ` (supersedes ${supersedes})` : \"\";\n return {\n content: [\n {\n type: \"text\",\n text: `Captured: ${id}${redactionNote}${msgNote}${trustNote}${supersedesNote}${conflictInfo}`,\n },\n ],\n };\n}\n\n/** Handle the search tool. */\nasync function handleSearch(\n args: Record<string, unknown>,\n opts: ServerOptions,\n): Promise<{ content: Array<{ type: \"text\"; text: string }>; isError?: boolean }> {\n const query = args.query as string;\n const mode = (args.mode as SearchMode) ?? \"hybrid\";\n const format = (args.format as \"text\" | \"json\") ?? \"text\";\n const filters = args.filters as\n | {\n type?: CaptureType;\n tags?: string[];\n agent_id?: string;\n date_from?: string;\n date_to?: string;\n team_id?: string;\n user_id?: string;\n task_id?: string;\n }\n | undefined;\n const limit = Math.min((args.limit as number) ?? 20, 500);\n\n let queryEmbedding: number[] | null = null;\n let vectorDegraded = false;\n if (mode === \"hybrid\" || mode === \"vector\") {\n try {\n queryEmbedding = await opts.embedder.embed(query);\n } catch (err) {\n console.error(`[remem-mcp] Embedding failed: ${err}`);\n vectorDegraded = true;\n }\n }\n\n const results = await opts.storage.search(query, queryEmbedding, {\n sessionKey: (args.session_key as string) ?? defaultSessionKey(),\n limit,\n offset: 0,\n mode,\n filters: filters\n ? {\n type: filters.type,\n tags: filters.tags,\n agentId: filters.agent_id,\n dateFrom: filters.date_from,\n dateTo: filters.date_to,\n teamId: filters.team_id,\n userId: filters.user_id,\n taskId: filters.task_id,\n }\n : undefined,\n });\n\n if (format === \"json\") {\n // Atom-aware search: if atoms exist for a capture, use the atom fact as\n // content instead of the raw capture. This ensures current-state facts\n // (e.g., \"Migrated database to Turso\") replace raw migration text that\n // contains old values (e.g., \"from SQLite to Turso\").\n const atomMap = new Map<string, string>();\n for (const r of results) {\n try {\n const atoms = await opts.pipelineCtx.storage.listAtoms({ captureId: r.entry.id, limit: 5 });\n if (atoms.length > 0) {\n atomMap.set(r.entry.id, atoms.map((a) => a.fact).join(\" | \"));\n }\n } catch {}\n }\n const jsonResults = results.map((r) => ({\n id: r.entry.id,\n content: atomMap.get(r.entry.id) ?? r.entry.content,\n score: r.score,\n type: r.entry.type,\n tags: r.entry.tags,\n created_at: new Date(r.entry.createdAt).toISOString(),\n trust_state: r.entry.trustState ?? \"candidate\",\n }));\n const jsonText = JSON.stringify(jsonResults);\n opts.audit.log({\n tool: \"search\",\n argsHash: AuditLogger.hashArgs({ query, mode, filters }),\n resultLen: jsonText.length,\n quotaHit: false,\n redacted: false,\n });\n return { content: [{ type: \"text\", text: jsonText }] };\n }\n\n let text = formatResults(results);\n if (vectorDegraded) {\n text = `[note: vector search unavailable, results are keyword-only]\\n${text}`;\n }\n const { text: finalText, quotaHit } = enforceQuota(text, opts.maxTokensSearch);\n\n opts.audit.log({\n tool: \"search\",\n argsHash: AuditLogger.hashArgs({ query, mode, filters }),\n resultLen: finalText.length,\n quotaHit,\n redacted: false,\n });\n\n return { content: [{ type: \"text\", text: finalText }] };\n}\n\n/**\n * Handle the related tool.\n * Finds memories connected to a given capture by shared tags, project (session_key),\n * or type. Inspired by Mnema's graph spreading-activation.\n *\n * Scoring: +3 for each shared tag, +2 for same session_key, +1 for same type.\n * Excludes the source capture itself.\n */\nasync function handleRelated(\n args: Record<string, unknown>,\n opts: ServerOptions,\n): Promise<{ content: Array<{ type: \"text\"; text: string }>; isError?: boolean }> {\n const id = args.id as string;\n const limit = Math.min((args.limit as number) ?? 10, 50);\n\n // Get the source capture\n const source = await opts.storage.get(id);\n if (!source) {\n return {\n content: [{ type: \"text\", text: `Capture ${id} not found.` }],\n isError: true,\n };\n }\n\n const sourceTags = source.tags ?? [];\n const sourceSessionKey = source.sessionKey;\n const sourceType = source.type;\n\n // Build candidate pool: search by tags + by content keywords.\n // listByTags bypasses FTS5 — direct SQL on tags column.\n const candidateMap = new Map<\n string,\n { entry: CaptureEntry; score: number; reasons: Set<string> }\n >();\n\n // Search by tags (if any) — direct SQL, no FTS5\n if (sourceTags.length > 0) {\n const tagMatches = await opts.storage.listByTags(sourceTags.slice(0, 10), 100);\n for (const entry of tagMatches) {\n if (entry.id === id) continue;\n const entryTags = entry.tags ?? [];\n const sharedTags = sourceTags.filter((t: string) => entryTags.includes(t));\n const tagScore = sharedTags.length * 3;\n const existing = candidateMap.get(entry.id);\n if (existing) {\n existing.score += tagScore;\n for (const t of sharedTags) existing.reasons.add(`tag: ${t}`);\n } else {\n candidateMap.set(entry.id, {\n entry,\n score: tagScore,\n reasons: new Set(sharedTags.map((t: string) => `tag: ${t}`)),\n });\n }\n }\n }\n\n // Also search by content keywords (broader net)\n const contentResults = await opts.storage.search(source.content.slice(0, 200), null, {\n limit: 100,\n offset: 0,\n mode: \"keyword\",\n });\n for (const r of contentResults) {\n if (r.entry.id === id) continue;\n const existing = candidateMap.get(r.entry.id);\n if (existing) {\n existing.score += Math.min(r.score, 5);\n existing.reasons.add(\"content overlap\");\n } else {\n candidateMap.set(r.entry.id, {\n entry: r.entry,\n score: Math.min(r.score, 5),\n reasons: new Set([\"content overlap\"]),\n });\n }\n }\n\n // Score: add same project and same type bonuses\n const scored: Array<{ entry: CaptureEntry; score: number; reasons: string[] }> = [];\n for (const { entry, score, reasons } of candidateMap.values()) {\n let finalScore = score;\n const reasonList = [...reasons];\n\n // Same project (session_key)\n if (sourceSessionKey && entry.sessionKey === sourceSessionKey) {\n finalScore += 2;\n reasonList.push(\"same project\");\n }\n\n // Same type\n if (sourceType && entry.type === sourceType) {\n finalScore += 1;\n reasonList.push(`same type: ${entry.type}`);\n }\n\n if (finalScore > 0) {\n scored.push({ entry, score: finalScore, reasons: reasonList });\n }\n }\n\n // Sort by score, take top N\n scored.sort((a, b) => b.score - a.score);\n const top = scored.slice(0, limit);\n\n if (top.length === 0) {\n return {\n content: [\n {\n type: \"text\",\n text: `No related memories found for capture ${id}.\\n\\nSource: ${source.content.slice(0, 100)}...`,\n },\n ],\n };\n }\n\n // Format output\n const lines: string[] = [\n `Related memories for capture ${id}:`,\n `Source: [${source.type}] ${source.content.slice(0, 100)}...`,\n \"\",\n ];\n\n for (const { entry, score, reasons } of top) {\n const date = new Date(entry.createdAt).toISOString().split(\"T\")[0];\n const preview = entry.content.slice(0, 120).replace(/\\n/g, \" \");\n lines.push(`- [${entry.type}] ${date} (score=${score}, ${reasons.join(\"; \")})`);\n lines.push(` ${preview}...`);\n if (entry.tags && entry.tags.length > 0) {\n lines.push(` tags: ${entry.tags.join(\", \")}`);\n }\n lines.push(` id: ${entry.id}`);\n lines.push(\"\");\n }\n\n lines.push(`Found ${top.length} related memor${top.length === 1 ? \"y\" : \"ies\"}.`);\n\n opts.audit.log({\n tool: \"related\",\n argsHash: AuditLogger.hashArgs({ id, limit }),\n resultLen: lines.join(\"\\n\").length,\n quotaHit: false,\n redacted: false,\n });\n\n return { content: [{ type: \"text\", text: lines.join(\"\\n\") }] };\n}\n\n/**\n * Handle the explain_recall tool.\n * Shows WHY each result was recalled: BM25 score, vector score, RRF fused score,\n * rank, and matching keywords. If capture_id is provided, explains why that\n * specific capture was or was not retrieved.\n */\nasync function handleExplainRecall(\n args: Record<string, unknown>,\n opts: ServerOptions,\n): Promise<{ content: Array<{ type: \"text\"; text: string }>; isError?: boolean }> {\n const query = args.query as string;\n const captureId = args.capture_id as string | undefined;\n const sessionKey = (args.session_key as string) ?? defaultSessionKey();\n const mode = (args.mode as SearchMode) ?? \"hybrid\";\n const limit = Math.min((args.limit as number) ?? 10, 50);\n const { teamId, userId, taskId } = extractTenant(args);\n\n // Run keyword and vector searches separately to get individual scores\n let queryEmbedding: number[] | null = null;\n let vectorDegraded = false;\n if (mode === \"hybrid\" || mode === \"vector\") {\n try {\n queryEmbedding = await opts.embedder.embed(query);\n } catch (err) {\n console.error(`[remem-mcp] Embedding failed: ${err}`);\n vectorDegraded = true;\n }\n }\n\n // Get keyword-only results\n const keywordResults: SearchResult[] =\n mode === \"vector\"\n ? []\n : await opts.storage.search(query, null, {\n sessionKey,\n limit: limit * 3,\n offset: 0,\n mode: \"keyword\",\n filters: { teamId, userId, taskId },\n });\n\n // Get vector-only results\n const vectorResults: SearchResult[] =\n mode === \"keyword\" || !queryEmbedding\n ? []\n : await opts.storage.search(query, queryEmbedding, {\n sessionKey,\n limit: limit * 3,\n offset: 0,\n mode: \"vector\",\n filters: { teamId, userId, taskId },\n });\n\n // Get hybrid results (what recall actually returns)\n const hybridResults: SearchResult[] = await opts.storage.search(query, queryEmbedding, {\n sessionKey,\n limit,\n offset: 0,\n mode,\n filters: { teamId, userId, taskId },\n });\n\n // Build score lookup maps\n const keywordScores = new Map<string, number>();\n for (const r of keywordResults) keywordScores.set(r.entry.id, r.score);\n\n const vectorScores = new Map<string, number>();\n for (const r of vectorResults) vectorScores.set(r.entry.id, r.score);\n\n // Extract query keywords (simple tokenization)\n const queryTokens = query\n .toLowerCase()\n .split(/[^a-z0-9]+/)\n .filter((t) => t.length > 2);\n\n // Build explanation\n const lines: string[] = [\n `## explain_recall: \"${query}\"`,\n `Mode: ${mode}${vectorDegraded ? \" (vector degraded — keyword only)\" : \"\"}`,\n `Session: ${sessionKey}`,\n `Query tokens: ${queryTokens.join(\", \") || \"(none)\"}`,\n \"\",\n `### Top ${hybridResults.length} results (ranked by ${mode} score):`,\n \"\",\n ];\n\n for (let i = 0; i < hybridResults.length; i++) {\n const { entry, score } = hybridResults[i];\n const bm25Score = keywordScores.get(entry.id);\n const vecScore = vectorScores.get(entry.id);\n const date = new Date(entry.createdAt).toISOString().split(\"T\")[0];\n\n lines.push(`[${i + 1}] id: ${entry.id}`);\n lines.push(` type: ${entry.type} date: ${date} tags: [${entry.tags.join(\", \")}]`);\n lines.push(` fused_score: ${score.toFixed(4)}`);\n if (mode === \"hybrid\") {\n lines.push(\n ` bm25_score: ${bm25Score !== undefined ? bm25Score.toFixed(4) : \"not in top-k (0)\"}`,\n );\n lines.push(\n ` vector_score: ${vecScore !== undefined ? vecScore.toFixed(4) : \"not in top-k (0)\"}`,\n );\n } else if (mode === \"keyword\") {\n lines.push(` bm25_score: ${score.toFixed(4)}`);\n } else {\n lines.push(` vector_score: ${score.toFixed(4)}`);\n }\n\n // Show which query tokens appear in the content\n const contentLower = entry.content.toLowerCase();\n const matchedTokens = queryTokens.filter((t) => contentLower.includes(t));\n const missedTokens = queryTokens.filter((t) => !contentLower.includes(t));\n if (matchedTokens.length > 0) {\n lines.push(` matched_keywords: ${matchedTokens.join(\", \")}`);\n }\n if (missedTokens.length > 0) {\n lines.push(` missed_keywords: ${missedTokens.join(\", \")}`);\n }\n\n // Show trust state if not candidate\n if (entry.trustState && entry.trustState !== \"candidate\") {\n lines.push(` trust_state: ${entry.trustState}`);\n }\n\n // Show content preview (first 120 chars)\n const preview = entry.content.slice(0, 120).replace(/\\n/g, \" \");\n lines.push(` content_preview: ${preview}${entry.content.length > 120 ? \"...\" : \"\"}`);\n lines.push(\"\");\n }\n\n // If capture_id was provided, explain why that specific capture was or wasn't retrieved\n if (captureId) {\n lines.push(`### Explanation for capture: ${captureId}`);\n lines.push(\"\");\n\n const inResults = hybridResults.find((r) => r.entry.id === captureId);\n if (inResults) {\n const rank = hybridResults.findIndex((r) => r.entry.id === captureId) + 1;\n lines.push(`✓ This capture WAS retrieved at rank ${rank}/${hybridResults.length}.`);\n lines.push(` fused_score: ${inResults.score.toFixed(4)}`);\n const bm25 = keywordScores.get(captureId);\n const vec = vectorScores.get(captureId);\n if (bm25 !== undefined) lines.push(` bm25_score: ${bm25.toFixed(4)}`);\n if (vec !== undefined) lines.push(` vector_score: ${vec.toFixed(4)}`);\n } else {\n lines.push(`✗ This capture was NOT in the top ${limit} results.`);\n\n // Check if it exists at all\n const entry = await opts.storage.get(captureId);\n if (!entry) {\n lines.push(` Reason: capture not found in the database.`);\n } else {\n lines.push(` The capture exists in the database but was not retrieved.`);\n lines.push(` type: ${entry.type} session: ${entry.sessionKey}`);\n const bm25 = keywordScores.get(captureId);\n const vec = vectorScores.get(captureId);\n if (bm25 === undefined && vec === undefined) {\n lines.push(\n ` Reason: low relevance — neither BM25 nor vector search ranked it in top ${limit * 3}.`,\n );\n } else {\n if (bm25 !== undefined) lines.push(` bm25_score: ${bm25.toFixed(4)} (below threshold)`);\n if (vec !== undefined) lines.push(` vector_score: ${vec.toFixed(4)} (below threshold)`);\n }\n\n // Check session mismatch\n if (entry.sessionKey !== sessionKey) {\n lines.push(\n ` Possible reason: session mismatch — capture is in session ${entry.sessionKey}, query was for session ${sessionKey}.`,\n );\n }\n\n // Check trust state\n if (entry.trustState === \"rejected\") {\n lines.push(` Possible reason: capture is rejected (trust_state=rejected).`);\n }\n if (entry.trustState === \"stale\") {\n lines.push(` Possible reason: capture is stale (trust_state=stale).`);\n }\n }\n }\n lines.push(\"\");\n }\n\n // Summary stats\n lines.push(\"### Summary\");\n lines.push(`keyword_results: ${keywordResults.length}`);\n lines.push(`vector_results: ${vectorResults.length}`);\n lines.push(`hybrid_results: ${hybridResults.length}`);\n if (vectorDegraded) {\n lines.push(`note: vector search was unavailable — results are keyword-only.`);\n }\n\n const text = lines.join(\"\\n\");\n\n opts.audit.log({\n tool: \"explain_recall\",\n argsHash: AuditLogger.hashArgs({ query, capture_id: captureId, mode, limit }),\n resultLen: text.length,\n quotaHit: false,\n redacted: false,\n });\n\n return { content: [{ type: \"text\", text }] };\n}\n\n/** Handle the forget tool. */\nasync function handleForget(\n args: Record<string, unknown>,\n opts: ServerOptions,\n): Promise<{ content: Array<{ type: \"text\"; text: string }>; isError?: boolean }> {\n const id = args.id as string | undefined;\n const filter = args.filter as DeleteFilter | undefined;\n // When id is provided, default confirm to true (for MCP adapter compatibility)\n const confirm = (args.confirm as boolean) ?? (id ? true : false);\n const reject = (args.reject as boolean) ?? false;\n const reason = args.reason as string | undefined;\n const format = (args.format as \"text\" | \"json\") ?? \"text\";\n\n if (!confirm) {\n return {\n content: [\n {\n type: \"text\",\n text: \"Error: Set confirm to true to execute the deletion. The tool did not delete anything.\",\n },\n ],\n isError: true,\n };\n }\n\n if (reject && !reason) {\n return {\n content: [\n {\n type: \"text\",\n text: \"Error: When reject is true, provide a reason. The tool did not delete anything.\",\n },\n ],\n isError: true,\n };\n }\n\n if (reject && !id) {\n return {\n content: [\n {\n type: \"text\",\n text: \"Error: When reject is true, provide an id. Reject mode does not support filters.\",\n },\n ],\n isError: true,\n };\n }\n\n let result: DeleteResult;\n if (reject && id) {\n result = await opts.storage.reject(id, reason ?? \"\");\n } else if (id) {\n result = await opts.storage.delete(id);\n } else if (filter) {\n result = await opts.storage.deleteByFilter(filter);\n } else {\n return {\n content: [\n {\n type: \"text\",\n text: \"Error: Provide an id or a filter. The tool did not delete anything.\",\n },\n ],\n isError: true,\n };\n }\n\n opts.audit.log({\n tool: \"forget\",\n argsHash: AuditLogger.hashArgs({ id, filter, reject, reason }),\n resultLen: null,\n quotaHit: false,\n redacted: false,\n mutation: { id, filter, captures: result.captures, reject, reason },\n });\n\n const action = reject ? \"Rejected\" : \"Deleted\";\n if (format === \"json\") {\n return {\n content: [\n {\n type: \"text\",\n text: JSON.stringify({\n deleted: true,\n id: id ?? null,\n action: action.toLowerCase(),\n captures: result.captures,\n atoms: result.atoms,\n scenarios: result.scenarios,\n }),\n },\n ],\n };\n }\n return {\n content: [\n {\n type: \"text\",\n text: `${action}: ${result.captures} captures, ${result.atoms} atoms, ${result.scenarios} scenarios`,\n },\n ],\n };\n}\n\n/** Handle the update tool. */\nasync function handleUpdate(\n args: Record<string, unknown>,\n opts: ServerOptions,\n): Promise<{ content: Array<{ type: \"text\"; text: string }>; isError?: boolean }> {\n const id = args.id as string;\n if (!id) {\n return { content: [{ type: \"text\", text: \"Error: id is required.\" }], isError: true };\n }\n\n const db = getDb(opts);\n const row = db.prepare(\"SELECT * FROM captures WHERE id = ? AND deleted_at IS NULL\").get(id) as\n | Record<string, unknown>\n | undefined;\n if (!row) {\n return { content: [{ type: \"text\", text: `Error: Capture ${id} not found.` }], isError: true };\n }\n\n const newContent = (args.content as string) ?? (row.content as string);\n const newTags = args.tags ? JSON.stringify(args.tags) : (row.tags as string);\n const newType = (args.type as string) ?? (row.type as string);\n const newTrust = args.verified ? \"verified\" : (row.trust_state as string);\n\n // Update content hash\n const contentHash = createHash(\"sha256\").update(newContent).digest(\"hex\");\n\n db.prepare(\n \"UPDATE captures SET content = ?, tags = ?, type = ?, trust_state = ?, content_hash = ? WHERE id = ?\",\n ).run(newContent, newTags, newType, newTrust, contentHash, id);\n\n // Update FTS index\n const rowid =\n (row.rowid as number) ?? db.prepare(\"SELECT rowid FROM captures WHERE id = ?\").get(id)?.rowid;\n if (rowid) {\n db.prepare(\n \"INSERT INTO captures_fts(captures_fts, rowid, content, tags, type) VALUES('delete', ?, '', '', '')\",\n ).run(rowid);\n db.prepare(\n \"INSERT INTO captures_fts (rowid, id, content, tags, type) VALUES (?, ?, ?, ?, ?)\",\n ).run(rowid, id, newContent, newTags, newType);\n }\n\n return {\n content: [{ type: \"text\", text: `Updated: ${id}\\nType: ${newType}\\nTrust: ${newTrust}` }],\n };\n}\n\n/** Handle the consolidate tool. */\nasync function handleConsolidate(\n args: Record<string, unknown>,\n opts: ServerOptions,\n): Promise<{ content: Array<{ type: \"text\"; text: string }>; isError?: boolean }> {\n const threshold = (args.threshold as number) ?? 0.75;\n const confirm = (args.confirm as boolean) ?? false;\n const sessionKey = (args.session_key as string) ?? defaultSessionKey();\n const db = getDb(opts);\n\n // Get all non-deleted captures for the session (or all if session_key === \"all\")\n let sql = \"SELECT id, content, type, tags, created_at FROM captures WHERE deleted_at IS NULL\";\n const params: unknown[] = [];\n if (sessionKey !== \"all\") {\n sql += \" AND session_key = ?\";\n params.push(sessionKey);\n }\n sql += \" ORDER BY created_at DESC\";\n const rows = db.prepare(sql).all(...params) as {\n id: string;\n content: string;\n type: string;\n tags: string;\n created_at: number;\n }[];\n\n if (rows.length < 2) {\n return {\n content: [{ type: \"text\", text: \"Not enough captures to consolidate (need at least 2).\" }],\n };\n }\n\n // Find duplicates by comparing content similarity (Jaccard on word sets)\n const groups: { ids: string[]; similarity: number; preview: string }[] = [];\n const seen = new Set<string>();\n\n for (let i = 0; i < rows.length; i++) {\n if (seen.has(rows[i].id)) continue;\n const words1 = new Set(rows[i].content.toLowerCase().split(/\\s+/));\n const group = [rows[i].id];\n\n for (let j = i + 1; j < rows.length; j++) {\n if (seen.has(rows[j].id)) continue;\n const words2 = new Set(rows[j].content.toLowerCase().split(/\\s+/));\n const intersection = [...words1].filter((w) => words2.has(w)).length;\n const union = new Set([...words1, ...words2]).size;\n const sim = union > 0 ? intersection / union : 0;\n if (sim >= threshold) {\n group.push(rows[j].id);\n seen.add(rows[j].id);\n }\n }\n\n if (group.length > 1) {\n seen.add(rows[i].id);\n groups.push({\n ids: group,\n similarity: threshold,\n preview: rows[i].content.slice(0, 80).replace(/\\n/g, \" \"),\n });\n }\n }\n\n if (groups.length === 0) {\n return {\n content: [\n {\n type: \"text\",\n text: `No duplicates found (threshold: ${threshold}). ${rows.length} captures checked.`,\n },\n ],\n };\n }\n\n if (!confirm) {\n const lines: string[] = [\n `Found ${groups.length} duplicate group(s) (threshold: ${threshold}):`,\n ];\n for (const g of groups) {\n lines.push(`\\n Group (${g.ids.length} captures): ${g.preview}...`);\n for (const id of g.ids) {\n lines.push(` - ${id}`);\n }\n }\n lines.push(\"\\nSet confirm=true to merge (keeps oldest, deletes rest).\");\n return { content: [{ type: \"text\", text: lines.join(\"\\n\") }] };\n }\n\n // Merge: keep the oldest capture, soft-delete the rest\n let merged = 0;\n for (const g of groups) {\n // Sort by created_at ascending (oldest first)\n const groupRows = g.ids\n .map((id) => rows.find((r) => r.id === id))\n .filter(Boolean)\n .sort((a, b) => a!.created_at - b!.created_at);\n const keeper = groupRows[0]!;\n const dups = groupRows.slice(1);\n for (const dup of dups) {\n db.prepare(\"UPDATE captures SET deleted_at = ? WHERE id = ?\").run(Date.now(), dup.id);\n db.prepare(\"DELETE FROM captures_vec WHERE id = ?\").run(dup.id);\n merged++;\n }\n // Log the merge\n void keeper;\n }\n\n return {\n content: [\n {\n type: \"text\",\n text: `Consolidated ${groups.length} group(s), merged ${merged} duplicate(s). Kept oldest capture in each group.`,\n },\n ],\n };\n}\n\n/** Handle the resolve tool. */\nasync function handleResolve(\n args: Record<string, unknown>,\n opts: ServerOptions,\n): Promise<{ content: Array<{ type: \"text\"; text: string }>; isError?: boolean }> {\n const winner = args.winner as string;\n const loser = args.loser as string;\n const reason = args.reason as string | undefined;\n\n if (!winner || !loser) {\n return {\n content: [\n {\n type: \"text\",\n text: \"Error: Provide both winner and loser IDs.\",\n },\n ],\n isError: true,\n };\n }\n\n if (winner === loser) {\n return {\n content: [\n {\n type: \"text\",\n text: \"Error: The winner and loser cannot be the same capture.\",\n },\n ],\n isError: true,\n };\n }\n\n const result = await opts.storage.supersede(loser, winner);\n\n if (result.updated === 0) {\n return {\n content: [\n {\n type: \"text\",\n text: `Error: Capture ${loser} was not found or is already rejected.`,\n },\n ],\n isError: true,\n };\n }\n\n opts.audit.log({\n tool: \"resolve\",\n argsHash: AuditLogger.hashArgs({ winner, loser, reason }),\n resultLen: null,\n quotaHit: false,\n redacted: false,\n mutation: { winner, loser, reason },\n });\n\n return {\n content: [\n {\n type: \"text\",\n text: `Resolved: ${loser} is now stale (superseded by ${winner}).${reason ? ` Reason: ${reason}` : \"\"}`,\n },\n ],\n };\n}\n\n/** Handle the handoff tool. Creates a structured handoff packet for the next agent. */\nasync function handleHandoff(\n args: Record<string, unknown>,\n opts: ServerOptions,\n): Promise<{ content: Array<{ type: \"text\"; text: string }>; isError?: boolean }> {\n const task = args.task as string;\n const status = args.status as string;\n const progress = args.progress as string;\n const decisions = (args.decisions as string[]) ?? [];\n const files = (args.files as string[]) ?? [];\n const nextSteps = (args.next_steps as string[]) ?? [];\n const sessionKey = (args.session_key as string) ?? defaultSessionKey();\n const { teamId, userId, taskId } = extractTenant(args);\n const agentId = (args.agent_id as string) ?? detectAgentId();\n\n const lines: string[] = [];\n lines.push(`# Handoff: ${task}`);\n lines.push(`Status: ${status}`);\n lines.push(`Date: ${new Date().toISOString()}`);\n lines.push(\"\");\n lines.push(\"## Progress\");\n lines.push(progress);\n lines.push(\"\");\n\n if (decisions.length > 0) {\n lines.push(\"## Decisions\");\n for (const d of decisions) {\n lines.push(`- ${d}`);\n }\n lines.push(\"\");\n }\n\n if (files.length > 0) {\n lines.push(\"## Files\");\n for (const f of files) {\n lines.push(`- ${f}`);\n }\n lines.push(\"\");\n }\n\n // Add code symbols for the touched files if CodeGraph is available\n try {\n const db = getDb(opts);\n const allSyms: string[] = [];\n for (const f of files.slice(0, 10)) {\n const syms = cgListSymbols(db, f, { teamId, limit: 5 });\n for (const s of syms) {\n allSyms.push(`- ${f}:${s.lineStart} ${s.kind} ${s.name}`);\n }\n }\n if (allSyms.length > 0) {\n lines.push(\"## Code symbols\");\n lines.push(...allSyms.slice(0, 20));\n lines.push(\"\");\n }\n } catch {\n // CodeGraph not available\n }\n\n if (nextSteps.length > 0) {\n lines.push(\"## Next steps\");\n for (let i = 0; i < nextSteps.length; i++) {\n lines.push(`${i + 1}. ${nextSteps[i]}`);\n }\n lines.push(\"\");\n }\n\n const content = lines.join(\"\\n\");\n\n if (!checkContentLength(content, opts.maxContentLength)) {\n return {\n content: [\n {\n type: \"text\",\n text: `Error: The handoff packet exceeds the maximum length of ${opts.maxContentLength} characters.`,\n },\n ],\n isError: true,\n };\n }\n\n const dedupPayload = JSON.stringify({ task, status, progress, decisions, files, nextSteps });\n const contentHash = createHash(\"sha256\").update(dedupPayload).digest(\"hex\");\n const existing = await opts.storage.findByContentHash(contentHash, sessionKey);\n if (existing.length > 0) {\n return {\n content: [\n {\n type: \"text\",\n text: `Duplicate handoff: ${existing[0].id} (same content already captured)`,\n },\n ],\n };\n }\n\n const id = generateId();\n\n const entry: CaptureEntry = {\n id,\n sessionKey,\n agentId,\n type: \"task\",\n content,\n tags: [\"handoff\", `status:${status}`],\n createdAt: Date.now(),\n metadata: {\n handoff: true,\n task,\n status,\n progress,\n decisions,\n files,\n nextSteps,\n },\n contentHash,\n teamId,\n userId,\n taskId,\n };\n\n await opts.storage.put(entry);\n\n try {\n const embedding = await opts.embedder.embed(content);\n await opts.storage.putVector(id, embedding);\n } catch (err) {\n console.error(`[remem-mcp] Embedding failed: ${err}`);\n }\n\n opts.audit.log({\n tool: \"handoff\",\n argsHash: AuditLogger.hashArgs({ task, status, teamId, userId, taskId }),\n resultLen: id.length,\n quotaHit: false,\n redacted: false,\n });\n\n return {\n content: [\n {\n type: \"text\",\n text: `Handoff saved: ${id}\\nStatus: ${status}\\nNext agent: call recall with query \"${task}\" to load this packet.`,\n },\n ],\n };\n}\n\n/** Handle the adr tool. Records an Architecture Decision Record as a structured capture. */\nasync function handleAdr(\n args: Record<string, unknown>,\n opts: ServerOptions,\n): Promise<{ content: Array<{ type: \"text\"; text: string }>; isError?: boolean }> {\n const title = args.title as string;\n const context = args.context as string;\n const decision = args.decision as string;\n const alternativesRaw = args.alternatives as string[] | string | undefined;\n const alternatives = Array.isArray(alternativesRaw)\n ? alternativesRaw\n : typeof alternativesRaw === \"string\" && alternativesRaw\n ? [alternativesRaw]\n : [];\n const consequences = (args.consequences as string) ?? \"\";\n const tags = (args.tags as string[]) ?? [];\n const sessionKey = (args.session_key as string) ?? defaultSessionKey();\n const { teamId, userId, taskId } = extractTenant(args);\n const agentId = (args.agent_id as string) ?? detectAgentId();\n\n const lines: string[] = [];\n lines.push(`# ADR: ${title}`);\n lines.push(`Date: ${new Date().toISOString()}`);\n lines.push(\"\");\n lines.push(\"## Context\");\n lines.push(context);\n lines.push(\"\");\n lines.push(\"## Decision\");\n lines.push(decision);\n lines.push(\"\");\n\n if (alternatives.length > 0) {\n lines.push(\"## Alternatives considered\");\n for (const alt of alternatives) {\n lines.push(`- ${alt}`);\n }\n lines.push(\"\");\n }\n\n if (consequences) {\n lines.push(\"## Consequences\");\n lines.push(consequences);\n lines.push(\"\");\n }\n\n const content = lines.join(\"\\n\");\n\n if (!checkContentLength(content, opts.maxContentLength)) {\n return {\n content: [\n {\n type: \"text\",\n text: `Error: The ADR exceeds the maximum length of ${opts.maxContentLength} characters.`,\n },\n ],\n isError: true,\n };\n }\n\n const dedupPayload = JSON.stringify({ title, context, decision, alternatives, consequences });\n const contentHash = createHash(\"sha256\").update(dedupPayload).digest(\"hex\");\n const existing = await opts.storage.findByContentHash(contentHash, sessionKey);\n if (existing.length > 0) {\n return {\n content: [\n {\n type: \"text\",\n text: `Duplicate ADR: ${existing[0].id} (same decision already recorded)`,\n },\n ],\n };\n }\n\n const id = generateId();\n const allTags = [\"adr\", ...tags];\n\n const entry: CaptureEntry = {\n id,\n sessionKey,\n agentId,\n type: \"decision\",\n content,\n tags: allTags,\n createdAt: Date.now(),\n metadata: {\n adr: true,\n title,\n context,\n decision,\n alternatives,\n consequences,\n },\n contentHash,\n teamId,\n userId,\n taskId,\n };\n\n await opts.storage.put(entry);\n\n try {\n const embedding = await opts.embedder.embed(content);\n await opts.storage.putVector(id, embedding);\n } catch (err) {\n console.error(`[remem-mcp] Embedding failed: ${err}`);\n }\n\n opts.audit.log({\n tool: \"adr\",\n argsHash: AuditLogger.hashArgs({ title, decision, teamId, userId, taskId }),\n resultLen: id.length,\n quotaHit: false,\n redacted: false,\n });\n\n return {\n content: [\n {\n type: \"text\",\n text: `ADR saved: ${id}\\nTitle: ${title}\\nRecall with: recall({ query: \"${title}\" })`,\n },\n ],\n };\n}\n\n// ─── Knowledge handlers ────────────────────────────────────────\n\nasync function handleKnowledgeCreate(\n args: Record<string, unknown>,\n opts: ServerOptions,\n): Promise<{ content: Array<{ type: \"text\"; text: string }>; isError?: boolean }> {\n const teamId = args.team_id as string;\n const name = args.name as string;\n const type = args.type as string;\n const summary = args.summary as string | undefined;\n const serviceUrl = args.service_url as string | undefined;\n const repoUrl = args.repo_url as string | undefined;\n const branch = args.branch as string | undefined;\n\n const id = generateId();\n const entry: KnowledgeEntry = {\n id,\n teamId,\n name,\n type,\n summary,\n serviceUrl,\n repoUrl,\n branch,\n createdAt: Date.now(),\n };\n\n await opts.storage.putKnowledge(entry);\n\n opts.audit.log({\n tool: \"knowledge_create\",\n argsHash: AuditLogger.hashArgs({ teamId, name, type }),\n resultLen: id.length,\n quotaHit: false,\n redacted: false,\n });\n\n return { content: [{ type: \"text\", text: `Knowledge created: ${id} (${type}: ${name})` }] };\n}\n\nasync function handleKnowledgeGet(\n args: Record<string, unknown>,\n opts: ServerOptions,\n): Promise<{ content: Array<{ type: \"text\"; text: string }>; isError?: boolean }> {\n const knowledgeId = args.knowledge_id as string;\n const entry = await opts.storage.getKnowledge(knowledgeId);\n if (!entry) {\n return {\n content: [{ type: \"text\", text: `Error: Knowledge asset ${knowledgeId} not found.` }],\n isError: true,\n };\n }\n return { content: [{ type: \"text\", text: JSON.stringify(entry, null, 2) }] };\n}\n\nasync function handleKnowledgeList(\n args: Record<string, unknown>,\n opts: ServerOptions,\n): Promise<{ content: Array<{ type: \"text\"; text: string }>; isError?: boolean }> {\n const teamId = args.team_id as string;\n const type = args.type as string | undefined;\n const entries = await opts.storage.listKnowledge(teamId, type);\n if (entries.length === 0) {\n return { content: [{ type: \"text\", text: \"No knowledge assets found.\" }] };\n }\n const lines = entries.map(\n (e) => `- ${e.id} [${e.type}] ${e.name}${e.summary ? ` — ${e.summary}` : \"\"}`,\n );\n return { content: [{ type: \"text\", text: lines.join(\"\\n\") }] };\n}\n\nasync function handleKnowledgeDelete(\n args: Record<string, unknown>,\n opts: ServerOptions,\n): Promise<{ content: Array<{ type: \"text\"; text: string }>; isError?: boolean }> {\n const knowledgeIds = args.knowledge_ids as string[];\n const count = await opts.storage.deleteKnowledge(knowledgeIds);\n opts.audit.log({\n tool: \"knowledge_delete\",\n argsHash: AuditLogger.hashArgs({ knowledgeIds }),\n resultLen: null,\n quotaHit: false,\n redacted: false,\n });\n return { content: [{ type: \"text\", text: `Deleted ${count} knowledge asset(s).` }] };\n}\n\n// ─── Skill handlers ────────────────────────────────────────────\n\nasync function handleSkillGet(\n args: Record<string, unknown>,\n opts: ServerOptions,\n): Promise<{ content: Array<{ type: \"text\"; text: string }>; isError?: boolean }> {\n const skillId = args.skill_id as string;\n const entry = await opts.storage.getSkill(skillId);\n if (!entry) {\n return {\n content: [{ type: \"text\", text: `Error: Skill ${skillId} not found.` }],\n isError: true,\n };\n }\n return { content: [{ type: \"text\", text: JSON.stringify(entry, null, 2) }] };\n}\n\nasync function handleSkillList(\n args: Record<string, unknown>,\n opts: ServerOptions,\n): Promise<{ content: Array<{ type: \"text\"; text: string }>; isError?: boolean }> {\n const teamId = args.team_id as string;\n const agentId = args.agent_id as string | undefined;\n const entries = await opts.storage.listSkills(teamId, agentId);\n if (entries.length === 0) {\n return { content: [{ type: \"text\", text: \"No skills found.\" }] };\n }\n const lines = entries.map(\n (e) => `- ${e.id} v${e.version} ${e.name}${e.description ? ` — ${e.description}` : \"\"}`,\n );\n return { content: [{ type: \"text\", text: lines.join(\"\\n\") }] };\n}\n\nasync function handleSkillSearch(\n args: Record<string, unknown>,\n opts: ServerOptions,\n): Promise<{ content: Array<{ type: \"text\"; text: string }>; isError?: boolean }> {\n const teamId = args.team_id as string;\n const agentId = args.agent_id as string;\n const query = args.query as string;\n const topK = (args.topK as number) ?? 10;\n const entries = await opts.storage.searchSkills(teamId, agentId, query, topK);\n if (entries.length === 0) {\n return { content: [{ type: \"text\", text: \"No matching skills found.\" }] };\n }\n const lines = entries.map(\n (e) => `- ${e.id} v${e.version} ${e.name}${e.description ? ` — ${e.description}` : \"\"}`,\n );\n return { content: [{ type: \"text\", text: lines.join(\"\\n\") }] };\n}\n\n// ─── CodeGraph handlers ───\n\n/** Get the raw database from storage (SQLiteBackend only). */\nfunction getDb(opts: ServerOptions): import(\"better-sqlite3\").Database {\n const storage = opts.storage as unknown as {\n getDatabase?: () => import(\"better-sqlite3\").Database;\n };\n if (!storage.getDatabase) {\n throw new Error(\"CodeGraph requires SQLite storage backend.\");\n }\n return storage.getDatabase();\n}\n\nasync function handleCodegraphIndex(\n args: Record<string, unknown>,\n opts: ServerOptions,\n): Promise<{ content: Array<{ type: \"text\"; text: string }>; isError?: boolean }> {\n const path = args.path as string;\n const repoPath = (args.repo_path as string) ?? path;\n const teamId = (args.team_id as string) ?? null;\n const maxFiles = (args.max_files as number) ?? 500;\n\n if (!path) {\n return { content: [{ type: \"text\", text: \"Error: path is required.\" }], isError: true };\n }\n\n const db = getDb(opts);\n const { statSync } = await import(\"node:fs\");\n let stat: ReturnType<typeof statSync>;\n try {\n stat = statSync(path);\n } catch {\n return { content: [{ type: \"text\", text: `Error: path not found: ${path}` }], isError: true };\n }\n\n let results: import(\"./codegraph/engine.js\").IndexResult[];\n if (stat.isDirectory()) {\n results = await cgIndexDirectory(db, path, repoPath, teamId, maxFiles);\n } else {\n const result = await cgIndexFile(db, path, repoPath, teamId);\n results = [result];\n }\n\n const indexed = results.filter((r) => !r.skipped);\n const skipped = results.filter((r) => r.skipped);\n const totalSymbols = indexed.reduce((s, r) => s + r.symbols, 0);\n const totalCalls = indexed.reduce((s, r) => s + r.calls, 0);\n const totalImports = indexed.reduce((s, r) => s + r.imports, 0);\n\n const lines = [\n `Indexed ${indexed.length} file(s) (${skipped.length} skipped).`,\n `Symbols: ${totalSymbols} Calls: ${totalCalls} Imports: ${totalImports}`,\n \"\",\n ...indexed\n .slice(0, 20)\n .map(\n (r) =>\n ` ${r.language.padEnd(12)} ${r.symbols.toString().padStart(3)} sym ${r.calls.toString().padStart(4)} calls ${r.file}`,\n ),\n ];\n if (indexed.length > 20) {\n lines.push(` ... and ${indexed.length - 20} more files.`);\n }\n return { content: [{ type: \"text\", text: lines.join(\"\\n\") }] };\n}\n\nfunction handleCodegraphSearch(\n args: Record<string, unknown>,\n opts: ServerOptions,\n): { content: Array<{ type: \"text\"; text: string }>; isError?: boolean } {\n const query = args.query as string;\n const kind = args.kind as string | undefined;\n const language = args.language as string | undefined;\n const teamId = (args.team_id as string) ?? undefined;\n const limit = (args.limit as number) ?? 20;\n\n if (!query) {\n return { content: [{ type: \"text\", text: \"Error: query is required.\" }], isError: true };\n }\n\n const db = getDb(opts);\n const symbols = cgSearchSymbols(db, query, { teamId, kind, language, limit });\n\n if (symbols.length === 0) {\n return { content: [{ type: \"text\", text: \"No symbols found.\" }] };\n }\n\n const lines = symbols.map(\n (s) => `${s.id} ${s.kind.padEnd(10)} ${s.name} at ${s.filePath}:${s.lineStart}`,\n );\n return {\n content: [{ type: \"text\", text: `Found ${symbols.length} symbol(s):\\n${lines.join(\"\\n\")}` }],\n };\n}\n\nfunction handleCodegraphCallers(\n args: Record<string, unknown>,\n opts: ServerOptions,\n): { content: Array<{ type: \"text\"; text: string }>; isError?: boolean } {\n const symbolId = args.symbol_id as string;\n const limit = (args.limit as number) ?? 50;\n\n if (!symbolId) {\n return { content: [{ type: \"text\", text: \"Error: symbol_id is required.\" }], isError: true };\n }\n\n const db = getDb(opts);\n const callers = cgFindCallers(db, symbolId, { limit });\n\n if (callers.length === 0) {\n return { content: [{ type: \"text\", text: \"No callers found.\" }] };\n }\n\n const lines = callers.map(\n (c) =>\n `${c.caller.id} ${c.caller.kind.padEnd(10)} ${c.caller.name} calls at ${c.caller.filePath}:${c.line}`,\n );\n return {\n content: [{ type: \"text\", text: `Found ${callers.length} caller(s):\\n${lines.join(\"\\n\")}` }],\n };\n}\n\nfunction handleCodegraphCallees(\n args: Record<string, unknown>,\n opts: ServerOptions,\n): { content: Array<{ type: \"text\"; text: string }>; isError?: boolean } {\n const symbolId = args.symbol_id as string;\n const limit = (args.limit as number) ?? 50;\n\n if (!symbolId) {\n return { content: [{ type: \"text\", text: \"Error: symbol_id is required.\" }], isError: true };\n }\n\n const db = getDb(opts);\n const callees = cgFindCallees(db, symbolId, { limit });\n\n if (callees.length === 0) {\n return { content: [{ type: \"text\", text: \"No callees found.\" }] };\n }\n\n const lines = callees.map(\n (c) =>\n `${c.calleeName}${c.callee ? ` -> ${c.callee.kind} ${c.callee.name} at ${c.callee.filePath}:${c.callee.lineStart}` : \" (unresolved)\"}`,\n );\n return {\n content: [{ type: \"text\", text: `Found ${callees.length} callee(s):\\n${lines.join(\"\\n\")}` }],\n };\n}\n\nfunction handleCodegraphImpact(\n args: Record<string, unknown>,\n opts: ServerOptions,\n): { content: Array<{ type: \"text\"; text: string }>; isError?: boolean } {\n const symbolId = args.symbol_id as string;\n const maxDepth = (args.max_depth as number) ?? 5;\n\n if (!symbolId) {\n return { content: [{ type: \"text\", text: \"Error: symbol_id is required.\" }], isError: true };\n }\n\n const db = getDb(opts);\n let impact: import(\"./codegraph/engine.js\").ImpactResult;\n try {\n impact = cgImpactAnalysis(db, symbolId, { maxDepth });\n } catch (e) {\n return { content: [{ type: \"text\", text: `Error: ${(e as Error).message}` }], isError: true };\n }\n\n const lines = [\n `Root: ${impact.rootSymbol.kind} ${impact.rootSymbol.name} at ${impact.rootSymbol.filePath}:${impact.rootSymbol.lineStart}`,\n `Affected: ${impact.affected.length} symbol(s)`,\n \"\",\n ...impact.affected.map(\n (a) =>\n `${\" \".repeat(a.depth)}-> ${a.symbol.kind} ${a.symbol.name} at ${a.symbol.filePath}:${a.symbol.lineStart} (depth ${a.depth})`,\n ),\n ];\n return { content: [{ type: \"text\", text: lines.join(\"\\n\") }] };\n}\n\nfunction handleCodegraphList(\n args: Record<string, unknown>,\n opts: ServerOptions,\n): { content: Array<{ type: \"text\"; text: string }>; isError?: boolean } {\n const filePath = args.file_path as string;\n const kind = args.kind as string | undefined;\n const teamId = (args.team_id as string) ?? undefined;\n const limit = (args.limit as number) ?? 100;\n\n if (!filePath) {\n return { content: [{ type: \"text\", text: \"Error: file_path is required.\" }], isError: true };\n }\n\n const db = getDb(opts);\n const symbols = cgListSymbols(db, filePath, { teamId, kind, limit });\n\n if (symbols.length === 0) {\n return { content: [{ type: \"text\", text: \"No symbols found.\" }] };\n }\n\n const lines = symbols.map(\n (s) => `${s.id} ${s.kind.padEnd(10)} L${s.lineStart}-${s.lineEnd} ${s.name}`,\n );\n return {\n content: [\n {\n type: \"text\",\n text: `Found ${symbols.length} symbol(s) in ${filePath}:\\n${lines.join(\"\\n\")}`,\n },\n ],\n };\n}\n\n// ─── Wiki handlers ───\n\nasync function handleWikiIngest(\n args: Record<string, unknown>,\n opts: ServerOptions,\n): Promise<{ content: Array<{ type: \"text\"; text: string }>; isError?: boolean }> {\n const path = args.path as string;\n const repoPath = (args.repo_path as string) ?? path;\n const teamId = (args.team_id as string) ?? null;\n const maxFiles = (args.max_files as number) ?? 200;\n\n if (!path) {\n return { content: [{ type: \"text\", text: \"Error: path is required.\" }], isError: true };\n }\n\n const db = getDb(opts);\n const { statSync } = await import(\"node:fs\");\n let stat: ReturnType<typeof statSync>;\n try {\n stat = statSync(path);\n } catch {\n return { content: [{ type: \"text\", text: `Error: path not found: ${path}` }], isError: true };\n }\n\n let results: import(\"./wiki/engine.js\").WikiIngestResult[];\n if (stat.isDirectory()) {\n results = wikiIngestDir(db, path, repoPath, teamId, maxFiles);\n } else {\n const result = wikiIngestFile(db, path, repoPath, teamId);\n results = [result];\n }\n\n const ingested = results.filter((r) => !r.skipped);\n const skipped = results.filter((r) => r.skipped);\n const totalPages = ingested.reduce((s, r) => s + r.pages, 0);\n const totalLinks = ingested.reduce((s, r) => s + r.links, 0);\n\n const lines = [\n `Ingested ${totalPages} page(s) from ${ingested.length} file(s) (${skipped.length} skipped).`,\n `Links: ${totalLinks}`,\n \"\",\n ...ingested.slice(0, 20).map((r) => ` ${r.pages} page ${r.links} links ${r.file}`),\n ];\n if (ingested.length > 20) {\n lines.push(` ... and ${ingested.length - 20} more files.`);\n }\n return { content: [{ type: \"text\", text: lines.join(\"\\n\") }] };\n}\n\nfunction handleWikiSearch(\n args: Record<string, unknown>,\n opts: ServerOptions,\n): { content: Array<{ type: \"text\"; text: string }>; isError?: boolean } {\n const query = args.query as string;\n const teamId = (args.team_id as string) ?? undefined;\n const limit = (args.limit as number) ?? 10;\n\n if (!query) {\n return { content: [{ type: \"text\", text: \"Error: query is required.\" }], isError: true };\n }\n\n const db = getDb(opts);\n const results = wikiSearch(db, query, { teamId, limit });\n\n if (results.length === 0) {\n return { content: [{ type: \"text\", text: \"No pages found.\" }] };\n }\n\n const lines = results.map((r) => `${r.id} ${r.title} (${r.sourceFile})\\n ${r.snippet}`);\n return {\n content: [{ type: \"text\", text: `Found ${results.length} page(s):\\n${lines.join(\"\\n\")}` }],\n };\n}\n\nfunction handleWikiGet(\n args: Record<string, unknown>,\n opts: ServerOptions,\n): { content: Array<{ type: \"text\"; text: string }>; isError?: boolean } {\n const pageId = args.page_id as string;\n\n if (!pageId) {\n return { content: [{ type: \"text\", text: \"Error: page_id is required.\" }], isError: true };\n }\n\n const db = getDb(opts);\n const result = wikiGet(db, pageId);\n\n if (!result) {\n return { content: [{ type: \"text\", text: \"Page not found.\" }], isError: true };\n }\n\n const { page, links, backlinks } = result;\n const lines = [\n `Title: ${page.title}`,\n `Source: ${page.sourceFile}`,\n `Tags: ${page.tags ?? \"(none)\"}`,\n \"\",\n page.content.slice(0, 500) + (page.content.length > 500 ? \"...\" : \"\"),\n \"\",\n `Links (${links.length}):`,\n ...links.map(\n (l) =>\n ` -> ${l.toTitle}${l.toPageId ? \" (resolved)\" : \" (unresolved)\"} [${l.linkType}] L${l.line}`,\n ),\n \"\",\n `Backlinks (${backlinks.length}):`,\n ...backlinks.map((l) => ` <- ${l.toTitle} [${l.linkType}] L${l.line}`),\n ];\n return { content: [{ type: \"text\", text: lines.join(\"\\n\") }] };\n}\n\nasync function handleWikiOutdated(\n args: Record<string, unknown>,\n opts: ServerOptions,\n): Promise<{ content: Array<{ type: \"text\"; text: string }>; isError?: boolean }> {\n const repoPath = args.repo_path as string;\n const teamId = (args.team_id as string) ?? undefined;\n\n if (!repoPath) {\n return { content: [{ type: \"text\", text: \"Error: repo_path is required.\" }], isError: true };\n }\n\n const db = getDb(opts);\n const outdated = wikiOutdated(db, repoPath, { teamId });\n\n if (outdated.length === 0) {\n return { content: [{ type: \"text\", text: \"All pages are up to date.\" }] };\n }\n\n const lines = outdated.map((o) => `${o.id} ${o.title} (${o.sourceFile}) — ${o.reason}`);\n return {\n content: [\n { type: \"text\", text: `Found ${outdated.length} outdated page(s):\\n${lines.join(\"\\n\")}` },\n ],\n };\n}\n","import { estimateTokens, truncateToTokens } from \"../utils/tokenize.js\";\n\n/** Quota enforcement result. */\nexport interface QuotaResult {\n /** The text, possibly truncated. */\n text: string;\n /** Whether the quota cap was reached. */\n quotaHit: boolean;\n}\n\n/** Enforce a token quota on a text. If the text exceeds the cap, truncate it and append a hint. */\nexport function enforceQuota(text: string, maxTokens: number): QuotaResult {\n const tokens = estimateTokens(text);\n if (tokens <= maxTokens) {\n return { text, quotaHit: false };\n }\n\n const truncated = truncateToTokens(text, maxTokens);\n const hint =\n \"\\n\\n[... The result was truncated. Use the search tool with a more specific query to drill down.]\";\n return {\n text: truncated + hint,\n quotaHit: true,\n };\n}\n\n/** Check if the content length is within the limit. */\nexport function checkContentLength(content: string, maxLength: number): boolean {\n return content.length <= maxLength;\n}\n","/**\n * Estimate the token count from text length.\n * Heuristic: 1 token = 4 characters.\n * This is not exact, but it is close enough for the quota cap.\n */\nexport function estimateTokens(text: string): number {\n return Math.ceil(text.length / 4);\n}\n\n/**\n * Truncate text to a maximum number of tokens.\n * Uses the same heuristic: 1 token = 4 characters.\n */\nexport function truncateToTokens(text: string, maxTokens: number): string {\n const maxChars = maxTokens * 4;\n if (text.length <= maxChars) return text;\n return text.slice(0, maxChars);\n}\n","import type { SearchResult } from \"../storage/types.js\";\n\n/** Format search results into a readable text block. */\nexport function formatResults(results: SearchResult[]): string {\n if (results.length === 0) {\n return \"No memory found for this query.\";\n }\n\n const lines: string[] = [];\n for (let i = 0; i < results.length; i++) {\n const { entry, score } = results[i];\n const date = new Date(entry.createdAt).toISOString();\n const tags = entry.tags.length > 0 ? ` tags: [${entry.tags.join(\", \")}]` : \"\";\n const scoreStr = Number.isNaN(score) ? \"N/A\" : score.toFixed(4);\n lines.push(\n `[${i + 1}] id: ${entry.id} type: ${entry.type}${tags} ${date} score: ${scoreStr}`,\n );\n lines.push(` ${entry.content}`);\n lines.push(\"\");\n }\n\n return lines.join(\"\\n\");\n}\n","import Database from \"better-sqlite3\";\n\ninterface TypeCount {\n type: string;\n count: number;\n}\n\n/** Print memory statistics: total captures, breakdown by type, top tags, sessions. */\nexport function stats(dbPath: string): void {\n const db = new Database(dbPath, { readonly: true });\n\n const total = db.prepare(\"SELECT COUNT(*) as count FROM captures\").get() as { count: number };\n\n if (total.count === 0) {\n console.log(\"No captures found. The database is empty.\");\n db.close();\n return;\n }\n\n console.log(`\\nMemory statistics`);\n console.log(`=================`);\n console.log(`Database: ${dbPath}`);\n console.log(`Total captures: ${total.count}`);\n\n // Breakdown by type\n const byType = db\n .prepare(\"SELECT type, COUNT(*) as count FROM captures GROUP BY type ORDER BY count DESC\")\n .all() as TypeCount[];\n\n console.log(`\\nBy type:`);\n const typeBar = Math.max(...byType.map((t) => t.count));\n for (const row of byType) {\n const bar = \"█\".repeat(Math.round((row.count / typeBar) * 20));\n console.log(` ${row.type.padEnd(14)} ${String(row.count).padStart(4)} ${bar}`);\n }\n\n // Top tags\n const allTags = db\n .prepare(\"SELECT tags FROM captures WHERE tags IS NOT NULL AND tags != '[]'\")\n .all() as { tags: string }[];\n\n const tagCounts = new Map<string, number>();\n for (const row of allTags) {\n try {\n const tags = JSON.parse(row.tags) as string[];\n for (const tag of tags) {\n tagCounts.set(tag, (tagCounts.get(tag) ?? 0) + 1);\n }\n } catch {\n // Skip invalid JSON\n }\n }\n\n if (tagCounts.size > 0) {\n const topTags = [...tagCounts.entries()].sort((a, b) => b[1] - a[1]).slice(0, 15);\n\n console.log(`\\nTop tags:`);\n const maxCount = topTags[0][1];\n for (const [tag, count] of topTags) {\n const bar = \"█\".repeat(Math.round((count / maxCount) * 20));\n console.log(` ${tag.padEnd(20)} ${String(count).padStart(4)} ${bar}`);\n }\n }\n\n // Sessions\n const sessions = db\n .prepare(\"SELECT COUNT(DISTINCT session_key) as count FROM captures\")\n .get() as { count: number };\n console.log(`\\nSessions: ${sessions.count}`);\n\n // Agents\n const agents = db\n .prepare(\n \"SELECT agent_id, COUNT(*) as count FROM captures GROUP BY agent_id ORDER BY count DESC\",\n )\n .all() as TypeCount[];\n if (agents.length > 0) {\n console.log(`\\nBy agent:`);\n for (const row of agents) {\n console.log(` ${row.agent_id.padEnd(14)} ${String(row.count).padStart(4)}`);\n }\n }\n\n // Date range\n const range = db\n .prepare(\"SELECT MIN(created_at) as min, MAX(created_at) as max FROM captures\")\n .get() as { min: number; max: number };\n\n if (range.min && range.max) {\n const minDate = new Date(range.min).toISOString().split(\"T\")[0];\n const maxDate = new Date(range.max).toISOString().split(\"T\")[0];\n console.log(`\\nDate range: ${minDate} to ${maxDate}`);\n }\n\n // L0 vs L1\n const l0 = db.prepare(\"SELECT COUNT(*) as count FROM captures WHERE type != 'atom'\").get() as {\n count: number;\n };\n const l1 = db.prepare(\"SELECT COUNT(*) as count FROM captures WHERE type = 'atom'\").get() as {\n count: number;\n };\n\n if (l1.count > 0) {\n console.log(`\\nLayer breakdown:`);\n console.log(` L0 (raw): ${String(l0.count).padStart(4)}`);\n console.log(` L1 (atoms): ${String(l1.count).padStart(4)}`);\n }\n\n // L1 atoms table (populated by pipeline)\n try {\n const atomsCount = db.prepare(\"SELECT COUNT(*) as count FROM atoms\").get() as { count: number };\n if (atomsCount.count > 0) {\n console.log(` L1 (atoms table): ${String(atomsCount.count).padStart(4)}`);\n }\n } catch {\n // atoms table may not exist in old databases\n }\n\n // L2 scenarios\n try {\n const scenariosCount = db.prepare(\"SELECT COUNT(*) as count FROM scenarios\").get() as {\n count: number;\n };\n if (scenariosCount.count > 0) {\n console.log(` L2 (scenarios): ${String(scenariosCount.count).padStart(4)}`);\n }\n } catch {\n // scenarios table may not exist in old databases\n }\n\n // Messages\n try {\n const msgCount = db.prepare(\"SELECT COUNT(*) as count FROM messages\").get() as {\n count: number;\n };\n if (msgCount.count > 0) {\n console.log(`\\nMessages: ${msgCount.count}`);\n }\n } catch {\n // messages table may not exist in old databases\n }\n\n // Multi-tenant: teams\n try {\n const teamsCount = db\n .prepare(\"SELECT COUNT(DISTINCT team_id) as count FROM captures WHERE team_id IS NOT NULL\")\n .get() as { count: number };\n if (teamsCount.count > 0) {\n console.log(`\\nTeams: ${teamsCount.count}`);\n const teamBreakdown = db\n .prepare(\n \"SELECT team_id, COUNT(*) as count FROM captures WHERE team_id IS NOT NULL GROUP BY team_id ORDER BY count DESC\",\n )\n .all() as TypeCount[];\n for (const row of teamBreakdown) {\n console.log(` ${row.team_id.padEnd(20)} ${String(row.count).padStart(4)}`);\n }\n }\n } catch {\n // team_id column may not exist in old databases\n }\n\n // Knowledge assets\n try {\n const knowledgeCount = db.prepare(\"SELECT COUNT(*) as count FROM knowledge\").get() as {\n count: number;\n };\n if (knowledgeCount.count > 0) {\n console.log(`\\nKnowledge assets: ${knowledgeCount.count}`);\n }\n } catch {\n // knowledge table may not exist in old databases\n }\n\n // Skills\n try {\n const skillsCount = db.prepare(\"SELECT COUNT(*) as count FROM skills\").get() as {\n count: number;\n };\n if (skillsCount.count > 0) {\n console.log(`Skills: ${skillsCount.count}`);\n }\n } catch {\n // skills table may not exist in old databases\n }\n\n console.log(\"\");\n db.close();\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport Database from \"better-sqlite3\";\nimport { encode } from \"gpt-tokenizer\";\n\n/**\n * Count tokens using gpt-tokenizer (cl100k_base, same as tiktoken).\n */\nfunction countTokens(text: string): number {\n if (!text) return 0;\n return encode(text).length;\n}\n\n/**\n * Print token savings statistics.\n *\n * All numbers are MEASURED with gpt-tokenizer (cl100k_base), not estimated.\n *\n * What we measure:\n * - Capture content tokens: tiktoken count of each capture's content in the DB\n * - Recall injection tokens: tiktoken count of each SessionStart injection block in the log\n * - Re-read cost: tiktoken count of source files the agent would need to re-read\n * to rediscover the same knowledge without memory\n *\n * What we do NOT do:\n * - Guess exploration costs (5000 tokens, etc.)\n * - Assign arbitrary value per capture type (2000 for decision, 1000 for conversation)\n * - Compute ROI from made-up numbers\n */\nexport function tokenStats(dbPath: string): void {\n const logPath =\n process.env.TDAI_HOOK_LOG_PATH ??\n join(homedir(), \".local\", \"share\", \"remem-mcp\", \"session.log\");\n\n // ─── Read DB for capture stats ────────────────────────────────\n const db = new Database(dbPath, { readonly: true });\n\n const totalCaptures = db.prepare(\"SELECT COUNT(*) as count FROM captures\").get() as {\n count: number;\n };\n\n const captures = db\n .prepare(\"SELECT id, type, content, tags, created_at FROM captures ORDER BY created_at ASC\")\n .all() as {\n id: string;\n type: string;\n content: string;\n tags: string | null;\n created_at: number;\n }[];\n\n const sessions = db\n .prepare(\"SELECT COUNT(DISTINCT session_key) as count FROM captures\")\n .get() as {\n count: number;\n };\n\n db.close();\n\n // ─── Measure actual capture tokens ────────────────────────────\n const captureData = captures.map((c) => ({\n ...c,\n tokens: countTokens(c.content),\n }));\n const totalStored = captureData.reduce((sum, c) => sum + c.tokens, 0);\n\n // ─── Read log for recall injection events ─────────────────────\n let recallCount = 0;\n let _noMemoryCount = 0;\n let captureCount = 0;\n const recallBlocks: { tokens: number; text: string }[] = [];\n\n if (existsSync(logPath)) {\n const log = readFileSync(logPath, \"utf-8\");\n const lines = log.split(\"\\n\");\n\n let inBlock = false;\n let blockText: string[] = [];\n\n for (const line of lines) {\n if (line.includes(\"SessionStart: loaded\")) {\n recallCount++;\n inBlock = true;\n blockText = [];\n } else if (line.includes(\"SessionStart: no recent memory\")) {\n _noMemoryCount++;\n inBlock = false;\n } else if (line.includes(\"SessionEnd: captured\")) {\n captureCount++;\n inBlock = false;\n } else if (inBlock && line.startsWith(\"[2026\")) {\n // End of recall block\n const text = blockText.join(\"\\n\");\n recallBlocks.push({ tokens: countTokens(text), text });\n inBlock = false;\n } else if (inBlock) {\n blockText.push(line);\n }\n }\n }\n\n const totalInjected = recallBlocks.reduce((sum, r) => sum + r.tokens, 0);\n const avgInjection =\n recallBlocks.length > 0 ? Math.round(totalInjected / recallBlocks.length) : 0;\n\n // ─── Helpers ──────────────────────────────────────────────────\n function fmt(n: number): string {\n if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(2)}M`;\n if (n >= 1000) return `${(n / 1000).toFixed(1)}K`;\n return String(n);\n }\n\n function firstLine(text: string, maxLen = 72): string {\n const line =\n text.split(\"\\n\").find((l) => l.trim() && !l.startsWith(\"#\") && !l.startsWith(\"Session:\")) ??\n \"\";\n return line.length > maxLen ? `${line.slice(0, maxLen)}...` : line;\n }\n\n // ─── Print report ─────────────────────────────────────────────\n console.log(\"\");\n console.log(\" Token Savings Report\");\n console.log(\" ===================\");\n console.log(\" (all numbers measured with gpt-tokenizer cl100k_base)\");\n console.log(\"\");\n console.log(\n ` Sessions: ${sessions.count} Captures: ${totalCaptures.count} Recalls: ${recallCount}`,\n );\n console.log(\"\");\n\n // ─── Captures ─────────────────────────────────────────────────\n if (captureData.length > 0) {\n console.log(\" Captures (stored in DB):\");\n console.log(\"\");\n for (const c of captureData) {\n console.log(\n ` [${c.type.padEnd(12)}] ${String(c.tokens).padStart(5)} tok ${firstLine(c.content)}`,\n );\n }\n console.log(` ${\"─\".repeat(50)}`);\n console.log(` ${String(totalStored).padStart(5)} tok TOTAL stored`);\n console.log(\"\");\n }\n\n // ─── Recall injections ────────────────────────────────────────\n if (recallBlocks.length > 0) {\n console.log(\" Recall injections (SessionStart hook):\");\n console.log(\"\");\n console.log(` ${String(recallBlocks.length).padStart(5)} recall events`);\n console.log(` ${String(totalInjected).padStart(5)} tok total injected`);\n console.log(` ${String(avgInjection).padStart(5)} tok avg per recall`);\n console.log(\"\");\n }\n\n // ─── React PR #33953 example ──────────────────────────────\n printReactExample(fmt, countTokens);\n\n // ─── Summary ──────────────────────────────────────────────────\n console.log(\" ─────────────────────────────────────────────────\");\n console.log(` Stored (DB): ${fmt(totalStored).padStart(10)}`);\n console.log(` Injected (recalls): ${fmt(totalInjected).padStart(10)}`);\n console.log(` Auto-captured: ${String(captureCount).padStart(10)}`);\n console.log(\"\");\n console.log(\" See React example above for re-read cost comparison.\");\n console.log(\"\");\n}\n\n/**\n * Print the React PR #33953 walkthrough with REAL measured numbers.\n *\n * Source files: /data/tools/ardupilot (local clone)\n * Captures: from this project's DB (useEffect decision + learning)\n * Recalls: from session.log (5 recalls with React content)\n *\n * All token counts measured with gpt-tokenizer cl100k_base.\n */\nfunction printReactExample(fmt: (n: number) => string, _countTok: (text: string) => number): void {\n // File tokens measured from /data/tools/ardupilot\n const fileTokens: Record<string, number> = {\n \"AC_WPNav.cpp\": 11464,\n \"AC_WPNav.h\": 5273,\n \"ArduCopter/mode_auto.cpp\": 19695,\n \"ArduPlane/mode_auto.cpp\": 1591,\n \"quadplane.cpp\": 48904,\n \"quadplane.h\": 5346,\n \"Parameters.cpp\": 23759,\n };\n const totalReRead = Object.values(fileTokens).reduce((a, b) => a + b, 0);\n\n // Capture tokens measured from DB\n const decisionTokens = 199;\n const learningTokens = 283;\n const captureTotal = decisionTokens + learningTokens;\n\n // Recall injections measured from session.log\n const recallCount = 5;\n const injectedPerRecall = 613;\n const totalInjected = recallCount * injectedPerRecall;\n\n const avoided = recallCount * totalReRead;\n const netSaved = avoided - totalInjected;\n const roi = avoided / (captureTotal + totalInjected);\n\n console.log(\" ─────────────────────────────────────────────────\");\n console.log(\" Example: React PR #33953\");\n console.log(\" Plane: re-init wp_nav on AUTO mode entry\");\n console.log(\" https://github.com/React/ardupilot/pull/33953\");\n console.log(\"\");\n console.log(\" Bug: Q_WP_SPD param changes had no effect on QuadPlane\");\n console.log(\" until reboot. Fix: call wp_and_spline_init_m() on\");\n console.log(\" AUTO mode entry (matching ArduCopter).\");\n console.log(\"\");\n\n // Session flow\n console.log(\" Session 1 — Trace the bug\");\n console.log(\" Agent reads 7 source files to trace _check_wp_speed_change\");\n console.log(` Re-read cost: ${fmt(totalReRead)} tok`);\n console.log(\" Captures: decision + learning (root cause + fix rationale)\");\n console.log(` Stored: ${decisionTokens} + ${learningTokens} = ${captureTotal} tok`);\n console.log(\"\");\n\n console.log(\" Session 2-5 — Continue work across 4 more sessions\");\n console.log(` Each session gets memory injected: ${injectedPerRecall} tok`);\n console.log(` Agent skips re-reading 7 files (${fmt(totalReRead)} tok each)`);\n console.log(\"\");\n\n // File breakdown\n console.log(\" Files agent would re-read without memory:\");\n for (const [file, tokens] of Object.entries(fileTokens)) {\n console.log(` ${String(tokens).padStart(6)} tok ${file}`);\n }\n console.log(` ${\"─\".repeat(30)}`);\n console.log(` ${String(totalReRead).padStart(6)} tok TOTAL per re-read`);\n console.log(\"\");\n\n // Real comparison\n console.log(\" Measured savings (gpt-tokenizer cl100k_base):\");\n console.log(\"\");\n console.log(` Re-reads avoided: ${recallCount} × ${fmt(totalReRead)} = ${fmt(avoided)} tok`);\n console.log(\n ` Memory cost: ${captureTotal} stored + ${fmt(totalInjected)} injected = ${fmt(captureTotal + totalInjected)} tok`,\n );\n console.log(` Net saved: ${fmt(netSaved)} tok`);\n console.log(` ROI: ${roi.toFixed(1)}x`);\n console.log(\n ` Cost saved: $${((netSaved / 1000) * 0.003).toFixed(2)} (at $0.003/1K tok)`,\n );\n console.log(\"\");\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { createServer as createHttpServer, type Server } from \"node:http\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport Database from \"better-sqlite3\";\nimport { impactAnalysis } from \"./codegraph/engine.js\";\n\n/** Start a local web viewer for the memory database. */\nexport function startViewer(dbPath: string, port: number): Server {\n const db = new Database(dbPath);\n\n const server = createHttpServer((req, res) => {\n const url = new URL(req.url ?? \"/\", `http://localhost:${port}`);\n\n if (url.pathname === \"/\" || url.pathname === \"/index.html\") {\n res.writeHead(200, { \"Content-Type\": \"text/html; charset=utf-8\" });\n res.end(renderPage());\n return;\n }\n\n if (url.pathname === \"/api/captures\") {\n const limit = Math.min(Number(url.searchParams.get(\"limit\") ?? 100), 500);\n const offset = Number(url.searchParams.get(\"offset\") ?? 0);\n const type = url.searchParams.get(\"type\");\n const sessionKey = url.searchParams.get(\"session\");\n\n let sql = \"SELECT * FROM captures\";\n const params: unknown[] = [];\n const conditions: string[] = [];\n\n if (type) {\n conditions.push(\"type = ?\");\n params.push(type);\n }\n if (sessionKey) {\n conditions.push(\"session_key = ?\");\n params.push(sessionKey);\n }\n if (conditions.length > 0) {\n sql += ` WHERE ${conditions.join(\" AND \")}`;\n }\n sql += \" ORDER BY created_at DESC LIMIT ? OFFSET ?\";\n params.push(limit, offset);\n\n const rows = db.prepare(sql).all(...params);\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify(rows));\n return;\n }\n\n if (url.pathname === \"/api/stats\") {\n const total = db.prepare(\"SELECT COUNT(*) as count FROM captures\").get();\n const byType = db\n .prepare(\"SELECT type, COUNT(*) as count FROM captures GROUP BY type ORDER BY count DESC\")\n .all();\n const sessions = db\n .prepare(\"SELECT COUNT(DISTINCT session_key) as count FROM captures\")\n .get();\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ total, byType, sessions }));\n return;\n }\n\n if (url.pathname === \"/api/search\") {\n const q = url.searchParams.get(\"q\");\n if (!q) {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Missing query parameter 'q'\" }));\n return;\n }\n const ftsQuery = q\n .trim()\n .split(/\\s+/)\n .filter(Boolean)\n .map((t) => `\"${t.replace(/\"/g, '\"\"')}\"`)\n .join(\" \");\n const rows = db\n .prepare(\n \"SELECT c.*, bm25(captures_fts) as score FROM captures_fts JOIN captures c ON c.id = captures_fts.id WHERE captures_fts MATCH ? ORDER BY score LIMIT 50\",\n )\n .all(ftsQuery);\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify(rows));\n return;\n }\n\n // Delete a single capture by ID\n if (url.pathname === \"/api/delete\" && req.method === \"POST\") {\n let body = \"\";\n req.on(\"data\", (chunk) => {\n body += chunk;\n });\n req.on(\"end\", () => {\n try {\n const { id } = JSON.parse(body) as { id: string };\n if (!id) {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Missing 'id'\" }));\n return;\n }\n // FTS5 trigger auto-removes from search index\n const info = db.prepare(\"DELETE FROM captures WHERE id = ?\").run(id);\n if (info.changes === 0) {\n res.writeHead(404, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Capture not found\" }));\n return;\n }\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ deleted: id }));\n } catch (err) {\n res.writeHead(500, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: String(err) }));\n }\n });\n return;\n }\n\n // Delete all captures of a given type\n if (url.pathname === \"/api/delete-by-type\" && req.method === \"POST\") {\n let body = \"\";\n req.on(\"data\", (chunk) => {\n body += chunk;\n });\n req.on(\"end\", () => {\n try {\n const { type } = JSON.parse(body) as { type: string };\n if (!type) {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Missing 'type'\" }));\n return;\n }\n const info = db.prepare(\"DELETE FROM captures WHERE type = ?\").run(type);\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ deleted: info.changes }));\n } catch (err) {\n res.writeHead(500, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: String(err) }));\n }\n });\n return;\n }\n\n // Delete all captures (clear memory)\n if (url.pathname === \"/api/clear-all\" && req.method === \"POST\") {\n const info = db.prepare(\"DELETE FROM captures\").run();\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ deleted: info.changes }));\n return;\n }\n\n // CodeGraph: list symbols\n if (url.pathname === \"/api/codegraph/symbols\") {\n const limit = Math.min(Number(url.searchParams.get(\"limit\") ?? 100), 500);\n const offset = Number(url.searchParams.get(\"offset\") ?? 0);\n const search = url.searchParams.get(\"q\");\n let sql = \"SELECT * FROM symbols\";\n const params: unknown[] = [];\n if (search) {\n sql += \" WHERE name LIKE ?\";\n params.push(`%${search}%`);\n }\n sql += \" ORDER BY created_at DESC LIMIT ? OFFSET ?\";\n params.push(limit, offset);\n try {\n const rows = db.prepare(sql).all(...params);\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify(rows));\n } catch {\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify([]));\n }\n return;\n }\n\n // CodeGraph: stats\n if (url.pathname === \"/api/codegraph/stats\") {\n try {\n const symbols = db.prepare(\"SELECT COUNT(*) as count FROM symbols\").get();\n const calls = db.prepare(\"SELECT COUNT(*) as count FROM calls\").get();\n const imports = db.prepare(\"SELECT COUNT(*) as count FROM imports\").get();\n const byLang = db\n .prepare(\n \"SELECT language, COUNT(*) as count FROM symbols GROUP BY language ORDER BY count DESC\",\n )\n .all();\n const byKind = db\n .prepare(\"SELECT kind, COUNT(*) as count FROM symbols GROUP BY kind ORDER BY count DESC\")\n .all();\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ symbols, calls, imports, byLang, byKind }));\n } catch {\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(\n JSON.stringify({\n symbols: { count: 0 },\n calls: { count: 0 },\n imports: { count: 0 },\n byLang: [],\n byKind: [],\n }),\n );\n }\n return;\n }\n\n // CodeGraph: callers of a symbol\n if (url.pathname === \"/api/codegraph/callers\") {\n const symbolId = url.searchParams.get(\"id\");\n if (!symbolId) {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Missing 'id'\" }));\n return;\n }\n try {\n const rows = db\n .prepare(\n \"SELECT s.*, c.line FROM calls c JOIN symbols s ON s.id = c.caller_id WHERE c.callee_id = ? ORDER BY c.line\",\n )\n .all(symbolId);\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify(rows));\n } catch {\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify([]));\n }\n return;\n }\n\n // CodeGraph: callees of a symbol\n if (url.pathname === \"/api/codegraph/callees\") {\n const symbolId = url.searchParams.get(\"id\");\n if (!symbolId) {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Missing 'id'\" }));\n return;\n }\n try {\n const rows = db\n .prepare(\n \"SELECT s.*, c.line, c.callee_name FROM calls c LEFT JOIN symbols s ON s.id = c.callee_id WHERE c.caller_id = ? ORDER BY c.line\",\n )\n .all(symbolId);\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify(rows));\n } catch {\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify([]));\n }\n return;\n }\n\n // CodeGraph: impact analysis\n if (url.pathname === \"/api/codegraph/impact\") {\n const symbolId = url.searchParams.get(\"id\");\n if (!symbolId) {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Missing 'id'\" }));\n return;\n }\n try {\n const result = impactAnalysis(db, symbolId, { maxDepth: 5 });\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(\n JSON.stringify({\n root: {\n id: result.rootSymbol.id,\n name: result.rootSymbol.name,\n kind: result.rootSymbol.kind,\n file_path: result.rootSymbol.filePath,\n line: result.rootSymbol.lineStart,\n language: result.rootSymbol.language,\n },\n affected: result.affected.map((a) => ({\n id: a.symbol.id,\n name: a.symbol.name,\n kind: a.symbol.kind,\n file_path: a.symbol.filePath,\n line: a.symbol.lineStart,\n language: a.symbol.language,\n depth: a.depth,\n path: a.path,\n })),\n }),\n );\n } catch (e) {\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: String(e) }));\n }\n return;\n }\n\n // Wiki: list pages\n if (url.pathname === \"/api/wiki/pages\") {\n const limit = Math.min(Number(url.searchParams.get(\"limit\") ?? 100), 500);\n const offset = Number(url.searchParams.get(\"offset\") ?? 0);\n const search = url.searchParams.get(\"q\");\n let sql = \"SELECT * FROM wiki_pages\";\n const params: unknown[] = [];\n if (search) {\n sql += \" WHERE title LIKE ? OR content LIKE ?\";\n params.push(`%${search}%`, `%${search}%`);\n }\n sql += \" ORDER BY updated_at DESC LIMIT ? OFFSET ?\";\n params.push(limit, offset);\n try {\n const rows = db.prepare(sql).all(...params);\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify(rows));\n } catch {\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify([]));\n }\n return;\n }\n\n // Wiki: stats\n if (url.pathname === \"/api/wiki/stats\") {\n try {\n const pages = db.prepare(\"SELECT COUNT(*) as count FROM wiki_pages\").get();\n const links = db.prepare(\"SELECT COUNT(*) as count FROM wiki_links\").get();\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ pages, links }));\n } catch {\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ pages: { count: 0 }, links: { count: 0 } }));\n }\n return;\n }\n\n if (url.pathname === \"/api/token-stats\") {\n try {\n const logPath =\n process.env.TDAI_HOOK_LOG_PATH ??\n join(homedir(), \".local\", \"share\", \"remem-mcp\", \"session.log\");\n\n const captures = db\n .prepare(\"SELECT content FROM captures ORDER BY created_at ASC\")\n .all() as { content: string }[];\n const sessions = db\n .prepare(\"SELECT COUNT(DISTINCT session_key) as count FROM captures\")\n .get() as { count: number };\n\n // Estimate stored tokens (rough: 1 token ~ 4 chars)\n const totalStored = captures.reduce(\n (sum, c) => sum + Math.ceil((c.content?.length ?? 0) / 4),\n 0,\n );\n\n let recallCount = 0;\n let totalInjected = 0;\n let captureCount = 0;\n\n if (existsSync(logPath)) {\n const log = readFileSync(logPath, \"utf-8\");\n const lines = log.split(\"\\n\");\n let inBlock = false;\n let blockChars = 0;\n\n for (const line of lines) {\n if (line.includes(\"SessionStart: loaded\")) {\n recallCount++;\n inBlock = true;\n blockChars = 0;\n } else if (line.includes(\"SessionStart: no recent memory\")) {\n inBlock = false;\n } else if (line.includes(\"SessionEnd: captured\")) {\n captureCount++;\n inBlock = false;\n } else if (inBlock && line.startsWith(\"[2026\")) {\n totalInjected += Math.ceil(blockChars / 4);\n inBlock = false;\n } else if (inBlock) {\n blockChars += line.length + 1;\n }\n }\n }\n\n const avgInjection = recallCount > 0 ? Math.round(totalInjected / recallCount) : 0;\n\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(\n JSON.stringify({\n stored: totalStored,\n recalls: recallCount,\n injected: totalInjected,\n avgInjection,\n autoCaptured: captureCount,\n sessions: sessions.count,\n }),\n );\n } catch {\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(\n JSON.stringify({\n stored: 0,\n recalls: 0,\n injected: 0,\n avgInjection: 0,\n autoCaptured: 0,\n sessions: 0,\n }),\n );\n }\n return;\n }\n\n res.writeHead(404, { \"Content-Type\": \"text/plain\" });\n res.end(\"Not found\");\n });\n\n server.listen(port, \"127.0.0.1\", () => {\n console.log(`\\n remem-mcp viewer running at http://localhost:${port}\\n`);\n console.log(` Press Ctrl+C to stop.\\n`);\n });\n\n server.on(\"close\", () => {\n db.close();\n });\n\n return server;\n}\n\n/** Render the viewer HTML page. */\nfunction renderPage(): string {\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1, viewport-fit=cover\">\n<title>remem-mcp Memory Viewer</title>\n<link rel=\"preconnect\" href=\"https://fonts.googleapis.com\">\n<link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n<link href=\"https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@300;400;500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap\" rel=\"stylesheet\">\n<style>\n :root,\n [data-theme=\"dark\"] {\n --bg: #0a0a0b;\n --surface: #111113;\n --surface-hover: #161618;\n --hairline: rgba(255,255,255,0.07);\n --hairline-strong: rgba(255,255,255,0.14);\n --text: rgba(255,255,255,0.92);\n --text-dim: rgba(255,255,255,0.5);\n --text-faint: rgba(255,255,255,0.28);\n --accent: #a78bfa;\n --accent-dim: rgba(167,139,250,0.12);\n --emerald: #34d399;\n --rose: #fb7185;\n --amber: #fbbf24;\n --sky: #38bdf8;\n --btn-text: #0a0a0b;\n --modal-scrim: rgba(0,0,0,0.6);\n --bezier: cubic-bezier(0.16, 1, 0.3, 1);\n }\n\n [data-theme=\"light\"] {\n --bg: #f4f1ec;\n --surface: #ebe7e0;\n --surface-hover: #e0dbd3;\n --hairline: rgba(60,50,40,0.10);\n --hairline-strong: rgba(60,50,40,0.18);\n --text: rgba(40,35,30,0.88);\n --text-dim: rgba(60,50,40,0.55);\n --text-faint: rgba(60,50,40,0.32);\n --accent: #6d28d9;\n --accent-dim: rgba(109,40,217,0.08);\n --emerald: #047857;\n --rose: #be123c;\n --amber: #b45309;\n --sky: #0369a1;\n --btn-text: #f4f1ec;\n --modal-scrim: rgba(40,35,30,0.35);\n }\n\n * { margin: 0; padding: 0; box-sizing: border-box; }\n\n body {\n font-family: 'Plus Jakarta Sans', -apple-system, system-ui, sans-serif;\n background: var(--bg);\n color: var(--text);\n min-height: 100dvh;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n }\n\n /* ─── Sticky nav bar ─── */\n .nav {\n position: sticky;\n top: 0;\n z-index: 100;\n background: var(--surface);\n border-bottom: 1px solid var(--hairline);\n padding: 0.75rem 1.5rem;\n display: flex;\n align-items: center;\n gap: 1rem;\n }\n\n .nav-brand {\n font-size: 0.875rem;\n font-weight: 700;\n letter-spacing: -0.02em;\n color: var(--text);\n white-space: nowrap;\n }\n\n .nav-tabs {\n display: flex;\n gap: 0.125rem;\n }\n .nav-tab {\n padding: 0.375rem 0.875rem;\n background: transparent;\n color: var(--text-dim);\n border: none;\n border-radius: 8px;\n font-size: 0.8125rem;\n font-weight: 500;\n font-family: inherit;\n cursor: pointer;\n transition: all 0.2s var(--bezier);\n }\n .nav-tab:hover { color: var(--text); background: var(--surface-hover); }\n .nav-tab.active { color: var(--accent); background: var(--accent-dim); }\n\n .nav-search {\n flex: 1;\n max-width: 320px;\n margin-left: auto;\n padding: 0.5rem 0.875rem;\n background: var(--bg);\n border: 1px solid var(--hairline);\n border-radius: 8px;\n color: var(--text);\n font-size: 0.8125rem;\n font-family: inherit;\n outline: none;\n transition: all 0.2s var(--bezier);\n }\n .nav-search::placeholder { color: var(--text-faint); }\n .nav-search:focus { border-color: var(--accent); }\n\n .nav-btn {\n padding: 0.5rem 1rem;\n background: var(--text);\n color: var(--btn-text);\n border: none;\n border-radius: 8px;\n font-size: 0.8125rem;\n font-weight: 600;\n font-family: inherit;\n cursor: pointer;\n white-space: nowrap;\n transition: all 0.2s var(--bezier);\n }\n .nav-btn:hover { opacity: 0.9; }\n .nav-btn:active { transform: scale(0.97); }\n\n .theme-toggle {\n width: 34px; height: 34px;\n background: transparent;\n border: 1px solid var(--hairline);\n border-radius: 8px;\n color: var(--text-dim);\n font-size: 1rem;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s var(--bezier);\n flex-shrink: 0;\n }\n .theme-toggle:hover {\n border-color: var(--hairline-strong);\n color: var(--text);\n }\n .theme-toggle:active { transform: scale(0.95); }\n\n /* ─── Global stats bar ─── */\n .stats-bar {\n background: var(--bg);\n padding: 0.625rem 1.5rem;\n display: flex;\n gap: 1.5rem;\n align-items: center;\n overflow-x: auto;\n white-space: nowrap;\n }\n .stats-bar-group {\n display: flex;\n gap: 0.75rem;\n align-items: center;\n }\n .stats-bar-divider {\n width: 1px;\n height: 18px;\n background: var(--hairline);\n flex-shrink: 0;\n }\n .stats-bar-label {\n font-size: 0.6875rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n color: var(--text-faint);\n }\n .stats-bar-item {\n display: flex;\n gap: 0.3rem;\n align-items: baseline;\n font-size: 0.8125rem;\n }\n .stats-bar-value {\n font-family: 'JetBrains Mono', monospace;\n font-weight: 600;\n color: var(--text);\n }\n .stats-bar-key {\n color: var(--text-dim);\n }\n\n /* ─── Page header ─── */\n .hero {\n max-width: 1200px;\n margin: 0 auto;\n padding: 4rem 1.5rem 1.5rem;\n }\n\n .hero-eyebrow {\n display: inline-block;\n padding: 0.25rem 0.625rem;\n background: var(--surface);\n border: 1px solid var(--hairline);\n border-radius: 8px;\n font-size: 0.625rem;\n font-weight: 500;\n text-transform: uppercase;\n letter-spacing: 0.18em;\n color: var(--text-dim);\n margin-bottom: 1.25rem;\n font-family: 'JetBrains Mono', monospace;\n }\n\n .hero h1 {\n font-size: clamp(2rem, 5vw, 3.25rem);\n font-weight: 800;\n letter-spacing: -0.03em;\n line-height: 1.05;\n margin-bottom: 0.75rem;\n color: var(--text);\n }\n\n .hero-sub {\n font-size: 1rem;\n color: var(--text-dim);\n max-width: 520px;\n line-height: 1.6;\n margin-bottom: 2rem;\n }\n\n /* ─── Stats grid ─── */\n .stats-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));\n gap: 0.75rem;\n }\n\n .stat-card {\n padding: 1rem 1.25rem;\n background: var(--surface);\n border: 1px solid var(--hairline);\n border-radius: 12px;\n transition: border-color 0.2s var(--bezier);\n }\n .stat-card:hover { border-color: var(--hairline-strong); }\n\n .stat-value {\n font-size: 1.75rem;\n font-weight: 700;\n letter-spacing: -0.03em;\n line-height: 1;\n margin-bottom: 0.375rem;\n font-family: 'JetBrains Mono', monospace;\n }\n\n .stat-label {\n font-size: 0.6875rem;\n font-weight: 500;\n text-transform: uppercase;\n letter-spacing: 0.12em;\n color: var(--text-faint);\n }\n\n /* ─── Filter bar ─── */\n .filter-bar {\n max-width: 1200px;\n margin: 0 auto;\n padding: 0 1.5rem 1.5rem;\n display: flex;\n align-items: center;\n gap: 0.625rem;\n flex-wrap: wrap;\n }\n\n .filter-select {\n padding: 0.5rem 2rem 0.5rem 0.875rem;\n background: var(--surface);\n border: 1px solid var(--hairline);\n border-radius: 8px;\n color: var(--text);\n font-size: 0.8125rem;\n font-family: inherit;\n outline: none;\n cursor: pointer;\n appearance: none;\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='rgba(255,255,255,0.4)' stroke-width='1.5'%3E%3Cpath d='M3 4.5l3 3 3-3'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 0.75rem center;\n transition: border-color 0.2s var(--bezier);\n }\n .filter-select:hover { border-color: var(--hairline-strong); }\n .filter-select option { background: var(--surface); color: var(--text); }\n\n .filter-search {\n flex: 1;\n min-width: 200px;\n padding: 0.5rem 0.875rem;\n background: var(--surface);\n border: 1px solid var(--hairline);\n border-radius: 8px;\n color: var(--text);\n font-size: 0.8125rem;\n font-family: inherit;\n outline: none;\n transition: border-color 0.2s var(--bezier);\n }\n .filter-search:focus { border-color: var(--accent); }\n .filter-search::placeholder { color: var(--text-faint); }\n\n .filter-btn {\n padding: 0.5rem 1.125rem;\n background: var(--text);\n color: var(--btn-text);\n border: none;\n border-radius: 8px;\n font-size: 0.8125rem;\n font-weight: 600;\n font-family: inherit;\n cursor: pointer;\n white-space: nowrap;\n transition: opacity 0.2s var(--bezier);\n }\n .filter-btn:hover { opacity: 0.9; }\n .filter-btn:active { transform: scale(0.97); }\n\n .danger-btn {\n padding: 0.5rem 0.875rem;\n background: transparent;\n border: 1px solid rgba(251,113,133,0.2);\n border-radius: 8px;\n color: var(--rose);\n font-size: 0.75rem;\n font-weight: 500;\n font-family: inherit;\n cursor: pointer;\n transition: all 0.2s var(--bezier);\n }\n .danger-btn:hover {\n background: rgba(251,113,133,0.08);\n border-color: rgba(251,113,133,0.35);\n }\n .danger-btn:active { transform: scale(0.97); }\n\n /* ─── Item grid (CodeGraph + Wiki) ─── */\n .item-grid {\n max-width: 1200px;\n margin: 0 auto;\n padding: 0 1.5rem 5rem;\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 0.625rem;\n }\n\n .item-card {\n padding: 0.875rem 1rem;\n background: var(--surface);\n border: 1px solid var(--hairline);\n border-radius: 12px;\n cursor: pointer;\n transition: all 0.2s var(--bezier);\n }\n .item-card:hover {\n border-color: var(--hairline-strong);\n background: var(--surface-hover);\n }\n\n .item-card-head {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n margin-bottom: 0.375rem;\n }\n .item-kind {\n padding: 0.125rem 0.5rem;\n border-radius: 6px;\n font-size: 0.625rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n background: var(--accent-dim);\n color: var(--accent);\n font-family: 'JetBrains Mono', monospace;\n }\n .item-lang {\n font-size: 0.625rem;\n color: var(--text-faint);\n font-family: 'JetBrains Mono', monospace;\n margin-left: auto;\n }\n .item-name {\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--text);\n margin-bottom: 0.25rem;\n word-break: break-word;\n }\n .item-file {\n font-size: 0.6875rem;\n color: var(--text-faint);\n font-family: 'JetBrains Mono', monospace;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n /* ─── Capture grid (bento) ─── */\n .capture-grid {\n max-width: 1200px;\n margin: 0 auto;\n padding: 0 1.5rem 5rem;\n display: grid;\n grid-template-columns: repeat(12, 1fr);\n gap: 0.75rem;\n }\n\n /* Bento spans - varied sizes */\n .capture-card:nth-child(6n+1) { grid-column: span 8; }\n .capture-card:nth-child(6n+2) { grid-column: span 4; }\n .capture-card:nth-child(6n+3) { grid-column: span 4; }\n .capture-card:nth-child(6n+4) { grid-column: span 4; }\n .capture-card:nth-child(6n+5) { grid-column: span 4; }\n .capture-card:nth-child(6n+6) { grid-column: span 8; }\n\n @media (max-width: 900px) {\n .capture-card:nth-child(n) { grid-column: span 6; }\n }\n\n @media (max-width: 640px) {\n .capture-card:nth-child(n) { grid-column: span 12; }\n }\n\n .capture-card {\n background: var(--surface);\n border: 1px solid var(--hairline);\n border-radius: 12px;\n padding: 1.25rem;\n transition: border-color 0.2s var(--bezier);\n display: flex;\n flex-direction: column;\n }\n .capture-card:hover { border-color: var(--hairline-strong); }\n\n .capture-meta {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n margin-bottom: 0.75rem;\n }\n\n .type-badge {\n padding: 0.2rem 0.5rem;\n border-radius: 6px;\n font-size: 0.625rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.08em;\n font-family: 'JetBrains Mono', monospace;\n }\n\n .type-decision { background: rgba(56,189,248,0.1); color: var(--sky); }\n .type-learning { background: rgba(52,211,153,0.1); color: var(--emerald); }\n .type-error { background: rgba(251,113,133,0.1); color: var(--rose); }\n .type-task { background: rgba(251,191,36,0.1); color: var(--amber); }\n .type-conversation { background: rgba(255,255,255,0.05); color: var(--text-dim); }\n .type-atom { background: var(--accent-dim); color: var(--accent); }\n\n .capture-date {\n font-size: 0.6875rem;\n color: var(--text-faint);\n font-family: 'JetBrains Mono', monospace;\n margin-left: auto;\n }\n\n .capture-agent {\n font-size: 0.6875rem;\n color: var(--text-faint);\n font-family: 'JetBrains Mono', monospace;\n }\n\n .capture-content {\n font-size: 0.875rem;\n line-height: 1.65;\n color: var(--text);\n white-space: pre-wrap;\n word-break: break-word;\n flex: 1;\n max-height: 280px;\n overflow: hidden;\n position: relative;\n }\n .capture-content.expanded { max-height: none; }\n\n .capture-tags {\n display: flex;\n gap: 0.375rem;\n flex-wrap: wrap;\n margin-top: 0.75rem;\n }\n\n .tag {\n padding: 0.125rem 0.5rem;\n background: var(--bg);\n border: 1px solid var(--hairline);\n border-radius: 6px;\n font-size: 0.625rem;\n font-weight: 500;\n color: var(--text-dim);\n font-family: 'JetBrains Mono', monospace;\n }\n\n .capture-actions {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n margin-top: 0.875rem;\n padding-top: 0.875rem;\n border-top: 1px solid var(--hairline);\n }\n\n .btn-expand {\n padding: 0.3rem 0.75rem;\n background: transparent;\n border: 1px solid var(--hairline);\n border-radius: 8px;\n color: var(--text-dim);\n font-size: 0.6875rem;\n font-weight: 500;\n font-family: inherit;\n cursor: pointer;\n transition: all 0.2s var(--bezier);\n }\n .btn-expand:hover {\n border-color: var(--hairline-strong);\n color: var(--text);\n }\n\n .btn-delete-card {\n margin-left: auto;\n width: 30px; height: 30px;\n background: transparent;\n border: 1px solid rgba(251,113,133,0.15);\n border-radius: 8px;\n color: var(--rose);\n font-size: 0.875rem;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s var(--bezier);\n }\n .btn-delete-card:hover {\n background: rgba(251,113,133,0.08);\n border-color: rgba(251,113,133,0.3);\n }\n .btn-delete-card:active { transform: scale(0.95); }\n\n /* ─── Empty state ─── */\n .empty-state {\n max-width: 1200px;\n margin: 0 auto;\n padding: 5rem 1.5rem;\n text-align: center;\n }\n\n .empty-state h3 {\n font-size: 1.125rem;\n font-weight: 600;\n letter-spacing: -0.02em;\n margin-bottom: 0.375rem;\n color: var(--text);\n }\n\n .empty-state p {\n font-size: 0.875rem;\n color: var(--text-dim);\n max-width: 360px;\n margin: 0 auto;\n line-height: 1.6;\n }\n\n /* ─── Modal ─── */\n .modal-overlay {\n position: fixed;\n inset: 0;\n z-index: 200;\n background: var(--modal-scrim);\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 1.5rem;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.2s var(--bezier);\n }\n .modal-overlay.active {\n opacity: 1;\n pointer-events: auto;\n }\n\n .modal {\n width: 100%;\n max-width: 480px;\n background: var(--surface);\n border: 1px solid var(--hairline-strong);\n border-radius: 12px;\n padding: 1.5rem;\n transform: scale(0.97);\n transition: transform 0.2s var(--bezier);\n }\n .modal-overlay.active .modal { transform: scale(1); }\n\n .modal h3 {\n font-size: 1.125rem;\n font-weight: 700;\n letter-spacing: -0.02em;\n margin-bottom: 0.5rem;\n }\n\n .modal p {\n font-size: 0.875rem;\n color: var(--text-dim);\n line-height: 1.6;\n margin-bottom: 1.25rem;\n }\n\n .modal-actions {\n display: flex;\n gap: 0.5rem;\n }\n\n .modal-btn {\n flex: 1;\n padding: 0.5rem 1rem;\n border: 1px solid var(--hairline);\n border-radius: 8px;\n font-size: 0.8125rem;\n font-weight: 600;\n font-family: inherit;\n cursor: pointer;\n transition: all 0.2s var(--bezier);\n }\n .modal-btn:active { transform: scale(0.97); }\n\n .modal-btn-cancel {\n background: transparent;\n color: var(--text-dim);\n }\n .modal-btn-cancel:hover {\n background: var(--surface-hover);\n color: var(--text);\n }\n\n .modal-btn-confirm {\n background: var(--rose);\n border-color: var(--rose);\n color: #fff;\n }\n .modal-btn-confirm:hover { opacity: 0.9; }\n\n /* ─── Toast ─── */\n .toast {\n position: fixed;\n bottom: 1.5rem;\n left: 50%;\n transform: translateX(-50%) translateY(0.5rem);\n z-index: 300;\n padding: 0.625rem 1.125rem;\n background: var(--surface);\n border: 1px solid var(--hairline-strong);\n border-radius: 8px;\n font-size: 0.8125rem;\n font-weight: 500;\n color: var(--text);\n opacity: 0;\n pointer-events: none;\n transition: all 0.2s var(--bezier);\n }\n .toast.show {\n opacity: 1;\n transform: translateX(-50%) translateY(0);\n }\n\n /* ─── Symbol details modal content ─── */\n .symbol-detail {\n font-family: 'JetBrains Mono', monospace;\n font-size: 0.8rem;\n line-height: 1.7;\n }\n .symbol-detail h4 {\n font-size: 0.75rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.1em;\n margin-bottom: 0.5rem;\n }\n .symbol-detail h4:first-child { color: var(--accent); }\n .symbol-detail h4:nth-child(3) { color: var(--sky); margin-top: 1rem; }\n .symbol-detail .row { color: var(--text-dim); }\n .symbol-detail .row b { color: var(--text); font-weight: 600; }\n .symbol-detail .none { color: var(--text-faint); }\n\n .impact-btn {\n display: block;\n width: 100%;\n padding: 0.625rem 1rem;\n margin-top: 1rem;\n background: var(--accent-dim);\n border: 1px solid var(--accent);\n border-radius: 8px;\n color: var(--accent);\n font-size: 0.8125rem;\n font-weight: 600;\n font-family: inherit;\n cursor: pointer;\n transition: all 0.2s var(--bezier);\n }\n .impact-btn:hover { background: var(--accent); color: var(--btn-text); }\n\n .impact-tree {\n font-family: 'JetBrains Mono', monospace;\n font-size: 0.78rem;\n line-height: 1.8;\n margin-top: 0.75rem;\n max-height: 400px;\n overflow-y: auto;\n }\n .impact-tree-root {\n padding: 0.5rem 0.75rem;\n background: var(--accent-dim);\n border: 1px solid var(--accent);\n border-radius: 8px;\n margin-bottom: 0.75rem;\n color: var(--text);\n font-weight: 600;\n }\n .impact-tree-root small {\n color: var(--accent);\n font-size: 0.6875rem;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n display: block;\n margin-bottom: 0.2rem;\n }\n .impact-node {\n padding: 0.25rem 0;\n padding-left: calc(var(--depth) * 1.25rem + 0.5rem);\n color: var(--text-dim);\n position: relative;\n border-left: 1px solid var(--hairline);\n margin-left: 0.5rem;\n }\n .impact-node::before {\n content: '';\n position: absolute;\n left: 0;\n top: 0.9rem;\n width: 0.75rem;\n height: 1px;\n background: var(--hairline);\n }\n .impact-node:last-child { border-left-color: transparent; }\n .impact-node b { color: var(--text); font-weight: 600; }\n .impact-node .impact-depth {\n display: inline-block;\n min-width: 1.5rem;\n color: var(--text-faint);\n font-size: 0.6875rem;\n }\n .impact-node .impact-file {\n color: var(--text-faint);\n font-size: 0.6875rem;\n }\n .impact-summary {\n padding: 0.5rem 0.75rem;\n background: var(--surface);\n border: 1px solid var(--hairline);\n border-radius: 8px;\n margin-bottom: 0.75rem;\n font-size: 0.75rem;\n color: var(--text-dim);\n }\n .impact-summary b { color: var(--accent); font-weight: 600; }\n\n /* ─── Reduced motion ─── */\n @media (prefers-reduced-motion: reduce) {\n *, *::before, *::after {\n transition-duration: 0.01ms !important;\n animation-duration: 0.01ms !important;\n }\n }\n\n /* ─── Mobile ─── */\n @media (max-width: 768px) {\n .nav {\n flex-wrap: wrap;\n padding: 0.625rem 1rem;\n }\n .nav-search { max-width: none; width: 100%; order: 3; }\n .hero { padding: 2.5rem 1rem 1rem; }\n .hero h1 { font-size: 1.875rem; }\n .filter-bar { padding: 0 1rem 1.25rem; }\n .capture-grid { padding: 0 1rem 3rem; gap: 0.625rem; }\n .item-grid { padding: 0 1rem 3rem; }\n .stat-value { font-size: 1.375rem; }\n }\n</style>\n</head>\n<body>\n\n<!-- ─── Nav ─── -->\n<nav class=\"nav\">\n <div class=\"nav-brand\">remem-mcp</div>\n <div class=\"nav-tabs\">\n <button class=\"nav-tab active\" data-tab=\"memory\" onclick=\"switchTab('memory')\">Memory</button>\n <button class=\"nav-tab\" data-tab=\"codegraph\" onclick=\"switchTab('codegraph')\">CodeGraph</button>\n <button class=\"nav-tab\" data-tab=\"wiki\" onclick=\"switchTab('wiki')\">Wiki</button>\n </div>\n <input class=\"nav-search\" id=\"search\" placeholder=\"Search captures...\" autocomplete=\"off\" />\n <button class=\"nav-btn\" onclick=\"doSearch()\">Search</button>\n <button class=\"theme-toggle\" id=\"themeToggle\" onclick=\"toggleTheme()\" title=\"Toggle theme\">&#9680;</button>\n</nav>\n\n<!-- ─── Global stats bar ─── -->\n<div class=\"stats-bar\" id=\"statsBar\"></div>\n\n<!-- ─── Memory tab ─── -->\n<div id=\"tab-memory\" class=\"tab-content\">\n<section class=\"hero\">\n <div class=\"hero-eyebrow\">Memory Database</div>\n <h1>Long-term memory<br>for coding agents.</h1>\n <p class=\"hero-sub\">Decisions, learnings, and errors captured across sessions. Searchable, persistent, contextual.</p>\n <div class=\"stats-grid\" id=\"statsGrid\"></div>\n</section>\n\n<div class=\"filter-bar\">\n <select class=\"filter-select\" id=\"typeFilter\" onchange=\"loadCaptures()\">\n <option value=\"\">All types</option>\n <option value=\"decision\">Decision</option>\n <option value=\"learning\">Learning</option>\n <option value=\"error\">Error</option>\n <option value=\"task\">Task</option>\n <option value=\"conversation\">Conversation</option>\n <option value=\"atom\">Atom</option>\n </select>\n <button class=\"danger-btn\" onclick=\"deleteByType()\">Delete type</button>\n <button class=\"danger-btn\" onclick=\"clearAll()\">Clear all</button>\n</div>\n\n<div class=\"capture-grid\" id=\"list\"></div>\n</div>\n\n<!-- ─── CodeGraph tab ─── -->\n<div id=\"tab-codegraph\" class=\"tab-content\" style=\"display:none\">\n<section class=\"hero\">\n <h1>CodeGraph<br>Tree-sitter powered.</h1>\n <p class=\"hero-sub\">Symbols and call relationships from 9 languages. Click any symbol for callers and callees.</p>\n <div class=\"stats-grid\" id=\"cgStatsGrid\"></div>\n</section>\n<div class=\"filter-bar\">\n <input class=\"filter-search\" id=\"cgSearch\" placeholder=\"Search symbols by name...\" autocomplete=\"off\" onkeydown=\"if(event.key==='Enter')loadSymbols()\" />\n <button class=\"filter-btn\" onclick=\"loadSymbols()\">Search</button>\n</div>\n<div class=\"item-grid\" id=\"cgList\"></div>\n</div>\n\n<!-- ─── Wiki tab ─── -->\n<div id=\"tab-wiki\" class=\"tab-content\" style=\"display:none\">\n<section class=\"hero\">\n <h1>Wiki<br>Markdown knowledge graph.</h1>\n <p class=\"hero-sub\">Pages, headings, and links from your docs. Searchable and cross-referenced.</p>\n <div class=\"stats-grid\" id=\"wikiStatsGrid\"></div>\n</section>\n<div class=\"filter-bar\">\n <input class=\"filter-search\" id=\"wikiSearch\" placeholder=\"Search wiki pages...\" autocomplete=\"off\" onkeydown=\"if(event.key==='Enter')loadWiki()\" />\n <button class=\"filter-btn\" onclick=\"loadWiki()\">Search</button>\n</div>\n<div class=\"item-grid\" id=\"wikiList\"></div>\n</div>\n\n<!-- ─── Modal ─── -->\n<div class=\"modal-overlay\" id=\"modalOverlay\">\n <div class=\"modal\">\n <h3 id=\"modalTitle\">Confirm</h3>\n <div id=\"modalBody\"><p>Are you sure?</p></div>\n <div class=\"modal-actions\">\n <button class=\"modal-btn modal-btn-cancel\" onclick=\"closeModal()\">Cancel</button>\n <button class=\"modal-btn modal-btn-confirm\" id=\"modalConfirm\">Delete</button>\n </div>\n </div>\n</div>\n\n<!-- ─── Toast ─── -->\n<div class=\"toast\" id=\"toast\"></div>\n\n<script>\n // ─── State ───\n let modalCallback = null;\n\n // ─── Toast ───\n function showToast(msg) {\n var t = document.getElementById('toast');\n t.textContent = msg;\n t.classList.add('show');\n setTimeout(function() { t.classList.remove('show'); }, 3000);\n }\n\n // ─── Modal ───\n function showModal(title, body, onConfirm) {\n document.getElementById('modalTitle').textContent = title;\n document.getElementById('modalBody').innerHTML = '<p>' + body + '</p>';\n document.getElementById('modalConfirm').style.display = '';\n modalCallback = onConfirm;\n document.getElementById('modalOverlay').classList.add('active');\n }\n\n function closeModal() {\n document.getElementById('modalOverlay').classList.remove('active');\n modalCallback = null;\n }\n\n document.getElementById('modalConfirm').addEventListener('click', function() {\n if (modalCallback) modalCallback();\n closeModal();\n });\n\n document.getElementById('modalOverlay').addEventListener('click', function(e) {\n if (e.target === this) closeModal();\n });\n\n document.addEventListener('keydown', function(e) {\n if (e.key === 'Escape') closeModal();\n });\n\n // ─── Stats ───\n async function loadStats() {\n var r = await fetch('/api/stats');\n var d = await r.json();\n var grid = document.getElementById('statsGrid');\n var typeColors = {\n decision: 'var(--sky)',\n learning: 'var(--emerald)',\n error: 'var(--rose)',\n task: 'var(--amber)',\n conversation: 'var(--text-dim)',\n atom: 'var(--accent)'\n };\n var cards = [\n { value: d.total.count, label: 'Total Captures' },\n { value: d.sessions.count, label: 'Sessions' },\n { value: d.byType.length, label: 'Types' }\n ];\n d.byType.forEach(function(t) {\n cards.push({ value: t.count, label: t.type, color: typeColors[t.type] || 'var(--text)' });\n });\n grid.innerHTML = cards.map(function(c) {\n return '<div class=\"stat-card\">'\n + '<div class=\"stat-value\" style=\"' + (c.color ? 'color:' + c.color : '') + '\">' + c.value + '</div>'\n + '<div class=\"stat-label\">' + c.label + '</div>'\n + '</div>';\n }).join('');\n }\n\n // ─── Global stats bar ───\n function fmtTok(n) {\n if (n >= 1000000) return (n / 1000000).toFixed(1) + 'M';\n if (n >= 1000) return (n / 1000).toFixed(1) + 'K';\n return String(n);\n }\n async function loadStatsBar() {\n try {\n var [memR, cgR, wikiR, tokR] = await Promise.all([\n fetch('/api/stats').then(function(r) { return r.json(); }),\n fetch('/api/codegraph/stats').then(function(r) { return r.json(); }),\n fetch('/api/wiki/stats').then(function(r) { return r.json(); }),\n fetch('/api/token-stats').then(function(r) { return r.json(); })\n ]);\n var bar = document.getElementById('statsBar');\n var html = ''\n + '<div class=\"stats-bar-group\">'\n + '<span class=\"stats-bar-label\">Memory</span>'\n + '<span class=\"stats-bar-item\"><span class=\"stats-bar-value\">' + memR.total.count + '</span><span class=\"stats-bar-key\">captures</span></span>'\n + '<span class=\"stats-bar-item\"><span class=\"stats-bar-value\">' + memR.sessions.count + '</span><span class=\"stats-bar-key\">sessions</span></span>'\n + '</div>'\n + '<div class=\"stats-bar-divider\"></div>'\n + '<div class=\"stats-bar-group\">'\n + '<span class=\"stats-bar-label\">CodeGraph</span>'\n + '<span class=\"stats-bar-item\"><span class=\"stats-bar-value\">' + cgR.symbols.count + '</span><span class=\"stats-bar-key\">symbols</span></span>'\n + '<span class=\"stats-bar-item\"><span class=\"stats-bar-value\">' + cgR.calls.count + '</span><span class=\"stats-bar-key\">calls</span></span>'\n + '<span class=\"stats-bar-item\"><span class=\"stats-bar-value\">' + cgR.imports.count + '</span><span class=\"stats-bar-key\">imports</span></span>'\n + '</div>'\n + '<div class=\"stats-bar-divider\"></div>'\n + '<div class=\"stats-bar-group\">'\n + '<span class=\"stats-bar-label\">Wiki</span>'\n + '<span class=\"stats-bar-item\"><span class=\"stats-bar-value\">' + wikiR.pages.count + '</span><span class=\"stats-bar-key\">pages</span></span>'\n + '<span class=\"stats-bar-item\"><span class=\"stats-bar-value\">' + wikiR.links.count + '</span><span class=\"stats-bar-key\">links</span></span>'\n + '</div>'\n + '<div class=\"stats-bar-divider\"></div>'\n + '<div class=\"stats-bar-group\">'\n + '<span class=\"stats-bar-label\">Tokens</span>'\n + '<span class=\"stats-bar-item\"><span class=\"stats-bar-value\">' + fmtTok(tokR.stored) + '</span><span class=\"stats-bar-key\">stored</span></span>'\n + '<span class=\"stats-bar-item\"><span class=\"stats-bar-value\">' + fmtTok(tokR.injected) + '</span><span class=\"stats-bar-key\">injected</span></span>'\n + '<span class=\"stats-bar-item\"><span class=\"stats-bar-value\">' + tokR.recalls + '</span><span class=\"stats-bar-key\">recalls</span></span>'\n + '<span class=\"stats-bar-item\"><span class=\"stats-bar-value\">' + tokR.autoCaptured + '</span><span class=\"stats-bar-key\">auto-captured</span></span>'\n + '</div>';\n bar.innerHTML = html;\n } catch(e) {\n document.getElementById('statsBar').innerHTML = '';\n }\n }\n\n // ─── Tab switching ───\n function switchTab(tab) {\n document.querySelectorAll('.nav-tab').forEach(function(t) { t.classList.remove('active'); });\n document.querySelector('[data-tab=\"' + tab + '\"]').classList.add('active');\n document.querySelectorAll('.tab-content').forEach(function(c) { c.style.display = 'none'; });\n var el = document.getElementById('tab-' + tab);\n if (el) el.style.display = '';\n if (tab === 'codegraph') { loadCgStats(); loadSymbols(); }\n if (tab === 'wiki') { loadWikiStats(); loadWiki(); }\n }\n\n // ─── CodeGraph ───\n async function loadCgStats() {\n try {\n var r = await fetch('/api/codegraph/stats');\n var d = await r.json();\n var grid = document.getElementById('cgStatsGrid');\n var cards = [\n { value: d.symbols.count, label: 'Symbols', color: 'var(--accent)' },\n { value: d.calls.count, label: 'Calls', color: 'var(--sky)' },\n { value: d.imports.count, label: 'Imports', color: 'var(--emerald)' }\n ];\n (d.byLang || []).forEach(function(l) {\n cards.push({ value: l.count, label: l.language, color: 'var(--text-dim)' });\n });\n grid.innerHTML = cards.map(function(c) {\n return '<div class=\"stat-card\">'\n + '<div class=\"stat-value\" style=\"' + (c.color ? 'color:' + c.color : '') + '\">' + c.value + '</div>'\n + '<div class=\"stat-label\">' + c.label + '</div>'\n + '</div>';\n }).join('');\n } catch(e) {\n document.getElementById('cgStatsGrid').innerHTML = '<p style=\"color:var(--text-dim);padding:1.5rem 0\">No CodeGraph data. Run: remem-mcp index --path src --repo .</p>';\n }\n }\n\n async function loadSymbols() {\n var q = document.getElementById('cgSearch').value;\n var url = '/api/codegraph/symbols?limit=100' + (q ? '&q=' + encodeURIComponent(q) : '');\n var r = await fetch(url);\n var rows = await r.json();\n var list = document.getElementById('cgList');\n if (!rows || rows.length === 0) {\n list.innerHTML = '<p style=\"color:var(--text-dim);padding:2rem 0;text-align:center;grid-column:1/-1\">No symbols found.</p>';\n return;\n }\n list.innerHTML = rows.map(function(s) {\n return '<div class=\"item-card\" onclick=\"showSymbolDetails(\\\\''+s.id+'\\\\')\">'\n + '<div class=\"item-card-head\">'\n + '<span class=\"item-kind\">' + s.kind + '</span>'\n + '<span class=\"item-lang\">' + s.language + '</span>'\n + '</div>'\n + '<div class=\"item-name\">' + escapeHtml(s.name) + '</div>'\n + '<div class=\"item-file\">' + escapeHtml(s.file_path) + ':' + s.line_start + '</div>'\n + '</div>';\n }).join('');\n }\n\n async function showSymbolDetails(id) {\n var r1 = await fetch('/api/codegraph/callers?id=' + id);\n var callers = await r1.json();\n var r2 = await fetch('/api/codegraph/callees?id=' + id);\n var callees = await r2.json();\n var html = '<div class=\"symbol-detail\">'\n + '<h4>Callers (' + callers.length + ')</h4>'\n + (callers.length ? callers.map(function(c) {\n return '<div class=\"row\">' + c.kind + ' <b>' + escapeHtml(c.name) + '</b> ' + escapeHtml(c.file_path) + ':' + c.line + '</div>';\n }).join('') : '<div class=\"none\">None</div>')\n + '<h4>Callees (' + callees.length + ')</h4>'\n + (callees.length ? callees.map(function(c) {\n return c.name\n ? '<div class=\"row\">' + c.kind + ' <b>' + escapeHtml(c.name) + '</b> ' + escapeHtml(c.file_path) + ':' + c.line + '</div>'\n : '<div class=\"row\"><b>' + escapeHtml(c.callee_name) + '</b> <span class=\"none\">unresolved</span></div>';\n }).join('') : '<div class=\"none\">None</div>')\n + '</div>'\n + '<button class=\"impact-btn\" onclick=\"loadImpact(\\\\'' + id + '\\\\')\">Show Impact Analysis</button>';\n document.getElementById('modalTitle').textContent = 'Symbol Details';\n document.getElementById('modalBody').innerHTML = html;\n document.getElementById('modalConfirm').style.display = 'none';\n document.getElementById('modalOverlay').classList.add('active');\n }\n\n async function loadImpact(id) {\n var r = await fetch('/api/codegraph/impact?id=' + id);\n var data = await r.json();\n if (data.error) {\n document.getElementById('modalBody').innerHTML = '<div class=\"symbol-detail\"><div class=\"none\">' + escapeHtml(data.error) + '</div></div>';\n return;\n }\n var root = data.root;\n var affected = data.affected;\n var maxDepth = 0;\n affected.forEach(function(a) { if (a.depth > maxDepth) maxDepth = a.depth; });\n var fileCount = {};\n affected.forEach(function(a) { fileCount[a.file_path] = (fileCount[a.file_path] || 0) + 1; });\n var uniqueFiles = Object.keys(fileCount).length;\n\n var html = '<div class=\"symbol-detail\">'\n + '<div class=\"impact-tree-root\">'\n + '<small>Root: if you change this</small>'\n + escapeHtml(root.kind) + ' <b>' + escapeHtml(root.name) + '</b>'\n + '<div class=\"impact-file\">' + escapeHtml(root.file_path) + ':' + root.line + '</div>'\n + '</div>'\n + '<div class=\"impact-summary\">'\n + '<b>' + affected.length + '</b> symbols affected across <b>' + uniqueFiles + '</b> files, max depth <b>' + maxDepth + '</b>'\n + '</div>'\n + '<div class=\"impact-tree\">';\n\n if (affected.length === 0) {\n html += '<div class=\"none\">No affected symbols. This symbol has no callers.</div>';\n } else {\n affected.forEach(function(a) {\n html += '<div class=\"impact-node\" style=\"--depth:' + a.depth + '\">'\n + '<span class=\"impact-depth\">d' + a.depth + '</span>'\n + a.kind + ' <b>' + escapeHtml(a.name) + '</b> '\n + '<span class=\"impact-file\">' + escapeHtml(a.file_path) + ':' + a.line + '</span>'\n + '</div>';\n });\n }\n\n html += '</div></div>'\n + '<button class=\"impact-btn\" onclick=\"showSymbolDetails(\\\\'' + id + '\\\\')\">Back to Details</button>';\n\n document.getElementById('modalTitle').textContent = 'Impact Analysis';\n document.getElementById('modalBody').innerHTML = html;\n }\n window.loadImpact = loadImpact;\n\n // ─── Wiki ───\n async function loadWikiStats() {\n try {\n var r = await fetch('/api/wiki/stats');\n var d = await r.json();\n var grid = document.getElementById('wikiStatsGrid');\n var cards = [\n { value: d.pages.count, label: 'Pages', color: 'var(--accent)' },\n { value: d.links.count, label: 'Links', color: 'var(--sky)' }\n ];\n grid.innerHTML = cards.map(function(c) {\n return '<div class=\"stat-card\">'\n + '<div class=\"stat-value\" style=\"color:' + c.color + '\">' + c.value + '</div>'\n + '<div class=\"stat-label\">' + c.label + '</div>'\n + '</div>';\n }).join('');\n } catch(e) {\n document.getElementById('wikiStatsGrid').innerHTML = '<p style=\"color:var(--text-dim);padding:1.5rem 0\">No Wiki data. Run: remem-mcp wiki ingest --path docs --repo .</p>';\n }\n }\n\n async function loadWiki() {\n var q = document.getElementById('wikiSearch').value;\n var url = '/api/wiki/pages?limit=100' + (q ? '&q=' + encodeURIComponent(q) : '');\n var r = await fetch(url);\n var rows = await r.json();\n var list = document.getElementById('wikiList');\n if (!rows || rows.length === 0) {\n list.innerHTML = '<p style=\"color:var(--text-dim);padding:2rem 0;text-align:center;grid-column:1/-1\">No wiki pages found.</p>';\n return;\n }\n list.innerHTML = rows.map(function(p) {\n return '<div class=\"item-card\">'\n + '<div class=\"item-card-head\">'\n + '<span class=\"item-kind\">page</span>'\n + '</div>'\n + '<div class=\"item-name\">' + escapeHtml(p.title) + '</div>'\n + '<div class=\"item-file\">' + escapeHtml(p.source_file) + '</div>'\n + '</div>';\n }).join('');\n }\n\n // ─── Captures ───\n async function loadCaptures() {\n var type = document.getElementById('typeFilter').value;\n var params = new URLSearchParams({ limit: 100 });\n if (type) params.set('type', type);\n var r = await fetch('/api/captures?' + params);\n var rows = await r.json();\n renderList(rows);\n }\n\n async function doSearch() {\n var q = document.getElementById('search').value.trim();\n if (!q) { loadCaptures(); return; }\n var r = await fetch('/api/search?q=' + encodeURIComponent(q));\n var rows = await r.json();\n renderList(rows);\n }\n\n function renderList(rows) {\n var el = document.getElementById('list');\n if (rows.length === 0) {\n el.className = '';\n el.innerHTML = '<div class=\"empty-state\">'\n + '<h3>No captures found</h3>'\n + '<p>Try adjusting your filters or search query. Captures will appear here as your agent learns.</p>'\n + '</div>';\n return;\n }\n el.className = 'capture-grid';\n el.innerHTML = rows.map(function(r) {\n var tags = r.tags ? JSON.parse(r.tags) : [];\n var date = new Date(r.created_at).toISOString().split('T')[0];\n var needsExpand = r.content.length > 500;\n return '<div class=\"capture-card\" data-id=\"' + r.id + '\">'\n + '<div class=\"capture-meta\">'\n + '<span class=\"type-badge type-' + r.type + '\">' + r.type + '</span>'\n + '<span class=\"capture-agent\">' + escapeHtml(r.agent_id || '') + '</span>'\n + '<span class=\"capture-date\">' + date + '</span>'\n + '</div>'\n + '<div class=\"capture-content\" id=\"content-' + r.id + '\">' + escapeHtml(r.content) + '</div>'\n + (tags.length > 0 ? '<div class=\"capture-tags\">' + tags.map(function(t) {\n return '<span class=\"tag\">' + escapeHtml(t) + '</span>';\n }).join('') + '</div>' : '')\n + '<div class=\"capture-actions\">'\n + (needsExpand ? '<button class=\"btn-expand\" onclick=\"toggleExpand(\\\\'' + r.id + '\\\\')\">Show more</button>' : '<span></span>')\n + '<button class=\"btn-delete-card\" onclick=\"deleteCapture(\\\\'' + r.id + '\\\\')\" title=\"Delete\">x</button>'\n + '</div>'\n + '</div>';\n }).join('');\n }\n\n function toggleExpand(id) {\n var content = document.getElementById('content-' + id);\n var fade = document.getElementById('fade-' + id);\n var btn = content.parentElement.querySelector('.btn-expand');\n if (content.classList.contains('expanded')) {\n content.classList.remove('expanded');\n if (fade) fade.style.opacity = '1';\n if (btn) btn.textContent = 'Show more';\n } else {\n content.classList.add('expanded');\n if (fade) fade.style.opacity = '0';\n if (btn) btn.textContent = 'Show less';\n }\n }\n\n function escapeHtml(s) {\n var d = document.createElement('div');\n d.textContent = s;\n return d.innerHTML;\n }\n\n // ─── Delete actions ───\n async function deleteCapture(id) {\n showModal('Delete capture?', 'This capture will be permanently removed from memory.', async function() {\n var r = await fetch('/api/delete', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ id: id }),\n });\n if (r.ok) {\n showToast('Capture deleted');\n loadStats();\n loadCaptures();\n } else {\n var err = await r.json();\n showToast('Delete failed: ' + (err.error || 'unknown error'));\n }\n });\n }\n\n async function deleteByType() {\n var type = document.getElementById('typeFilter').value;\n if (!type) {\n showToast('Select a type first');\n return;\n }\n showModal(\n 'Delete all ' + type + ' captures?',\n 'All captures of type ' + type + ' will be permanently deleted.',\n async function() {\n var r = await fetch('/api/delete-by-type', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ type: type }),\n });\n if (r.ok) {\n var d = await r.json();\n showToast('Deleted ' + d.deleted + ' capture(s)');\n loadStats();\n loadCaptures();\n } else {\n var err = await r.json();\n showToast('Delete failed: ' + (err.error || 'unknown error'));\n }\n }\n );\n }\n\n async function clearAll() {\n showModal(\n 'Clear all memory?',\n 'All captures will be permanently deleted. This action cannot be undone.',\n async function() {\n var r = await fetch('/api/clear-all', { method: 'POST' });\n if (r.ok) {\n var d = await r.json();\n showToast('Deleted ' + d.deleted + ' capture(s)');\n loadStats();\n loadCaptures();\n } else {\n var err = await r.json();\n showToast('Clear failed: ' + (err.error || 'unknown error'));\n }\n }\n );\n }\n\n // ─── Theme ───\n function getStoredTheme() {\n try { return localStorage.getItem('remem-theme'); } catch(e) { return null; }\n }\n function setStoredTheme(t) {\n try { localStorage.setItem('remem-theme', t); } catch(e) {}\n }\n function applyTheme(t) {\n document.documentElement.setAttribute('data-theme', t);\n var btn = document.getElementById('themeToggle');\n if (btn) btn.innerHTML = t === 'dark' ? '&#9728;' : '&#9680;';\n }\n function toggleTheme() {\n var cur = document.documentElement.getAttribute('data-theme') || 'dark';\n applyTheme(cur === 'dark' ? 'light' : 'dark');\n }\n (function() {\n var stored = getStoredTheme();\n if (stored) {\n applyTheme(stored);\n } else {\n var prefersLight = window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches;\n applyTheme(prefersLight ? 'light' : 'dark');\n }\n })();\n\n // ─── Init ───\n document.getElementById('search').addEventListener('keydown', function(e) {\n if (e.key === 'Enter') doSearch();\n });\n\n loadStatsBar();\n loadStats();\n loadCaptures();\n loadCgStats();\n loadSymbols();\n loadWikiStats();\n loadWiki();\n</script>\n</body>\n</html>`;\n}\n"],"mappings":"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AA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA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","names":["existsSync","readFileSync","statSync","homedir","dirname","join","fileURLToPath","Database","sqliteVec","__dirname","line","existsSync","mkdirSync","dirname","join","createHash","existsSync","mkdirSync","readFileSync","dirname","join","fileURLToPath","Database","sqliteVec","dirname","fileURLToPath","join","mkdirSync","Database","readFileSync","createHash","existsSync","prompt","type","line","prompt","errors","output","teamId","type","entries","existsSync","homedir","join","Database","existsSync","readFileSync","homedir","join","homedir","join","existsSync","readFileSync","defaultDbPath","existsSync","readFileSync","homedir","join","existsSync","readFileSync","join","homedir","homedir","join","Database","defaultDbPath","resolved","days","status","type","writeFileSync","Database","execSync","spawn","createHash","appendFileSync","existsSync","mkdirSync","readFileSync","writeFileSync","homedir","tmpdir","dirname","join","Database","line","output","db","sessionKey","id","content","generateId","driftHit","cwd","basename","lines","errors","decayed","sqliteVec","LocalEmbedder","sleep","fileURLToPath","indexFile","execFileSync","existsSync","mkdirSync","readFileSync","writeFileSync","homedir","dirname","join","hooks","existsSync","readFileSync","dirname","join","fileURLToPath","Database","sqliteVec","__dirname","ensureSchema","existsSync","mkdirSync","readFileSync","writeFileSync","homedir","dirname","join","existsSync","mkdirSync","readFileSync","writeFileSync","homedir","dirname","join","createHash","appendFileSync","existsSync","mkdirSync","dirname","line","createHash","createHash","type","status","statSync","Database","existsSync","readFileSync","homedir","join","Database","line","existsSync","readFileSync","homedir","join","Database","Database","type","join","homedir","existsSync","readFileSync","line","defaultDbPath","join","homedir","Database","dirname","fileURLToPath","readFileSync","existsSync","Memory","statSync","output","estimateTokens","type"]}