open-mem 0.14.0 → 0.14.2

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,122 +1,123 @@
1
1
  #!/usr/bin/env bun
2
2
  // @bun
3
- var dp=Object.defineProperty;var sp=(n,p)=>{for(var y in p)dp(n,y,{get:p[y],enumerable:!0,configurable:!0,set:(e)=>p[y]=()=>e})};var j=(n,p)=>()=>(n&&(p=n(n=0)),p);var $=import.meta.require;import{existsSync as My,readdirSync as Ey,readFileSync as cy}from"fs";import{join as fy}from"path";function X(n){return{...n,observationTypes:[...n.observationTypes],conceptVocabulary:[...n.conceptVocabulary],entityTypes:[...n.entityTypes],relationshipTypes:[...n.relationshipTypes],promptOverrides:n.promptOverrides?{...n.promptOverrides}:void 0}}function Ry(n){if(!n||typeof n!=="object")return!1;let p=n,y=(S)=>Array.isArray(S)&&S.every((u)=>typeof u==="string"),e=(S)=>typeof S==="object"&&S!==null&&!Array.isArray(S)&&Object.values(S).every((u)=>typeof u==="string");return typeof p.id==="string"&&(p.extends===void 0||typeof p.extends==="string")&&(p.locale===void 0||typeof p.locale==="string")&&(p.name===void 0||typeof p.name==="string")&&(p.description===void 0||typeof p.description==="string")&&(p.observationTypes===void 0||y(p.observationTypes))&&(p.conceptVocabulary===void 0||y(p.conceptVocabulary))&&(p.entityTypes===void 0||y(p.entityTypes))&&(p.relationshipTypes===void 0||y(p.relationshipTypes))&&(p.promptOverrides===void 0||e(p.promptOverrides))}function Ny(n){return typeof n.name==="string"&&typeof n.description==="string"&&Array.isArray(n.observationTypes)&&Array.isArray(n.conceptVocabulary)&&Array.isArray(n.entityTypes)&&Array.isArray(n.relationshipTypes)}function Gn(n,p){return{...n,...p,id:p.id,name:p.name??n.name,description:p.description??n.description,observationTypes:p.observationTypes??n.observationTypes,conceptVocabulary:p.conceptVocabulary??n.conceptVocabulary,entityTypes:p.entityTypes??n.entityTypes,relationshipTypes:p.relationshipTypes??n.relationshipTypes,promptOverrides:{...n.promptOverrides??{},...p.promptOverrides??{}}}}class mn{modesDir;constructor(n){this.modesDir=n}loadAllRaw(){let n=new Map;if(!My(this.modesDir))return n;for(let p of Ey(this.modesDir)){if(!p.endsWith(".json"))continue;let y=fy(this.modesDir,p);try{let e=cy(y,"utf-8"),S=JSON.parse(e);if(!Ry(S))continue;if(n.has(S.id))console.warn(`[open-mem] Duplicate mode id "${S.id}" in ${y}; overriding previous definition.`);n.set(S.id,S)}catch{}}return n}resolveById(n,p){let y=new Set,e=!1,S=(m)=>{if(y.has(m))return e=!0,X(z);y.add(m);let r=p.get(m);if(!r)return X(z);if(!r.extends){if(!Ny(r))return X(z);return Gn(X(z),r)}let O=S(r.extends);if(e)return X(z);return Gn(O,r)},u=S(n);return e?X(z):X(u)}}var z;var vn=j(()=>{z={id:"code",name:"Code",description:"Default coding workflow mode",observationTypes:["decision","bugfix","feature","refactor","discovery","change"],conceptVocabulary:["how-it-works","why-it-exists","what-changed","problem-solution","gotcha","pattern","trade-off"],entityTypes:["technology","library","pattern","concept","file","person","project","other"],relationshipTypes:["uses","depends_on","implements","extends","related_to","replaces","configures"]}});import{join as gy}from"path";function _y(){if(P)return P;return P=ty.loadAllRaw(),P}function xn(){return[..._y().keys()].sort()}var hy,ty,P=null;var jn=j(()=>{vn();hy=gy(import.meta.dir,"."),ty=new mn(hy)});import{existsSync as Vy,readFileSync as Ay}from"fs";function Jy(){let n={};if(process.env.OPEN_MEM_DB_PATH)n.dbPath=process.env.OPEN_MEM_DB_PATH;if(process.env.OPEN_MEM_PROVIDER)n.provider=process.env.OPEN_MEM_PROVIDER;if(process.env.OPEN_MEM_MODEL)n.model=process.env.OPEN_MEM_MODEL;if(process.env.OPEN_MEM_MAX_CONTEXT_TOKENS)n.maxContextTokens=Number.parseInt(process.env.OPEN_MEM_MAX_CONTEXT_TOKENS,10);if(process.env.OPEN_MEM_COMPRESSION==="false")n.compressionEnabled=!1;if(process.env.OPEN_MEM_CONTEXT_INJECTION==="false")n.contextInjectionEnabled=!1;if(process.env.OPEN_MEM_IGNORED_TOOLS)n.ignoredTools=process.env.OPEN_MEM_IGNORED_TOOLS.split(",").map((p)=>p.trim());if(process.env.OPEN_MEM_BATCH_SIZE)n.batchSize=Number.parseInt(process.env.OPEN_MEM_BATCH_SIZE,10);if(process.env.OPEN_MEM_RETENTION_DAYS)n.retentionDays=Number.parseInt(process.env.OPEN_MEM_RETENTION_DAYS,10);if(process.env.OPEN_MEM_LOG_LEVEL)n.logLevel=process.env.OPEN_MEM_LOG_LEVEL;if(process.env.OPEN_MEM_CONTEXT_SHOW_TOKEN_COSTS==="false")n.contextShowTokenCosts=!1;if(process.env.OPEN_MEM_CONTEXT_TYPES)n.contextObservationTypes=process.env.OPEN_MEM_CONTEXT_TYPES==="all"?"all":process.env.OPEN_MEM_CONTEXT_TYPES.split(",").map((p)=>p.trim());if(process.env.OPEN_MEM_CONTEXT_FULL_COUNT)n.contextFullObservationCount=Number.parseInt(process.env.OPEN_MEM_CONTEXT_FULL_COUNT,10);if(process.env.OPEN_MEM_MAX_OBSERVATIONS)n.maxObservations=Number.parseInt(process.env.OPEN_MEM_MAX_OBSERVATIONS,10);if(process.env.OPEN_MEM_CONTEXT_SHOW_LAST_SUMMARY==="false")n.contextShowLastSummary=!1;if(process.env.OPEN_MEM_RATE_LIMITING==="false")n.rateLimitingEnabled=!1;if(process.env.OPEN_MEM_FOLDER_CONTEXT==="false")n.folderContextEnabled=!1;if(process.env.OPEN_MEM_FOLDER_CONTEXT_MAX_DEPTH)n.folderContextMaxDepth=Number.parseInt(process.env.OPEN_MEM_FOLDER_CONTEXT_MAX_DEPTH,10);if(process.env.OPEN_MEM_FOLDER_CONTEXT_MODE==="single")n.folderContextMode="single";if(process.env.OPEN_MEM_FOLDER_CONTEXT_MODE==="dispersed")n.folderContextMode="dispersed";if(process.env.OPEN_MEM_FOLDER_CONTEXT_FILENAME)n.folderContextFilename=process.env.OPEN_MEM_FOLDER_CONTEXT_FILENAME;if(process.env.OPEN_MEM_DAEMON==="true")n.daemonEnabled=!0;if(process.env.OPEN_MEM_DASHBOARD==="true")n.dashboardEnabled=!0;if(process.env.OPEN_MEM_DASHBOARD_PORT)n.dashboardPort=Number.parseInt(process.env.OPEN_MEM_DASHBOARD_PORT,10);if(process.env.OPEN_MEM_PLATFORM_OPENCODE==="false")n.platformOpenCodeEnabled=!1;if(process.env.OPEN_MEM_PLATFORM_CLAUDE_CODE==="true")n.platformClaudeCodeEnabled=!0;if(process.env.OPEN_MEM_PLATFORM_CURSOR==="true")n.platformCursorEnabled=!0;if(process.env.OPEN_MEM_MCP_PROTOCOL_VERSION)n.mcpProtocolVersion=process.env.OPEN_MEM_MCP_PROTOCOL_VERSION;if(process.env.OPEN_MEM_MCP_SUPPORTED_PROTOCOLS)n.mcpSupportedProtocolVersions=process.env.OPEN_MEM_MCP_SUPPORTED_PROTOCOLS.split(",").map((p)=>p.trim()).filter(Boolean);if(process.env.OPEN_MEM_EMBEDDING_DIMENSION)n.embeddingDimension=Number.parseInt(process.env.OPEN_MEM_EMBEDDING_DIMENSION,10);if(process.env.OPEN_MEM_CONFLICT_RESOLUTION==="true")n.conflictResolutionEnabled=!0;if(process.env.OPEN_MEM_CONFLICT_BAND_LOW){let p=Number.parseFloat(process.env.OPEN_MEM_CONFLICT_BAND_LOW);if(!Number.isNaN(p))n.conflictSimilarityBandLow=p}if(process.env.OPEN_MEM_CONFLICT_BAND_HIGH){let p=Number.parseFloat(process.env.OPEN_MEM_CONFLICT_BAND_HIGH);if(!Number.isNaN(p))n.conflictSimilarityBandHigh=p}if(process.env.OPEN_MEM_USER_MEMORY==="true")n.userMemoryEnabled=!0;if(process.env.OPEN_MEM_USER_MEMORY_DB_PATH)n.userMemoryDbPath=process.env.OPEN_MEM_USER_MEMORY_DB_PATH;if(process.env.OPEN_MEM_USER_MEMORY_MAX_TOKENS)n.userMemoryMaxContextTokens=Number.parseInt(process.env.OPEN_MEM_USER_MEMORY_MAX_TOKENS,10);if(process.env.OPEN_MEM_RERANKING==="true")n.rerankingEnabled=!0;if(process.env.OPEN_MEM_RERANKING_MAX_CANDIDATES)n.rerankingMaxCandidates=Number.parseInt(process.env.OPEN_MEM_RERANKING_MAX_CANDIDATES,10);if(process.env.OPEN_MEM_ENTITY_EXTRACTION==="true")n.entityExtractionEnabled=!0;if(process.env.OPEN_MEM_FALLBACK_PROVIDERS)n.fallbackProviders=process.env.OPEN_MEM_FALLBACK_PROVIDERS.split(",").map((p)=>p.trim()).filter(Boolean);if(process.env.OPEN_MEM_MODE)n.mode=process.env.OPEN_MEM_MODE;return n}function Cy(n){let p=`${n}/.open-mem/config.json`;if(!Vy(p))return{};try{let y=Ay(p,"utf-8"),e=JSON.parse(y);if(!e||typeof e!=="object"||Array.isArray(e))return{};return e}catch{return{}}}function $y(n){switch(n){case"google":return 768;case"openai":return 1536;case"bedrock":return 1024;case"anthropic":return 0;case"openrouter":return 0;default:return 768}}function T(n,p){let y=Cy(n),e=Jy(),S={...Pn,...y,...e,...p};if(!S.dbPath.startsWith("/"))S.dbPath=`${n}/${S.dbPath}`;if(!process.env.OPEN_MEM_PROVIDER&&!p?.provider){if(process.env.GOOGLE_GENERATIVE_AI_API_KEY||process.env.GEMINI_API_KEY)S.provider="google";else if(process.env.ANTHROPIC_API_KEY)S.provider="anthropic";else if(process.env.AWS_BEARER_TOKEN_BEDROCK||process.env.AWS_ACCESS_KEY_ID||process.env.AWS_PROFILE)S.provider="bedrock";else if(process.env.OPENROUTER_API_KEY)S.provider="openrouter"}if(!S.apiKey)switch(S.provider){case"google":S.apiKey=process.env.GOOGLE_GENERATIVE_AI_API_KEY||process.env.GEMINI_API_KEY;break;case"anthropic":S.apiKey=process.env.ANTHROPIC_API_KEY;break;case"openai":S.apiKey=process.env.OPENAI_API_KEY;break;case"openrouter":S.apiKey=process.env.OPENROUTER_API_KEY;break;case"bedrock":break}if(S.provider==="openrouter"&&S.model==="gemini-2.5-flash-lite")S.model="google/gemini-2.5-flash-lite";if(S.embeddingDimension===void 0)S.embeddingDimension=$y(S.provider);if(S.mode&&!xn().includes(S.mode))S.mode="code";return S}function rn(){return{...Pn}}var Pn;var On=j(()=>{jn();Pn={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,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 tp={};sp(tp,{writeProjectConfig:()=>hp,validatePatch:()=>Vn,readProjectConfig:()=>b,previewConfig:()=>pe,patchConfig:()=>ye,getEffectiveConfig:()=>x,getConfigSchema:()=>ne});import{existsSync as Iy}from"fs";import{mkdir as qy,readFile as wy,writeFile as by}from"fs/promises";import{dirname as oy,join as ay}from"path";function Np(n){return ay(n,".open-mem","config.json")}function gp(n){return Rp.find((p)=>p.key===n)}function sy(n,p){let y=gp(n);if(!y)return null;if(y.type==="string"&&typeof p!=="string")return`${String(n)} must be a string`;if(y.type==="number"&&typeof p!=="number")return`${String(n)} must be a number`;if(y.type==="boolean"&&typeof p!=="boolean")return`${String(n)} must be a boolean`;if(y.type==="array"&&!Array.isArray(p))return`${String(n)} must be an array`;if(y.enum&&typeof p==="string"&&!y.enum.includes(p))return`${String(n)} must be one of: ${y.enum.join(", ")}`;if(typeof p==="number"){if(y.min!==void 0&&p<y.min)return`${String(n)} must be >= ${y.min}`;if(y.max!==void 0&&p>y.max)return`${String(n)} must be <= ${y.max}`}return null}function ne(){return Rp}async function b(n){let p=Np(n);if(!Iy(p))return{};try{let y=await wy(p,"utf-8"),e=JSON.parse(y);if(!e||typeof e!=="object"||Array.isArray(e))return{};return e}catch{return{}}}async function hp(n,p){let y=Np(n),S={...await b(n),...p};await qy(oy(y),{recursive:!0}),await by(y,JSON.stringify(S,null,2),"utf-8")}function Vn(n){let p=[];for(let[y,e]of Object.entries(n)){let u=sy(y,e);if(u)p.push(u)}return p}async function x(n){let p=rn(),y=await b(n),e=T(n),S=[],u={};for(let[m,r]of Object.entries(p)){let O=m,M=gp(O),f=(dy[O]??[]).some((h)=>typeof process.env[h]==="string"),g=Object.hasOwn(y,O),N="default";if(g)N="file";if(f)N="env";if(u[O]={source:N,locked:f,restartRequired:M?.restartRequired??!1,liveApply:M?.liveApply??!1},N==="env"&&g)S.push(`${String(O)} is overridden by environment variable.`);if(e[O]===void 0&&r!==void 0)S.push(`${String(O)} resolved to undefined unexpectedly.`)}return{config:e,meta:u,warnings:S}}async function pe(n,p){let y=Vn(p);if(y.length>0)return{...await x(n),warnings:y};let e=rn(),S=await b(n),u={...e,...S,...p},r={...T(n,p),...u},O=(await x(n)).meta;return{config:r,meta:O,warnings:[]}}async function ye(n,p){let y=Vn(p);if(y.length>0)return{...await x(n),warnings:y};return await hp(n,p),x(n)}var Rp,dy;var _p=j(()=>{On();Rp=[{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:"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}],dy={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"],mcpProtocolVersion:["OPEN_MEM_MCP_PROTOCOL_VERSION"],mcpSupportedProtocolVersions:["OPEN_MEM_MCP_SUPPORTED_PROTOCOLS"],rerankingEnabled:["OPEN_MEM_RERANKING"],userMemoryEnabled:["OPEN_MEM_USER_MEMORY"]}});import{readFileSync as Ze}from"fs";import{join as ze}from"path";import{parseArgs as Ke}from"util";import{createInterface as ny}from"readline";import{z as l}from"zod";import{z as c}from"zod";var k=c.enum(["decision","bugfix","feature","refactor","discovery","change"]),A={find:c.object({query:c.string().min(1),scope:c.enum(["project","user","all"]).optional().default("project"),types:c.array(k).optional(),limit:c.number().int().min(1).max(50).optional().default(10),cursor:c.string().optional(),include:c.object({snippets:c.boolean().optional(),scores:c.boolean().optional(),relations:c.boolean().optional()}).optional()}),history:c.object({limit:c.number().int().min(1).max(20).optional().default(5),cursor:c.string().optional(),sessionId:c.string().optional(),anchor:c.string().optional().describe("Observation ID to center the timeline around"),depthBefore:c.number().int().min(0).max(20).optional().default(5),depthAfter:c.number().int().min(0).max(20).optional().default(5)}),get:c.object({ids:c.array(c.string()).min(1),includeHistory:c.boolean().optional().default(!1),limit:c.number().int().min(1).max(50).optional().default(10)}),create:c.object({title:c.string(),type:k,narrative:c.string(),concepts:c.array(c.string()).optional(),files:c.array(c.string()).optional(),importance:c.number().int().min(1).max(5).optional(),scope:c.enum(["project","user"]).optional().default("project")}),revise:c.object({id:c.string(),title:c.string().optional(),narrative:c.string().optional(),type:k.optional(),concepts:c.array(c.string()).optional(),importance:c.number().int().min(1).max(5).optional(),reason:c.string().optional()}),remove:c.object({id:c.string(),reason:c.string().optional()}),transferExport:c.object({scope:c.enum(["project"]).optional().default("project"),type:k.optional(),limit:c.number().int().min(1).optional(),format:c.enum(["json"]).optional().default("json")}),transferImport:c.object({payload:c.string(),mode:c.enum(["skip","merge","replace"]).optional().default("skip")}),maintenance:c.object({action:c.enum(["folderContextDryRun","folderContextClean","folderContextRebuild","folderContextPurge"])}),help:c.object({})},yn=[{name:"mem-find",schema:"find",description:"Search past memories \u2014 decisions, discoveries, gotchas, and session history. Use to recall context from previous sessions before starting work."},{name:"mem-history",schema:"history",description:"Browse session timeline and summaries. Use to understand what happened in recent sessions or drill into a specific session."},{name:"mem-get",schema:"get",description:"Fetch full memory details by ID. Use after mem-find or mem-history to get complete narratives, facts, and file lists."},{name:"mem-create",schema:"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."},{name:"mem-revise",schema:"revise",description:"Update an existing memory with a new revision. Use when a previous decision changed, a gotcha was resolved, or information became outdated."},{name:"mem-remove",schema:"remove",description:"Tombstone an obsolete or incorrect memory. Use to clean up memories that are no longer accurate or relevant."},{name:"mem-export",schema:"transferExport",description:"Export project memories as portable JSON for backup or transfer between machines."},{name:"mem-import",schema:"transferImport",description:"Import memories from a JSON export. Skips duplicates by default."},{name:"mem-maintenance",schema:"maintenance",description:"Run folder context maintenance \u2014 clean, rebuild, purge, or dry-run AGENTS.md files."},{name:"mem-help",schema:"help",description:"Show detailed memory workflow guidance including when to save, what to save, and memory type reference."}];function _(n,p={}){return{data:n,error:null,meta:p}}function B(n,p,y){return{data:null,error:{code:n,message:p,details:y},meta:{}}}var py="2024-11-05",yy=l.object({name:l.string().min(1),arguments:l.record(l.string(),l.unknown()).optional()});function ey(n){if(typeof n!=="object"||n===null)return!1;let p=n;return p.jsonrpc==="2.0"&&typeof p.method==="string"}function Sy(n){let y=l.toJSONSchema(n);return{type:"object",properties:y.properties??{},required:y.required??void 0,additionalProperties:!1}}function Wn(n){return n.issues.map((p)=>{return`${p.path.length>0?p.path.join("."):"input"}: ${p.message}`}).join("; ")}class en{memoryEngine;version;protocolVersion;supportedProtocolVersions;initialized=!1;pendingOps=[];constructor(n){this.memoryEngine=n.memoryEngine,this.version=n.version,this.protocolVersion=n.protocolVersion??py,this.supportedProtocolVersions=n.supportedProtocolVersions&&n.supportedProtocolVersions.length>0?n.supportedProtocolVersions:[this.protocolVersion]}start(){let n=ny({input:process.stdin,terminal:!1});n.on("line",(p)=>{let y=p.trim();if(!y)return;try{let e=JSON.parse(y);if(!ey(e)){this.send({jsonrpc:"2.0",id:null,error:{code:-32600,message:"Invalid Request"}});return}this.handle(e)}catch{this.send({jsonrpc:"2.0",id:null,error:{code:-32700,message:"Parse error"}})}}),n.on("close",()=>{Promise.allSettled(this.pendingOps).then(()=>process.exit(0))})}handle(n){if(n.method==="notifications/initialized"){this.initialized=!0;return}if(n.id===void 0||n.id===null)return;if(n.method==="initialize"){this.handleInitialize(n);return}if(!this.initialized){this.send({jsonrpc:"2.0",id:n.id,error:{code:-32002,message:"Server not initialized"}});return}switch(n.method){case"tools/list":this.send({jsonrpc:"2.0",id:n.id,result:{tools:this.getToolDefinitions()}});return;case"tools/call":{let p=this.handleToolCall(n.id,n.params);this.pendingOps.push(p),p.finally(()=>{this.pendingOps=this.pendingOps.filter((y)=>y!==p)});return}case"ping":this.send({jsonrpc:"2.0",id:n.id,result:{}});return;default:this.send({jsonrpc:"2.0",id:n.id,error:{code:-32601,message:`Method not found: ${n.method}`}})}}handleInitialize(n){let p=typeof n.params?.protocolVersion==="string"?n.params.protocolVersion:this.protocolVersion;if(!this.supportedProtocolVersions.includes(p)){this.send({jsonrpc:"2.0",id:n.id??null,error:{code:-32602,message:`Unsupported protocol version: ${p}`,data:{supported:this.supportedProtocolVersions}}});return}this.initialized=!0,this.send({jsonrpc:"2.0",id:n.id??null,result:{protocolVersion:p,capabilities:{tools:{listChanged:!1}},serverInfo:{name:"open-mem",version:this.version}}})}getToolDefinitions(){return yn.map((n)=>({name:n.name,description:n.description,inputSchema:Sy(A[n.schema])}))}async handleToolCall(n,p){let y=yy.safeParse(p??{});if(!y.success){this.send({jsonrpc:"2.0",id:n,result:{content:[{type:"text",text:JSON.stringify(B("VALIDATION_ERROR",Wn(y.error)),null,2)}],isError:!0}});return}let e=y.data.name,S=y.data.arguments??{};try{let u=await this.executeTool(e,S);this.send({jsonrpc:"2.0",id:n,result:u})}catch(u){this.send({jsonrpc:"2.0",id:n,result:{content:[{type:"text",text:JSON.stringify(B("INTERNAL_ERROR",String(u)),null,2)}],isError:!0}})}}async executeTool(n,p){let y=async()=>{switch(n){case"mem-find":{let e=A.find.parse(p),S=await this.memoryEngine.search(e.query,{limit:e.limit,type:e.types?.[0]});return JSON.stringify(_({results:S}),null,2)}case"mem-history":{let e=A.history.parse(p);return JSON.stringify(_({items:await this.memoryEngine.timeline({limit:e.limit,sessionId:e.sessionId,anchor:e.anchor,depthBefore:e.depthBefore,depthAfter:e.depthAfter})}),null,2)}case"mem-get":{let e=A.get.parse(p);return JSON.stringify(_({observations:await this.memoryEngine.recall(e.ids,e.limit)}),null,2)}case"mem-create":{let e=A.create.parse(p),S=await this.memoryEngine.save({...e,sessionId:"mcp"});return JSON.stringify(S?_({observation:S}):B("CONFLICT","Unable to create memory"),null,2)}case"mem-revise":{let e=A.revise.parse(p),S=await this.memoryEngine.update(e);return JSON.stringify(S?_({previousId:e.id,newId:S.id,observation:S}):B("NOT_FOUND",`Observation ${e.id} not found`),null,2)}case"mem-remove":{let e=A.remove.parse(p),S=await this.memoryEngine.delete([e.id]);return JSON.stringify(S>0?_({id:e.id,tombstoned:!0}):B("NOT_FOUND",`Observation ${e.id} not found`),null,2)}case"mem-export":{let e=A.transferExport.parse(p),S=await this.memoryEngine.export("project",{type:e.type,limit:e.limit});return JSON.stringify(_({payload:S,format:e.format}),null,2)}case"mem-import":{let e=A.transferImport.parse(p),S=e.mode==="replace"?"overwrite":"skip-duplicates",u=await this.memoryEngine.import(e.payload,{mode:S});return JSON.stringify(_({imported:u.imported,skipped:u.skipped,mode:e.mode}),null,2)}case"mem-maintenance":{let e=A.maintenance.parse(p);if(e.action==="folderContextDryRun")return JSON.stringify(_(await this.memoryEngine.maintainFolderContext("clean",!0)),null,2);if(e.action==="folderContextClean")return JSON.stringify(_(await this.memoryEngine.maintainFolderContext("clean",!1)),null,2);if(e.action==="folderContextPurge")return JSON.stringify(_(await this.memoryEngine.maintainFolderContext("purge",!1)),null,2);return JSON.stringify(_(await this.memoryEngine.maintainFolderContext("rebuild",!1)),null,2)}case"mem-help":return JSON.stringify(_({guide:this.memoryEngine.guide()}),null,2);default:return JSON.stringify(B("NOT_FOUND",`Unknown tool: ${n}`),null,2)}};try{let e=await y(),S=e.includes('"error": {')&&!e.includes('"error": null');return{content:[{type:"text",text:e}],isError:S}}catch(e){if(e instanceof l.ZodError)return{content:[{type:"text",text:JSON.stringify(B("VALIDATION_ERROR",Wn(e)),null,2)}],isError:!0};return{content:[{type:"text",text:JSON.stringify(B("INTERNAL_ERROR",String(e)),null,2)}],isError:!0}}}send(n){process.stdout.write(`${JSON.stringify(n)}
4
- `)}}function Yn(n){if(typeof n!=="object"||n===null)return!1;let p=n,y=p.status;if(y===429||y===500||y===503)return!0;let e=p.error;if(typeof e==="object"&&e!==null&&e.type==="overloaded_error")return!0;return!1}function F(n){if(n&&typeof n==="object"){let p=n.status;if(typeof p==="number")return p===400||p===401||p===403}return!1}class Sn{shouldFailover(n){let{error:p,attemptIndex:y,totalProviders:e}=n;if(F(p))return!1;if(y>=e-1)return!1;return Yn(p)}onFailover(n){let p=n.error?.status??"unknown";if(!n.nextProvider)return;console.error(`[open-mem] Provider ${n.provider} failed (${p}), falling over to ${n.nextProvider}`)}}class un{specificationVersion;provider;modelId;supportedUrls;providers;policy;constructor(n,p=new Sn){if(n.length===0)throw Error("At least one provider required");let y=n[0].model;this.specificationVersion=y.specificationVersion,this.provider=y.provider,this.modelId=y.modelId,this.supportedUrls=y.supportedUrls,this.providers=n,this.policy=p}async doGenerate(n){let p;for(let y=0;y<this.providers.length;y++){let e=this.providers[y];try{return this.policy.onAttempt?.({error:null,provider:e.name,nextProvider:this.providers[y+1]?.name,attemptIndex:y,totalProviders:this.providers.length}),await e.model.doGenerate(n)}catch(S){if(p=S,F(S))throw S;let u=this.providers[y+1]?.name,m={error:S,provider:e.name,nextProvider:u,attemptIndex:y,totalProviders:this.providers.length};if(this.policy.shouldFailover(m)){this.policy.onFailover(m);continue}throw this.policy.onFinalFailure?.(m),S}}throw p}async doStream(n){let p;for(let y=0;y<this.providers.length;y++){let e=this.providers[y];try{return this.policy.onAttempt?.({error:null,provider:e.name,nextProvider:this.providers[y+1]?.name,attemptIndex:y,totalProviders:this.providers.length}),await e.model.doStream(n)}catch(S){if(p=S,F(S))throw S;let u=this.providers[y+1]?.name,m={error:S,provider:e.name,nextProvider:u,attemptIndex:y,totalProviders:this.providers.length};if(this.policy.shouldFailover(m)){this.policy.onFailover(m);continue}throw this.policy.onFinalFailure?.(m),S}}throw p}}var uy={"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 my(n){if(n.includes("."))return n;return uy[n]||`us.anthropic.${n}-v1:0`}function Dn(n){switch(n.provider){case"anthropic":{let{createAnthropic:p}=$("@ai-sdk/anthropic");return p({apiKey:n.apiKey})(n.model)}case"bedrock":{let{createAmazonBedrock:p}=$("@ai-sdk/amazon-bedrock");return p()(my(n.model))}case"openai":{let{createOpenAI:p}=$("@ai-sdk/openai");return p({apiKey:n.apiKey})(n.model)}case"google":{let{createGoogleGenerativeAI:p}=$("@ai-sdk/google");return p({apiKey:n.apiKey})(n.model)}case"openrouter":{let{createOpenRouter:p}=$("@openrouter/ai-sdk-provider");return p({apiKey:n.apiKey})(n.model)}default:throw Error(`Unknown provider: ${n.provider}. Supported: anthropic, bedrock, openai, google, openrouter`)}}function kn(n){try{switch(n.provider){case"google":{let{createGoogleGenerativeAI:p}=$("@ai-sdk/google");return p({apiKey:n.apiKey}).embedding("text-embedding-004")}case"openai":{let{createOpenAI:p}=$("@ai-sdk/openai");return p({apiKey:n.apiKey}).embedding("text-embedding-3-small")}case"bedrock":{let{createAmazonBedrock:p}=$("@ai-sdk/amazon-bedrock");return p().embedding("amazon.titan-embed-text-v2:0")}case"anthropic":return null;case"openrouter":return null;default:return null}}catch{return null}}var ry={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 Oy(n){switch(n){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 Fn(n){if(!n.fallbackProviders||n.fallbackProviders.length===0)return[];return n.fallbackProviders.map((p)=>({provider:p,model:ry[p]??"gemini-2.5-flash-lite",apiKey:Oy(p)}))}function Tn(n,p=[],y){let e=Dn(n);if(p.length===0)return e;let S=[{name:n.provider,model:e},...p.map((u)=>({name:u.provider,model:Dn(u)}))];return new un(S,y)}On();import{randomUUID as Vp}from"crypto";function By(n,p){let y=new RegExp(`<${p}[^>]*>([\\s\\S]*?)</${p}>`,"i"),e=n.match(y);return e?e[1].trim():""}function Uy(n,p){let y=new RegExp(`<${p}[^>]*>([\\s\\S]*?)</${p}>`,"gi"),e=[];for(let S of n.matchAll(y)){let u=S[1].trim();if(u)e.push(u)}return e}function In(n){let p=By(n,"reranked");if(!p)return null;let y=Uy(p,"index");if(y.length===0)return null;let e=[];for(let S of y){let u=Number.parseInt(S,10);if(Number.isNaN(u)||u<0)return null;e.push(u)}return e}function U(n){return Math.ceil(n.length/4)}var Ly={showTokenCosts:!0,observationTypes:"all",fullObservationCount:3,showLastSummary:!0},G={bugfix:"\uD83D\uDD34",feature:"\uD83D\uDFE3",refactor:"\uD83D\uDD04",change:"\u2705",discovery:"\uD83D\uDD35",decision:"\u2696\uFE0F"};function qn(n,p=Ly){let y=[];if(y.push("## open-mem: Past Session Memory"),y.push(""),y.push("**\uD83D\uDCA1 Progressive Disclosure:** This is a compact index showing WHAT was observed and retrieval COST."),y.push("Use `mem-find` to find observations by query, then `mem-get` with IDs to fetch full details."),y.push(""),y.push("**3-Layer Memory Access:**"),y.push("- **Layer 1** `mem-find` \u2014 Find observations by query (returns IDs + summaries)"),y.push("- **Layer 2** `mem-history` \u2014 Browse session history and drill into sessions"),y.push("- **Layer 3** `mem-get` \u2014 Get full details by ID (use IDs from search results or the index below)"),y.push(""),y.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."),p.showLastSummary&&n.recentSummaries.length>0){y.push(""),y.push("### Recent Sessions"),y.push("| Session | Summary | Decisions |"),y.push("|---------|---------|-----------|");for(let m of n.recentSummaries){let r=m.keyDecisions.length>0?m.keyDecisions.join("; "):"\u2014";y.push(`| ${m.sessionId} | ${m.summary} | ${r} |`)}}let e=p.observationTypes==="all"?n.observationIndex:n.observationIndex.filter((m)=>p.observationTypes.includes(m.type));if(e.length>0){y.push(""),y.push(`### Recent Observations (${e.length} entries)`);let m=Xy(e,n.fullObservations);for(let[r,O]of m){if(y.push(""),y.push(`**${r}**`),p.showTokenCosts)y.push("| ID | Type | Title | ~Tokens |"),y.push("|----|------|-------|---------|");else y.push("| ID | Type | Title |"),y.push("|----|------|-------|");for(let M of O){let E=G[M.type]||"\uD83D\uDCDD";if(p.showTokenCosts)y.push(`| ${M.id} | ${E} | ${M.title} | ~${M.tokenCount} |`);else y.push(`| ${M.id} | ${E} | ${M.title} |`)}}}let S=n.fullObservations.slice(0,p.fullObservationCount);if(S.length>0){y.push(""),y.push("### Full Details (most recent)");for(let m of S){let r=G[m.type]||"\uD83D\uDCDD";if(y.push(""),y.push(`#### ${r} ${m.title} (${m.id})`),y.push(m.narrative),m.facts.length>0)y.push(`**Facts:** ${m.facts.map((M)=>`- ${M}`).join(" ")}`);if(m.concepts.length>0)y.push(`**Concepts:** ${m.concepts.join(", ")}`);let O=[...m.filesRead,...m.filesModified];if(O.length>0)y.push(`**Files:** ${O.join(", ")}`)}}let u=ly(n);if(u)y.push(""),y.push(u);return y.join(`
5
- `)}function ly(n){let p=0,y=0,e=new Set(n.observationIndex.map((m)=>m.id));for(let m of n.observationIndex)p+=m.tokenCount,y+=m.discoveryTokens;for(let m of n.fullObservations)if(!e.has(m.id))p+=m.tokenCount,y+=m.discoveryTokens;if(y===0)return null;let S=y-p,u=Math.max(0,Math.round(S/y*100));return`### \uD83D\uDCB0 Memory Economics
6
- **Read cost:** ~${p}t | **Discovery cost:** ~${y}t | **Savings:** ${u}% (${S}t saved)`}function Xy(n,p){let y=new Map;for(let S of p){let u=S.filesModified[0]||S.filesRead[0];if(u)y.set(S.id,u)}let e=new Map;for(let S of n){let u=y.get(S.id)??"General",m=e.get(u)??[];m.push(S),e.set(u,m)}return e}function wn(n){let p=[];if(p.push("[open-mem] Memory context:"),n.recentSummaries.length>0){p.push(`
7
- Recent sessions:`);for(let y of n.recentSummaries)p.push(`- ${y.summary}`)}if(n.observationIndex.length>0){p.push(`
8
- Recent observations (${n.observationIndex.length} entries):`);for(let y of n.observationIndex)p.push(`- ${G[y.type]||"\uD83D\uDCDD"} ${y.title}`)}return p.join(`
9
- `)}function bn(n,p){if(n.length===0)return"";let y=p,e=[];for(let u of n){let m=u.tokenCount||U(u.title);if(y-m<0)break;e.push(u),y-=m}if(e.length===0)return"";let S=[];S.push("### Cross-Project Memory"),S.push(""),S.push("| ID | Type | Title | ~Tokens |"),S.push("|----|------|-------|---------|");for(let u of e){let m=G[u.type]||"\uD83D\uDCDD";S.push(`| ${u.id} | ${m} | ${u.title} | ~${u.tokenCount} |`)}return S.join(`
10
- `)}function on(n,p){if(n.length===0)return"";let y=p,e=[];for(let u of n){let m=u.tokenCount||U(u.title);if(y-m<0)break;e.push(u),y-=m}if(e.length===0)return"";let S=[];S.push(`
11
- Cross-project observations (${e.length} entries):`);for(let u of e)S.push(`- ${G[u.type]||"\uD83D\uDCDD"} ${u.title}`);return S.join(`
12
- `)}var I={recency:0.4,typeImportance:0.3,sessionAffinity:0.2,tokenEfficiency:0.1},Zy={decision:1,bugfix:0.9,feature:0.8,refactor:0.6,discovery:0.5,change:0.4};function zy(n,p){let y=new Date(n),S=(p.getTime()-y.getTime())/3600000;if(S<0)return 1;if(S<24)return 1;if(S<48)return 0.8;if(S<168)return 0.5;return 0.2}function Ky(n){return Zy[n]??0.3}function Hy(n,p){if(!p)return 0.5;return n===p?1:0.3}function Qy(n){if(n<=10)return 1;if(n>=200)return 0.2;return 1-(n-10)/190*0.8}function Wy(n,p){let y=zy(n.createdAt,p.now),e=Ky(n.type),S=Hy(n.sessionId,p.currentSessionId),u=Qy(n.tokenCount);return y*I.recency+e*I.typeImportance+S*I.sessionAffinity+u*I.tokenEfficiency}function an(n,p){let y=new Map;for(let e of n)y.set(e.id,Wy(e,p));return[...n].sort((e,S)=>{let u=y.get(e.id)??0,m=y.get(S.id)??0;if(m!==u)return m-u;return new Date(S.createdAt).getTime()-new Date(e.createdAt).getTime()})}function dn(n,p,y,e,S=[],u){let m=e,r=[],O=[];for(let E of p){let f=E.tokenCount||U(E.summary);if(m-f<0)break;r.push(E),m-=f}let M=u?an(y,u):y;for(let E of M){let f=E.tokenCount||U(E.title);if(m-f<0)break;O.push(E),m-=f}return{recentSummaries:r,observationIndex:O,fullObservations:[...S],totalTokens:e-m}}import{existsSync as gn}from"fs";import{readdir as Py,readFile as mp,unlink as Nn,writeFile as rp}from"fs/promises";import{join as hn,resolve as tn}from"path";import{existsSync as np}from"fs";import{mkdir as Yy,readFile as iy,rename as Dy,unlink as ky,writeFile as Fy}from"fs/promises";import{dirname as q,isAbsolute as cn,join as v,normalize as Ty,relative as fn,resolve as H,sep as Mn}from"path";var K="<!-- open-mem-context -->",Z="<!-- /open-mem-context -->",pp={bugfix:"\uD83D\uDD34",feature:"\uD83D\uDFE3",refactor:"\uD83D\uDD04",change:"\u2705",discovery:"\uD83D\uDD35",decision:"\u2696\uFE0F"},sn=new Map,Gy=new Set(["node_modules",".git","dist","coverage",".open-mem","build","__pycache__",".next",".nuxt"]);async function yp(n,p,y){if(p.length===0)return;if(y.mode==="single")return vy(n,p,y);let{maxDepth:e,filename:S}=y,u=[];for(let O of p){for(let M of O.filesModified)u.push(M);for(let M of O.filesRead)u.push(M)}let m=Sp(u,n,e);if(m.size===0)return;let r=up(p,m,n);for(let[O,M]of r)try{let E=xy(O,M,n);await ep(O,E,S)}catch(E){console.error(`[open-mem] Failed to update AGENTS.md in ${O}:`,E)}}async function vy(n,p,y){let{maxDepth:e,filename:S}=y,u=p.filter(En);if(u.length===0)return;let m=[];for(let N of u){for(let h of N.filesModified)m.push(h);for(let h of N.filesRead)m.push(h)}let r=Sp(m,n,e),O=up(u,r,n),M=u.filter((N)=>{return[...N.filesModified,...N.filesRead].some((V)=>{if(!V)return!1;let L=cn(V)?V:v(n,V);return H(q(L))===H(n)})});if(M.length>0)O.set(H(n),M);if(O.size===0)return;let E=[];E.push("## Project Activity (auto-generated by open-mem)"),E.push("");let f=[...O.entries()].map(([N,h])=>({relPath:fn(n,N)||".",observations:h})).sort((N,h)=>N.relPath.localeCompare(h.relPath));for(let{relPath:N,observations:h}of f){let V=h.filter(En).sort((t,D)=>D.createdAt.localeCompare(t.createdAt)).slice(0,10);if(V.length===0)continue;E.push(`### ${N}/`),E.push("| ID | Type | Title | Date |"),E.push("|----|------|-------|------|");for(let t of V){let D=pp[t.type]||"\uD83D\uDCDD",op=t.createdAt.split("T")[0],ap=t.title.replace(/\|/g,"\\|");E.push(`| ${t.id} | ${D} ${t.type} | ${ap} | ${op} |`)}let L=new Set;for(let t of V)for(let D of t.concepts)L.add(D);if(L.size>0){let t=[...L].slice(0,10).join(", ");E.push(""),E.push(`**Key concepts:** ${t}`)}let C=V.filter((t)=>t.type==="decision").map((t)=>t.title);if(C.length>0)E.push(""),E.push(`**Recent decisions:** ${C.slice(0,5).join("; ")}`);E.push("")}E.push("\uD83D\uDCA1 *Use `mem-find` to search full details. Use `mem-create` to save important decisions.*");let g=E.join(`
13
- `);await ep(n,g,S)}function En(n){return!/^\w[\w-]*\s+execution$/i.test(n.title)}function xy(n,p,y){let e=[...p].filter(En).sort((M,E)=>E.createdAt.localeCompare(M.createdAt)).slice(0,10),S=fn(y,n)||".",u=[];u.push(`## Recent Activity in \`${S}/\` (auto-generated by open-mem)`),u.push(""),u.push("| ID | Type | Title | Date |"),u.push("|----|------|-------|------|");for(let M of e){let E=pp[M.type]||"\uD83D\uDCDD",f=M.createdAt.split("T")[0],g=M.title.replace(/\|/g,"\\|");u.push(`| ${M.id} | ${E} ${M.type} | ${g} | ${f} |`)}let m=new Set;for(let M of e)for(let E of M.concepts)m.add(E);if(m.size>0){let M=[...m].slice(0,10).join(", ");u.push(""),u.push(`**Key concepts:** ${M}`)}let r=e.filter((M)=>M.type==="decision").map((M)=>M.title);if(r.length>0)u.push(""),u.push(`**Recent decisions:** ${r.slice(0,5).join("; ")}`);let O=e.filter((M)=>M.type==="decision"&&M.narrative).slice(0,3);if(O.length>0){u.push(""),u.push("**Decision details:**");for(let M of O){let E=M.narrative.split(/[.!?]\s/)[0],f=E.length>120?`${E.slice(0,117)}...`:E;u.push(`- \u2696\uFE0F ${M.title}: ${f}`)}}return u.push(""),u.push("\uD83D\uDCA1 *Use `mem-find` to search full details across all sessions. Use `mem-create` to save important decisions.*"),u.join(`
14
- `)}async function ep(n,p,y){if(!np(n))return;let S=(sn.get(n)??Promise.resolve()).then(async()=>{let u=v(n,y),m=v(n,`.${y}.tmp`),r="";try{r=await iy(u,"utf-8")}catch{}let O=jy(r,p);try{await Yy(q(m),{recursive:!0}),await Fy(m,O,"utf-8"),await Dy(m,u)}catch(M){try{await ky(m)}catch{}throw M}});return sn.set(n,S.catch(()=>{})),S}function jy(n,p){if(!n)return`${K}
15
- ${p}
16
- ${Z}
17
- `;let y=n.indexOf(K),e=n.indexOf(Z);if(y!==-1&&e!==-1&&e>y){let u=n.substring(0,y),m=n.substring(e+Z.length);return`${u}${K}
18
- ${p}
19
- ${Z}${m}`}let S=n;if(y!==-1&&e===-1)S=S.replace(K,"").trim();else if(y===-1&&e!==-1)S=S.replace(Z,"").trim();else if(y!==-1&&e!==-1&&e<=y)S=S.replace(Z,"").replace(K,"").trim();return`${S}
20
-
21
- ${K}
22
- ${p}
23
- ${Z}
24
- `}function Sp(n,p,y){let e=new Set,S=H(p);for(let u of n){if(!u||!u.trim())continue;if(u.startsWith("~")||u.startsWith("http"))continue;let m=cn(u)?u:v(p,u),r=q(m),O=H(r);if(!O.startsWith(S+Mn)&&O!==S)continue;if(O===S)continue;let M=fn(S,O);if(M.split(Mn).length>y)continue;if(Ty(M).split(Mn).some((g)=>Gy.has(g)))continue;if(!np(O))continue;e.add(O)}return e}function up(n,p,y){let e=new Map;for(let S of n){let u=[...S.filesModified,...S.filesRead],m=new Set;for(let r of u){if(!r)continue;let O=cn(r)?r:v(y,r),M=H(q(O));if(p.has(M))m.add(M)}for(let r of m){let O=e.get(r)??[];O.push(S),e.set(r,O)}}return e}var Rn="<!-- open-mem-context -->",w="<!-- /open-mem-context -->";async function Mp(n,p,y){let e;try{e=await Py(n,{withFileTypes:!0,encoding:"utf8"})}catch{return}for(let S of e){let u=String(S.name);if(u===".git"||u==="node_modules"||u===".open-mem"||u==="dist")continue;let m=hn(n,u);if(S.isDirectory())await Mp(m,p,y);else if(S.isFile()&&u===p)y.push(m)}}async function _n(n,p){let y=tn(n),e=[];return await Mp(y,p,e),e}function Op(n){let p=n.indexOf(Rn),y=n.indexOf(w);if(p===-1&&y===-1)return n;if(p!==-1&&y===-1){let u=n.replace(Rn,"").trim();return u?`${u}
25
- `:""}if(p===-1&&y!==-1){let u=n.replace(w,"").trim();return u?`${u}
26
- `:""}if(y<=p){let u=n.replace(Rn,"").replace(w,"").trim();return u?`${u}
27
- `:""}let e=n.slice(0,p).trimEnd(),S=n.slice(y+w.length).trimStart();if(!e&&!S)return"";if(!e)return`${S}
28
- `;if(!S)return`${e}
29
- `;return`${e}
30
-
3
+ var Ru=Object.defineProperty;var Nu=(y,S)=>{for(var u in S)Ru(y,u,{get:S[u],enumerable:!0,configurable:!0,set:(n)=>S[u]=()=>n})};var e=(y,S)=>()=>(y&&(S=y(y=0)),S);var H=import.meta.require;import{existsSync as Bu,readdirSync as Zu,readFileSync as Xu}from"fs";import{join as Hu}from"path";function W(y){return{...y,observationTypes:[...y.observationTypes],conceptVocabulary:[...y.conceptVocabulary],entityTypes:[...y.entityTypes],relationshipTypes:[...y.relationshipTypes],promptOverrides:y.promptOverrides?{...y.promptOverrides}:void 0}}function Ku(y){if(!y||typeof y!=="object")return!1;let S=y,u=(O)=>Array.isArray(O)&&O.every((M)=>typeof M==="string"),n=(O)=>typeof O==="object"&&O!==null&&!Array.isArray(O)&&Object.values(O).every((M)=>typeof M==="string");return typeof S.id==="string"&&(S.extends===void 0||typeof S.extends==="string")&&(S.locale===void 0||typeof S.locale==="string")&&(S.name===void 0||typeof S.name==="string")&&(S.description===void 0||typeof S.description==="string")&&(S.observationTypes===void 0||u(S.observationTypes))&&(S.conceptVocabulary===void 0||u(S.conceptVocabulary))&&(S.entityTypes===void 0||u(S.entityTypes))&&(S.relationshipTypes===void 0||u(S.relationshipTypes))&&(S.promptOverrides===void 0||n(S.promptOverrides))}function Yu(y){return typeof y.name==="string"&&typeof y.description==="string"&&Array.isArray(y.observationTypes)&&Array.isArray(y.conceptVocabulary)&&Array.isArray(y.entityTypes)&&Array.isArray(y.relationshipTypes)}function Py(y,S){return{...y,...S,id:S.id,name:S.name??y.name,description:S.description??y.description,observationTypes:S.observationTypes??y.observationTypes,conceptVocabulary:S.conceptVocabulary??y.conceptVocabulary,entityTypes:S.entityTypes??y.entityTypes,relationshipTypes:S.relationshipTypes??y.relationshipTypes,promptOverrides:{...y.promptOverrides??{},...S.promptOverrides??{}}}}class Ry{modesDir;constructor(y){this.modesDir=y}loadAllRaw(){let y=new Map;if(!Bu(this.modesDir))return y;for(let S of Zu(this.modesDir)){if(!S.endsWith(".json"))continue;let u=Hu(this.modesDir,S);try{let n=Xu(u,"utf-8"),O=JSON.parse(n);if(!Ku(O))continue;if(y.has(O.id))console.warn(`[open-mem] Duplicate mode id "${O.id}" in ${u}; overriding previous definition.`);y.set(O.id,O)}catch{}}return y}resolveById(y,S){let u=new Set,n=!1,O=(f)=>{if(u.has(f))return n=!0,W(L);u.add(f);let p=S.get(f);if(!p)return W(L);if(!p.extends){if(!Yu(p))return W(L);return Py(W(L),p)}let E=O(p.extends);if(n)return W(L);return Py(E,p)},M=O(y);return n?W(L):W(M)}}var L;var ry=e(()=>{L={id:"code",name:"Code",description:"Default coding workflow mode",observationTypes:["decision","bugfix","feature","refactor","discovery","change"],conceptVocabulary:["how-it-works","why-it-exists","what-changed","problem-solution","gotcha","pattern","trade-off"],entityTypes:["technology","library","pattern","concept","file","person","project","other"],relationshipTypes:["uses","depends_on","implements","extends","related_to","replaces","configures"]}});import{join as cu}from"path";function Qu(){if(i)return i;return i=Wu.loadAllRaw(),i}function ey(){return[...Qu().keys()].sort()}var zu,Wu,i=null;var iy=e(()=>{ry();zu=cu(import.meta.dir,"."),Wu=new Ry(zu)});import{existsSync as Lu,readFileSync as Fu}from"fs";function Du(){let y={};if(process.env.OPEN_MEM_DB_PATH)y.dbPath=process.env.OPEN_MEM_DB_PATH;if(process.env.OPEN_MEM_PROVIDER)y.provider=process.env.OPEN_MEM_PROVIDER;if(process.env.OPEN_MEM_MODEL)y.model=process.env.OPEN_MEM_MODEL;if(process.env.OPEN_MEM_MAX_CONTEXT_TOKENS)y.maxContextTokens=Number.parseInt(process.env.OPEN_MEM_MAX_CONTEXT_TOKENS,10);if(process.env.OPEN_MEM_COMPRESSION==="false")y.compressionEnabled=!1;if(process.env.OPEN_MEM_CONTEXT_INJECTION==="false")y.contextInjectionEnabled=!1;if(process.env.OPEN_MEM_IGNORED_TOOLS)y.ignoredTools=process.env.OPEN_MEM_IGNORED_TOOLS.split(",").map((S)=>S.trim());if(process.env.OPEN_MEM_BATCH_SIZE)y.batchSize=Number.parseInt(process.env.OPEN_MEM_BATCH_SIZE,10);if(process.env.OPEN_MEM_RETENTION_DAYS)y.retentionDays=Number.parseInt(process.env.OPEN_MEM_RETENTION_DAYS,10);if(process.env.OPEN_MEM_LOG_LEVEL)y.logLevel=process.env.OPEN_MEM_LOG_LEVEL;if(process.env.OPEN_MEM_CONTEXT_SHOW_TOKEN_COSTS==="false")y.contextShowTokenCosts=!1;if(process.env.OPEN_MEM_CONTEXT_TYPES)y.contextObservationTypes=process.env.OPEN_MEM_CONTEXT_TYPES==="all"?"all":process.env.OPEN_MEM_CONTEXT_TYPES.split(",").map((S)=>S.trim());if(process.env.OPEN_MEM_CONTEXT_FULL_COUNT)y.contextFullObservationCount=Number.parseInt(process.env.OPEN_MEM_CONTEXT_FULL_COUNT,10);if(process.env.OPEN_MEM_MAX_OBSERVATIONS)y.maxObservations=Number.parseInt(process.env.OPEN_MEM_MAX_OBSERVATIONS,10);if(process.env.OPEN_MEM_CONTEXT_SHOW_LAST_SUMMARY==="false")y.contextShowLastSummary=!1;if(process.env.OPEN_MEM_RATE_LIMITING==="false")y.rateLimitingEnabled=!1;if(process.env.OPEN_MEM_FOLDER_CONTEXT==="false")y.folderContextEnabled=!1;if(process.env.OPEN_MEM_FOLDER_CONTEXT_MAX_DEPTH)y.folderContextMaxDepth=Number.parseInt(process.env.OPEN_MEM_FOLDER_CONTEXT_MAX_DEPTH,10);if(process.env.OPEN_MEM_FOLDER_CONTEXT_MODE==="single")y.folderContextMode="single";if(process.env.OPEN_MEM_FOLDER_CONTEXT_MODE==="dispersed")y.folderContextMode="dispersed";if(process.env.OPEN_MEM_FOLDER_CONTEXT_FILENAME)y.folderContextFilename=process.env.OPEN_MEM_FOLDER_CONTEXT_FILENAME;if(process.env.OPEN_MEM_DAEMON==="true")y.daemonEnabled=!0;if(process.env.OPEN_MEM_DASHBOARD==="true")y.dashboardEnabled=!0;if(process.env.OPEN_MEM_DASHBOARD_PORT)y.dashboardPort=Number.parseInt(process.env.OPEN_MEM_DASHBOARD_PORT,10);if(process.env.OPEN_MEM_PLATFORM_OPENCODE==="false")y.platformOpenCodeEnabled=!1;if(process.env.OPEN_MEM_PLATFORM_CLAUDE_CODE==="true")y.platformClaudeCodeEnabled=!0;if(process.env.OPEN_MEM_PLATFORM_CURSOR==="true")y.platformCursorEnabled=!0;if(process.env.OPEN_MEM_MCP_PROTOCOL_VERSION)y.mcpProtocolVersion=process.env.OPEN_MEM_MCP_PROTOCOL_VERSION;if(process.env.OPEN_MEM_MCP_SUPPORTED_PROTOCOLS)y.mcpSupportedProtocolVersions=process.env.OPEN_MEM_MCP_SUPPORTED_PROTOCOLS.split(",").map((S)=>S.trim()).filter(Boolean);if(process.env.OPEN_MEM_EMBEDDING_DIMENSION)y.embeddingDimension=Number.parseInt(process.env.OPEN_MEM_EMBEDDING_DIMENSION,10);if(process.env.OPEN_MEM_CONFLICT_RESOLUTION==="true")y.conflictResolutionEnabled=!0;if(process.env.OPEN_MEM_CONFLICT_BAND_LOW){let S=Number.parseFloat(process.env.OPEN_MEM_CONFLICT_BAND_LOW);if(!Number.isNaN(S))y.conflictSimilarityBandLow=S}if(process.env.OPEN_MEM_CONFLICT_BAND_HIGH){let S=Number.parseFloat(process.env.OPEN_MEM_CONFLICT_BAND_HIGH);if(!Number.isNaN(S))y.conflictSimilarityBandHigh=S}if(process.env.OPEN_MEM_USER_MEMORY==="true")y.userMemoryEnabled=!0;if(process.env.OPEN_MEM_USER_MEMORY_DB_PATH)y.userMemoryDbPath=process.env.OPEN_MEM_USER_MEMORY_DB_PATH;if(process.env.OPEN_MEM_USER_MEMORY_MAX_TOKENS)y.userMemoryMaxContextTokens=Number.parseInt(process.env.OPEN_MEM_USER_MEMORY_MAX_TOKENS,10);if(process.env.OPEN_MEM_RERANKING==="true")y.rerankingEnabled=!0;if(process.env.OPEN_MEM_RERANKING_MAX_CANDIDATES)y.rerankingMaxCandidates=Number.parseInt(process.env.OPEN_MEM_RERANKING_MAX_CANDIDATES,10);if(process.env.OPEN_MEM_ENTITY_EXTRACTION==="true")y.entityExtractionEnabled=!0;if(process.env.OPEN_MEM_FALLBACK_PROVIDERS)y.fallbackProviders=process.env.OPEN_MEM_FALLBACK_PROVIDERS.split(",").map((S)=>S.trim()).filter(Boolean);if(process.env.OPEN_MEM_MODE)y.mode=process.env.OPEN_MEM_MODE;return y}function Gu(y){let S=`${y}/.open-mem/config.json`;if(!Lu(S))return{};try{let u=Fu(S,"utf-8"),n=JSON.parse(u);if(!n||typeof n!=="object"||Array.isArray(n))return{};return n}catch{return{}}}function Tu(y){switch(y){case"google":return 768;case"openai":return 1536;case"bedrock":return 1024;case"anthropic":return 0;case"openrouter":return 0;default:return 768}}function q(y,S){let u=Gu(y),n=Du(),O={...by,...u,...n,...S};if(!O.dbPath.startsWith("/"))O.dbPath=`${y}/${O.dbPath}`;if(!process.env.OPEN_MEM_PROVIDER&&!S?.provider){if(process.env.GOOGLE_GENERATIVE_AI_API_KEY||process.env.GEMINI_API_KEY)O.provider="google";else if(process.env.ANTHROPIC_API_KEY)O.provider="anthropic";else if(process.env.AWS_BEARER_TOKEN_BEDROCK||process.env.AWS_ACCESS_KEY_ID||process.env.AWS_PROFILE)O.provider="bedrock";else if(process.env.OPENROUTER_API_KEY)O.provider="openrouter"}if(!O.apiKey)switch(O.provider){case"google":O.apiKey=process.env.GOOGLE_GENERATIVE_AI_API_KEY||process.env.GEMINI_API_KEY;break;case"anthropic":O.apiKey=process.env.ANTHROPIC_API_KEY;break;case"openai":O.apiKey=process.env.OPENAI_API_KEY;break;case"openrouter":O.apiKey=process.env.OPENROUTER_API_KEY;break;case"bedrock":break}if(O.provider==="openrouter"&&O.model==="gemini-2.5-flash-lite")O.model="google/gemini-2.5-flash-lite";if(O.embeddingDimension===void 0)O.embeddingDimension=Tu(O.provider);if(O.mode&&!ey().includes(O.mode))O.mode="code";return O}function Ny(){return{...by}}var by;var my=e(()=>{iy();by={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:"single",folderContextFilename:"AGENTS.md",daemonEnabled:!1,dashboardEnabled:!1,dashboardPort:3737,platformOpenCodeEnabled:!0,platformClaudeCodeEnabled:!1,platformCursorEnabled:!1,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 BS={};Nu(BS,{writeProjectConfig:()=>US,validatePatch:()=>Xy,readProjectConfig:()=>d,previewConfig:()=>Vn,patchConfig:()=>Jn,getEffectiveConfig:()=>P,getConfigSchema:()=>mn});import{existsSync as nn}from"fs";import{mkdir as On,readFile as Mn,writeFile as fn}from"fs/promises";import{dirname as pn,join as En}from"path";function gS(y){return En(y,".open-mem","config.json")}function CS(y){return $S.find((S)=>S.key===y)}function Nn(y,S){let u=CS(y);if(!u)return null;if(u.type==="string"&&typeof S!=="string")return`${String(y)} must be a string`;if(u.type==="number"&&typeof S!=="number")return`${String(y)} must be a number`;if(u.type==="boolean"&&typeof S!=="boolean")return`${String(y)} must be a boolean`;if(u.type==="array"&&!Array.isArray(S))return`${String(y)} must be an array`;if(u.enum&&typeof S==="string"&&!u.enum.includes(S))return`${String(y)} must be one of: ${u.enum.join(", ")}`;if(typeof S==="number"){if(u.min!==void 0&&S<u.min)return`${String(y)} must be >= ${u.min}`;if(u.max!==void 0&&S>u.max)return`${String(y)} must be <= ${u.max}`}return null}function mn(){return $S}async function d(y){let S=gS(y);if(!nn(S))return{};try{let u=await Mn(S,"utf-8"),n=JSON.parse(u);if(!n||typeof n!=="object"||Array.isArray(n))return{};return n}catch{return{}}}async function US(y,S){let u=gS(y),O={...await d(y),...S};await On(pn(u),{recursive:!0}),await fn(u,JSON.stringify(O,null,2),"utf-8")}function Xy(y){let S=[];for(let[u,n]of Object.entries(y)){let M=Nn(u,n);if(M)S.push(M)}return S}async function P(y){let S=Ny(),u=await d(y),n=q(y),O=[],M={};for(let[f,p]of Object.entries(S)){let E=f,R=CS(E),V=(Rn[E]??[]).some(($)=>typeof process.env[$]==="string"),J=Object.hasOwn(u,E),_="default";if(J)_="file";if(V)_="env";if(M[E]={source:_,locked:V,restartRequired:R?.restartRequired??!1,liveApply:R?.liveApply??!1},_==="env"&&J)O.push(`${String(E)} is overridden by environment variable.`);if(n[E]===void 0&&p!==void 0)O.push(`${String(E)} resolved to undefined unexpectedly.`)}return{config:n,meta:M,warnings:O}}async function Vn(y,S){let u=Xy(S);if(u.length>0)return{...await P(y),warnings:u};let n=Ny(),O=await d(y),M={...n,...O,...S},p={...q(y,S),...M},E=(await P(y)).meta;return{config:p,meta:E,warnings:[]}}async function Jn(y,S){let u=Xy(S);if(u.length>0)return{...await P(y),warnings:u};return await US(y,S),P(y)}var $S,Rn;var ZS=e(()=>{my();$S=[{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:"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}],Rn={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"],mcpProtocolVersion:["OPEN_MEM_MCP_PROTOCOL_VERSION"],mcpSupportedProtocolVersions:["OPEN_MEM_MCP_SUPPORTED_PROTOCOLS"],rerankingEnabled:["OPEN_MEM_RERANKING"],userMemoryEnabled:["OPEN_MEM_USER_MEMORY"]}});import{readFileSync as RO}from"fs";import{join as NO}from"path";import{parseArgs as mO}from"util";import{createInterface as mu}from"readline";import{z}from"zod";import{z as m}from"zod";var k=m.enum(["decision","bugfix","feature","refactor","discovery","change"]),B={find:m.object({query:m.string().min(1),scope:m.enum(["project","user","all"]).optional().default("project"),types:m.array(k).optional(),limit:m.number().int().min(1).max(50).optional().default(10),cursor:m.string().optional(),include:m.object({snippets:m.boolean().optional(),scores:m.boolean().optional(),relations:m.boolean().optional()}).optional()}),history:m.object({limit:m.number().int().min(1).max(20).optional().default(5),cursor:m.string().optional(),sessionId:m.string().optional(),anchor:m.string().optional().describe("Observation ID to center the timeline around"),depthBefore:m.number().int().min(0).max(20).optional().default(5),depthAfter:m.number().int().min(0).max(20).optional().default(5)}),get:m.object({ids:m.array(m.string()).min(1),includeHistory:m.boolean().optional().default(!1),limit:m.number().int().min(1).max(50).optional().default(10)}),create:m.object({title:m.string(),type:k,narrative:m.string(),concepts:m.array(m.string()).optional(),files:m.array(m.string()).optional(),importance:m.number().int().min(1).max(5).optional(),scope:m.enum(["project","user"]).optional().default("project")}),revise:m.object({id:m.string(),title:m.string().optional(),narrative:m.string().optional(),type:k.optional(),concepts:m.array(m.string()).optional(),importance:m.number().int().min(1).max(5).optional(),reason:m.string().optional()}),remove:m.object({id:m.string(),reason:m.string().optional()}),transferExport:m.object({scope:m.enum(["project"]).optional().default("project"),type:k.optional(),limit:m.number().int().min(1).optional(),format:m.enum(["json"]).optional().default("json")}),transferImport:m.object({payload:m.string(),mode:m.enum(["skip","merge","replace"]).optional().default("skip")}),maintenance:m.object({action:m.enum(["folderContextDryRun","folderContextClean","folderContextRebuild","folderContextPurge"])}),help:m.object({})},My=[{name:"mem-find",schema:"find",description:"Search past memories \u2014 decisions, discoveries, gotchas, and session history. Use to recall context from previous sessions before starting work."},{name:"mem-history",schema:"history",description:"Browse session timeline and summaries. Use to understand what happened in recent sessions or drill into a specific session."},{name:"mem-get",schema:"get",description:"Fetch full memory details by ID. Use after mem-find or mem-history to get complete narratives, facts, and file lists."},{name:"mem-create",schema:"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."},{name:"mem-revise",schema:"revise",description:"Update an existing memory with a new revision. Use when a previous decision changed, a gotcha was resolved, or information became outdated."},{name:"mem-remove",schema:"remove",description:"Tombstone an obsolete or incorrect memory. Use to clean up memories that are no longer accurate or relevant."},{name:"mem-export",schema:"transferExport",description:"Export project memories as portable JSON for backup or transfer between machines."},{name:"mem-import",schema:"transferImport",description:"Import memories from a JSON export. Skips duplicates by default."},{name:"mem-maintenance",schema:"maintenance",description:"Run folder context maintenance \u2014 clean, rebuild, purge, or dry-run AGENTS.md files."},{name:"mem-help",schema:"help",description:"Show detailed memory workflow guidance including when to save, what to save, and memory type reference."}];function C(y,S={}){return{data:y,error:null,meta:S}}function K(y,S,u){return{data:null,error:{code:y,message:S,details:u},meta:{}}}var Vu="2024-11-05",Ju=z.object({name:z.string().min(1),arguments:z.record(z.string(),z.unknown()).optional()});function _u(y){if(typeof y!=="object"||y===null)return!1;let S=y;return S.jsonrpc==="2.0"&&typeof S.method==="string"}function Au(y){let u=z.toJSONSchema(y);return{type:"object",properties:u.properties??{},required:u.required??void 0,additionalProperties:!1}}function xy(y){return y.issues.map((S)=>{return`${S.path.length>0?S.path.join("."):"input"}: ${S.message}`}).join("; ")}class fy{memoryEngine;version;protocolVersion;supportedProtocolVersions;initialized=!1;pendingOps=[];constructor(y){this.memoryEngine=y.memoryEngine,this.version=y.version,this.protocolVersion=y.protocolVersion??Vu,this.supportedProtocolVersions=y.supportedProtocolVersions&&y.supportedProtocolVersions.length>0?y.supportedProtocolVersions:[this.protocolVersion]}start(){let y=mu({input:process.stdin,terminal:!1});y.on("line",(S)=>{let u=S.trim();if(!u)return;try{let n=JSON.parse(u);if(!_u(n)){this.send({jsonrpc:"2.0",id:null,error:{code:-32600,message:"Invalid Request"}});return}this.handle(n)}catch{this.send({jsonrpc:"2.0",id:null,error:{code:-32700,message:"Parse error"}})}}),y.on("close",()=>{Promise.allSettled(this.pendingOps).then(()=>process.exit(0))})}handle(y){if(y.method==="notifications/initialized"){this.initialized=!0;return}if(y.id===void 0||y.id===null)return;if(y.method==="initialize"){this.handleInitialize(y);return}if(!this.initialized){this.send({jsonrpc:"2.0",id:y.id,error:{code:-32002,message:"Server not initialized"}});return}switch(y.method){case"tools/list":this.send({jsonrpc:"2.0",id:y.id,result:{tools:this.getToolDefinitions()}});return;case"tools/call":{let S=this.handleToolCall(y.id,y.params);this.pendingOps.push(S),S.finally(()=>{this.pendingOps=this.pendingOps.filter((u)=>u!==S)});return}case"ping":this.send({jsonrpc:"2.0",id:y.id,result:{}});return;default:this.send({jsonrpc:"2.0",id:y.id,error:{code:-32601,message:`Method not found: ${y.method}`}})}}handleInitialize(y){let S=typeof y.params?.protocolVersion==="string"?y.params.protocolVersion:this.protocolVersion;if(!this.supportedProtocolVersions.includes(S)){this.send({jsonrpc:"2.0",id:y.id??null,error:{code:-32602,message:`Unsupported protocol version: ${S}`,data:{supported:this.supportedProtocolVersions}}});return}this.initialized=!0,this.send({jsonrpc:"2.0",id:y.id??null,result:{protocolVersion:S,capabilities:{tools:{listChanged:!1}},serverInfo:{name:"open-mem",version:this.version}}})}getToolDefinitions(){return My.map((y)=>({name:y.name,description:y.description,inputSchema:Au(B[y.schema])}))}async handleToolCall(y,S){let u=Ju.safeParse(S??{});if(!u.success){this.send({jsonrpc:"2.0",id:y,result:{content:[{type:"text",text:JSON.stringify(K("VALIDATION_ERROR",xy(u.error)),null,2)}],isError:!0}});return}let n=u.data.name,O=u.data.arguments??{};try{let M=await this.executeTool(n,O);this.send({jsonrpc:"2.0",id:y,result:M})}catch(M){this.send({jsonrpc:"2.0",id:y,result:{content:[{type:"text",text:JSON.stringify(K("INTERNAL_ERROR",String(M)),null,2)}],isError:!0}})}}async executeTool(y,S){let u=async()=>{switch(y){case"mem-find":{let n=B.find.parse(S),O=await this.memoryEngine.search(n.query,{limit:n.limit,type:n.types?.[0]});return JSON.stringify(C({results:O}),null,2)}case"mem-history":{let n=B.history.parse(S);return JSON.stringify(C({items:await this.memoryEngine.timeline({limit:n.limit,sessionId:n.sessionId,anchor:n.anchor,depthBefore:n.depthBefore,depthAfter:n.depthAfter})}),null,2)}case"mem-get":{let n=B.get.parse(S);return JSON.stringify(C({observations:await this.memoryEngine.recall(n.ids,n.limit)}),null,2)}case"mem-create":{let n=B.create.parse(S),O=await this.memoryEngine.save({...n,sessionId:"mcp"});return JSON.stringify(O?C({observation:O}):K("CONFLICT","Unable to create memory"),null,2)}case"mem-revise":{let n=B.revise.parse(S),O=await this.memoryEngine.update(n);return JSON.stringify(O?C({previousId:n.id,newId:O.id,observation:O}):K("NOT_FOUND",`Observation ${n.id} not found`),null,2)}case"mem-remove":{let n=B.remove.parse(S),O=await this.memoryEngine.delete([n.id]);return JSON.stringify(O>0?C({id:n.id,tombstoned:!0}):K("NOT_FOUND",`Observation ${n.id} not found`),null,2)}case"mem-export":{let n=B.transferExport.parse(S),O=await this.memoryEngine.export("project",{type:n.type,limit:n.limit});return JSON.stringify(C({payload:O,format:n.format}),null,2)}case"mem-import":{let n=B.transferImport.parse(S),O=n.mode==="replace"?"overwrite":"skip-duplicates",M=await this.memoryEngine.import(n.payload,{mode:O});return JSON.stringify(C({imported:M.imported,skipped:M.skipped,mode:n.mode}),null,2)}case"mem-maintenance":{let n=B.maintenance.parse(S);if(n.action==="folderContextDryRun")return JSON.stringify(C(await this.memoryEngine.maintainFolderContext("clean",!0)),null,2);if(n.action==="folderContextClean")return JSON.stringify(C(await this.memoryEngine.maintainFolderContext("clean",!1)),null,2);if(n.action==="folderContextPurge")return JSON.stringify(C(await this.memoryEngine.maintainFolderContext("purge",!1)),null,2);return JSON.stringify(C(await this.memoryEngine.maintainFolderContext("rebuild",!1)),null,2)}case"mem-help":return JSON.stringify(C({guide:this.memoryEngine.guide()}),null,2);default:return JSON.stringify(K("NOT_FOUND",`Unknown tool: ${y}`),null,2)}};try{let n=await u(),O=n.includes('"error": {')&&!n.includes('"error": null');return{content:[{type:"text",text:n}],isError:O}}catch(n){if(n instanceof z.ZodError)return{content:[{type:"text",text:JSON.stringify(K("VALIDATION_ERROR",xy(n)),null,2)}],isError:!0};return{content:[{type:"text",text:JSON.stringify(K("INTERNAL_ERROR",String(n)),null,2)}],isError:!0}}}send(y){process.stdout.write(`${JSON.stringify(y)}
4
+ `)}}function ky(y){if(typeof y!=="object"||y===null)return!1;let S=y,u=S.status;if(u===429||u===500||u===503)return!0;let n=S.error;if(typeof n==="object"&&n!==null&&n.type==="overloaded_error")return!0;return!1}function I(y){if(y&&typeof y==="object"){let S=y.status;if(typeof S==="number")return S===400||S===401||S===403}return!1}class py{shouldFailover(y){let{error:S,attemptIndex:u,totalProviders:n}=y;if(I(S))return!1;if(u>=n-1)return!1;return ky(S)}onFailover(y){let S=y.error?.status??"unknown";if(!y.nextProvider)return;console.error(`[open-mem] Provider ${y.provider} failed (${S}), falling over to ${y.nextProvider}`)}}class Ey{specificationVersion;provider;modelId;supportedUrls;providers;policy;constructor(y,S=new py){if(y.length===0)throw Error("At least one provider required");let u=y[0].model;this.specificationVersion=u.specificationVersion,this.provider=u.provider,this.modelId=u.modelId,this.supportedUrls=u.supportedUrls,this.providers=y,this.policy=S}async doGenerate(y){let S;for(let u=0;u<this.providers.length;u++){let n=this.providers[u];try{return this.policy.onAttempt?.({error:null,provider:n.name,nextProvider:this.providers[u+1]?.name,attemptIndex:u,totalProviders:this.providers.length}),await n.model.doGenerate(y)}catch(O){if(S=O,I(O))throw O;let M=this.providers[u+1]?.name,f={error:O,provider:n.name,nextProvider:M,attemptIndex:u,totalProviders:this.providers.length};if(this.policy.shouldFailover(f)){this.policy.onFailover(f);continue}throw this.policy.onFinalFailure?.(f),O}}throw S}async doStream(y){let S;for(let u=0;u<this.providers.length;u++){let n=this.providers[u];try{return this.policy.onAttempt?.({error:null,provider:n.name,nextProvider:this.providers[u+1]?.name,attemptIndex:u,totalProviders:this.providers.length}),await n.model.doStream(y)}catch(O){if(S=O,I(O))throw O;let M=this.providers[u+1]?.name,f={error:O,provider:n.name,nextProvider:M,attemptIndex:u,totalProviders:this.providers.length};if(this.policy.shouldFailover(f)){this.policy.onFailover(f);continue}throw this.policy.onFinalFailure?.(f),O}}throw S}}var $u={"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 gu(y){if(y.includes("."))return y;return $u[y]||`us.anthropic.${y}-v1:0`}function Iy(y){switch(y.provider){case"anthropic":{let{createAnthropic:S}=H("@ai-sdk/anthropic");return S({apiKey:y.apiKey})(y.model)}case"bedrock":{let{createAmazonBedrock:S}=H("@ai-sdk/amazon-bedrock");return S()(gu(y.model))}case"openai":{let{createOpenAI:S}=H("@ai-sdk/openai");return S({apiKey:y.apiKey})(y.model)}case"google":{let{createGoogleGenerativeAI:S}=H("@ai-sdk/google");return S({apiKey:y.apiKey})(y.model)}case"openrouter":{let{createOpenRouter:S}=H("@openrouter/ai-sdk-provider");return S({apiKey:y.apiKey})(y.model)}default:throw Error(`Unknown provider: ${y.provider}. Supported: anthropic, bedrock, openai, google, openrouter`)}}function qy(y){try{switch(y.provider){case"google":{let{createGoogleGenerativeAI:S}=H("@ai-sdk/google");return S({apiKey:y.apiKey}).embedding("text-embedding-004")}case"openai":{let{createOpenAI:S}=H("@ai-sdk/openai");return S({apiKey:y.apiKey}).embedding("text-embedding-3-small")}case"bedrock":{let{createAmazonBedrock:S}=H("@ai-sdk/amazon-bedrock");return S().embedding("amazon.titan-embed-text-v2:0")}case"anthropic":return null;case"openrouter":return null;default:return null}}catch{return null}}var Cu={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 Uu(y){switch(y){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 wy(y){if(!y.fallbackProviders||y.fallbackProviders.length===0)return[];return y.fallbackProviders.map((S)=>({provider:S,model:Cu[S]??"gemini-2.5-flash-lite",apiKey:Uu(S)}))}function ly(y,S=[],u){let n=Iy(y);if(S.length===0)return n;let O=[{name:y.provider,model:n},...S.map((M)=>({name:M.provider,model:Iy(M)}))];return new Ey(O,u)}my();import{randomUUID as XS}from"crypto";function hu(y,S){let u=new RegExp(`<${S}[^>]*>([\\s\\S]*?)</${S}>`,"i"),n=y.match(u);return n?n[1].trim():""}function ju(y,S){let u=new RegExp(`<${S}[^>]*>([\\s\\S]*?)</${S}>`,"gi"),n=[];for(let O of y.matchAll(u)){let M=O[1].trim();if(M)n.push(M)}return n}function ty(y){let S=hu(y,"reranked");if(!S)return null;let u=ju(S,"index");if(u.length===0)return null;let n=[];for(let O of u){let M=Number.parseInt(O,10);if(Number.isNaN(M)||M<0)return null;n.push(M)}return n}function Y(y){return Math.ceil(y.length/4)}var vu={showTokenCosts:!0,observationTypes:"all",fullObservationCount:3,showLastSummary:!0},w={bugfix:"\uD83D\uDD34",feature:"\uD83D\uDFE3",refactor:"\uD83D\uDD04",change:"\u2705",discovery:"\uD83D\uDD35",decision:"\u2696\uFE0F"};function oy(y,S=vu){let u=[];if(u.push("## open-mem: Past Session Memory"),u.push(""),u.push("**\uD83D\uDCA1 Progressive Disclosure:** This is a compact index showing WHAT was observed and retrieval COST."),u.push("Use `mem-find` to find observations by query, then `mem-get` with IDs to fetch full details."),u.push(""),u.push("**3-Layer Memory Access:**"),u.push("- **Layer 1** `mem-find` \u2014 Find observations by query (returns IDs + summaries)"),u.push("- **Layer 2** `mem-history` \u2014 Browse session history and drill into sessions"),u.push("- **Layer 3** `mem-get` \u2014 Get full details by ID (use IDs from search results or the index below)"),u.push(""),u.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."),S.showLastSummary&&y.recentSummaries.length>0){u.push(""),u.push("### Recent Sessions"),u.push("| Session | Summary | Decisions |"),u.push("|---------|---------|-----------|");for(let f of y.recentSummaries){let p=f.keyDecisions.length>0?f.keyDecisions.join("; "):"\u2014";u.push(`| ${f.sessionId} | ${f.summary} | ${p} |`)}}let n=S.observationTypes==="all"?y.observationIndex:y.observationIndex.filter((f)=>S.observationTypes.includes(f.type));if(n.length>0){u.push(""),u.push(`### Recent Observations (${n.length} entries)`);let f=ku(n,y.fullObservations);for(let[p,E]of f){if(u.push(""),u.push(`**${p}**`),S.showTokenCosts)u.push("| ID | Type | Title | ~Tokens |"),u.push("|----|------|-------|---------|");else u.push("| ID | Type | Title |"),u.push("|----|------|-------|");for(let R of E){let N=w[R.type]||"\uD83D\uDCDD";if(S.showTokenCosts)u.push(`| ${R.id} | ${N} | ${R.title} | ~${R.tokenCount} |`);else u.push(`| ${R.id} | ${N} | ${R.title} |`)}}}let O=y.fullObservations.slice(0,S.fullObservationCount);if(O.length>0){u.push(""),u.push("### Full Details (most recent)");for(let f of O){let p=w[f.type]||"\uD83D\uDCDD";if(u.push(""),u.push(`#### ${p} ${f.title} (${f.id})`),u.push(f.narrative),f.facts.length>0)u.push(`**Facts:** ${f.facts.map((R)=>`- ${R}`).join(" ")}`);if(f.concepts.length>0)u.push(`**Concepts:** ${f.concepts.join(", ")}`);let E=[...f.filesRead,...f.filesModified];if(E.length>0)u.push(`**Files:** ${E.join(", ")}`)}}let M=xu(y);if(M)u.push(""),u.push(M);return u.join(`
5
+ `)}function xu(y){let S=0,u=0,n=new Set(y.observationIndex.map((f)=>f.id));for(let f of y.observationIndex)S+=f.tokenCount,u+=f.discoveryTokens;for(let f of y.fullObservations)if(!n.has(f.id))S+=f.tokenCount,u+=f.discoveryTokens;if(u===0)return null;let O=u-S,M=Math.max(0,Math.round(O/u*100));return`### \uD83D\uDCB0 Memory Economics
6
+ **Read cost:** ~${S}t | **Discovery cost:** ~${u}t | **Savings:** ${M}% (${O}t saved)`}function ku(y,S){let u=new Map;for(let O of S){let M=O.filesModified[0]||O.filesRead[0];if(M)u.set(O.id,M)}let n=new Map;for(let O of y){let M=u.get(O.id)??"General",f=n.get(M)??[];f.push(O),n.set(M,f)}return n}function dy(y){let S=[];if(S.push("[open-mem] Memory context:"),y.recentSummaries.length>0){S.push(`
7
+ Recent sessions:`);for(let u of y.recentSummaries)S.push(`- ${u.summary}`)}if(y.observationIndex.length>0){S.push(`
8
+ Recent observations (${y.observationIndex.length} entries):`);for(let u of y.observationIndex)S.push(`- ${w[u.type]||"\uD83D\uDCDD"} ${u.title}`)}return S.join(`
9
+ `)}function ay(y,S){if(y.length===0)return"";let u=S,n=[];for(let M of y){let f=M.tokenCount||Y(M.title);if(u-f<0)break;n.push(M),u-=f}if(n.length===0)return"";let O=[];O.push("### Cross-Project Memory"),O.push(""),O.push("| ID | Type | Title | ~Tokens |"),O.push("|----|------|-------|---------|");for(let M of n){let f=w[M.type]||"\uD83D\uDCDD";O.push(`| ${M.id} | ${f} | ${M.title} | ~${M.tokenCount} |`)}return O.join(`
10
+ `)}function sy(y,S){if(y.length===0)return"";let u=S,n=[];for(let M of y){let f=M.tokenCount||Y(M.title);if(u-f<0)break;n.push(M),u-=f}if(n.length===0)return"";let O=[];O.push(`
11
+ Cross-project observations (${n.length} entries):`);for(let M of n)O.push(`- ${w[M.type]||"\uD83D\uDCDD"} ${M.title}`);return O.join(`
12
+ `)}var b={recency:0.4,typeImportance:0.3,sessionAffinity:0.2,tokenEfficiency:0.1},Iu={decision:1,bugfix:0.9,feature:0.8,refactor:0.6,discovery:0.5,change:0.4};function qu(y,S){let u=new Date(y),O=(S.getTime()-u.getTime())/3600000;if(O<0)return 1;if(O<24)return 1;if(O<48)return 0.8;if(O<168)return 0.5;return 0.2}function wu(y){return Iu[y]??0.3}function lu(y,S){if(!S)return 0.5;return y===S?1:0.3}function Pu(y){if(y<=10)return 1;if(y>=200)return 0.2;return 1-(y-10)/190*0.8}function ru(y,S){let u=qu(y.createdAt,S.now),n=wu(y.type),O=lu(y.sessionId,S.currentSessionId),M=Pu(y.tokenCount);return u*b.recency+n*b.typeImportance+O*b.sessionAffinity+M*b.tokenEfficiency}function yS(y,S){let u=new Map;for(let n of y)u.set(n.id,ru(n,S));return[...y].sort((n,O)=>{let M=u.get(n.id)??0,f=u.get(O.id)??0;if(f!==M)return f-M;return new Date(O.createdAt).getTime()-new Date(n.createdAt).getTime()})}function SS(y,S,u,n,O=[],M){let f=n,p=[],E=[];for(let N of S){let V=N.tokenCount||Y(N.summary);if(f-V<0)break;p.push(N),f-=V}let R=M?yS(u,M):u;for(let N of R){let V=N.tokenCount||Y(N.title);if(f-V<0)break;E.push(N),f-=V}return{recentSummaries:p,observationIndex:E,fullObservations:[...O],totalTokens:n-f}}import{existsSync as Cy}from"fs";import{readdir as un,readFile as RS,unlink as gy,writeFile as NS}from"fs/promises";import{join as Uy,resolve as By}from"path";import{existsSync as nS}from"fs";import{mkdir as eu,readFile as iu,rename as bu,unlink as tu,writeFile as ou}from"fs/promises";import{dirname as t,isAbsolute as _y,join as l,normalize as du,relative as Ay,resolve as D,sep as Vy}from"path";var F="<!-- open-mem-context -->",Q="<!-- /open-mem-context -->",OS={bugfix:"\uD83D\uDD34",feature:"\uD83D\uDFE3",refactor:"\uD83D\uDD04",change:"\u2705",discovery:"\uD83D\uDD35",decision:"\u2696\uFE0F"},uS=new Map,au=new Set(["node_modules",".git","dist","coverage",".open-mem","build","__pycache__",".next",".nuxt"]);async function MS(y,S,u){if(S.length===0)return;if(u.mode==="single")return su(y,S,u);let{maxDepth:n,filename:O}=u,M=[];for(let E of S){for(let R of E.filesModified)M.push(R);for(let R of E.filesRead)M.push(R)}let f=pS(M,y,n);if(f.size===0)return;let p=ES(S,f,y);for(let[E,R]of p)try{let N=yn(E,R,y);await fS(E,N,O)}catch(N){console.error(`[open-mem] Failed to update AGENTS.md in ${E}:`,N)}}async function su(y,S,u){let{maxDepth:n,filename:O}=u,M=S.filter(Jy);if(M.length===0)return;let f=[];for(let _ of M){for(let $ of _.filesModified)f.push($);for(let $ of _.filesRead)f.push($)}let p=pS(f,y,n),E=ES(M,p,y),R=M.filter((_)=>{return[..._.filesModified,..._.filesRead].some((U)=>{if(!U)return!1;let c=_y(U)?U:l(y,U);return D(t(c))===D(y)})});if(R.length>0)E.set(D(y),R);if(E.size===0)return;let N=[];N.push("## Project Activity (auto-generated by open-mem)"),N.push("");let V=[...E.entries()].map(([_,$])=>({relPath:Ay(y,_)||".",observations:$})).sort((_,$)=>_.relPath.localeCompare($.relPath));for(let{relPath:_,observations:$}of V){let U=$.filter(Jy).sort((g,x)=>x.createdAt.localeCompare(g.createdAt)).slice(0,10);if(U.length===0)continue;N.push(`### ${_}/`),N.push("| ID | Type | Title | Date |"),N.push("|----|------|-------|------|");for(let g of U){let x=OS[g.type]||"\uD83D\uDCDD",pu=g.createdAt.split("T")[0],Eu=g.title.replace(/\|/g,"\\|");N.push(`| ${g.id} | ${x} ${g.type} | ${Eu} | ${pu} |`)}let c=new Set;for(let g of U)for(let x of g.concepts)c.add(x);if(c.size>0){let g=[...c].slice(0,10).join(", ");N.push(""),N.push(`**Key concepts:** ${g}`)}let X=U.filter((g)=>g.type==="decision").map((g)=>g.title);if(X.length>0)N.push(""),N.push(`**Recent decisions:** ${X.slice(0,5).join("; ")}`);N.push("")}N.push("\uD83D\uDCA1 *Use `mem-find` to search full details. Use `mem-create` to save important decisions.*");let J=N.join(`
13
+ `);await fS(y,J,O)}function Jy(y){return!/^\w[\w-]*\s+execution$/i.test(y.title)}function yn(y,S,u){let n=[...S].filter(Jy).sort((R,N)=>N.createdAt.localeCompare(R.createdAt)).slice(0,10),O=Ay(u,y)||".",M=[];M.push(`## Recent Activity in \`${O}/\` (auto-generated by open-mem)`),M.push(""),M.push("| ID | Type | Title | Date |"),M.push("|----|------|-------|------|");for(let R of n){let N=OS[R.type]||"\uD83D\uDCDD",V=R.createdAt.split("T")[0],J=R.title.replace(/\|/g,"\\|");M.push(`| ${R.id} | ${N} ${R.type} | ${J} | ${V} |`)}let f=new Set;for(let R of n)for(let N of R.concepts)f.add(N);if(f.size>0){let R=[...f].slice(0,10).join(", ");M.push(""),M.push(`**Key concepts:** ${R}`)}let p=n.filter((R)=>R.type==="decision").map((R)=>R.title);if(p.length>0)M.push(""),M.push(`**Recent decisions:** ${p.slice(0,5).join("; ")}`);let E=n.filter((R)=>R.type==="decision"&&R.narrative).slice(0,3);if(E.length>0){M.push(""),M.push("**Decision details:**");for(let R of E){let N=R.narrative.split(/[.!?]\s/)[0],V=N.length>120?`${N.slice(0,117)}...`:N;M.push(`- \u2696\uFE0F ${R.title}: ${V}`)}}return M.push(""),M.push("\uD83D\uDCA1 *Use `mem-find` to search full details across all sessions. Use `mem-create` to save important decisions.*"),M.join(`
14
+ `)}async function fS(y,S,u){if(!nS(y))return;let O=(uS.get(y)??Promise.resolve()).then(async()=>{let M=l(y,u),f=l(y,`.${u}.tmp`),p="";try{p=await iu(M,"utf-8")}catch{}let E=Sn(p,S);try{await eu(t(f),{recursive:!0}),await ou(f,E,"utf-8"),await bu(f,M)}catch(R){try{await tu(f)}catch{}throw R}});return uS.set(y,O.catch(()=>{})),O}function Sn(y,S){if(!y)return`${F}
15
+ ${S}
16
+ ${Q}
17
+ `;let u=y.indexOf(F),n=y.indexOf(Q);if(u!==-1&&n!==-1&&n>u){let M=y.substring(0,u),f=y.substring(n+Q.length);return`${M}${F}
31
18
  ${S}
32
- `}async function Ep(n,p,y=!1){let e=await _n(n,p),S=0;for(let u of e){let m=await mp(u,"utf-8"),r=Op(m);if(r!==m){if(S+=1,!y)if(r==="")await Nn(u);else await rp(u,r,"utf-8")}}if(p){let u=hn(tn(n),p);if(gn(u))try{let m=await mp(u,"utf-8"),r=Op(m);if(r!==m){if(S+=1,!y)if(r==="")await Nn(u);else await rp(u,r,"utf-8")}if(!e.includes(u))e.push(u)}catch{}}return{files:e,changed:S}}async function cp(n,p){let y=await _n(n,p);if(p){let S=hn(tn(n),p);if(gn(S)&&!y.includes(S))y.push(S)}let e=0;for(let S of y)try{await Nn(S),e++}catch{}return{deleted:e,files:y}}async function fp(n,p,y,e,S=!1){let m=p.getAll(n).flatMap((O)=>y.getBySession(O.id));if(S){let O=new Set;for(let M of m)for(let E of[...M.filesRead,...M.filesModified])O.add(E);return{observations:m.length,filesTouched:O.size}}if(!gn(n))return{observations:0,filesTouched:0};await yp(n,m,{maxDepth:e.maxDepth,mode:e.mode,filename:e.filename});let r=await _n(n,e.filename);return{observations:m.length,filesTouched:r.length}}class An{observations;sessions;summaries;searchOrchestrator;projectPath;config;userObservationRepo;runtimeSnapshotProvider;configAuditStore;maintenanceHistoryStore;configAuditLogFallback=[];maintenanceLogFallback=[];constructor(n){this.observations=n.observations,this.sessions=n.sessions,this.summaries=n.summaries,this.searchOrchestrator=n.searchOrchestrator,this.projectPath=n.projectPath,this.config=n.config,this.userObservationRepo=n.userObservationRepo??null,this.runtimeSnapshotProvider=n.runtimeSnapshotProvider??null,this.configAuditStore=n.configAuditStore??null,this.maintenanceHistoryStore=n.maintenanceHistoryStore??null}getByIdIncludingArchived(n){let p=this.observations;return p.getByIdIncludingArchived?p.getByIdIncludingArchived(n):this.observations.getById(n)}listByProjectWithState(n){let p=this.observations;if(p.listByProject)return p.listByProject(this.projectPath,n);if(n.state!=="current")return[];return this.listObservations({limit:n.limit,offset:n.offset,type:n.type,sessionId:n.sessionId})}async ingest(n){}async processPending(n){return 0}async search(n,p={}){return this.searchOrchestrator.search(n,{type:p.type,limit:p.limit??10,projectPath:this.projectPath,importanceMin:p.importanceMin,importanceMax:p.importanceMax,createdAfter:p.after,createdBefore:p.before,concepts:p.concepts,files:p.files})}async timeline(n={}){if(n.anchor){let y=this.observations.getById(n.anchor);if(!y)return[];let e=n.depthBefore??5,S=n.depthAfter??5,u=this.observations.getAroundTimestamp(y.createdAt,e,S,this.projectPath),m=[...u.filter((O)=>O.createdAt<y.createdAt),y,...u.filter((O)=>O.createdAt>y.createdAt)];return[{session:this.sessions.getById(y.sessionId)??{id:y.sessionId,projectPath:this.projectPath,startedAt:y.createdAt,endedAt:null,status:"completed",observationCount:0,summaryId:null},summary:null,observations:m}]}if(n.sessionId){let y=this.sessions.getById(n.sessionId);if(!y)return[];return[{session:y,summary:this.summaries.getBySessionId(y.id),observations:this.observations.getBySession(y.id)}]}return this.sessions.getRecent(this.projectPath,n.limit??5).map((y)=>({session:y,summary:this.summaries.getBySessionId(y.id),observations:[]}))}async recall(n,p=10){let y=[];for(let e of n.slice(0,p)){let S=this.observations.getById(e);if(S){y.push(S);continue}if(!this.userObservationRepo)continue;let u=this.userObservationRepo.getById(e);if(!u)continue;y.push({...u,sessionId:"",rawToolOutput:"",discoveryTokens:0})}return y}async save(n){if(n.scope==="user"){if(!this.userObservationRepo)return null;return{...this.userObservationRepo.create({type:n.type,title:n.title,subtitle:"",facts:[],narrative:n.narrative,concepts:n.concepts??[],filesRead:[],filesModified:n.files??[],toolName:"mem-create",tokenCount:U(`${n.title} ${n.narrative}`),importance:n.importance??3,sourceProject:this.projectPath}),sessionId:"",rawToolOutput:"",discoveryTokens:0}}this.sessions.getOrCreate(n.sessionId,this.projectPath);let p=this.observations.create({sessionId:n.sessionId,type:n.type,title:n.title,subtitle:"",facts:[],narrative:n.narrative,concepts:n.concepts??[],filesRead:[],filesModified:n.files??[],rawToolOutput:`[Manual save] ${n.narrative}`,toolName:"mem-create",tokenCount:U(`${n.title} ${n.narrative}`),discoveryTokens:0,importance:n.importance??3});return this.sessions.incrementObservationCount(n.sessionId),p}async update(n){let p=this.observations.getById(n.id);if(!p)return null;let y=this.sessions.getById(p.sessionId);if(!y||y.projectPath!==this.projectPath)return null;let{id:e,...S}=n;return this.observations.update(n.id,S)??null}async delete(n){let p=0;for(let y of n){let e=this.observations.getById(y);if(!e)continue;let S=this.sessions.getById(e.sessionId);if(!S||S.projectPath!==this.projectPath)continue;if(this.observations.delete(y))p+=1}return p}async export(n,p={}){if(n!=="project")throw Error("Only project scope export is supported.");let y=this.sessions.getAll(this.projectPath),e=[];for(let r of y)e.push(...this.observations.getBySession(r.id));if(p.type)e=e.filter((r)=>r.type===p.type);if(e.sort((r,O)=>new Date(r.createdAt).getTime()-new Date(O.createdAt).getTime()),p.limit&&p.limit<e.length)e=e.slice(0,p.limit);let S=e.map(({rawToolOutput:r,...O})=>O),u=y.map((r)=>this.summaries.getBySessionId(r.id)).filter((r)=>r!==null);return{version:1,exportedAt:new Date().toISOString(),project:this.projectPath,observations:S,summaries:u}}async import(n,p={}){let y;try{y=JSON.parse(n)}catch{throw Error("Invalid JSON payload.")}if(typeof y!=="object"||y===null)throw Error("Invalid import payload.");let e=y;if(e.version!==1||!Array.isArray(e.observations))throw Error("Unsupported export format.");let S=p.mode??"skip-duplicates",u=0,m=0;for(let r of e.observations){let O=this.observations.getById(r.id);if(O&&S==="skip-duplicates"){m+=1;continue}if(O&&S==="overwrite")this.observations.delete(r.id);this.sessions.getOrCreate(r.sessionId,this.projectPath),this.observations.importObservation({id:r.id,sessionId:r.sessionId,type:r.type,title:r.title,subtitle:r.subtitle??"",facts:r.facts??[],narrative:r.narrative??"",concepts:r.concepts??[],filesRead:r.filesRead??[],filesModified:r.filesModified??[],rawToolOutput:r.rawToolOutput??"",toolName:r.toolName??"unknown",createdAt:r.createdAt,tokenCount:r.tokenCount??0,discoveryTokens:r.discoveryTokens??0,importance:r.importance??3,supersededBy:r.supersededBy??null,supersededAt:r.supersededAt??null}),this.sessions.incrementObservationCount(r.sessionId),u+=1}for(let r of e.summaries??[]){let O=this.summaries.getBySessionId(r.sessionId);if(O&&S==="skip-duplicates")continue;if(O&&S==="overwrite")continue;this.sessions.getOrCreate(r.sessionId,this.projectPath),this.summaries.importSummary(r),this.sessions.setSummary(r.sessionId,r.id)}return{imported:u,skipped:m}}async buildContext(n,p="normal"){let y=this.sessions.getRecent(this.projectPath,5),e=y.map((E)=>E.summaryId?this.summaries.getBySessionId(E.id):null).filter((E)=>E!==null),S=this.observations.getIndex(this.projectPath,this.config.maxObservations),m=S.slice(0,this.config.contextFullObservationCount).map((E)=>E.id).map((E)=>this.observations.getById(E)).filter((E)=>E!==null),r=dn(y,e,S,this.config.maxContextTokens,m);if(p==="compaction"){let E=wn(r);if(this.config.userMemoryEnabled&&this.userObservationRepo)E+=on(this.userObservationRepo.getIndex(this.config.maxObservations),this.config.userMemoryMaxContextTokens);return E}let O={showTokenCosts:this.config.contextShowTokenCosts,observationTypes:this.config.contextObservationTypes,fullObservationCount:this.config.contextFullObservationCount,showLastSummary:this.config.contextShowLastSummary},M=qn(r,O);if(this.config.userMemoryEnabled&&this.userObservationRepo){let E=bn(this.userObservationRepo.getIndex(this.config.maxObservations),this.config.userMemoryMaxContextTokens);if(E)M+=`
19
+ ${Q}${f}`}let O=y;if(u!==-1&&n===-1)O=O.replace(F,"").trim();else if(u===-1&&n!==-1)O=O.replace(Q,"").trim();else if(u!==-1&&n!==-1&&n<=u)O=O.replace(Q,"").replace(F,"").trim();return`${O}
33
20
 
34
- ${E}`}return M}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(n){let{limit:p=50,offset:y=0,type:e,sessionId:S,state:u}=n;if(u)return this.listByProjectWithState({limit:p,offset:y,type:e,state:u,sessionId:S});if(S){let O=this.observations.getBySession(S);if(e)O=O.filter((M)=>M.type===e);return O.slice(y,y+p)}let r=this.observations.getIndex(this.projectPath,y+p).slice(y);if(e)r=r.filter((O)=>O.type===e);return r.map((O)=>this.observations.getById(O.id)).filter((O)=>O!==null)}getObservation(n){return this.observations.getById(n)}getLineage(n){let y=this.getByIdIncludingArchived(n);if(!y)return null;let e=y,S=0,u=new Set([y.id]);while(e.revisionOf&&S<256){let E=this.getByIdIncludingArchived(e.revisionOf);if(!E||u.has(E.id))break;e=E,u.add(E.id),S+=1}let m=[],r=e,O=new Set,M=0;while(r&&!O.has(r.id)&&M<256){O.add(r.id);let E=r.deletedAt?"tombstoned":r.supersededBy?"superseded":"current";m.push({id:r.id,revisionOf:r.revisionOf??null,supersededBy:r.supersededBy??null,supersededAt:r.supersededAt??null,deletedAt:r.deletedAt??null,state:E,observation:r}),r=r.supersededBy?this.getByIdIncludingArchived(r.supersededBy):null,M+=1}return m}listSessions(n){return this.sessions.getRecent(n.projectPath??this.projectPath,n.limit??20)}getSession(n){let p=this.sessions.getById(n);if(!p)return null;return{session:p,summary:this.summaries.getBySessionId(n),observations:this.observations.getBySession(n)}}stats(){let n=this.observations.getCount(),y=this.sessions.getAll(this.projectPath).length,e=this.observations.getIndex(this.projectPath,1e4),S=0,u=0,m={};for(let M of e)S+=M.tokenCount,u+=M.discoveryTokens,m[M.type]=(m[M.type]||0)+1;let r=u-S,O=e.length>0?Math.round(S/e.length):0;return{totalObservations:n,totalSessions:y,totalTokensSaved:r,averageObservationSize:O,typeBreakdown:m}}async maintainFolderContext(n,p){if(n==="purge")return{action:"purge",dryRun:!1,...await cp(this.projectPath,this.config.folderContextFilename)};if(n==="rebuild"){let e=await fp(this.projectPath,this.sessions,this.observations,{maxDepth:this.config.folderContextMaxDepth,mode:this.config.folderContextMode,filename:this.config.folderContextFilename},p);return{action:n,dryRun:p,...e}}let y=await Ep(this.projectPath,this.config.folderContextFilename,p);return{action:"clean",dryRun:p,...y}}getRevisionDiff(n,p){let y=this.getByIdIncludingArchived(n),e=this.getByIdIncludingArchived(p);if(!y||!e)return null;let S=[],u=(r,O,M)=>{if(JSON.stringify(O)!==JSON.stringify(M))S.push({field:r,before:O,after:M})};u("title",e.title,y.title),u("subtitle",e.subtitle,y.subtitle),u("narrative",e.narrative,y.narrative),u("type",e.type,y.type),u("facts",e.facts,y.facts),u("concepts",e.concepts,y.concepts),u("filesRead",e.filesRead,y.filesRead),u("filesModified",e.filesModified,y.filesModified),u("importance",e.importance,y.importance);let m=S.length===0?"No material changes between revisions.":`Changed ${S.length} field${S.length===1?"":"s"}: ${S.map((r)=>r.field).join(", ")}.`;return{fromId:p,toId:n,summary:m,changedFields:S}}getHealth(){let n=this.runtimeSnapshotProvider?.(),p=n?.queue.lastError?"degraded":"ok";return{status:n?.status??"ok",timestamp:n?.timestamp??new Date().toISOString(),components:{database:{status:"ok"},search:{status:"ok"},config:{status:"ok"},queue:{status:p,detail:n?.queue.lastError??void 0}}}}getMetrics(){let n=this.stats();return{timestamp:this.runtimeSnapshotProvider?.()?.timestamp??new Date().toISOString(),memory:{totalObservations:n.totalObservations,totalSessions:n.totalSessions,totalTokensSaved:n.totalTokensSaved,averageObservationSize:n.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 n={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((y)=>({name:y.name,version:y.version,enabled:n[y.name]??!1,capabilities:y.capabilities}))}getConfigAuditTimeline(){if(this.configAuditStore)return this.configAuditStore.list();return[...this.configAuditLogFallback].reverse()}trackConfigAudit(n){if(this.configAuditStore){this.configAuditStore.append(n);return}this.configAuditLogFallback.push(n)}async rollbackConfig(n){let p=this.configAuditStore?this.configAuditStore.getById(n):this.configAuditLogFallback.find((u)=>u.id===n)??null;if(!p)return null;if(!p.previousValues||typeof p.previousValues!=="object")return null;let{patchConfig:y}=await Promise.resolve().then(() => (_p(),tp)),e=p.previousValues;try{await y(this.projectPath,e)}catch(u){let m={id:`rollback-failed-${Vp()}`,timestamp:new Date().toISOString(),patch:p.previousValues,previousValues:p.patch,source:"rollback-failed"};throw this.trackConfigAudit(m),u}let S={id:`rollback-${Vp()}`,timestamp:new Date().toISOString(),patch:p.previousValues,previousValues:p.patch,source:"rollback"};return this.trackConfigAudit(S),S}getMaintenanceHistory(){if(this.maintenanceHistoryStore)return this.maintenanceHistoryStore.list();return[...this.maintenanceLogFallback].reverse()}trackMaintenanceResult(n){if(this.maintenanceHistoryStore){this.maintenanceHistoryStore.append(n);return}this.maintenanceLogFallback.push(n)}}function o(n){try{let p=JSON.parse(n);return p&&typeof p==="object"?p:{}}catch{return{}}}class Jn{db;constructor(n){this.db=n}list(){return this.db.all("SELECT id, timestamp, patch, previous_values, source FROM config_audit_events ORDER BY timestamp DESC").map((n)=>({id:n.id,timestamp:n.timestamp,patch:o(n.patch),previousValues:o(n.previous_values),source:n.source}))}getById(n){let p=this.db.get("SELECT id, timestamp, patch, previous_values, source FROM config_audit_events WHERE id = ?",[n]);if(!p)return null;return{id:p.id,timestamp:p.timestamp,patch:o(p.patch),previousValues:o(p.previous_values),source:p.source}}append(n){this.db.run("INSERT INTO config_audit_events (id, timestamp, patch, previous_values, source) VALUES (?, ?, ?, ?, ?)",[n.id,n.timestamp,JSON.stringify(n.patch??{}),JSON.stringify(n.previousValues??{}),n.source])}}import{Database as Ap}from"bun:sqlite";import{existsSync as Cn,mkdirSync as ee,unlinkSync as Jp}from"fs";import*as Cp from"sqlite-vec";class a{db;dbPath;_hasVectorExtension=!1;static enableExtensionSupport(){let n=["/opt/homebrew/opt/sqlite/lib/libsqlite3.dylib","/usr/local/opt/sqlite/lib/libsqlite3.dylib"];for(let p of n)try{if(Cn(p))return Ap.setCustomSQLite(p),!0}catch{return!1}return!1}constructor(n){this.dbPath=n,this.db=this.open(n),this.configure()}open(n){let p=n.lastIndexOf("/");if(p>0){let y=n.substring(0,p);ee(y,{recursive:!0})}return new Ap(n,{create:!0})}configure(){try{this.applyPragmas(),this.loadExtensions()}catch(n){console.warn("[open-mem] Database configure failed, attempting recovery by removing WAL/SHM files:",n.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(p){console.warn("[open-mem] WAL/SHM cleanup insufficient, recreating database from scratch:",p.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(y){throw console.warn("[open-mem] All recovery attempts failed, filesystem may be broken:",y.message),n}}}}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{Cp.load(this.db),this._hasVectorExtension=!0}catch{this._hasVectorExtension=!1}}get hasVectorExtension(){return this._hasVectorExtension}deleteSidecarFiles(){for(let n of["-wal","-shm"]){let p=this.dbPath+n;try{if(Cn(p))Jp(p)}catch{}}}deleteDatabaseFiles(){this.deleteSidecarFiles();try{if(Cn(this.dbPath))Jp(this.dbPath)}catch{}}ensureMigrationTable(){this.db.exec(`
21
+ ${F}
22
+ ${S}
23
+ ${Q}
24
+ `}function pS(y,S,u){let n=new Set,O=D(S);for(let M of y){if(!M||!M.trim())continue;if(M.startsWith("~")||M.startsWith("http"))continue;let f=_y(M)?M:l(S,M),p=t(f),E=D(p);if(!E.startsWith(O+Vy)&&E!==O)continue;if(E===O)continue;let R=Ay(O,E);if(R.split(Vy).length>u)continue;if(du(R).split(Vy).some((J)=>au.has(J)))continue;if(!nS(E))continue;n.add(E)}return n}function ES(y,S,u){let n=new Map;for(let O of y){let M=[...O.filesModified,...O.filesRead],f=new Set;for(let p of M){if(!p)continue;let E=_y(p)?p:l(u,p),R=D(t(E));if(S.has(R))f.add(R)}for(let p of f){let E=n.get(p)??[];E.push(O),n.set(p,E)}}return n}var $y="<!-- open-mem-context -->",o="<!-- /open-mem-context -->";async function VS(y,S,u){let n;try{n=await un(y,{withFileTypes:!0,encoding:"utf8"})}catch{return}for(let O of n){let M=String(O.name);if(M===".git"||M==="node_modules"||M===".open-mem"||M==="dist")continue;let f=Uy(y,M);if(O.isDirectory())await VS(f,S,u);else if(O.isFile()&&M===S)u.push(f)}}async function Zy(y,S){let u=By(y),n=[];return await VS(u,S,n),n}function mS(y){let S=y.indexOf($y),u=y.indexOf(o);if(S===-1&&u===-1)return y;if(S!==-1&&u===-1){let M=y.replace($y,"").trim();return M?`${M}
25
+ `:""}if(S===-1&&u!==-1){let M=y.replace(o,"").trim();return M?`${M}
26
+ `:""}if(u<=S){let M=y.replace($y,"").replace(o,"").trim();return M?`${M}
27
+ `:""}let n=y.slice(0,S).trimEnd(),O=y.slice(u+o.length).trimStart();if(!n&&!O)return"";if(!n)return`${O}
28
+ `;if(!O)return`${n}
29
+ `;return`${n}
30
+
31
+ ${O}
32
+ `}async function JS(y,S,u=!1){let n=await Zy(y,S),O=0;for(let M of n){let f=await RS(M,"utf-8"),p=mS(f);if(p!==f){if(O+=1,!u)if(p==="")await gy(M);else await NS(M,p,"utf-8")}}if(S){let M=Uy(By(y),S);if(Cy(M))try{let f=await RS(M,"utf-8"),p=mS(f);if(p!==f){if(O+=1,!u)if(p==="")await gy(M);else await NS(M,p,"utf-8")}if(!n.includes(M))n.push(M)}catch{}}return{files:n,changed:O}}async function _S(y,S){let u=await Zy(y,S);if(S){let O=Uy(By(y),S);if(Cy(O)&&!u.includes(O))u.push(O)}let n=0;for(let O of u)try{await gy(O),n++}catch{}return{deleted:n,files:u}}async function AS(y,S,u,n,O=!1){let f=S.getAll(y).flatMap((E)=>u.getBySession(E.id));if(O){let E=new Set;for(let R of f)for(let N of[...R.filesRead,...R.filesModified])E.add(N);return{observations:f.length,filesTouched:E.size}}if(!Cy(y))return{observations:0,filesTouched:0};await MS(y,f,{maxDepth:n.maxDepth,mode:n.mode,filename:n.filename});let p=await Zy(y,n.filename);return{observations:f.length,filesTouched:p.length}}class Hy{observations;sessions;summaries;searchOrchestrator;projectPath;config;userObservationRepo;runtimeSnapshotProvider;configAuditStore;maintenanceHistoryStore;configAuditLogFallback=[];maintenanceLogFallback=[];constructor(y){this.observations=y.observations,this.sessions=y.sessions,this.summaries=y.summaries,this.searchOrchestrator=y.searchOrchestrator,this.projectPath=y.projectPath,this.config=y.config,this.userObservationRepo=y.userObservationRepo??null,this.runtimeSnapshotProvider=y.runtimeSnapshotProvider??null,this.configAuditStore=y.configAuditStore??null,this.maintenanceHistoryStore=y.maintenanceHistoryStore??null}getByIdIncludingArchived(y){let S=this.observations;return S.getByIdIncludingArchived?S.getByIdIncludingArchived(y):this.observations.getById(y)}listByProjectWithState(y){let S=this.observations;if(S.listByProject)return S.listByProject(this.projectPath,y);if(y.state!=="current")return[];return this.listObservations({limit:y.limit,offset:y.offset,type:y.type,sessionId:y.sessionId})}async ingest(y){}async processPending(y){return 0}async search(y,S={}){return this.searchOrchestrator.search(y,{type:S.type,limit:S.limit??10,projectPath:this.projectPath,importanceMin:S.importanceMin,importanceMax:S.importanceMax,createdAfter:S.after,createdBefore:S.before,concepts:S.concepts,files:S.files})}async timeline(y={}){if(y.anchor){let u=this.observations.getById(y.anchor);if(!u)return[];let n=y.depthBefore??5,O=y.depthAfter??5,M=this.observations.getAroundTimestamp(u.createdAt,n,O,this.projectPath),f=[...M.filter((E)=>E.createdAt<u.createdAt),u,...M.filter((E)=>E.createdAt>u.createdAt)];return[{session:this.sessions.getById(u.sessionId)??{id:u.sessionId,projectPath:this.projectPath,startedAt:u.createdAt,endedAt:null,status:"completed",observationCount:0,summaryId:null},summary:null,observations:f}]}if(y.sessionId){let u=this.sessions.getById(y.sessionId);if(!u)return[];return[{session:u,summary:this.summaries.getBySessionId(u.id),observations:this.observations.getBySession(u.id)}]}return this.sessions.getRecent(this.projectPath,y.limit??5).map((u)=>({session:u,summary:this.summaries.getBySessionId(u.id),observations:[]}))}async recall(y,S=10){let u=[];for(let n of y.slice(0,S)){let O=this.observations.getById(n);if(O){u.push(O);continue}if(!this.userObservationRepo)continue;let M=this.userObservationRepo.getById(n);if(!M)continue;u.push({...M,sessionId:"",rawToolOutput:"",discoveryTokens:0})}return u}async save(y){if(y.scope==="user"){if(!this.userObservationRepo)return null;return{...this.userObservationRepo.create({type:y.type,title:y.title,subtitle:"",facts:[],narrative:y.narrative,concepts:y.concepts??[],filesRead:[],filesModified:y.files??[],toolName:"mem-create",tokenCount:Y(`${y.title} ${y.narrative}`),importance:y.importance??3,sourceProject:this.projectPath}),sessionId:"",rawToolOutput:"",discoveryTokens:0}}this.sessions.getOrCreate(y.sessionId,this.projectPath);let S=this.observations.create({sessionId:y.sessionId,type:y.type,title:y.title,subtitle:"",facts:[],narrative:y.narrative,concepts:y.concepts??[],filesRead:[],filesModified:y.files??[],rawToolOutput:`[Manual save] ${y.narrative}`,toolName:"mem-create",tokenCount:Y(`${y.title} ${y.narrative}`),discoveryTokens:0,importance:y.importance??3});return this.sessions.incrementObservationCount(y.sessionId),S}async update(y){let S=this.observations.getById(y.id);if(!S)return null;let u=this.sessions.getById(S.sessionId);if(!u||u.projectPath!==this.projectPath)return null;let{id:n,...O}=y;return this.observations.update(y.id,O)??null}async delete(y){let S=0;for(let u of y){let n=this.observations.getById(u);if(!n)continue;let O=this.sessions.getById(n.sessionId);if(!O||O.projectPath!==this.projectPath)continue;if(this.observations.delete(u))S+=1}return S}async export(y,S={}){if(y!=="project")throw Error("Only project scope export is supported.");let u=this.sessions.getAll(this.projectPath),n=[];for(let p of u)n.push(...this.observations.getBySession(p.id));if(S.type)n=n.filter((p)=>p.type===S.type);if(n.sort((p,E)=>new Date(p.createdAt).getTime()-new Date(E.createdAt).getTime()),S.limit&&S.limit<n.length)n=n.slice(0,S.limit);let O=n.map(({rawToolOutput:p,...E})=>E),M=u.map((p)=>this.summaries.getBySessionId(p.id)).filter((p)=>p!==null);return{version:1,exportedAt:new Date().toISOString(),project:this.projectPath,observations:O,summaries:M}}async import(y,S={}){let u;try{u=JSON.parse(y)}catch{throw Error("Invalid JSON payload.")}if(typeof u!=="object"||u===null)throw Error("Invalid import payload.");let n=u;if(n.version!==1||!Array.isArray(n.observations))throw Error("Unsupported export format.");let O=S.mode??"skip-duplicates",M=0,f=0;for(let p of n.observations){let E=this.observations.getById(p.id);if(E&&O==="skip-duplicates"){f+=1;continue}if(E&&O==="overwrite")this.observations.delete(p.id);this.sessions.getOrCreate(p.sessionId,this.projectPath),this.observations.importObservation({id:p.id,sessionId:p.sessionId,type:p.type,title:p.title,subtitle:p.subtitle??"",facts:p.facts??[],narrative:p.narrative??"",concepts:p.concepts??[],filesRead:p.filesRead??[],filesModified:p.filesModified??[],rawToolOutput:p.rawToolOutput??"",toolName:p.toolName??"unknown",createdAt:p.createdAt,tokenCount:p.tokenCount??0,discoveryTokens:p.discoveryTokens??0,importance:p.importance??3,supersededBy:p.supersededBy??null,supersededAt:p.supersededAt??null}),this.sessions.incrementObservationCount(p.sessionId),M+=1}for(let p of n.summaries??[]){let E=this.summaries.getBySessionId(p.sessionId);if(E&&O==="skip-duplicates")continue;if(E&&O==="overwrite")continue;this.sessions.getOrCreate(p.sessionId,this.projectPath),this.summaries.importSummary(p),this.sessions.setSummary(p.sessionId,p.id)}return{imported:M,skipped:f}}async buildContext(y,S="normal"){let u=this.sessions.getRecent(this.projectPath,5),n=u.map((N)=>N.summaryId?this.summaries.getBySessionId(N.id):null).filter((N)=>N!==null),O=this.observations.getIndex(this.projectPath,this.config.maxObservations),f=O.slice(0,this.config.contextFullObservationCount).map((N)=>N.id).map((N)=>this.observations.getById(N)).filter((N)=>N!==null),p=SS(u,n,O,this.config.maxContextTokens,f);if(S==="compaction"){let N=dy(p);if(this.config.userMemoryEnabled&&this.userObservationRepo)N+=sy(this.userObservationRepo.getIndex(this.config.maxObservations),this.config.userMemoryMaxContextTokens);return N}let E={showTokenCosts:this.config.contextShowTokenCosts,observationTypes:this.config.contextObservationTypes,fullObservationCount:this.config.contextFullObservationCount,showLastSummary:this.config.contextShowLastSummary},R=oy(p,E);if(this.config.userMemoryEnabled&&this.userObservationRepo){let N=ay(this.userObservationRepo.getIndex(this.config.maxObservations),this.config.userMemoryMaxContextTokens);if(N)R+=`
33
+
34
+ ${N}`}return R}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(y){let{limit:S=50,offset:u=0,type:n,sessionId:O,state:M}=y;if(M)return this.listByProjectWithState({limit:S,offset:u,type:n,state:M,sessionId:O});if(O){let E=this.observations.getBySession(O);if(n)E=E.filter((R)=>R.type===n);return E.slice(u,u+S)}let p=this.observations.getIndex(this.projectPath,u+S).slice(u);if(n)p=p.filter((E)=>E.type===n);return p.map((E)=>this.observations.getById(E.id)).filter((E)=>E!==null)}getObservation(y){return this.observations.getById(y)}getLineage(y){let u=this.getByIdIncludingArchived(y);if(!u)return null;let n=u,O=0,M=new Set([u.id]);while(n.revisionOf&&O<256){let N=this.getByIdIncludingArchived(n.revisionOf);if(!N||M.has(N.id))break;n=N,M.add(N.id),O+=1}let f=[],p=n,E=new Set,R=0;while(p&&!E.has(p.id)&&R<256){E.add(p.id);let N=p.deletedAt?"tombstoned":p.supersededBy?"superseded":"current";f.push({id:p.id,revisionOf:p.revisionOf??null,supersededBy:p.supersededBy??null,supersededAt:p.supersededAt??null,deletedAt:p.deletedAt??null,state:N,observation:p}),p=p.supersededBy?this.getByIdIncludingArchived(p.supersededBy):null,R+=1}return f}listSessions(y){return this.sessions.getRecent(y.projectPath??this.projectPath,y.limit??20)}getSession(y){let S=this.sessions.getById(y);if(!S)return null;return{session:S,summary:this.summaries.getBySessionId(y),observations:this.observations.getBySession(y)}}stats(){let y=this.observations.getCount(),u=this.sessions.getAll(this.projectPath).length,n=this.observations.getIndex(this.projectPath,1e4),O=0,M=0,f={};for(let R of n)O+=R.tokenCount,M+=R.discoveryTokens,f[R.type]=(f[R.type]||0)+1;let p=M-O,E=n.length>0?Math.round(O/n.length):0;return{totalObservations:y,totalSessions:u,totalTokensSaved:p,averageObservationSize:E,typeBreakdown:f}}async maintainFolderContext(y,S){if(y==="purge")return{action:"purge",dryRun:!1,...await _S(this.projectPath,this.config.folderContextFilename)};if(y==="rebuild"){let n=await AS(this.projectPath,this.sessions,this.observations,{maxDepth:this.config.folderContextMaxDepth,mode:this.config.folderContextMode,filename:this.config.folderContextFilename},S);return{action:y,dryRun:S,...n}}let u=await JS(this.projectPath,this.config.folderContextFilename,S);return{action:"clean",dryRun:S,...u}}getRevisionDiff(y,S){let u=this.getByIdIncludingArchived(y),n=this.getByIdIncludingArchived(S);if(!u||!n)return null;let O=[],M=(p,E,R)=>{if(JSON.stringify(E)!==JSON.stringify(R))O.push({field:p,before:E,after:R})};M("title",n.title,u.title),M("subtitle",n.subtitle,u.subtitle),M("narrative",n.narrative,u.narrative),M("type",n.type,u.type),M("facts",n.facts,u.facts),M("concepts",n.concepts,u.concepts),M("filesRead",n.filesRead,u.filesRead),M("filesModified",n.filesModified,u.filesModified),M("importance",n.importance,u.importance);let f=O.length===0?"No material changes between revisions.":`Changed ${O.length} field${O.length===1?"":"s"}: ${O.map((p)=>p.field).join(", ")}.`;return{fromId:S,toId:y,summary:f,changedFields:O}}getHealth(){let y=this.runtimeSnapshotProvider?.(),S=y?.queue.lastError?"degraded":"ok";return{status:y?.status??"ok",timestamp:y?.timestamp??new Date().toISOString(),components:{database:{status:"ok"},search:{status:"ok"},config:{status:"ok"},queue:{status:S,detail:y?.queue.lastError??void 0}}}}getMetrics(){let y=this.stats();return{timestamp:this.runtimeSnapshotProvider?.()?.timestamp??new Date().toISOString(),memory:{totalObservations:y.totalObservations,totalSessions:y.totalSessions,totalTokensSaved:y.totalTokensSaved,averageObservationSize:y.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 y={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((u)=>({name:u.name,version:u.version,enabled:y[u.name]??!1,capabilities:u.capabilities}))}getConfigAuditTimeline(){if(this.configAuditStore)return this.configAuditStore.list();return[...this.configAuditLogFallback].reverse()}trackConfigAudit(y){if(this.configAuditStore){this.configAuditStore.append(y);return}this.configAuditLogFallback.push(y)}async rollbackConfig(y){let S=this.configAuditStore?this.configAuditStore.getById(y):this.configAuditLogFallback.find((M)=>M.id===y)??null;if(!S)return null;if(!S.previousValues||typeof S.previousValues!=="object")return null;let{patchConfig:u}=await Promise.resolve().then(() => (ZS(),BS)),n=S.previousValues;try{await u(this.projectPath,n)}catch(M){let f={id:`rollback-failed-${XS()}`,timestamp:new Date().toISOString(),patch:S.previousValues,previousValues:S.patch,source:"rollback-failed"};throw this.trackConfigAudit(f),M}let O={id:`rollback-${XS()}`,timestamp:new Date().toISOString(),patch:S.previousValues,previousValues:S.patch,source:"rollback"};return this.trackConfigAudit(O),O}getMaintenanceHistory(){if(this.maintenanceHistoryStore)return this.maintenanceHistoryStore.list();return[...this.maintenanceLogFallback].reverse()}trackMaintenanceResult(y){if(this.maintenanceHistoryStore){this.maintenanceHistoryStore.append(y);return}this.maintenanceLogFallback.push(y)}}function a(y){try{let S=JSON.parse(y);return S&&typeof S==="object"?S:{}}catch{return{}}}class Ky{db;constructor(y){this.db=y}list(){return this.db.all("SELECT id, timestamp, patch, previous_values, source FROM config_audit_events ORDER BY timestamp DESC").map((y)=>({id:y.id,timestamp:y.timestamp,patch:a(y.patch),previousValues:a(y.previous_values),source:y.source}))}getById(y){let S=this.db.get("SELECT id, timestamp, patch, previous_values, source FROM config_audit_events WHERE id = ?",[y]);if(!S)return null;return{id:S.id,timestamp:S.timestamp,patch:a(S.patch),previousValues:a(S.previous_values),source:S.source}}append(y){this.db.run("INSERT INTO config_audit_events (id, timestamp, patch, previous_values, source) VALUES (?, ?, ?, ?, ?)",[y.id,y.timestamp,JSON.stringify(y.patch??{}),JSON.stringify(y.previousValues??{}),y.source])}}import{Database as FS}from"bun:sqlite";import{existsSync as Yn,mkdirSync as cn}from"fs";import*as GS from"sqlite-vec";import{closeSync as _n,fsyncSync as An,openSync as $n,readFileSync as gn,unlinkSync as YS,writeFileSync as Cn}from"fs";import{hostname as cS}from"os";function HS(y){try{return process.kill(y,0),!0}catch(S){if(S instanceof Error&&"code"in S&&S.code==="EPERM")return!0;return!1}}var zS="plugin";class s extends Error{lockPath;role;waitDurationMs;owner;constructor(y){super(`Timed out acquiring advisory write lock after ${y.waitDurationMs}ms (role=${y.role}, lockPath=${y.lockPath})`);this.name="AdvisoryLockTimeoutError",this.lockPath=y.lockPath,this.role=y.role,this.waitDurationMs=y.waitDurationMs,this.owner=y.owner}}var Un=5000,Bn=50,G=new Map;function Zn(y){if(y<=0)return;Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,y)}function KS(y,S){if(typeof y!=="number"||!Number.isFinite(y)||y<=0)return S;return Math.floor(y)}function WS(y){try{let S=gn(y,"utf8").trim();if(!S)return null;let u=JSON.parse(S);if(typeof u!=="object"||u===null||typeof u.pid!=="number"||typeof u.role!=="string"||typeof u.hostname!=="string"||typeof u.acquiredAt!=="string")return null;return{pid:u.pid,role:u.role,hostname:u.hostname,acquiredAt:u.acquiredAt,ownerId:typeof u.ownerId==="string"?u.ownerId:void 0}}catch{return null}}function Xn(y,S){if(!y||!S)return!1;return y.pid===S.pid&&y.role===S.role&&y.hostname===S.hostname&&y.acquiredAt===S.acquiredAt&&y.ownerId===S.ownerId}function Hn(y,S){if(!S)return!1;if(S.hostname!==cS())return!1;if(HS(S.pid))return!1;let u=WS(y);if(!Xn(u,S))return!1;try{return YS(y),!0}catch(n){if(n.code==="ENOENT")return!1;throw n}}function Yy(y,S){_n(S);try{YS(y)}catch(u){if(u.code!=="ENOENT")throw u}}function QS(y){return`${y}.write.lock`}function Kn(y,S){let u=S.now??Date.now,n=KS(S.timeoutMs,Un),O=KS(S.retryIntervalMs,Bn),M=G.get(y);if(M){M.count+=1;let R=!1;return{lockPath:y,role:S.role,waitDurationMs:0,reentrant:!0,release:()=>{if(R)return;R=!0;let N=G.get(y);if(!N)return;if(N.count-=1,N.count===0)G.delete(y),Yy(y,N.fd)}}}let f={pid:process.pid,role:S.role,hostname:cS(),acquiredAt:new Date(u()).toISOString(),ownerId:S.ownerId},p=u(),E=null;for(;;)try{let R=$n(y,"wx");try{Cn(R,JSON.stringify(f),"utf8"),An(R)}catch(V){throw Yy(y,R),V}G.set(y,{count:1,fd:R});let N=!1;return{lockPath:y,role:S.role,waitDurationMs:u()-p,reentrant:!1,release:()=>{if(N)return;N=!0;let V=G.get(y);if(!V)return;if(V.count-=1,V.count===0)G.delete(y),Yy(y,V.fd)}}}catch(R){if(R.code!=="EEXIST")throw R;if(E=WS(y),Hn(y,E))continue;let V=u()-p;if(V>=n)throw new s({lockPath:y,role:S.role,waitDurationMs:V,owner:E});Zn(Math.min(O,n-V))}}function LS(y,S,u){let n=Kn(y,S);try{return u()}finally{n.release()}}var zn=new Set(["SQLITE_BUSY","SQLITE_LOCKED","SQLITE_IOERR","SQLITE_IOERR_VNODE","SQLITE_IOERR_READ","SQLITE_IOERR_WRITE","SQLITE_IOERR_SHORT_READ","SQLITE_IOERR_FSYNC","SQLITE_PROTOCOL"]),Wn=3,DS=50,Qn=new Set(["INSERT","UPDATE","DELETE","REPLACE","CREATE","ALTER","DROP","VACUUM","REINDEX","ANALYZE","ATTACH","DETACH"]),Ln=new Set(["WAL_CHECKPOINT","OPTIMIZE","INCREMENTAL_VACUUM","SHRINK_MEMORY"]),Fn=/^(?:\s+|--[^\n]*(?:\n|$)|\/\*[\s\S]*?\*\/)+/;function Dn(y){let S=y;for(;;){let u=S.replace(Fn,"");if(u===S)return S.trimStart();S=u}}function Gn(y){let S=[],u=0,n=!1,O=!1,M=!1,f=!1,p=!1,E=!1;for(let N=0;N<y.length;N+=1){let V=y[N],J=y[N+1];if(p){if(V===`
36
+ `)p=!1;continue}if(E){if(V==="*"&&J==="/")E=!1,N+=1;continue}if(n){if(V==="'")if(J==="'")N+=1;else n=!1;continue}if(O){if(V==='"')if(J==='"')N+=1;else O=!1;continue}if(M){if(V==="`")M=!1;continue}if(f){if(V==="]")f=!1;continue}if(V==="-"&&J==="-"){p=!0,N+=1;continue}if(V==="/"&&J==="*"){E=!0,N+=1;continue}if(V==="'"){n=!0;continue}if(V==='"'){O=!0;continue}if(V==="`"){M=!0;continue}if(V==="["){f=!0;continue}if(V===";"){let _=y.slice(u,N).trim();if(_.length>0)S.push(_);u=N+1}}let R=y.slice(u).trim();if(R.length>0)S.push(R);return S}function Tn(y){let S=Dn(y);if(!S)return!1;let u=S.toUpperCase();if(/\bRETURNING\b/.test(u))return!0;if(u.startsWith("PRAGMA")){if(/^PRAGMA\s+(?:[A-Z0-9_]+\.)?[A-Z0-9_]+\s*=/.test(u))return!0;let O=/^PRAGMA\s+(?:[A-Z0-9_]+\.)?([A-Z0-9_]+)/.exec(u)?.[1];if(!O)return!1;return Ln.has(O)}let n=/^[A-Z]+/.exec(u)?.[0];if(!n)return!1;if(Qn.has(n))return!0;if(n==="WITH")return/\b(INSERT|UPDATE|DELETE|REPLACE)\b/.test(u);return!1}function cy(y){let S=Gn(y);if(S.length===0)return!1;for(let u of S)if(Tn(u))return!0;return!1}var hn=new Set(["PASSIVE","FULL","RESTART","TRUNCATE"]);function r(y){if(y instanceof Error){let S=y.code;return{code:typeof S==="string"?S:"UNKNOWN",message:y.message}}return{code:"UNKNOWN",message:String(y)}}function jn(y){if(y&&typeof y==="object"&&"code"in y){let S=y.code;return zn.has(S)}return!1}class yy{db;dbPath;advisoryWriteLockPath;processRole;transactionDepth=0;_hasVectorExtension=!1;static enableExtensionSupport(){let y=["/opt/homebrew/opt/sqlite/lib/libsqlite3.dylib","/usr/local/opt/sqlite/lib/libsqlite3.dylib"];for(let S of y)try{if(Yn(S))return FS.setCustomSQLite(S),!0}catch{return!1}return!1}constructor(y,S={}){this.dbPath=y,this.processRole=S.processRole??zS,this.advisoryWriteLockPath=QS(y),this.db=this.open(y),this.configure()}open(y){let S=y.lastIndexOf("/");if(S>0){let u=y.substring(0,S);cn(u,{recursive:!0})}return new FS(y,{create:!0})}configure(){this.runConfigureStage("applyPragmas",()=>this.applyPragmas()),this.runConfigureStage("loadExtensions",()=>this.loadExtensions())}runConfigureStage(y,S){try{S()}catch(u){this.throwConfigureFailure(y,u)}}throwConfigureFailure(y,S){let u=r(S);try{this.db.close()}catch{}throw console.error("[open-mem] Database configure failed (non-destructive fail-safe)",{stage:y,dbPath:this.dbPath,sqliteCode:u.code,sqliteMessage:u.message,action:"startup-abort",deletionAttempted:!1}),Error(`Database startup failed during ${y} (fail-safe, non-destructive): [${u.code}] ${u.message}`)}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{GS.load(this.db),this._hasVectorExtension=!0}catch(y){let S=r(y);console.warn("[open-mem] SQLite extension load skipped",{stage:"loadExtensions",dbPath:this.dbPath,sqliteCode:S.code,sqliteMessage:S.message,action:"continue-without-extension"}),this._hasVectorExtension=!1}}get hasVectorExtension(){return this._hasVectorExtension}ensureMigrationTable(){this.db.exec(`
36
37
  CREATE TABLE IF NOT EXISTS _migrations (
37
38
  version INTEGER PRIMARY KEY,
38
39
  name TEXT NOT NULL,
39
40
  applied_at TEXT NOT NULL DEFAULT (datetime('now'))
40
41
  )
41
- `)}migrate(n){this.ensureMigrationTable();let p=this.db.query("SELECT version FROM _migrations ORDER BY version").all(),y=new Set(p.map((S)=>S.version)),e=n.filter((S)=>!y.has(S.version)).sort((S,u)=>S.version-u.version);for(let S of e)this.db.transaction(()=>{this.db.exec(S.up),this.db.query("INSERT INTO _migrations (version, name) VALUES ($version, $name)").run({$version:S.version,$name:S.name})})()}run(n,p){let y=this.db.query(n);if(p)y.run(...p);else y.run()}get(n,p){let y=this.db.query(n);return p?y.get(...p):y.get()}all(n,p){let y=this.db.query(n);return p?y.all(...p):y.all()}exec(n){this.db.exec(n)}transaction(n){return this.db.transaction(n)()}close(){this.db.close()}get isOpen(){try{return this.db.query("SELECT 1").get(),!0}catch{return!1}}get raw(){return this.db}}function d(n){return new a(n)}import{randomUUID as $p}from"crypto";class $n{db;constructor(n){this.db=n}upsertEntity(n,p){let y=$p(),e=new Date().toISOString();this.db.run(`INSERT INTO entities (id, name, entity_type, first_seen_at, last_seen_at, mention_count)
42
+ `)}migrate(y){this.withAdvisoryWriteLock(this.processRole,()=>{this.ensureMigrationTable();let S=this.withRetry("migrate.applied_versions",()=>{return this.db.query("SELECT version FROM _migrations ORDER BY version").all()}),u=new Set(S.map((O)=>O.version)),n=y.filter((O)=>!u.has(O.version)).sort((O,M)=>O.version-M.version);for(let O of n)this.transaction(()=>{this.exec(O.up),this.run("INSERT INTO _migrations (version, name) VALUES ($version, $name)",[{$version:O.version,$name:O.name}])})})}withRetry(y,S){let u=this.transactionDepth>0?0:Wn,n;for(let O=0;O<=u;O++)try{return S()}catch(M){if(n=M,!jn(M)||O===u)throw M;let f=DS*2**O+Math.random()*DS;Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,f);let p=r(M);console.warn("[open-mem] Retrying after transient SQLite error",{attempt:O+1,maxRetries:u,operation:y,role:this.processRole,dbPath:this.dbPath,sqliteCode:p.code,sqliteMessage:p.message})}throw n}run(y,S){this.withAdvisoryWriteLock(this.processRole,()=>{this.withRetry("run",()=>{let u=this.db.query(y);if(S)u.run(...S);else u.run()})})}get(y,S){let u=()=>{let n=this.db.query(y);return S?n.get(...S):n.get()};if(cy(y))return this.withAdvisoryWriteLock(this.processRole,()=>this.withRetry("get",u));return this.withRetry("get",u)}all(y,S){let u=()=>{let n=this.db.query(y);return S?n.all(...S):n.all()};if(cy(y))return this.withAdvisoryWriteLock(this.processRole,()=>this.withRetry("all",u));return this.withRetry("all",u)}exec(y){let S=()=>this.withRetry("exec",()=>this.db.exec(y));if(cy(y)){this.withAdvisoryWriteLock(this.processRole,S);return}S()}transaction(y){return this.withAdvisoryWriteLock(this.processRole,()=>{if(this.transactionDepth>0)return y();let S=this.db.transaction(y);if(typeof S.immediate==="function"){this.transactionDepth+=1;try{return S.immediate()}finally{this.transactionDepth-=1}}this.db.exec("BEGIN IMMEDIATE"),this.transactionDepth+=1;try{let u=y();return this.db.exec("COMMIT"),u}catch(u){let n=u;try{this.db.exec("ROLLBACK")}catch(O){if(n instanceof Error){let M=n;if(M.cause===void 0)M.cause=O;else M.suppressed=[...M.suppressed??[],O]}console.warn("[open-mem] Transaction rollback failed after transaction error",{dbPath:this.dbPath,originalError:r(n),rollbackError:r(O)})}throw n}finally{this.transactionDepth-=1}})}get writeLockPath(){return this.advisoryWriteLockPath}withAdvisoryWriteLock(y,S,u){try{return LS(this.advisoryWriteLockPath,{...u,role:y},S)}catch(n){if(n instanceof s)console.error("[open-mem] Advisory write lock timeout",{role:y,dbPath:this.dbPath,lockPath:n.lockPath,waitDurationMs:n.waitDurationMs,owner:n.owner});throw n}}checkpointWal(y="PASSIVE"){let S=typeof y==="string"?y.toUpperCase():"";if(!hn.has(S))throw Error(`Invalid wal_checkpoint mode: ${String(y)}`);return this.withAdvisoryWriteLock(this.processRole,()=>{return this.withRetry("maintenance.wal_checkpoint",()=>{let u=this.db.query(`PRAGMA wal_checkpoint(${S})`).get();if(!u)throw Error("wal_checkpoint returned no result row");return{mode:S,busy:u.busy??0,logFrames:u.log??0,checkpointedFrames:u.checkpointed??0}})})}integrityCheck(y=1){let S=Number.isFinite(y)?Math.max(1,Math.floor(y)):1;return this.withRetry("maintenance.integrity_check",()=>{let u=this.db.query(`PRAGMA integrity_check(${S})`).all();if(u.length===0)throw Error("integrity_check returned no result rows");let n=u.map((O)=>Object.values(O).find((M)=>typeof M==="string")).filter((O)=>typeof O==="string").map((O)=>O.trim()).filter((O)=>O.length>0);if(n.length===0)throw Error("integrity_check returned no diagnostic messages");return{ok:n.length===1&&n[0].toLowerCase()==="ok",messages:n,maxErrors:S}})}close(){this.db.close()}get isOpen(){try{return this.db.query("SELECT 1").get(),!0}catch{return!1}}get raw(){return this.db}}function Sy(y,S){return new yy(y,S)}import{randomUUID as TS}from"crypto";class zy{db;constructor(y){this.db=y}upsertEntity(y,S){let u=TS(),n=new Date().toISOString();this.db.run(`INSERT INTO entities (id, name, entity_type, first_seen_at, last_seen_at, mention_count)
42
43
  VALUES (?, ?, ?, ?, ?, 1)
43
44
  ON CONFLICT(name, entity_type) DO UPDATE SET
44
45
  mention_count = mention_count + 1,
45
- last_seen_at = ?`,[y,n,p,e,e,e]);let S=this.db.get("SELECT * FROM entities WHERE name = ? AND entity_type = ?",[n,p]);if(!S)throw Error(`Failed to upsert entity: ${n} (${p})`);return this.mapEntityRow(S)}createRelation(n,p,y,e){let S=$p(),u=new Date().toISOString();try{this.db.run(`INSERT OR IGNORE INTO entity_relations
46
+ last_seen_at = ?`,[u,y,S,n,n,n]);let O=this.db.get("SELECT * FROM entities WHERE name = ? AND entity_type = ?",[y,S]);if(!O)throw Error(`Failed to upsert entity: ${y} (${S})`);return this.mapEntityRow(O)}createRelation(y,S,u,n){let O=TS(),M=new Date().toISOString();try{this.db.run(`INSERT OR IGNORE INTO entity_relations
46
47
  (id, source_entity_id, target_entity_id, relationship, observation_id, created_at)
47
- VALUES (?, ?, ?, ?, ?, ?)`,[S,n,p,y,e,u])}catch{return null}let m=this.db.get(`SELECT * FROM entity_relations
48
- WHERE source_entity_id = ? AND target_entity_id = ? AND relationship = ?`,[n,p,y]);return m?this.mapRelationRow(m):null}linkObservation(n,p){this.db.run("INSERT OR IGNORE INTO entity_observations (entity_id, observation_id) VALUES (?, ?)",[n,p])}findByName(n){try{return this.db.all(`SELECT e.*
48
+ VALUES (?, ?, ?, ?, ?, ?)`,[O,y,S,u,n,M])}catch{return null}let f=this.db.get(`SELECT * FROM entity_relations
49
+ WHERE source_entity_id = ? AND target_entity_id = ? AND relationship = ?`,[y,S,u]);return f?this.mapRelationRow(f):null}linkObservation(y,S){this.db.run("INSERT OR IGNORE INTO entity_observations (entity_id, observation_id) VALUES (?, ?)",[y,S])}findByName(y){try{return this.db.all(`SELECT e.*
49
50
  FROM entities e
50
51
  JOIN entities_fts fts ON e._rowid = fts.rowid
51
52
  WHERE entities_fts MATCH ?
52
- ORDER BY rank`,[n]).map((y)=>this.mapEntityRow(y))}catch{return[]}}getRelationsFor(n){return this.db.all(`SELECT * FROM entity_relations
53
- WHERE source_entity_id = ? OR target_entity_id = ?`,[n,n]).map((y)=>this.mapRelationRow(y))}traverseRelations(n,p=1){let y=Math.min(p,2),e=100,S=new Set,u=[{id:n,currentDepth:0}];S.add(n);while(u.length>0){if(S.size>=100)break;let m=u.shift();if(!m)continue;if(m.currentDepth>=y)continue;let r=this.getRelationsFor(m.id);for(let O of r){let M=O.sourceEntityId===m.id?O.targetEntityId:O.sourceEntityId;if(!S.has(M))S.add(M),u.push({id:M,currentDepth:m.currentDepth+1})}}return S}getObservationsForEntity(n){return this.db.all("SELECT observation_id FROM entity_observations WHERE entity_id = ?",[n]).map((y)=>y.observation_id)}getById(n){let p=this.db.get("SELECT * FROM entities WHERE id = ?",[n]);return p?this.mapEntityRow(p):null}mapEntityRow(n){return{id:n.id,name:n.name,entityType:n.entity_type,firstSeenAt:n.first_seen_at,lastSeenAt:n.last_seen_at,mentionCount:n.mention_count}}mapRelationRow(n){return{id:n.id,sourceEntityId:n.source_entity_id,targetEntityId:n.target_entity_id,relationship:n.relationship,observationId:n.observation_id,createdAt:n.created_at}}}function Se(n){try{let p=JSON.parse(n);return p&&typeof p==="object"?p:{}}catch{return{}}}class Bn{db;constructor(n){this.db=n}list(){return this.db.all("SELECT id, timestamp, action, dry_run, result FROM maintenance_history ORDER BY timestamp DESC").map((n)=>({id:n.id,timestamp:n.timestamp,action:n.action,dryRun:n.dry_run===1,result:Se(n.result)}))}append(n){this.db.run("INSERT INTO maintenance_history (id, timestamp, action, dry_run, result) VALUES (?, ?, ?, ?, ?)",[n.id,n.timestamp,n.action,n.dryRun?1:0,JSON.stringify(n.result??{})])}}import{randomUUID as me}from"crypto";import{embed as ue}from"ai";async function s(n,p){try{let{embedding:y}=await ue({model:n,value:p});return y}catch{return null}}function Q(n,p){if(n.length!==p.length||n.length===0)return 0;let y=0,e=0,S=0;for(let m=0;m<n.length;m++)y+=n[m]*p[m],e+=n[m]*n[m],S+=p[m]*p[m];let u=Math.sqrt(e)*Math.sqrt(S);if(u===0)return 0;return y/u}function re(n){return n.replace(/[%_\\]/g,"\\$&")}class Un{db;constructor(n){this.db=n}create(n){let p=me(),y=new Date().toISOString(),e=n.discoveryTokens??0,S=n.importance??3,u=n.scope??"project";return this.db.run(`INSERT INTO observations
53
+ ORDER BY rank`,[y]).map((u)=>this.mapEntityRow(u))}catch{return[]}}getRelationsFor(y){return this.db.all(`SELECT * FROM entity_relations
54
+ WHERE source_entity_id = ? OR target_entity_id = ?`,[y,y]).map((u)=>this.mapRelationRow(u))}traverseRelations(y,S=1){let u=Math.min(S,2),n=100,O=new Set,M=[{id:y,currentDepth:0}];O.add(y);while(M.length>0){if(O.size>=100)break;let f=M.shift();if(!f)continue;if(f.currentDepth>=u)continue;let p=this.getRelationsFor(f.id);for(let E of p){let R=E.sourceEntityId===f.id?E.targetEntityId:E.sourceEntityId;if(!O.has(R))O.add(R),M.push({id:R,currentDepth:f.currentDepth+1})}}return O}getObservationsForEntity(y){return this.db.all("SELECT observation_id FROM entity_observations WHERE entity_id = ?",[y]).map((u)=>u.observation_id)}getById(y){let S=this.db.get("SELECT * FROM entities WHERE id = ?",[y]);return S?this.mapEntityRow(S):null}mapEntityRow(y){return{id:y.id,name:y.name,entityType:y.entity_type,firstSeenAt:y.first_seen_at,lastSeenAt:y.last_seen_at,mentionCount:y.mention_count}}mapRelationRow(y){return{id:y.id,sourceEntityId:y.source_entity_id,targetEntityId:y.target_entity_id,relationship:y.relationship,observationId:y.observation_id,createdAt:y.created_at}}}function vn(y){try{let S=JSON.parse(y);return S&&typeof S==="object"?S:{}}catch{return{}}}class Wy{db;constructor(y){this.db=y}list(){return this.db.all("SELECT id, timestamp, action, dry_run, result FROM maintenance_history ORDER BY timestamp DESC").map((y)=>({id:y.id,timestamp:y.timestamp,action:y.action,dryRun:y.dry_run===1,result:vn(y.result)}))}append(y){this.db.run("INSERT INTO maintenance_history (id, timestamp, action, dry_run, result) VALUES (?, ?, ?, ?, ?)",[y.id,y.timestamp,y.action,y.dryRun?1:0,JSON.stringify(y.result??{})])}}import{randomUUID as kn}from"crypto";import{embed as xn}from"ai";async function uy(y,S){try{let{embedding:u}=await xn({model:y,value:S});return u}catch{return null}}function T(y,S){if(y.length!==S.length||y.length===0)return 0;let u=0,n=0,O=0;for(let f=0;f<y.length;f++)u+=y[f]*S[f],n+=y[f]*y[f],O+=S[f]*S[f];let M=Math.sqrt(n)*Math.sqrt(O);if(M===0)return 0;return u/M}function In(y){return y.replace(/[%_\\]/g,"\\$&")}class Qy{db;constructor(y){this.db=y}create(y){let S=kn(),u=new Date().toISOString(),n=y.discoveryTokens??0,O=y.importance??3,M=y.scope??"project";return this.db.run(`INSERT INTO observations
54
55
  (id, session_id, scope, type, title, subtitle, facts, narrative,
55
56
  concepts, files_read, files_modified, raw_tool_output,
56
57
  tool_name, created_at, token_count, discovery_tokens, importance, revision_of, deleted_at)
57
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[p,n.sessionId,u,n.type,n.title,n.subtitle,JSON.stringify(n.facts),n.narrative,JSON.stringify(n.concepts),JSON.stringify(n.filesRead),JSON.stringify(n.filesModified),n.rawToolOutput,n.toolName,y,n.tokenCount,e,S,null,null]),{...n,id:p,scope:u,createdAt:y,discoveryTokens:e,importance:S,revisionOf:null,deletedAt:null,supersededBy:null,supersededAt:null}}importObservation(n){this.db.run(`INSERT INTO observations
58
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[S,y.sessionId,M,y.type,y.title,y.subtitle,JSON.stringify(y.facts),y.narrative,JSON.stringify(y.concepts),JSON.stringify(y.filesRead),JSON.stringify(y.filesModified),y.rawToolOutput,y.toolName,u,y.tokenCount,n,O,null,null]),{...y,id:S,scope:M,createdAt:u,discoveryTokens:n,importance:O,revisionOf:null,deletedAt:null,supersededBy:null,supersededAt:null}}importObservation(y){this.db.run(`INSERT INTO observations
58
59
  (id, session_id, scope, type, title, subtitle, facts, narrative,
59
60
  concepts, files_read, files_modified, raw_tool_output,
60
61
  tool_name, created_at, token_count, discovery_tokens, importance, revision_of, deleted_at)
61
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[n.id,n.sessionId,n.scope??"project",n.type,n.title,n.subtitle,JSON.stringify(n.facts),n.narrative,JSON.stringify(n.concepts),JSON.stringify(n.filesRead),JSON.stringify(n.filesModified),n.rawToolOutput,n.toolName,n.createdAt,n.tokenCount,n.discoveryTokens??0,n.importance??3,n.revisionOf??null,n.deletedAt??null])}getById(n){let p=this.db.get("SELECT * FROM observations WHERE id = ? AND superseded_by IS NULL AND deleted_at IS NULL",[n]);return p?this.mapRow(p):null}getByIdIncludingArchived(n){let p=this.db.get("SELECT * FROM observations WHERE id = ?",[n]);return p?this.mapRow(p):null}getBySession(n){return this.db.all("SELECT * FROM observations WHERE session_id = ? AND superseded_by IS NULL AND deleted_at IS NULL ORDER BY created_at ASC",[n]).map((p)=>this.mapRow(p))}getCount(n){if(n)return this.db.get("SELECT COUNT(*) as count FROM observations WHERE session_id = ?",[n])?.count??0;return this.db.get("SELECT COUNT(*) as count FROM observations")?.count??0}getIndex(n,p=20){return this.db.all(`SELECT o.id, o.session_id, o.type, o.title, o.token_count, o.discovery_tokens, o.created_at, o.importance
62
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[y.id,y.sessionId,y.scope??"project",y.type,y.title,y.subtitle,JSON.stringify(y.facts),y.narrative,JSON.stringify(y.concepts),JSON.stringify(y.filesRead),JSON.stringify(y.filesModified),y.rawToolOutput,y.toolName,y.createdAt,y.tokenCount,y.discoveryTokens??0,y.importance??3,y.revisionOf??null,y.deletedAt??null])}getById(y){let S=this.db.get("SELECT * FROM observations WHERE id = ? AND superseded_by IS NULL AND deleted_at IS NULL",[y]);return S?this.mapRow(S):null}getByIdIncludingArchived(y){let S=this.db.get("SELECT * FROM observations WHERE id = ?",[y]);return S?this.mapRow(S):null}getBySession(y){return this.db.all("SELECT * FROM observations WHERE session_id = ? AND superseded_by IS NULL AND deleted_at IS NULL ORDER BY created_at ASC",[y]).map((S)=>this.mapRow(S))}getCount(y){if(y)return this.db.get("SELECT COUNT(*) as count FROM observations WHERE session_id = ?",[y])?.count??0;return this.db.get("SELECT COUNT(*) as count FROM observations")?.count??0}getIndex(y,S=20){return this.db.all(`SELECT o.id, o.session_id, o.type, o.title, o.token_count, o.discovery_tokens, o.created_at, o.importance
62
63
  FROM observations o
63
64
  JOIN sessions s ON o.session_id = s.id
64
65
  WHERE s.project_path = ? AND o.superseded_by IS NULL AND o.deleted_at IS NULL
65
66
  ORDER BY o.created_at DESC
66
- LIMIT ?`,[n,p]).map((y)=>({id:y.id,sessionId:y.session_id,type:y.type,title:y.title,tokenCount:y.token_count,discoveryTokens:y.discovery_tokens??0,createdAt:y.created_at,importance:y.importance??3}))}getAroundTimestamp(n,p,y,e){let S=p>0?this.db.all(`SELECT o.*
67
+ LIMIT ?`,[y,S]).map((u)=>({id:u.id,sessionId:u.session_id,type:u.type,title:u.title,tokenCount:u.token_count,discoveryTokens:u.discovery_tokens??0,createdAt:u.created_at,importance:u.importance??3}))}getAroundTimestamp(y,S,u,n){let O=S>0?this.db.all(`SELECT o.*
67
68
  FROM observations o
68
69
  JOIN sessions s ON o.session_id = s.id
69
70
  WHERE s.project_path = ? AND o.created_at < ?
70
71
  AND o.superseded_by IS NULL AND o.deleted_at IS NULL
71
72
  ORDER BY o.created_at DESC
72
- LIMIT ?`,[e,n,p]).reverse():[],u=y>0?this.db.all(`SELECT o.*
73
+ LIMIT ?`,[n,y,S]).reverse():[],M=u>0?this.db.all(`SELECT o.*
73
74
  FROM observations o
74
75
  JOIN sessions s ON o.session_id = s.id
75
76
  WHERE s.project_path = ? AND o.created_at > ?
76
77
  AND o.superseded_by IS NULL AND o.deleted_at IS NULL
77
78
  ORDER BY o.created_at ASC
78
- LIMIT ?`,[e,n,y]):[];return[...S,...u].map((m)=>this.mapRow(m))}listByProject(n,p={}){let{limit:y=50,offset:e=0,type:S,state:u,sessionId:m}=p,r=`SELECT o.*
79
+ LIMIT ?`,[n,y,u]):[];return[...O,...M].map((f)=>this.mapRow(f))}listByProject(y,S={}){let{limit:u=50,offset:n=0,type:O,state:M,sessionId:f}=S,p=`SELECT o.*
79
80
  FROM observations o
80
81
  JOIN sessions s ON o.session_id = s.id
81
- WHERE s.project_path = ?`,O=[n];if(m)r+=" AND o.session_id = ?",O.push(m);if(S)r+=" AND o.type = ?",O.push(S);if(u==="current")r+=" AND o.superseded_by IS NULL AND o.deleted_at IS NULL";else if(u==="superseded")r+=" AND o.superseded_by IS NOT NULL AND o.deleted_at IS NULL";else if(u==="tombstoned")r+=" AND o.deleted_at IS NOT NULL";else r+=" AND o.superseded_by IS NULL AND o.deleted_at IS NULL";return r+=" ORDER BY o.created_at DESC LIMIT ? OFFSET ?",O.push(y,e),this.db.all(r,O).map((M)=>this.mapRow(M))}search(n){let p=!!n.projectPath,y=`
82
+ WHERE s.project_path = ?`,E=[y];if(f)p+=" AND o.session_id = ?",E.push(f);if(O)p+=" AND o.type = ?",E.push(O);if(M==="current")p+=" AND o.superseded_by IS NULL AND o.deleted_at IS NULL";else if(M==="superseded")p+=" AND o.superseded_by IS NOT NULL AND o.deleted_at IS NULL";else if(M==="tombstoned")p+=" AND o.deleted_at IS NOT NULL";else p+=" AND o.superseded_by IS NULL AND o.deleted_at IS NULL";return p+=" ORDER BY o.created_at DESC LIMIT ? OFFSET ?",E.push(u,n),this.db.all(p,E).map((R)=>this.mapRow(R))}search(y){let S=!!y.projectPath,u=`
82
83
  SELECT o.*, rank
83
84
  FROM observations o
84
85
  JOIN observations_fts fts ON o._rowid = fts.rowid
85
- ${p?"JOIN sessions s ON o.session_id = s.id":""}
86
+ ${S?"JOIN sessions s ON o.session_id = s.id":""}
86
87
  WHERE observations_fts MATCH ? AND o.superseded_by IS NULL AND o.deleted_at IS NULL
87
- `,e=[n.query];if(p&&n.projectPath)y+=" AND s.project_path = ?",e.push(n.projectPath);if(n.sessionId)y+=" AND o.session_id = ?",e.push(n.sessionId);if(n.type)y+=" AND o.type = ?",e.push(n.type);if(n.importanceMin!==void 0)y+=" AND o.importance >= ?",e.push(n.importanceMin);if(n.importanceMax!==void 0)y+=" AND o.importance <= ?",e.push(n.importanceMax);if(n.createdAfter)y+=" AND o.created_at >= ?",e.push(n.createdAfter);if(n.createdBefore)y+=" AND o.created_at <= ?",e.push(n.createdBefore);if(n.concepts&&n.concepts.length>0){let S=n.concepts.map(()=>"EXISTS (SELECT 1 FROM json_each(o.concepts) WHERE LOWER(value) = LOWER(?))");y+=` AND (${S.join(" OR ")})`;for(let u of n.concepts)e.push(u)}if(n.files&&n.files.length>0){let S=n.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 '\\'))`);y+=` AND (${S.join(" OR ")})`;for(let u of n.files){let m=`%${re(u)}%`;e.push(m,m)}}return y+=" ORDER BY rank LIMIT ? OFFSET ?",e.push(n.limit??10),e.push(n.offset??0),this.db.all(y,e).map((S)=>({observation:this.mapRow(S),rank:S.rank,snippet:S.title}))}searchByConcept(n,p=10,y){let e=!!y,S=`SELECT o.*
88
+ `,n=[y.query];if(S&&y.projectPath)u+=" AND s.project_path = ?",n.push(y.projectPath);if(y.sessionId)u+=" AND o.session_id = ?",n.push(y.sessionId);if(y.type)u+=" AND o.type = ?",n.push(y.type);if(y.importanceMin!==void 0)u+=" AND o.importance >= ?",n.push(y.importanceMin);if(y.importanceMax!==void 0)u+=" AND o.importance <= ?",n.push(y.importanceMax);if(y.createdAfter)u+=" AND o.created_at >= ?",n.push(y.createdAfter);if(y.createdBefore)u+=" AND o.created_at <= ?",n.push(y.createdBefore);if(y.concepts&&y.concepts.length>0){let O=y.concepts.map(()=>"EXISTS (SELECT 1 FROM json_each(o.concepts) WHERE LOWER(value) = LOWER(?))");u+=` AND (${O.join(" OR ")})`;for(let M of y.concepts)n.push(M)}if(y.files&&y.files.length>0){let O=y.files.map(()=>`(EXISTS (SELECT 1 FROM json_each(o.files_read) WHERE LOWER(value) LIKE LOWER(?) ESCAPE '\\')
89
+ OR EXISTS (SELECT 1 FROM json_each(o.files_modified) WHERE LOWER(value) LIKE LOWER(?) ESCAPE '\\'))`);u+=` AND (${O.join(" OR ")})`;for(let M of y.files){let f=`%${In(M)}%`;n.push(f,f)}}return u+=" ORDER BY rank LIMIT ? OFFSET ?",n.push(y.limit??10),n.push(y.offset??0),this.db.all(u,n).map((O)=>({observation:this.mapRow(O),rank:O.rank,snippet:O.title}))}searchByConcept(y,S=10,u){let n=!!u,O=`SELECT o.*
89
90
  FROM observations o
90
91
  JOIN observations_fts fts ON o._rowid = fts.rowid
91
- ${e?"JOIN sessions s ON o.session_id = s.id":""}
92
+ ${n?"JOIN sessions s ON o.session_id = s.id":""}
92
93
  WHERE observations_fts MATCH ?
93
94
  AND o.superseded_by IS NULL AND o.deleted_at IS NULL
94
- ${e?"AND s.project_path = ?":""}
95
+ ${n?"AND s.project_path = ?":""}
95
96
  ORDER BY rank
96
- LIMIT ?`,m=[`concepts:"${n.replace(/"/g,'""')}"`];if(e&&y)m.push(y);return m.push(p),this.db.all(S,m).map((r)=>this.mapRow(r))}searchByFile(n,p=10,y){let e=!!y,S=`SELECT o.*
97
+ LIMIT ?`,f=[`concepts:"${y.replace(/"/g,'""')}"`];if(n&&u)f.push(u);return f.push(S),this.db.all(O,f).map((p)=>this.mapRow(p))}searchByFile(y,S=10,u){let n=!!u,O=`SELECT o.*
97
98
  FROM observations o
98
99
  JOIN observations_fts fts ON o._rowid = fts.rowid
99
- ${e?"JOIN sessions s ON o.session_id = s.id":""}
100
+ ${n?"JOIN sessions s ON o.session_id = s.id":""}
100
101
  WHERE observations_fts MATCH ?
101
102
  AND o.superseded_by IS NULL AND o.deleted_at IS NULL
102
- ${e?"AND s.project_path = ?":""}
103
+ ${n?"AND s.project_path = ?":""}
103
104
  ORDER BY rank
104
- LIMIT ?`,u=[`files_read:"${n.replace(/"/g,'""')}" OR files_modified:"${n.replace(/"/g,'""')}"`];if(e&&y)u.push(y);return u.push(p),this.db.all(S,u).map((m)=>this.mapRow(m))}setEmbedding(n,p){this.db.run("UPDATE observations SET embedding = ? WHERE id = ?",[JSON.stringify(p),n])}getWithEmbeddings(n,p){return this.db.all(`SELECT o.id, o.embedding, o.title
105
+ LIMIT ?`,M=[`files_read:"${y.replace(/"/g,'""')}" OR files_modified:"${y.replace(/"/g,'""')}"`];if(n&&u)M.push(u);return M.push(S),this.db.all(O,M).map((f)=>this.mapRow(f))}setEmbedding(y,S){this.db.run("UPDATE observations SET embedding = ? WHERE id = ?",[JSON.stringify(S),y])}getWithEmbeddings(y,S){return this.db.all(`SELECT o.id, o.embedding, o.title
105
106
  FROM observations o
106
107
  JOIN sessions s ON o.session_id = s.id
107
108
  WHERE s.project_path = ? AND o.embedding IS NOT NULL AND o.superseded_by IS NULL AND o.deleted_at IS NULL
108
109
  ORDER BY o.created_at DESC
109
- LIMIT ?`,[n,p]).map((y)=>{try{return{id:y.id,embedding:JSON.parse(y.embedding),title:y.title}}catch{return null}}).filter((y)=>y!==null)}findSimilar(n,p,y,e){let S=this.db.all(`SELECT id, embedding FROM observations
110
+ LIMIT ?`,[y,S]).map((u)=>{try{return{id:u.id,embedding:JSON.parse(u.embedding),title:u.title}}catch{return null}}).filter((u)=>u!==null)}findSimilar(y,S,u,n){let O=this.db.all(`SELECT id, embedding FROM observations
110
111
  WHERE embedding IS NOT NULL AND type = ? AND superseded_by IS NULL AND deleted_at IS NULL
111
112
  ORDER BY created_at DESC
112
- LIMIT 200`,[p]),u=[];for(let m of S)try{let r=JSON.parse(m.embedding);if(!Array.isArray(r)||r.length!==n.length)continue;let O=Q(n,r);if(O>=y)u.push({id:m.id,similarity:O})}catch{}return u.sort((m,r)=>r.similarity-m.similarity).slice(0,e)}insertVecEmbedding(n,p){let y=new Float32Array(p);this.db.run("BEGIN");try{this.db.run("DELETE FROM observation_embeddings WHERE observation_id = ?",[n]),this.db.run("INSERT INTO observation_embeddings (observation_id, embedding) VALUES (?, ?)",[n,y]),this.db.run("COMMIT")}catch(e){throw this.db.run("ROLLBACK"),e}}migrateExistingEmbeddings(n){let p=this.db.all("SELECT id, embedding FROM observations WHERE embedding IS NOT NULL"),y=0,e=0;for(let S of p)try{let u=JSON.parse(S.embedding);if(!Array.isArray(u)||u.length!==n){e++;continue}this.insertVecEmbedding(S.id,u),y++}catch{e++}return{migrated:y,skipped:e}}getVecEmbeddingMatches(n,p){try{let y=new Float32Array(n);return this.db.all(`SELECT observation_id, distance
113
+ LIMIT 200`,[S]),M=[];for(let f of O)try{let p=JSON.parse(f.embedding);if(!Array.isArray(p)||p.length!==y.length)continue;let E=T(y,p);if(E>=u)M.push({id:f.id,similarity:E})}catch{}return M.sort((f,p)=>p.similarity-f.similarity).slice(0,n)}insertVecEmbedding(y,S){let u=new Float32Array(S);this.db.run("BEGIN");try{this.db.run("DELETE FROM observation_embeddings WHERE observation_id = ?",[y]),this.db.run("INSERT INTO observation_embeddings (observation_id, embedding) VALUES (?, ?)",[y,u]),this.db.run("COMMIT")}catch(n){throw this.db.run("ROLLBACK"),n}}migrateExistingEmbeddings(y){let S=this.db.all("SELECT id, embedding FROM observations WHERE embedding IS NOT NULL"),u=0,n=0;for(let O of S)try{let M=JSON.parse(O.embedding);if(!Array.isArray(M)||M.length!==y){n++;continue}this.insertVecEmbedding(O.id,M),u++}catch{n++}return{migrated:u,skipped:n}}getVecEmbeddingMatches(y,S){try{let u=new Float32Array(y);return this.db.all(`SELECT observation_id, distance
113
114
  FROM observation_embeddings
114
- WHERE embedding MATCH ? AND k = ?`,[y,p]).map((e)=>({observationId:e.observation_id,distance:e.distance}))}catch{return[]}}searchVecSubset(n,p,y){if(p.length===0)return[];try{let e=new Float32Array(n),S=Math.max(y*5,p.length),u=this.db.all(`SELECT observation_id, distance
115
+ WHERE embedding MATCH ? AND k = ?`,[u,S]).map((n)=>({observationId:n.observation_id,distance:n.distance}))}catch{return[]}}searchVecSubset(y,S,u){if(S.length===0)return[];try{let n=new Float32Array(y),O=Math.max(u*5,S.length),M=this.db.all(`SELECT observation_id, distance
115
116
  FROM observation_embeddings
116
- WHERE embedding MATCH ? AND k = ?`,[e,S]),m=new Set(p);return u.filter((r)=>m.has(r.observation_id)).slice(0,y).map((r)=>({observationId:r.observation_id,distance:r.distance}))}catch{return[]}}update(n,p){let y=this.getById(n);if(!y)return null;if(Object.keys(p).length===0)return y;let e=this.create({sessionId:y.sessionId,scope:y.scope??"project",type:p.type??y.type,title:p.title??y.title,subtitle:p.subtitle??y.subtitle,facts:p.facts??y.facts,narrative:p.narrative??y.narrative,concepts:p.concepts??y.concepts,filesRead:p.filesRead??y.filesRead,filesModified:p.filesModified??y.filesModified,rawToolOutput:y.rawToolOutput,toolName:"mem-revise",tokenCount:y.tokenCount,discoveryTokens:y.discoveryTokens,importance:p.importance??y.importance});return this.db.run("UPDATE observations SET revision_of = ? WHERE id = ?",[n,e.id]),this.supersede(n,e.id),this.getById(e.id)}supersede(n,p){let y=new Date().toISOString();this.db.run("UPDATE observations SET superseded_by = ?, superseded_at = ? WHERE id = ?",[p,y,n])}delete(n){if(this.db.all("SELECT id FROM observations WHERE id = ?",[n]).length===0)return!1;let y=new Date().toISOString();return this.db.run("UPDATE observations SET deleted_at = ? WHERE id = ?",[y,n]),this.deleteEmbeddingsForObservations([n]),!0}getLineage(n){let p=this.getByIdIncludingArchived(n);if(!p)return[];let y=new Set([p.id]),e=[p];while(e[0].revisionOf){let S=this.getByIdIncludingArchived(e[0].revisionOf);if(!S||y.has(S.id))break;e.unshift(S),y.add(S.id)}while(e[e.length-1].supersededBy){let S=e[e.length-1].supersededBy;if(!S)break;let u=this.getByIdIncludingArchived(S);if(!u||y.has(u.id))break;e.push(u),y.add(u.id)}return e}deleteOlderThan(n){return this.db.all(`DELETE FROM observations
117
+ WHERE embedding MATCH ? AND k = ?`,[n,O]),f=new Set(S);return M.filter((p)=>f.has(p.observation_id)).slice(0,u).map((p)=>({observationId:p.observation_id,distance:p.distance}))}catch{return[]}}update(y,S){let u=this.getById(y);if(!u)return null;if(Object.keys(S).length===0)return u;let n=this.create({sessionId:u.sessionId,scope:u.scope??"project",type:S.type??u.type,title:S.title??u.title,subtitle:S.subtitle??u.subtitle,facts:S.facts??u.facts,narrative:S.narrative??u.narrative,concepts:S.concepts??u.concepts,filesRead:S.filesRead??u.filesRead,filesModified:S.filesModified??u.filesModified,rawToolOutput:u.rawToolOutput,toolName:"mem-revise",tokenCount:u.tokenCount,discoveryTokens:u.discoveryTokens,importance:S.importance??u.importance});return this.db.run("UPDATE observations SET revision_of = ? WHERE id = ?",[y,n.id]),this.supersede(y,n.id),this.getById(n.id)}supersede(y,S){let u=new Date().toISOString();this.db.run("UPDATE observations SET superseded_by = ?, superseded_at = ? WHERE id = ?",[S,u,y])}delete(y){if(this.db.all("SELECT id FROM observations WHERE id = ?",[y]).length===0)return!1;let u=new Date().toISOString();return this.db.run("UPDATE observations SET deleted_at = ? WHERE id = ?",[u,y]),this.deleteEmbeddingsForObservations([y]),!0}getLineage(y){let S=this.getByIdIncludingArchived(y);if(!S)return[];let u=new Set([S.id]),n=[S];while(n[0].revisionOf){let O=this.getByIdIncludingArchived(n[0].revisionOf);if(!O||u.has(O.id))break;n.unshift(O),u.add(O.id)}while(n[n.length-1].supersededBy){let O=n[n.length-1].supersededBy;if(!O)break;let M=this.getByIdIncludingArchived(O);if(!M||u.has(M.id))break;n.push(M),u.add(M.id)}return n}deleteOlderThan(y){return this.db.all(`DELETE FROM observations
117
118
  WHERE (created_at < datetime('now', '-' || ? || ' days') OR deleted_at IS NOT NULL)
118
119
  AND session_id NOT IN (SELECT id FROM sessions WHERE status != 'completed')
119
- RETURNING id`,[n]).length}deleteEmbeddingsForObservations(n){if(n.length===0)return;let p=n.map(()=>"?").join(",");try{this.db.run(`DELETE FROM observation_embeddings WHERE observation_id IN (${p})`,n)}catch{}this.db.run(`UPDATE observations SET embedding = NULL WHERE id IN (${p})`,n)}mapRow(n){return{id:n.id,sessionId:n.session_id,scope:n.scope??"project",type:n.type,title:n.title,subtitle:n.subtitle,facts:JSON.parse(n.facts),narrative:n.narrative,concepts:JSON.parse(n.concepts),filesRead:JSON.parse(n.files_read),filesModified:JSON.parse(n.files_modified),rawToolOutput:n.raw_tool_output,toolName:n.tool_name,createdAt:n.created_at,tokenCount:n.token_count,discoveryTokens:n.discovery_tokens??0,importance:n.importance??3,revisionOf:n.revision_of??null,deletedAt:n.deleted_at??null,supersededBy:n.superseded_by??null,supersededAt:n.superseded_at??null}}}var Oe=[{version:1,name:"create-schema",up:`
120
+ RETURNING id`,[y]).length}deleteEmbeddingsForObservations(y){if(y.length===0)return;let S=y.map(()=>"?").join(",");try{this.db.run(`DELETE FROM observation_embeddings WHERE observation_id IN (${S})`,y)}catch{}this.db.run(`UPDATE observations SET embedding = NULL WHERE id IN (${S})`,y)}mapRow(y){return{id:y.id,sessionId:y.session_id,scope:y.scope??"project",type:y.type,title:y.title,subtitle:y.subtitle,facts:JSON.parse(y.facts),narrative:y.narrative,concepts:JSON.parse(y.concepts),filesRead:JSON.parse(y.files_read),filesModified:JSON.parse(y.files_modified),rawToolOutput:y.raw_tool_output,toolName:y.tool_name,createdAt:y.created_at,tokenCount:y.token_count,discoveryTokens:y.discovery_tokens??0,importance:y.importance??3,revisionOf:y.revision_of??null,deletedAt:y.deleted_at??null,supersededBy:y.superseded_by??null,supersededAt:y.superseded_at??null}}}var qn=[{version:1,name:"create-schema",up:`
120
121
  -- Sessions table
121
122
  CREATE TABLE IF NOT EXISTS sessions (
122
123
  _rowid INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -410,24 +411,24 @@ ${E}`}return M}guide(){return["# open-mem Workflow Guide","","## Reading Memorie
410
411
  INSERT INTO entities_fts(rowid, name, entity_type)
411
412
  VALUES (new._rowid, new.name, new.entity_type);
412
413
  END;
413
- `}];function Bp(n,p){if(n.migrate(Oe),p?.hasVectorExtension&&p?.embeddingDimension&&p.embeddingDimension>0)Me(n,p.embeddingDimension)}function Me(n,p){if(n.get("SELECT name FROM sqlite_master WHERE type='table' AND name='observation_embeddings'")){let e=n.get("SELECT value FROM _embedding_meta WHERE key = 'dimension'");if(e&&Number(e.value)!==p){console.warn(`[open-mem] vec0 table exists with dimension ${e.value}, but config specifies ${p}. Drop observation_embeddings to re-create with new dimension.`);return}}else n.exec(`CREATE VIRTUAL TABLE observation_embeddings USING vec0(
414
+ `}];function hS(y,S){if(y.migrate(qn),S?.hasVectorExtension&&S?.embeddingDimension&&S.embeddingDimension>0)wn(y,S.embeddingDimension)}function wn(y,S){if(y.get("SELECT name FROM sqlite_master WHERE type='table' AND name='observation_embeddings'")){let n=y.get("SELECT value FROM _embedding_meta WHERE key = 'dimension'");if(n&&Number(n.value)!==S){console.warn(`[open-mem] vec0 table exists with dimension ${n.value}, but config specifies ${S}. Drop observation_embeddings to re-create with new dimension.`);return}}else y.exec(`CREATE VIRTUAL TABLE observation_embeddings USING vec0(
414
415
  observation_id TEXT PRIMARY KEY,
415
- embedding float[${p}] distance_metric=cosine
416
- )`);n.run("INSERT OR REPLACE INTO _embedding_meta (key, value) VALUES (?, ?)",["dimension",String(p)])}class Ln{db;constructor(n){this.db=n}create(n,p){let y=new Date().toISOString();return this.db.run(`INSERT INTO sessions (id, project_path, started_at, status)
417
- VALUES (?, ?, ?, 'active')`,[n,p,y]),this.getById(n)}getOrCreate(n,p){let y=this.getById(n);if(y)return y;return this.create(n,p)}getById(n){let p=this.db.get("SELECT * FROM sessions WHERE id = ?",[n]);return p?this.mapRow(p):null}getRecent(n,p=10){return this.db.all("SELECT * FROM sessions WHERE project_path = ? ORDER BY started_at DESC LIMIT ?",[n,p]).map((y)=>this.mapRow(y))}getAll(n){return this.db.all("SELECT * FROM sessions WHERE project_path = ? ORDER BY started_at DESC",[n]).map((p)=>this.mapRow(p))}getActive(){return this.db.all("SELECT * FROM sessions WHERE status = 'active' ORDER BY started_at DESC").map((n)=>this.mapRow(n))}updateStatus(n,p){this.db.run("UPDATE sessions SET status = ? WHERE id = ?",[p,n])}markCompleted(n){this.db.run("UPDATE sessions SET status = 'completed', ended_at = datetime('now') WHERE id = ?",[n])}incrementObservationCount(n){this.db.run("UPDATE sessions SET observation_count = observation_count + 1 WHERE id = ?",[n])}setSummary(n,p){this.db.run("UPDATE sessions SET summary_id = ? WHERE id = ?",[p,n])}mapRow(n){return{id:n.id,projectPath:n.project_path,startedAt:n.started_at,endedAt:n.ended_at??null,status:n.status,observationCount:n.observation_count,summaryId:n.summary_id??null}}}import{randomUUID as Ee}from"crypto";class ln{db;constructor(n){this.db=n}create(n){let p=Ee(),y=new Date().toISOString();return this.db.run(`INSERT INTO session_summaries
416
+ embedding float[${S}] distance_metric=cosine
417
+ )`);y.run("INSERT OR REPLACE INTO _embedding_meta (key, value) VALUES (?, ?)",["dimension",String(S)])}class Ly{db;constructor(y){this.db=y}create(y,S){let u=new Date().toISOString();return this.db.run(`INSERT INTO sessions (id, project_path, started_at, status)
418
+ VALUES (?, ?, ?, 'active')`,[y,S,u]),this.getById(y)}getOrCreate(y,S){let u=this.getById(y);if(u)return u;return this.create(y,S)}getById(y){let S=this.db.get("SELECT * FROM sessions WHERE id = ?",[y]);return S?this.mapRow(S):null}getRecent(y,S=10){return this.db.all("SELECT * FROM sessions WHERE project_path = ? ORDER BY started_at DESC LIMIT ?",[y,S]).map((u)=>this.mapRow(u))}getAll(y){return this.db.all("SELECT * FROM sessions WHERE project_path = ? ORDER BY started_at DESC",[y]).map((S)=>this.mapRow(S))}getActive(){return this.db.all("SELECT * FROM sessions WHERE status = 'active' ORDER BY started_at DESC").map((y)=>this.mapRow(y))}updateStatus(y,S){this.db.run("UPDATE sessions SET status = ? WHERE id = ?",[S,y])}markCompleted(y){this.db.run("UPDATE sessions SET status = 'completed', ended_at = datetime('now') WHERE id = ?",[y])}incrementObservationCount(y){this.db.run("UPDATE sessions SET observation_count = observation_count + 1 WHERE id = ?",[y])}setSummary(y,S){this.db.run("UPDATE sessions SET summary_id = ? WHERE id = ?",[S,y])}mapRow(y){return{id:y.id,projectPath:y.project_path,startedAt:y.started_at,endedAt:y.ended_at??null,status:y.status,observationCount:y.observation_count,summaryId:y.summary_id??null}}}import{randomUUID as ln}from"crypto";class Fy{db;constructor(y){this.db=y}create(y){let S=ln(),u=new Date().toISOString();return this.db.run(`INSERT INTO session_summaries
418
419
  (id, session_id, summary, key_decisions, files_modified,
419
420
  concepts, created_at, token_count,
420
421
  request, investigated, learned, completed, next_steps)
421
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[p,n.sessionId,n.summary,JSON.stringify(n.keyDecisions),JSON.stringify(n.filesModified),JSON.stringify(n.concepts),y,n.tokenCount,n.request??"",n.investigated??"",n.learned??"",n.completed??"",n.nextSteps??""]),{...n,id:p,createdAt:y}}importSummary(n){this.db.run(`INSERT INTO session_summaries
422
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[S,y.sessionId,y.summary,JSON.stringify(y.keyDecisions),JSON.stringify(y.filesModified),JSON.stringify(y.concepts),u,y.tokenCount,y.request??"",y.investigated??"",y.learned??"",y.completed??"",y.nextSteps??""]),{...y,id:S,createdAt:u}}importSummary(y){this.db.run(`INSERT INTO session_summaries
422
423
  (id, session_id, summary, key_decisions, files_modified,
423
424
  concepts, created_at, token_count,
424
425
  request, investigated, learned, completed, next_steps)
425
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[n.id,n.sessionId,n.summary,JSON.stringify(n.keyDecisions),JSON.stringify(n.filesModified),JSON.stringify(n.concepts),n.createdAt,n.tokenCount,n.request??"",n.investigated??"",n.learned??"",n.completed??"",n.nextSteps??""])}getBySessionId(n){let p=this.db.get("SELECT * FROM session_summaries WHERE session_id = ?",[n]);return p?this.mapRow(p):null}getRecent(n=10){return this.db.all("SELECT * FROM session_summaries ORDER BY created_at DESC LIMIT ?",[n]).map((p)=>this.mapRow(p))}search(n,p=10){return this.db.all(`SELECT ss.*
426
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[y.id,y.sessionId,y.summary,JSON.stringify(y.keyDecisions),JSON.stringify(y.filesModified),JSON.stringify(y.concepts),y.createdAt,y.tokenCount,y.request??"",y.investigated??"",y.learned??"",y.completed??"",y.nextSteps??""])}getBySessionId(y){let S=this.db.get("SELECT * FROM session_summaries WHERE session_id = ?",[y]);return S?this.mapRow(S):null}getRecent(y=10){return this.db.all("SELECT * FROM session_summaries ORDER BY created_at DESC LIMIT ?",[y]).map((S)=>this.mapRow(S))}search(y,S=10){return this.db.all(`SELECT ss.*
426
427
  FROM session_summaries ss
427
428
  JOIN summaries_fts fts ON ss._rowid = fts.rowid
428
429
  WHERE summaries_fts MATCH ?
429
430
  ORDER BY rank
430
- LIMIT ?`,[n,p]).map((y)=>this.mapRow(y))}mapRow(n){return{id:n.id,sessionId:n.session_id,summary:n.summary,keyDecisions:JSON.parse(n.key_decisions),filesModified:JSON.parse(n.files_modified),concepts:JSON.parse(n.concepts),createdAt:n.created_at,tokenCount:n.token_count,request:n.request||void 0,investigated:n.investigated||void 0,learned:n.learned||void 0,completed:n.completed||void 0,nextSteps:n.next_steps||void 0}}}import{randomUUID as ce}from"crypto";var fe=[{version:1,name:"create-user-observations",up:`
431
+ LIMIT ?`,[y,S]).map((u)=>this.mapRow(u))}mapRow(y){return{id:y.id,sessionId:y.session_id,summary:y.summary,keyDecisions:JSON.parse(y.key_decisions),filesModified:JSON.parse(y.files_modified),concepts:JSON.parse(y.concepts),createdAt:y.created_at,tokenCount:y.token_count,request:y.request||void 0,investigated:y.investigated||void 0,learned:y.learned||void 0,completed:y.completed||void 0,nextSteps:y.next_steps||void 0}}}import{randomUUID as Pn}from"crypto";var rn=[{version:1,name:"create-user-observations",up:`
431
432
  CREATE TABLE IF NOT EXISTS user_observations (
432
433
  _rowid INTEGER PRIMARY KEY AUTOINCREMENT,
433
434
  id TEXT UNIQUE NOT NULL,
@@ -498,21 +499,21 @@ ${E}`}return M}guide(){return["# open-mem Workflow Guide","","## Reading Memorie
498
499
  new.facts, new.concepts, new.files_read, new.files_modified
499
500
  );
500
501
  END;
501
- `}];class Xn{db;constructor(n){let p=Re(n);this.db=d(p),this.initializeUserSchema()}initializeUserSchema(){this.db.migrate(fe)}get database(){return this.db}close(){this.db.close()}}class Zn{db;constructor(n){this.db=n}create(n){let p=ce(),y=new Date().toISOString();return this.db.run(`INSERT INTO user_observations
502
+ `}];class Dy{db;constructor(y){let S=en(y);this.db=Sy(S),this.initializeUserSchema()}initializeUserSchema(){this.db.migrate(rn)}get database(){return this.db}close(){this.db.close()}}class Gy{db;constructor(y){this.db=y}create(y){let S=Pn(),u=new Date().toISOString();return this.db.run(`INSERT INTO user_observations
502
503
  (id, type, title, subtitle, facts, narrative,
503
504
  concepts, files_read, files_modified, tool_name,
504
505
  created_at, token_count, importance, source_project)
505
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[p,n.type,n.title,n.subtitle,JSON.stringify(n.facts),n.narrative,JSON.stringify(n.concepts),JSON.stringify(n.filesRead),JSON.stringify(n.filesModified),n.toolName,y,n.tokenCount,n.importance??3,n.sourceProject]),{...n,id:p,createdAt:y,importance:n.importance??3}}search(n){try{let p=`
506
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[S,y.type,y.title,y.subtitle,JSON.stringify(y.facts),y.narrative,JSON.stringify(y.concepts),JSON.stringify(y.filesRead),JSON.stringify(y.filesModified),y.toolName,u,y.tokenCount,y.importance??3,y.sourceProject]),{...y,id:S,createdAt:u,importance:y.importance??3}}search(y){try{let S=`
506
507
  SELECT o.*, rank
507
508
  FROM user_observations o
508
509
  JOIN user_observations_fts fts ON o._rowid = fts.rowid
509
510
  WHERE user_observations_fts MATCH ?
510
- `,y=[n.query];if(n.sourceProject)p+=" AND o.source_project = ?",y.push(n.sourceProject);return p+=" ORDER BY rank LIMIT ?",y.push(n.limit??10),this.db.all(p,y).map((e)=>({observation:this.mapRow(e),rank:e.rank}))}catch{return[]}}getIndex(n,p){let y=`SELECT id, type, title, token_count, created_at, importance, source_project
511
- FROM user_observations`,e=[];if(p)y+=" WHERE source_project = ?",e.push(p);return y+=" ORDER BY created_at DESC LIMIT ?",e.push(n??20),this.db.all(y,e).map((S)=>({id:S.id,sessionId:"",type:S.type,title:S.title,tokenCount:S.token_count,discoveryTokens:0,createdAt:S.created_at,importance:S.importance??3}))}getById(n){let p=this.db.get("SELECT * FROM user_observations WHERE id = ?",[n]);return p?this.mapRow(p):null}delete(n){return this.db.all("DELETE FROM user_observations WHERE id = ? RETURNING id",[n]).length>0}mapRow(n){return{id:n.id,type:n.type,title:n.title,subtitle:n.subtitle,facts:JSON.parse(n.facts),narrative:n.narrative,concepts:JSON.parse(n.concepts),filesRead:JSON.parse(n.files_read),filesModified:JSON.parse(n.files_modified),toolName:n.tool_name,createdAt:n.created_at,tokenCount:n.token_count,importance:n.importance??3,sourceProject:n.source_project}}}function Re(n){if(n.startsWith("~/")){let p=process.env.HOME||process.env.USERPROFILE||"";if(!p)throw Error("Cannot resolve user DB path: HOME environment variable is not set");let y=`${p}${n.slice(1)}`,e=y.substring(0,y.lastIndexOf("/"));return $("fs").mkdirSync(e,{recursive:!0}),y}return n}async function Up(n,p,y,e,S){if(!n.trim())return p;let u=Ne(n),m=new Set;for(let M of u){let E=y.findByName(M);for(let f of E){let g=y.traverseRelations(f.id,1);for(let N of g){let h=y.getObservationsForEntity(N);for(let V of h)m.add(V)}}}if(m.size===0)return p;let r=new Set(p.map((M)=>M.observation.id)),O=[];for(let M of m){if(r.has(M))continue;let E=e.getById(M);if(!E)continue;if(E.supersededBy)continue;O.push({observation:E,rank:0,snippet:E.title,source:"project",rankingSource:"graph",explain:{strategy:"hybrid",matchedBy:["graph"]}})}return[...p,...O].slice(0,S)}function Ne(n){let p=n.split(/\s+/).filter((e)=>e.length>=2),y=[];for(let e of p)y.push(e);for(let e=0;e<p.length-1;e++)y.push(`${p[e]} ${p[e+1]}`);return y}class zn{strategies=new Map;register(n,p){this.strategies.set(n,p)}get(n){return this.strategies.get(n)??null}list(){return[...this.strategies.keys()]}}function nn(n){return Array.from(new Set(n))}function Lp(n,p){let y=[],e=new Set;for(let S of n){if(e.has(S.observation.id))continue;if(e.add(S.observation.id),y.push(S),y.length>=p)break}return y}function ge(n,p){let y=p.toLowerCase();return n.some((e)=>e.toLowerCase()===y)}function he(n,p){let y=p.toLowerCase();return n.some((e)=>e.toLowerCase().includes(y))}function lp(n,p){let y=nn([...p.concept?[p.concept]:[],...p.concepts??[]]),e=nn([...p.file?[p.file]:[],...p.files??[]]);return n.filter((S)=>{let u=S.observation;if(p.type&&u.type!==p.type)return!1;if(p.importanceMin!==void 0&&u.importance<p.importanceMin)return!1;if(p.importanceMax!==void 0&&u.importance>p.importanceMax)return!1;if(p.createdAfter&&u.createdAt<p.createdAfter)return!1;if(p.createdBefore&&u.createdAt>p.createdBefore)return!1;if(y.length>0&&!y.some((m)=>ge(u.concepts,m)))return!1;if(e.length>0){let m=[...u.filesRead,...u.filesModified];if(!e.some((r)=>he(m,r)))return!1}return!0})}function W(n,p,y,e){let S=nn([...y.concept?[y.concept]:[],...y.concepts??[]]);if(S.length>0){let m=S.flatMap((O)=>n.observations.searchByConcept(O,e,y.projectPath)),r=Lp(m.map((O)=>({observation:O,rank:0,snippet:O.title,rankingSource:"graph",explain:{strategy:"filter-only",matchedBy:["concept-filter"]}})),e);return lp(r,y).slice(0,e)}let u=nn([...y.file?[y.file]:[],...y.files??[]]);if(u.length>0){let m=u.flatMap((O)=>n.observations.searchByFile(O,e,y.projectPath)),r=Lp(m.map((O)=>({observation:O,rank:0,snippet:O.title,rankingSource:"graph",explain:{strategy:"filter-only",matchedBy:["file-filter"]}})),e);return lp(r,y).slice(0,e)}return n.observations.search({query:p,type:y.type,limit:e,projectPath:y.projectPath,importanceMin:y.importanceMin,importanceMax:y.importanceMax,createdAfter:y.createdAfter,createdBefore:y.createdBefore,concepts:y.concepts,files:y.files})}function Y(n,p){if(p.type&&n.type!==p.type)return!1;if(p.importanceMin!==void 0&&n.importance<p.importanceMin)return!1;if(p.importanceMax!==void 0&&n.importance>p.importanceMax)return!1;if(p.createdAfter&&n.createdAt<p.createdAfter)return!1;if(p.createdBefore&&n.createdAt>p.createdBefore)return!1;if(p.concepts&&p.concepts.length>0){if(!p.concepts.some((e)=>n.concepts.some((S)=>S.toLowerCase().includes(e.toLowerCase()))))return!1}if(p.files&&p.files.length>0){let y=[...n.filesRead,...n.filesModified];if(!p.files.some((S)=>y.some((u)=>u.toLowerCase().includes(S.toLowerCase()))))return!1}return!0}var Xp=60;async function Zp(n,p,y,e){let S=e.limit??10,u=te(p,n,e,S);if(!y)return u;let m=await s(y,n);if(!m)return u;let r=u.map((M)=>M.observation.id),O=_e(p,m,e.projectPath,e,S,e.hasVectorExtension??!1,r);if(O.length===0)return u;return Je(u,O,S)}function te(n,p,y,e){try{return n.search({query:p,type:y.type,limit:e,projectPath:y.projectPath,importanceMin:y.importanceMin,importanceMax:y.importanceMax,createdAfter:y.createdAfter,createdBefore:y.createdBefore,concepts:y.concepts,files:y.files})}catch{return[]}}function _e(n,p,y,e,S,u,m){if(u)return Ve(n,p,e,S,m);return Ae(n,p,y,e,S)}function Ve(n,p,y,e,S){try{let u;if(S.length>0){if(u=n.searchVecSubset(p,S,e*3),u.length===0)u=n.getVecEmbeddingMatches(p,e*3)}else u=n.getVecEmbeddingMatches(p,e*3);if(u.length===0)return[];let m=[];for(let{observationId:r,distance:O}of u){if(m.length>=e)break;let M=n.getById(r);if(!M)continue;if(!Y(M,y))continue;m.push({observation:M,rank:O-1,snippet:M.title,rankingSource:"vector",explain:{strategy:"hybrid",matchedBy:["vector"],vectorDistance:O}})}return m}catch{return[]}}function Ae(n,p,y,e,S){let u=n.getWithEmbeddings(y,S*10);if(u.length===0)return[];let m=u.map((O)=>({id:O.id,similarity:Q(p,O.embedding)})).filter(({similarity:O})=>O>=0.3).sort((O,M)=>M.similarity-O.similarity),r=[];for(let{id:O,similarity:M}of m){if(r.length>=S)break;let E=n.getById(O);if(!E)continue;if(!Y(E,e))continue;r.push({observation:E,rank:-M,snippet:E.title,rankingSource:"vector",explain:{strategy:"hybrid",matchedBy:["vector"],vectorSimilarity:M}})}return r}function Je(n,p,y){let e=new Map;for(let S=0;S<n.length;S++){let u=n[S],m=1/(Xp+S+1);e.set(u.observation.id,{score:m,result:{...u,rankingSource:"fts",explain:{strategy:"hybrid",matchedBy:["fts"],ftsRank:u.rank}}})}for(let S=0;S<p.length;S++){let u=p[S],m=1/(Xp+S+1),r=e.get(u.observation.id);if(r)r.score+=m,r.result={...r.result,explain:{strategy:"hybrid",matchedBy:["fts","vector"],ftsRank:r.result.explain?.ftsRank??r.result.rank,vectorDistance:u.explain?.vectorDistance,vectorSimilarity:u.explain?.vectorSimilarity}};else e.set(u.observation.id,{score:m,result:{...u,explain:{strategy:"hybrid",matchedBy:["vector"],vectorDistance:u.explain?.vectorDistance,vectorSimilarity:u.explain?.vectorSimilarity}}})}return[...e.values()].sort((S,u)=>u.score-S.score).slice(0,y).map(({score:S,result:u})=>({...u,explain:{...u.explain??{strategy:"hybrid",matchedBy:[]},strategy:"hybrid",matchedBy:u.explain?.matchedBy??[],rrfScore:S,ftsRank:u.explain?.ftsRank,vectorDistance:u.explain?.vectorDistance,vectorSimilarity:u.explain?.vectorSimilarity}}))}async function zp(n,p,y,e){return Zp(p,n.observations,n.embeddingModel,{type:y.type,limit:e,projectPath:y.projectPath,hasVectorExtension:n.hasVectorExtension,importanceMin:y.importanceMin,importanceMax:y.importanceMax,createdAfter:y.createdAfter,createdBefore:y.createdBefore,concepts:y.concepts,files:y.files})}async function Kp(n,p,y,e){if(!n.embeddingModel)return W(n,p,y,e);let S=await s(n.embeddingModel,p);if(!S)return W(n,p,y,e);if(n.hasVectorExtension)try{let O=n.observations.getVecEmbeddingMatches(S,e*3);if(O.length===0)return[];let M=[];for(let{observationId:E,distance:f}of O){if(M.length>=e)break;let g=n.observations.getById(E);if(!g)continue;if(!Y(g,y))continue;M.push({observation:g,rank:f-1,snippet:g.title,rankingSource:"vector",explain:{strategy:"semantic",matchedBy:["vector"],vectorDistance:f}})}return M}catch{return W(n,p,y,e)}let u=n.observations.getWithEmbeddings(y.projectPath,e*10);if(u.length===0)return[];let m=u.map((O)=>({id:O.id,similarity:Q(S,O.embedding)})).filter(({similarity:O})=>O>=0.3).sort((O,M)=>M.similarity-O.similarity),r=[];for(let{id:O,similarity:M}of m){if(r.length>=e)break;let E=n.observations.getById(O);if(!E)continue;if(!Y(E,y))continue;r.push({observation:E,rank:-M,snippet:E.title,rankingSource:"vector",explain:{strategy:"semantic",matchedBy:["vector"],vectorSimilarity:M}})}return r}class Kn{observations;embeddingModel;hasVectorExtension;reranker;userObservationRepo;entityRepo;strategyRegistry;constructor(n,p,y,e=null,S=null,u=null,m=null){this.observations=n;this.embeddingModel=p;this.hasVectorExtension=y;this.reranker=e;this.userObservationRepo=S;this.entityRepo=u;if(this.strategyRegistry=m??new zn,!this.strategyRegistry.get("filter-only"))this.strategyRegistry.register("filter-only",(r,O)=>W({observations:this.observations,embeddingModel:this.embeddingModel,hasVectorExtension:this.hasVectorExtension},O.query,r,O.limit));if(!this.strategyRegistry.get("semantic"))this.strategyRegistry.register("semantic",(r,O)=>Kp({observations:this.observations,embeddingModel:this.embeddingModel,hasVectorExtension:this.hasVectorExtension},O.query,r,O.limit));if(!this.strategyRegistry.get("hybrid"))this.strategyRegistry.register("hybrid",(r,O)=>zp({observations:this.observations,embeddingModel:this.embeddingModel,hasVectorExtension:this.hasVectorExtension},O.query,r,O.limit))}async search(n,p){let y=p.strategy??"hybrid",e=p.limit??10,S=this.normalizeOptions(p),u=this.strategyRegistry.get(y);if(!u)throw Error(`Unknown search strategy: ${y}`);let m=await u(S,{query:n,limit:e});if(m=m.map((r)=>({...r,source:"project"})),this.entityRepo&&n.trim())m=await Up(n,m,this.entityRepo,this.observations,e);if(this.userObservationRepo){let r=this.searchUserMemory(n,e);m=this.mergeResults(m,r,e)}if(this.reranker&&m.length>1)return this.reranker.rerank(n,m,e);return m}normalizeOptions(n){let p=n.concept?Array.from(new Set([n.concept,...n.concepts??[]])):n.concepts,y=n.file?Array.from(new Set([n.file,...n.files??[]])):n.files;return{...n,concepts:p,files:y}}searchUserMemory(n,p){if(!this.userObservationRepo)return[];try{return this.userObservationRepo.search({query:n,limit:p}).map(({observation:e,rank:S})=>({observation:Ce(e),rank:S,snippet:e.title,source:"user",rankingSource:"user-memory",explain:{strategy:"filter-only",matchedBy:["user-memory"]}}))}catch{return[]}}mergeResults(n,p,y){let e=new Set(n.map((m)=>m.observation.id)),S=new Set(n.map((m)=>`${m.observation.title}::${m.observation.narrative}`)),u=p.filter((m)=>{if(e.has(m.observation.id))return!1;let r=`${m.observation.title}::${m.observation.narrative}`;if(S.has(r))return!1;return S.add(r),!0});return[...n,...u].slice(0,y)}}function Ce(n){return{id:n.id,sessionId:"",type:n.type,title:n.title,subtitle:n.subtitle,facts:n.facts,narrative:n.narrative,concepts:n.concepts,filesRead:n.filesRead,filesModified:n.filesModified,rawToolOutput:"",toolName:n.toolName,createdAt:n.createdAt,tokenCount:n.tokenCount,discoveryTokens:0,importance:n.importance}}import{generateText as Be}from"ai";function Hp(n,p){let y=p.map((e,S)=>` <candidate index="${S}"><title>${e.title}</title><narrative>${e.narrative}</narrative></candidate>`).join(`
511
+ `,u=[y.query];if(y.sourceProject)S+=" AND o.source_project = ?",u.push(y.sourceProject);return S+=" ORDER BY rank LIMIT ?",u.push(y.limit??10),this.db.all(S,u).map((n)=>({observation:this.mapRow(n),rank:n.rank}))}catch{return[]}}getIndex(y,S){let u=`SELECT id, type, title, token_count, created_at, importance, source_project
512
+ FROM user_observations`,n=[];if(S)u+=" WHERE source_project = ?",n.push(S);return u+=" ORDER BY created_at DESC LIMIT ?",n.push(y??20),this.db.all(u,n).map((O)=>({id:O.id,sessionId:"",type:O.type,title:O.title,tokenCount:O.token_count,discoveryTokens:0,createdAt:O.created_at,importance:O.importance??3}))}getById(y){let S=this.db.get("SELECT * FROM user_observations WHERE id = ?",[y]);return S?this.mapRow(S):null}delete(y){return this.db.all("DELETE FROM user_observations WHERE id = ? RETURNING id",[y]).length>0}mapRow(y){return{id:y.id,type:y.type,title:y.title,subtitle:y.subtitle,facts:JSON.parse(y.facts),narrative:y.narrative,concepts:JSON.parse(y.concepts),filesRead:JSON.parse(y.files_read),filesModified:JSON.parse(y.files_modified),toolName:y.tool_name,createdAt:y.created_at,tokenCount:y.token_count,importance:y.importance??3,sourceProject:y.source_project}}}function en(y){if(y.startsWith("~/")){let S=process.env.HOME||process.env.USERPROFILE||"";if(!S)throw Error("Cannot resolve user DB path: HOME environment variable is not set");let u=`${S}${y.slice(1)}`,n=u.substring(0,u.lastIndexOf("/"));return H("fs").mkdirSync(n,{recursive:!0}),u}return y}async function jS(y,S,u,n,O){if(!y.trim())return S;let M=bn(y),f=new Set;for(let R of M){let N=u.findByName(R);for(let V of N){let J=u.traverseRelations(V.id,1);for(let _ of J){let $=u.getObservationsForEntity(_);for(let U of $)f.add(U)}}}if(f.size===0)return S;let p=new Set(S.map((R)=>R.observation.id)),E=[];for(let R of f){if(p.has(R))continue;let N=n.getById(R);if(!N)continue;if(N.supersededBy)continue;E.push({observation:N,rank:0,snippet:N.title,source:"project",rankingSource:"graph",explain:{strategy:"hybrid",matchedBy:["graph"]}})}return[...S,...E].slice(0,O)}function bn(y){let S=y.split(/\s+/).filter((n)=>n.length>=2),u=[];for(let n of S)u.push(n);for(let n=0;n<S.length-1;n++)u.push(`${S[n]} ${S[n+1]}`);return u}class Ty{strategies=new Map;register(y,S){this.strategies.set(y,S)}get(y){return this.strategies.get(y)??null}list(){return[...this.strategies.keys()]}}function ny(y){return Array.from(new Set(y))}function vS(y,S){let u=[],n=new Set;for(let O of y){if(n.has(O.observation.id))continue;if(n.add(O.observation.id),u.push(O),u.length>=S)break}return u}function tn(y,S){let u=S.toLowerCase();return y.some((n)=>n.toLowerCase()===u)}function on(y,S){let u=S.toLowerCase();return y.some((n)=>n.toLowerCase().includes(u))}function xS(y,S){let u=ny([...S.concept?[S.concept]:[],...S.concepts??[]]),n=ny([...S.file?[S.file]:[],...S.files??[]]);return y.filter((O)=>{let M=O.observation;if(S.type&&M.type!==S.type)return!1;if(S.importanceMin!==void 0&&M.importance<S.importanceMin)return!1;if(S.importanceMax!==void 0&&M.importance>S.importanceMax)return!1;if(S.createdAfter&&M.createdAt<S.createdAfter)return!1;if(S.createdBefore&&M.createdAt>S.createdBefore)return!1;if(u.length>0&&!u.some((f)=>tn(M.concepts,f)))return!1;if(n.length>0){let f=[...M.filesRead,...M.filesModified];if(!n.some((p)=>on(f,p)))return!1}return!0})}function h(y,S,u,n){let O=ny([...u.concept?[u.concept]:[],...u.concepts??[]]);if(O.length>0){let f=O.flatMap((E)=>y.observations.searchByConcept(E,n,u.projectPath)),p=vS(f.map((E)=>({observation:E,rank:0,snippet:E.title,rankingSource:"graph",explain:{strategy:"filter-only",matchedBy:["concept-filter"]}})),n);return xS(p,u).slice(0,n)}let M=ny([...u.file?[u.file]:[],...u.files??[]]);if(M.length>0){let f=M.flatMap((E)=>y.observations.searchByFile(E,n,u.projectPath)),p=vS(f.map((E)=>({observation:E,rank:0,snippet:E.title,rankingSource:"graph",explain:{strategy:"filter-only",matchedBy:["file-filter"]}})),n);return xS(p,u).slice(0,n)}return y.observations.search({query:S,type:u.type,limit:n,projectPath:u.projectPath,importanceMin:u.importanceMin,importanceMax:u.importanceMax,createdAfter:u.createdAfter,createdBefore:u.createdBefore,concepts:u.concepts,files:u.files})}function j(y,S){if(S.type&&y.type!==S.type)return!1;if(S.importanceMin!==void 0&&y.importance<S.importanceMin)return!1;if(S.importanceMax!==void 0&&y.importance>S.importanceMax)return!1;if(S.createdAfter&&y.createdAt<S.createdAfter)return!1;if(S.createdBefore&&y.createdAt>S.createdBefore)return!1;if(S.concepts&&S.concepts.length>0){if(!S.concepts.some((n)=>y.concepts.some((O)=>O.toLowerCase().includes(n.toLowerCase()))))return!1}if(S.files&&S.files.length>0){let u=[...y.filesRead,...y.filesModified];if(!S.files.some((O)=>u.some((M)=>M.toLowerCase().includes(O.toLowerCase()))))return!1}return!0}var kS=60;async function IS(y,S,u,n){let O=n.limit??10,M=dn(S,y,n,O);if(!u)return M;let f=await uy(u,y);if(!f)return M;let p=M.map((R)=>R.observation.id),E=an(S,f,n.projectPath,n,O,n.hasVectorExtension??!1,p);if(E.length===0)return M;return SO(M,E,O)}function dn(y,S,u,n){try{return y.search({query:S,type:u.type,limit:n,projectPath:u.projectPath,importanceMin:u.importanceMin,importanceMax:u.importanceMax,createdAfter:u.createdAfter,createdBefore:u.createdBefore,concepts:u.concepts,files:u.files})}catch{return[]}}function an(y,S,u,n,O,M,f){if(M)return sn(y,S,n,O,f);return yO(y,S,u,n,O)}function sn(y,S,u,n,O){try{let M;if(O.length>0){if(M=y.searchVecSubset(S,O,n*3),M.length===0)M=y.getVecEmbeddingMatches(S,n*3)}else M=y.getVecEmbeddingMatches(S,n*3);if(M.length===0)return[];let f=[];for(let{observationId:p,distance:E}of M){if(f.length>=n)break;let R=y.getById(p);if(!R)continue;if(!j(R,u))continue;f.push({observation:R,rank:E-1,snippet:R.title,rankingSource:"vector",explain:{strategy:"hybrid",matchedBy:["vector"],vectorDistance:E}})}return f}catch{return[]}}function yO(y,S,u,n,O){let M=y.getWithEmbeddings(u,O*10);if(M.length===0)return[];let f=M.map((E)=>({id:E.id,similarity:T(S,E.embedding)})).filter(({similarity:E})=>E>=0.3).sort((E,R)=>R.similarity-E.similarity),p=[];for(let{id:E,similarity:R}of f){if(p.length>=O)break;let N=y.getById(E);if(!N)continue;if(!j(N,n))continue;p.push({observation:N,rank:-R,snippet:N.title,rankingSource:"vector",explain:{strategy:"hybrid",matchedBy:["vector"],vectorSimilarity:R}})}return p}function SO(y,S,u){let n=new Map;for(let O=0;O<y.length;O++){let M=y[O],f=1/(kS+O+1);n.set(M.observation.id,{score:f,result:{...M,rankingSource:"fts",explain:{strategy:"hybrid",matchedBy:["fts"],ftsRank:M.rank}}})}for(let O=0;O<S.length;O++){let M=S[O],f=1/(kS+O+1),p=n.get(M.observation.id);if(p)p.score+=f,p.result={...p.result,explain:{strategy:"hybrid",matchedBy:["fts","vector"],ftsRank:p.result.explain?.ftsRank??p.result.rank,vectorDistance:M.explain?.vectorDistance,vectorSimilarity:M.explain?.vectorSimilarity}};else n.set(M.observation.id,{score:f,result:{...M,explain:{strategy:"hybrid",matchedBy:["vector"],vectorDistance:M.explain?.vectorDistance,vectorSimilarity:M.explain?.vectorSimilarity}}})}return[...n.values()].sort((O,M)=>M.score-O.score).slice(0,u).map(({score:O,result:M})=>({...M,explain:{...M.explain??{strategy:"hybrid",matchedBy:[]},strategy:"hybrid",matchedBy:M.explain?.matchedBy??[],rrfScore:O,ftsRank:M.explain?.ftsRank,vectorDistance:M.explain?.vectorDistance,vectorSimilarity:M.explain?.vectorSimilarity}}))}async function qS(y,S,u,n){return IS(S,y.observations,y.embeddingModel,{type:u.type,limit:n,projectPath:u.projectPath,hasVectorExtension:y.hasVectorExtension,importanceMin:u.importanceMin,importanceMax:u.importanceMax,createdAfter:u.createdAfter,createdBefore:u.createdBefore,concepts:u.concepts,files:u.files})}async function wS(y,S,u,n){if(!y.embeddingModel)return h(y,S,u,n);let O=await uy(y.embeddingModel,S);if(!O)return h(y,S,u,n);if(y.hasVectorExtension)try{let E=y.observations.getVecEmbeddingMatches(O,n*3);if(E.length===0)return[];let R=[];for(let{observationId:N,distance:V}of E){if(R.length>=n)break;let J=y.observations.getById(N);if(!J)continue;if(!j(J,u))continue;R.push({observation:J,rank:V-1,snippet:J.title,rankingSource:"vector",explain:{strategy:"semantic",matchedBy:["vector"],vectorDistance:V}})}return R}catch{return h(y,S,u,n)}let M=y.observations.getWithEmbeddings(u.projectPath,n*10);if(M.length===0)return[];let f=M.map((E)=>({id:E.id,similarity:T(O,E.embedding)})).filter(({similarity:E})=>E>=0.3).sort((E,R)=>R.similarity-E.similarity),p=[];for(let{id:E,similarity:R}of f){if(p.length>=n)break;let N=y.observations.getById(E);if(!N)continue;if(!j(N,u))continue;p.push({observation:N,rank:-R,snippet:N.title,rankingSource:"vector",explain:{strategy:"semantic",matchedBy:["vector"],vectorSimilarity:R}})}return p}class hy{observations;embeddingModel;hasVectorExtension;reranker;userObservationRepo;entityRepo;strategyRegistry;constructor(y,S,u,n=null,O=null,M=null,f=null){this.observations=y;this.embeddingModel=S;this.hasVectorExtension=u;this.reranker=n;this.userObservationRepo=O;this.entityRepo=M;if(this.strategyRegistry=f??new Ty,!this.strategyRegistry.get("filter-only"))this.strategyRegistry.register("filter-only",(p,E)=>h({observations:this.observations,embeddingModel:this.embeddingModel,hasVectorExtension:this.hasVectorExtension},E.query,p,E.limit));if(!this.strategyRegistry.get("semantic"))this.strategyRegistry.register("semantic",(p,E)=>wS({observations:this.observations,embeddingModel:this.embeddingModel,hasVectorExtension:this.hasVectorExtension},E.query,p,E.limit));if(!this.strategyRegistry.get("hybrid"))this.strategyRegistry.register("hybrid",(p,E)=>qS({observations:this.observations,embeddingModel:this.embeddingModel,hasVectorExtension:this.hasVectorExtension},E.query,p,E.limit))}async search(y,S){let u=S.strategy??"hybrid",n=S.limit??10,O=this.normalizeOptions(S),M=this.strategyRegistry.get(u);if(!M)throw Error(`Unknown search strategy: ${u}`);let f=await M(O,{query:y,limit:n});if(f=f.map((p)=>({...p,source:"project"})),this.entityRepo&&y.trim())f=await jS(y,f,this.entityRepo,this.observations,n);if(this.userObservationRepo){let p=this.searchUserMemory(y,n);f=this.mergeResults(f,p,n)}if(this.reranker&&f.length>1)return this.reranker.rerank(y,f,n);return f}normalizeOptions(y){let S=y.concept?Array.from(new Set([y.concept,...y.concepts??[]])):y.concepts,u=y.file?Array.from(new Set([y.file,...y.files??[]])):y.files;return{...y,concepts:S,files:u}}searchUserMemory(y,S){if(!this.userObservationRepo)return[];try{return this.userObservationRepo.search({query:y,limit:S}).map(({observation:n,rank:O})=>({observation:uO(n),rank:O,snippet:n.title,source:"user",rankingSource:"user-memory",explain:{strategy:"filter-only",matchedBy:["user-memory"]}}))}catch{return[]}}mergeResults(y,S,u){let n=new Set(y.map((f)=>f.observation.id)),O=new Set(y.map((f)=>`${f.observation.title}::${f.observation.narrative}`)),M=S.filter((f)=>{if(n.has(f.observation.id))return!1;let p=`${f.observation.title}::${f.observation.narrative}`;if(O.has(p))return!1;return O.add(p),!0});return[...y,...M].slice(0,u)}}function uO(y){return{id:y.id,sessionId:"",type:y.type,title:y.title,subtitle:y.subtitle,facts:y.facts,narrative:y.narrative,concepts:y.concepts,filesRead:y.filesRead,filesModified:y.filesModified,rawToolOutput:"",toolName:y.toolName,createdAt:y.createdAt,tokenCount:y.tokenCount,discoveryTokens:0,importance:y.importance}}import{generateText as OO}from"ai";function lS(y,S){let u=S.map((n,O)=>` <candidate index="${O}"><title>${n.title}</title><narrative>${n.narrative}</narrative></candidate>`).join(`
512
513
  `);return`<rerank_request>
513
- <query>${n}</query>
514
+ <query>${y}</query>
514
515
  <candidates>
515
- ${y}
516
+ ${u}
516
517
  </candidates>
517
518
  <instructions>Reorder the candidates by relevance to the query. Return indices from most to least relevant.
518
519
 
@@ -523,4 +524,4 @@ Respond with EXACTLY this XML format:
523
524
  <index>0</index>
524
525
  </reranked>
525
526
  </instructions>
526
- </rerank_request>`}var $e={"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},Qp=0;async function Wp(n,p){if(!p)return;let y=$e[n]||5,e=Math.ceil(60000/y)+100,u=Date.now()-Qp;if(u<e){let m=e-u;await new Promise((r)=>setTimeout(r,m))}Qp=Date.now()}class Yp{languageModel;maxCandidates;provider;modelName;rateLimitingEnabled;_generate=Be;constructor(n,p){this.languageModel=n,this.maxCandidates=p.rerankingMaxCandidates,this.provider=p.provider??"",this.modelName=p.model??"",this.rateLimitingEnabled=p.rateLimitingEnabled??!0}async rerank(n,p,y){if(p.length<=1)return p;let e=p.slice(0,this.maxCandidates),S=p.slice(this.maxCandidates),u=Hp(n,e.map((r)=>({title:r.observation.title,narrative:r.observation.narrative}))),m=2;for(let r=0;r<=m;r++)try{if(this.provider==="google")await Wp(this.modelName,this.rateLimitingEnabled);let{text:O}=await this._generate({model:this.languageModel,maxOutputTokens:512,prompt:u}),M=In(O);if(!M)return p.slice(0,y);let E=this.applyReranking(e,M,y);for(let f of S){if(E.length>=y)break;E.push(f)}return E}catch(O){if(Ue(O)&&r<m){await Le(2**r*1000);continue}return p.slice(0,y)}return p.slice(0,y)}applyReranking(n,p,y){let e=[],S=new Set;for(let u of p)if(u>=0&&u<n.length&&!S.has(u)){if(S.add(u),e.push(n[u]),e.length>=y)break}if(e.length<y){for(let u=0;u<n.length&&e.length<y;u++)if(!S.has(u))e.push(n[u])}return e}}class ip{async rerank(n,p,y){if(p.length<=1)return p.slice(0,y);let e=Hn(n),S=p.map((u)=>({result:u,score:this.scoreCandidate(u,e)}));return S.sort((u,m)=>m.score-u.score),S.slice(0,y).map((u)=>u.result)}scoreCandidate(n,p){let y=n.observation,e=Hn(y.title),S=Hn(y.narrative),u=new Set(y.concepts.map((C)=>C.toLowerCase())),m=0,r=0,O=0;for(let C of p){if(e.has(C))m++;if(S.has(C))r++;if(u.has(C))O++}let M=p.size||1,E=m/M*0.4,f=r/M*0.3,g=O/M*0.15,h=(Date.now()-new Date(y.createdAt).getTime())/86400000,V=h<1?0.1:h<7?0.05:0,L=y.importance/5*0.05;return E+f+g+V+L}}function Dp(n,p){if(!n.rerankingEnabled)return null;if(p)return new Yp(p,n);return new ip}function Hn(n){return new Set(n.toLowerCase().split(/[\s\-_./\\,;:!?()[\]{}'"]+/).filter((p)=>p.length>1))}function Ue(n){if(typeof n!=="object"||n===null)return!1;let p=n,y=p.status;if(y===429||y===500||y===503)return!0;let e=p.error;if(typeof e==="object"&&e!==null&&e.type==="overloaded_error")return!0;return!1}function Le(n){return new Promise((p)=>setTimeout(p,n))}function kp(n){return n}function Fp(n){return n}function Tp(n){return n}function Gp(n){if(!n)return null;return n}import{spawnSync as vp}from"child_process";import{dirname as le,resolve as xp}from"path";function Xe(n){try{let p=vp("git",["rev-parse","--git-common-dir"],{cwd:n,encoding:"utf-8",timeout:5000});if(p.status!==0||!p.stdout)return null;let y=p.stdout.trim();if(y===".git")return null;let e=vp("git",["rev-parse","--git-dir"],{cwd:n,encoding:"utf-8",timeout:5000});if(e.status!==0||!e.stdout)return null;let S=e.stdout.trim(),u=xp(n,y),m=xp(n,S);if(u===m)return null;let r=le(u);if(r===u||r==="/")return null;return r}catch{return null}}function jp(n){return Xe(n)??n}var __dirname="/Users/clopca/dev/github/open-mem/src",{values:Pp}=Ke({options:{project:{type:"string",short:"p"}},strict:!1}),He=typeof Pp.project==="string"?Pp.project:process.cwd(),Ip=jp(He),R=T(Ip);a.enableExtensionSupport();var J=d(R.dbPath);Bp(J,{hasVectorExtension:J.hasVectorExtension,embeddingDimension:R.embeddingDimension});var Qe=new Ln(J),qp=new Un(J),We=new ln(J),Ye=new Jn(J),ie=new Bn(J),i=null,Qn=null;if(R.userMemoryEnabled)try{i=new Xn(R.userMemoryDbPath),Qn=new Zn(i.database)}catch(n){console.error(`[open-mem-mcp] Failed to initialize user-level memory: ${n}`)}var wp=R.provider!=="bedrock",De=R.compressionEnabled&&(!wp||R.apiKey)?kn({provider:R.provider,model:R.model,apiKey:R.apiKey}):null,ke=Dp(R,R.rerankingEnabled&&(!wp||R.apiKey)?Tn({provider:R.provider,model:R.model,apiKey:R.apiKey},Fn(R)):null),Fe=new $n(J),Te=new Kn(qp,De,J.hasVectorExtension,ke,Qn,Fe),Ge=JSON.parse(Ze(ze(__dirname,"..","package.json"),"utf-8")),ve=new en({memoryEngine:new An({observations:kp(qp),sessions:Fp(Qe),summaries:Tp(We),searchOrchestrator:Te,projectPath:Ip,config:R,userObservationRepo:Gp(Qn),configAuditStore:Ye,maintenanceHistoryStore:ie}),version:Ge.version,protocolVersion:R.mcpProtocolVersion,supportedProtocolVersions:R.mcpSupportedProtocolVersions}),pn=!1,bp=()=>{if(!pn){if(pn=!0,i)i.close();J.close()}process.exit(0)};process.on("SIGINT",bp);process.on("SIGTERM",bp);process.on("beforeExit",()=>{if(!pn){if(pn=!0,i)i.close();J.close()}});ve.start();
527
+ </rerank_request>`}var nO={"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},PS=0;async function rS(y,S){if(!S)return;let u=nO[y]||5,n=Math.ceil(60000/u)+100,M=Date.now()-PS;if(M<n){let f=n-M;await new Promise((p)=>setTimeout(p,f))}PS=Date.now()}class eS{languageModel;maxCandidates;provider;modelName;rateLimitingEnabled;_generate=OO;constructor(y,S){this.languageModel=y,this.maxCandidates=S.rerankingMaxCandidates,this.provider=S.provider??"",this.modelName=S.model??"",this.rateLimitingEnabled=S.rateLimitingEnabled??!0}async rerank(y,S,u){if(S.length<=1)return S;let n=S.slice(0,this.maxCandidates),O=S.slice(this.maxCandidates),M=lS(y,n.map((p)=>({title:p.observation.title,narrative:p.observation.narrative}))),f=2;for(let p=0;p<=f;p++)try{if(this.provider==="google")await rS(this.modelName,this.rateLimitingEnabled);let{text:E}=await this._generate({model:this.languageModel,maxOutputTokens:512,prompt:M}),R=ty(E);if(!R)return S.slice(0,u);let N=this.applyReranking(n,R,u);for(let V of O){if(N.length>=u)break;N.push(V)}return N}catch(E){if(MO(E)&&p<f){await fO(2**p*1000);continue}return S.slice(0,u)}return S.slice(0,u)}applyReranking(y,S,u){let n=[],O=new Set;for(let M of S)if(M>=0&&M<y.length&&!O.has(M)){if(O.add(M),n.push(y[M]),n.length>=u)break}if(n.length<u){for(let M=0;M<y.length&&n.length<u;M++)if(!O.has(M))n.push(y[M])}return n}}class iS{async rerank(y,S,u){if(S.length<=1)return S.slice(0,u);let n=jy(y),O=S.map((M)=>({result:M,score:this.scoreCandidate(M,n)}));return O.sort((M,f)=>f.score-M.score),O.slice(0,u).map((M)=>M.result)}scoreCandidate(y,S){let u=y.observation,n=jy(u.title),O=jy(u.narrative),M=new Set(u.concepts.map((X)=>X.toLowerCase())),f=0,p=0,E=0;for(let X of S){if(n.has(X))f++;if(O.has(X))p++;if(M.has(X))E++}let R=S.size||1,N=f/R*0.4,V=p/R*0.3,J=E/R*0.15,$=(Date.now()-new Date(u.createdAt).getTime())/86400000,U=$<1?0.1:$<7?0.05:0,c=u.importance/5*0.05;return N+V+J+U+c}}function bS(y,S){if(!y.rerankingEnabled)return null;if(S)return new eS(S,y);return new iS}function jy(y){return new Set(y.toLowerCase().split(/[\s\-_./\\,;:!?()[\]{}'"]+/).filter((S)=>S.length>1))}function MO(y){if(typeof y!=="object"||y===null)return!1;let S=y,u=S.status;if(u===429||u===500||u===503)return!0;let n=S.error;if(typeof n==="object"&&n!==null&&n.type==="overloaded_error")return!0;return!1}function fO(y){return new Promise((S)=>setTimeout(S,y))}function tS(y){return y}function oS(y){return y}function dS(y){return y}function aS(y){if(!y)return null;return y}import{spawnSync as sS}from"child_process";import{dirname as pO,resolve as yu}from"path";function EO(y){try{let S=sS("git",["rev-parse","--git-common-dir"],{cwd:y,encoding:"utf-8",timeout:5000});if(S.status!==0||!S.stdout)return null;let u=S.stdout.trim();if(u===".git")return null;let n=sS("git",["rev-parse","--git-dir"],{cwd:y,encoding:"utf-8",timeout:5000});if(n.status!==0||!n.stdout)return null;let O=n.stdout.trim(),M=yu(y,u),f=yu(y,O);if(M===f)return null;let p=pO(M);if(p===M||p==="/")return null;return p}catch{return null}}function Su(y){return EO(y)??y}var __dirname="/Users/clopca/dev/github/open-mem/src",{values:uu}=mO({options:{project:{type:"string",short:"p"}},strict:!1}),VO=typeof uu.project==="string"?uu.project:process.cwd(),nu=Su(VO),A=q(nu);yy.enableExtensionSupport();var Z=Sy(A.dbPath);hS(Z,{hasVectorExtension:Z.hasVectorExtension,embeddingDimension:A.embeddingDimension});var JO=new Ly(Z),Ou=new Qy(Z),_O=new Fy(Z),AO=new Ky(Z),$O=new Wy(Z),v=null,vy=null;if(A.userMemoryEnabled)try{v=new Dy(A.userMemoryDbPath),vy=new Gy(v.database)}catch(y){console.error(`[open-mem-mcp] Failed to initialize user-level memory: ${y}`)}var Mu=A.provider!=="bedrock",gO=A.compressionEnabled&&(!Mu||A.apiKey)?qy({provider:A.provider,model:A.model,apiKey:A.apiKey}):null,CO=bS(A,A.rerankingEnabled&&(!Mu||A.apiKey)?ly({provider:A.provider,model:A.model,apiKey:A.apiKey},wy(A)):null),UO=new zy(Z),BO=new hy(Ou,gO,Z.hasVectorExtension,CO,vy,UO),ZO=JSON.parse(RO(NO(__dirname,"..","package.json"),"utf-8")),XO=new fy({memoryEngine:new Hy({observations:tS(Ou),sessions:oS(JO),summaries:dS(_O),searchOrchestrator:BO,projectPath:nu,config:A,userObservationRepo:aS(vy),configAuditStore:AO,maintenanceHistoryStore:$O}),version:ZO.version,protocolVersion:A.mcpProtocolVersion,supportedProtocolVersions:A.mcpSupportedProtocolVersions}),Oy=!1,fu=()=>{if(!Oy){if(Oy=!0,v)v.close();Z.close()}process.exit(0)};process.on("SIGINT",fu);process.on("SIGTERM",fu);process.on("beforeExit",()=>{if(!Oy){if(Oy=!0,v)v.close();Z.close()}});XO.start();