open-mem 0.10.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/mcp.js CHANGED
@@ -1,60 +1,60 @@
1
1
  #!/usr/bin/env bun
2
2
  // @bun
3
- var q0=Object.defineProperty;var h0=(E,M)=>{for(var N in M)q0(E,N,{get:M[N],enumerable:!0,configurable:!0,set:(_)=>M[N]=()=>_})};var kE=(E,M)=>()=>(E&&(M=E(E=0)),M);var D=import.meta.require;import{existsSync as n0,readFileSync as d0}from"fs";function i0(){let E={};if(process.env.OPEN_MEM_DB_PATH)E.dbPath=process.env.OPEN_MEM_DB_PATH;if(process.env.OPEN_MEM_PROVIDER)E.provider=process.env.OPEN_MEM_PROVIDER;if(process.env.OPEN_MEM_MODEL)E.model=process.env.OPEN_MEM_MODEL;if(process.env.OPEN_MEM_MAX_CONTEXT_TOKENS)E.maxContextTokens=Number.parseInt(process.env.OPEN_MEM_MAX_CONTEXT_TOKENS,10);if(process.env.OPEN_MEM_COMPRESSION==="false")E.compressionEnabled=!1;if(process.env.OPEN_MEM_CONTEXT_INJECTION==="false")E.contextInjectionEnabled=!1;if(process.env.OPEN_MEM_IGNORED_TOOLS)E.ignoredTools=process.env.OPEN_MEM_IGNORED_TOOLS.split(",").map((M)=>M.trim());if(process.env.OPEN_MEM_BATCH_SIZE)E.batchSize=Number.parseInt(process.env.OPEN_MEM_BATCH_SIZE,10);if(process.env.OPEN_MEM_RETENTION_DAYS)E.retentionDays=Number.parseInt(process.env.OPEN_MEM_RETENTION_DAYS,10);if(process.env.OPEN_MEM_LOG_LEVEL)E.logLevel=process.env.OPEN_MEM_LOG_LEVEL;if(process.env.OPEN_MEM_CONTEXT_SHOW_TOKEN_COSTS==="false")E.contextShowTokenCosts=!1;if(process.env.OPEN_MEM_CONTEXT_TYPES)E.contextObservationTypes=process.env.OPEN_MEM_CONTEXT_TYPES==="all"?"all":process.env.OPEN_MEM_CONTEXT_TYPES.split(",").map((M)=>M.trim());if(process.env.OPEN_MEM_CONTEXT_FULL_COUNT)E.contextFullObservationCount=Number.parseInt(process.env.OPEN_MEM_CONTEXT_FULL_COUNT,10);if(process.env.OPEN_MEM_MAX_OBSERVATIONS)E.maxObservations=Number.parseInt(process.env.OPEN_MEM_MAX_OBSERVATIONS,10);if(process.env.OPEN_MEM_CONTEXT_SHOW_LAST_SUMMARY==="false")E.contextShowLastSummary=!1;if(process.env.OPEN_MEM_RATE_LIMITING==="false")E.rateLimitingEnabled=!1;if(process.env.OPEN_MEM_FOLDER_CONTEXT==="false")E.folderContextEnabled=!1;if(process.env.OPEN_MEM_FOLDER_CONTEXT_MAX_DEPTH)E.folderContextMaxDepth=Number.parseInt(process.env.OPEN_MEM_FOLDER_CONTEXT_MAX_DEPTH,10);if(process.env.OPEN_MEM_FOLDER_CONTEXT_MODE==="single")E.folderContextMode="single";if(process.env.OPEN_MEM_FOLDER_CONTEXT_MODE==="dispersed")E.folderContextMode="dispersed";if(process.env.OPEN_MEM_FOLDER_CONTEXT_FILENAME)E.folderContextFilename=process.env.OPEN_MEM_FOLDER_CONTEXT_FILENAME;if(process.env.OPEN_MEM_DAEMON==="true")E.daemonEnabled=!0;if(process.env.OPEN_MEM_DASHBOARD==="true")E.dashboardEnabled=!0;if(process.env.OPEN_MEM_DASHBOARD_PORT)E.dashboardPort=Number.parseInt(process.env.OPEN_MEM_DASHBOARD_PORT,10);if(process.env.OPEN_MEM_PLATFORM_OPENCODE==="false")E.platformOpenCodeEnabled=!1;if(process.env.OPEN_MEM_PLATFORM_CLAUDE_CODE==="true")E.platformClaudeCodeEnabled=!0;if(process.env.OPEN_MEM_PLATFORM_CURSOR==="true")E.platformCursorEnabled=!0;if(process.env.OPEN_MEM_MCP_COMPAT_MODE)E.mcpCompatibilityMode=process.env.OPEN_MEM_MCP_COMPAT_MODE;if(process.env.OPEN_MEM_MCP_PROTOCOL_VERSION)E.mcpProtocolVersion=process.env.OPEN_MEM_MCP_PROTOCOL_VERSION;if(process.env.OPEN_MEM_MCP_SUPPORTED_PROTOCOLS)E.mcpSupportedProtocolVersions=process.env.OPEN_MEM_MCP_SUPPORTED_PROTOCOLS.split(",").map((M)=>M.trim()).filter(Boolean);if(process.env.OPEN_MEM_EMBEDDING_DIMENSION)E.embeddingDimension=Number.parseInt(process.env.OPEN_MEM_EMBEDDING_DIMENSION,10);if(process.env.OPEN_MEM_CONFLICT_RESOLUTION==="true")E.conflictResolutionEnabled=!0;if(process.env.OPEN_MEM_CONFLICT_BAND_LOW){let M=Number.parseFloat(process.env.OPEN_MEM_CONFLICT_BAND_LOW);if(!Number.isNaN(M))E.conflictSimilarityBandLow=M}if(process.env.OPEN_MEM_CONFLICT_BAND_HIGH){let M=Number.parseFloat(process.env.OPEN_MEM_CONFLICT_BAND_HIGH);if(!Number.isNaN(M))E.conflictSimilarityBandHigh=M}if(process.env.OPEN_MEM_USER_MEMORY==="true")E.userMemoryEnabled=!0;if(process.env.OPEN_MEM_USER_MEMORY_DB_PATH)E.userMemoryDbPath=process.env.OPEN_MEM_USER_MEMORY_DB_PATH;if(process.env.OPEN_MEM_USER_MEMORY_MAX_TOKENS)E.userMemoryMaxContextTokens=Number.parseInt(process.env.OPEN_MEM_USER_MEMORY_MAX_TOKENS,10);if(process.env.OPEN_MEM_RERANKING==="true")E.rerankingEnabled=!0;if(process.env.OPEN_MEM_RERANKING_MAX_CANDIDATES)E.rerankingMaxCandidates=Number.parseInt(process.env.OPEN_MEM_RERANKING_MAX_CANDIDATES,10);if(process.env.OPEN_MEM_ENTITY_EXTRACTION==="true")E.entityExtractionEnabled=!0;if(process.env.OPEN_MEM_FALLBACK_PROVIDERS)E.fallbackProviders=process.env.OPEN_MEM_FALLBACK_PROVIDERS.split(",").map((M)=>M.trim()).filter(Boolean);return E}function a0(E){let M=`${E}/.open-mem/config.json`;if(!n0(M))return{};try{let N=d0(M,"utf-8"),_=JSON.parse(N);if(!_||typeof _!=="object"||Array.isArray(_))return{};return _}catch{return{}}}function r0(E){switch(E){case"google":return 768;case"openai":return 1536;case"bedrock":return 1024;case"anthropic":return 0;case"openrouter":return 0;default:return 768}}function h(E,M){let N=a0(E),_=i0(),J={...fE,...N,..._,...M};if(!J.dbPath.startsWith("/"))J.dbPath=`${E}/${J.dbPath}`;if(!process.env.OPEN_MEM_PROVIDER&&!M?.provider){if(process.env.GOOGLE_GENERATIVE_AI_API_KEY||process.env.GEMINI_API_KEY)J.provider="google";else if(process.env.ANTHROPIC_API_KEY)J.provider="anthropic";else if(process.env.AWS_BEARER_TOKEN_BEDROCK||process.env.AWS_ACCESS_KEY_ID||process.env.AWS_PROFILE)J.provider="bedrock";else if(process.env.OPENROUTER_API_KEY)J.provider="openrouter"}if(!J.apiKey)switch(J.provider){case"google":J.apiKey=process.env.GOOGLE_GENERATIVE_AI_API_KEY||process.env.GEMINI_API_KEY;break;case"anthropic":J.apiKey=process.env.ANTHROPIC_API_KEY;break;case"openai":J.apiKey=process.env.OPENAI_API_KEY;break;case"openrouter":J.apiKey=process.env.OPENROUTER_API_KEY;break;case"bedrock":break}if(J.provider==="openrouter"&&J.model==="gemini-2.5-flash-lite")J.model="google/gemini-2.5-flash-lite";if(J.embeddingDimension===void 0)J.embeddingDimension=r0(J.provider);return J}function EE(){return{...fE}}var fE;var ME=kE(()=>{fE={dbPath:".open-mem/memory.db",provider:"google",apiKey:void 0,model:"gemini-2.5-flash-lite",maxTokensPerCompression:1024,compressionEnabled:!0,contextInjectionEnabled:!0,maxContextTokens:4000,batchSize:5,batchIntervalMs:30000,ignoredTools:[],minOutputLength:50,maxIndexEntries:20,sensitivePatterns:[],retentionDays:90,maxDatabaseSizeMb:500,logLevel:"warn",contextShowTokenCosts:!0,contextObservationTypes:"all",contextFullObservationCount:3,maxObservations:50,contextShowLastSummary:!0,rateLimitingEnabled:!0,folderContextEnabled:!0,folderContextMaxDepth:5,folderContextMode:"dispersed",folderContextFilename:"AGENTS.md",daemonEnabled:!1,dashboardEnabled:!1,dashboardPort:3737,platformOpenCodeEnabled:!0,platformClaudeCodeEnabled:!1,platformCursorEnabled:!1,mcpCompatibilityMode:"strict",mcpProtocolVersion:"2024-11-05",mcpSupportedProtocolVersions:["2024-11-05"],embeddingDimension:void 0,conflictResolutionEnabled:!1,conflictSimilarityBandLow:0.7,conflictSimilarityBandHigh:0.92,userMemoryEnabled:!1,userMemoryDbPath:"~/.config/open-mem/user-memory.db",userMemoryMaxContextTokens:1000,rerankingEnabled:!1,rerankingMaxCandidates:20,entityExtractionEnabled:!1,fallbackProviders:void 0}});var J0={};h0(J0,{writeProjectConfig:()=>_0,validatePatch:()=>ZE,readProjectConfig:()=>b,previewConfig:()=>jM,patchConfig:()=>TM,getEffectiveConfig:()=>v,getConfigSchema:()=>kM});import{existsSync as RM}from"fs";import{mkdir as WM,readFile as YM,writeFile as LM}from"fs/promises";import{dirname as BM,join as GM}from"path";function M0(E){return GM(E,".open-mem","config.json")}function N0(E){return E0.find((M)=>M.key===E)}function FM(E,M){let N=N0(E);if(!N)return null;if(N.type==="string"&&typeof M!=="string")return`${String(E)} must be a string`;if(N.type==="number"&&typeof M!=="number")return`${String(E)} must be a number`;if(N.type==="boolean"&&typeof M!=="boolean")return`${String(E)} must be a boolean`;if(N.type==="array"&&!Array.isArray(M))return`${String(E)} must be an array`;if(N.enum&&typeof M==="string"&&!N.enum.includes(M))return`${String(E)} must be one of: ${N.enum.join(", ")}`;if(typeof M==="number"){if(N.min!==void 0&&M<N.min)return`${String(E)} must be >= ${N.min}`;if(N.max!==void 0&&M>N.max)return`${String(E)} must be <= ${N.max}`}return null}function kM(){return E0}async function b(E){let M=M0(E);if(!RM(M))return{};try{let N=await YM(M,"utf-8"),_=JSON.parse(N);if(!_||typeof _!=="object"||Array.isArray(_))return{};return _}catch{return{}}}async function _0(E,M){let N=M0(E),J={...await b(E),...M};await WM(BM(N),{recursive:!0}),await LM(N,JSON.stringify(J,null,2),"utf-8")}function ZE(E){let M=[];for(let[N,_]of Object.entries(E)){let S=FM(N,_);if(S)M.push(S)}return M}async function v(E){let M=EE(),N=await b(E),_=h(E),J=[],S={};for(let[V,A]of Object.entries(M)){let $=V,O=N0($),Z=(DM[$]??[]).some((z)=>typeof process.env[z]==="string"),Y=Object.hasOwn(N,$),H="default";if(Y)H="file";if(Z)H="env";if(S[$]={source:H,locked:Z,restartRequired:O?.restartRequired??!1,liveApply:O?.liveApply??!1},H==="env"&&Y)J.push(`${String($)} is overridden by environment variable.`);if(_[$]===void 0&&A!==void 0)J.push(`${String($)} resolved to undefined unexpectedly.`)}return{config:_,meta:S,warnings:J}}async function jM(E,M){let N=ZE(M);if(N.length>0)return{...await v(E),warnings:N};let _=EE(),J=await b(E),S={..._,...J,...M},A={...h(E,M),...S},$=(await v(E)).meta;return{config:A,meta:$,warnings:[]}}async function TM(E,M){let N=ZE(M);if(N.length>0)return{...await v(E),warnings:N};return await _0(E,M),v(E)}var E0,DM;var S0=kE(()=>{ME();E0=[{key:"dbPath",label:"Database Path",type:"string",group:"Storage",liveApply:!1,restartRequired:!0},{key:"provider",label:"Provider",type:"string",group:"AI",liveApply:!1,restartRequired:!0,enum:["google","anthropic","openai","bedrock"]},{key:"model",label:"Model",type:"string",group:"AI",liveApply:!1,restartRequired:!0},{key:"maxTokensPerCompression",label:"Max Tokens Per Compression",type:"number",group:"AI",liveApply:!0,restartRequired:!1,min:128,max:8192},{key:"compressionEnabled",label:"Compression Enabled",type:"boolean",group:"Behavior",liveApply:!0,restartRequired:!1},{key:"contextInjectionEnabled",label:"Context Injection Enabled",type:"boolean",group:"Behavior",liveApply:!0,restartRequired:!1},{key:"maxContextTokens",label:"Max Context Tokens",type:"number",group:"Behavior",liveApply:!0,restartRequired:!1,min:500,max:64000},{key:"batchSize",label:"Batch Size",type:"number",group:"Behavior",liveApply:!0,restartRequired:!1,min:1,max:100},{key:"batchIntervalMs",label:"Batch Interval (ms)",type:"number",group:"Behavior",liveApply:!0,restartRequired:!1,min:1000,max:300000},{key:"ignoredTools",label:"Ignored Tools",type:"array",group:"Filtering",liveApply:!0,restartRequired:!1},{key:"minOutputLength",label:"Min Output Length",type:"number",group:"Filtering",liveApply:!0,restartRequired:!1,min:0,max:1e4},{key:"maxObservations",label:"Max Observations",type:"number",group:"Progressive Disclosure",liveApply:!0,restartRequired:!1,min:1,max:200},{key:"contextFullObservationCount",label:"Full Observation Count",type:"number",group:"Progressive Disclosure",liveApply:!0,restartRequired:!1,min:0,max:20},{key:"contextShowTokenCosts",label:"Show Token Costs",type:"boolean",group:"Progressive Disclosure",liveApply:!0,restartRequired:!1},{key:"sensitivePatterns",label:"Sensitive Patterns",type:"array",group:"Privacy",liveApply:!0,restartRequired:!1},{key:"retentionDays",label:"Retention Days",type:"number",group:"Data Retention",liveApply:!1,restartRequired:!0,min:0,max:3650},{key:"maxDatabaseSizeMb",label:"Max Database Size (MB)",type:"number",group:"Data Retention",liveApply:!1,restartRequired:!0,min:0,max:1e5},{key:"dashboardEnabled",label:"Dashboard Enabled",type:"boolean",group:"Dashboard",liveApply:!1,restartRequired:!0},{key:"dashboardPort",label:"Dashboard Port",type:"number",group:"Dashboard",liveApply:!1,restartRequired:!0,min:1,max:65535},{key:"platformOpenCodeEnabled",label:"OpenCode Adapter",type:"boolean",group:"Advanced",liveApply:!1,restartRequired:!0},{key:"platformClaudeCodeEnabled",label:"Claude Code Adapter",type:"boolean",group:"Advanced",liveApply:!1,restartRequired:!0},{key:"platformCursorEnabled",label:"Cursor Adapter",type:"boolean",group:"Advanced",liveApply:!1,restartRequired:!0},{key:"mcpCompatibilityMode",label:"MCP Compatibility Mode",type:"string",group:"Advanced",liveApply:!1,restartRequired:!0,enum:["strict","legacy"]},{key:"mcpProtocolVersion",label:"MCP Protocol Version",type:"string",group:"Advanced",liveApply:!1,restartRequired:!0},{key:"mcpSupportedProtocolVersions",label:"MCP Supported Protocols",type:"array",group:"Advanced",liveApply:!1,restartRequired:!0},{key:"rerankingEnabled",label:"Reranking Enabled",type:"boolean",group:"Advanced",liveApply:!0,restartRequired:!1},{key:"entityExtractionEnabled",label:"Entity Extraction Enabled",type:"boolean",group:"Advanced",liveApply:!0,restartRequired:!1},{key:"userMemoryEnabled",label:"User Memory Enabled",type:"boolean",group:"Advanced",liveApply:!1,restartRequired:!0},{key:"userMemoryMaxContextTokens",label:"User Memory Max Context Tokens",type:"number",group:"Advanced",liveApply:!0,restartRequired:!1,min:0,max:8000}],DM={dbPath:["OPEN_MEM_DB_PATH"],provider:["OPEN_MEM_PROVIDER"],model:["OPEN_MEM_MODEL"],compressionEnabled:["OPEN_MEM_COMPRESSION"],contextInjectionEnabled:["OPEN_MEM_CONTEXT_INJECTION"],maxContextTokens:["OPEN_MEM_MAX_CONTEXT_TOKENS"],ignoredTools:["OPEN_MEM_IGNORED_TOOLS"],batchSize:["OPEN_MEM_BATCH_SIZE"],retentionDays:["OPEN_MEM_RETENTION_DAYS"],contextShowTokenCosts:["OPEN_MEM_CONTEXT_SHOW_TOKEN_COSTS"],contextFullObservationCount:["OPEN_MEM_CONTEXT_FULL_COUNT"],maxObservations:["OPEN_MEM_MAX_OBSERVATIONS"],dashboardEnabled:["OPEN_MEM_DASHBOARD"],dashboardPort:["OPEN_MEM_DASHBOARD_PORT"],platformOpenCodeEnabled:["OPEN_MEM_PLATFORM_OPENCODE"],platformClaudeCodeEnabled:["OPEN_MEM_PLATFORM_CLAUDE_CODE"],platformCursorEnabled:["OPEN_MEM_PLATFORM_CURSOR"],mcpCompatibilityMode:["OPEN_MEM_MCP_COMPAT_MODE"],mcpProtocolVersion:["OPEN_MEM_MCP_PROTOCOL_VERSION"],mcpSupportedProtocolVersions:["OPEN_MEM_MCP_SUPPORTED_PROTOCOLS"],rerankingEnabled:["OPEN_MEM_RERANKING"],userMemoryEnabled:["OPEN_MEM_USER_MEMORY"]}});import{readFileSync as sM}from"fs";import{join as EN}from"path";import{parseArgs as MN}from"util";import{createInterface as u0}from"readline";import{z as T}from"zod";import{z as X}from"zod";var g=X.enum(["decision","bugfix","feature","refactor","discovery","change"]);function R(E,M={}){return{data:E,error:null,meta:M}}function F(E,M,N){return{data:null,error:{code:E,message:M,details:N},meta:{}}}var K={find:X.object({query:X.string().min(1),scope:X.enum(["project","user","all"]).optional().default("project"),types:X.array(g).optional(),limit:X.number().int().min(1).max(50).optional().default(10),cursor:X.string().optional(),include:X.object({snippets:X.boolean().optional(),scores:X.boolean().optional(),relations:X.boolean().optional()}).optional()}),history:X.object({limit:X.number().int().min(1).max(20).optional().default(5),cursor:X.string().optional(),sessionId:X.string().optional(),anchor:X.string().optional().describe("Observation ID to center the timeline around"),depthBefore:X.number().int().min(0).max(20).optional().default(5).describe("Number of observations to show before the anchor"),depthAfter:X.number().int().min(0).max(20).optional().default(5).describe("Number of observations to show after the anchor")}),get:X.object({ids:X.array(X.string()).min(1),includeHistory:X.boolean().optional().default(!1),limit:X.number().int().min(1).max(50).optional().default(10)}),create:X.object({title:X.string(),type:g,narrative:X.string(),concepts:X.array(X.string()).optional(),files:X.array(X.string()).optional(),importance:X.number().int().min(1).max(5).optional(),scope:X.enum(["project","user"]).optional().default("project")}),revise:X.object({id:X.string(),title:X.string().optional(),narrative:X.string().optional(),type:g.optional(),concepts:X.array(X.string()).optional(),importance:X.number().int().min(1).max(5).optional(),reason:X.string().optional()}),remove:X.object({id:X.string(),reason:X.string().optional()}),transferExport:X.object({scope:X.enum(["project"]).optional().default("project"),type:g.optional(),limit:X.number().int().min(1).optional(),format:X.enum(["json"]).optional().default("json")}),transferImport:X.object({payload:X.string(),mode:X.enum(["skip","merge","replace"]).optional().default("skip")}),maintenance:X.object({action:X.enum(["folderContextDryRun","folderContextClean","folderContextRebuild","folderContextPurge"])}),help:X.object({})};var p0="2024-11-05",v0=T.object({name:T.string().min(1),arguments:T.record(T.string(),T.unknown()).optional()});function g0(E){if(typeof E!=="object"||E===null)return!1;let M=E;return M.jsonrpc==="2.0"&&typeof M.method==="string"}function B(E){let N=T.toJSONSchema(E);return{type:"object",properties:N.properties??{},required:N.required??void 0,additionalProperties:!1}}function jE(E){return E.issues.map((M)=>{return`${M.path.length>0?M.path.join("."):"input"}: ${M.message}`}).join("; ")}class o{memoryEngine;version;compatibilityMode;protocolVersion;supportedProtocolVersions;initialized=!1;pendingOps=[];constructor(E){this.memoryEngine=E.memoryEngine,this.version=E.version,this.compatibilityMode=E.compatibilityMode??"strict",this.protocolVersion=E.protocolVersion??p0,this.supportedProtocolVersions=E.supportedProtocolVersions&&E.supportedProtocolVersions.length>0?E.supportedProtocolVersions:[this.protocolVersion]}start(){let E=u0({input:process.stdin,terminal:!1});E.on("line",(M)=>{let N=M.trim();if(!N)return;try{let _=JSON.parse(N);if(!g0(_)){this.send({jsonrpc:"2.0",id:null,error:{code:-32600,message:"Invalid Request"}});return}this.handle(_)}catch{this.send({jsonrpc:"2.0",id:null,error:{code:-32700,message:"Parse error"}})}}),E.on("close",()=>{Promise.allSettled(this.pendingOps).then(()=>process.exit(0))})}handle(E){if(E.method==="notifications/initialized"){this.initialized=!0;return}if(E.id===void 0||E.id===null)return;if(E.method==="initialize"){this.handleInitialize(E);return}if(!this.initialized&&this.compatibilityMode==="strict"){this.send({jsonrpc:"2.0",id:E.id,error:{code:-32002,message:"Server not initialized"}});return}switch(E.method){case"tools/list":this.send({jsonrpc:"2.0",id:E.id,result:{tools:this.getToolDefinitions()}});return;case"tools/call":{let M=this.handleToolCall(E.id,E.params);this.pendingOps.push(M),M.finally(()=>{this.pendingOps=this.pendingOps.filter((N)=>N!==M)});return}case"ping":this.send({jsonrpc:"2.0",id:E.id,result:{}});return;default:this.send({jsonrpc:"2.0",id:E.id,error:{code:-32601,message:`Method not found: ${E.method}`}})}}handleInitialize(E){let M=typeof E.params?.protocolVersion==="string"?E.params.protocolVersion:this.protocolVersion;if(!this.supportedProtocolVersions.includes(M)){this.send({jsonrpc:"2.0",id:E.id??null,error:{code:-32602,message:`Unsupported protocol version: ${M}`,data:{supported:this.supportedProtocolVersions}}});return}this.initialized=!0,this.send({jsonrpc:"2.0",id:E.id??null,result:{protocolVersion:M,capabilities:{tools:{listChanged:!1}},serverInfo:{name:"open-mem",version:this.version}}})}getToolDefinitions(){return[{name:"mem-find",description:"Search past memories \u2014 decisions, discoveries, gotchas, and session history. Use to recall context from previous sessions before starting work.",inputSchema:B(K.find)},{name:"mem-history",description:"Browse session timeline and summaries. Use to understand what happened in recent sessions or drill into a specific session.",inputSchema:B(K.history)},{name:"mem-get",description:"Fetch full memory details by ID. Use after mem-find or mem-history to get complete narratives, facts, and file lists.",inputSchema:B(K.get)},{name:"mem-create",description:"Save an important observation to memory. Use for decisions + rationale, non-obvious gotchas, user preferences, or cross-session plans that auto-capture wouldn't understand the significance of.",inputSchema:B(K.create)},{name:"mem-revise",description:"Update an existing memory with a new revision. Use when a previous decision changed, a gotcha was resolved, or information became outdated.",inputSchema:B(K.revise)},{name:"mem-remove",description:"Tombstone an obsolete or incorrect memory. Use to clean up memories that are no longer accurate or relevant.",inputSchema:B(K.remove)},{name:"mem-export",description:"Export project memories as portable JSON for backup or transfer between machines.",inputSchema:B(K.transferExport)},{name:"mem-import",description:"Import memories from a JSON export. Skips duplicates by default.",inputSchema:B(K.transferImport)},{name:"mem-maintenance",description:"Run folder context maintenance \u2014 clean, rebuild, purge, or dry-run AGENTS.md files.",inputSchema:B(K.maintenance)},{name:"mem-help",description:"Show detailed memory workflow guidance including when to save, what to save, and memory type reference.",inputSchema:B(K.help)}]}async handleToolCall(E,M){let N=v0.safeParse(M??{});if(!N.success){this.send({jsonrpc:"2.0",id:E,result:{content:[{type:"text",text:JSON.stringify(F("VALIDATION_ERROR",jE(N.error)),null,2)}],isError:!0}});return}let _=N.data.name,J=N.data.arguments??{};try{let S=await this.executeTool(_,J);this.send({jsonrpc:"2.0",id:E,result:S})}catch(S){this.send({jsonrpc:"2.0",id:E,result:{content:[{type:"text",text:JSON.stringify(F("INTERNAL_ERROR",String(S)),null,2)}],isError:!0}})}}async executeTool(E,M){let N=async()=>{switch(E){case"mem-find":{let _=K.find.parse(M),J=await this.memoryEngine.search(_.query,{limit:_.limit,type:_.types?.[0]});return JSON.stringify(R({results:J}),null,2)}case"mem-history":{let _=K.history.parse(M);return JSON.stringify(R({items:await this.memoryEngine.timeline({limit:_.limit,sessionId:_.sessionId,anchor:_.anchor,depthBefore:_.depthBefore,depthAfter:_.depthAfter})}),null,2)}case"mem-get":{let _=K.get.parse(M);return JSON.stringify(R({observations:await this.memoryEngine.recall(_.ids,_.limit)}),null,2)}case"mem-create":{let _=K.create.parse(M),J=await this.memoryEngine.save({..._,sessionId:"mcp"});return JSON.stringify(J?R({observation:J}):F("CONFLICT","Unable to create memory"),null,2)}case"mem-revise":{let _=K.revise.parse(M),J=await this.memoryEngine.update(_);return JSON.stringify(J?R({previousId:_.id,newId:J.id,observation:J}):F("NOT_FOUND",`Observation ${_.id} not found`),null,2)}case"mem-remove":{let _=K.remove.parse(M),J=await this.memoryEngine.delete([_.id]);return JSON.stringify(J>0?R({id:_.id,tombstoned:!0}):F("NOT_FOUND",`Observation ${_.id} not found`),null,2)}case"mem-export":{let _=K.transferExport.parse(M),J=await this.memoryEngine.export("project",{type:_.type,limit:_.limit});return JSON.stringify(R({payload:J,format:_.format}),null,2)}case"mem-import":{let _=K.transferImport.parse(M),J=_.mode==="replace"?"overwrite":"skip-duplicates",S=await this.memoryEngine.import(_.payload,{mode:J});return JSON.stringify(R({imported:S.imported,skipped:S.skipped,mode:_.mode}),null,2)}case"mem-maintenance":{let _=K.maintenance.parse(M);if(_.action==="folderContextDryRun")return JSON.stringify(R(await this.memoryEngine.maintainFolderContext("clean",!0)),null,2);if(_.action==="folderContextClean")return JSON.stringify(R(await this.memoryEngine.maintainFolderContext("clean",!1)),null,2);if(_.action==="folderContextPurge")return JSON.stringify(R(await this.memoryEngine.maintainFolderContext("purge",!1)),null,2);return JSON.stringify(R(await this.memoryEngine.maintainFolderContext("rebuild",!1)),null,2)}case"mem-help":return JSON.stringify(R({guide:this.memoryEngine.guide()}),null,2);default:return JSON.stringify(F("NOT_FOUND",`Unknown tool: ${E}`),null,2)}};try{let _=await N(),J=_.includes('"error": {')&&!_.includes('"error": null');return{content:[{type:"text",text:_}],isError:J}}catch(_){if(_ instanceof T.ZodError)return{content:[{type:"text",text:JSON.stringify(F("VALIDATION_ERROR",jE(_)),null,2)}],isError:!0};return{content:[{type:"text",text:JSON.stringify(F("INTERNAL_ERROR",String(_)),null,2)}],isError:!0}}}send(E){process.stdout.write(`${JSON.stringify(E)}
4
- `)}}function t(E){if(typeof E!=="object"||E===null)return!1;let M=E,N=M.status;if(N===429||N===500||N===503)return!0;let _=M.error;if(typeof _==="object"&&_!==null&&_.type==="overloaded_error")return!0;return!1}function e(E){if(E&&typeof E==="object"){let M=E.status;if(typeof M==="number")return M===400||M===401||M===403}return!1}class s{specificationVersion;provider;modelId;supportedUrls;providers;constructor(E){if(E.length===0)throw Error("At least one provider required");let M=E[0].model;this.specificationVersion=M.specificationVersion,this.provider=M.provider,this.modelId=M.modelId,this.supportedUrls=M.supportedUrls,this.providers=E}async doGenerate(E){let M;for(let N=0;N<this.providers.length;N++){let _=this.providers[N];try{return await _.model.doGenerate(E)}catch(J){if(M=J,e(J))throw J;if(t(J)&&N<this.providers.length-1){let S=this.providers[N+1],V=J.status??"unknown";console.error(`[open-mem] Provider ${_.name} failed (${V}), falling over to ${S.name}`);continue}throw J}}throw M}async doStream(E){let M;for(let N=0;N<this.providers.length;N++){let _=this.providers[N];try{return await _.model.doStream(E)}catch(J){if(M=J,e(J))throw J;if(t(J)&&N<this.providers.length-1){let S=this.providers[N+1],V=J.status??"unknown";console.error(`[open-mem] Provider ${_.name} failed (${V}), falling over to ${S.name}`);continue}throw J}}throw M}}var w0={"claude-sonnet-4-20250514":"us.anthropic.claude-sonnet-4-20250514-v1:0","claude-opus-4-20250514":"us.anthropic.claude-opus-4-20250514-v1:0","claude-3-5-sonnet-20241022":"us.anthropic.claude-3-5-sonnet-20241022-v2:0","claude-3-5-haiku-20241022":"us.anthropic.claude-3-5-haiku-20241022-v1:0","claude-3-haiku-20240307":"anthropic.claude-3-haiku-20240307-v1:0"};function c0(E){if(E.includes("."))return E;return w0[E]||`us.anthropic.${E}-v1:0`}function TE(E){switch(E.provider){case"anthropic":{let{createAnthropic:M}=D("@ai-sdk/anthropic");return M({apiKey:E.apiKey})(E.model)}case"bedrock":{let{createAmazonBedrock:M}=D("@ai-sdk/amazon-bedrock");return M()(c0(E.model))}case"openai":{let{createOpenAI:M}=D("@ai-sdk/openai");return M({apiKey:E.apiKey})(E.model)}case"google":{let{createGoogleGenerativeAI:M}=D("@ai-sdk/google");return M({apiKey:E.apiKey})(E.model)}case"openrouter":{let{createOpenRouter:M}=D("@openrouter/ai-sdk-provider");return M({apiKey:E.apiKey})(E.model)}default:throw Error(`Unknown provider: ${E.provider}. Supported: anthropic, bedrock, openai, google, openrouter`)}}function yE(E){try{switch(E.provider){case"google":{let{createGoogleGenerativeAI:M}=D("@ai-sdk/google");return M({apiKey:E.apiKey}).embedding("text-embedding-004")}case"openai":{let{createOpenAI:M}=D("@ai-sdk/openai");return M({apiKey:E.apiKey}).embedding("text-embedding-3-small")}case"bedrock":{let{createAmazonBedrock:M}=D("@ai-sdk/amazon-bedrock");return M().embedding("amazon.titan-embed-text-v2:0")}case"anthropic":return null;case"openrouter":return null;default:return null}}catch{return null}}var l0={google:"gemini-2.5-flash-lite",anthropic:"claude-sonnet-4-20250514",openai:"gpt-4o-mini",bedrock:"us.anthropic.claude-3-5-haiku-20241022-v1:0",openrouter:"google/gemini-2.5-flash-lite"};function b0(E){switch(E){case"google":return process.env.GOOGLE_GENERATIVE_AI_API_KEY||process.env.GEMINI_API_KEY;case"anthropic":return process.env.ANTHROPIC_API_KEY;case"openai":return process.env.OPENAI_API_KEY;case"openrouter":return process.env.OPENROUTER_API_KEY;case"bedrock":return;default:return}}function mE(E){if(!E.fallbackProviders||E.fallbackProviders.length===0)return[];return E.fallbackProviders.map((M)=>({provider:M,model:l0[M]??"gemini-2.5-flash-lite",apiKey:b0(M)}))}function PE(E,M=[]){let N=TE(E);if(M.length===0)return N;let _=[{name:E.provider,model:N},...M.map((J)=>({name:J.provider,model:TE(J)}))];return new s(_)}ME();import{randomUUID as V0}from"crypto";function o0(E,M){let N=new RegExp(`<${M}[^>]*>([\\s\\S]*?)</${M}>`,"i"),_=E.match(N);return _?_[1].trim():""}function t0(E,M){let N=new RegExp(`<${M}[^>]*>([\\s\\S]*?)</${M}>`,"gi"),_=[];for(let J of E.matchAll(N)){let S=J[1].trim();if(S)_.push(S)}return _}function IE(E){let M=o0(E,"reranked");if(!M)return null;let N=t0(M,"index");if(N.length===0)return null;let _=[];for(let J of N){let S=Number.parseInt(J,10);if(Number.isNaN(S)||S<0)return null;_.push(S)}return _}function k(E){return Math.ceil(E.length/4)}var e0={showTokenCosts:!0,observationTypes:"all",fullObservationCount:3,showLastSummary:!0},u={bugfix:"\uD83D\uDD34",feature:"\uD83D\uDFE3",refactor:"\uD83D\uDD04",change:"\u2705",discovery:"\uD83D\uDD35",decision:"\u2696\uFE0F"};function xE(E,M=e0){let N=[];if(N.push("## open-mem: Past Session Memory"),N.push(""),N.push("**\uD83D\uDCA1 Progressive Disclosure:** This is a compact index showing WHAT was observed and retrieval COST."),N.push("Use `mem-find` to find observations by query, then `mem-get` with IDs to fetch full details."),N.push(""),N.push("**3-Layer Memory Access:**"),N.push("- **Layer 1** `mem-find` \u2014 Find observations by query (returns IDs + summaries)"),N.push("- **Layer 2** `mem-history` \u2014 Browse session history and drill into sessions"),N.push("- **Layer 3** `mem-get` \u2014 Get full details by ID (use IDs from search results or the index below)"),N.push(""),N.push("**\uD83D\uDCDD When to Save (`mem-create`):** Proactively save decisions + rationale, non-obvious gotchas/workarounds, user preferences, and cross-session plans. Auto-capture handles tool executions \u2014 use `mem-create` for insights auto-capture can't understand the significance of. Wrap sensitive content in `<private>` tags to exclude from memory. Call `mem-help` for detailed guidance."),M.showLastSummary&&E.recentSummaries.length>0){N.push(""),N.push("### Recent Sessions"),N.push("| Session | Summary | Decisions |"),N.push("|---------|---------|-----------|");for(let V of E.recentSummaries){let A=V.keyDecisions.length>0?V.keyDecisions.join("; "):"\u2014";N.push(`| ${V.sessionId} | ${V.summary} | ${A} |`)}}let _=M.observationTypes==="all"?E.observationIndex:E.observationIndex.filter((V)=>M.observationTypes.includes(V.type));if(_.length>0){N.push(""),N.push(`### Recent Observations (${_.length} entries)`);let V=EM(_,E.fullObservations);for(let[A,$]of V){if(N.push(""),N.push(`**${A}**`),M.showTokenCosts)N.push("| ID | Type | Title | ~Tokens |"),N.push("|----|------|-------|---------|");else N.push("| ID | Type | Title |"),N.push("|----|------|-------|");for(let O of $){let C=u[O.type]||"\uD83D\uDCDD";if(M.showTokenCosts)N.push(`| ${O.id} | ${C} | ${O.title} | ~${O.tokenCount} |`);else N.push(`| ${O.id} | ${C} | ${O.title} |`)}}}let J=E.fullObservations.slice(0,M.fullObservationCount);if(J.length>0){N.push(""),N.push("### Full Details (most recent)");for(let V of J){let A=u[V.type]||"\uD83D\uDCDD";if(N.push(""),N.push(`#### ${A} ${V.title} (${V.id})`),N.push(V.narrative),V.facts.length>0)N.push(`**Facts:** ${V.facts.map((O)=>`- ${O}`).join(" ")}`);if(V.concepts.length>0)N.push(`**Concepts:** ${V.concepts.join(", ")}`);let $=[...V.filesRead,...V.filesModified];if($.length>0)N.push(`**Files:** ${$.join(", ")}`)}}let S=s0(E);if(S)N.push(""),N.push(S);return N.join(`
5
- `)}function s0(E){let M=0,N=0,_=new Set(E.observationIndex.map((V)=>V.id));for(let V of E.observationIndex)M+=V.tokenCount,N+=V.discoveryTokens;for(let V of E.fullObservations)if(!_.has(V.id))M+=V.tokenCount,N+=V.discoveryTokens;if(N===0)return null;let J=N-M,S=Math.max(0,Math.round(J/N*100));return`### \uD83D\uDCB0 Memory Economics
6
- **Read cost:** ~${M}t | **Discovery cost:** ~${N}t | **Savings:** ${S}% (${J}t saved)`}function EM(E,M){let N=new Map;for(let J of M){let S=J.filesModified[0]||J.filesRead[0];if(S)N.set(J.id,S)}let _=new Map;for(let J of E){let S=N.get(J.id)??"General",V=_.get(S)??[];V.push(J),_.set(S,V)}return _}function qE(E){let M=[];if(M.push("[open-mem] Memory context:"),E.recentSummaries.length>0){M.push(`
3
+ var w0=Object.defineProperty;var g0=(E,M)=>{for(var N in M)w0(E,N,{get:M[N],enumerable:!0,configurable:!0,set:(_)=>M[N]=()=>_})};var t=(E,M)=>()=>(E&&(M=E(E=0)),M);var D=import.meta.require;import{existsSync as o0,readdirSync as t0,readFileSync as e0}from"fs";import{join as xE}from"path";function s0(){if(P)return P;if(P=new Map,!o0(NE))return P;for(let E of t0(NE)){if(!E.endsWith(".json"))continue;try{let M=e0(xE(NE,E),"utf-8"),N=JSON.parse(M);if(N.id&&N.observationTypes&&N.conceptVocabulary)P.set(N.id,N)}catch{}}return P}function hE(){return[...s0().keys()].sort()}var NE,P=null;var uE=t(()=>{NE=xE(import.meta.dir,".")});import{existsSync as EM,readFileSync as MM}from"fs";function NM(){let E={};if(process.env.OPEN_MEM_DB_PATH)E.dbPath=process.env.OPEN_MEM_DB_PATH;if(process.env.OPEN_MEM_PROVIDER)E.provider=process.env.OPEN_MEM_PROVIDER;if(process.env.OPEN_MEM_MODEL)E.model=process.env.OPEN_MEM_MODEL;if(process.env.OPEN_MEM_MAX_CONTEXT_TOKENS)E.maxContextTokens=Number.parseInt(process.env.OPEN_MEM_MAX_CONTEXT_TOKENS,10);if(process.env.OPEN_MEM_COMPRESSION==="false")E.compressionEnabled=!1;if(process.env.OPEN_MEM_CONTEXT_INJECTION==="false")E.contextInjectionEnabled=!1;if(process.env.OPEN_MEM_IGNORED_TOOLS)E.ignoredTools=process.env.OPEN_MEM_IGNORED_TOOLS.split(",").map((M)=>M.trim());if(process.env.OPEN_MEM_BATCH_SIZE)E.batchSize=Number.parseInt(process.env.OPEN_MEM_BATCH_SIZE,10);if(process.env.OPEN_MEM_RETENTION_DAYS)E.retentionDays=Number.parseInt(process.env.OPEN_MEM_RETENTION_DAYS,10);if(process.env.OPEN_MEM_LOG_LEVEL)E.logLevel=process.env.OPEN_MEM_LOG_LEVEL;if(process.env.OPEN_MEM_CONTEXT_SHOW_TOKEN_COSTS==="false")E.contextShowTokenCosts=!1;if(process.env.OPEN_MEM_CONTEXT_TYPES)E.contextObservationTypes=process.env.OPEN_MEM_CONTEXT_TYPES==="all"?"all":process.env.OPEN_MEM_CONTEXT_TYPES.split(",").map((M)=>M.trim());if(process.env.OPEN_MEM_CONTEXT_FULL_COUNT)E.contextFullObservationCount=Number.parseInt(process.env.OPEN_MEM_CONTEXT_FULL_COUNT,10);if(process.env.OPEN_MEM_MAX_OBSERVATIONS)E.maxObservations=Number.parseInt(process.env.OPEN_MEM_MAX_OBSERVATIONS,10);if(process.env.OPEN_MEM_CONTEXT_SHOW_LAST_SUMMARY==="false")E.contextShowLastSummary=!1;if(process.env.OPEN_MEM_RATE_LIMITING==="false")E.rateLimitingEnabled=!1;if(process.env.OPEN_MEM_FOLDER_CONTEXT==="false")E.folderContextEnabled=!1;if(process.env.OPEN_MEM_FOLDER_CONTEXT_MAX_DEPTH)E.folderContextMaxDepth=Number.parseInt(process.env.OPEN_MEM_FOLDER_CONTEXT_MAX_DEPTH,10);if(process.env.OPEN_MEM_FOLDER_CONTEXT_MODE==="single")E.folderContextMode="single";if(process.env.OPEN_MEM_FOLDER_CONTEXT_MODE==="dispersed")E.folderContextMode="dispersed";if(process.env.OPEN_MEM_FOLDER_CONTEXT_FILENAME)E.folderContextFilename=process.env.OPEN_MEM_FOLDER_CONTEXT_FILENAME;if(process.env.OPEN_MEM_DAEMON==="true")E.daemonEnabled=!0;if(process.env.OPEN_MEM_DASHBOARD==="true")E.dashboardEnabled=!0;if(process.env.OPEN_MEM_DASHBOARD_PORT)E.dashboardPort=Number.parseInt(process.env.OPEN_MEM_DASHBOARD_PORT,10);if(process.env.OPEN_MEM_PLATFORM_OPENCODE==="false")E.platformOpenCodeEnabled=!1;if(process.env.OPEN_MEM_PLATFORM_CLAUDE_CODE==="true")E.platformClaudeCodeEnabled=!0;if(process.env.OPEN_MEM_PLATFORM_CURSOR==="true")E.platformCursorEnabled=!0;if(process.env.OPEN_MEM_MCP_COMPAT_MODE)E.mcpCompatibilityMode=process.env.OPEN_MEM_MCP_COMPAT_MODE;if(process.env.OPEN_MEM_MCP_PROTOCOL_VERSION)E.mcpProtocolVersion=process.env.OPEN_MEM_MCP_PROTOCOL_VERSION;if(process.env.OPEN_MEM_MCP_SUPPORTED_PROTOCOLS)E.mcpSupportedProtocolVersions=process.env.OPEN_MEM_MCP_SUPPORTED_PROTOCOLS.split(",").map((M)=>M.trim()).filter(Boolean);if(process.env.OPEN_MEM_EMBEDDING_DIMENSION)E.embeddingDimension=Number.parseInt(process.env.OPEN_MEM_EMBEDDING_DIMENSION,10);if(process.env.OPEN_MEM_CONFLICT_RESOLUTION==="true")E.conflictResolutionEnabled=!0;if(process.env.OPEN_MEM_CONFLICT_BAND_LOW){let M=Number.parseFloat(process.env.OPEN_MEM_CONFLICT_BAND_LOW);if(!Number.isNaN(M))E.conflictSimilarityBandLow=M}if(process.env.OPEN_MEM_CONFLICT_BAND_HIGH){let M=Number.parseFloat(process.env.OPEN_MEM_CONFLICT_BAND_HIGH);if(!Number.isNaN(M))E.conflictSimilarityBandHigh=M}if(process.env.OPEN_MEM_USER_MEMORY==="true")E.userMemoryEnabled=!0;if(process.env.OPEN_MEM_USER_MEMORY_DB_PATH)E.userMemoryDbPath=process.env.OPEN_MEM_USER_MEMORY_DB_PATH;if(process.env.OPEN_MEM_USER_MEMORY_MAX_TOKENS)E.userMemoryMaxContextTokens=Number.parseInt(process.env.OPEN_MEM_USER_MEMORY_MAX_TOKENS,10);if(process.env.OPEN_MEM_RERANKING==="true")E.rerankingEnabled=!0;if(process.env.OPEN_MEM_RERANKING_MAX_CANDIDATES)E.rerankingMaxCandidates=Number.parseInt(process.env.OPEN_MEM_RERANKING_MAX_CANDIDATES,10);if(process.env.OPEN_MEM_ENTITY_EXTRACTION==="true")E.entityExtractionEnabled=!0;if(process.env.OPEN_MEM_FALLBACK_PROVIDERS)E.fallbackProviders=process.env.OPEN_MEM_FALLBACK_PROVIDERS.split(",").map((M)=>M.trim()).filter(Boolean);if(process.env.OPEN_MEM_MODE)E.mode=process.env.OPEN_MEM_MODE;return E}function _M(E){let M=`${E}/.open-mem/config.json`;if(!EM(M))return{};try{let N=MM(M,"utf-8"),_=JSON.parse(N);if(!_||typeof _!=="object"||Array.isArray(_))return{};return _}catch{return{}}}function JM(E){switch(E){case"google":return 768;case"openai":return 1536;case"bedrock":return 1024;case"anthropic":return 0;case"openrouter":return 0;default:return 768}}function f(E,M){let N=_M(E),_=NM(),J={...fE,...N,..._,...M};if(!J.dbPath.startsWith("/"))J.dbPath=`${E}/${J.dbPath}`;if(!process.env.OPEN_MEM_PROVIDER&&!M?.provider){if(process.env.GOOGLE_GENERATIVE_AI_API_KEY||process.env.GEMINI_API_KEY)J.provider="google";else if(process.env.ANTHROPIC_API_KEY)J.provider="anthropic";else if(process.env.AWS_BEARER_TOKEN_BEDROCK||process.env.AWS_ACCESS_KEY_ID||process.env.AWS_PROFILE)J.provider="bedrock";else if(process.env.OPENROUTER_API_KEY)J.provider="openrouter"}if(!J.apiKey)switch(J.provider){case"google":J.apiKey=process.env.GOOGLE_GENERATIVE_AI_API_KEY||process.env.GEMINI_API_KEY;break;case"anthropic":J.apiKey=process.env.ANTHROPIC_API_KEY;break;case"openai":J.apiKey=process.env.OPENAI_API_KEY;break;case"openrouter":J.apiKey=process.env.OPENROUTER_API_KEY;break;case"bedrock":break}if(J.provider==="openrouter"&&J.model==="gemini-2.5-flash-lite")J.model="google/gemini-2.5-flash-lite";if(J.embeddingDimension===void 0)J.embeddingDimension=JM(J.provider);if(J.mode&&!hE().includes(J.mode))J.mode="code";return J}function _E(){return{...fE}}var fE;var JE=t(()=>{uE();fE={dbPath:".open-mem/memory.db",provider:"google",apiKey:void 0,model:"gemini-2.5-flash-lite",maxTokensPerCompression:1024,compressionEnabled:!0,contextInjectionEnabled:!0,maxContextTokens:4000,batchSize:5,batchIntervalMs:30000,ignoredTools:[],minOutputLength:50,maxIndexEntries:20,sensitivePatterns:[],retentionDays:90,maxDatabaseSizeMb:500,logLevel:"warn",contextShowTokenCosts:!0,contextObservationTypes:"all",contextFullObservationCount:3,maxObservations:50,contextShowLastSummary:!0,rateLimitingEnabled:!0,folderContextEnabled:!0,folderContextMaxDepth:5,folderContextMode:"dispersed",folderContextFilename:"AGENTS.md",daemonEnabled:!1,dashboardEnabled:!1,dashboardPort:3737,platformOpenCodeEnabled:!0,platformClaudeCodeEnabled:!1,platformCursorEnabled:!1,mcpCompatibilityMode:"strict",mcpProtocolVersion:"2024-11-05",mcpSupportedProtocolVersions:["2024-11-05"],embeddingDimension:void 0,conflictResolutionEnabled:!1,conflictSimilarityBandLow:0.7,conflictSimilarityBandHigh:0.92,userMemoryEnabled:!1,userMemoryDbPath:"~/.config/open-mem/user-memory.db",userMemoryMaxContextTokens:1000,rerankingEnabled:!1,rerankingMaxCandidates:20,entityExtractionEnabled:!1,fallbackProviders:void 0,mode:"code"}});var O0={};g0(O0,{writeProjectConfig:()=>$0,validatePatch:()=>zE,readProjectConfig:()=>n,previewConfig:()=>uM,patchConfig:()=>fM,getEffectiveConfig:()=>w,getConfigSchema:()=>hM});import{existsSync as jM}from"fs";import{mkdir as TM,readFile as yM,writeFile as PM}from"fs/promises";import{dirname as mM,join as IM}from"path";function S0(E){return IM(E,".open-mem","config.json")}function A0(E){return V0.find((M)=>M.key===E)}function xM(E,M){let N=A0(E);if(!N)return null;if(N.type==="string"&&typeof M!=="string")return`${String(E)} must be a string`;if(N.type==="number"&&typeof M!=="number")return`${String(E)} must be a number`;if(N.type==="boolean"&&typeof M!=="boolean")return`${String(E)} must be a boolean`;if(N.type==="array"&&!Array.isArray(M))return`${String(E)} must be an array`;if(N.enum&&typeof M==="string"&&!N.enum.includes(M))return`${String(E)} must be one of: ${N.enum.join(", ")}`;if(typeof M==="number"){if(N.min!==void 0&&M<N.min)return`${String(E)} must be >= ${N.min}`;if(N.max!==void 0&&M>N.max)return`${String(E)} must be <= ${N.max}`}return null}function hM(){return V0}async function n(E){let M=S0(E);if(!jM(M))return{};try{let N=await yM(M,"utf-8"),_=JSON.parse(N);if(!_||typeof _!=="object"||Array.isArray(_))return{};return _}catch{return{}}}async function $0(E,M){let N=S0(E),J={...await n(E),...M};await TM(mM(N),{recursive:!0}),await PM(N,JSON.stringify(J,null,2),"utf-8")}function zE(E){let M=[];for(let[N,_]of Object.entries(E)){let V=xM(N,_);if(V)M.push(V)}return M}async function w(E){let M=_E(),N=await n(E),_=f(E),J=[],V={};for(let[S,A]of Object.entries(M)){let $=S,O=A0($),U=(qM[$]??[]).some((Q)=>typeof process.env[Q]==="string"),L=Object.hasOwn(N,$),z="default";if(L)z="file";if(U)z="env";if(V[$]={source:z,locked:U,restartRequired:O?.restartRequired??!1,liveApply:O?.liveApply??!1},z==="env"&&L)J.push(`${String($)} is overridden by environment variable.`);if(_[$]===void 0&&A!==void 0)J.push(`${String($)} resolved to undefined unexpectedly.`)}return{config:_,meta:V,warnings:J}}async function uM(E,M){let N=zE(M);if(N.length>0)return{...await w(E),warnings:N};let _=_E(),J=await n(E),V={..._,...J,...M},A={...f(E,M),...V},$=(await w(E)).meta;return{config:A,meta:$,warnings:[]}}async function fM(E,M){let N=zE(M);if(N.length>0)return{...await w(E),warnings:N};return await $0(E,M),w(E)}var V0,qM;var X0=t(()=>{JE();V0=[{key:"dbPath",label:"Database Path",type:"string",group:"Storage",liveApply:!1,restartRequired:!0},{key:"provider",label:"Provider",type:"string",group:"AI",liveApply:!1,restartRequired:!0,enum:["google","anthropic","openai","bedrock"]},{key:"model",label:"Model",type:"string",group:"AI",liveApply:!1,restartRequired:!0},{key:"maxTokensPerCompression",label:"Max Tokens Per Compression",type:"number",group:"AI",liveApply:!0,restartRequired:!1,min:128,max:8192},{key:"compressionEnabled",label:"Compression Enabled",type:"boolean",group:"Behavior",liveApply:!0,restartRequired:!1},{key:"contextInjectionEnabled",label:"Context Injection Enabled",type:"boolean",group:"Behavior",liveApply:!0,restartRequired:!1},{key:"maxContextTokens",label:"Max Context Tokens",type:"number",group:"Behavior",liveApply:!0,restartRequired:!1,min:500,max:64000},{key:"batchSize",label:"Batch Size",type:"number",group:"Behavior",liveApply:!0,restartRequired:!1,min:1,max:100},{key:"batchIntervalMs",label:"Batch Interval (ms)",type:"number",group:"Behavior",liveApply:!0,restartRequired:!1,min:1000,max:300000},{key:"ignoredTools",label:"Ignored Tools",type:"array",group:"Filtering",liveApply:!0,restartRequired:!1},{key:"minOutputLength",label:"Min Output Length",type:"number",group:"Filtering",liveApply:!0,restartRequired:!1,min:0,max:1e4},{key:"maxObservations",label:"Max Observations",type:"number",group:"Progressive Disclosure",liveApply:!0,restartRequired:!1,min:1,max:200},{key:"contextFullObservationCount",label:"Full Observation Count",type:"number",group:"Progressive Disclosure",liveApply:!0,restartRequired:!1,min:0,max:20},{key:"contextShowTokenCosts",label:"Show Token Costs",type:"boolean",group:"Progressive Disclosure",liveApply:!0,restartRequired:!1},{key:"sensitivePatterns",label:"Sensitive Patterns",type:"array",group:"Privacy",liveApply:!0,restartRequired:!1},{key:"retentionDays",label:"Retention Days",type:"number",group:"Data Retention",liveApply:!1,restartRequired:!0,min:0,max:3650},{key:"maxDatabaseSizeMb",label:"Max Database Size (MB)",type:"number",group:"Data Retention",liveApply:!1,restartRequired:!0,min:0,max:1e5},{key:"dashboardEnabled",label:"Dashboard Enabled",type:"boolean",group:"Dashboard",liveApply:!1,restartRequired:!0},{key:"dashboardPort",label:"Dashboard Port",type:"number",group:"Dashboard",liveApply:!1,restartRequired:!0,min:1,max:65535},{key:"platformOpenCodeEnabled",label:"OpenCode Adapter",type:"boolean",group:"Advanced",liveApply:!1,restartRequired:!0},{key:"platformClaudeCodeEnabled",label:"Claude Code Adapter",type:"boolean",group:"Advanced",liveApply:!1,restartRequired:!0},{key:"platformCursorEnabled",label:"Cursor Adapter",type:"boolean",group:"Advanced",liveApply:!1,restartRequired:!0},{key:"mcpCompatibilityMode",label:"MCP Compatibility Mode",type:"string",group:"Advanced",liveApply:!1,restartRequired:!0,enum:["strict","legacy"]},{key:"mcpProtocolVersion",label:"MCP Protocol Version",type:"string",group:"Advanced",liveApply:!1,restartRequired:!0},{key:"mcpSupportedProtocolVersions",label:"MCP Supported Protocols",type:"array",group:"Advanced",liveApply:!1,restartRequired:!0},{key:"rerankingEnabled",label:"Reranking Enabled",type:"boolean",group:"Advanced",liveApply:!0,restartRequired:!1},{key:"entityExtractionEnabled",label:"Entity Extraction Enabled",type:"boolean",group:"Advanced",liveApply:!0,restartRequired:!1},{key:"userMemoryEnabled",label:"User Memory Enabled",type:"boolean",group:"Advanced",liveApply:!1,restartRequired:!0},{key:"userMemoryMaxContextTokens",label:"User Memory Max Context Tokens",type:"number",group:"Advanced",liveApply:!0,restartRequired:!1,min:0,max:8000}],qM={dbPath:["OPEN_MEM_DB_PATH"],provider:["OPEN_MEM_PROVIDER"],model:["OPEN_MEM_MODEL"],compressionEnabled:["OPEN_MEM_COMPRESSION"],contextInjectionEnabled:["OPEN_MEM_CONTEXT_INJECTION"],maxContextTokens:["OPEN_MEM_MAX_CONTEXT_TOKENS"],ignoredTools:["OPEN_MEM_IGNORED_TOOLS"],batchSize:["OPEN_MEM_BATCH_SIZE"],retentionDays:["OPEN_MEM_RETENTION_DAYS"],contextShowTokenCosts:["OPEN_MEM_CONTEXT_SHOW_TOKEN_COSTS"],contextFullObservationCount:["OPEN_MEM_CONTEXT_FULL_COUNT"],maxObservations:["OPEN_MEM_MAX_OBSERVATIONS"],dashboardEnabled:["OPEN_MEM_DASHBOARD"],dashboardPort:["OPEN_MEM_DASHBOARD_PORT"],platformOpenCodeEnabled:["OPEN_MEM_PLATFORM_OPENCODE"],platformClaudeCodeEnabled:["OPEN_MEM_PLATFORM_CLAUDE_CODE"],platformCursorEnabled:["OPEN_MEM_PLATFORM_CURSOR"],mcpCompatibilityMode:["OPEN_MEM_MCP_COMPAT_MODE"],mcpProtocolVersion:["OPEN_MEM_MCP_PROTOCOL_VERSION"],mcpSupportedProtocolVersions:["OPEN_MEM_MCP_SUPPORTED_PROTOCOLS"],rerankingEnabled:["OPEN_MEM_RERANKING"],userMemoryEnabled:["OPEN_MEM_USER_MEMORY"]}});import{readFileSync as $N}from"fs";import{join as ON}from"path";import{parseArgs as XN}from"util";import{createInterface as l0}from"readline";import{z as T}from"zod";import{z as Z}from"zod";var g=Z.enum(["decision","bugfix","feature","refactor","discovery","change"]);function Y(E,M={}){return{data:E,error:null,meta:M}}function F(E,M,N){return{data:null,error:{code:E,message:M,details:N},meta:{}}}var H={find:Z.object({query:Z.string().min(1),scope:Z.enum(["project","user","all"]).optional().default("project"),types:Z.array(g).optional(),limit:Z.number().int().min(1).max(50).optional().default(10),cursor:Z.string().optional(),include:Z.object({snippets:Z.boolean().optional(),scores:Z.boolean().optional(),relations:Z.boolean().optional()}).optional()}),history:Z.object({limit:Z.number().int().min(1).max(20).optional().default(5),cursor:Z.string().optional(),sessionId:Z.string().optional(),anchor:Z.string().optional().describe("Observation ID to center the timeline around"),depthBefore:Z.number().int().min(0).max(20).optional().default(5).describe("Number of observations to show before the anchor"),depthAfter:Z.number().int().min(0).max(20).optional().default(5).describe("Number of observations to show after the anchor")}),get:Z.object({ids:Z.array(Z.string()).min(1),includeHistory:Z.boolean().optional().default(!1),limit:Z.number().int().min(1).max(50).optional().default(10)}),create:Z.object({title:Z.string(),type:g,narrative:Z.string(),concepts:Z.array(Z.string()).optional(),files:Z.array(Z.string()).optional(),importance:Z.number().int().min(1).max(5).optional(),scope:Z.enum(["project","user"]).optional().default("project")}),revise:Z.object({id:Z.string(),title:Z.string().optional(),narrative:Z.string().optional(),type:g.optional(),concepts:Z.array(Z.string()).optional(),importance:Z.number().int().min(1).max(5).optional(),reason:Z.string().optional()}),remove:Z.object({id:Z.string(),reason:Z.string().optional()}),transferExport:Z.object({scope:Z.enum(["project"]).optional().default("project"),type:g.optional(),limit:Z.number().int().min(1).optional(),format:Z.enum(["json"]).optional().default("json")}),transferImport:Z.object({payload:Z.string(),mode:Z.enum(["skip","merge","replace"]).optional().default("skip")}),maintenance:Z.object({action:Z.enum(["folderContextDryRun","folderContextClean","folderContextRebuild","folderContextPurge"])}),help:Z.object({})};var c0="2024-11-05",b0=T.object({name:T.string().min(1),arguments:T.record(T.string(),T.unknown()).optional()});function n0(E){if(typeof E!=="object"||E===null)return!1;let M=E;return M.jsonrpc==="2.0"&&typeof M.method==="string"}function C(E){let N=T.toJSONSchema(E);return{type:"object",properties:N.properties??{},required:N.required??void 0,additionalProperties:!1}}function yE(E){return E.issues.map((M)=>{return`${M.path.length>0?M.path.join("."):"input"}: ${M.message}`}).join("; ")}class e{memoryEngine;version;compatibilityMode;protocolVersion;supportedProtocolVersions;initialized=!1;pendingOps=[];constructor(E){this.memoryEngine=E.memoryEngine,this.version=E.version,this.compatibilityMode=E.compatibilityMode??"strict",this.protocolVersion=E.protocolVersion??c0,this.supportedProtocolVersions=E.supportedProtocolVersions&&E.supportedProtocolVersions.length>0?E.supportedProtocolVersions:[this.protocolVersion]}start(){let E=l0({input:process.stdin,terminal:!1});E.on("line",(M)=>{let N=M.trim();if(!N)return;try{let _=JSON.parse(N);if(!n0(_)){this.send({jsonrpc:"2.0",id:null,error:{code:-32600,message:"Invalid Request"}});return}this.handle(_)}catch{this.send({jsonrpc:"2.0",id:null,error:{code:-32700,message:"Parse error"}})}}),E.on("close",()=>{Promise.allSettled(this.pendingOps).then(()=>process.exit(0))})}handle(E){if(E.method==="notifications/initialized"){this.initialized=!0;return}if(E.id===void 0||E.id===null)return;if(E.method==="initialize"){this.handleInitialize(E);return}if(!this.initialized&&this.compatibilityMode==="strict"){this.send({jsonrpc:"2.0",id:E.id,error:{code:-32002,message:"Server not initialized"}});return}switch(E.method){case"tools/list":this.send({jsonrpc:"2.0",id:E.id,result:{tools:this.getToolDefinitions()}});return;case"tools/call":{let M=this.handleToolCall(E.id,E.params);this.pendingOps.push(M),M.finally(()=>{this.pendingOps=this.pendingOps.filter((N)=>N!==M)});return}case"ping":this.send({jsonrpc:"2.0",id:E.id,result:{}});return;default:this.send({jsonrpc:"2.0",id:E.id,error:{code:-32601,message:`Method not found: ${E.method}`}})}}handleInitialize(E){let M=typeof E.params?.protocolVersion==="string"?E.params.protocolVersion:this.protocolVersion;if(!this.supportedProtocolVersions.includes(M)){this.send({jsonrpc:"2.0",id:E.id??null,error:{code:-32602,message:`Unsupported protocol version: ${M}`,data:{supported:this.supportedProtocolVersions}}});return}this.initialized=!0,this.send({jsonrpc:"2.0",id:E.id??null,result:{protocolVersion:M,capabilities:{tools:{listChanged:!1}},serverInfo:{name:"open-mem",version:this.version}}})}getToolDefinitions(){return[{name:"mem-find",description:"Search past memories \u2014 decisions, discoveries, gotchas, and session history. Use to recall context from previous sessions before starting work.",inputSchema:C(H.find)},{name:"mem-history",description:"Browse session timeline and summaries. Use to understand what happened in recent sessions or drill into a specific session.",inputSchema:C(H.history)},{name:"mem-get",description:"Fetch full memory details by ID. Use after mem-find or mem-history to get complete narratives, facts, and file lists.",inputSchema:C(H.get)},{name:"mem-create",description:"Save an important observation to memory. Use for decisions + rationale, non-obvious gotchas, user preferences, or cross-session plans that auto-capture wouldn't understand the significance of.",inputSchema:C(H.create)},{name:"mem-revise",description:"Update an existing memory with a new revision. Use when a previous decision changed, a gotcha was resolved, or information became outdated.",inputSchema:C(H.revise)},{name:"mem-remove",description:"Tombstone an obsolete or incorrect memory. Use to clean up memories that are no longer accurate or relevant.",inputSchema:C(H.remove)},{name:"mem-export",description:"Export project memories as portable JSON for backup or transfer between machines.",inputSchema:C(H.transferExport)},{name:"mem-import",description:"Import memories from a JSON export. Skips duplicates by default.",inputSchema:C(H.transferImport)},{name:"mem-maintenance",description:"Run folder context maintenance \u2014 clean, rebuild, purge, or dry-run AGENTS.md files.",inputSchema:C(H.maintenance)},{name:"mem-help",description:"Show detailed memory workflow guidance including when to save, what to save, and memory type reference.",inputSchema:C(H.help)}]}async handleToolCall(E,M){let N=b0.safeParse(M??{});if(!N.success){this.send({jsonrpc:"2.0",id:E,result:{content:[{type:"text",text:JSON.stringify(F("VALIDATION_ERROR",yE(N.error)),null,2)}],isError:!0}});return}let _=N.data.name,J=N.data.arguments??{};try{let V=await this.executeTool(_,J);this.send({jsonrpc:"2.0",id:E,result:V})}catch(V){this.send({jsonrpc:"2.0",id:E,result:{content:[{type:"text",text:JSON.stringify(F("INTERNAL_ERROR",String(V)),null,2)}],isError:!0}})}}async executeTool(E,M){let N=async()=>{switch(E){case"mem-find":{let _=H.find.parse(M),J=await this.memoryEngine.search(_.query,{limit:_.limit,type:_.types?.[0]});return JSON.stringify(Y({results:J}),null,2)}case"mem-history":{let _=H.history.parse(M);return JSON.stringify(Y({items:await this.memoryEngine.timeline({limit:_.limit,sessionId:_.sessionId,anchor:_.anchor,depthBefore:_.depthBefore,depthAfter:_.depthAfter})}),null,2)}case"mem-get":{let _=H.get.parse(M);return JSON.stringify(Y({observations:await this.memoryEngine.recall(_.ids,_.limit)}),null,2)}case"mem-create":{let _=H.create.parse(M),J=await this.memoryEngine.save({..._,sessionId:"mcp"});return JSON.stringify(J?Y({observation:J}):F("CONFLICT","Unable to create memory"),null,2)}case"mem-revise":{let _=H.revise.parse(M),J=await this.memoryEngine.update(_);return JSON.stringify(J?Y({previousId:_.id,newId:J.id,observation:J}):F("NOT_FOUND",`Observation ${_.id} not found`),null,2)}case"mem-remove":{let _=H.remove.parse(M),J=await this.memoryEngine.delete([_.id]);return JSON.stringify(J>0?Y({id:_.id,tombstoned:!0}):F("NOT_FOUND",`Observation ${_.id} not found`),null,2)}case"mem-export":{let _=H.transferExport.parse(M),J=await this.memoryEngine.export("project",{type:_.type,limit:_.limit});return JSON.stringify(Y({payload:J,format:_.format}),null,2)}case"mem-import":{let _=H.transferImport.parse(M),J=_.mode==="replace"?"overwrite":"skip-duplicates",V=await this.memoryEngine.import(_.payload,{mode:J});return JSON.stringify(Y({imported:V.imported,skipped:V.skipped,mode:_.mode}),null,2)}case"mem-maintenance":{let _=H.maintenance.parse(M);if(_.action==="folderContextDryRun")return JSON.stringify(Y(await this.memoryEngine.maintainFolderContext("clean",!0)),null,2);if(_.action==="folderContextClean")return JSON.stringify(Y(await this.memoryEngine.maintainFolderContext("clean",!1)),null,2);if(_.action==="folderContextPurge")return JSON.stringify(Y(await this.memoryEngine.maintainFolderContext("purge",!1)),null,2);return JSON.stringify(Y(await this.memoryEngine.maintainFolderContext("rebuild",!1)),null,2)}case"mem-help":return JSON.stringify(Y({guide:this.memoryEngine.guide()}),null,2);default:return JSON.stringify(F("NOT_FOUND",`Unknown tool: ${E}`),null,2)}};try{let _=await N(),J=_.includes('"error": {')&&!_.includes('"error": null');return{content:[{type:"text",text:_}],isError:J}}catch(_){if(_ instanceof T.ZodError)return{content:[{type:"text",text:JSON.stringify(F("VALIDATION_ERROR",yE(_)),null,2)}],isError:!0};return{content:[{type:"text",text:JSON.stringify(F("INTERNAL_ERROR",String(_)),null,2)}],isError:!0}}}send(E){process.stdout.write(`${JSON.stringify(E)}
4
+ `)}}function s(E){if(typeof E!=="object"||E===null)return!1;let M=E,N=M.status;if(N===429||N===500||N===503)return!0;let _=M.error;if(typeof _==="object"&&_!==null&&_.type==="overloaded_error")return!0;return!1}function EE(E){if(E&&typeof E==="object"){let M=E.status;if(typeof M==="number")return M===400||M===401||M===403}return!1}class ME{specificationVersion;provider;modelId;supportedUrls;providers;constructor(E){if(E.length===0)throw Error("At least one provider required");let M=E[0].model;this.specificationVersion=M.specificationVersion,this.provider=M.provider,this.modelId=M.modelId,this.supportedUrls=M.supportedUrls,this.providers=E}async doGenerate(E){let M;for(let N=0;N<this.providers.length;N++){let _=this.providers[N];try{return await _.model.doGenerate(E)}catch(J){if(M=J,EE(J))throw J;if(s(J)&&N<this.providers.length-1){let V=this.providers[N+1],S=J.status??"unknown";console.error(`[open-mem] Provider ${_.name} failed (${S}), falling over to ${V.name}`);continue}throw J}}throw M}async doStream(E){let M;for(let N=0;N<this.providers.length;N++){let _=this.providers[N];try{return await _.model.doStream(E)}catch(J){if(M=J,EE(J))throw J;if(s(J)&&N<this.providers.length-1){let V=this.providers[N+1],S=J.status??"unknown";console.error(`[open-mem] Provider ${_.name} failed (${S}), falling over to ${V.name}`);continue}throw J}}throw M}}var d0={"claude-sonnet-4-20250514":"us.anthropic.claude-sonnet-4-20250514-v1:0","claude-opus-4-20250514":"us.anthropic.claude-opus-4-20250514-v1:0","claude-3-5-sonnet-20241022":"us.anthropic.claude-3-5-sonnet-20241022-v2:0","claude-3-5-haiku-20241022":"us.anthropic.claude-3-5-haiku-20241022-v1:0","claude-3-haiku-20240307":"anthropic.claude-3-haiku-20240307-v1:0"};function i0(E){if(E.includes("."))return E;return d0[E]||`us.anthropic.${E}-v1:0`}function PE(E){switch(E.provider){case"anthropic":{let{createAnthropic:M}=D("@ai-sdk/anthropic");return M({apiKey:E.apiKey})(E.model)}case"bedrock":{let{createAmazonBedrock:M}=D("@ai-sdk/amazon-bedrock");return M()(i0(E.model))}case"openai":{let{createOpenAI:M}=D("@ai-sdk/openai");return M({apiKey:E.apiKey})(E.model)}case"google":{let{createGoogleGenerativeAI:M}=D("@ai-sdk/google");return M({apiKey:E.apiKey})(E.model)}case"openrouter":{let{createOpenRouter:M}=D("@openrouter/ai-sdk-provider");return M({apiKey:E.apiKey})(E.model)}default:throw Error(`Unknown provider: ${E.provider}. Supported: anthropic, bedrock, openai, google, openrouter`)}}function mE(E){try{switch(E.provider){case"google":{let{createGoogleGenerativeAI:M}=D("@ai-sdk/google");return M({apiKey:E.apiKey}).embedding("text-embedding-004")}case"openai":{let{createOpenAI:M}=D("@ai-sdk/openai");return M({apiKey:E.apiKey}).embedding("text-embedding-3-small")}case"bedrock":{let{createAmazonBedrock:M}=D("@ai-sdk/amazon-bedrock");return M().embedding("amazon.titan-embed-text-v2:0")}case"anthropic":return null;case"openrouter":return null;default:return null}}catch{return null}}var r0={google:"gemini-2.5-flash-lite",anthropic:"claude-sonnet-4-20250514",openai:"gpt-4o-mini",bedrock:"us.anthropic.claude-3-5-haiku-20241022-v1:0",openrouter:"google/gemini-2.5-flash-lite"};function a0(E){switch(E){case"google":return process.env.GOOGLE_GENERATIVE_AI_API_KEY||process.env.GEMINI_API_KEY;case"anthropic":return process.env.ANTHROPIC_API_KEY;case"openai":return process.env.OPENAI_API_KEY;case"openrouter":return process.env.OPENROUTER_API_KEY;case"bedrock":return;default:return}}function IE(E){if(!E.fallbackProviders||E.fallbackProviders.length===0)return[];return E.fallbackProviders.map((M)=>({provider:M,model:r0[M]??"gemini-2.5-flash-lite",apiKey:a0(M)}))}function qE(E,M=[]){let N=PE(E);if(M.length===0)return N;let _=[{name:E.provider,model:N},...M.map((J)=>({name:J.provider,model:PE(J)}))];return new ME(_)}JE();import{randomUUID as Z0}from"crypto";function VM(E,M){let N=new RegExp(`<${M}[^>]*>([\\s\\S]*?)</${M}>`,"i"),_=E.match(N);return _?_[1].trim():""}function SM(E,M){let N=new RegExp(`<${M}[^>]*>([\\s\\S]*?)</${M}>`,"gi"),_=[];for(let J of E.matchAll(N)){let V=J[1].trim();if(V)_.push(V)}return _}function vE(E){let M=VM(E,"reranked");if(!M)return null;let N=SM(M,"index");if(N.length===0)return null;let _=[];for(let J of N){let V=Number.parseInt(J,10);if(Number.isNaN(V)||V<0)return null;_.push(V)}return _}function k(E){return Math.ceil(E.length/4)}var AM={showTokenCosts:!0,observationTypes:"all",fullObservationCount:3,showLastSummary:!0},v={bugfix:"\uD83D\uDD34",feature:"\uD83D\uDFE3",refactor:"\uD83D\uDD04",change:"\u2705",discovery:"\uD83D\uDD35",decision:"\u2696\uFE0F"};function pE(E,M=AM){let N=[];if(N.push("## open-mem: Past Session Memory"),N.push(""),N.push("**\uD83D\uDCA1 Progressive Disclosure:** This is a compact index showing WHAT was observed and retrieval COST."),N.push("Use `mem-find` to find observations by query, then `mem-get` with IDs to fetch full details."),N.push(""),N.push("**3-Layer Memory Access:**"),N.push("- **Layer 1** `mem-find` \u2014 Find observations by query (returns IDs + summaries)"),N.push("- **Layer 2** `mem-history` \u2014 Browse session history and drill into sessions"),N.push("- **Layer 3** `mem-get` \u2014 Get full details by ID (use IDs from search results or the index below)"),N.push(""),N.push("**\uD83D\uDCDD When to Save (`mem-create`):** Proactively save decisions + rationale, non-obvious gotchas/workarounds, user preferences, and cross-session plans. Auto-capture handles tool executions \u2014 use `mem-create` for insights auto-capture can't understand the significance of. Wrap sensitive content in `<private>` tags to exclude from memory. Call `mem-help` for detailed guidance."),M.showLastSummary&&E.recentSummaries.length>0){N.push(""),N.push("### Recent Sessions"),N.push("| Session | Summary | Decisions |"),N.push("|---------|---------|-----------|");for(let S of E.recentSummaries){let A=S.keyDecisions.length>0?S.keyDecisions.join("; "):"\u2014";N.push(`| ${S.sessionId} | ${S.summary} | ${A} |`)}}let _=M.observationTypes==="all"?E.observationIndex:E.observationIndex.filter((S)=>M.observationTypes.includes(S.type));if(_.length>0){N.push(""),N.push(`### Recent Observations (${_.length} entries)`);let S=OM(_,E.fullObservations);for(let[A,$]of S){if(N.push(""),N.push(`**${A}**`),M.showTokenCosts)N.push("| ID | Type | Title | ~Tokens |"),N.push("|----|------|-------|---------|");else N.push("| ID | Type | Title |"),N.push("|----|------|-------|");for(let O of $){let X=v[O.type]||"\uD83D\uDCDD";if(M.showTokenCosts)N.push(`| ${O.id} | ${X} | ${O.title} | ~${O.tokenCount} |`);else N.push(`| ${O.id} | ${X} | ${O.title} |`)}}}let J=E.fullObservations.slice(0,M.fullObservationCount);if(J.length>0){N.push(""),N.push("### Full Details (most recent)");for(let S of J){let A=v[S.type]||"\uD83D\uDCDD";if(N.push(""),N.push(`#### ${A} ${S.title} (${S.id})`),N.push(S.narrative),S.facts.length>0)N.push(`**Facts:** ${S.facts.map((O)=>`- ${O}`).join(" ")}`);if(S.concepts.length>0)N.push(`**Concepts:** ${S.concepts.join(", ")}`);let $=[...S.filesRead,...S.filesModified];if($.length>0)N.push(`**Files:** ${$.join(", ")}`)}}let V=$M(E);if(V)N.push(""),N.push(V);return N.join(`
5
+ `)}function $M(E){let M=0,N=0,_=new Set(E.observationIndex.map((S)=>S.id));for(let S of E.observationIndex)M+=S.tokenCount,N+=S.discoveryTokens;for(let S of E.fullObservations)if(!_.has(S.id))M+=S.tokenCount,N+=S.discoveryTokens;if(N===0)return null;let J=N-M,V=Math.max(0,Math.round(J/N*100));return`### \uD83D\uDCB0 Memory Economics
6
+ **Read cost:** ~${M}t | **Discovery cost:** ~${N}t | **Savings:** ${V}% (${J}t saved)`}function OM(E,M){let N=new Map;for(let J of M){let V=J.filesModified[0]||J.filesRead[0];if(V)N.set(J.id,V)}let _=new Map;for(let J of E){let V=N.get(J.id)??"General",S=_.get(V)??[];S.push(J),_.set(V,S)}return _}function wE(E){let M=[];if(M.push("[open-mem] Memory context:"),E.recentSummaries.length>0){M.push(`
7
7
  Recent sessions:`);for(let N of E.recentSummaries)M.push(`- ${N.summary}`)}if(E.observationIndex.length>0){M.push(`
8
- Recent observations (${E.observationIndex.length} entries):`);for(let N of E.observationIndex)M.push(`- ${u[N.type]||"\uD83D\uDCDD"} ${N.title}`)}return M.join(`
9
- `)}function hE(E,M){if(E.length===0)return"";let N=M,_=[];for(let S of E){let V=S.tokenCount||k(S.title);if(N-V<0)break;_.push(S),N-=V}if(_.length===0)return"";let J=[];J.push("### Cross-Project Memory"),J.push(""),J.push("| ID | Type | Title | ~Tokens |"),J.push("|----|------|-------|---------|");for(let S of _){let V=u[S.type]||"\uD83D\uDCDD";J.push(`| ${S.id} | ${V} | ${S.title} | ~${S.tokenCount} |`)}return J.join(`
10
- `)}function uE(E,M){if(E.length===0)return"";let N=M,_=[];for(let S of E){let V=S.tokenCount||k(S.title);if(N-V<0)break;_.push(S),N-=V}if(_.length===0)return"";let J=[];J.push(`
11
- Cross-project observations (${_.length} entries):`);for(let S of _)J.push(`- ${u[S.type]||"\uD83D\uDCDD"} ${S.title}`);return J.join(`
12
- `)}var w={recency:0.4,typeImportance:0.3,sessionAffinity:0.2,tokenEfficiency:0.1},MM={decision:1,bugfix:0.9,feature:0.8,refactor:0.6,discovery:0.5,change:0.4};function NM(E,M){let N=new Date(E),J=(M.getTime()-N.getTime())/3600000;if(J<0)return 1;if(J<24)return 1;if(J<48)return 0.8;if(J<168)return 0.5;return 0.2}function _M(E){return MM[E]??0.3}function JM(E,M){if(!M)return 0.5;return E===M?1:0.3}function SM(E){if(E<=10)return 1;if(E>=200)return 0.2;return 1-(E-10)/190*0.8}function VM(E,M){let N=NM(E.createdAt,M.now),_=_M(E.type),J=JM(E.sessionId,M.currentSessionId),S=SM(E.tokenCount);return N*w.recency+_*w.typeImportance+J*w.sessionAffinity+S*w.tokenEfficiency}function pE(E,M){let N=new Map;for(let _ of E)N.set(_.id,VM(_,M));return[...E].sort((_,J)=>{let S=N.get(_.id)??0,V=N.get(J.id)??0;if(V!==S)return V-S;return new Date(J.createdAt).getTime()-new Date(_.createdAt).getTime()})}function vE(E,M,N,_,J=[],S){let V=_,A=[],$=[];for(let C of M){let Z=C.tokenCount||k(C.summary);if(V-Z<0)break;A.push(C),V-=Z}let O=S?pE(N,S):N;for(let C of O){let Z=C.tokenCount||k(C.title);if(V-Z<0)break;$.push(C),V-=Z}return{recentSummaries:A,observationIndex:$,fullObservations:[...J],totalTokens:_-V}}import{existsSync as $E}from"fs";import{readdir as QM,readFile as iE,unlink as AE,writeFile as aE}from"fs/promises";import{join as OE,resolve as CE}from"path";import{existsSync as wE}from"fs";import{mkdir as AM,readFile as $M,rename as OM,unlink as CM,writeFile as XM}from"fs/promises";import{dirname as c,isAbsolute as JE,join as p,normalize as ZM,relative as SE,resolve as P,sep as NE}from"path";var m="<!-- open-mem-context -->",y="<!-- /open-mem-context -->",cE={bugfix:"\uD83D\uDD34",feature:"\uD83D\uDFE3",refactor:"\uD83D\uDD04",change:"\u2705",discovery:"\uD83D\uDD35",decision:"\u2696\uFE0F"},gE=new Map,UM=new Set(["node_modules",".git","dist","coverage",".open-mem","build","__pycache__",".next",".nuxt"]);async function lE(E,M,N){if(M.length===0)return;if(N.mode==="single")return KM(E,M,N);let{maxDepth:_,filename:J}=N,S=[];for(let $ of M){for(let O of $.filesModified)S.push(O);for(let O of $.filesRead)S.push(O)}let V=nE(S,E,_);if(V.size===0)return;let A=dE(M,V,E);for(let[$,O]of A)try{let C=HM($,O,E);await bE($,C,J)}catch(C){console.error(`[open-mem] Failed to update AGENTS.md in ${$}:`,C)}}async function KM(E,M,N){let{maxDepth:_,filename:J}=N,S=M.filter(_E);if(S.length===0)return;let V=[];for(let H of S){for(let z of H.filesModified)V.push(z);for(let z of H.filesRead)V.push(z)}let A=nE(V,E,_),$=dE(S,A,E),O=S.filter((H)=>{return[...H.filesModified,...H.filesRead].some((W)=>{if(!W)return!1;let j=JE(W)?W:p(E,W);return P(c(j))===P(E)})});if(O.length>0)$.set(P(E),O);if($.size===0)return;let C=[];C.push("## Project Activity (auto-generated by open-mem)"),C.push("");let Z=[...$.entries()].map(([H,z])=>({relPath:SE(E,H)||".",observations:z})).sort((H,z)=>H.relPath.localeCompare(z.relPath));for(let{relPath:H,observations:z}of Z){let W=z.filter(_E).sort((Q,q)=>q.createdAt.localeCompare(Q.createdAt)).slice(0,10);if(W.length===0)continue;C.push(`### ${H}/`),C.push("| ID | Type | Title | Date |"),C.push("|----|------|-------|------|");for(let Q of W){let q=cE[Q.type]||"\uD83D\uDCDD",I0=Q.createdAt.split("T")[0],x0=Q.title.replace(/\|/g,"\\|");C.push(`| ${Q.id} | ${q} ${Q.type} | ${x0} | ${I0} |`)}let j=new Set;for(let Q of W)for(let q of Q.concepts)j.add(q);if(j.size>0){let Q=[...j].slice(0,10).join(", ");C.push(""),C.push(`**Key concepts:** ${Q}`)}let G=W.filter((Q)=>Q.type==="decision").map((Q)=>Q.title);if(G.length>0)C.push(""),C.push(`**Recent decisions:** ${G.slice(0,5).join("; ")}`);C.push("")}C.push("\uD83D\uDCA1 *Use `mem-find` to search full details. Use `mem-create` to save important decisions.*");let Y=C.join(`
13
- `);await bE(E,Y,J)}function _E(E){return!/^\w[\w-]*\s+execution$/i.test(E.title)}function HM(E,M,N){let _=[...M].filter(_E).sort((O,C)=>C.createdAt.localeCompare(O.createdAt)).slice(0,10),J=SE(N,E)||".",S=[];S.push(`## Recent Activity in \`${J}/\` (auto-generated by open-mem)`),S.push(""),S.push("| ID | Type | Title | Date |"),S.push("|----|------|-------|------|");for(let O of _){let C=cE[O.type]||"\uD83D\uDCDD",Z=O.createdAt.split("T")[0],Y=O.title.replace(/\|/g,"\\|");S.push(`| ${O.id} | ${C} ${O.type} | ${Y} | ${Z} |`)}let V=new Set;for(let O of _)for(let C of O.concepts)V.add(C);if(V.size>0){let O=[...V].slice(0,10).join(", ");S.push(""),S.push(`**Key concepts:** ${O}`)}let A=_.filter((O)=>O.type==="decision").map((O)=>O.title);if(A.length>0)S.push(""),S.push(`**Recent decisions:** ${A.slice(0,5).join("; ")}`);let $=_.filter((O)=>O.type==="decision"&&O.narrative).slice(0,3);if($.length>0){S.push(""),S.push("**Decision details:**");for(let O of $){let C=O.narrative.split(/[.!?]\s/)[0],Z=C.length>120?`${C.slice(0,117)}...`:C;S.push(`- \u2696\uFE0F ${O.title}: ${Z}`)}}return S.push(""),S.push("\uD83D\uDCA1 *Use `mem-find` to search full details across all sessions. Use `mem-create` to save important decisions.*"),S.join(`
14
- `)}async function bE(E,M,N){if(!wE(E))return;let J=(gE.get(E)??Promise.resolve()).then(async()=>{let S=p(E,N),V=p(E,`.${N}.tmp`),A="";try{A=await $M(S,"utf-8")}catch{}let $=zM(A,M);try{await AM(c(V),{recursive:!0}),await XM(V,$,"utf-8"),await OM(V,S)}catch(O){try{await CM(V)}catch{}throw O}});return gE.set(E,J.catch(()=>{})),J}function zM(E,M){if(!E)return`${m}
8
+ Recent observations (${E.observationIndex.length} entries):`);for(let N of E.observationIndex)M.push(`- ${v[N.type]||"\uD83D\uDCDD"} ${N.title}`)}return M.join(`
9
+ `)}function gE(E,M){if(E.length===0)return"";let N=M,_=[];for(let V of E){let S=V.tokenCount||k(V.title);if(N-S<0)break;_.push(V),N-=S}if(_.length===0)return"";let J=[];J.push("### Cross-Project Memory"),J.push(""),J.push("| ID | Type | Title | ~Tokens |"),J.push("|----|------|-------|---------|");for(let V of _){let S=v[V.type]||"\uD83D\uDCDD";J.push(`| ${V.id} | ${S} | ${V.title} | ~${V.tokenCount} |`)}return J.join(`
10
+ `)}function lE(E,M){if(E.length===0)return"";let N=M,_=[];for(let V of E){let S=V.tokenCount||k(V.title);if(N-S<0)break;_.push(V),N-=S}if(_.length===0)return"";let J=[];J.push(`
11
+ Cross-project observations (${_.length} entries):`);for(let V of _)J.push(`- ${v[V.type]||"\uD83D\uDCDD"} ${V.title}`);return J.join(`
12
+ `)}var l={recency:0.4,typeImportance:0.3,sessionAffinity:0.2,tokenEfficiency:0.1},XM={decision:1,bugfix:0.9,feature:0.8,refactor:0.6,discovery:0.5,change:0.4};function ZM(E,M){let N=new Date(E),J=(M.getTime()-N.getTime())/3600000;if(J<0)return 1;if(J<24)return 1;if(J<48)return 0.8;if(J<168)return 0.5;return 0.2}function UM(E){return XM[E]??0.3}function KM(E,M){if(!M)return 0.5;return E===M?1:0.3}function HM(E){if(E<=10)return 1;if(E>=200)return 0.2;return 1-(E-10)/190*0.8}function zM(E,M){let N=ZM(E.createdAt,M.now),_=UM(E.type),J=KM(E.sessionId,M.currentSessionId),V=HM(E.tokenCount);return N*l.recency+_*l.typeImportance+J*l.sessionAffinity+V*l.tokenEfficiency}function cE(E,M){let N=new Map;for(let _ of E)N.set(_.id,zM(_,M));return[...E].sort((_,J)=>{let V=N.get(_.id)??0,S=N.get(J.id)??0;if(S!==V)return S-V;return new Date(J.createdAt).getTime()-new Date(_.createdAt).getTime()})}function bE(E,M,N,_,J=[],V){let S=_,A=[],$=[];for(let X of M){let U=X.tokenCount||k(X.summary);if(S-U<0)break;A.push(X),S-=U}let O=V?cE(N,V):N;for(let X of O){let U=X.tokenCount||k(X.title);if(S-U<0)break;$.push(X),S-=U}return{recentSummaries:A,observationIndex:$,fullObservations:[...J],totalTokens:_-S}}import{existsSync as ZE}from"fs";import{readdir as kM,readFile as eE,unlink as XE,writeFile as sE}from"fs/promises";import{join as UE,resolve as KE}from"path";import{existsSync as dE}from"fs";import{mkdir as QM,readFile as WM,rename as YM,unlink as BM,writeFile as LM}from"fs/promises";import{dirname as c,isAbsolute as AE,join as p,normalize as RM,relative as $E,resolve as I,sep as VE}from"path";var m="<!-- open-mem-context -->",y="<!-- /open-mem-context -->",iE={bugfix:"\uD83D\uDD34",feature:"\uD83D\uDFE3",refactor:"\uD83D\uDD04",change:"\u2705",discovery:"\uD83D\uDD35",decision:"\u2696\uFE0F"},nE=new Map,CM=new Set(["node_modules",".git","dist","coverage",".open-mem","build","__pycache__",".next",".nuxt"]);async function rE(E,M,N){if(M.length===0)return;if(N.mode==="single")return GM(E,M,N);let{maxDepth:_,filename:J}=N,V=[];for(let $ of M){for(let O of $.filesModified)V.push(O);for(let O of $.filesRead)V.push(O)}let S=oE(V,E,_);if(S.size===0)return;let A=tE(M,S,E);for(let[$,O]of A)try{let X=DM($,O,E);await aE($,X,J)}catch(X){console.error(`[open-mem] Failed to update AGENTS.md in ${$}:`,X)}}async function GM(E,M,N){let{maxDepth:_,filename:J}=N,V=M.filter(SE);if(V.length===0)return;let S=[];for(let z of V){for(let Q of z.filesModified)S.push(Q);for(let Q of z.filesRead)S.push(Q)}let A=oE(S,E,_),$=tE(V,A,E),O=V.filter((z)=>{return[...z.filesModified,...z.filesRead].some((B)=>{if(!B)return!1;let j=AE(B)?B:p(E,B);return I(c(j))===I(E)})});if(O.length>0)$.set(I(E),O);if($.size===0)return;let X=[];X.push("## Project Activity (auto-generated by open-mem)"),X.push("");let U=[...$.entries()].map(([z,Q])=>({relPath:$E(E,z)||".",observations:Q})).sort((z,Q)=>z.relPath.localeCompare(Q.relPath));for(let{relPath:z,observations:Q}of U){let B=Q.filter(SE).sort((W,u)=>u.createdAt.localeCompare(W.createdAt)).slice(0,10);if(B.length===0)continue;X.push(`### ${z}/`),X.push("| ID | Type | Title | Date |"),X.push("|----|------|-------|------|");for(let W of B){let u=iE[W.type]||"\uD83D\uDCDD",v0=W.createdAt.split("T")[0],p0=W.title.replace(/\|/g,"\\|");X.push(`| ${W.id} | ${u} ${W.type} | ${p0} | ${v0} |`)}let j=new Set;for(let W of B)for(let u of W.concepts)j.add(u);if(j.size>0){let W=[...j].slice(0,10).join(", ");X.push(""),X.push(`**Key concepts:** ${W}`)}let G=B.filter((W)=>W.type==="decision").map((W)=>W.title);if(G.length>0)X.push(""),X.push(`**Recent decisions:** ${G.slice(0,5).join("; ")}`);X.push("")}X.push("\uD83D\uDCA1 *Use `mem-find` to search full details. Use `mem-create` to save important decisions.*");let L=X.join(`
13
+ `);await aE(E,L,J)}function SE(E){return!/^\w[\w-]*\s+execution$/i.test(E.title)}function DM(E,M,N){let _=[...M].filter(SE).sort((O,X)=>X.createdAt.localeCompare(O.createdAt)).slice(0,10),J=$E(N,E)||".",V=[];V.push(`## Recent Activity in \`${J}/\` (auto-generated by open-mem)`),V.push(""),V.push("| ID | Type | Title | Date |"),V.push("|----|------|-------|------|");for(let O of _){let X=iE[O.type]||"\uD83D\uDCDD",U=O.createdAt.split("T")[0],L=O.title.replace(/\|/g,"\\|");V.push(`| ${O.id} | ${X} ${O.type} | ${L} | ${U} |`)}let S=new Set;for(let O of _)for(let X of O.concepts)S.add(X);if(S.size>0){let O=[...S].slice(0,10).join(", ");V.push(""),V.push(`**Key concepts:** ${O}`)}let A=_.filter((O)=>O.type==="decision").map((O)=>O.title);if(A.length>0)V.push(""),V.push(`**Recent decisions:** ${A.slice(0,5).join("; ")}`);let $=_.filter((O)=>O.type==="decision"&&O.narrative).slice(0,3);if($.length>0){V.push(""),V.push("**Decision details:**");for(let O of $){let X=O.narrative.split(/[.!?]\s/)[0],U=X.length>120?`${X.slice(0,117)}...`:X;V.push(`- \u2696\uFE0F ${O.title}: ${U}`)}}return V.push(""),V.push("\uD83D\uDCA1 *Use `mem-find` to search full details across all sessions. Use `mem-create` to save important decisions.*"),V.join(`
14
+ `)}async function aE(E,M,N){if(!dE(E))return;let J=(nE.get(E)??Promise.resolve()).then(async()=>{let V=p(E,N),S=p(E,`.${N}.tmp`),A="";try{A=await WM(V,"utf-8")}catch{}let $=FM(A,M);try{await QM(c(S),{recursive:!0}),await LM(S,$,"utf-8"),await YM(S,V)}catch(O){try{await BM(S)}catch{}throw O}});return nE.set(E,J.catch(()=>{})),J}function FM(E,M){if(!E)return`${m}
15
15
  ${M}
16
16
  ${y}
17
- `;let N=E.indexOf(m),_=E.indexOf(y);if(N!==-1&&_!==-1&&_>N){let S=E.substring(0,N),V=E.substring(_+y.length);return`${S}${m}
17
+ `;let N=E.indexOf(m),_=E.indexOf(y);if(N!==-1&&_!==-1&&_>N){let V=E.substring(0,N),S=E.substring(_+y.length);return`${V}${m}
18
18
  ${M}
19
- ${y}${V}`}let J=E;if(N!==-1&&_===-1)J=J.replace(m,"").trim();else if(N===-1&&_!==-1)J=J.replace(y,"").trim();else if(N!==-1&&_!==-1&&_<=N)J=J.replace(y,"").replace(m,"").trim();return`${J}
19
+ ${y}${S}`}let J=E;if(N!==-1&&_===-1)J=J.replace(m,"").trim();else if(N===-1&&_!==-1)J=J.replace(y,"").trim();else if(N!==-1&&_!==-1&&_<=N)J=J.replace(y,"").replace(m,"").trim();return`${J}
20
20
 
21
21
  ${m}
22
22
  ${M}
23
23
  ${y}
24
- `}function nE(E,M,N){let _=new Set,J=P(M);for(let S of E){if(!S||!S.trim())continue;if(S.startsWith("~")||S.startsWith("http"))continue;let V=JE(S)?S:p(M,S),A=c(V),$=P(A);if(!$.startsWith(J+NE)&&$!==J)continue;if($===J)continue;let O=SE(J,$);if(O.split(NE).length>N)continue;if(ZM(O).split(NE).some((Y)=>UM.has(Y)))continue;if(!wE($))continue;_.add($)}return _}function dE(E,M,N){let _=new Map;for(let J of E){let S=[...J.filesModified,...J.filesRead],V=new Set;for(let A of S){if(!A)continue;let $=JE(A)?A:p(N,A),O=P(c($));if(M.has(O))V.add(O)}for(let A of V){let $=_.get(A)??[];$.push(J),_.set(A,$)}}return _}var VE="<!-- open-mem-context -->",l="<!-- /open-mem-context -->";async function oE(E,M,N){let _;try{_=await QM(E,{withFileTypes:!0,encoding:"utf8"})}catch{return}for(let J of _){let S=String(J.name);if(S===".git"||S==="node_modules"||S===".open-mem"||S==="dist")continue;let V=OE(E,S);if(J.isDirectory())await oE(V,M,N);else if(J.isFile()&&S===M)N.push(V)}}async function XE(E,M){let N=CE(E),_=[];return await oE(N,M,_),_}function rE(E){let M=E.indexOf(VE),N=E.indexOf(l);if(M===-1&&N===-1)return E;if(M!==-1&&N===-1){let S=E.replace(VE,"").trim();return S?`${S}
25
- `:""}if(M===-1&&N!==-1){let S=E.replace(l,"").trim();return S?`${S}
26
- `:""}if(N<=M){let S=E.replace(VE,"").replace(l,"").trim();return S?`${S}
27
- `:""}let _=E.slice(0,M).trimEnd(),J=E.slice(N+l.length).trimStart();if(!_&&!J)return"";if(!_)return`${J}
24
+ `}function oE(E,M,N){let _=new Set,J=I(M);for(let V of E){if(!V||!V.trim())continue;if(V.startsWith("~")||V.startsWith("http"))continue;let S=AE(V)?V:p(M,V),A=c(S),$=I(A);if(!$.startsWith(J+VE)&&$!==J)continue;if($===J)continue;let O=$E(J,$);if(O.split(VE).length>N)continue;if(RM(O).split(VE).some((L)=>CM.has(L)))continue;if(!dE($))continue;_.add($)}return _}function tE(E,M,N){let _=new Map;for(let J of E){let V=[...J.filesModified,...J.filesRead],S=new Set;for(let A of V){if(!A)continue;let $=AE(A)?A:p(N,A),O=I(c($));if(M.has(O))S.add(O)}for(let A of S){let $=_.get(A)??[];$.push(J),_.set(A,$)}}return _}var OE="<!-- open-mem-context -->",b="<!-- /open-mem-context -->";async function M0(E,M,N){let _;try{_=await kM(E,{withFileTypes:!0,encoding:"utf8"})}catch{return}for(let J of _){let V=String(J.name);if(V===".git"||V==="node_modules"||V===".open-mem"||V==="dist")continue;let S=UE(E,V);if(J.isDirectory())await M0(S,M,N);else if(J.isFile()&&V===M)N.push(S)}}async function HE(E,M){let N=KE(E),_=[];return await M0(N,M,_),_}function E0(E){let M=E.indexOf(OE),N=E.indexOf(b);if(M===-1&&N===-1)return E;if(M!==-1&&N===-1){let V=E.replace(OE,"").trim();return V?`${V}
25
+ `:""}if(M===-1&&N!==-1){let V=E.replace(b,"").trim();return V?`${V}
26
+ `:""}if(N<=M){let V=E.replace(OE,"").replace(b,"").trim();return V?`${V}
27
+ `:""}let _=E.slice(0,M).trimEnd(),J=E.slice(N+b.length).trimStart();if(!_&&!J)return"";if(!_)return`${J}
28
28
  `;if(!J)return`${_}
29
29
  `;return`${_}
30
30
 
31
31
  ${J}
32
- `}async function tE(E,M,N=!1){let _=await XE(E,M),J=0;for(let S of _){let V=await iE(S,"utf-8"),A=rE(V);if(A!==V){if(J+=1,!N)if(A==="")await AE(S);else await aE(S,A,"utf-8")}}if(M){let S=OE(CE(E),M);if($E(S))try{let V=await iE(S,"utf-8"),A=rE(V);if(A!==V){if(J+=1,!N)if(A==="")await AE(S);else await aE(S,A,"utf-8")}if(!_.includes(S))_.push(S)}catch{}}return{files:_,changed:J}}async function eE(E,M){let N=await XE(E,M);if(M){let J=OE(CE(E),M);if($E(J)&&!N.includes(J))N.push(J)}let _=0;for(let J of N)try{await AE(J),_++}catch{}return{deleted:_,files:N}}async function sE(E,M,N,_,J=!1){let V=M.getAll(E).flatMap(($)=>N.getBySession($.id));if(J){let $=new Set;for(let O of V)for(let C of[...O.filesRead,...O.filesModified])$.add(C);return{observations:V.length,filesTouched:$.size}}if(!$E(E))return{observations:0,filesTouched:0};await lE(E,V,{maxDepth:_.maxDepth,mode:_.mode,filename:_.filename});let A=await XE(E,_.filename);return{observations:V.length,filesTouched:A.length}}class UE{observations;sessions;summaries;searchOrchestrator;projectPath;config;userObservationRepo;runtimeSnapshotProvider;configAuditStore;maintenanceHistoryStore;configAuditLogFallback=[];maintenanceLogFallback=[];constructor(E){this.observations=E.observations,this.sessions=E.sessions,this.summaries=E.summaries,this.searchOrchestrator=E.searchOrchestrator,this.projectPath=E.projectPath,this.config=E.config,this.userObservationRepo=E.userObservationRepo??null,this.runtimeSnapshotProvider=E.runtimeSnapshotProvider??null,this.configAuditStore=E.configAuditStore??null,this.maintenanceHistoryStore=E.maintenanceHistoryStore??null}getByIdIncludingArchived(E){let M=this.observations;return M.getByIdIncludingArchived?M.getByIdIncludingArchived(E):this.observations.getById(E)}listByProjectWithState(E){let M=this.observations;if(M.listByProject)return M.listByProject(this.projectPath,E);if(E.state!=="current")return[];return this.listObservations({limit:E.limit,offset:E.offset,type:E.type,sessionId:E.sessionId})}async ingest(E){}async processPending(E){return 0}async search(E,M={}){return this.searchOrchestrator.search(E,{type:M.type,limit:M.limit??10,projectPath:this.projectPath,importanceMin:M.importanceMin,importanceMax:M.importanceMax,createdAfter:M.after,createdBefore:M.before,concepts:M.concepts,files:M.files})}async timeline(E={}){if(E.anchor){let N=this.observations.getById(E.anchor);if(!N)return[];let _=E.depthBefore??5,J=E.depthAfter??5,S=this.observations.getAroundTimestamp(N.createdAt,_,J,this.projectPath),V=[...S.filter(($)=>$.createdAt<N.createdAt),N,...S.filter(($)=>$.createdAt>N.createdAt)];return[{session:this.sessions.getById(N.sessionId)??{id:N.sessionId,projectPath:this.projectPath,startedAt:N.createdAt,endedAt:null,status:"completed",observationCount:0,summaryId:null},summary:null,observations:V}]}if(E.sessionId){let N=this.sessions.getById(E.sessionId);if(!N)return[];return[{session:N,summary:this.summaries.getBySessionId(N.id),observations:this.observations.getBySession(N.id)}]}return this.sessions.getRecent(this.projectPath,E.limit??5).map((N)=>({session:N,summary:this.summaries.getBySessionId(N.id),observations:[]}))}async recall(E,M=10){let N=[];for(let _ of E.slice(0,M)){let J=this.observations.getById(_);if(J){N.push(J);continue}if(!this.userObservationRepo)continue;let S=this.userObservationRepo.getById(_);if(!S)continue;N.push({...S,sessionId:"",rawToolOutput:"",discoveryTokens:0})}return N}async save(E){if(E.scope==="user"){if(!this.userObservationRepo)return null;return{...this.userObservationRepo.create({type:E.type,title:E.title,subtitle:"",facts:[],narrative:E.narrative,concepts:E.concepts??[],filesRead:[],filesModified:E.files??[],toolName:"mem-create",tokenCount:k(`${E.title} ${E.narrative}`),importance:E.importance??3,sourceProject:this.projectPath}),sessionId:"",rawToolOutput:"",discoveryTokens:0}}this.sessions.getOrCreate(E.sessionId,this.projectPath);let M=this.observations.create({sessionId:E.sessionId,type:E.type,title:E.title,subtitle:"",facts:[],narrative:E.narrative,concepts:E.concepts??[],filesRead:[],filesModified:E.files??[],rawToolOutput:`[Manual save] ${E.narrative}`,toolName:"mem-create",tokenCount:k(`${E.title} ${E.narrative}`),discoveryTokens:0,importance:E.importance??3});return this.sessions.incrementObservationCount(E.sessionId),M}async update(E){let M=this.observations.getById(E.id);if(!M)return null;let N=this.sessions.getById(M.sessionId);if(!N||N.projectPath!==this.projectPath)return null;let{id:_,...J}=E;return this.observations.update(E.id,J)??null}async delete(E){let M=0;for(let N of E){let _=this.observations.getById(N);if(!_)continue;let J=this.sessions.getById(_.sessionId);if(!J||J.projectPath!==this.projectPath)continue;if(this.observations.delete(N))M+=1}return M}async export(E,M={}){if(E!=="project")throw Error("Only project scope export is supported.");let N=this.sessions.getAll(this.projectPath),_=[];for(let A of N)_.push(...this.observations.getBySession(A.id));if(M.type)_=_.filter((A)=>A.type===M.type);if(_.sort((A,$)=>new Date(A.createdAt).getTime()-new Date($.createdAt).getTime()),M.limit&&M.limit<_.length)_=_.slice(0,M.limit);let J=_.map(({rawToolOutput:A,...$})=>$),S=N.map((A)=>this.summaries.getBySessionId(A.id)).filter((A)=>A!==null);return{version:1,exportedAt:new Date().toISOString(),project:this.projectPath,observations:J,summaries:S}}async import(E,M={}){let N;try{N=JSON.parse(E)}catch{throw Error("Invalid JSON payload.")}if(typeof N!=="object"||N===null)throw Error("Invalid import payload.");let _=N;if(_.version!==1||!Array.isArray(_.observations))throw Error("Unsupported export format.");let J=M.mode??"skip-duplicates",S=0,V=0;for(let A of _.observations){let $=this.observations.getById(A.id);if($&&J==="skip-duplicates"){V+=1;continue}if($&&J==="overwrite")this.observations.delete(A.id);this.sessions.getOrCreate(A.sessionId,this.projectPath),this.observations.importObservation({id:A.id,sessionId:A.sessionId,type:A.type,title:A.title,subtitle:A.subtitle??"",facts:A.facts??[],narrative:A.narrative??"",concepts:A.concepts??[],filesRead:A.filesRead??[],filesModified:A.filesModified??[],rawToolOutput:A.rawToolOutput??"",toolName:A.toolName??"unknown",createdAt:A.createdAt,tokenCount:A.tokenCount??0,discoveryTokens:A.discoveryTokens??0,importance:A.importance??3,supersededBy:A.supersededBy??null,supersededAt:A.supersededAt??null}),this.sessions.incrementObservationCount(A.sessionId),S+=1}for(let A of _.summaries??[]){let $=this.summaries.getBySessionId(A.sessionId);if($&&J==="skip-duplicates")continue;if($&&J==="overwrite")continue;this.sessions.getOrCreate(A.sessionId,this.projectPath),this.summaries.importSummary(A),this.sessions.setSummary(A.sessionId,A.id)}return{imported:S,skipped:V}}async buildContext(E,M="normal"){let N=this.sessions.getRecent(this.projectPath,5),_=N.map((C)=>C.summaryId?this.summaries.getBySessionId(C.id):null).filter((C)=>C!==null),J=this.observations.getIndex(this.projectPath,this.config.maxObservations),V=J.slice(0,this.config.contextFullObservationCount).map((C)=>C.id).map((C)=>this.observations.getById(C)).filter((C)=>C!==null),A=vE(N,_,J,this.config.maxContextTokens,V);if(M==="compaction"){let C=qE(A);if(this.config.userMemoryEnabled&&this.userObservationRepo)C+=uE(this.userObservationRepo.getIndex(this.config.maxObservations),this.config.userMemoryMaxContextTokens);return C}let $={showTokenCosts:this.config.contextShowTokenCosts,observationTypes:this.config.contextObservationTypes,fullObservationCount:this.config.contextFullObservationCount,showLastSummary:this.config.contextShowLastSummary},O=xE(A,$);if(this.config.userMemoryEnabled&&this.userObservationRepo){let C=hE(this.userObservationRepo.getIndex(this.config.maxObservations),this.config.userMemoryMaxContextTokens);if(C)O+=`
32
+ `}async function N0(E,M,N=!1){let _=await HE(E,M),J=0;for(let V of _){let S=await eE(V,"utf-8"),A=E0(S);if(A!==S){if(J+=1,!N)if(A==="")await XE(V);else await sE(V,A,"utf-8")}}if(M){let V=UE(KE(E),M);if(ZE(V))try{let S=await eE(V,"utf-8"),A=E0(S);if(A!==S){if(J+=1,!N)if(A==="")await XE(V);else await sE(V,A,"utf-8")}if(!_.includes(V))_.push(V)}catch{}}return{files:_,changed:J}}async function _0(E,M){let N=await HE(E,M);if(M){let J=UE(KE(E),M);if(ZE(J)&&!N.includes(J))N.push(J)}let _=0;for(let J of N)try{await XE(J),_++}catch{}return{deleted:_,files:N}}async function J0(E,M,N,_,J=!1){let S=M.getAll(E).flatMap(($)=>N.getBySession($.id));if(J){let $=new Set;for(let O of S)for(let X of[...O.filesRead,...O.filesModified])$.add(X);return{observations:S.length,filesTouched:$.size}}if(!ZE(E))return{observations:0,filesTouched:0};await rE(E,S,{maxDepth:_.maxDepth,mode:_.mode,filename:_.filename});let A=await HE(E,_.filename);return{observations:S.length,filesTouched:A.length}}class QE{observations;sessions;summaries;searchOrchestrator;projectPath;config;userObservationRepo;runtimeSnapshotProvider;configAuditStore;maintenanceHistoryStore;configAuditLogFallback=[];maintenanceLogFallback=[];constructor(E){this.observations=E.observations,this.sessions=E.sessions,this.summaries=E.summaries,this.searchOrchestrator=E.searchOrchestrator,this.projectPath=E.projectPath,this.config=E.config,this.userObservationRepo=E.userObservationRepo??null,this.runtimeSnapshotProvider=E.runtimeSnapshotProvider??null,this.configAuditStore=E.configAuditStore??null,this.maintenanceHistoryStore=E.maintenanceHistoryStore??null}getByIdIncludingArchived(E){let M=this.observations;return M.getByIdIncludingArchived?M.getByIdIncludingArchived(E):this.observations.getById(E)}listByProjectWithState(E){let M=this.observations;if(M.listByProject)return M.listByProject(this.projectPath,E);if(E.state!=="current")return[];return this.listObservations({limit:E.limit,offset:E.offset,type:E.type,sessionId:E.sessionId})}async ingest(E){}async processPending(E){return 0}async search(E,M={}){return this.searchOrchestrator.search(E,{type:M.type,limit:M.limit??10,projectPath:this.projectPath,importanceMin:M.importanceMin,importanceMax:M.importanceMax,createdAfter:M.after,createdBefore:M.before,concepts:M.concepts,files:M.files})}async timeline(E={}){if(E.anchor){let N=this.observations.getById(E.anchor);if(!N)return[];let _=E.depthBefore??5,J=E.depthAfter??5,V=this.observations.getAroundTimestamp(N.createdAt,_,J,this.projectPath),S=[...V.filter(($)=>$.createdAt<N.createdAt),N,...V.filter(($)=>$.createdAt>N.createdAt)];return[{session:this.sessions.getById(N.sessionId)??{id:N.sessionId,projectPath:this.projectPath,startedAt:N.createdAt,endedAt:null,status:"completed",observationCount:0,summaryId:null},summary:null,observations:S}]}if(E.sessionId){let N=this.sessions.getById(E.sessionId);if(!N)return[];return[{session:N,summary:this.summaries.getBySessionId(N.id),observations:this.observations.getBySession(N.id)}]}return this.sessions.getRecent(this.projectPath,E.limit??5).map((N)=>({session:N,summary:this.summaries.getBySessionId(N.id),observations:[]}))}async recall(E,M=10){let N=[];for(let _ of E.slice(0,M)){let J=this.observations.getById(_);if(J){N.push(J);continue}if(!this.userObservationRepo)continue;let V=this.userObservationRepo.getById(_);if(!V)continue;N.push({...V,sessionId:"",rawToolOutput:"",discoveryTokens:0})}return N}async save(E){if(E.scope==="user"){if(!this.userObservationRepo)return null;return{...this.userObservationRepo.create({type:E.type,title:E.title,subtitle:"",facts:[],narrative:E.narrative,concepts:E.concepts??[],filesRead:[],filesModified:E.files??[],toolName:"mem-create",tokenCount:k(`${E.title} ${E.narrative}`),importance:E.importance??3,sourceProject:this.projectPath}),sessionId:"",rawToolOutput:"",discoveryTokens:0}}this.sessions.getOrCreate(E.sessionId,this.projectPath);let M=this.observations.create({sessionId:E.sessionId,type:E.type,title:E.title,subtitle:"",facts:[],narrative:E.narrative,concepts:E.concepts??[],filesRead:[],filesModified:E.files??[],rawToolOutput:`[Manual save] ${E.narrative}`,toolName:"mem-create",tokenCount:k(`${E.title} ${E.narrative}`),discoveryTokens:0,importance:E.importance??3});return this.sessions.incrementObservationCount(E.sessionId),M}async update(E){let M=this.observations.getById(E.id);if(!M)return null;let N=this.sessions.getById(M.sessionId);if(!N||N.projectPath!==this.projectPath)return null;let{id:_,...J}=E;return this.observations.update(E.id,J)??null}async delete(E){let M=0;for(let N of E){let _=this.observations.getById(N);if(!_)continue;let J=this.sessions.getById(_.sessionId);if(!J||J.projectPath!==this.projectPath)continue;if(this.observations.delete(N))M+=1}return M}async export(E,M={}){if(E!=="project")throw Error("Only project scope export is supported.");let N=this.sessions.getAll(this.projectPath),_=[];for(let A of N)_.push(...this.observations.getBySession(A.id));if(M.type)_=_.filter((A)=>A.type===M.type);if(_.sort((A,$)=>new Date(A.createdAt).getTime()-new Date($.createdAt).getTime()),M.limit&&M.limit<_.length)_=_.slice(0,M.limit);let J=_.map(({rawToolOutput:A,...$})=>$),V=N.map((A)=>this.summaries.getBySessionId(A.id)).filter((A)=>A!==null);return{version:1,exportedAt:new Date().toISOString(),project:this.projectPath,observations:J,summaries:V}}async import(E,M={}){let N;try{N=JSON.parse(E)}catch{throw Error("Invalid JSON payload.")}if(typeof N!=="object"||N===null)throw Error("Invalid import payload.");let _=N;if(_.version!==1||!Array.isArray(_.observations))throw Error("Unsupported export format.");let J=M.mode??"skip-duplicates",V=0,S=0;for(let A of _.observations){let $=this.observations.getById(A.id);if($&&J==="skip-duplicates"){S+=1;continue}if($&&J==="overwrite")this.observations.delete(A.id);this.sessions.getOrCreate(A.sessionId,this.projectPath),this.observations.importObservation({id:A.id,sessionId:A.sessionId,type:A.type,title:A.title,subtitle:A.subtitle??"",facts:A.facts??[],narrative:A.narrative??"",concepts:A.concepts??[],filesRead:A.filesRead??[],filesModified:A.filesModified??[],rawToolOutput:A.rawToolOutput??"",toolName:A.toolName??"unknown",createdAt:A.createdAt,tokenCount:A.tokenCount??0,discoveryTokens:A.discoveryTokens??0,importance:A.importance??3,supersededBy:A.supersededBy??null,supersededAt:A.supersededAt??null}),this.sessions.incrementObservationCount(A.sessionId),V+=1}for(let A of _.summaries??[]){let $=this.summaries.getBySessionId(A.sessionId);if($&&J==="skip-duplicates")continue;if($&&J==="overwrite")continue;this.sessions.getOrCreate(A.sessionId,this.projectPath),this.summaries.importSummary(A),this.sessions.setSummary(A.sessionId,A.id)}return{imported:V,skipped:S}}async buildContext(E,M="normal"){let N=this.sessions.getRecent(this.projectPath,5),_=N.map((X)=>X.summaryId?this.summaries.getBySessionId(X.id):null).filter((X)=>X!==null),J=this.observations.getIndex(this.projectPath,this.config.maxObservations),S=J.slice(0,this.config.contextFullObservationCount).map((X)=>X.id).map((X)=>this.observations.getById(X)).filter((X)=>X!==null),A=bE(N,_,J,this.config.maxContextTokens,S);if(M==="compaction"){let X=wE(A);if(this.config.userMemoryEnabled&&this.userObservationRepo)X+=lE(this.userObservationRepo.getIndex(this.config.maxObservations),this.config.userMemoryMaxContextTokens);return X}let $={showTokenCosts:this.config.contextShowTokenCosts,observationTypes:this.config.contextObservationTypes,fullObservationCount:this.config.contextFullObservationCount,showLastSummary:this.config.contextShowLastSummary},O=pE(A,$);if(this.config.userMemoryEnabled&&this.userObservationRepo){let X=gE(this.userObservationRepo.getIndex(this.config.maxObservations),this.config.userMemoryMaxContextTokens);if(X)O+=`
33
33
 
34
- ${C}`}return O}guide(){return["# open-mem Workflow Guide","","## Reading Memories","1. `mem-find` \u2014 Search by query (returns IDs + summaries)","2. `mem-history` \u2014 Browse session timeline and summaries","3. `mem-get` \u2014 Fetch full details by ID (from find/history results)","","## When to Save (`mem-create`)","Save when the information is **stable, reusable, and non-obvious**:",'- Architectural decisions + rationale ("chose X over Y because...")',"- Non-obvious gotchas or workarounds discovered","- User preferences and conventions","- Cross-session plans or migration progress",'- Environment constraints ("Bedrock requires tool names matching [a-zA-Z0-9_-]+")',"","## When NOT to Save","Auto-capture already handles tool executions. Don't manually save:","- Ephemeral logs or one-off command outputs","- Information already visible in code or config files","- Routine file reads or edits (auto-captured)","","## Memory Types","- `decision` \u2014 Architectural choices with rationale","- `discovery` \u2014 Non-obvious findings, gotchas, constraints","- `bugfix` \u2014 Bug root causes and fixes","- `feature` \u2014 Feature implementations and design notes","- `refactor` \u2014 Refactoring rationale and approach","- `change` \u2014 General changes worth remembering","","## Editing & Cleanup","- `mem-revise` \u2014 Update outdated memories with new revisions","- `mem-remove` \u2014 Tombstone obsolete or incorrect memories","","## Privacy","Wrap sensitive content in `<private>` tags to exclude from memory.","","## Transfer","- `mem-export` \u2014 Backup/portability as JSON","- `mem-import` \u2014 Restore from JSON export"].join(`
35
- `)}listObservations(E){let{limit:M=50,offset:N=0,type:_,sessionId:J,state:S}=E;if(S)return this.listByProjectWithState({limit:M,offset:N,type:_,state:S,sessionId:J});if(J){let $=this.observations.getBySession(J);if(_)$=$.filter((O)=>O.type===_);return $.slice(N,N+M)}let A=this.observations.getIndex(this.projectPath,N+M).slice(N);if(_)A=A.filter(($)=>$.type===_);return A.map(($)=>this.observations.getById($.id)).filter(($)=>$!==null)}getObservation(E){return this.observations.getById(E)}getLineage(E){let N=this.getByIdIncludingArchived(E);if(!N)return null;let _=N,J=0,S=new Set([N.id]);while(_.revisionOf&&J<256){let C=this.getByIdIncludingArchived(_.revisionOf);if(!C||S.has(C.id))break;_=C,S.add(C.id),J+=1}let V=[],A=_,$=new Set,O=0;while(A&&!$.has(A.id)&&O<256){$.add(A.id);let C=A.deletedAt?"tombstoned":A.supersededBy?"superseded":"current";V.push({id:A.id,revisionOf:A.revisionOf??null,supersededBy:A.supersededBy??null,supersededAt:A.supersededAt??null,deletedAt:A.deletedAt??null,state:C,observation:A}),A=A.supersededBy?this.getByIdIncludingArchived(A.supersededBy):null,O+=1}return V}listSessions(E){return this.sessions.getRecent(E.projectPath??this.projectPath,E.limit??20)}getSession(E){let M=this.sessions.getById(E);if(!M)return null;return{session:M,summary:this.summaries.getBySessionId(E),observations:this.observations.getBySession(E)}}stats(){let E=this.observations.getCount(),N=this.sessions.getAll(this.projectPath).length,_=this.observations.getIndex(this.projectPath,1e4),J=0,S=0,V={};for(let O of _)J+=O.tokenCount,S+=O.discoveryTokens,V[O.type]=(V[O.type]||0)+1;let A=S-J,$=_.length>0?Math.round(J/_.length):0;return{totalObservations:E,totalSessions:N,totalTokensSaved:A,averageObservationSize:$,typeBreakdown:V}}async maintainFolderContext(E,M){if(E==="purge")return{action:"purge",dryRun:!1,...await eE(this.projectPath,this.config.folderContextFilename)};if(E==="rebuild"){let _=await sE(this.projectPath,this.sessions,this.observations,{maxDepth:this.config.folderContextMaxDepth,mode:this.config.folderContextMode,filename:this.config.folderContextFilename},M);return{action:E,dryRun:M,..._}}let N=await tE(this.projectPath,this.config.folderContextFilename,M);return{action:"clean",dryRun:M,...N}}getRevisionDiff(E,M){let N=this.getByIdIncludingArchived(E),_=this.getByIdIncludingArchived(M);if(!N||!_)return null;let J=[],S=(A,$,O)=>{if(JSON.stringify($)!==JSON.stringify(O))J.push({field:A,before:$,after:O})};S("title",_.title,N.title),S("subtitle",_.subtitle,N.subtitle),S("narrative",_.narrative,N.narrative),S("type",_.type,N.type),S("facts",_.facts,N.facts),S("concepts",_.concepts,N.concepts),S("filesRead",_.filesRead,N.filesRead),S("filesModified",_.filesModified,N.filesModified),S("importance",_.importance,N.importance);let V=J.length===0?"No material changes between revisions.":`Changed ${J.length} field${J.length===1?"":"s"}: ${J.map((A)=>A.field).join(", ")}.`;return{fromId:M,toId:E,summary:V,changedFields:J}}getHealth(){let E=this.runtimeSnapshotProvider?.(),M=E&&E.queue.lastError?"degraded":"ok";return{status:E?.status??"ok",timestamp:E?.timestamp??new Date().toISOString(),components:{database:{status:"ok"},search:{status:"ok"},config:{status:"ok"},queue:{status:M,detail:E?.queue.lastError??void 0}}}}getMetrics(){let E=this.stats();return{timestamp:this.runtimeSnapshotProvider?.()?.timestamp??new Date().toISOString(),memory:{totalObservations:E.totalObservations,totalSessions:E.totalSessions,totalTokensSaved:E.totalTokensSaved,averageObservationSize:E.averageObservationSize}}}getPlatforms(){return{name:"open-mem",provider:this.config.provider,dashboardEnabled:this.config.dashboardEnabled,vectorEnabled:Boolean(this.config.embeddingDimension&&this.config.embeddingDimension>0)}}getAdapterStatuses(){let E={opencode:this.config.platformOpenCodeEnabled??!0,"claude-code":this.config.platformClaudeCodeEnabled??!1,cursor:this.config.platformCursorEnabled??!1};return[{name:"opencode",version:"1.0",capabilities:{nativeSessionLifecycle:!0,nativeToolCapture:!0,nativeChatCapture:!0,emulatedIdleFlush:!1}},{name:"claude-code",version:"0.1",capabilities:{nativeSessionLifecycle:!0,nativeToolCapture:!0,nativeChatCapture:!0,emulatedIdleFlush:!0}},{name:"cursor",version:"0.1",capabilities:{nativeSessionLifecycle:!1,nativeToolCapture:!0,nativeChatCapture:!0,emulatedIdleFlush:!0}}].map((N)=>({name:N.name,version:N.version,enabled:E[N.name]??!1,capabilities:N.capabilities}))}getConfigAuditTimeline(){if(this.configAuditStore)return this.configAuditStore.list();return[...this.configAuditLogFallback].reverse()}trackConfigAudit(E){if(this.configAuditStore){this.configAuditStore.append(E);return}this.configAuditLogFallback.push(E)}async rollbackConfig(E){let M=this.configAuditStore?this.configAuditStore.getById(E):this.configAuditLogFallback.find((S)=>S.id===E)??null;if(!M)return null;if(!M.previousValues||typeof M.previousValues!=="object")return null;let{patchConfig:N}=await Promise.resolve().then(() => (S0(),J0)),_=M.previousValues;try{await N(this.projectPath,_)}catch(S){let V={id:`rollback-failed-${V0()}`,timestamp:new Date().toISOString(),patch:M.previousValues,previousValues:M.patch,source:"rollback-failed"};throw this.trackConfigAudit(V),S}let J={id:`rollback-${V0()}`,timestamp:new Date().toISOString(),patch:M.previousValues,previousValues:M.patch,source:"rollback"};return this.trackConfigAudit(J),J}getMaintenanceHistory(){if(this.maintenanceHistoryStore)return this.maintenanceHistoryStore.list();return[...this.maintenanceLogFallback].reverse()}trackMaintenanceResult(E){if(this.maintenanceHistoryStore){this.maintenanceHistoryStore.append(E);return}this.maintenanceLogFallback.push(E)}}function n(E){try{let M=JSON.parse(E);return M&&typeof M==="object"?M:{}}catch{return{}}}class KE{db;constructor(E){this.db=E}list(){return this.db.all("SELECT id, timestamp, patch, previous_values, source FROM config_audit_events ORDER BY timestamp DESC").map((E)=>({id:E.id,timestamp:E.timestamp,patch:n(E.patch),previousValues:n(E.previous_values),source:E.source}))}getById(E){let M=this.db.get("SELECT id, timestamp, patch, previous_values, source FROM config_audit_events WHERE id = ?",[E]);if(!M)return null;return{id:M.id,timestamp:M.timestamp,patch:n(M.patch),previousValues:n(M.previous_values),source:M.source}}append(E){this.db.run("INSERT INTO config_audit_events (id, timestamp, patch, previous_values, source) VALUES (?, ?, ?, ?, ?)",[E.id,E.timestamp,JSON.stringify(E.patch??{}),JSON.stringify(E.previousValues??{}),E.source])}}import{Database as A0}from"bun:sqlite";import{existsSync as HE,mkdirSync as yM,unlinkSync as $0}from"fs";import*as O0 from"sqlite-vec";class d{db;dbPath;_hasVectorExtension=!1;static enableExtensionSupport(){let E=["/opt/homebrew/opt/sqlite/lib/libsqlite3.dylib","/usr/local/opt/sqlite/lib/libsqlite3.dylib"];for(let M of E)try{if(HE(M))return A0.setCustomSQLite(M),!0}catch{return!1}return!1}constructor(E){this.dbPath=E,this.db=this.open(E),this.configure()}open(E){let M=E.lastIndexOf("/");if(M>0){let N=E.substring(0,M);yM(N,{recursive:!0})}return new A0(E,{create:!0})}configure(){try{this.applyPragmas(),this.loadExtensions()}catch(E){console.warn("[open-mem] Database configure failed, attempting recovery by removing WAL/SHM files:",E.message);try{this.db.close()}catch{}this.deleteSidecarFiles();try{this.db=this.open(this.dbPath),this.applyPragmas(),this.loadExtensions(),console.warn("[open-mem] Recovery successful after removing WAL/SHM files");return}catch(M){console.warn("[open-mem] WAL/SHM cleanup insufficient, recreating database from scratch:",M.message);try{this.db.close()}catch{}this.deleteDatabaseFiles();try{this.db=this.open(this.dbPath),this.applyPragmas(),this.loadExtensions(),console.warn("[open-mem] Recovery successful after full database recreation");return}catch(N){throw console.warn("[open-mem] All recovery attempts failed, filesystem may be broken:",N.message),E}}}}applyPragmas(){this.db.exec("PRAGMA journal_mode = WAL"),this.db.exec("PRAGMA synchronous = NORMAL"),this.db.exec("PRAGMA foreign_keys = ON"),this.db.exec("PRAGMA busy_timeout = 5000")}loadExtensions(){try{O0.load(this.db),this._hasVectorExtension=!0}catch{this._hasVectorExtension=!1}}get hasVectorExtension(){return this._hasVectorExtension}deleteSidecarFiles(){for(let E of["-wal","-shm"]){let M=this.dbPath+E;try{if(HE(M))$0(M)}catch{}}}deleteDatabaseFiles(){this.deleteSidecarFiles();try{if(HE(this.dbPath))$0(this.dbPath)}catch{}}ensureMigrationTable(){this.db.exec(`
34
+ ${X}`}return O}guide(){return["# open-mem Workflow Guide","","## Reading Memories","1. `mem-find` \u2014 Search by query (returns IDs + summaries)","2. `mem-history` \u2014 Browse session timeline and summaries","3. `mem-get` \u2014 Fetch full details by ID (from find/history results)","","## When to Save (`mem-create`)","Save when the information is **stable, reusable, and non-obvious**:",'- Architectural decisions + rationale ("chose X over Y because...")',"- Non-obvious gotchas or workarounds discovered","- User preferences and conventions","- Cross-session plans or migration progress",'- Environment constraints ("Bedrock requires tool names matching [a-zA-Z0-9_-]+")',"","## When NOT to Save","Auto-capture already handles tool executions. Don't manually save:","- Ephemeral logs or one-off command outputs","- Information already visible in code or config files","- Routine file reads or edits (auto-captured)","","## Memory Types","- `decision` \u2014 Architectural choices with rationale","- `discovery` \u2014 Non-obvious findings, gotchas, constraints","- `bugfix` \u2014 Bug root causes and fixes","- `feature` \u2014 Feature implementations and design notes","- `refactor` \u2014 Refactoring rationale and approach","- `change` \u2014 General changes worth remembering","","## Editing & Cleanup","- `mem-revise` \u2014 Update outdated memories with new revisions","- `mem-remove` \u2014 Tombstone obsolete or incorrect memories","","## Privacy","Wrap sensitive content in `<private>` tags to exclude from memory.","","## Transfer","- `mem-export` \u2014 Backup/portability as JSON","- `mem-import` \u2014 Restore from JSON export"].join(`
35
+ `)}listObservations(E){let{limit:M=50,offset:N=0,type:_,sessionId:J,state:V}=E;if(V)return this.listByProjectWithState({limit:M,offset:N,type:_,state:V,sessionId:J});if(J){let $=this.observations.getBySession(J);if(_)$=$.filter((O)=>O.type===_);return $.slice(N,N+M)}let A=this.observations.getIndex(this.projectPath,N+M).slice(N);if(_)A=A.filter(($)=>$.type===_);return A.map(($)=>this.observations.getById($.id)).filter(($)=>$!==null)}getObservation(E){return this.observations.getById(E)}getLineage(E){let N=this.getByIdIncludingArchived(E);if(!N)return null;let _=N,J=0,V=new Set([N.id]);while(_.revisionOf&&J<256){let X=this.getByIdIncludingArchived(_.revisionOf);if(!X||V.has(X.id))break;_=X,V.add(X.id),J+=1}let S=[],A=_,$=new Set,O=0;while(A&&!$.has(A.id)&&O<256){$.add(A.id);let X=A.deletedAt?"tombstoned":A.supersededBy?"superseded":"current";S.push({id:A.id,revisionOf:A.revisionOf??null,supersededBy:A.supersededBy??null,supersededAt:A.supersededAt??null,deletedAt:A.deletedAt??null,state:X,observation:A}),A=A.supersededBy?this.getByIdIncludingArchived(A.supersededBy):null,O+=1}return S}listSessions(E){return this.sessions.getRecent(E.projectPath??this.projectPath,E.limit??20)}getSession(E){let M=this.sessions.getById(E);if(!M)return null;return{session:M,summary:this.summaries.getBySessionId(E),observations:this.observations.getBySession(E)}}stats(){let E=this.observations.getCount(),N=this.sessions.getAll(this.projectPath).length,_=this.observations.getIndex(this.projectPath,1e4),J=0,V=0,S={};for(let O of _)J+=O.tokenCount,V+=O.discoveryTokens,S[O.type]=(S[O.type]||0)+1;let A=V-J,$=_.length>0?Math.round(J/_.length):0;return{totalObservations:E,totalSessions:N,totalTokensSaved:A,averageObservationSize:$,typeBreakdown:S}}async maintainFolderContext(E,M){if(E==="purge")return{action:"purge",dryRun:!1,...await _0(this.projectPath,this.config.folderContextFilename)};if(E==="rebuild"){let _=await J0(this.projectPath,this.sessions,this.observations,{maxDepth:this.config.folderContextMaxDepth,mode:this.config.folderContextMode,filename:this.config.folderContextFilename},M);return{action:E,dryRun:M,..._}}let N=await N0(this.projectPath,this.config.folderContextFilename,M);return{action:"clean",dryRun:M,...N}}getRevisionDiff(E,M){let N=this.getByIdIncludingArchived(E),_=this.getByIdIncludingArchived(M);if(!N||!_)return null;let J=[],V=(A,$,O)=>{if(JSON.stringify($)!==JSON.stringify(O))J.push({field:A,before:$,after:O})};V("title",_.title,N.title),V("subtitle",_.subtitle,N.subtitle),V("narrative",_.narrative,N.narrative),V("type",_.type,N.type),V("facts",_.facts,N.facts),V("concepts",_.concepts,N.concepts),V("filesRead",_.filesRead,N.filesRead),V("filesModified",_.filesModified,N.filesModified),V("importance",_.importance,N.importance);let S=J.length===0?"No material changes between revisions.":`Changed ${J.length} field${J.length===1?"":"s"}: ${J.map((A)=>A.field).join(", ")}.`;return{fromId:M,toId:E,summary:S,changedFields:J}}getHealth(){let E=this.runtimeSnapshotProvider?.(),M=E&&E.queue.lastError?"degraded":"ok";return{status:E?.status??"ok",timestamp:E?.timestamp??new Date().toISOString(),components:{database:{status:"ok"},search:{status:"ok"},config:{status:"ok"},queue:{status:M,detail:E?.queue.lastError??void 0}}}}getMetrics(){let E=this.stats();return{timestamp:this.runtimeSnapshotProvider?.()?.timestamp??new Date().toISOString(),memory:{totalObservations:E.totalObservations,totalSessions:E.totalSessions,totalTokensSaved:E.totalTokensSaved,averageObservationSize:E.averageObservationSize}}}getPlatforms(){return{name:"open-mem",provider:this.config.provider,dashboardEnabled:this.config.dashboardEnabled,vectorEnabled:Boolean(this.config.embeddingDimension&&this.config.embeddingDimension>0)}}getAdapterStatuses(){let E={opencode:this.config.platformOpenCodeEnabled??!0,"claude-code":this.config.platformClaudeCodeEnabled??!1,cursor:this.config.platformCursorEnabled??!1};return[{name:"opencode",version:"1.0",capabilities:{nativeSessionLifecycle:!0,nativeToolCapture:!0,nativeChatCapture:!0,emulatedIdleFlush:!1}},{name:"claude-code",version:"0.1",capabilities:{nativeSessionLifecycle:!0,nativeToolCapture:!0,nativeChatCapture:!0,emulatedIdleFlush:!0}},{name:"cursor",version:"0.1",capabilities:{nativeSessionLifecycle:!1,nativeToolCapture:!0,nativeChatCapture:!0,emulatedIdleFlush:!0}}].map((N)=>({name:N.name,version:N.version,enabled:E[N.name]??!1,capabilities:N.capabilities}))}getConfigAuditTimeline(){if(this.configAuditStore)return this.configAuditStore.list();return[...this.configAuditLogFallback].reverse()}trackConfigAudit(E){if(this.configAuditStore){this.configAuditStore.append(E);return}this.configAuditLogFallback.push(E)}async rollbackConfig(E){let M=this.configAuditStore?this.configAuditStore.getById(E):this.configAuditLogFallback.find((V)=>V.id===E)??null;if(!M)return null;if(!M.previousValues||typeof M.previousValues!=="object")return null;let{patchConfig:N}=await Promise.resolve().then(() => (X0(),O0)),_=M.previousValues;try{await N(this.projectPath,_)}catch(V){let S={id:`rollback-failed-${Z0()}`,timestamp:new Date().toISOString(),patch:M.previousValues,previousValues:M.patch,source:"rollback-failed"};throw this.trackConfigAudit(S),V}let J={id:`rollback-${Z0()}`,timestamp:new Date().toISOString(),patch:M.previousValues,previousValues:M.patch,source:"rollback"};return this.trackConfigAudit(J),J}getMaintenanceHistory(){if(this.maintenanceHistoryStore)return this.maintenanceHistoryStore.list();return[...this.maintenanceLogFallback].reverse()}trackMaintenanceResult(E){if(this.maintenanceHistoryStore){this.maintenanceHistoryStore.append(E);return}this.maintenanceLogFallback.push(E)}}function d(E){try{let M=JSON.parse(E);return M&&typeof M==="object"?M:{}}catch{return{}}}class WE{db;constructor(E){this.db=E}list(){return this.db.all("SELECT id, timestamp, patch, previous_values, source FROM config_audit_events ORDER BY timestamp DESC").map((E)=>({id:E.id,timestamp:E.timestamp,patch:d(E.patch),previousValues:d(E.previous_values),source:E.source}))}getById(E){let M=this.db.get("SELECT id, timestamp, patch, previous_values, source FROM config_audit_events WHERE id = ?",[E]);if(!M)return null;return{id:M.id,timestamp:M.timestamp,patch:d(M.patch),previousValues:d(M.previous_values),source:M.source}}append(E){this.db.run("INSERT INTO config_audit_events (id, timestamp, patch, previous_values, source) VALUES (?, ?, ?, ?, ?)",[E.id,E.timestamp,JSON.stringify(E.patch??{}),JSON.stringify(E.previousValues??{}),E.source])}}import{Database as U0}from"bun:sqlite";import{existsSync as YE,mkdirSync as vM,unlinkSync as K0}from"fs";import*as H0 from"sqlite-vec";class i{db;dbPath;_hasVectorExtension=!1;static enableExtensionSupport(){let E=["/opt/homebrew/opt/sqlite/lib/libsqlite3.dylib","/usr/local/opt/sqlite/lib/libsqlite3.dylib"];for(let M of E)try{if(YE(M))return U0.setCustomSQLite(M),!0}catch{return!1}return!1}constructor(E){this.dbPath=E,this.db=this.open(E),this.configure()}open(E){let M=E.lastIndexOf("/");if(M>0){let N=E.substring(0,M);vM(N,{recursive:!0})}return new U0(E,{create:!0})}configure(){try{this.applyPragmas(),this.loadExtensions()}catch(E){console.warn("[open-mem] Database configure failed, attempting recovery by removing WAL/SHM files:",E.message);try{this.db.close()}catch{}this.deleteSidecarFiles();try{this.db=this.open(this.dbPath),this.applyPragmas(),this.loadExtensions(),console.warn("[open-mem] Recovery successful after removing WAL/SHM files");return}catch(M){console.warn("[open-mem] WAL/SHM cleanup insufficient, recreating database from scratch:",M.message);try{this.db.close()}catch{}this.deleteDatabaseFiles();try{this.db=this.open(this.dbPath),this.applyPragmas(),this.loadExtensions(),console.warn("[open-mem] Recovery successful after full database recreation");return}catch(N){throw console.warn("[open-mem] All recovery attempts failed, filesystem may be broken:",N.message),E}}}}applyPragmas(){this.db.exec("PRAGMA journal_mode = WAL"),this.db.exec("PRAGMA synchronous = NORMAL"),this.db.exec("PRAGMA foreign_keys = ON"),this.db.exec("PRAGMA busy_timeout = 5000")}loadExtensions(){try{H0.load(this.db),this._hasVectorExtension=!0}catch{this._hasVectorExtension=!1}}get hasVectorExtension(){return this._hasVectorExtension}deleteSidecarFiles(){for(let E of["-wal","-shm"]){let M=this.dbPath+E;try{if(YE(M))K0(M)}catch{}}}deleteDatabaseFiles(){this.deleteSidecarFiles();try{if(YE(this.dbPath))K0(this.dbPath)}catch{}}ensureMigrationTable(){this.db.exec(`
36
36
  CREATE TABLE IF NOT EXISTS _migrations (
37
37
  version INTEGER PRIMARY KEY,
38
38
  name TEXT NOT NULL,
39
39
  applied_at TEXT NOT NULL DEFAULT (datetime('now'))
40
40
  )
41
- `)}migrate(E){this.ensureMigrationTable();let M=this.db.query("SELECT version FROM _migrations ORDER BY version").all(),N=new Set(M.map((J)=>J.version)),_=E.filter((J)=>!N.has(J.version)).sort((J,S)=>J.version-S.version);for(let J of _)this.db.transaction(()=>{this.db.exec(J.up),this.db.query("INSERT INTO _migrations (version, name) VALUES ($version, $name)").run({$version:J.version,$name:J.name})})()}run(E,M){let N=this.db.query(E);if(M)N.run(...M);else N.run()}get(E,M){let N=this.db.query(E);return M?N.get(...M):N.get()}all(E,M){let N=this.db.query(E);return M?N.all(...M):N.all()}exec(E){this.db.exec(E)}transaction(E){return this.db.transaction(E)()}close(){this.db.close()}get isOpen(){try{return this.db.query("SELECT 1").get(),!0}catch{return!1}}get raw(){return this.db}}function i(E){return new d(E)}import{randomUUID as C0}from"crypto";class zE{db;constructor(E){this.db=E}upsertEntity(E,M){let N=C0(),_=new Date().toISOString();this.db.run(`INSERT INTO entities (id, name, entity_type, first_seen_at, last_seen_at, mention_count)
41
+ `)}migrate(E){this.ensureMigrationTable();let M=this.db.query("SELECT version FROM _migrations ORDER BY version").all(),N=new Set(M.map((J)=>J.version)),_=E.filter((J)=>!N.has(J.version)).sort((J,V)=>J.version-V.version);for(let J of _)this.db.transaction(()=>{this.db.exec(J.up),this.db.query("INSERT INTO _migrations (version, name) VALUES ($version, $name)").run({$version:J.version,$name:J.name})})()}run(E,M){let N=this.db.query(E);if(M)N.run(...M);else N.run()}get(E,M){let N=this.db.query(E);return M?N.get(...M):N.get()}all(E,M){let N=this.db.query(E);return M?N.all(...M):N.all()}exec(E){this.db.exec(E)}transaction(E){return this.db.transaction(E)()}close(){this.db.close()}get isOpen(){try{return this.db.query("SELECT 1").get(),!0}catch{return!1}}get raw(){return this.db}}function r(E){return new i(E)}import{randomUUID as z0}from"crypto";class BE{db;constructor(E){this.db=E}upsertEntity(E,M){let N=z0(),_=new Date().toISOString();this.db.run(`INSERT INTO entities (id, name, entity_type, first_seen_at, last_seen_at, mention_count)
42
42
  VALUES (?, ?, ?, ?, ?, 1)
43
43
  ON CONFLICT(name, entity_type) DO UPDATE SET
44
44
  mention_count = mention_count + 1,
45
- last_seen_at = ?`,[N,E,M,_,_,_]);let J=this.db.get("SELECT * FROM entities WHERE name = ? AND entity_type = ?",[E,M]);if(!J)throw Error(`Failed to upsert entity: ${E} (${M})`);return this.mapEntityRow(J)}createRelation(E,M,N,_){let J=C0(),S=new Date().toISOString();try{this.db.run(`INSERT OR IGNORE INTO entity_relations
45
+ last_seen_at = ?`,[N,E,M,_,_,_]);let J=this.db.get("SELECT * FROM entities WHERE name = ? AND entity_type = ?",[E,M]);if(!J)throw Error(`Failed to upsert entity: ${E} (${M})`);return this.mapEntityRow(J)}createRelation(E,M,N,_){let J=z0(),V=new Date().toISOString();try{this.db.run(`INSERT OR IGNORE INTO entity_relations
46
46
  (id, source_entity_id, target_entity_id, relationship, observation_id, created_at)
47
- VALUES (?, ?, ?, ?, ?, ?)`,[J,E,M,N,_,S])}catch{return null}let V=this.db.get(`SELECT * FROM entity_relations
48
- WHERE source_entity_id = ? AND target_entity_id = ? AND relationship = ?`,[E,M,N]);return V?this.mapRelationRow(V):null}linkObservation(E,M){this.db.run("INSERT OR IGNORE INTO entity_observations (entity_id, observation_id) VALUES (?, ?)",[E,M])}findByName(E){try{return this.db.all(`SELECT e.*
47
+ VALUES (?, ?, ?, ?, ?, ?)`,[J,E,M,N,_,V])}catch{return null}let S=this.db.get(`SELECT * FROM entity_relations
48
+ WHERE source_entity_id = ? AND target_entity_id = ? AND relationship = ?`,[E,M,N]);return S?this.mapRelationRow(S):null}linkObservation(E,M){this.db.run("INSERT OR IGNORE INTO entity_observations (entity_id, observation_id) VALUES (?, ?)",[E,M])}findByName(E){try{return this.db.all(`SELECT e.*
49
49
  FROM entities e
50
50
  JOIN entities_fts fts ON e._rowid = fts.rowid
51
51
  WHERE entities_fts MATCH ?
52
52
  ORDER BY rank`,[E]).map((N)=>this.mapEntityRow(N))}catch{return[]}}getRelationsFor(E){return this.db.all(`SELECT * FROM entity_relations
53
- WHERE source_entity_id = ? OR target_entity_id = ?`,[E,E]).map((N)=>this.mapRelationRow(N))}traverseRelations(E,M=1){let N=Math.min(M,2),_=100,J=new Set,S=[{id:E,currentDepth:0}];J.add(E);while(S.length>0){if(J.size>=100)break;let V=S.shift();if(!V)continue;if(V.currentDepth>=N)continue;let A=this.getRelationsFor(V.id);for(let $ of A){let O=$.sourceEntityId===V.id?$.targetEntityId:$.sourceEntityId;if(!J.has(O))J.add(O),S.push({id:O,currentDepth:V.currentDepth+1})}}return J}getObservationsForEntity(E){return this.db.all("SELECT observation_id FROM entity_observations WHERE entity_id = ?",[E]).map((N)=>N.observation_id)}getById(E){let M=this.db.get("SELECT * FROM entities WHERE id = ?",[E]);return M?this.mapEntityRow(M):null}mapEntityRow(E){return{id:E.id,name:E.name,entityType:E.entity_type,firstSeenAt:E.first_seen_at,lastSeenAt:E.last_seen_at,mentionCount:E.mention_count}}mapRelationRow(E){return{id:E.id,sourceEntityId:E.source_entity_id,targetEntityId:E.target_entity_id,relationship:E.relationship,observationId:E.observation_id,createdAt:E.created_at}}}function mM(E){try{let M=JSON.parse(E);return M&&typeof M==="object"?M:{}}catch{return{}}}class QE{db;constructor(E){this.db=E}list(){return this.db.all("SELECT id, timestamp, action, dry_run, result FROM maintenance_history ORDER BY timestamp DESC").map((E)=>({id:E.id,timestamp:E.timestamp,action:E.action,dryRun:E.dry_run===1,result:mM(E.result)}))}append(E){this.db.run("INSERT INTO maintenance_history (id, timestamp, action, dry_run, result) VALUES (?, ?, ?, ?, ?)",[E.id,E.timestamp,E.action,E.dryRun?1:0,JSON.stringify(E.result??{})])}}import{randomUUID as fM}from"crypto";import{embed as PM}from"ai";async function a(E,M){try{let{embedding:N}=await PM({model:E,value:M});return N}catch{return null}}function f(E,M){if(E.length!==M.length||E.length===0)return 0;let N=0,_=0,J=0;for(let V=0;V<E.length;V++)N+=E[V]*M[V],_+=E[V]*E[V],J+=M[V]*M[V];let S=Math.sqrt(_)*Math.sqrt(J);if(S===0)return 0;return N/S}function IM(E){return E.replace(/[%_\\]/g,"\\$&")}class RE{db;constructor(E){this.db=E}create(E){let M=fM(),N=new Date().toISOString(),_=E.discoveryTokens??0,J=E.importance??3,S=E.scope??"project";return this.db.run(`INSERT INTO observations
53
+ WHERE source_entity_id = ? OR target_entity_id = ?`,[E,E]).map((N)=>this.mapRelationRow(N))}traverseRelations(E,M=1){let N=Math.min(M,2),_=100,J=new Set,V=[{id:E,currentDepth:0}];J.add(E);while(V.length>0){if(J.size>=100)break;let S=V.shift();if(!S)continue;if(S.currentDepth>=N)continue;let A=this.getRelationsFor(S.id);for(let $ of A){let O=$.sourceEntityId===S.id?$.targetEntityId:$.sourceEntityId;if(!J.has(O))J.add(O),V.push({id:O,currentDepth:S.currentDepth+1})}}return J}getObservationsForEntity(E){return this.db.all("SELECT observation_id FROM entity_observations WHERE entity_id = ?",[E]).map((N)=>N.observation_id)}getById(E){let M=this.db.get("SELECT * FROM entities WHERE id = ?",[E]);return M?this.mapEntityRow(M):null}mapEntityRow(E){return{id:E.id,name:E.name,entityType:E.entity_type,firstSeenAt:E.first_seen_at,lastSeenAt:E.last_seen_at,mentionCount:E.mention_count}}mapRelationRow(E){return{id:E.id,sourceEntityId:E.source_entity_id,targetEntityId:E.target_entity_id,relationship:E.relationship,observationId:E.observation_id,createdAt:E.created_at}}}function pM(E){try{let M=JSON.parse(E);return M&&typeof M==="object"?M:{}}catch{return{}}}class LE{db;constructor(E){this.db=E}list(){return this.db.all("SELECT id, timestamp, action, dry_run, result FROM maintenance_history ORDER BY timestamp DESC").map((E)=>({id:E.id,timestamp:E.timestamp,action:E.action,dryRun:E.dry_run===1,result:pM(E.result)}))}append(E){this.db.run("INSERT INTO maintenance_history (id, timestamp, action, dry_run, result) VALUES (?, ?, ?, ?, ?)",[E.id,E.timestamp,E.action,E.dryRun?1:0,JSON.stringify(E.result??{})])}}import{randomUUID as gM}from"crypto";import{embed as wM}from"ai";async function a(E,M){try{let{embedding:N}=await wM({model:E,value:M});return N}catch{return null}}function q(E,M){if(E.length!==M.length||E.length===0)return 0;let N=0,_=0,J=0;for(let S=0;S<E.length;S++)N+=E[S]*M[S],_+=E[S]*E[S],J+=M[S]*M[S];let V=Math.sqrt(_)*Math.sqrt(J);if(V===0)return 0;return N/V}function lM(E){return E.replace(/[%_\\]/g,"\\$&")}class RE{db;constructor(E){this.db=E}create(E){let M=gM(),N=new Date().toISOString(),_=E.discoveryTokens??0,J=E.importance??3,V=E.scope??"project";return this.db.run(`INSERT INTO observations
54
54
  (id, session_id, scope, type, title, subtitle, facts, narrative,
55
55
  concepts, files_read, files_modified, raw_tool_output,
56
56
  tool_name, created_at, token_count, discovery_tokens, importance, revision_of, deleted_at)
57
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[M,E.sessionId,S,E.type,E.title,E.subtitle,JSON.stringify(E.facts),E.narrative,JSON.stringify(E.concepts),JSON.stringify(E.filesRead),JSON.stringify(E.filesModified),E.rawToolOutput,E.toolName,N,E.tokenCount,_,J,null,null]),{...E,id:M,scope:S,createdAt:N,discoveryTokens:_,importance:J,revisionOf:null,deletedAt:null,supersededBy:null,supersededAt:null}}importObservation(E){this.db.run(`INSERT INTO observations
57
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[M,E.sessionId,V,E.type,E.title,E.subtitle,JSON.stringify(E.facts),E.narrative,JSON.stringify(E.concepts),JSON.stringify(E.filesRead),JSON.stringify(E.filesModified),E.rawToolOutput,E.toolName,N,E.tokenCount,_,J,null,null]),{...E,id:M,scope:V,createdAt:N,discoveryTokens:_,importance:J,revisionOf:null,deletedAt:null,supersededBy:null,supersededAt:null}}importObservation(E){this.db.run(`INSERT INTO observations
58
58
  (id, session_id, scope, type, title, subtitle, facts, narrative,
59
59
  concepts, files_read, files_modified, raw_tool_output,
60
60
  tool_name, created_at, token_count, discovery_tokens, importance, revision_of, deleted_at)
@@ -69,23 +69,23 @@ ${C}`}return O}guide(){return["# open-mem Workflow Guide","","## Reading Memorie
69
69
  WHERE s.project_path = ? AND o.created_at < ?
70
70
  AND o.superseded_by IS NULL AND o.deleted_at IS NULL
71
71
  ORDER BY o.created_at DESC
72
- LIMIT ?`,[_,E,M]).reverse():[],S=N>0?this.db.all(`SELECT o.*
72
+ LIMIT ?`,[_,E,M]).reverse():[],V=N>0?this.db.all(`SELECT o.*
73
73
  FROM observations o
74
74
  JOIN sessions s ON o.session_id = s.id
75
75
  WHERE s.project_path = ? AND o.created_at > ?
76
76
  AND o.superseded_by IS NULL AND o.deleted_at IS NULL
77
77
  ORDER BY o.created_at ASC
78
- LIMIT ?`,[_,E,N]):[];return[...J,...S].map((V)=>this.mapRow(V))}listByProject(E,M={}){let{limit:N=50,offset:_=0,type:J,state:S,sessionId:V}=M,A=`SELECT o.*
78
+ LIMIT ?`,[_,E,N]):[];return[...J,...V].map((S)=>this.mapRow(S))}listByProject(E,M={}){let{limit:N=50,offset:_=0,type:J,state:V,sessionId:S}=M,A=`SELECT o.*
79
79
  FROM observations o
80
80
  JOIN sessions s ON o.session_id = s.id
81
- WHERE s.project_path = ?`,$=[E];if(V)A+=" AND o.session_id = ?",$.push(V);if(J)A+=" AND o.type = ?",$.push(J);if(S==="current")A+=" AND o.superseded_by IS NULL AND o.deleted_at IS NULL";else if(S==="superseded")A+=" AND o.superseded_by IS NOT NULL AND o.deleted_at IS NULL";else if(S==="tombstoned")A+=" AND o.deleted_at IS NOT NULL";else A+=" AND o.superseded_by IS NULL AND o.deleted_at IS NULL";return A+=" ORDER BY o.created_at DESC LIMIT ? OFFSET ?",$.push(N,_),this.db.all(A,$).map((O)=>this.mapRow(O))}search(E){let M=!!E.projectPath,N=`
81
+ WHERE s.project_path = ?`,$=[E];if(S)A+=" AND o.session_id = ?",$.push(S);if(J)A+=" AND o.type = ?",$.push(J);if(V==="current")A+=" AND o.superseded_by IS NULL AND o.deleted_at IS NULL";else if(V==="superseded")A+=" AND o.superseded_by IS NOT NULL AND o.deleted_at IS NULL";else if(V==="tombstoned")A+=" AND o.deleted_at IS NOT NULL";else A+=" AND o.superseded_by IS NULL AND o.deleted_at IS NULL";return A+=" ORDER BY o.created_at DESC LIMIT ? OFFSET ?",$.push(N,_),this.db.all(A,$).map((O)=>this.mapRow(O))}search(E){let M=!!E.projectPath,N=`
82
82
  SELECT o.*, rank
83
83
  FROM observations o
84
84
  JOIN observations_fts fts ON o._rowid = fts.rowid
85
85
  ${M?"JOIN sessions s ON o.session_id = s.id":""}
86
86
  WHERE observations_fts MATCH ? AND o.superseded_by IS NULL AND o.deleted_at IS NULL
87
- `,_=[E.query];if(M&&E.projectPath)N+=" AND s.project_path = ?",_.push(E.projectPath);if(E.sessionId)N+=" AND o.session_id = ?",_.push(E.sessionId);if(E.type)N+=" AND o.type = ?",_.push(E.type);if(E.importanceMin!==void 0)N+=" AND o.importance >= ?",_.push(E.importanceMin);if(E.importanceMax!==void 0)N+=" AND o.importance <= ?",_.push(E.importanceMax);if(E.createdAfter)N+=" AND o.created_at >= ?",_.push(E.createdAfter);if(E.createdBefore)N+=" AND o.created_at <= ?",_.push(E.createdBefore);if(E.concepts&&E.concepts.length>0){let J=E.concepts.map(()=>"EXISTS (SELECT 1 FROM json_each(o.concepts) WHERE LOWER(value) = LOWER(?))");N+=` AND (${J.join(" OR ")})`;for(let S of E.concepts)_.push(S)}if(E.files&&E.files.length>0){let J=E.files.map(()=>`(EXISTS (SELECT 1 FROM json_each(o.files_read) WHERE LOWER(value) LIKE LOWER(?) ESCAPE '\\')
88
- OR EXISTS (SELECT 1 FROM json_each(o.files_modified) WHERE LOWER(value) LIKE LOWER(?) ESCAPE '\\'))`);N+=` AND (${J.join(" OR ")})`;for(let S of E.files){let V=`%${IM(S)}%`;_.push(V,V)}}return N+=" ORDER BY rank LIMIT ? OFFSET ?",_.push(E.limit??10),_.push(E.offset??0),this.db.all(N,_).map((J)=>({observation:this.mapRow(J),rank:J.rank,snippet:J.title}))}searchByConcept(E,M=10,N){let _=!!N,J=`SELECT o.*
87
+ `,_=[E.query];if(M&&E.projectPath)N+=" AND s.project_path = ?",_.push(E.projectPath);if(E.sessionId)N+=" AND o.session_id = ?",_.push(E.sessionId);if(E.type)N+=" AND o.type = ?",_.push(E.type);if(E.importanceMin!==void 0)N+=" AND o.importance >= ?",_.push(E.importanceMin);if(E.importanceMax!==void 0)N+=" AND o.importance <= ?",_.push(E.importanceMax);if(E.createdAfter)N+=" AND o.created_at >= ?",_.push(E.createdAfter);if(E.createdBefore)N+=" AND o.created_at <= ?",_.push(E.createdBefore);if(E.concepts&&E.concepts.length>0){let J=E.concepts.map(()=>"EXISTS (SELECT 1 FROM json_each(o.concepts) WHERE LOWER(value) = LOWER(?))");N+=` AND (${J.join(" OR ")})`;for(let V of E.concepts)_.push(V)}if(E.files&&E.files.length>0){let J=E.files.map(()=>`(EXISTS (SELECT 1 FROM json_each(o.files_read) WHERE LOWER(value) LIKE LOWER(?) ESCAPE '\\')
88
+ OR EXISTS (SELECT 1 FROM json_each(o.files_modified) WHERE LOWER(value) LIKE LOWER(?) ESCAPE '\\'))`);N+=` AND (${J.join(" OR ")})`;for(let V of E.files){let S=`%${lM(V)}%`;_.push(S,S)}}return N+=" ORDER BY rank LIMIT ? OFFSET ?",_.push(E.limit??10),_.push(E.offset??0),this.db.all(N,_).map((J)=>({observation:this.mapRow(J),rank:J.rank,snippet:J.title}))}searchByConcept(E,M=10,N){let _=!!N,J=`SELECT o.*
89
89
  FROM observations o
90
90
  JOIN observations_fts fts ON o._rowid = fts.rowid
91
91
  ${_?"JOIN sessions s ON o.session_id = s.id":""}
@@ -93,7 +93,7 @@ ${C}`}return O}guide(){return["# open-mem Workflow Guide","","## Reading Memorie
93
93
  AND o.superseded_by IS NULL AND o.deleted_at IS NULL
94
94
  ${_?"AND s.project_path = ?":""}
95
95
  ORDER BY rank
96
- LIMIT ?`,S=[`concepts:${E}`];if(_&&N)S.push(N);return S.push(M),this.db.all(J,S).map((V)=>this.mapRow(V))}searchByFile(E,M=10,N){let _=!!N,J=`SELECT o.*
96
+ LIMIT ?`,V=[`concepts:${E}`];if(_&&N)V.push(N);return V.push(M),this.db.all(J,V).map((S)=>this.mapRow(S))}searchByFile(E,M=10,N){let _=!!N,J=`SELECT o.*
97
97
  FROM observations o
98
98
  JOIN observations_fts fts ON o._rowid = fts.rowid
99
99
  ${_?"JOIN sessions s ON o.session_id = s.id":""}
@@ -101,7 +101,7 @@ ${C}`}return O}guide(){return["# open-mem Workflow Guide","","## Reading Memorie
101
101
  AND o.superseded_by IS NULL AND o.deleted_at IS NULL
102
102
  ${_?"AND s.project_path = ?":""}
103
103
  ORDER BY rank
104
- LIMIT ?`,S=[`files_read:"${E.replace(/"/g,'""')}" OR files_modified:"${E.replace(/"/g,'""')}"`];if(_&&N)S.push(N);return S.push(M),this.db.all(J,S).map((V)=>this.mapRow(V))}setEmbedding(E,M){this.db.run("UPDATE observations SET embedding = ? WHERE id = ?",[JSON.stringify(M),E])}getWithEmbeddings(E,M){return this.db.all(`SELECT o.id, o.embedding, o.title
104
+ LIMIT ?`,V=[`files_read:"${E.replace(/"/g,'""')}" OR files_modified:"${E.replace(/"/g,'""')}"`];if(_&&N)V.push(N);return V.push(M),this.db.all(J,V).map((S)=>this.mapRow(S))}setEmbedding(E,M){this.db.run("UPDATE observations SET embedding = ? WHERE id = ?",[JSON.stringify(M),E])}getWithEmbeddings(E,M){return this.db.all(`SELECT o.id, o.embedding, o.title
105
105
  FROM observations o
106
106
  JOIN sessions s ON o.session_id = s.id
107
107
  WHERE s.project_path = ? AND o.embedding IS NOT NULL AND o.superseded_by IS NULL AND o.deleted_at IS NULL
@@ -109,14 +109,14 @@ ${C}`}return O}guide(){return["# open-mem Workflow Guide","","## Reading Memorie
109
109
  LIMIT ?`,[E,M]).map((N)=>{try{return{id:N.id,embedding:JSON.parse(N.embedding),title:N.title}}catch{return null}}).filter((N)=>N!==null)}findSimilar(E,M,N,_){let J=this.db.all(`SELECT id, embedding FROM observations
110
110
  WHERE embedding IS NOT NULL AND type = ? AND superseded_by IS NULL AND deleted_at IS NULL
111
111
  ORDER BY created_at DESC
112
- LIMIT 200`,[M]),S=[];for(let V of J)try{let A=JSON.parse(V.embedding);if(!Array.isArray(A)||A.length!==E.length)continue;let $=f(E,A);if($>=N)S.push({id:V.id,similarity:$})}catch{}return S.sort((V,A)=>A.similarity-V.similarity).slice(0,_)}insertVecEmbedding(E,M){let N=new Float32Array(M);this.db.run("BEGIN");try{this.db.run("DELETE FROM observation_embeddings WHERE observation_id = ?",[E]),this.db.run("INSERT INTO observation_embeddings (observation_id, embedding) VALUES (?, ?)",[E,N]),this.db.run("COMMIT")}catch(_){throw this.db.run("ROLLBACK"),_}}migrateExistingEmbeddings(E){let M=this.db.all("SELECT id, embedding FROM observations WHERE embedding IS NOT NULL"),N=0,_=0;for(let J of M)try{let S=JSON.parse(J.embedding);if(!Array.isArray(S)||S.length!==E){_++;continue}this.insertVecEmbedding(J.id,S),N++}catch{_++}return{migrated:N,skipped:_}}getVecEmbeddingMatches(E,M){try{let N=new Float32Array(E);return this.db.all(`SELECT observation_id, distance
112
+ LIMIT 200`,[M]),V=[];for(let S of J)try{let A=JSON.parse(S.embedding);if(!Array.isArray(A)||A.length!==E.length)continue;let $=q(E,A);if($>=N)V.push({id:S.id,similarity:$})}catch{}return V.sort((S,A)=>A.similarity-S.similarity).slice(0,_)}insertVecEmbedding(E,M){let N=new Float32Array(M);this.db.run("BEGIN");try{this.db.run("DELETE FROM observation_embeddings WHERE observation_id = ?",[E]),this.db.run("INSERT INTO observation_embeddings (observation_id, embedding) VALUES (?, ?)",[E,N]),this.db.run("COMMIT")}catch(_){throw this.db.run("ROLLBACK"),_}}migrateExistingEmbeddings(E){let M=this.db.all("SELECT id, embedding FROM observations WHERE embedding IS NOT NULL"),N=0,_=0;for(let J of M)try{let V=JSON.parse(J.embedding);if(!Array.isArray(V)||V.length!==E){_++;continue}this.insertVecEmbedding(J.id,V),N++}catch{_++}return{migrated:N,skipped:_}}getVecEmbeddingMatches(E,M){try{let N=new Float32Array(E);return this.db.all(`SELECT observation_id, distance
113
113
  FROM observation_embeddings
114
- WHERE embedding MATCH ? AND k = ?`,[N,M]).map((_)=>({observationId:_.observation_id,distance:_.distance}))}catch{return[]}}searchVecSubset(E,M,N){if(M.length===0)return[];try{let _=new Float32Array(E),J=Math.max(N*5,M.length),S=this.db.all(`SELECT observation_id, distance
114
+ WHERE embedding MATCH ? AND k = ?`,[N,M]).map((_)=>({observationId:_.observation_id,distance:_.distance}))}catch{return[]}}searchVecSubset(E,M,N){if(M.length===0)return[];try{let _=new Float32Array(E),J=Math.max(N*5,M.length),V=this.db.all(`SELECT observation_id, distance
115
115
  FROM observation_embeddings
116
- WHERE embedding MATCH ? AND k = ?`,[_,J]),V=new Set(M);return S.filter((A)=>V.has(A.observation_id)).slice(0,N).map((A)=>({observationId:A.observation_id,distance:A.distance}))}catch{return[]}}update(E,M){let N=this.getById(E);if(!N)return null;if(Object.keys(M).length===0)return N;let _=this.create({sessionId:N.sessionId,scope:N.scope??"project",type:M.type??N.type,title:M.title??N.title,subtitle:M.subtitle??N.subtitle,facts:M.facts??N.facts,narrative:M.narrative??N.narrative,concepts:M.concepts??N.concepts,filesRead:M.filesRead??N.filesRead,filesModified:M.filesModified??N.filesModified,rawToolOutput:N.rawToolOutput,toolName:"mem-revise",tokenCount:N.tokenCount,discoveryTokens:N.discoveryTokens,importance:M.importance??N.importance});return this.db.run("UPDATE observations SET revision_of = ? WHERE id = ?",[E,_.id]),this.supersede(E,_.id),this.getById(_.id)}supersede(E,M){let N=new Date().toISOString();this.db.run("UPDATE observations SET superseded_by = ?, superseded_at = ? WHERE id = ?",[M,N,E])}delete(E){if(this.db.all("SELECT id FROM observations WHERE id = ?",[E]).length===0)return!1;let N=new Date().toISOString();return this.db.run("UPDATE observations SET deleted_at = ? WHERE id = ?",[N,E]),this.deleteEmbeddingsForObservations([E]),!0}getLineage(E){let M=this.getByIdIncludingArchived(E);if(!M)return[];let N=new Set([M.id]),_=[M];while(_[0].revisionOf){let J=this.getByIdIncludingArchived(_[0].revisionOf);if(!J||N.has(J.id))break;_.unshift(J),N.add(J.id)}while(_[_.length-1].supersededBy){let J=_[_.length-1].supersededBy;if(!J)break;let S=this.getByIdIncludingArchived(J);if(!S||N.has(S.id))break;_.push(S),N.add(S.id)}return _}deleteOlderThan(E){return this.db.all(`DELETE FROM observations
116
+ WHERE embedding MATCH ? AND k = ?`,[_,J]),S=new Set(M);return V.filter((A)=>S.has(A.observation_id)).slice(0,N).map((A)=>({observationId:A.observation_id,distance:A.distance}))}catch{return[]}}update(E,M){let N=this.getById(E);if(!N)return null;if(Object.keys(M).length===0)return N;let _=this.create({sessionId:N.sessionId,scope:N.scope??"project",type:M.type??N.type,title:M.title??N.title,subtitle:M.subtitle??N.subtitle,facts:M.facts??N.facts,narrative:M.narrative??N.narrative,concepts:M.concepts??N.concepts,filesRead:M.filesRead??N.filesRead,filesModified:M.filesModified??N.filesModified,rawToolOutput:N.rawToolOutput,toolName:"mem-revise",tokenCount:N.tokenCount,discoveryTokens:N.discoveryTokens,importance:M.importance??N.importance});return this.db.run("UPDATE observations SET revision_of = ? WHERE id = ?",[E,_.id]),this.supersede(E,_.id),this.getById(_.id)}supersede(E,M){let N=new Date().toISOString();this.db.run("UPDATE observations SET superseded_by = ?, superseded_at = ? WHERE id = ?",[M,N,E])}delete(E){if(this.db.all("SELECT id FROM observations WHERE id = ?",[E]).length===0)return!1;let N=new Date().toISOString();return this.db.run("UPDATE observations SET deleted_at = ? WHERE id = ?",[N,E]),this.deleteEmbeddingsForObservations([E]),!0}getLineage(E){let M=this.getByIdIncludingArchived(E);if(!M)return[];let N=new Set([M.id]),_=[M];while(_[0].revisionOf){let J=this.getByIdIncludingArchived(_[0].revisionOf);if(!J||N.has(J.id))break;_.unshift(J),N.add(J.id)}while(_[_.length-1].supersededBy){let J=_[_.length-1].supersededBy;if(!J)break;let V=this.getByIdIncludingArchived(J);if(!V||N.has(V.id))break;_.push(V),N.add(V.id)}return _}deleteOlderThan(E){return this.db.all(`DELETE FROM observations
117
117
  WHERE (created_at < datetime('now', '-' || ? || ' days') OR deleted_at IS NOT NULL)
118
118
  AND session_id NOT IN (SELECT id FROM sessions WHERE status != 'completed')
119
- RETURNING id`,[E]).length}deleteEmbeddingsForObservations(E){if(E.length===0)return;let M=E.map(()=>"?").join(",");try{this.db.run(`DELETE FROM observation_embeddings WHERE observation_id IN (${M})`,E)}catch{}this.db.run(`UPDATE observations SET embedding = NULL WHERE id IN (${M})`,E)}mapRow(E){return{id:E.id,sessionId:E.session_id,scope:E.scope??"project",type:E.type,title:E.title,subtitle:E.subtitle,facts:JSON.parse(E.facts),narrative:E.narrative,concepts:JSON.parse(E.concepts),filesRead:JSON.parse(E.files_read),filesModified:JSON.parse(E.files_modified),rawToolOutput:E.raw_tool_output,toolName:E.tool_name,createdAt:E.created_at,tokenCount:E.token_count,discoveryTokens:E.discovery_tokens??0,importance:E.importance??3,revisionOf:E.revision_of??null,deletedAt:E.deleted_at??null,supersededBy:E.superseded_by??null,supersededAt:E.superseded_at??null}}}var xM=[{version:1,name:"create-schema",up:`
119
+ RETURNING id`,[E]).length}deleteEmbeddingsForObservations(E){if(E.length===0)return;let M=E.map(()=>"?").join(",");try{this.db.run(`DELETE FROM observation_embeddings WHERE observation_id IN (${M})`,E)}catch{}this.db.run(`UPDATE observations SET embedding = NULL WHERE id IN (${M})`,E)}mapRow(E){return{id:E.id,sessionId:E.session_id,scope:E.scope??"project",type:E.type,title:E.title,subtitle:E.subtitle,facts:JSON.parse(E.facts),narrative:E.narrative,concepts:JSON.parse(E.concepts),filesRead:JSON.parse(E.files_read),filesModified:JSON.parse(E.files_modified),rawToolOutput:E.raw_tool_output,toolName:E.tool_name,createdAt:E.created_at,tokenCount:E.token_count,discoveryTokens:E.discovery_tokens??0,importance:E.importance??3,revisionOf:E.revision_of??null,deletedAt:E.deleted_at??null,supersededBy:E.superseded_by??null,supersededAt:E.superseded_at??null}}}var cM=[{version:1,name:"create-schema",up:`
120
120
  -- Sessions table
121
121
  CREATE TABLE IF NOT EXISTS sessions (
122
122
  _rowid INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -410,11 +410,11 @@ ${C}`}return O}guide(){return["# open-mem Workflow Guide","","## Reading Memorie
410
410
  INSERT INTO entities_fts(rowid, name, entity_type)
411
411
  VALUES (new._rowid, new.name, new.entity_type);
412
412
  END;
413
- `}];function X0(E,M){if(E.migrate(xM),M?.hasVectorExtension&&M?.embeddingDimension&&M.embeddingDimension>0)qM(E,M.embeddingDimension)}function qM(E,M){if(E.get("SELECT name FROM sqlite_master WHERE type='table' AND name='observation_embeddings'")){let _=E.get("SELECT value FROM _embedding_meta WHERE key = 'dimension'");if(_&&Number(_.value)!==M){console.warn(`[open-mem] vec0 table exists with dimension ${_.value}, but config specifies ${M}. Drop observation_embeddings to re-create with new dimension.`);return}}else E.exec(`CREATE VIRTUAL TABLE observation_embeddings USING vec0(
413
+ `}];function Q0(E,M){if(E.migrate(cM),M?.hasVectorExtension&&M?.embeddingDimension&&M.embeddingDimension>0)bM(E,M.embeddingDimension)}function bM(E,M){if(E.get("SELECT name FROM sqlite_master WHERE type='table' AND name='observation_embeddings'")){let _=E.get("SELECT value FROM _embedding_meta WHERE key = 'dimension'");if(_&&Number(_.value)!==M){console.warn(`[open-mem] vec0 table exists with dimension ${_.value}, but config specifies ${M}. Drop observation_embeddings to re-create with new dimension.`);return}}else E.exec(`CREATE VIRTUAL TABLE observation_embeddings USING vec0(
414
414
  observation_id TEXT PRIMARY KEY,
415
415
  embedding float[${M}] distance_metric=cosine
416
- )`);E.run("INSERT OR REPLACE INTO _embedding_meta (key, value) VALUES (?, ?)",["dimension",String(M)])}class WE{db;constructor(E){this.db=E}create(E,M){let N=new Date().toISOString();return this.db.run(`INSERT INTO sessions (id, project_path, started_at, status)
417
- VALUES (?, ?, ?, 'active')`,[E,M,N]),this.getById(E)}getOrCreate(E,M){let N=this.getById(E);if(N)return N;return this.create(E,M)}getById(E){let M=this.db.get("SELECT * FROM sessions WHERE id = ?",[E]);return M?this.mapRow(M):null}getRecent(E,M=10){return this.db.all("SELECT * FROM sessions WHERE project_path = ? ORDER BY started_at DESC LIMIT ?",[E,M]).map((N)=>this.mapRow(N))}getAll(E){return this.db.all("SELECT * FROM sessions WHERE project_path = ? ORDER BY started_at DESC",[E]).map((M)=>this.mapRow(M))}getActive(){return this.db.all("SELECT * FROM sessions WHERE status = 'active' ORDER BY started_at DESC").map((E)=>this.mapRow(E))}updateStatus(E,M){this.db.run("UPDATE sessions SET status = ? WHERE id = ?",[M,E])}markCompleted(E){this.db.run("UPDATE sessions SET status = 'completed', ended_at = datetime('now') WHERE id = ?",[E])}incrementObservationCount(E){this.db.run("UPDATE sessions SET observation_count = observation_count + 1 WHERE id = ?",[E])}setSummary(E,M){this.db.run("UPDATE sessions SET summary_id = ? WHERE id = ?",[M,E])}mapRow(E){return{id:E.id,projectPath:E.project_path,startedAt:E.started_at,endedAt:E.ended_at??null,status:E.status,observationCount:E.observation_count,summaryId:E.summary_id??null}}}import{randomUUID as hM}from"crypto";class YE{db;constructor(E){this.db=E}create(E){let M=hM(),N=new Date().toISOString();return this.db.run(`INSERT INTO session_summaries
416
+ )`);E.run("INSERT OR REPLACE INTO _embedding_meta (key, value) VALUES (?, ?)",["dimension",String(M)])}class CE{db;constructor(E){this.db=E}create(E,M){let N=new Date().toISOString();return this.db.run(`INSERT INTO sessions (id, project_path, started_at, status)
417
+ VALUES (?, ?, ?, 'active')`,[E,M,N]),this.getById(E)}getOrCreate(E,M){let N=this.getById(E);if(N)return N;return this.create(E,M)}getById(E){let M=this.db.get("SELECT * FROM sessions WHERE id = ?",[E]);return M?this.mapRow(M):null}getRecent(E,M=10){return this.db.all("SELECT * FROM sessions WHERE project_path = ? ORDER BY started_at DESC LIMIT ?",[E,M]).map((N)=>this.mapRow(N))}getAll(E){return this.db.all("SELECT * FROM sessions WHERE project_path = ? ORDER BY started_at DESC",[E]).map((M)=>this.mapRow(M))}getActive(){return this.db.all("SELECT * FROM sessions WHERE status = 'active' ORDER BY started_at DESC").map((E)=>this.mapRow(E))}updateStatus(E,M){this.db.run("UPDATE sessions SET status = ? WHERE id = ?",[M,E])}markCompleted(E){this.db.run("UPDATE sessions SET status = 'completed', ended_at = datetime('now') WHERE id = ?",[E])}incrementObservationCount(E){this.db.run("UPDATE sessions SET observation_count = observation_count + 1 WHERE id = ?",[E])}setSummary(E,M){this.db.run("UPDATE sessions SET summary_id = ? WHERE id = ?",[M,E])}mapRow(E){return{id:E.id,projectPath:E.project_path,startedAt:E.started_at,endedAt:E.ended_at??null,status:E.status,observationCount:E.observation_count,summaryId:E.summary_id??null}}}import{randomUUID as nM}from"crypto";class GE{db;constructor(E){this.db=E}create(E){let M=nM(),N=new Date().toISOString();return this.db.run(`INSERT INTO session_summaries
418
418
  (id, session_id, summary, key_decisions, files_modified,
419
419
  concepts, created_at, token_count,
420
420
  request, investigated, learned, completed, next_steps)
@@ -427,7 +427,7 @@ ${C}`}return O}guide(){return["# open-mem Workflow Guide","","## Reading Memorie
427
427
  JOIN summaries_fts fts ON ss._rowid = fts.rowid
428
428
  WHERE summaries_fts MATCH ?
429
429
  ORDER BY rank
430
- LIMIT ?`,[E,M]).map((N)=>this.mapRow(N))}mapRow(E){return{id:E.id,sessionId:E.session_id,summary:E.summary,keyDecisions:JSON.parse(E.key_decisions),filesModified:JSON.parse(E.files_modified),concepts:JSON.parse(E.concepts),createdAt:E.created_at,tokenCount:E.token_count,request:E.request||void 0,investigated:E.investigated||void 0,learned:E.learned||void 0,completed:E.completed||void 0,nextSteps:E.next_steps||void 0}}}import{randomUUID as uM}from"crypto";var pM=[{version:1,name:"create-user-observations",up:`
430
+ LIMIT ?`,[E,M]).map((N)=>this.mapRow(N))}mapRow(E){return{id:E.id,sessionId:E.session_id,summary:E.summary,keyDecisions:JSON.parse(E.key_decisions),filesModified:JSON.parse(E.files_modified),concepts:JSON.parse(E.concepts),createdAt:E.created_at,tokenCount:E.token_count,request:E.request||void 0,investigated:E.investigated||void 0,learned:E.learned||void 0,completed:E.completed||void 0,nextSteps:E.next_steps||void 0}}}import{randomUUID as dM}from"crypto";var iM=[{version:1,name:"create-user-observations",up:`
431
431
  CREATE TABLE IF NOT EXISTS user_observations (
432
432
  _rowid INTEGER PRIMARY KEY AUTOINCREMENT,
433
433
  id TEXT UNIQUE NOT NULL,
@@ -498,7 +498,7 @@ ${C}`}return O}guide(){return["# open-mem Workflow Guide","","## Reading Memorie
498
498
  new.facts, new.concepts, new.files_read, new.files_modified
499
499
  );
500
500
  END;
501
- `}];class LE{db;constructor(E){let M=vM(E);this.db=i(M),this.initializeUserSchema()}initializeUserSchema(){this.db.migrate(pM)}get database(){return this.db}close(){this.db.close()}}class BE{db;constructor(E){this.db=E}create(E){let M=uM(),N=new Date().toISOString();return this.db.run(`INSERT INTO user_observations
501
+ `}];class DE{db;constructor(E){let M=rM(E);this.db=r(M),this.initializeUserSchema()}initializeUserSchema(){this.db.migrate(iM)}get database(){return this.db}close(){this.db.close()}}class FE{db;constructor(E){this.db=E}create(E){let M=dM(),N=new Date().toISOString();return this.db.run(`INSERT INTO user_observations
502
502
  (id, type, title, subtitle, facts, narrative,
503
503
  concepts, files_read, files_modified, tool_name,
504
504
  created_at, token_count, importance, source_project)
@@ -508,7 +508,7 @@ ${C}`}return O}guide(){return["# open-mem Workflow Guide","","## Reading Memorie
508
508
  JOIN user_observations_fts fts ON o._rowid = fts.rowid
509
509
  WHERE user_observations_fts MATCH ?
510
510
  `,N=[E.query];if(E.sourceProject)M+=" AND o.source_project = ?",N.push(E.sourceProject);return M+=" ORDER BY rank LIMIT ?",N.push(E.limit??10),this.db.all(M,N).map((_)=>({observation:this.mapRow(_),rank:_.rank}))}catch{return[]}}getIndex(E,M){let N=`SELECT id, type, title, token_count, created_at, importance, source_project
511
- FROM user_observations`,_=[];if(M)N+=" WHERE source_project = ?",_.push(M);return N+=" ORDER BY created_at DESC LIMIT ?",_.push(E??20),this.db.all(N,_).map((J)=>({id:J.id,sessionId:"",type:J.type,title:J.title,tokenCount:J.token_count,discoveryTokens:0,createdAt:J.created_at,importance:J.importance??3}))}getById(E){let M=this.db.get("SELECT * FROM user_observations WHERE id = ?",[E]);return M?this.mapRow(M):null}delete(E){return this.db.all("DELETE FROM user_observations WHERE id = ? RETURNING id",[E]).length>0}mapRow(E){return{id:E.id,type:E.type,title:E.title,subtitle:E.subtitle,facts:JSON.parse(E.facts),narrative:E.narrative,concepts:JSON.parse(E.concepts),filesRead:JSON.parse(E.files_read),filesModified:JSON.parse(E.files_modified),toolName:E.tool_name,createdAt:E.created_at,tokenCount:E.token_count,importance:E.importance??3,sourceProject:E.source_project}}}function vM(E){if(E.startsWith("~/")){let M=process.env.HOME||process.env.USERPROFILE||"";if(!M)throw Error("Cannot resolve user DB path: HOME environment variable is not set");let N=`${M}${E.slice(1)}`,_=N.substring(0,N.lastIndexOf("/"));return D("fs").mkdirSync(_,{recursive:!0}),N}return E}function I(E,M){if(M.type&&E.type!==M.type)return!1;if(M.importanceMin!==void 0&&E.importance<M.importanceMin)return!1;if(M.importanceMax!==void 0&&E.importance>M.importanceMax)return!1;if(M.createdAfter&&E.createdAt<M.createdAfter)return!1;if(M.createdBefore&&E.createdAt>M.createdBefore)return!1;if(M.concepts&&M.concepts.length>0){if(!M.concepts.some((_)=>E.concepts.some((J)=>J.toLowerCase().includes(_.toLowerCase()))))return!1}if(M.files&&M.files.length>0){let N=[...E.filesRead,...E.filesModified];if(!M.files.some((J)=>N.some((S)=>S.toLowerCase().includes(J.toLowerCase()))))return!1}return!0}async function Z0(E,M,N,_,J){if(!E.trim())return M;let S=gM(E),V=new Set;for(let O of S){let C=N.findByName(O);for(let Z of C){let Y=N.traverseRelations(Z.id,1);for(let H of Y){let z=N.getObservationsForEntity(H);for(let W of z)V.add(W)}}}if(V.size===0)return M;let A=new Set(M.map((O)=>O.observation.id)),$=[];for(let O of V){if(A.has(O))continue;let C=_.getById(O);if(!C)continue;if(C.supersededBy)continue;$.push({observation:C,rank:0,snippet:C.title,source:"project",rankingSource:"graph",explain:{strategy:"hybrid",matchedBy:["graph"]}})}return[...M,...$].slice(0,J)}function gM(E){let M=E.split(/\s+/).filter((_)=>_.length>=2),N=[];for(let _ of M)N.push(_);for(let _=0;_<M.length-1;_++)N.push(`${M[_]} ${M[_+1]}`);return N}var U0=60;async function K0(E,M,N,_){let J=_.limit??10,S=wM(M,E,_,J);if(!N)return S;let V=await a(N,E);if(!V)return S;let A=S.map((O)=>O.observation.id),$=cM(M,V,_.projectPath,_,J,_.hasVectorExtension??!1,A);if($.length===0)return S;return nM(S,$,J)}function wM(E,M,N,_){try{return E.search({query:M,type:N.type,limit:_,projectPath:N.projectPath,importanceMin:N.importanceMin,importanceMax:N.importanceMax,createdAfter:N.createdAfter,createdBefore:N.createdBefore,concepts:N.concepts,files:N.files})}catch{return[]}}function cM(E,M,N,_,J,S,V){if(S)return lM(E,M,_,J,V);return bM(E,M,N,_,J)}function lM(E,M,N,_,J){try{let S;if(J.length>0){if(S=E.searchVecSubset(M,J,_*3),S.length===0)S=E.getVecEmbeddingMatches(M,_*3)}else S=E.getVecEmbeddingMatches(M,_*3);if(S.length===0)return[];let V=[];for(let{observationId:A,distance:$}of S){if(V.length>=_)break;let O=E.getById(A);if(!O)continue;if(!I(O,N))continue;V.push({observation:O,rank:$-1,snippet:O.title,rankingSource:"vector",explain:{strategy:"hybrid",matchedBy:["vector"],vectorDistance:$}})}return V}catch{return[]}}function bM(E,M,N,_,J){let S=E.getWithEmbeddings(N,J*10);if(S.length===0)return[];let V=S.map(($)=>({id:$.id,similarity:f(M,$.embedding)})).filter(({similarity:$})=>$>=0.3).sort(($,O)=>O.similarity-$.similarity),A=[];for(let{id:$,similarity:O}of V){if(A.length>=J)break;let C=E.getById($);if(!C)continue;if(!I(C,_))continue;A.push({observation:C,rank:-O,snippet:C.title,rankingSource:"vector",explain:{strategy:"hybrid",matchedBy:["vector"],vectorSimilarity:O}})}return A}function nM(E,M,N){let _=new Map;for(let J=0;J<E.length;J++){let S=E[J],V=1/(U0+J+1);_.set(S.observation.id,{score:V,result:{...S,rankingSource:"fts",explain:{strategy:"hybrid",matchedBy:["fts"],ftsRank:S.rank}}})}for(let J=0;J<M.length;J++){let S=M[J],V=1/(U0+J+1),A=_.get(S.observation.id);if(A)A.score+=V,A.result={...A.result,explain:{strategy:"hybrid",matchedBy:["fts","vector"],ftsRank:A.result.explain?.ftsRank??A.result.rank,vectorDistance:S.explain?.vectorDistance,vectorSimilarity:S.explain?.vectorSimilarity}};else _.set(S.observation.id,{score:V,result:{...S,explain:{strategy:"hybrid",matchedBy:["vector"],vectorDistance:S.explain?.vectorDistance,vectorSimilarity:S.explain?.vectorSimilarity}}})}return[..._.values()].sort((J,S)=>S.score-J.score).slice(0,N).map(({score:J,result:S})=>({...S,explain:{...S.explain??{strategy:"hybrid",matchedBy:[]},strategy:"hybrid",matchedBy:S.explain?.matchedBy??[],rrfScore:J,ftsRank:S.explain?.ftsRank,vectorDistance:S.explain?.vectorDistance,vectorSimilarity:S.explain?.vectorSimilarity}}))}class GE{observations;embeddingModel;hasVectorExtension;reranker;userObservationRepo;entityRepo;constructor(E,M,N,_=null,J=null,S=null){this.observations=E;this.embeddingModel=M;this.hasVectorExtension=N;this.reranker=_;this.userObservationRepo=J;this.entityRepo=S}async search(E,M){let N=M.strategy??"hybrid",_=M.limit??10,J;switch(N){case"filter-only":J=this.filterOnlySearch(E,M,_);break;case"semantic":J=await this.semanticSearch(E,M,_);break;case"hybrid":J=await this.hybridSearchStrategy(E,M,_);break}for(let S of J)S.source="project";if(this.entityRepo&&E.trim())J=await Z0(E,J,this.entityRepo,this.observations,_);if(this.userObservationRepo){let S=this.searchUserMemory(E,M,_);J=this.mergeResults(J,S,_)}if(this.reranker&&J.length>1)return this.reranker.rerank(E,J,_);return J}filterOnlySearch(E,M,N){if(M.concept)return this.observations.searchByConcept(M.concept,N,M.projectPath).map((J)=>({observation:J,rank:0,snippet:J.title,rankingSource:"graph",explain:{strategy:"filter-only",matchedBy:["concept-filter"]}}));if(M.file)return this.observations.searchByFile(M.file,N,M.projectPath).map((J)=>({observation:J,rank:0,snippet:J.title,rankingSource:"graph",explain:{strategy:"filter-only",matchedBy:["file-filter"]}}));return this.observations.search({query:E,type:M.type,limit:N,projectPath:M.projectPath,importanceMin:M.importanceMin,importanceMax:M.importanceMax,createdAfter:M.createdAfter,createdBefore:M.createdBefore,concepts:M.concepts,files:M.files})}async semanticSearch(E,M,N){if(!this.embeddingModel)return this.filterOnlySearch(E,M,N);let _=await a(this.embeddingModel,E);if(!_)return this.filterOnlySearch(E,M,N);if(this.hasVectorExtension)return this.nativeVectorSearch(_,M,N);return this.jsFallbackVectorSearch(_,M,N)}async hybridSearchStrategy(E,M,N){return K0(E,this.observations,this.embeddingModel,{type:M.type,limit:N,projectPath:M.projectPath,hasVectorExtension:this.hasVectorExtension,importanceMin:M.importanceMin,importanceMax:M.importanceMax,createdAfter:M.createdAfter,createdBefore:M.createdBefore,concepts:M.concepts,files:M.files})}nativeVectorSearch(E,M,N){try{let _=this.observations.getVecEmbeddingMatches(E,N*3);if(_.length===0)return[];let J=[];for(let{observationId:S,distance:V}of _){if(J.length>=N)break;let A=this.observations.getById(S);if(!A)continue;if(!I(A,M))continue;J.push({observation:A,rank:V-1,snippet:A.title,rankingSource:"vector",explain:{strategy:"semantic",matchedBy:["vector"],vectorDistance:V}})}return J}catch{return[]}}jsFallbackVectorSearch(E,M,N){let _=this.observations.getWithEmbeddings(M.projectPath,N*10);if(_.length===0)return[];let J=_.map((V)=>({id:V.id,similarity:f(E,V.embedding)})).filter(({similarity:V})=>V>=0.3).sort((V,A)=>A.similarity-V.similarity),S=[];for(let{id:V,similarity:A}of J){if(S.length>=N)break;let $=this.observations.getById(V);if(!$)continue;if(!I($,M))continue;S.push({observation:$,rank:-A,snippet:$.title,rankingSource:"vector",explain:{strategy:"semantic",matchedBy:["vector"],vectorSimilarity:A}})}return S}searchUserMemory(E,M,N){if(!this.userObservationRepo)return[];try{return this.userObservationRepo.search({query:E,limit:N}).map(({observation:J,rank:S})=>({observation:dM(J),rank:S,snippet:J.title,source:"user",rankingSource:"user-memory",explain:{strategy:"filter-only",matchedBy:["user-memory"]}}))}catch{return[]}}mergeResults(E,M,N){let _=new Set(E.map((V)=>V.observation.id)),J=new Set(E.map((V)=>`${V.observation.title}::${V.observation.narrative}`)),S=M.filter((V)=>{if(_.has(V.observation.id))return!1;let A=`${V.observation.title}::${V.observation.narrative}`;if(J.has(A))return!1;return J.add(A),!0});return[...E,...S].slice(0,N)}}function dM(E){return{id:E.id,sessionId:"",type:E.type,title:E.title,subtitle:E.subtitle,facts:E.facts,narrative:E.narrative,concepts:E.concepts,filesRead:E.filesRead,filesModified:E.filesModified,rawToolOutput:"",toolName:E.toolName,createdAt:E.createdAt,tokenCount:E.tokenCount,discoveryTokens:0,importance:E.importance}}import{generateText as aM}from"ai";function H0(E,M){let N=M.map((_,J)=>` <candidate index="${J}"><title>${_.title}</title><narrative>${_.narrative}</narrative></candidate>`).join(`
511
+ FROM user_observations`,_=[];if(M)N+=" WHERE source_project = ?",_.push(M);return N+=" ORDER BY created_at DESC LIMIT ?",_.push(E??20),this.db.all(N,_).map((J)=>({id:J.id,sessionId:"",type:J.type,title:J.title,tokenCount:J.token_count,discoveryTokens:0,createdAt:J.created_at,importance:J.importance??3}))}getById(E){let M=this.db.get("SELECT * FROM user_observations WHERE id = ?",[E]);return M?this.mapRow(M):null}delete(E){return this.db.all("DELETE FROM user_observations WHERE id = ? RETURNING id",[E]).length>0}mapRow(E){return{id:E.id,type:E.type,title:E.title,subtitle:E.subtitle,facts:JSON.parse(E.facts),narrative:E.narrative,concepts:JSON.parse(E.concepts),filesRead:JSON.parse(E.files_read),filesModified:JSON.parse(E.files_modified),toolName:E.tool_name,createdAt:E.created_at,tokenCount:E.token_count,importance:E.importance??3,sourceProject:E.source_project}}}function rM(E){if(E.startsWith("~/")){let M=process.env.HOME||process.env.USERPROFILE||"";if(!M)throw Error("Cannot resolve user DB path: HOME environment variable is not set");let N=`${M}${E.slice(1)}`,_=N.substring(0,N.lastIndexOf("/"));return D("fs").mkdirSync(_,{recursive:!0}),N}return E}function x(E,M){if(M.type&&E.type!==M.type)return!1;if(M.importanceMin!==void 0&&E.importance<M.importanceMin)return!1;if(M.importanceMax!==void 0&&E.importance>M.importanceMax)return!1;if(M.createdAfter&&E.createdAt<M.createdAfter)return!1;if(M.createdBefore&&E.createdAt>M.createdBefore)return!1;if(M.concepts&&M.concepts.length>0){if(!M.concepts.some((_)=>E.concepts.some((J)=>J.toLowerCase().includes(_.toLowerCase()))))return!1}if(M.files&&M.files.length>0){let N=[...E.filesRead,...E.filesModified];if(!M.files.some((J)=>N.some((V)=>V.toLowerCase().includes(J.toLowerCase()))))return!1}return!0}async function W0(E,M,N,_,J){if(!E.trim())return M;let V=aM(E),S=new Set;for(let O of V){let X=N.findByName(O);for(let U of X){let L=N.traverseRelations(U.id,1);for(let z of L){let Q=N.getObservationsForEntity(z);for(let B of Q)S.add(B)}}}if(S.size===0)return M;let A=new Set(M.map((O)=>O.observation.id)),$=[];for(let O of S){if(A.has(O))continue;let X=_.getById(O);if(!X)continue;if(X.supersededBy)continue;$.push({observation:X,rank:0,snippet:X.title,source:"project",rankingSource:"graph",explain:{strategy:"hybrid",matchedBy:["graph"]}})}return[...M,...$].slice(0,J)}function aM(E){let M=E.split(/\s+/).filter((_)=>_.length>=2),N=[];for(let _ of M)N.push(_);for(let _=0;_<M.length-1;_++)N.push(`${M[_]} ${M[_+1]}`);return N}var Y0=60;async function B0(E,M,N,_){let J=_.limit??10,V=oM(M,E,_,J);if(!N)return V;let S=await a(N,E);if(!S)return V;let A=V.map((O)=>O.observation.id),$=tM(M,S,_.projectPath,_,J,_.hasVectorExtension??!1,A);if($.length===0)return V;return EN(V,$,J)}function oM(E,M,N,_){try{return E.search({query:M,type:N.type,limit:_,projectPath:N.projectPath,importanceMin:N.importanceMin,importanceMax:N.importanceMax,createdAfter:N.createdAfter,createdBefore:N.createdBefore,concepts:N.concepts,files:N.files})}catch{return[]}}function tM(E,M,N,_,J,V,S){if(V)return eM(E,M,_,J,S);return sM(E,M,N,_,J)}function eM(E,M,N,_,J){try{let V;if(J.length>0){if(V=E.searchVecSubset(M,J,_*3),V.length===0)V=E.getVecEmbeddingMatches(M,_*3)}else V=E.getVecEmbeddingMatches(M,_*3);if(V.length===0)return[];let S=[];for(let{observationId:A,distance:$}of V){if(S.length>=_)break;let O=E.getById(A);if(!O)continue;if(!x(O,N))continue;S.push({observation:O,rank:$-1,snippet:O.title,rankingSource:"vector",explain:{strategy:"hybrid",matchedBy:["vector"],vectorDistance:$}})}return S}catch{return[]}}function sM(E,M,N,_,J){let V=E.getWithEmbeddings(N,J*10);if(V.length===0)return[];let S=V.map(($)=>({id:$.id,similarity:q(M,$.embedding)})).filter(({similarity:$})=>$>=0.3).sort(($,O)=>O.similarity-$.similarity),A=[];for(let{id:$,similarity:O}of S){if(A.length>=J)break;let X=E.getById($);if(!X)continue;if(!x(X,_))continue;A.push({observation:X,rank:-O,snippet:X.title,rankingSource:"vector",explain:{strategy:"hybrid",matchedBy:["vector"],vectorSimilarity:O}})}return A}function EN(E,M,N){let _=new Map;for(let J=0;J<E.length;J++){let V=E[J],S=1/(Y0+J+1);_.set(V.observation.id,{score:S,result:{...V,rankingSource:"fts",explain:{strategy:"hybrid",matchedBy:["fts"],ftsRank:V.rank}}})}for(let J=0;J<M.length;J++){let V=M[J],S=1/(Y0+J+1),A=_.get(V.observation.id);if(A)A.score+=S,A.result={...A.result,explain:{strategy:"hybrid",matchedBy:["fts","vector"],ftsRank:A.result.explain?.ftsRank??A.result.rank,vectorDistance:V.explain?.vectorDistance,vectorSimilarity:V.explain?.vectorSimilarity}};else _.set(V.observation.id,{score:S,result:{...V,explain:{strategy:"hybrid",matchedBy:["vector"],vectorDistance:V.explain?.vectorDistance,vectorSimilarity:V.explain?.vectorSimilarity}}})}return[..._.values()].sort((J,V)=>V.score-J.score).slice(0,N).map(({score:J,result:V})=>({...V,explain:{...V.explain??{strategy:"hybrid",matchedBy:[]},strategy:"hybrid",matchedBy:V.explain?.matchedBy??[],rrfScore:J,ftsRank:V.explain?.ftsRank,vectorDistance:V.explain?.vectorDistance,vectorSimilarity:V.explain?.vectorSimilarity}}))}class kE{observations;embeddingModel;hasVectorExtension;reranker;userObservationRepo;entityRepo;constructor(E,M,N,_=null,J=null,V=null){this.observations=E;this.embeddingModel=M;this.hasVectorExtension=N;this.reranker=_;this.userObservationRepo=J;this.entityRepo=V}async search(E,M){let N=M.strategy??"hybrid",_=M.limit??10,J;switch(N){case"filter-only":J=this.filterOnlySearch(E,M,_);break;case"semantic":J=await this.semanticSearch(E,M,_);break;case"hybrid":J=await this.hybridSearchStrategy(E,M,_);break}for(let V of J)V.source="project";if(this.entityRepo&&E.trim())J=await W0(E,J,this.entityRepo,this.observations,_);if(this.userObservationRepo){let V=this.searchUserMemory(E,M,_);J=this.mergeResults(J,V,_)}if(this.reranker&&J.length>1)return this.reranker.rerank(E,J,_);return J}filterOnlySearch(E,M,N){if(M.concept)return this.observations.searchByConcept(M.concept,N,M.projectPath).map((J)=>({observation:J,rank:0,snippet:J.title,rankingSource:"graph",explain:{strategy:"filter-only",matchedBy:["concept-filter"]}}));if(M.file)return this.observations.searchByFile(M.file,N,M.projectPath).map((J)=>({observation:J,rank:0,snippet:J.title,rankingSource:"graph",explain:{strategy:"filter-only",matchedBy:["file-filter"]}}));return this.observations.search({query:E,type:M.type,limit:N,projectPath:M.projectPath,importanceMin:M.importanceMin,importanceMax:M.importanceMax,createdAfter:M.createdAfter,createdBefore:M.createdBefore,concepts:M.concepts,files:M.files})}async semanticSearch(E,M,N){if(!this.embeddingModel)return this.filterOnlySearch(E,M,N);let _=await a(this.embeddingModel,E);if(!_)return this.filterOnlySearch(E,M,N);if(this.hasVectorExtension)return this.nativeVectorSearch(_,M,N);return this.jsFallbackVectorSearch(_,M,N)}async hybridSearchStrategy(E,M,N){return B0(E,this.observations,this.embeddingModel,{type:M.type,limit:N,projectPath:M.projectPath,hasVectorExtension:this.hasVectorExtension,importanceMin:M.importanceMin,importanceMax:M.importanceMax,createdAfter:M.createdAfter,createdBefore:M.createdBefore,concepts:M.concepts,files:M.files})}nativeVectorSearch(E,M,N){try{let _=this.observations.getVecEmbeddingMatches(E,N*3);if(_.length===0)return[];let J=[];for(let{observationId:V,distance:S}of _){if(J.length>=N)break;let A=this.observations.getById(V);if(!A)continue;if(!x(A,M))continue;J.push({observation:A,rank:S-1,snippet:A.title,rankingSource:"vector",explain:{strategy:"semantic",matchedBy:["vector"],vectorDistance:S}})}return J}catch{return[]}}jsFallbackVectorSearch(E,M,N){let _=this.observations.getWithEmbeddings(M.projectPath,N*10);if(_.length===0)return[];let J=_.map((S)=>({id:S.id,similarity:q(E,S.embedding)})).filter(({similarity:S})=>S>=0.3).sort((S,A)=>A.similarity-S.similarity),V=[];for(let{id:S,similarity:A}of J){if(V.length>=N)break;let $=this.observations.getById(S);if(!$)continue;if(!x($,M))continue;V.push({observation:$,rank:-A,snippet:$.title,rankingSource:"vector",explain:{strategy:"semantic",matchedBy:["vector"],vectorSimilarity:A}})}return V}searchUserMemory(E,M,N){if(!this.userObservationRepo)return[];try{return this.userObservationRepo.search({query:E,limit:N}).map(({observation:J,rank:V})=>({observation:MN(J),rank:V,snippet:J.title,source:"user",rankingSource:"user-memory",explain:{strategy:"filter-only",matchedBy:["user-memory"]}}))}catch{return[]}}mergeResults(E,M,N){let _=new Set(E.map((S)=>S.observation.id)),J=new Set(E.map((S)=>`${S.observation.title}::${S.observation.narrative}`)),V=M.filter((S)=>{if(_.has(S.observation.id))return!1;let A=`${S.observation.title}::${S.observation.narrative}`;if(J.has(A))return!1;return J.add(A),!0});return[...E,...V].slice(0,N)}}function MN(E){return{id:E.id,sessionId:"",type:E.type,title:E.title,subtitle:E.subtitle,facts:E.facts,narrative:E.narrative,concepts:E.concepts,filesRead:E.filesRead,filesModified:E.filesModified,rawToolOutput:"",toolName:E.toolName,createdAt:E.createdAt,tokenCount:E.tokenCount,discoveryTokens:0,importance:E.importance}}import{generateText as _N}from"ai";function L0(E,M){let N=M.map((_,J)=>` <candidate index="${J}"><title>${_.title}</title><narrative>${_.narrative}</narrative></candidate>`).join(`
512
512
  `);return`<rerank_request>
513
513
  <query>${E}</query>
514
514
  <candidates>
@@ -523,4 +523,4 @@ Respond with EXACTLY this XML format:
523
523
  <index>0</index>
524
524
  </reranked>
525
525
  </instructions>
526
- </rerank_request>`}var iM={"gemini-2.5-flash-lite":10,"gemini-2.5-flash":10,"gemini-2.5-pro":5,"gemini-2.0-flash":15,"gemini-2.0-flash-lite":30,"gemini-3-flash":5},z0=0;async function Q0(E,M){if(!M)return;let N=iM[E]||5,_=Math.ceil(60000/N)+100,S=Date.now()-z0;if(S<_){let V=_-S;await new Promise((A)=>setTimeout(A,V))}z0=Date.now()}class R0{languageModel;maxCandidates;provider;modelName;rateLimitingEnabled;_generate=aM;constructor(E,M){this.languageModel=E,this.maxCandidates=M.rerankingMaxCandidates,this.provider=M.provider??"",this.modelName=M.model??"",this.rateLimitingEnabled=M.rateLimitingEnabled??!0}async rerank(E,M,N){if(M.length<=1)return M;let _=M.slice(0,this.maxCandidates),J=M.slice(this.maxCandidates),S=H0(E,_.map((A)=>({title:A.observation.title,narrative:A.observation.narrative}))),V=2;for(let A=0;A<=V;A++)try{if(this.provider==="google")await Q0(this.modelName,this.rateLimitingEnabled);let{text:$}=await this._generate({model:this.languageModel,maxOutputTokens:512,prompt:S}),O=IE($);if(!O)return M.slice(0,N);let C=this.applyReranking(_,O,N);for(let Z of J){if(C.length>=N)break;C.push(Z)}return C}catch($){if(rM($)&&A<V){await oM(2**A*1000);continue}return M.slice(0,N)}return M.slice(0,N)}applyReranking(E,M,N){let _=[],J=new Set;for(let S of M)if(S>=0&&S<E.length&&!J.has(S)){if(J.add(S),_.push(E[S]),_.length>=N)break}if(_.length<N){for(let S=0;S<E.length&&_.length<N;S++)if(!J.has(S))_.push(E[S])}return _}}class W0{async rerank(E,M,N){if(M.length<=1)return M.slice(0,N);let _=DE(E),J=M.map((S)=>({result:S,score:this.scoreCandidate(S,_)}));return J.sort((S,V)=>V.score-S.score),J.slice(0,N).map((S)=>S.result)}scoreCandidate(E,M){let N=E.observation,_=DE(N.title),J=DE(N.narrative),S=new Set(N.concepts.map((G)=>G.toLowerCase())),V=0,A=0,$=0;for(let G of M){if(_.has(G))V++;if(J.has(G))A++;if(S.has(G))$++}let O=M.size||1,C=V/O*0.4,Z=A/O*0.3,Y=$/O*0.15,z=(Date.now()-new Date(N.createdAt).getTime())/86400000,W=z<1?0.1:z<7?0.05:0,j=N.importance/5*0.05;return C+Z+Y+W+j}}function Y0(E,M){if(!E.rerankingEnabled)return null;if(M)return new R0(M,E);return new W0}function DE(E){return new Set(E.toLowerCase().split(/[\s\-_./\\,;:!?()[\]{}'"]+/).filter((M)=>M.length>1))}function rM(E){if(typeof E!=="object"||E===null)return!1;let M=E,N=M.status;if(N===429||N===500||N===503)return!0;let _=M.error;if(typeof _==="object"&&_!==null&&_.type==="overloaded_error")return!0;return!1}function oM(E){return new Promise((M)=>setTimeout(M,E))}function L0(E){return E}function B0(E){return E}function G0(E){return E}function D0(E){if(!E)return null;return E}import{spawnSync as F0}from"child_process";import{dirname as tM,resolve as k0}from"path";function eM(E){try{let M=F0("git",["rev-parse","--git-common-dir"],{cwd:E,encoding:"utf-8",timeout:5000});if(M.status!==0||!M.stdout)return null;let N=M.stdout.trim();if(N===".git")return null;let _=F0("git",["rev-parse","--git-dir"],{cwd:E,encoding:"utf-8",timeout:5000});if(_.status!==0||!_.stdout)return null;let J=_.stdout.trim(),S=k0(E,N),V=k0(E,J);if(S===V)return null;let A=tM(S);if(A===S||A==="/")return null;return A}catch{return null}}function j0(E){return eM(E)??E}var __dirname="/Users/clopca/dev/github/open-mem/src",{values:T0}=MN({options:{project:{type:"string",short:"p"}},strict:!1}),NN=typeof T0.project==="string"?T0.project:process.cwd(),y0=j0(NN),U=h(y0);d.enableExtensionSupport();var L=i(U.dbPath);X0(L,{hasVectorExtension:L.hasVectorExtension,embeddingDimension:U.embeddingDimension});var _N=new WE(L),m0=new RE(L),JN=new YE(L),SN=new KE(L),VN=new QE(L),x=null,FE=null;if(U.userMemoryEnabled)try{x=new LE(U.userMemoryDbPath),FE=new BE(x.database)}catch(E){console.error(`[open-mem-mcp] Failed to initialize user-level memory: ${E}`)}var P0=U.provider!=="bedrock",AN=U.compressionEnabled&&(!P0||U.apiKey)?yE({provider:U.provider,model:U.model,apiKey:U.apiKey}):null,$N=Y0(U,U.rerankingEnabled&&(!P0||U.apiKey)?PE({provider:U.provider,model:U.model,apiKey:U.apiKey},mE(U)):null),ON=new zE(L),CN=new GE(m0,AN,L.hasVectorExtension,$N,FE,ON),XN=JSON.parse(sM(EN(__dirname,"..","package.json"),"utf-8")),ZN=new o({memoryEngine:new UE({observations:L0(m0),sessions:B0(_N),summaries:G0(JN),searchOrchestrator:CN,projectPath:y0,config:U,userObservationRepo:D0(FE),configAuditStore:SN,maintenanceHistoryStore:VN}),version:XN.version,compatibilityMode:U.mcpCompatibilityMode,protocolVersion:U.mcpProtocolVersion,supportedProtocolVersions:U.mcpSupportedProtocolVersions}),r=!1,f0=()=>{if(!r){if(r=!0,x)x.close();L.close()}process.exit(0)};process.on("SIGINT",f0);process.on("SIGTERM",f0);process.on("beforeExit",()=>{if(!r){if(r=!0,x)x.close();L.close()}});ZN.start();
526
+ </rerank_request>`}var NN={"gemini-2.5-flash-lite":10,"gemini-2.5-flash":10,"gemini-2.5-pro":5,"gemini-2.0-flash":15,"gemini-2.0-flash-lite":30,"gemini-3-flash":5},R0=0;async function C0(E,M){if(!M)return;let N=NN[E]||5,_=Math.ceil(60000/N)+100,V=Date.now()-R0;if(V<_){let S=_-V;await new Promise((A)=>setTimeout(A,S))}R0=Date.now()}class G0{languageModel;maxCandidates;provider;modelName;rateLimitingEnabled;_generate=_N;constructor(E,M){this.languageModel=E,this.maxCandidates=M.rerankingMaxCandidates,this.provider=M.provider??"",this.modelName=M.model??"",this.rateLimitingEnabled=M.rateLimitingEnabled??!0}async rerank(E,M,N){if(M.length<=1)return M;let _=M.slice(0,this.maxCandidates),J=M.slice(this.maxCandidates),V=L0(E,_.map((A)=>({title:A.observation.title,narrative:A.observation.narrative}))),S=2;for(let A=0;A<=S;A++)try{if(this.provider==="google")await C0(this.modelName,this.rateLimitingEnabled);let{text:$}=await this._generate({model:this.languageModel,maxOutputTokens:512,prompt:V}),O=vE($);if(!O)return M.slice(0,N);let X=this.applyReranking(_,O,N);for(let U of J){if(X.length>=N)break;X.push(U)}return X}catch($){if(JN($)&&A<S){await VN(2**A*1000);continue}return M.slice(0,N)}return M.slice(0,N)}applyReranking(E,M,N){let _=[],J=new Set;for(let V of M)if(V>=0&&V<E.length&&!J.has(V)){if(J.add(V),_.push(E[V]),_.length>=N)break}if(_.length<N){for(let V=0;V<E.length&&_.length<N;V++)if(!J.has(V))_.push(E[V])}return _}}class D0{async rerank(E,M,N){if(M.length<=1)return M.slice(0,N);let _=jE(E),J=M.map((V)=>({result:V,score:this.scoreCandidate(V,_)}));return J.sort((V,S)=>S.score-V.score),J.slice(0,N).map((V)=>V.result)}scoreCandidate(E,M){let N=E.observation,_=jE(N.title),J=jE(N.narrative),V=new Set(N.concepts.map((G)=>G.toLowerCase())),S=0,A=0,$=0;for(let G of M){if(_.has(G))S++;if(J.has(G))A++;if(V.has(G))$++}let O=M.size||1,X=S/O*0.4,U=A/O*0.3,L=$/O*0.15,Q=(Date.now()-new Date(N.createdAt).getTime())/86400000,B=Q<1?0.1:Q<7?0.05:0,j=N.importance/5*0.05;return X+U+L+B+j}}function F0(E,M){if(!E.rerankingEnabled)return null;if(M)return new G0(M,E);return new D0}function jE(E){return new Set(E.toLowerCase().split(/[\s\-_./\\,;:!?()[\]{}'"]+/).filter((M)=>M.length>1))}function JN(E){if(typeof E!=="object"||E===null)return!1;let M=E,N=M.status;if(N===429||N===500||N===503)return!0;let _=M.error;if(typeof _==="object"&&_!==null&&_.type==="overloaded_error")return!0;return!1}function VN(E){return new Promise((M)=>setTimeout(M,E))}function k0(E){return E}function j0(E){return E}function T0(E){return E}function y0(E){if(!E)return null;return E}import{spawnSync as P0}from"child_process";import{dirname as SN,resolve as m0}from"path";function AN(E){try{let M=P0("git",["rev-parse","--git-common-dir"],{cwd:E,encoding:"utf-8",timeout:5000});if(M.status!==0||!M.stdout)return null;let N=M.stdout.trim();if(N===".git")return null;let _=P0("git",["rev-parse","--git-dir"],{cwd:E,encoding:"utf-8",timeout:5000});if(_.status!==0||!_.stdout)return null;let J=_.stdout.trim(),V=m0(E,N),S=m0(E,J);if(V===S)return null;let A=SN(V);if(A===V||A==="/")return null;return A}catch{return null}}function I0(E){return AN(E)??E}var __dirname="/Users/clopca/dev/github/open-mem/src",{values:q0}=XN({options:{project:{type:"string",short:"p"}},strict:!1}),ZN=typeof q0.project==="string"?q0.project:process.cwd(),x0=I0(ZN),K=f(x0);i.enableExtensionSupport();var R=r(K.dbPath);Q0(R,{hasVectorExtension:R.hasVectorExtension,embeddingDimension:K.embeddingDimension});var UN=new CE(R),h0=new RE(R),KN=new GE(R),HN=new WE(R),zN=new LE(R),h=null,TE=null;if(K.userMemoryEnabled)try{h=new DE(K.userMemoryDbPath),TE=new FE(h.database)}catch(E){console.error(`[open-mem-mcp] Failed to initialize user-level memory: ${E}`)}var u0=K.provider!=="bedrock",QN=K.compressionEnabled&&(!u0||K.apiKey)?mE({provider:K.provider,model:K.model,apiKey:K.apiKey}):null,WN=F0(K,K.rerankingEnabled&&(!u0||K.apiKey)?qE({provider:K.provider,model:K.model,apiKey:K.apiKey},IE(K)):null),YN=new BE(R),BN=new kE(h0,QN,R.hasVectorExtension,WN,TE,YN),LN=JSON.parse($N(ON(__dirname,"..","package.json"),"utf-8")),RN=new e({memoryEngine:new QE({observations:k0(h0),sessions:j0(UN),summaries:T0(KN),searchOrchestrator:BN,projectPath:x0,config:K,userObservationRepo:y0(TE),configAuditStore:HN,maintenanceHistoryStore:zN}),version:LN.version,compatibilityMode:K.mcpCompatibilityMode,protocolVersion:K.mcpProtocolVersion,supportedProtocolVersions:K.mcpSupportedProtocolVersions}),o=!1,f0=()=>{if(!o){if(o=!0,h)h.close();R.close()}process.exit(0)};process.on("SIGINT",f0);process.on("SIGTERM",f0);process.on("beforeExit",()=>{if(!o){if(o=!0,h)h.close();R.close()}});RN.start();