open-mem 0.7.2 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -57,7 +57,7 @@ import{rmSync as T}from"fs";import{parseArgs as jH}from"util";import{existsSync
57
57
  FROM observation_embeddings
58
58
  WHERE embedding MATCH ? AND k = ?`,[Q,J]).map((Z)=>({observationId:Z.observation_id,distance:Z.distance}))}catch{return[]}}searchVecSubset(H,J,Q){if(J.length===0)return[];try{let Z=new Float32Array(H),$=Math.max(Q*5,J.length),K=this.db.all(`SELECT observation_id, distance
59
59
  FROM observation_embeddings
60
- WHERE embedding MATCH ? AND k = ?`,[Z,$]),W=new Set(J);return K.filter((X)=>W.has(X.observation_id)).slice(0,Q).map((X)=>({observationId:X.observation_id,distance:X.distance}))}catch{return[]}}update(H,J){let Q=this.getById(H);if(!Q)return null;if(Object.keys(J).length===0)return Q;let Z=this.create({sessionId:Q.sessionId,scope:Q.scope??"project",type:J.type??Q.type,title:J.title??Q.title,subtitle:J.subtitle??Q.subtitle,facts:J.facts??Q.facts,narrative:J.narrative??Q.narrative,concepts:J.concepts??Q.concepts,filesRead:J.filesRead??Q.filesRead,filesModified:J.filesModified??Q.filesModified,rawToolOutput:Q.rawToolOutput,toolName:"memory.revise",tokenCount:Q.tokenCount,discoveryTokens:Q.discoveryTokens,importance:J.importance??Q.importance});return this.db.run("UPDATE observations SET revision_of = ? WHERE id = ?",[H,Z.id]),this.supersede(H,Z.id),this.getById(Z.id)}supersede(H,J){let Q=new Date().toISOString();this.db.run("UPDATE observations SET superseded_by = ?, superseded_at = ? WHERE id = ?",[J,Q,H])}delete(H){if(this.db.all("SELECT id FROM observations WHERE id = ?",[H]).length===0)return!1;let Q=new Date().toISOString();return this.db.run("UPDATE observations SET deleted_at = ? WHERE id = ?",[Q,H]),this.deleteEmbeddingsForObservations([H]),!0}getLineage(H){let J=this.getByIdIncludingArchived(H);if(!J)return[];let Q=new Set([J.id]),Z=[J];while(Z[0].revisionOf){let $=this.getByIdIncludingArchived(Z[0].revisionOf);if(!$||Q.has($.id))break;Z.unshift($),Q.add($.id)}while(Z[Z.length-1].supersededBy){let $=Z[Z.length-1].supersededBy;if(!$)break;let K=this.getByIdIncludingArchived($);if(!K||Q.has(K.id))break;Z.push(K),Q.add(K.id)}return Z}deleteOlderThan(H){return this.db.all(`DELETE FROM observations
60
+ WHERE embedding MATCH ? AND k = ?`,[Z,$]),W=new Set(J);return K.filter((X)=>W.has(X.observation_id)).slice(0,Q).map((X)=>({observationId:X.observation_id,distance:X.distance}))}catch{return[]}}update(H,J){let Q=this.getById(H);if(!Q)return null;if(Object.keys(J).length===0)return Q;let Z=this.create({sessionId:Q.sessionId,scope:Q.scope??"project",type:J.type??Q.type,title:J.title??Q.title,subtitle:J.subtitle??Q.subtitle,facts:J.facts??Q.facts,narrative:J.narrative??Q.narrative,concepts:J.concepts??Q.concepts,filesRead:J.filesRead??Q.filesRead,filesModified:J.filesModified??Q.filesModified,rawToolOutput:Q.rawToolOutput,toolName:"mem-revise",tokenCount:Q.tokenCount,discoveryTokens:Q.discoveryTokens,importance:J.importance??Q.importance});return this.db.run("UPDATE observations SET revision_of = ? WHERE id = ?",[H,Z.id]),this.supersede(H,Z.id),this.getById(Z.id)}supersede(H,J){let Q=new Date().toISOString();this.db.run("UPDATE observations SET superseded_by = ?, superseded_at = ? WHERE id = ?",[J,Q,H])}delete(H){if(this.db.all("SELECT id FROM observations WHERE id = ?",[H]).length===0)return!1;let Q=new Date().toISOString();return this.db.run("UPDATE observations SET deleted_at = ? WHERE id = ?",[Q,H]),this.deleteEmbeddingsForObservations([H]),!0}getLineage(H){let J=this.getByIdIncludingArchived(H);if(!J)return[];let Q=new Set([J.id]),Z=[J];while(Z[0].revisionOf){let $=this.getByIdIncludingArchived(Z[0].revisionOf);if(!$||Q.has($.id))break;Z.unshift($),Q.add($.id)}while(Z[Z.length-1].supersededBy){let $=Z[Z.length-1].supersededBy;if(!$)break;let K=this.getByIdIncludingArchived($);if(!K||Q.has(K.id))break;Z.push(K),Q.add(K.id)}return Z}deleteOlderThan(H){return this.db.all(`DELETE FROM observations
61
61
  WHERE (created_at < datetime('now', '-' || ? || ' days') OR deleted_at IS NOT NULL)
62
62
  AND session_id NOT IN (SELECT id FROM sessions WHERE status != 'completed')
63
63
  RETURNING id`,[H]).length}deleteEmbeddingsForObservations(H){if(H.length===0)return;let J=H.map(()=>"?").join(",");try{this.db.run(`DELETE FROM observation_embeddings WHERE observation_id IN (${J})`,H)}catch{}this.db.run(`UPDATE observations SET embedding = NULL WHERE id IN (${J})`,H)}mapRow(H){return{id:H.id,sessionId:H.session_id,scope:H.scope??"project",type:H.type,title:H.title,subtitle:H.subtitle,facts:JSON.parse(H.facts),narrative:H.narrative,concepts:JSON.parse(H.concepts),filesRead:JSON.parse(H.files_read),filesModified:JSON.parse(H.files_modified),rawToolOutput:H.raw_tool_output,toolName:H.tool_name,createdAt:H.created_at,tokenCount:H.token_count,discoveryTokens:H.discovery_tokens??0,importance:H.importance??3,revisionOf:H.revision_of??null,deletedAt:H.deleted_at??null,supersededBy:H.superseded_by??null,supersededAt:H.superseded_at??null}}}var WH=[{version:1,name:"create-schema",up:`
package/dist/mcp.js CHANGED
@@ -1,26 +1,26 @@
1
1
  #!/usr/bin/env bun
2
2
  // @bun
3
- var RM=Object.defineProperty;var HM=(E,M)=>{for(var N in M)RM(E,N,{get:M[N],enumerable:!0,configurable:!0,set:(_)=>M[N]=()=>_})};var ZE=(E,M)=>()=>(E&&(M=E(E=0)),M);var U=import.meta.require;import{existsSync as UM,readFileSync as BM}from"fs";function FM(){let E={};if(process.env.OPEN_MEM_DB_PATH)E.dbPath=process.env.OPEN_MEM_DB_PATH;if(process.env.OPEN_MEM_PROVIDER)E.provider=process.env.OPEN_MEM_PROVIDER;if(process.env.OPEN_MEM_MODEL)E.model=process.env.OPEN_MEM_MODEL;if(process.env.OPEN_MEM_MAX_CONTEXT_TOKENS)E.maxContextTokens=Number.parseInt(process.env.OPEN_MEM_MAX_CONTEXT_TOKENS,10);if(process.env.OPEN_MEM_COMPRESSION==="false")E.compressionEnabled=!1;if(process.env.OPEN_MEM_CONTEXT_INJECTION==="false")E.contextInjectionEnabled=!1;if(process.env.OPEN_MEM_IGNORED_TOOLS)E.ignoredTools=process.env.OPEN_MEM_IGNORED_TOOLS.split(",").map((M)=>M.trim());if(process.env.OPEN_MEM_BATCH_SIZE)E.batchSize=Number.parseInt(process.env.OPEN_MEM_BATCH_SIZE,10);if(process.env.OPEN_MEM_RETENTION_DAYS)E.retentionDays=Number.parseInt(process.env.OPEN_MEM_RETENTION_DAYS,10);if(process.env.OPEN_MEM_LOG_LEVEL)E.logLevel=process.env.OPEN_MEM_LOG_LEVEL;if(process.env.OPEN_MEM_CONTEXT_SHOW_TOKEN_COSTS==="false")E.contextShowTokenCosts=!1;if(process.env.OPEN_MEM_CONTEXT_TYPES)E.contextObservationTypes=process.env.OPEN_MEM_CONTEXT_TYPES==="all"?"all":process.env.OPEN_MEM_CONTEXT_TYPES.split(",").map((M)=>M.trim());if(process.env.OPEN_MEM_CONTEXT_FULL_COUNT)E.contextFullObservationCount=Number.parseInt(process.env.OPEN_MEM_CONTEXT_FULL_COUNT,10);if(process.env.OPEN_MEM_MAX_OBSERVATIONS)E.maxObservations=Number.parseInt(process.env.OPEN_MEM_MAX_OBSERVATIONS,10);if(process.env.OPEN_MEM_CONTEXT_SHOW_LAST_SUMMARY==="false")E.contextShowLastSummary=!1;if(process.env.OPEN_MEM_RATE_LIMITING==="false")E.rateLimitingEnabled=!1;if(process.env.OPEN_MEM_FOLDER_CONTEXT==="false")E.folderContextEnabled=!1;if(process.env.OPEN_MEM_FOLDER_CONTEXT_MAX_DEPTH)E.folderContextMaxDepth=Number.parseInt(process.env.OPEN_MEM_FOLDER_CONTEXT_MAX_DEPTH,10);if(process.env.OPEN_MEM_DAEMON==="true")E.daemonEnabled=!0;if(process.env.OPEN_MEM_DASHBOARD==="true")E.dashboardEnabled=!0;if(process.env.OPEN_MEM_DASHBOARD_PORT)E.dashboardPort=Number.parseInt(process.env.OPEN_MEM_DASHBOARD_PORT,10);if(process.env.OPEN_MEM_PLATFORM_OPENCODE==="false")E.platformOpenCodeEnabled=!1;if(process.env.OPEN_MEM_PLATFORM_CLAUDE_CODE==="true")E.platformClaudeCodeEnabled=!0;if(process.env.OPEN_MEM_PLATFORM_CURSOR==="true")E.platformCursorEnabled=!0;if(process.env.OPEN_MEM_MCP_COMPAT_MODE)E.mcpCompatibilityMode=process.env.OPEN_MEM_MCP_COMPAT_MODE;if(process.env.OPEN_MEM_MCP_PROTOCOL_VERSION)E.mcpProtocolVersion=process.env.OPEN_MEM_MCP_PROTOCOL_VERSION;if(process.env.OPEN_MEM_MCP_SUPPORTED_PROTOCOLS)E.mcpSupportedProtocolVersions=process.env.OPEN_MEM_MCP_SUPPORTED_PROTOCOLS.split(",").map((M)=>M.trim()).filter(Boolean);if(process.env.OPEN_MEM_EMBEDDING_DIMENSION)E.embeddingDimension=Number.parseInt(process.env.OPEN_MEM_EMBEDDING_DIMENSION,10);if(process.env.OPEN_MEM_CONFLICT_RESOLUTION==="true")E.conflictResolutionEnabled=!0;if(process.env.OPEN_MEM_CONFLICT_BAND_LOW){let M=Number.parseFloat(process.env.OPEN_MEM_CONFLICT_BAND_LOW);if(!Number.isNaN(M))E.conflictSimilarityBandLow=M}if(process.env.OPEN_MEM_CONFLICT_BAND_HIGH){let M=Number.parseFloat(process.env.OPEN_MEM_CONFLICT_BAND_HIGH);if(!Number.isNaN(M))E.conflictSimilarityBandHigh=M}if(process.env.OPEN_MEM_USER_MEMORY==="true")E.userMemoryEnabled=!0;if(process.env.OPEN_MEM_USER_MEMORY_DB_PATH)E.userMemoryDbPath=process.env.OPEN_MEM_USER_MEMORY_DB_PATH;if(process.env.OPEN_MEM_USER_MEMORY_MAX_TOKENS)E.userMemoryMaxContextTokens=Number.parseInt(process.env.OPEN_MEM_USER_MEMORY_MAX_TOKENS,10);if(process.env.OPEN_MEM_RERANKING==="true")E.rerankingEnabled=!0;if(process.env.OPEN_MEM_RERANKING_MAX_CANDIDATES)E.rerankingMaxCandidates=Number.parseInt(process.env.OPEN_MEM_RERANKING_MAX_CANDIDATES,10);if(process.env.OPEN_MEM_ENTITY_EXTRACTION==="true")E.entityExtractionEnabled=!0;return E}function GM(E){let M=`${E}/.open-mem/config.json`;if(!UM(M))return{};try{let N=BM(M,"utf-8"),_=JSON.parse(N);if(!_||typeof _!=="object"||Array.isArray(_))return{};return _}catch{return{}}}function DM(E){switch(E){case"google":return 768;case"openai":return 1536;case"bedrock":return 1024;case"anthropic":return 0;default:return 768}}function m(E,M){let N=GM(E),_=FM(),O={...LE,...N,..._,...M};if(!O.dbPath.startsWith("/"))O.dbPath=`${E}/${O.dbPath}`;if(!process.env.OPEN_MEM_PROVIDER&&!M?.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"}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"bedrock":break}if(O.embeddingDimension===void 0)O.embeddingDimension=DM(O.provider);return O}function d(){return{...LE}}var LE;var i=ZE(()=>{LE={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,daemonEnabled:!1,dashboardEnabled:!1,dashboardPort:3737,platformOpenCodeEnabled:!0,platformClaudeCodeEnabled:!1,platformCursorEnabled:!1,mcpCompatibilityMode:"strict",mcpProtocolVersion:"2024-11-05",mcpSupportedProtocolVersions:["2024-11-05"],embeddingDimension:void 0,conflictResolutionEnabled:!1,conflictSimilarityBandLow:0.7,conflictSimilarityBandHigh:0.92,userMemoryEnabled:!1,userMemoryDbPath:"~/.config/open-mem/user-memory.db",userMemoryMaxContextTokens:1000,rerankingEnabled:!1,rerankingMaxCandidates:20,entityExtractionEnabled:!1}});var hE={};HM(hE,{writeProjectConfig:()=>IE,validatePatch:()=>t,readProjectConfig:()=>q,previewConfig:()=>R0,patchConfig:()=>H0,getEffectiveConfig:()=>p,getConfigSchema:()=>Z0});import{existsSync as O0}from"fs";import{mkdir as J0,readFile as S0,writeFile as V0}from"fs/promises";import{dirname as C0,join as A0}from"path";function vE(E){return A0(E,".open-mem","config.json")}function gE(E){return pE.find((M)=>M.key===E)}function X0(E,M){let N=gE(E);if(!N)return null;if(N.type==="string"&&typeof M!=="string")return`${String(E)} must be a string`;if(N.type==="number"&&typeof M!=="number")return`${String(E)} must be a number`;if(N.type==="boolean"&&typeof M!=="boolean")return`${String(E)} must be a boolean`;if(N.type==="array"&&!Array.isArray(M))return`${String(E)} must be an array`;if(N.enum&&typeof M==="string"&&!N.enum.includes(M))return`${String(E)} must be one of: ${N.enum.join(", ")}`;if(typeof M==="number"){if(N.min!==void 0&&M<N.min)return`${String(E)} must be >= ${N.min}`;if(N.max!==void 0&&M>N.max)return`${String(E)} must be <= ${N.max}`}return null}function Z0(){return pE}async function q(E){let M=vE(E);if(!O0(M))return{};try{let N=await S0(M,"utf-8"),_=JSON.parse(N);if(!_||typeof _!=="object"||Array.isArray(_))return{};return _}catch{return{}}}async function IE(E,M){let N=vE(E),O={...await q(E),...M};await J0(C0(N),{recursive:!0}),await V0(N,JSON.stringify(O,null,2),"utf-8")}function t(E){let M=[];for(let[N,_]of Object.entries(E)){let J=X0(N,_);if(J)M.push(J)}return M}async function p(E){let M=d(),N=await q(E),_=m(E),O=[],J={};for(let[S,V]of Object.entries(M)){let C=S,A=gE(C),H=($0[C]??[]).some((D)=>typeof process.env[D]==="string"),Y=Object.hasOwn(N,C),B="default";if(Y)B="file";if(H)B="env";if(J[C]={source:B,locked:H,restartRequired:A?.restartRequired??!1,liveApply:A?.liveApply??!1},B==="env"&&Y)O.push(`${String(C)} is overridden by environment variable.`);if(_[C]===void 0&&V!==void 0)O.push(`${String(C)} resolved to undefined unexpectedly.`)}return{config:_,meta:J,warnings:O}}async function R0(E,M){let N=t(M);if(N.length>0)return{...await p(E),warnings:N};let _=d(),O=await q(E),J={..._,...O,...M},V={...m(E,M),...J},C=(await p(E)).meta;return{config:V,meta:C,warnings:[]}}async function H0(E,M){let N=t(M);if(N.length>0)return{...await p(E),warnings:N};return await IE(E,M),p(E)}var pE,$0;var qE=ZE(()=>{i();pE=[{key:"dbPath",label:"Database Path",type:"string",group:"Storage",liveApply:!1,restartRequired:!0},{key:"provider",label:"Provider",type:"string",group:"AI",liveApply:!1,restartRequired:!0,enum:["google","anthropic","openai","bedrock"]},{key:"model",label:"Model",type:"string",group:"AI",liveApply:!1,restartRequired:!0},{key:"maxTokensPerCompression",label:"Max Tokens Per Compression",type:"number",group:"AI",liveApply:!0,restartRequired:!1,min:128,max:8192},{key:"compressionEnabled",label:"Compression Enabled",type:"boolean",group:"Behavior",liveApply:!0,restartRequired:!1},{key:"contextInjectionEnabled",label:"Context Injection Enabled",type:"boolean",group:"Behavior",liveApply:!0,restartRequired:!1},{key:"maxContextTokens",label:"Max Context Tokens",type:"number",group:"Behavior",liveApply:!0,restartRequired:!1,min:500,max:64000},{key:"batchSize",label:"Batch Size",type:"number",group:"Behavior",liveApply:!0,restartRequired:!1,min:1,max:100},{key:"batchIntervalMs",label:"Batch Interval (ms)",type:"number",group:"Behavior",liveApply:!0,restartRequired:!1,min:1000,max:300000},{key:"ignoredTools",label:"Ignored Tools",type:"array",group:"Filtering",liveApply:!0,restartRequired:!1},{key:"minOutputLength",label:"Min Output Length",type:"number",group:"Filtering",liveApply:!0,restartRequired:!1,min:0,max:1e4},{key:"maxObservations",label:"Max Observations",type:"number",group:"Progressive Disclosure",liveApply:!0,restartRequired:!1,min:1,max:200},{key:"contextFullObservationCount",label:"Full Observation Count",type:"number",group:"Progressive Disclosure",liveApply:!0,restartRequired:!1,min:0,max:20},{key:"contextShowTokenCosts",label:"Show Token Costs",type:"boolean",group:"Progressive Disclosure",liveApply:!0,restartRequired:!1},{key:"sensitivePatterns",label:"Sensitive Patterns",type:"array",group:"Privacy",liveApply:!0,restartRequired:!1},{key:"retentionDays",label:"Retention Days",type:"number",group:"Data Retention",liveApply:!1,restartRequired:!0,min:0,max:3650},{key:"maxDatabaseSizeMb",label:"Max Database Size (MB)",type:"number",group:"Data Retention",liveApply:!1,restartRequired:!0,min:0,max:1e5},{key:"dashboardEnabled",label:"Dashboard Enabled",type:"boolean",group:"Dashboard",liveApply:!1,restartRequired:!0},{key:"dashboardPort",label:"Dashboard Port",type:"number",group:"Dashboard",liveApply:!1,restartRequired:!0,min:1,max:65535},{key:"platformOpenCodeEnabled",label:"OpenCode Adapter",type:"boolean",group:"Advanced",liveApply:!1,restartRequired:!0},{key:"platformClaudeCodeEnabled",label:"Claude Code Adapter",type:"boolean",group:"Advanced",liveApply:!1,restartRequired:!0},{key:"platformCursorEnabled",label:"Cursor Adapter",type:"boolean",group:"Advanced",liveApply:!1,restartRequired:!0},{key:"mcpCompatibilityMode",label:"MCP Compatibility Mode",type:"string",group:"Advanced",liveApply:!1,restartRequired:!0,enum:["strict","legacy"]},{key:"mcpProtocolVersion",label:"MCP Protocol Version",type:"string",group:"Advanced",liveApply:!1,restartRequired:!0},{key:"mcpSupportedProtocolVersions",label:"MCP Supported Protocols",type:"array",group:"Advanced",liveApply:!1,restartRequired:!0},{key:"rerankingEnabled",label:"Reranking Enabled",type:"boolean",group:"Advanced",liveApply:!0,restartRequired:!1},{key:"entityExtractionEnabled",label:"Entity Extraction Enabled",type:"boolean",group:"Advanced",liveApply:!0,restartRequired:!1},{key:"userMemoryEnabled",label:"User Memory Enabled",type:"boolean",group:"Advanced",liveApply:!1,restartRequired:!0},{key:"userMemoryMaxContextTokens",label:"User Memory Max Context Tokens",type:"number",group:"Advanced",liveApply:!0,restartRequired:!1,min:0,max:8000}],$0={dbPath:["OPEN_MEM_DB_PATH"],provider:["OPEN_MEM_PROVIDER"],model:["OPEN_MEM_MODEL"],compressionEnabled:["OPEN_MEM_COMPRESSION"],contextInjectionEnabled:["OPEN_MEM_CONTEXT_INJECTION"],maxContextTokens:["OPEN_MEM_MAX_CONTEXT_TOKENS"],ignoredTools:["OPEN_MEM_IGNORED_TOOLS"],batchSize:["OPEN_MEM_BATCH_SIZE"],retentionDays:["OPEN_MEM_RETENTION_DAYS"],contextShowTokenCosts:["OPEN_MEM_CONTEXT_SHOW_TOKEN_COSTS"],contextFullObservationCount:["OPEN_MEM_CONTEXT_FULL_COUNT"],maxObservations:["OPEN_MEM_MAX_OBSERVATIONS"],dashboardEnabled:["OPEN_MEM_DASHBOARD"],dashboardPort:["OPEN_MEM_DASHBOARD_PORT"],platformOpenCodeEnabled:["OPEN_MEM_PLATFORM_OPENCODE"],platformClaudeCodeEnabled:["OPEN_MEM_PLATFORM_CLAUDE_CODE"],platformCursorEnabled:["OPEN_MEM_PLATFORM_CURSOR"],mcpCompatibilityMode:["OPEN_MEM_MCP_COMPAT_MODE"],mcpProtocolVersion:["OPEN_MEM_MCP_PROTOCOL_VERSION"],mcpSupportedProtocolVersions:["OPEN_MEM_MCP_SUPPORTED_PROTOCOLS"],rerankingEnabled:["OPEN_MEM_RERANKING"],userMemoryEnabled:["OPEN_MEM_USER_MEMORY"]}});import{readFileSync as x0}from"fs";import{join as u0}from"path";import{parseArgs as w0}from"util";import{createInterface as KM}from"readline";import{z as F}from"zod";import{z as X}from"zod";var v=X.enum(["decision","bugfix","feature","refactor","discovery","change"]);function K(E,M={}){return{data:E,error:null,meta:M}}function z(E,M,N){return{data:null,error:{code:E,message:M,details:N},meta:{}}}var Z={find:X.object({query:X.string().min(1),scope:X.enum(["project","user","all"]).optional().default("project"),types:X.array(v).optional(),limit:X.number().int().min(1).max(50).optional().default(10),cursor:X.string().optional(),include:X.object({snippets:X.boolean().optional(),scores:X.boolean().optional(),relations:X.boolean().optional()}).optional()}),history:X.object({limit:X.number().int().min(1).max(20).optional().default(5),cursor:X.string().optional(),sessionId:X.string().optional()}),get:X.object({ids:X.array(X.string()).min(1),includeHistory:X.boolean().optional().default(!1),limit:X.number().int().min(1).max(50).optional().default(10)}),create:X.object({title:X.string(),type:v,narrative:X.string(),concepts:X.array(X.string()).optional(),files:X.array(X.string()).optional(),importance:X.number().int().min(1).max(5).optional(),scope:X.enum(["project","user"]).optional().default("project")}),revise:X.object({id:X.string(),title:X.string().optional(),narrative:X.string().optional(),type:v.optional(),concepts:X.array(X.string()).optional(),importance:X.number().int().min(1).max(5).optional(),reason:X.string().optional()}),remove:X.object({id:X.string(),reason:X.string().optional()}),transferExport:X.object({scope:X.enum(["project"]).optional().default("project"),type:v.optional(),limit:X.number().int().min(1).optional(),format:X.enum(["json"]).optional().default("json")}),transferImport:X.object({payload:X.string(),mode:X.enum(["skip","merge","replace"]).optional().default("skip")}),maintenance:X.object({action:X.enum(["folderContextDryRun","folderContextClean","folderContextRebuild"])}),help:X.object({})};var LM="2024-11-05",QM=F.object({name:F.string().min(1),arguments:F.record(F.string(),F.unknown()).optional()});function zM(E){if(typeof E!=="object"||E===null)return!1;let M=E;return M.jsonrpc==="2.0"&&typeof M.method==="string"}function Q(E){let N=F.toJSONSchema(E);return{type:"object",properties:N.properties??{},required:N.required??void 0,additionalProperties:!1}}function RE(E){return E.issues.map((M)=>{return`${M.path.length>0?M.path.join("."):"input"}: ${M.message}`}).join("; ")}class n{memoryEngine;version;compatibilityMode;protocolVersion;supportedProtocolVersions;initialized=!1;pendingOps=[];constructor(E){this.memoryEngine=E.memoryEngine,this.version=E.version,this.compatibilityMode=E.compatibilityMode??"strict",this.protocolVersion=E.protocolVersion??LM,this.supportedProtocolVersions=E.supportedProtocolVersions&&E.supportedProtocolVersions.length>0?E.supportedProtocolVersions:[this.protocolVersion]}start(){let E=KM({input:process.stdin,terminal:!1});E.on("line",(M)=>{let N=M.trim();if(!N)return;try{let _=JSON.parse(N);if(!zM(_)){this.send({jsonrpc:"2.0",id:null,error:{code:-32600,message:"Invalid Request"}});return}this.handle(_)}catch{this.send({jsonrpc:"2.0",id:null,error:{code:-32700,message:"Parse error"}})}}),E.on("close",()=>{Promise.allSettled(this.pendingOps).then(()=>process.exit(0))})}handle(E){if(E.method==="notifications/initialized"){this.initialized=!0;return}if(E.id===void 0||E.id===null)return;if(E.method==="initialize"){this.handleInitialize(E);return}if(!this.initialized&&this.compatibilityMode==="strict"){this.send({jsonrpc:"2.0",id:E.id,error:{code:-32002,message:"Server not initialized"}});return}switch(E.method){case"tools/list":this.send({jsonrpc:"2.0",id:E.id,result:{tools:this.getToolDefinitions()}});return;case"tools/call":{let M=this.handleToolCall(E.id,E.params);this.pendingOps.push(M),M.finally(()=>{this.pendingOps=this.pendingOps.filter((N)=>N!==M)});return}case"ping":this.send({jsonrpc:"2.0",id:E.id,result:{}});return;default:this.send({jsonrpc:"2.0",id:E.id,error:{code:-32601,message:`Method not found: ${E.method}`}})}}handleInitialize(E){let M=typeof E.params?.protocolVersion==="string"?E.params.protocolVersion:this.protocolVersion;if(!this.supportedProtocolVersions.includes(M)){this.send({jsonrpc:"2.0",id:E.id??null,error:{code:-32602,message:`Unsupported protocol version: ${M}`,data:{supported:this.supportedProtocolVersions}}});return}this.initialized=!0,this.send({jsonrpc:"2.0",id:E.id??null,result:{protocolVersion:M,capabilities:{tools:{listChanged:!1}},serverInfo:{name:"open-mem",version:this.version}}})}getToolDefinitions(){return[{name:"memory.find",description:"Find relevant memory records.",inputSchema:Q(Z.find)},{name:"memory.history",description:"Browse session history.",inputSchema:Q(Z.history)},{name:"memory.get",description:"Fetch full memory records by id.",inputSchema:Q(Z.get)},{name:"memory.create",description:"Create a memory record.",inputSchema:Q(Z.create)},{name:"memory.revise",description:"Create a revised memory revision.",inputSchema:Q(Z.revise)},{name:"memory.remove",description:"Tombstone a memory record.",inputSchema:Q(Z.remove)},{name:"memory.transfer.export",description:"Export memory.",inputSchema:Q(Z.transferExport)},{name:"memory.transfer.import",description:"Import memory payload.",inputSchema:Q(Z.transferImport)},{name:"memory.maintenance",description:"Run maintenance action.",inputSchema:Q(Z.maintenance)},{name:"memory.help",description:"Show memory workflow guidance.",inputSchema:Q(Z.help)}]}async handleToolCall(E,M){let N=QM.safeParse(M??{});if(!N.success){this.send({jsonrpc:"2.0",id:E,result:{content:[{type:"text",text:JSON.stringify(z("VALIDATION_ERROR",RE(N.error)),null,2)}],isError:!0}});return}let _=N.data.name,O=N.data.arguments??{};try{let J=await this.executeTool(_,O);this.send({jsonrpc:"2.0",id:E,result:J})}catch(J){this.send({jsonrpc:"2.0",id:E,result:{content:[{type:"text",text:JSON.stringify(z("INTERNAL_ERROR",String(J)),null,2)}],isError:!0}})}}async executeTool(E,M){let N=async()=>{switch(E){case"memory.find":{let _=Z.find.parse(M),O=await this.memoryEngine.search(_.query,{limit:_.limit,type:_.types?.[0]});return JSON.stringify(K({results:O}),null,2)}case"memory.history":{let _=Z.history.parse(M);return JSON.stringify(K({items:await this.memoryEngine.timeline({limit:_.limit,sessionId:_.sessionId})}),null,2)}case"memory.get":{let _=Z.get.parse(M);return JSON.stringify(K({observations:await this.memoryEngine.recall(_.ids,_.limit)}),null,2)}case"memory.create":{let _=Z.create.parse(M),O=await this.memoryEngine.save({..._,sessionId:"mcp"});return JSON.stringify(O?K({observation:O}):z("CONFLICT","Unable to create memory"),null,2)}case"memory.revise":{let _=Z.revise.parse(M),O=await this.memoryEngine.update(_);return JSON.stringify(O?K({previousId:_.id,newId:O.id,observation:O}):z("NOT_FOUND",`Observation ${_.id} not found`),null,2)}case"memory.remove":{let _=Z.remove.parse(M),O=await this.memoryEngine.delete([_.id]);return JSON.stringify(O>0?K({id:_.id,tombstoned:!0}):z("NOT_FOUND",`Observation ${_.id} not found`),null,2)}case"memory.transfer.export":{let _=Z.transferExport.parse(M),O=await this.memoryEngine.export("project",{type:_.type,limit:_.limit});return JSON.stringify(K({payload:O,format:_.format}),null,2)}case"memory.transfer.import":{let _=Z.transferImport.parse(M),O=_.mode==="replace"?"overwrite":"skip-duplicates",J=await this.memoryEngine.import(_.payload,{mode:O});return JSON.stringify(K({imported:J.imported,skipped:J.skipped,mode:_.mode}),null,2)}case"memory.maintenance":{let _=Z.maintenance.parse(M);if(_.action==="folderContextDryRun")return JSON.stringify(K(await this.memoryEngine.maintainFolderContext("clean",!0)),null,2);if(_.action==="folderContextClean")return JSON.stringify(K(await this.memoryEngine.maintainFolderContext("clean",!1)),null,2);return JSON.stringify(K(await this.memoryEngine.maintainFolderContext("rebuild",!1)),null,2)}case"memory.help":return JSON.stringify(K({guide:this.memoryEngine.guide()}),null,2);default:return JSON.stringify(z("NOT_FOUND",`Unknown tool: ${E}`),null,2)}};try{let _=await N(),O=_.includes('"error": {')&&!_.includes('"error": null');return{content:[{type:"text",text:_}],isError:O}}catch(_){if(_ instanceof F.ZodError)return{content:[{type:"text",text:JSON.stringify(z("VALIDATION_ERROR",RE(_)),null,2)}],isError:!0};return{content:[{type:"text",text:JSON.stringify(z("INTERNAL_ERROR",String(_)),null,2)}],isError:!0}}}send(E){process.stdout.write(`${JSON.stringify(E)}
4
- `)}}var WM={"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 YM(E){if(E.includes("."))return E;return WM[E]||`us.anthropic.${E}-v1:0`}function HE(E){switch(E.provider){case"anthropic":{let{createAnthropic:M}=U("@ai-sdk/anthropic");return M({apiKey:E.apiKey})(E.model)}case"bedrock":{let{createAmazonBedrock:M}=U("@ai-sdk/amazon-bedrock");return M()(YM(E.model))}case"openai":{let{createOpenAI:M}=U("@ai-sdk/openai");return M({apiKey:E.apiKey})(E.model)}case"google":{let{createGoogleGenerativeAI:M}=U("@ai-sdk/google");return M({apiKey:E.apiKey})(E.model)}default:throw Error(`Unknown provider: ${E.provider}. Supported: anthropic, bedrock, openai, google`)}}function KE(E){try{switch(E.provider){case"google":{let{createGoogleGenerativeAI:M}=U("@ai-sdk/google");return M({apiKey:E.apiKey}).embedding("text-embedding-004")}case"openai":{let{createOpenAI:M}=U("@ai-sdk/openai");return M({apiKey:E.apiKey}).embedding("text-embedding-3-small")}case"bedrock":{let{createAmazonBedrock:M}=U("@ai-sdk/amazon-bedrock");return M().embedding("amazon.titan-embed-text-v2:0")}case"anthropic":return null;default:return null}}catch{return null}}i();import{randomUUID as xE}from"crypto";function yM(E,M){let N=new RegExp(`<${M}[^>]*>([\\s\\S]*?)</${M}>`,"i"),_=E.match(N);return _?_[1].trim():""}function jM(E,M){let N=new RegExp(`<${M}[^>]*>([\\s\\S]*?)</${M}>`,"gi"),_=[];for(let O of E.matchAll(N)){let J=O[1].trim();if(J)_.push(J)}return _}function QE(E){let M=yM(E,"reranked");if(!M)return null;let N=jM(M,"index");if(N.length===0)return null;let _=[];for(let O of N){let J=Number.parseInt(O,10);if(Number.isNaN(J)||J<0)return null;_.push(J)}return _}function W(E){return Math.ceil(E.length/4)}var kM={showTokenCosts:!0,observationTypes:"all",fullObservationCount:3,showLastSummary:!0},T={bugfix:"\uD83D\uDD34",feature:"\uD83D\uDFE3",refactor:"\uD83D\uDD04",change:"\u2705",discovery:"\uD83D\uDD35",decision:"\u2696\uFE0F"};function zE(E,M=kM){let N=[];if(N.push("## open-mem: Past Session Memory"),N.push(""),N.push("**\uD83D\uDCA1 Progressive Disclosure:** This is a compact index showing WHAT was observed and retrieval COST."),N.push("Use `memory.find` to find observations by query, then `memory.get` with IDs to fetch full details."),N.push(""),N.push("**3-Layer Memory Access:**"),N.push("- **Layer 1** `memory.find` \u2014 Find observations by query (returns IDs + summaries)"),N.push("- **Layer 2** `memory.history` \u2014 Browse session history and drill into sessions"),N.push("- **Layer 3** `memory.get` \u2014 Get full details by ID (use IDs from search results or the index below)"),M.showLastSummary&&E.recentSummaries.length>0){N.push(""),N.push("### Recent Sessions"),N.push("| Session | Summary | Decisions |"),N.push("|---------|---------|-----------|");for(let S of E.recentSummaries){let V=S.keyDecisions.length>0?S.keyDecisions.join("; "):"\u2014";N.push(`| ${S.sessionId} | ${S.summary} | ${V} |`)}}let _=M.observationTypes==="all"?E.observationIndex:E.observationIndex.filter((S)=>M.observationTypes.includes(S.type));if(_.length>0){N.push(""),N.push(`### Recent Observations (${_.length} entries)`);let S=PM(_,E.fullObservations);for(let[V,C]of S){if(N.push(""),N.push(`**${V}**`),M.showTokenCosts)N.push("| ID | Type | Title | ~Tokens |"),N.push("|----|------|-------|---------|");else N.push("| ID | Type | Title |"),N.push("|----|------|-------|");for(let A of C){let $=T[A.type]||"\uD83D\uDCDD";if(M.showTokenCosts)N.push(`| ${A.id} | ${$} | ${A.title} | ~${A.tokenCount} |`);else N.push(`| ${A.id} | ${$} | ${A.title} |`)}}}let O=E.fullObservations.slice(0,M.fullObservationCount);if(O.length>0){N.push(""),N.push("### Full Details (most recent)");for(let S of O){let V=T[S.type]||"\uD83D\uDCDD";if(N.push(""),N.push(`#### ${V} ${S.title} (${S.id})`),N.push(S.narrative),S.facts.length>0)N.push(`**Facts:** ${S.facts.map((A)=>`- ${A}`).join(" ")}`);if(S.concepts.length>0)N.push(`**Concepts:** ${S.concepts.join(", ")}`);let C=[...S.filesRead,...S.filesModified];if(C.length>0)N.push(`**Files:** ${C.join(", ")}`)}}let J=fM(E);if(J)N.push(""),N.push(J);return N.join(`
5
- `)}function fM(E){let M=0,N=0,_=new Set(E.observationIndex.map((S)=>S.id));for(let S of E.observationIndex)M+=S.tokenCount,N+=S.discoveryTokens;for(let S of E.fullObservations)if(!_.has(S.id))M+=S.tokenCount,N+=S.discoveryTokens;if(N===0)return null;let O=N-M,J=Math.max(0,Math.round(O/N*100));return`### \uD83D\uDCB0 Memory Economics
3
+ var RM=Object.defineProperty;var HM=(E,M)=>{for(var N in M)RM(E,N,{get:M[N],enumerable:!0,configurable:!0,set:(_)=>M[N]=()=>_})};var ZE=(E,M)=>()=>(E&&(M=E(E=0)),M);var U=import.meta.require;import{existsSync as UM,readFileSync as BM}from"fs";function FM(){let E={};if(process.env.OPEN_MEM_DB_PATH)E.dbPath=process.env.OPEN_MEM_DB_PATH;if(process.env.OPEN_MEM_PROVIDER)E.provider=process.env.OPEN_MEM_PROVIDER;if(process.env.OPEN_MEM_MODEL)E.model=process.env.OPEN_MEM_MODEL;if(process.env.OPEN_MEM_MAX_CONTEXT_TOKENS)E.maxContextTokens=Number.parseInt(process.env.OPEN_MEM_MAX_CONTEXT_TOKENS,10);if(process.env.OPEN_MEM_COMPRESSION==="false")E.compressionEnabled=!1;if(process.env.OPEN_MEM_CONTEXT_INJECTION==="false")E.contextInjectionEnabled=!1;if(process.env.OPEN_MEM_IGNORED_TOOLS)E.ignoredTools=process.env.OPEN_MEM_IGNORED_TOOLS.split(",").map((M)=>M.trim());if(process.env.OPEN_MEM_BATCH_SIZE)E.batchSize=Number.parseInt(process.env.OPEN_MEM_BATCH_SIZE,10);if(process.env.OPEN_MEM_RETENTION_DAYS)E.retentionDays=Number.parseInt(process.env.OPEN_MEM_RETENTION_DAYS,10);if(process.env.OPEN_MEM_LOG_LEVEL)E.logLevel=process.env.OPEN_MEM_LOG_LEVEL;if(process.env.OPEN_MEM_CONTEXT_SHOW_TOKEN_COSTS==="false")E.contextShowTokenCosts=!1;if(process.env.OPEN_MEM_CONTEXT_TYPES)E.contextObservationTypes=process.env.OPEN_MEM_CONTEXT_TYPES==="all"?"all":process.env.OPEN_MEM_CONTEXT_TYPES.split(",").map((M)=>M.trim());if(process.env.OPEN_MEM_CONTEXT_FULL_COUNT)E.contextFullObservationCount=Number.parseInt(process.env.OPEN_MEM_CONTEXT_FULL_COUNT,10);if(process.env.OPEN_MEM_MAX_OBSERVATIONS)E.maxObservations=Number.parseInt(process.env.OPEN_MEM_MAX_OBSERVATIONS,10);if(process.env.OPEN_MEM_CONTEXT_SHOW_LAST_SUMMARY==="false")E.contextShowLastSummary=!1;if(process.env.OPEN_MEM_RATE_LIMITING==="false")E.rateLimitingEnabled=!1;if(process.env.OPEN_MEM_FOLDER_CONTEXT==="false")E.folderContextEnabled=!1;if(process.env.OPEN_MEM_FOLDER_CONTEXT_MAX_DEPTH)E.folderContextMaxDepth=Number.parseInt(process.env.OPEN_MEM_FOLDER_CONTEXT_MAX_DEPTH,10);if(process.env.OPEN_MEM_DAEMON==="true")E.daemonEnabled=!0;if(process.env.OPEN_MEM_DASHBOARD==="true")E.dashboardEnabled=!0;if(process.env.OPEN_MEM_DASHBOARD_PORT)E.dashboardPort=Number.parseInt(process.env.OPEN_MEM_DASHBOARD_PORT,10);if(process.env.OPEN_MEM_PLATFORM_OPENCODE==="false")E.platformOpenCodeEnabled=!1;if(process.env.OPEN_MEM_PLATFORM_CLAUDE_CODE==="true")E.platformClaudeCodeEnabled=!0;if(process.env.OPEN_MEM_PLATFORM_CURSOR==="true")E.platformCursorEnabled=!0;if(process.env.OPEN_MEM_MCP_COMPAT_MODE)E.mcpCompatibilityMode=process.env.OPEN_MEM_MCP_COMPAT_MODE;if(process.env.OPEN_MEM_MCP_PROTOCOL_VERSION)E.mcpProtocolVersion=process.env.OPEN_MEM_MCP_PROTOCOL_VERSION;if(process.env.OPEN_MEM_MCP_SUPPORTED_PROTOCOLS)E.mcpSupportedProtocolVersions=process.env.OPEN_MEM_MCP_SUPPORTED_PROTOCOLS.split(",").map((M)=>M.trim()).filter(Boolean);if(process.env.OPEN_MEM_EMBEDDING_DIMENSION)E.embeddingDimension=Number.parseInt(process.env.OPEN_MEM_EMBEDDING_DIMENSION,10);if(process.env.OPEN_MEM_CONFLICT_RESOLUTION==="true")E.conflictResolutionEnabled=!0;if(process.env.OPEN_MEM_CONFLICT_BAND_LOW){let M=Number.parseFloat(process.env.OPEN_MEM_CONFLICT_BAND_LOW);if(!Number.isNaN(M))E.conflictSimilarityBandLow=M}if(process.env.OPEN_MEM_CONFLICT_BAND_HIGH){let M=Number.parseFloat(process.env.OPEN_MEM_CONFLICT_BAND_HIGH);if(!Number.isNaN(M))E.conflictSimilarityBandHigh=M}if(process.env.OPEN_MEM_USER_MEMORY==="true")E.userMemoryEnabled=!0;if(process.env.OPEN_MEM_USER_MEMORY_DB_PATH)E.userMemoryDbPath=process.env.OPEN_MEM_USER_MEMORY_DB_PATH;if(process.env.OPEN_MEM_USER_MEMORY_MAX_TOKENS)E.userMemoryMaxContextTokens=Number.parseInt(process.env.OPEN_MEM_USER_MEMORY_MAX_TOKENS,10);if(process.env.OPEN_MEM_RERANKING==="true")E.rerankingEnabled=!0;if(process.env.OPEN_MEM_RERANKING_MAX_CANDIDATES)E.rerankingMaxCandidates=Number.parseInt(process.env.OPEN_MEM_RERANKING_MAX_CANDIDATES,10);if(process.env.OPEN_MEM_ENTITY_EXTRACTION==="true")E.entityExtractionEnabled=!0;return E}function GM(E){let M=`${E}/.open-mem/config.json`;if(!UM(M))return{};try{let N=BM(M,"utf-8"),_=JSON.parse(N);if(!_||typeof _!=="object"||Array.isArray(_))return{};return _}catch{return{}}}function DM(E){switch(E){case"google":return 768;case"openai":return 1536;case"bedrock":return 1024;case"anthropic":return 0;default:return 768}}function m(E,M){let N=GM(E),_=FM(),O={...LE,...N,..._,...M};if(!O.dbPath.startsWith("/"))O.dbPath=`${E}/${O.dbPath}`;if(!process.env.OPEN_MEM_PROVIDER&&!M?.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"}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"bedrock":break}if(O.embeddingDimension===void 0)O.embeddingDimension=DM(O.provider);return O}function d(){return{...LE}}var LE;var i=ZE(()=>{LE={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,daemonEnabled:!1,dashboardEnabled:!1,dashboardPort:3737,platformOpenCodeEnabled:!0,platformClaudeCodeEnabled:!1,platformCursorEnabled:!1,mcpCompatibilityMode:"strict",mcpProtocolVersion:"2024-11-05",mcpSupportedProtocolVersions:["2024-11-05"],embeddingDimension:void 0,conflictResolutionEnabled:!1,conflictSimilarityBandLow:0.7,conflictSimilarityBandHigh:0.92,userMemoryEnabled:!1,userMemoryDbPath:"~/.config/open-mem/user-memory.db",userMemoryMaxContextTokens:1000,rerankingEnabled:!1,rerankingMaxCandidates:20,entityExtractionEnabled:!1}});var hE={};HM(hE,{writeProjectConfig:()=>IE,validatePatch:()=>t,readProjectConfig:()=>q,previewConfig:()=>R0,patchConfig:()=>H0,getEffectiveConfig:()=>p,getConfigSchema:()=>Z0});import{existsSync as O0}from"fs";import{mkdir as J0,readFile as S0,writeFile as V0}from"fs/promises";import{dirname as C0,join as A0}from"path";function vE(E){return A0(E,".open-mem","config.json")}function gE(E){return pE.find((M)=>M.key===E)}function X0(E,M){let N=gE(E);if(!N)return null;if(N.type==="string"&&typeof M!=="string")return`${String(E)} must be a string`;if(N.type==="number"&&typeof M!=="number")return`${String(E)} must be a number`;if(N.type==="boolean"&&typeof M!=="boolean")return`${String(E)} must be a boolean`;if(N.type==="array"&&!Array.isArray(M))return`${String(E)} must be an array`;if(N.enum&&typeof M==="string"&&!N.enum.includes(M))return`${String(E)} must be one of: ${N.enum.join(", ")}`;if(typeof M==="number"){if(N.min!==void 0&&M<N.min)return`${String(E)} must be >= ${N.min}`;if(N.max!==void 0&&M>N.max)return`${String(E)} must be <= ${N.max}`}return null}function Z0(){return pE}async function q(E){let M=vE(E);if(!O0(M))return{};try{let N=await S0(M,"utf-8"),_=JSON.parse(N);if(!_||typeof _!=="object"||Array.isArray(_))return{};return _}catch{return{}}}async function IE(E,M){let N=vE(E),O={...await q(E),...M};await J0(C0(N),{recursive:!0}),await V0(N,JSON.stringify(O,null,2),"utf-8")}function t(E){let M=[];for(let[N,_]of Object.entries(E)){let J=X0(N,_);if(J)M.push(J)}return M}async function p(E){let M=d(),N=await q(E),_=m(E),O=[],J={};for(let[S,V]of Object.entries(M)){let C=S,A=gE(C),H=($0[C]??[]).some((D)=>typeof process.env[D]==="string"),Y=Object.hasOwn(N,C),B="default";if(Y)B="file";if(H)B="env";if(J[C]={source:B,locked:H,restartRequired:A?.restartRequired??!1,liveApply:A?.liveApply??!1},B==="env"&&Y)O.push(`${String(C)} is overridden by environment variable.`);if(_[C]===void 0&&V!==void 0)O.push(`${String(C)} resolved to undefined unexpectedly.`)}return{config:_,meta:J,warnings:O}}async function R0(E,M){let N=t(M);if(N.length>0)return{...await p(E),warnings:N};let _=d(),O=await q(E),J={..._,...O,...M},V={...m(E,M),...J},C=(await p(E)).meta;return{config:V,meta:C,warnings:[]}}async function H0(E,M){let N=t(M);if(N.length>0)return{...await p(E),warnings:N};return await IE(E,M),p(E)}var pE,$0;var qE=ZE(()=>{i();pE=[{key:"dbPath",label:"Database Path",type:"string",group:"Storage",liveApply:!1,restartRequired:!0},{key:"provider",label:"Provider",type:"string",group:"AI",liveApply:!1,restartRequired:!0,enum:["google","anthropic","openai","bedrock"]},{key:"model",label:"Model",type:"string",group:"AI",liveApply:!1,restartRequired:!0},{key:"maxTokensPerCompression",label:"Max Tokens Per Compression",type:"number",group:"AI",liveApply:!0,restartRequired:!1,min:128,max:8192},{key:"compressionEnabled",label:"Compression Enabled",type:"boolean",group:"Behavior",liveApply:!0,restartRequired:!1},{key:"contextInjectionEnabled",label:"Context Injection Enabled",type:"boolean",group:"Behavior",liveApply:!0,restartRequired:!1},{key:"maxContextTokens",label:"Max Context Tokens",type:"number",group:"Behavior",liveApply:!0,restartRequired:!1,min:500,max:64000},{key:"batchSize",label:"Batch Size",type:"number",group:"Behavior",liveApply:!0,restartRequired:!1,min:1,max:100},{key:"batchIntervalMs",label:"Batch Interval (ms)",type:"number",group:"Behavior",liveApply:!0,restartRequired:!1,min:1000,max:300000},{key:"ignoredTools",label:"Ignored Tools",type:"array",group:"Filtering",liveApply:!0,restartRequired:!1},{key:"minOutputLength",label:"Min Output Length",type:"number",group:"Filtering",liveApply:!0,restartRequired:!1,min:0,max:1e4},{key:"maxObservations",label:"Max Observations",type:"number",group:"Progressive Disclosure",liveApply:!0,restartRequired:!1,min:1,max:200},{key:"contextFullObservationCount",label:"Full Observation Count",type:"number",group:"Progressive Disclosure",liveApply:!0,restartRequired:!1,min:0,max:20},{key:"contextShowTokenCosts",label:"Show Token Costs",type:"boolean",group:"Progressive Disclosure",liveApply:!0,restartRequired:!1},{key:"sensitivePatterns",label:"Sensitive Patterns",type:"array",group:"Privacy",liveApply:!0,restartRequired:!1},{key:"retentionDays",label:"Retention Days",type:"number",group:"Data Retention",liveApply:!1,restartRequired:!0,min:0,max:3650},{key:"maxDatabaseSizeMb",label:"Max Database Size (MB)",type:"number",group:"Data Retention",liveApply:!1,restartRequired:!0,min:0,max:1e5},{key:"dashboardEnabled",label:"Dashboard Enabled",type:"boolean",group:"Dashboard",liveApply:!1,restartRequired:!0},{key:"dashboardPort",label:"Dashboard Port",type:"number",group:"Dashboard",liveApply:!1,restartRequired:!0,min:1,max:65535},{key:"platformOpenCodeEnabled",label:"OpenCode Adapter",type:"boolean",group:"Advanced",liveApply:!1,restartRequired:!0},{key:"platformClaudeCodeEnabled",label:"Claude Code Adapter",type:"boolean",group:"Advanced",liveApply:!1,restartRequired:!0},{key:"platformCursorEnabled",label:"Cursor Adapter",type:"boolean",group:"Advanced",liveApply:!1,restartRequired:!0},{key:"mcpCompatibilityMode",label:"MCP Compatibility Mode",type:"string",group:"Advanced",liveApply:!1,restartRequired:!0,enum:["strict","legacy"]},{key:"mcpProtocolVersion",label:"MCP Protocol Version",type:"string",group:"Advanced",liveApply:!1,restartRequired:!0},{key:"mcpSupportedProtocolVersions",label:"MCP Supported Protocols",type:"array",group:"Advanced",liveApply:!1,restartRequired:!0},{key:"rerankingEnabled",label:"Reranking Enabled",type:"boolean",group:"Advanced",liveApply:!0,restartRequired:!1},{key:"entityExtractionEnabled",label:"Entity Extraction Enabled",type:"boolean",group:"Advanced",liveApply:!0,restartRequired:!1},{key:"userMemoryEnabled",label:"User Memory Enabled",type:"boolean",group:"Advanced",liveApply:!1,restartRequired:!0},{key:"userMemoryMaxContextTokens",label:"User Memory Max Context Tokens",type:"number",group:"Advanced",liveApply:!0,restartRequired:!1,min:0,max:8000}],$0={dbPath:["OPEN_MEM_DB_PATH"],provider:["OPEN_MEM_PROVIDER"],model:["OPEN_MEM_MODEL"],compressionEnabled:["OPEN_MEM_COMPRESSION"],contextInjectionEnabled:["OPEN_MEM_CONTEXT_INJECTION"],maxContextTokens:["OPEN_MEM_MAX_CONTEXT_TOKENS"],ignoredTools:["OPEN_MEM_IGNORED_TOOLS"],batchSize:["OPEN_MEM_BATCH_SIZE"],retentionDays:["OPEN_MEM_RETENTION_DAYS"],contextShowTokenCosts:["OPEN_MEM_CONTEXT_SHOW_TOKEN_COSTS"],contextFullObservationCount:["OPEN_MEM_CONTEXT_FULL_COUNT"],maxObservations:["OPEN_MEM_MAX_OBSERVATIONS"],dashboardEnabled:["OPEN_MEM_DASHBOARD"],dashboardPort:["OPEN_MEM_DASHBOARD_PORT"],platformOpenCodeEnabled:["OPEN_MEM_PLATFORM_OPENCODE"],platformClaudeCodeEnabled:["OPEN_MEM_PLATFORM_CLAUDE_CODE"],platformCursorEnabled:["OPEN_MEM_PLATFORM_CURSOR"],mcpCompatibilityMode:["OPEN_MEM_MCP_COMPAT_MODE"],mcpProtocolVersion:["OPEN_MEM_MCP_PROTOCOL_VERSION"],mcpSupportedProtocolVersions:["OPEN_MEM_MCP_SUPPORTED_PROTOCOLS"],rerankingEnabled:["OPEN_MEM_RERANKING"],userMemoryEnabled:["OPEN_MEM_USER_MEMORY"]}});import{readFileSync as x0}from"fs";import{join as u0}from"path";import{parseArgs as w0}from"util";import{createInterface as KM}from"readline";import{z as F}from"zod";import{z as X}from"zod";var v=X.enum(["decision","bugfix","feature","refactor","discovery","change"]);function K(E,M={}){return{data:E,error:null,meta:M}}function z(E,M,N){return{data:null,error:{code:E,message:M,details:N},meta:{}}}var Z={find:X.object({query:X.string().min(1),scope:X.enum(["project","user","all"]).optional().default("project"),types:X.array(v).optional(),limit:X.number().int().min(1).max(50).optional().default(10),cursor:X.string().optional(),include:X.object({snippets:X.boolean().optional(),scores:X.boolean().optional(),relations:X.boolean().optional()}).optional()}),history:X.object({limit:X.number().int().min(1).max(20).optional().default(5),cursor:X.string().optional(),sessionId:X.string().optional()}),get:X.object({ids:X.array(X.string()).min(1),includeHistory:X.boolean().optional().default(!1),limit:X.number().int().min(1).max(50).optional().default(10)}),create:X.object({title:X.string(),type:v,narrative:X.string(),concepts:X.array(X.string()).optional(),files:X.array(X.string()).optional(),importance:X.number().int().min(1).max(5).optional(),scope:X.enum(["project","user"]).optional().default("project")}),revise:X.object({id:X.string(),title:X.string().optional(),narrative:X.string().optional(),type:v.optional(),concepts:X.array(X.string()).optional(),importance:X.number().int().min(1).max(5).optional(),reason:X.string().optional()}),remove:X.object({id:X.string(),reason:X.string().optional()}),transferExport:X.object({scope:X.enum(["project"]).optional().default("project"),type:v.optional(),limit:X.number().int().min(1).optional(),format:X.enum(["json"]).optional().default("json")}),transferImport:X.object({payload:X.string(),mode:X.enum(["skip","merge","replace"]).optional().default("skip")}),maintenance:X.object({action:X.enum(["folderContextDryRun","folderContextClean","folderContextRebuild"])}),help:X.object({})};var LM="2024-11-05",QM=F.object({name:F.string().min(1),arguments:F.record(F.string(),F.unknown()).optional()});function zM(E){if(typeof E!=="object"||E===null)return!1;let M=E;return M.jsonrpc==="2.0"&&typeof M.method==="string"}function Q(E){let N=F.toJSONSchema(E);return{type:"object",properties:N.properties??{},required:N.required??void 0,additionalProperties:!1}}function RE(E){return E.issues.map((M)=>{return`${M.path.length>0?M.path.join("."):"input"}: ${M.message}`}).join("; ")}class n{memoryEngine;version;compatibilityMode;protocolVersion;supportedProtocolVersions;initialized=!1;pendingOps=[];constructor(E){this.memoryEngine=E.memoryEngine,this.version=E.version,this.compatibilityMode=E.compatibilityMode??"strict",this.protocolVersion=E.protocolVersion??LM,this.supportedProtocolVersions=E.supportedProtocolVersions&&E.supportedProtocolVersions.length>0?E.supportedProtocolVersions:[this.protocolVersion]}start(){let E=KM({input:process.stdin,terminal:!1});E.on("line",(M)=>{let N=M.trim();if(!N)return;try{let _=JSON.parse(N);if(!zM(_)){this.send({jsonrpc:"2.0",id:null,error:{code:-32600,message:"Invalid Request"}});return}this.handle(_)}catch{this.send({jsonrpc:"2.0",id:null,error:{code:-32700,message:"Parse error"}})}}),E.on("close",()=>{Promise.allSettled(this.pendingOps).then(()=>process.exit(0))})}handle(E){if(E.method==="notifications/initialized"){this.initialized=!0;return}if(E.id===void 0||E.id===null)return;if(E.method==="initialize"){this.handleInitialize(E);return}if(!this.initialized&&this.compatibilityMode==="strict"){this.send({jsonrpc:"2.0",id:E.id,error:{code:-32002,message:"Server not initialized"}});return}switch(E.method){case"tools/list":this.send({jsonrpc:"2.0",id:E.id,result:{tools:this.getToolDefinitions()}});return;case"tools/call":{let M=this.handleToolCall(E.id,E.params);this.pendingOps.push(M),M.finally(()=>{this.pendingOps=this.pendingOps.filter((N)=>N!==M)});return}case"ping":this.send({jsonrpc:"2.0",id:E.id,result:{}});return;default:this.send({jsonrpc:"2.0",id:E.id,error:{code:-32601,message:`Method not found: ${E.method}`}})}}handleInitialize(E){let M=typeof E.params?.protocolVersion==="string"?E.params.protocolVersion:this.protocolVersion;if(!this.supportedProtocolVersions.includes(M)){this.send({jsonrpc:"2.0",id:E.id??null,error:{code:-32602,message:`Unsupported protocol version: ${M}`,data:{supported:this.supportedProtocolVersions}}});return}this.initialized=!0,this.send({jsonrpc:"2.0",id:E.id??null,result:{protocolVersion:M,capabilities:{tools:{listChanged:!1}},serverInfo:{name:"open-mem",version:this.version}}})}getToolDefinitions(){return[{name:"mem-find",description:"Find relevant memory records.",inputSchema:Q(Z.find)},{name:"mem-history",description:"Browse session history.",inputSchema:Q(Z.history)},{name:"mem-get",description:"Fetch full memory records by id.",inputSchema:Q(Z.get)},{name:"mem-create",description:"Create a memory record.",inputSchema:Q(Z.create)},{name:"mem-revise",description:"Create a revised memory revision.",inputSchema:Q(Z.revise)},{name:"mem-remove",description:"Tombstone a memory record.",inputSchema:Q(Z.remove)},{name:"mem-export",description:"Export memory.",inputSchema:Q(Z.transferExport)},{name:"mem-import",description:"Import memory payload.",inputSchema:Q(Z.transferImport)},{name:"mem-maintenance",description:"Run maintenance action.",inputSchema:Q(Z.maintenance)},{name:"mem-help",description:"Show memory workflow guidance.",inputSchema:Q(Z.help)}]}async handleToolCall(E,M){let N=QM.safeParse(M??{});if(!N.success){this.send({jsonrpc:"2.0",id:E,result:{content:[{type:"text",text:JSON.stringify(z("VALIDATION_ERROR",RE(N.error)),null,2)}],isError:!0}});return}let _=N.data.name,O=N.data.arguments??{};try{let J=await this.executeTool(_,O);this.send({jsonrpc:"2.0",id:E,result:J})}catch(J){this.send({jsonrpc:"2.0",id:E,result:{content:[{type:"text",text:JSON.stringify(z("INTERNAL_ERROR",String(J)),null,2)}],isError:!0}})}}async executeTool(E,M){let N=async()=>{switch(E){case"mem-find":{let _=Z.find.parse(M),O=await this.memoryEngine.search(_.query,{limit:_.limit,type:_.types?.[0]});return JSON.stringify(K({results:O}),null,2)}case"mem-history":{let _=Z.history.parse(M);return JSON.stringify(K({items:await this.memoryEngine.timeline({limit:_.limit,sessionId:_.sessionId})}),null,2)}case"mem-get":{let _=Z.get.parse(M);return JSON.stringify(K({observations:await this.memoryEngine.recall(_.ids,_.limit)}),null,2)}case"mem-create":{let _=Z.create.parse(M),O=await this.memoryEngine.save({..._,sessionId:"mcp"});return JSON.stringify(O?K({observation:O}):z("CONFLICT","Unable to create memory"),null,2)}case"mem-revise":{let _=Z.revise.parse(M),O=await this.memoryEngine.update(_);return JSON.stringify(O?K({previousId:_.id,newId:O.id,observation:O}):z("NOT_FOUND",`Observation ${_.id} not found`),null,2)}case"mem-remove":{let _=Z.remove.parse(M),O=await this.memoryEngine.delete([_.id]);return JSON.stringify(O>0?K({id:_.id,tombstoned:!0}):z("NOT_FOUND",`Observation ${_.id} not found`),null,2)}case"mem-export":{let _=Z.transferExport.parse(M),O=await this.memoryEngine.export("project",{type:_.type,limit:_.limit});return JSON.stringify(K({payload:O,format:_.format}),null,2)}case"mem-import":{let _=Z.transferImport.parse(M),O=_.mode==="replace"?"overwrite":"skip-duplicates",J=await this.memoryEngine.import(_.payload,{mode:O});return JSON.stringify(K({imported:J.imported,skipped:J.skipped,mode:_.mode}),null,2)}case"mem-maintenance":{let _=Z.maintenance.parse(M);if(_.action==="folderContextDryRun")return JSON.stringify(K(await this.memoryEngine.maintainFolderContext("clean",!0)),null,2);if(_.action==="folderContextClean")return JSON.stringify(K(await this.memoryEngine.maintainFolderContext("clean",!1)),null,2);return JSON.stringify(K(await this.memoryEngine.maintainFolderContext("rebuild",!1)),null,2)}case"mem-help":return JSON.stringify(K({guide:this.memoryEngine.guide()}),null,2);default:return JSON.stringify(z("NOT_FOUND",`Unknown tool: ${E}`),null,2)}};try{let _=await N(),O=_.includes('"error": {')&&!_.includes('"error": null');return{content:[{type:"text",text:_}],isError:O}}catch(_){if(_ instanceof F.ZodError)return{content:[{type:"text",text:JSON.stringify(z("VALIDATION_ERROR",RE(_)),null,2)}],isError:!0};return{content:[{type:"text",text:JSON.stringify(z("INTERNAL_ERROR",String(_)),null,2)}],isError:!0}}}send(E){process.stdout.write(`${JSON.stringify(E)}
4
+ `)}}var WM={"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 YM(E){if(E.includes("."))return E;return WM[E]||`us.anthropic.${E}-v1:0`}function HE(E){switch(E.provider){case"anthropic":{let{createAnthropic:M}=U("@ai-sdk/anthropic");return M({apiKey:E.apiKey})(E.model)}case"bedrock":{let{createAmazonBedrock:M}=U("@ai-sdk/amazon-bedrock");return M()(YM(E.model))}case"openai":{let{createOpenAI:M}=U("@ai-sdk/openai");return M({apiKey:E.apiKey})(E.model)}case"google":{let{createGoogleGenerativeAI:M}=U("@ai-sdk/google");return M({apiKey:E.apiKey})(E.model)}default:throw Error(`Unknown provider: ${E.provider}. Supported: anthropic, bedrock, openai, google`)}}function KE(E){try{switch(E.provider){case"google":{let{createGoogleGenerativeAI:M}=U("@ai-sdk/google");return M({apiKey:E.apiKey}).embedding("text-embedding-004")}case"openai":{let{createOpenAI:M}=U("@ai-sdk/openai");return M({apiKey:E.apiKey}).embedding("text-embedding-3-small")}case"bedrock":{let{createAmazonBedrock:M}=U("@ai-sdk/amazon-bedrock");return M().embedding("amazon.titan-embed-text-v2:0")}case"anthropic":return null;default:return null}}catch{return null}}i();import{randomUUID as xE}from"crypto";function jM(E,M){let N=new RegExp(`<${M}[^>]*>([\\s\\S]*?)</${M}>`,"i"),_=E.match(N);return _?_[1].trim():""}function kM(E,M){let N=new RegExp(`<${M}[^>]*>([\\s\\S]*?)</${M}>`,"gi"),_=[];for(let O of E.matchAll(N)){let J=O[1].trim();if(J)_.push(J)}return _}function QE(E){let M=jM(E,"reranked");if(!M)return null;let N=kM(M,"index");if(N.length===0)return null;let _=[];for(let O of N){let J=Number.parseInt(O,10);if(Number.isNaN(J)||J<0)return null;_.push(J)}return _}function W(E){return Math.ceil(E.length/4)}var fM={showTokenCosts:!0,observationTypes:"all",fullObservationCount:3,showLastSummary:!0},T={bugfix:"\uD83D\uDD34",feature:"\uD83D\uDFE3",refactor:"\uD83D\uDD04",change:"\u2705",discovery:"\uD83D\uDD35",decision:"\u2696\uFE0F"};function zE(E,M=fM){let N=[];if(N.push("## open-mem: Past Session Memory"),N.push(""),N.push("**\uD83D\uDCA1 Progressive Disclosure:** This is a compact index showing WHAT was observed and retrieval COST."),N.push("Use `mem-find` to find observations by query, then `mem-get` with IDs to fetch full details."),N.push(""),N.push("**3-Layer Memory Access:**"),N.push("- **Layer 1** `mem-find` \u2014 Find observations by query (returns IDs + summaries)"),N.push("- **Layer 2** `mem-history` \u2014 Browse session history and drill into sessions"),N.push("- **Layer 3** `mem-get` \u2014 Get full details by ID (use IDs from search results or the index below)"),M.showLastSummary&&E.recentSummaries.length>0){N.push(""),N.push("### Recent Sessions"),N.push("| Session | Summary | Decisions |"),N.push("|---------|---------|-----------|");for(let S of E.recentSummaries){let V=S.keyDecisions.length>0?S.keyDecisions.join("; "):"\u2014";N.push(`| ${S.sessionId} | ${S.summary} | ${V} |`)}}let _=M.observationTypes==="all"?E.observationIndex:E.observationIndex.filter((S)=>M.observationTypes.includes(S.type));if(_.length>0){N.push(""),N.push(`### Recent Observations (${_.length} entries)`);let S=PM(_,E.fullObservations);for(let[V,C]of S){if(N.push(""),N.push(`**${V}**`),M.showTokenCosts)N.push("| ID | Type | Title | ~Tokens |"),N.push("|----|------|-------|---------|");else N.push("| ID | Type | Title |"),N.push("|----|------|-------|");for(let A of C){let $=T[A.type]||"\uD83D\uDCDD";if(M.showTokenCosts)N.push(`| ${A.id} | ${$} | ${A.title} | ~${A.tokenCount} |`);else N.push(`| ${A.id} | ${$} | ${A.title} |`)}}}let O=E.fullObservations.slice(0,M.fullObservationCount);if(O.length>0){N.push(""),N.push("### Full Details (most recent)");for(let S of O){let V=T[S.type]||"\uD83D\uDCDD";if(N.push(""),N.push(`#### ${V} ${S.title} (${S.id})`),N.push(S.narrative),S.facts.length>0)N.push(`**Facts:** ${S.facts.map((A)=>`- ${A}`).join(" ")}`);if(S.concepts.length>0)N.push(`**Concepts:** ${S.concepts.join(", ")}`);let C=[...S.filesRead,...S.filesModified];if(C.length>0)N.push(`**Files:** ${C.join(", ")}`)}}let J=yM(E);if(J)N.push(""),N.push(J);return N.join(`
5
+ `)}function yM(E){let M=0,N=0,_=new Set(E.observationIndex.map((S)=>S.id));for(let S of E.observationIndex)M+=S.tokenCount,N+=S.discoveryTokens;for(let S of E.fullObservations)if(!_.has(S.id))M+=S.tokenCount,N+=S.discoveryTokens;if(N===0)return null;let O=N-M,J=Math.max(0,Math.round(O/N*100));return`### \uD83D\uDCB0 Memory Economics
6
6
  **Read cost:** ~${M}t | **Discovery cost:** ~${N}t | **Savings:** ${J}% (${O}t saved)`}function PM(E,M){let N=new Map;for(let O of M){let J=O.filesModified[0]||O.filesRead[0];if(J)N.set(O.id,J)}let _=new Map;for(let O of E){let J=N.get(O.id)??"General",S=_.get(J)??[];S.push(O),_.set(J,S)}return _}function WE(E){let M=[];if(M.push("[open-mem] Memory context:"),E.recentSummaries.length>0){M.push(`
7
7
  Recent sessions:`);for(let N of E.recentSummaries)M.push(`- ${N.summary}`)}if(E.observationIndex.length>0){M.push(`
8
8
  Recent observations (${E.observationIndex.length} entries):`);for(let N of E.observationIndex)M.push(`- ${T[N.type]||"\uD83D\uDCDD"} ${N.title}`)}return M.join(`
9
9
  `)}function YE(E,M){if(E.length===0)return"";let N=M,_=[];for(let J of E){let S=J.tokenCount||W(J.title);if(N-S<0)break;_.push(J),N-=S}if(_.length===0)return"";let O=[];O.push("### Cross-Project Memory"),O.push(""),O.push("| ID | Type | Title | ~Tokens |"),O.push("|----|------|-------|---------|");for(let J of _){let S=T[J.type]||"\uD83D\uDCDD";O.push(`| ${J.id} | ${S} | ${J.title} | ~${J.tokenCount} |`)}return O.join(`
10
10
  `)}function UE(E,M){if(E.length===0)return"";let N=M,_=[];for(let J of E){let S=J.tokenCount||W(J.title);if(N-S<0)break;_.push(J),N-=S}if(_.length===0)return"";let O=[];O.push(`
11
11
  Cross-project observations (${_.length} entries):`);for(let J of _)O.push(`- ${T[J.type]||"\uD83D\uDCDD"} ${J.title}`);return O.join(`
12
- `)}var g={recency:0.4,typeImportance:0.3,sessionAffinity:0.2,tokenEfficiency:0.1},mM={decision:1,bugfix:0.9,feature:0.8,refactor:0.6,discovery:0.5,change:0.4};function TM(E,M){let N=new Date(E),O=(M.getTime()-N.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 pM(E){return mM[E]??0.3}function vM(E,M){if(!M)return 0.5;return E===M?1:0.3}function gM(E){if(E<=10)return 1;if(E>=200)return 0.2;return 1-(E-10)/190*0.8}function IM(E,M){let N=TM(E.createdAt,M.now),_=pM(E.type),O=vM(E.sessionId,M.currentSessionId),J=gM(E.tokenCount);return N*g.recency+_*g.typeImportance+O*g.sessionAffinity+J*g.tokenEfficiency}function BE(E,M){let N=new Map;for(let _ of E)N.set(_.id,IM(_,M));return[...E].sort((_,O)=>{let J=N.get(_.id)??0,S=N.get(O.id)??0;if(S!==J)return S-J;return new Date(O.createdAt).getTime()-new Date(_.createdAt).getTime()})}function FE(E,M,N,_,O=[],J){let S=_,V=[],C=[];for(let $ of M){let H=$.tokenCount||W($.summary);if(S-H<0)break;V.push($),S-=H}let A=J?BE(N,J):N;for(let $ of A){let H=$.tokenCount||W($.title);if(S-H<0)break;C.push($),S-=H}return{recentSummaries:V,observationIndex:C,fullObservations:[...O],totalTokens:_-S}}import{existsSync as aM}from"fs";import{readdir as eM,readFile as tM,unlink as sM,writeFile as E0}from"fs/promises";import{join as M0,resolve as N0}from"path";import{existsSync as DE}from"fs";import{mkdir as hM,readFile as qM,rename as xM,unlink as uM,writeFile as wM}from"fs/promises";import{dirname as a,isAbsolute as yE,join as I,normalize as lM,relative as jE,resolve as o,sep as r}from"path";var y="<!-- open-mem-context -->",G="<!-- /open-mem-context -->",cM={bugfix:"\uD83D\uDD34",feature:"\uD83D\uDFE3",refactor:"\uD83D\uDD04",change:"\u2705",discovery:"\uD83D\uDD35",decision:"\u2696\uFE0F"},GE=new Map,bM=new Set(["node_modules",".git","dist","coverage",".open-mem","build","__pycache__",".next",".nuxt"]);async function kE(E,M,N=5){if(M.length===0)return;let _=[];for(let S of M){for(let V of S.filesModified)_.push(V);for(let V of S.filesRead)_.push(V)}let O=rM(_,E,N);if(O.size===0)return;let J=oM(M,O,E);for(let[S,V]of J)try{let C=nM(S,V,E);await dM(S,C)}catch(C){console.error(`[open-mem] Failed to update AGENTS.md in ${S}:`,C)}}function nM(E,M,N){let _=[...M].sort((C,A)=>A.createdAt.localeCompare(C.createdAt)).slice(0,10),O=jE(N,E)||".",J=[];J.push(`## Recent Activity in \`${O}/\` (auto-generated by open-mem)`),J.push(""),J.push("| Type | Title | Date |"),J.push("|------|-------|------|");for(let C of _){let A=cM[C.type]||"\uD83D\uDCDD",$=C.createdAt.split("T")[0],H=C.title.replace(/\|/g,"\\|");J.push(`| ${A} ${C.type} | ${H} | ${$} |`)}let S=new Set;for(let C of _)for(let A of C.concepts)S.add(A);if(S.size>0){let C=[...S].slice(0,10).join(", ");J.push(""),J.push(`**Key concepts:** ${C}`)}let V=_.filter((C)=>C.type==="decision").map((C)=>C.title);if(V.length>0)J.push(""),J.push(`**Recent decisions:** ${V.slice(0,5).join("; ")}`);return J.join(`
13
- `)}async function dM(E,M){if(!DE(E))return;let _=(GE.get(E)??Promise.resolve()).then(async()=>{let O=I(E,"AGENTS.md"),J=I(E,".AGENTS.md.tmp"),S="";try{S=await qM(O,"utf-8")}catch{}let V=iM(S,M);try{await hM(a(J),{recursive:!0}),await wM(J,V,"utf-8"),await xM(J,O)}catch(C){try{await uM(J)}catch{}throw C}});return GE.set(E,_.catch(()=>{})),_}function iM(E,M){if(!E)return`${y}
12
+ `)}var g={recency:0.4,typeImportance:0.3,sessionAffinity:0.2,tokenEfficiency:0.1},mM={decision:1,bugfix:0.9,feature:0.8,refactor:0.6,discovery:0.5,change:0.4};function TM(E,M){let N=new Date(E),O=(M.getTime()-N.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 pM(E){return mM[E]??0.3}function vM(E,M){if(!M)return 0.5;return E===M?1:0.3}function gM(E){if(E<=10)return 1;if(E>=200)return 0.2;return 1-(E-10)/190*0.8}function IM(E,M){let N=TM(E.createdAt,M.now),_=pM(E.type),O=vM(E.sessionId,M.currentSessionId),J=gM(E.tokenCount);return N*g.recency+_*g.typeImportance+O*g.sessionAffinity+J*g.tokenEfficiency}function BE(E,M){let N=new Map;for(let _ of E)N.set(_.id,IM(_,M));return[...E].sort((_,O)=>{let J=N.get(_.id)??0,S=N.get(O.id)??0;if(S!==J)return S-J;return new Date(O.createdAt).getTime()-new Date(_.createdAt).getTime()})}function FE(E,M,N,_,O=[],J){let S=_,V=[],C=[];for(let $ of M){let H=$.tokenCount||W($.summary);if(S-H<0)break;V.push($),S-=H}let A=J?BE(N,J):N;for(let $ of A){let H=$.tokenCount||W($.title);if(S-H<0)break;C.push($),S-=H}return{recentSummaries:V,observationIndex:C,fullObservations:[...O],totalTokens:_-S}}import{existsSync as oM}from"fs";import{readdir as eM,readFile as tM,unlink as sM,writeFile as E0}from"fs/promises";import{join as M0,resolve as N0}from"path";import{existsSync as DE}from"fs";import{mkdir as hM,readFile as qM,rename as xM,unlink as uM,writeFile as wM}from"fs/promises";import{dirname as o,isAbsolute as jE,join as I,normalize as lM,relative as kE,resolve as a,sep as r}from"path";var j="<!-- open-mem-context -->",G="<!-- /open-mem-context -->",cM={bugfix:"\uD83D\uDD34",feature:"\uD83D\uDFE3",refactor:"\uD83D\uDD04",change:"\u2705",discovery:"\uD83D\uDD35",decision:"\u2696\uFE0F"},GE=new Map,bM=new Set(["node_modules",".git","dist","coverage",".open-mem","build","__pycache__",".next",".nuxt"]);async function fE(E,M,N=5){if(M.length===0)return;let _=[];for(let S of M){for(let V of S.filesModified)_.push(V);for(let V of S.filesRead)_.push(V)}let O=rM(_,E,N);if(O.size===0)return;let J=aM(M,O,E);for(let[S,V]of J)try{let C=nM(S,V,E);await dM(S,C)}catch(C){console.error(`[open-mem] Failed to update AGENTS.md in ${S}:`,C)}}function nM(E,M,N){let _=[...M].sort((C,A)=>A.createdAt.localeCompare(C.createdAt)).slice(0,10),O=kE(N,E)||".",J=[];J.push(`## Recent Activity in \`${O}/\` (auto-generated by open-mem)`),J.push(""),J.push("| Type | Title | Date |"),J.push("|------|-------|------|");for(let C of _){let A=cM[C.type]||"\uD83D\uDCDD",$=C.createdAt.split("T")[0],H=C.title.replace(/\|/g,"\\|");J.push(`| ${A} ${C.type} | ${H} | ${$} |`)}let S=new Set;for(let C of _)for(let A of C.concepts)S.add(A);if(S.size>0){let C=[...S].slice(0,10).join(", ");J.push(""),J.push(`**Key concepts:** ${C}`)}let V=_.filter((C)=>C.type==="decision").map((C)=>C.title);if(V.length>0)J.push(""),J.push(`**Recent decisions:** ${V.slice(0,5).join("; ")}`);return J.join(`
13
+ `)}async function dM(E,M){if(!DE(E))return;let _=(GE.get(E)??Promise.resolve()).then(async()=>{let O=I(E,"AGENTS.md"),J=I(E,".AGENTS.md.tmp"),S="";try{S=await qM(O,"utf-8")}catch{}let V=iM(S,M);try{await hM(o(J),{recursive:!0}),await wM(J,V,"utf-8"),await xM(J,O)}catch(C){try{await uM(J)}catch{}throw C}});return GE.set(E,_.catch(()=>{})),_}function iM(E,M){if(!E)return`${j}
14
14
  ${M}
15
15
  ${G}
16
- `;let N=E.indexOf(y),_=E.indexOf(G);if(N!==-1&&_!==-1&&_>N){let J=E.substring(0,N),S=E.substring(_+G.length);return`${J}${y}
16
+ `;let N=E.indexOf(j),_=E.indexOf(G);if(N!==-1&&_!==-1&&_>N){let J=E.substring(0,N),S=E.substring(_+G.length);return`${J}${j}
17
17
  ${M}
18
- ${G}${S}`}let O=E;if(N!==-1&&_===-1)O=O.replace(y,"").trim();else if(N===-1&&_!==-1)O=O.replace(G,"").trim();else if(N!==-1&&_!==-1&&_<=N)O=O.replace(G,"").replace(y,"").trim();return`${O}
18
+ ${G}${S}`}let O=E;if(N!==-1&&_===-1)O=O.replace(j,"").trim();else if(N===-1&&_!==-1)O=O.replace(G,"").trim();else if(N!==-1&&_!==-1&&_<=N)O=O.replace(G,"").replace(j,"").trim();return`${O}
19
19
 
20
- ${y}
20
+ ${j}
21
21
  ${M}
22
22
  ${G}
23
- `}function rM(E,M,N){let _=new Set,O=o(M);for(let J of E){if(!J||!J.trim())continue;if(J.startsWith("~")||J.startsWith("http"))continue;let S=yE(J)?J:I(M,J),V=a(S),C=o(V);if(!C.startsWith(O+r)&&C!==O)continue;if(C===O)continue;let A=jE(O,C);if(A.split(r).length>N)continue;if(lM(A).split(r).some((Y)=>bM.has(Y)))continue;if(!DE(C))continue;_.add(C)}return _}function oM(E,M,N){let _=new Map;for(let O of E){let J=[...O.filesModified,...O.filesRead],S=new Set;for(let V of J){if(!V)continue;let C=yE(V)?V:I(N,V),A=o(a(C));if(M.has(A))S.add(A)}for(let V of S){let C=_.get(V)??[];C.push(O),_.set(V,C)}}return _}var e="<!-- open-mem-context -->",h="<!-- /open-mem-context -->";async function fE(E,M){let N;try{N=await eM(E,{withFileTypes:!0,encoding:"utf8"})}catch{return}for(let _ of N){let O=String(_.name);if(O===".git"||O==="node_modules"||O===".open-mem"||O==="dist")continue;let J=M0(E,O);if(_.isDirectory())await fE(J,M);else if(_.isFile()&&O==="AGENTS.md")M.push(J)}}async function PE(E){let M=N0(E),N=[];return await fE(M,N),N}function _0(E){let M=E.indexOf(e),N=E.indexOf(h);if(M===-1&&N===-1)return E;if(M!==-1&&N===-1){let J=E.replace(e,"").trim();return J?`${J}
23
+ `}function rM(E,M,N){let _=new Set,O=a(M);for(let J of E){if(!J||!J.trim())continue;if(J.startsWith("~")||J.startsWith("http"))continue;let S=jE(J)?J:I(M,J),V=o(S),C=a(V);if(!C.startsWith(O+r)&&C!==O)continue;if(C===O)continue;let A=kE(O,C);if(A.split(r).length>N)continue;if(lM(A).split(r).some((Y)=>bM.has(Y)))continue;if(!DE(C))continue;_.add(C)}return _}function aM(E,M,N){let _=new Map;for(let O of E){let J=[...O.filesModified,...O.filesRead],S=new Set;for(let V of J){if(!V)continue;let C=jE(V)?V:I(N,V),A=a(o(C));if(M.has(A))S.add(A)}for(let V of S){let C=_.get(V)??[];C.push(O),_.set(V,C)}}return _}var e="<!-- open-mem-context -->",h="<!-- /open-mem-context -->";async function yE(E,M){let N;try{N=await eM(E,{withFileTypes:!0,encoding:"utf8"})}catch{return}for(let _ of N){let O=String(_.name);if(O===".git"||O==="node_modules"||O===".open-mem"||O==="dist")continue;let J=M0(E,O);if(_.isDirectory())await yE(J,M);else if(_.isFile()&&O==="AGENTS.md")M.push(J)}}async function PE(E){let M=N0(E),N=[];return await yE(M,N),N}function _0(E){let M=E.indexOf(e),N=E.indexOf(h);if(M===-1&&N===-1)return E;if(M!==-1&&N===-1){let J=E.replace(e,"").trim();return J?`${J}
24
24
  `:""}if(M===-1&&N!==-1){let J=E.replace(h,"").trim();return J?`${J}
25
25
  `:""}if(N<=M){let J=E.replace(e,"").replace(h,"").trim();return J?`${J}
26
26
  `:""}let _=E.slice(0,M).trimEnd(),O=E.slice(N+h.length).trimStart();if(!_&&!O)return"";if(!_)return`${O}
@@ -28,9 +28,9 @@ ${G}
28
28
  `;return`${_}
29
29
 
30
30
  ${O}
31
- `}async function mE(E,M=!1){let N=await PE(E),_=0;for(let O of N){let J=await tM(O,"utf-8"),S=_0(J);if(S!==J){if(_+=1,!M)if(S==="")await sM(O);else await E0(O,S,"utf-8")}}return{files:N,changed:_}}async function TE(E,M,N,_,O=!1){let S=M.getAll(E).flatMap((C)=>N.getBySession(C.id));if(O){let C=new Set;for(let A of S)for(let $ of[...A.filesRead,...A.filesModified])C.add($);return{observations:S.length,filesTouched:C.size}}if(!aM(E))return{observations:0,filesTouched:0};await kE(E,S,_);let V=await PE(E);return{observations:S.length,filesTouched:V.length}}class s{observations;sessions;summaries;searchOrchestrator;projectPath;config;userObservationRepo;runtimeSnapshotProvider;configAuditStore;maintenanceHistoryStore;configAuditLogFallback=[];maintenanceLogFallback=[];constructor(E){this.observations=E.observations,this.sessions=E.sessions,this.summaries=E.summaries,this.searchOrchestrator=E.searchOrchestrator,this.projectPath=E.projectPath,this.config=E.config,this.userObservationRepo=E.userObservationRepo??null,this.runtimeSnapshotProvider=E.runtimeSnapshotProvider??null,this.configAuditStore=E.configAuditStore??null,this.maintenanceHistoryStore=E.maintenanceHistoryStore??null}getByIdIncludingArchived(E){let M=this.observations;return M.getByIdIncludingArchived?M.getByIdIncludingArchived(E):this.observations.getById(E)}listByProjectWithState(E){let M=this.observations;if(M.listByProject)return M.listByProject(this.projectPath,E);if(E.state!=="current")return[];return this.listObservations({limit:E.limit,offset:E.offset,type:E.type,sessionId:E.sessionId})}async ingest(E){}async processPending(E){return 0}async search(E,M={}){return this.searchOrchestrator.search(E,{type:M.type,limit:M.limit??10,projectPath:this.projectPath,importanceMin:M.importanceMin,importanceMax:M.importanceMax,createdAfter:M.after,createdBefore:M.before,concepts:M.concepts,files:M.files})}async timeline(E={}){if(E.sessionId){let N=this.sessions.getById(E.sessionId);if(!N)return[];return[{session:N,summary:this.summaries.getBySessionId(N.id),observations:this.observations.getBySession(N.id)}]}return this.sessions.getRecent(this.projectPath,E.limit??5).map((N)=>({session:N,summary:this.summaries.getBySessionId(N.id),observations:[]}))}async recall(E,M=10){let N=[];for(let _ of E.slice(0,M)){let O=this.observations.getById(_);if(O){N.push(O);continue}if(!this.userObservationRepo)continue;let J=this.userObservationRepo.getById(_);if(!J)continue;N.push({...J,sessionId:"",rawToolOutput:"",discoveryTokens:0})}return N}async save(E){if(E.scope==="user"){if(!this.userObservationRepo)return null;return{...this.userObservationRepo.create({type:E.type,title:E.title,subtitle:"",facts:[],narrative:E.narrative,concepts:E.concepts??[],filesRead:[],filesModified:E.files??[],toolName:"memory.create",tokenCount:W(`${E.title} ${E.narrative}`),importance:E.importance??3,sourceProject:this.projectPath}),sessionId:"",rawToolOutput:"",discoveryTokens:0}}this.sessions.getOrCreate(E.sessionId,this.projectPath);let M=this.observations.create({sessionId:E.sessionId,type:E.type,title:E.title,subtitle:"",facts:[],narrative:E.narrative,concepts:E.concepts??[],filesRead:[],filesModified:E.files??[],rawToolOutput:`[Manual save] ${E.narrative}`,toolName:"memory.create",tokenCount:W(`${E.title} ${E.narrative}`),discoveryTokens:0,importance:E.importance??3});return this.sessions.incrementObservationCount(E.sessionId),M}async update(E){let M=this.observations.getById(E.id);if(!M)return null;let N=this.sessions.getById(M.sessionId);if(!N||N.projectPath!==this.projectPath)return null;let{id:_,...O}=E;return this.observations.update(E.id,O)??null}async delete(E){let M=0;for(let N of E){let _=this.observations.getById(N);if(!_)continue;let O=this.sessions.getById(_.sessionId);if(!O||O.projectPath!==this.projectPath)continue;if(this.observations.delete(N))M+=1}return M}async export(E,M={}){if(E!=="project")throw Error("Only project scope export is supported.");let N=this.sessions.getAll(this.projectPath),_=[];for(let V of N)_.push(...this.observations.getBySession(V.id));if(M.type)_=_.filter((V)=>V.type===M.type);if(_.sort((V,C)=>new Date(V.createdAt).getTime()-new Date(C.createdAt).getTime()),M.limit&&M.limit<_.length)_=_.slice(0,M.limit);let O=_.map(({rawToolOutput:V,...C})=>C),J=N.map((V)=>this.summaries.getBySessionId(V.id)).filter((V)=>V!==null);return{version:1,exportedAt:new Date().toISOString(),project:this.projectPath,observations:O,summaries:J}}async import(E,M={}){let N;try{N=JSON.parse(E)}catch{throw Error("Invalid JSON payload.")}if(typeof N!=="object"||N===null)throw Error("Invalid import payload.");let _=N;if(_.version!==1||!Array.isArray(_.observations))throw Error("Unsupported export format.");let O=M.mode??"skip-duplicates",J=0,S=0;for(let V of _.observations){let C=this.observations.getById(V.id);if(C&&O==="skip-duplicates"){S+=1;continue}if(C&&O==="overwrite")this.observations.delete(V.id);this.sessions.getOrCreate(V.sessionId,this.projectPath),this.observations.importObservation({id:V.id,sessionId:V.sessionId,type:V.type,title:V.title,subtitle:V.subtitle??"",facts:V.facts??[],narrative:V.narrative??"",concepts:V.concepts??[],filesRead:V.filesRead??[],filesModified:V.filesModified??[],rawToolOutput:V.rawToolOutput??"",toolName:V.toolName??"unknown",createdAt:V.createdAt,tokenCount:V.tokenCount??0,discoveryTokens:V.discoveryTokens??0,importance:V.importance??3,supersededBy:V.supersededBy??null,supersededAt:V.supersededAt??null}),this.sessions.incrementObservationCount(V.sessionId),J+=1}for(let V of _.summaries??[]){let C=this.summaries.getBySessionId(V.sessionId);if(C&&O==="skip-duplicates")continue;if(C&&O==="overwrite")continue;this.sessions.getOrCreate(V.sessionId,this.projectPath),this.summaries.importSummary(V),this.sessions.setSummary(V.sessionId,V.id)}return{imported:J,skipped:S}}async buildContext(E,M="normal"){let N=this.sessions.getRecent(this.projectPath,5),_=N.map(($)=>$.summaryId?this.summaries.getBySessionId($.id):null).filter(($)=>$!==null),O=this.observations.getIndex(this.projectPath,this.config.maxObservations),S=O.slice(0,this.config.contextFullObservationCount).map(($)=>$.id).map(($)=>this.observations.getById($)).filter(($)=>$!==null),V=FE(N,_,O,this.config.maxContextTokens,S);if(M==="compaction"){let $=WE(V);if(this.config.userMemoryEnabled&&this.userObservationRepo)$+=UE(this.userObservationRepo.getIndex(this.config.maxObservations),this.config.userMemoryMaxContextTokens);return $}let C={showTokenCosts:this.config.contextShowTokenCosts,observationTypes:this.config.contextObservationTypes,fullObservationCount:this.config.contextFullObservationCount,showLastSummary:this.config.contextShowLastSummary},A=zE(V,C);if(this.config.userMemoryEnabled&&this.userObservationRepo){let $=YE(this.userObservationRepo.getIndex(this.config.maxObservations),this.config.userMemoryMaxContextTokens);if($)A+=`
31
+ `}async function mE(E,M=!1){let N=await PE(E),_=0;for(let O of N){let J=await tM(O,"utf-8"),S=_0(J);if(S!==J){if(_+=1,!M)if(S==="")await sM(O);else await E0(O,S,"utf-8")}}return{files:N,changed:_}}async function TE(E,M,N,_,O=!1){let S=M.getAll(E).flatMap((C)=>N.getBySession(C.id));if(O){let C=new Set;for(let A of S)for(let $ of[...A.filesRead,...A.filesModified])C.add($);return{observations:S.length,filesTouched:C.size}}if(!oM(E))return{observations:0,filesTouched:0};await fE(E,S,_);let V=await PE(E);return{observations:S.length,filesTouched:V.length}}class s{observations;sessions;summaries;searchOrchestrator;projectPath;config;userObservationRepo;runtimeSnapshotProvider;configAuditStore;maintenanceHistoryStore;configAuditLogFallback=[];maintenanceLogFallback=[];constructor(E){this.observations=E.observations,this.sessions=E.sessions,this.summaries=E.summaries,this.searchOrchestrator=E.searchOrchestrator,this.projectPath=E.projectPath,this.config=E.config,this.userObservationRepo=E.userObservationRepo??null,this.runtimeSnapshotProvider=E.runtimeSnapshotProvider??null,this.configAuditStore=E.configAuditStore??null,this.maintenanceHistoryStore=E.maintenanceHistoryStore??null}getByIdIncludingArchived(E){let M=this.observations;return M.getByIdIncludingArchived?M.getByIdIncludingArchived(E):this.observations.getById(E)}listByProjectWithState(E){let M=this.observations;if(M.listByProject)return M.listByProject(this.projectPath,E);if(E.state!=="current")return[];return this.listObservations({limit:E.limit,offset:E.offset,type:E.type,sessionId:E.sessionId})}async ingest(E){}async processPending(E){return 0}async search(E,M={}){return this.searchOrchestrator.search(E,{type:M.type,limit:M.limit??10,projectPath:this.projectPath,importanceMin:M.importanceMin,importanceMax:M.importanceMax,createdAfter:M.after,createdBefore:M.before,concepts:M.concepts,files:M.files})}async timeline(E={}){if(E.sessionId){let N=this.sessions.getById(E.sessionId);if(!N)return[];return[{session:N,summary:this.summaries.getBySessionId(N.id),observations:this.observations.getBySession(N.id)}]}return this.sessions.getRecent(this.projectPath,E.limit??5).map((N)=>({session:N,summary:this.summaries.getBySessionId(N.id),observations:[]}))}async recall(E,M=10){let N=[];for(let _ of E.slice(0,M)){let O=this.observations.getById(_);if(O){N.push(O);continue}if(!this.userObservationRepo)continue;let J=this.userObservationRepo.getById(_);if(!J)continue;N.push({...J,sessionId:"",rawToolOutput:"",discoveryTokens:0})}return N}async save(E){if(E.scope==="user"){if(!this.userObservationRepo)return null;return{...this.userObservationRepo.create({type:E.type,title:E.title,subtitle:"",facts:[],narrative:E.narrative,concepts:E.concepts??[],filesRead:[],filesModified:E.files??[],toolName:"mem-create",tokenCount:W(`${E.title} ${E.narrative}`),importance:E.importance??3,sourceProject:this.projectPath}),sessionId:"",rawToolOutput:"",discoveryTokens:0}}this.sessions.getOrCreate(E.sessionId,this.projectPath);let M=this.observations.create({sessionId:E.sessionId,type:E.type,title:E.title,subtitle:"",facts:[],narrative:E.narrative,concepts:E.concepts??[],filesRead:[],filesModified:E.files??[],rawToolOutput:`[Manual save] ${E.narrative}`,toolName:"mem-create",tokenCount:W(`${E.title} ${E.narrative}`),discoveryTokens:0,importance:E.importance??3});return this.sessions.incrementObservationCount(E.sessionId),M}async update(E){let M=this.observations.getById(E.id);if(!M)return null;let N=this.sessions.getById(M.sessionId);if(!N||N.projectPath!==this.projectPath)return null;let{id:_,...O}=E;return this.observations.update(E.id,O)??null}async delete(E){let M=0;for(let N of E){let _=this.observations.getById(N);if(!_)continue;let O=this.sessions.getById(_.sessionId);if(!O||O.projectPath!==this.projectPath)continue;if(this.observations.delete(N))M+=1}return M}async export(E,M={}){if(E!=="project")throw Error("Only project scope export is supported.");let N=this.sessions.getAll(this.projectPath),_=[];for(let V of N)_.push(...this.observations.getBySession(V.id));if(M.type)_=_.filter((V)=>V.type===M.type);if(_.sort((V,C)=>new Date(V.createdAt).getTime()-new Date(C.createdAt).getTime()),M.limit&&M.limit<_.length)_=_.slice(0,M.limit);let O=_.map(({rawToolOutput:V,...C})=>C),J=N.map((V)=>this.summaries.getBySessionId(V.id)).filter((V)=>V!==null);return{version:1,exportedAt:new Date().toISOString(),project:this.projectPath,observations:O,summaries:J}}async import(E,M={}){let N;try{N=JSON.parse(E)}catch{throw Error("Invalid JSON payload.")}if(typeof N!=="object"||N===null)throw Error("Invalid import payload.");let _=N;if(_.version!==1||!Array.isArray(_.observations))throw Error("Unsupported export format.");let O=M.mode??"skip-duplicates",J=0,S=0;for(let V of _.observations){let C=this.observations.getById(V.id);if(C&&O==="skip-duplicates"){S+=1;continue}if(C&&O==="overwrite")this.observations.delete(V.id);this.sessions.getOrCreate(V.sessionId,this.projectPath),this.observations.importObservation({id:V.id,sessionId:V.sessionId,type:V.type,title:V.title,subtitle:V.subtitle??"",facts:V.facts??[],narrative:V.narrative??"",concepts:V.concepts??[],filesRead:V.filesRead??[],filesModified:V.filesModified??[],rawToolOutput:V.rawToolOutput??"",toolName:V.toolName??"unknown",createdAt:V.createdAt,tokenCount:V.tokenCount??0,discoveryTokens:V.discoveryTokens??0,importance:V.importance??3,supersededBy:V.supersededBy??null,supersededAt:V.supersededAt??null}),this.sessions.incrementObservationCount(V.sessionId),J+=1}for(let V of _.summaries??[]){let C=this.summaries.getBySessionId(V.sessionId);if(C&&O==="skip-duplicates")continue;if(C&&O==="overwrite")continue;this.sessions.getOrCreate(V.sessionId,this.projectPath),this.summaries.importSummary(V),this.sessions.setSummary(V.sessionId,V.id)}return{imported:J,skipped:S}}async buildContext(E,M="normal"){let N=this.sessions.getRecent(this.projectPath,5),_=N.map(($)=>$.summaryId?this.summaries.getBySessionId($.id):null).filter(($)=>$!==null),O=this.observations.getIndex(this.projectPath,this.config.maxObservations),S=O.slice(0,this.config.contextFullObservationCount).map(($)=>$.id).map(($)=>this.observations.getById($)).filter(($)=>$!==null),V=FE(N,_,O,this.config.maxContextTokens,S);if(M==="compaction"){let $=WE(V);if(this.config.userMemoryEnabled&&this.userObservationRepo)$+=UE(this.userObservationRepo.getIndex(this.config.maxObservations),this.config.userMemoryMaxContextTokens);return $}let C={showTokenCosts:this.config.contextShowTokenCosts,observationTypes:this.config.contextObservationTypes,fullObservationCount:this.config.contextFullObservationCount,showLastSummary:this.config.contextShowLastSummary},A=zE(V,C);if(this.config.userMemoryEnabled&&this.userObservationRepo){let $=YE(this.userObservationRepo.getIndex(this.config.maxObservations),this.config.userMemoryMaxContextTokens);if($)A+=`
32
32
 
33
- ${$}`}return A}guide(){return["open-mem workflow:","1) Use memory.find to find candidate observations by query.","2) Use memory.history to inspect session-level history and summaries.","3) Use memory.get with IDs from find/history to fetch full details.","Write/edit flow: memory.create (new), memory.revise (refine), memory.remove (tombstone).","Transfer flow: memory.transfer.export for backup/portability, memory.transfer.import to restore."].join(`
33
+ ${$}`}return A}guide(){return["open-mem workflow:","1) Use mem-find to find candidate observations by query.","2) Use mem-history to inspect session-level history and summaries.","3) Use mem-get with IDs from find/history to fetch full details.","Write/edit flow: mem-create (new), mem-revise (refine), mem-remove (tombstone).","Transfer flow: mem-export for backup/portability, mem-import to restore."].join(`
34
34
  `)}listObservations(E){let{limit:M=50,offset:N=0,type:_,sessionId:O,state:J}=E;if(J)return this.listByProjectWithState({limit:M,offset:N,type:_,state:J,sessionId:O});if(O){let C=this.observations.getBySession(O);if(_)C=C.filter((A)=>A.type===_);return C.slice(N,N+M)}let V=this.observations.getIndex(this.projectPath,N+M).slice(N);if(_)V=V.filter((C)=>C.type===_);return V.map((C)=>this.observations.getById(C.id)).filter((C)=>C!==null)}getObservation(E){return this.observations.getById(E)}getLineage(E){let N=this.getByIdIncludingArchived(E);if(!N)return null;let _=N,O=0,J=new Set([N.id]);while(_.revisionOf&&O<256){let $=this.getByIdIncludingArchived(_.revisionOf);if(!$||J.has($.id))break;_=$,J.add($.id),O+=1}let S=[],V=_,C=new Set,A=0;while(V&&!C.has(V.id)&&A<256){C.add(V.id);let $=V.deletedAt?"tombstoned":V.supersededBy?"superseded":"current";S.push({id:V.id,revisionOf:V.revisionOf??null,supersededBy:V.supersededBy??null,supersededAt:V.supersededAt??null,deletedAt:V.deletedAt??null,state:$,observation:V}),V=V.supersededBy?this.getByIdIncludingArchived(V.supersededBy):null,A+=1}return S}listSessions(E){return this.sessions.getRecent(E.projectPath??this.projectPath,E.limit??20)}getSession(E){let M=this.sessions.getById(E);if(!M)return null;return{session:M,summary:this.summaries.getBySessionId(E),observations:this.observations.getBySession(E)}}stats(){let E=this.observations.getCount(),N=this.sessions.getAll(this.projectPath).length,_=this.observations.getIndex(this.projectPath,1e4),O=0,J=0,S={};for(let A of _)O+=A.tokenCount,J+=A.discoveryTokens,S[A.type]=(S[A.type]||0)+1;let V=J-O,C=_.length>0?Math.round(O/_.length):0;return{totalObservations:E,totalSessions:N,totalTokensSaved:V,averageObservationSize:C,typeBreakdown:S}}async maintainFolderContext(E,M){if(E==="rebuild"){let _=await TE(this.projectPath,this.sessions,this.observations,this.config.folderContextMaxDepth,M);return{action:E,dryRun:M,..._}}let N=await mE(this.projectPath,M);return{action:"clean",dryRun:M,...N}}getRevisionDiff(E,M){let N=this.getByIdIncludingArchived(E),_=this.getByIdIncludingArchived(M);if(!N||!_)return null;let O=[],J=(V,C,A)=>{if(JSON.stringify(C)!==JSON.stringify(A))O.push({field:V,before:C,after:A})};J("title",_.title,N.title),J("subtitle",_.subtitle,N.subtitle),J("narrative",_.narrative,N.narrative),J("type",_.type,N.type),J("facts",_.facts,N.facts),J("concepts",_.concepts,N.concepts),J("filesRead",_.filesRead,N.filesRead),J("filesModified",_.filesModified,N.filesModified),J("importance",_.importance,N.importance);let S=O.length===0?"No material changes between revisions.":`Changed ${O.length} field${O.length===1?"":"s"}: ${O.map((V)=>V.field).join(", ")}.`;return{fromId:M,toId:E,summary:S,changedFields:O}}getHealth(){let E=this.runtimeSnapshotProvider?.(),M=E&&E.queue.lastError?"degraded":"ok";return{status:E?.status??"ok",timestamp:E?.timestamp??new Date().toISOString(),components:{database:{status:"ok"},search:{status:"ok"},config:{status:"ok"},queue:{status:M,detail:E?.queue.lastError??void 0}}}}getMetrics(){let E=this.stats();return{timestamp:this.runtimeSnapshotProvider?.()?.timestamp??new Date().toISOString(),memory:{totalObservations:E.totalObservations,totalSessions:E.totalSessions,totalTokensSaved:E.totalTokensSaved,averageObservationSize:E.averageObservationSize}}}getPlatforms(){return{name:"open-mem",provider:this.config.provider,dashboardEnabled:this.config.dashboardEnabled,vectorEnabled:Boolean(this.config.embeddingDimension&&this.config.embeddingDimension>0)}}getAdapterStatuses(){let E={opencode:this.config.platformOpenCodeEnabled??!0,"claude-code":this.config.platformClaudeCodeEnabled??!1,cursor:this.config.platformCursorEnabled??!1};return[{name:"opencode",version:"1.0",capabilities:{nativeSessionLifecycle:!0,nativeToolCapture:!0,nativeChatCapture:!0,emulatedIdleFlush:!1}},{name:"claude-code",version:"0.1",capabilities:{nativeSessionLifecycle:!0,nativeToolCapture:!0,nativeChatCapture:!0,emulatedIdleFlush:!0}},{name:"cursor",version:"0.1",capabilities:{nativeSessionLifecycle:!1,nativeToolCapture:!0,nativeChatCapture:!0,emulatedIdleFlush:!0}}].map((N)=>({name:N.name,version:N.version,enabled:E[N.name]??!1,capabilities:N.capabilities}))}getConfigAuditTimeline(){if(this.configAuditStore)return this.configAuditStore.list();return[...this.configAuditLogFallback].reverse()}trackConfigAudit(E){if(this.configAuditStore){this.configAuditStore.append(E);return}this.configAuditLogFallback.push(E)}async rollbackConfig(E){let M=this.configAuditStore?this.configAuditStore.getById(E):this.configAuditLogFallback.find((J)=>J.id===E)??null;if(!M)return null;if(!M.previousValues||typeof M.previousValues!=="object")return null;let{patchConfig:N}=await Promise.resolve().then(() => (qE(),hE)),_=M.previousValues;try{await N(this.projectPath,_)}catch(J){let S={id:`rollback-failed-${xE()}`,timestamp:new Date().toISOString(),patch:M.previousValues,previousValues:M.patch,source:"rollback-failed"};throw this.trackConfigAudit(S),J}let O={id:`rollback-${xE()}`,timestamp:new Date().toISOString(),patch:M.previousValues,previousValues:M.patch,source:"rollback"};return this.trackConfigAudit(O),O}getMaintenanceHistory(){if(this.maintenanceHistoryStore)return this.maintenanceHistoryStore.list();return[...this.maintenanceLogFallback].reverse()}trackMaintenanceResult(E){if(this.maintenanceHistoryStore){this.maintenanceHistoryStore.append(E);return}this.maintenanceLogFallback.push(E)}}function x(E){try{let M=JSON.parse(E);return M&&typeof M==="object"?M:{}}catch{return{}}}class EE{db;constructor(E){this.db=E}list(){return this.db.all("SELECT id, timestamp, patch, previous_values, source FROM config_audit_events ORDER BY timestamp DESC").map((E)=>({id:E.id,timestamp:E.timestamp,patch:x(E.patch),previousValues:x(E.previous_values),source:E.source}))}getById(E){let M=this.db.get("SELECT id, timestamp, patch, previous_values, source FROM config_audit_events WHERE id = ?",[E]);if(!M)return null;return{id:M.id,timestamp:M.timestamp,patch:x(M.patch),previousValues:x(M.previous_values),source:M.source}}append(E){this.db.run("INSERT INTO config_audit_events (id, timestamp, patch, previous_values, source) VALUES (?, ?, ?, ?, ?)",[E.id,E.timestamp,JSON.stringify(E.patch??{}),JSON.stringify(E.previousValues??{}),E.source])}}import{Database as uE}from"bun:sqlite";import{existsSync as ME,mkdirSync as K0,unlinkSync as wE}from"fs";import*as lE from"sqlite-vec";class u{db;dbPath;_hasVectorExtension=!1;static enableExtensionSupport(){let E=["/opt/homebrew/opt/sqlite/lib/libsqlite3.dylib","/usr/local/opt/sqlite/lib/libsqlite3.dylib"];for(let M of E)try{if(ME(M))return uE.setCustomSQLite(M),!0}catch{return!1}return!1}constructor(E){this.dbPath=E,this.db=this.open(E),this.configure()}open(E){let M=E.lastIndexOf("/");if(M>0){let N=E.substring(0,M);K0(N,{recursive:!0})}return new uE(E,{create:!0})}configure(){try{this.applyPragmas(),this.loadExtensions()}catch(E){console.warn("[open-mem] Database configure failed, attempting recovery by removing WAL/SHM files:",E.message);try{this.db.close()}catch{}this.deleteSidecarFiles();try{this.db=this.open(this.dbPath),this.applyPragmas(),this.loadExtensions(),console.warn("[open-mem] Recovery successful after removing WAL/SHM files");return}catch(M){console.warn("[open-mem] WAL/SHM cleanup insufficient, recreating database from scratch:",M.message);try{this.db.close()}catch{}this.deleteDatabaseFiles();try{this.db=this.open(this.dbPath),this.applyPragmas(),this.loadExtensions(),console.warn("[open-mem] Recovery successful after full database recreation");return}catch(N){throw console.warn("[open-mem] All recovery attempts failed, filesystem may be broken:",N.message),E}}}}applyPragmas(){this.db.exec("PRAGMA journal_mode = WAL"),this.db.exec("PRAGMA synchronous = NORMAL"),this.db.exec("PRAGMA foreign_keys = ON"),this.db.exec("PRAGMA busy_timeout = 5000")}loadExtensions(){try{lE.load(this.db),this._hasVectorExtension=!0}catch{this._hasVectorExtension=!1}}get hasVectorExtension(){return this._hasVectorExtension}deleteSidecarFiles(){for(let E of["-wal","-shm"]){let M=this.dbPath+E;try{if(ME(M))wE(M)}catch{}}}deleteDatabaseFiles(){this.deleteSidecarFiles();try{if(ME(this.dbPath))wE(this.dbPath)}catch{}}ensureMigrationTable(){this.db.exec(`
35
35
  CREATE TABLE IF NOT EXISTS _migrations (
36
36
  version INTEGER PRIMARY KEY,
@@ -49,7 +49,7 @@ ${$}`}return A}guide(){return["open-mem workflow:","1) Use memory.find to find c
49
49
  JOIN entities_fts fts ON e._rowid = fts.rowid
50
50
  WHERE entities_fts MATCH ?
51
51
  ORDER BY rank`,[E]).map((N)=>this.mapEntityRow(N))}catch{return[]}}getRelationsFor(E){return this.db.all(`SELECT * FROM entity_relations
52
- WHERE source_entity_id = ? OR target_entity_id = ?`,[E,E]).map((N)=>this.mapRelationRow(N))}traverseRelations(E,M=1){let N=Math.min(M,2),_=100,O=new Set,J=[{id:E,currentDepth:0}];O.add(E);while(J.length>0){if(O.size>=100)break;let S=J.shift();if(!S)continue;if(S.currentDepth>=N)continue;let V=this.getRelationsFor(S.id);for(let C of V){let A=C.sourceEntityId===S.id?C.targetEntityId:C.sourceEntityId;if(!O.has(A))O.add(A),J.push({id:A,currentDepth:S.currentDepth+1})}}return O}getObservationsForEntity(E){return this.db.all("SELECT observation_id FROM entity_observations WHERE entity_id = ?",[E]).map((N)=>N.observation_id)}getById(E){let M=this.db.get("SELECT * FROM entities WHERE id = ?",[E]);return M?this.mapEntityRow(M):null}mapEntityRow(E){return{id:E.id,name:E.name,entityType:E.entity_type,firstSeenAt:E.first_seen_at,lastSeenAt:E.last_seen_at,mentionCount:E.mention_count}}mapRelationRow(E){return{id:E.id,sourceEntityId:E.source_entity_id,targetEntityId:E.target_entity_id,relationship:E.relationship,observationId:E.observation_id,createdAt:E.created_at}}}function L0(E){try{let M=JSON.parse(E);return M&&typeof M==="object"?M:{}}catch{return{}}}class _E{db;constructor(E){this.db=E}list(){return this.db.all("SELECT id, timestamp, action, dry_run, result FROM maintenance_history ORDER BY timestamp DESC").map((E)=>({id:E.id,timestamp:E.timestamp,action:E.action,dryRun:E.dry_run===1,result:L0(E.result)}))}append(E){this.db.run("INSERT INTO maintenance_history (id, timestamp, action, dry_run, result) VALUES (?, ?, ?, ?, ?)",[E.id,E.timestamp,E.action,E.dryRun?1:0,JSON.stringify(E.result??{})])}}import{randomUUID as z0}from"crypto";import{embed as Q0}from"ai";async function l(E,M){try{let{embedding:N}=await Q0({model:E,value:M});return N}catch{return null}}function j(E,M){if(E.length!==M.length||E.length===0)return 0;let N=0,_=0,O=0;for(let S=0;S<E.length;S++)N+=E[S]*M[S],_+=E[S]*E[S],O+=M[S]*M[S];let J=Math.sqrt(_)*Math.sqrt(O);if(J===0)return 0;return N/J}function W0(E){return E.replace(/[%_\\]/g,"\\$&")}class OE{db;constructor(E){this.db=E}create(E){let M=z0(),N=new Date().toISOString(),_=E.discoveryTokens??0,O=E.importance??3,J=E.scope??"project";return this.db.run(`INSERT INTO observations
52
+ WHERE source_entity_id = ? OR target_entity_id = ?`,[E,E]).map((N)=>this.mapRelationRow(N))}traverseRelations(E,M=1){let N=Math.min(M,2),_=100,O=new Set,J=[{id:E,currentDepth:0}];O.add(E);while(J.length>0){if(O.size>=100)break;let S=J.shift();if(!S)continue;if(S.currentDepth>=N)continue;let V=this.getRelationsFor(S.id);for(let C of V){let A=C.sourceEntityId===S.id?C.targetEntityId:C.sourceEntityId;if(!O.has(A))O.add(A),J.push({id:A,currentDepth:S.currentDepth+1})}}return O}getObservationsForEntity(E){return this.db.all("SELECT observation_id FROM entity_observations WHERE entity_id = ?",[E]).map((N)=>N.observation_id)}getById(E){let M=this.db.get("SELECT * FROM entities WHERE id = ?",[E]);return M?this.mapEntityRow(M):null}mapEntityRow(E){return{id:E.id,name:E.name,entityType:E.entity_type,firstSeenAt:E.first_seen_at,lastSeenAt:E.last_seen_at,mentionCount:E.mention_count}}mapRelationRow(E){return{id:E.id,sourceEntityId:E.source_entity_id,targetEntityId:E.target_entity_id,relationship:E.relationship,observationId:E.observation_id,createdAt:E.created_at}}}function L0(E){try{let M=JSON.parse(E);return M&&typeof M==="object"?M:{}}catch{return{}}}class _E{db;constructor(E){this.db=E}list(){return this.db.all("SELECT id, timestamp, action, dry_run, result FROM maintenance_history ORDER BY timestamp DESC").map((E)=>({id:E.id,timestamp:E.timestamp,action:E.action,dryRun:E.dry_run===1,result:L0(E.result)}))}append(E){this.db.run("INSERT INTO maintenance_history (id, timestamp, action, dry_run, result) VALUES (?, ?, ?, ?, ?)",[E.id,E.timestamp,E.action,E.dryRun?1:0,JSON.stringify(E.result??{})])}}import{randomUUID as z0}from"crypto";import{embed as Q0}from"ai";async function l(E,M){try{let{embedding:N}=await Q0({model:E,value:M});return N}catch{return null}}function k(E,M){if(E.length!==M.length||E.length===0)return 0;let N=0,_=0,O=0;for(let S=0;S<E.length;S++)N+=E[S]*M[S],_+=E[S]*E[S],O+=M[S]*M[S];let J=Math.sqrt(_)*Math.sqrt(O);if(J===0)return 0;return N/J}function W0(E){return E.replace(/[%_\\]/g,"\\$&")}class OE{db;constructor(E){this.db=E}create(E){let M=z0(),N=new Date().toISOString(),_=E.discoveryTokens??0,O=E.importance??3,J=E.scope??"project";return this.db.run(`INSERT INTO observations
53
53
  (id, session_id, scope, type, title, subtitle, facts, narrative,
54
54
  concepts, files_read, files_modified, raw_tool_output,
55
55
  tool_name, created_at, token_count, discovery_tokens, importance, revision_of, deleted_at)
@@ -96,11 +96,11 @@ ${$}`}return A}guide(){return["open-mem workflow:","1) Use memory.find to find c
96
96
  LIMIT ?`,[E,M]).map((N)=>{try{return{id:N.id,embedding:JSON.parse(N.embedding),title:N.title}}catch{return null}}).filter((N)=>N!==null)}findSimilar(E,M,N,_){let O=this.db.all(`SELECT id, embedding FROM observations
97
97
  WHERE embedding IS NOT NULL AND type = ? AND superseded_by IS NULL AND deleted_at IS NULL
98
98
  ORDER BY created_at DESC
99
- LIMIT 200`,[M]),J=[];for(let S of O)try{let V=JSON.parse(S.embedding);if(!Array.isArray(V)||V.length!==E.length)continue;let C=j(E,V);if(C>=N)J.push({id:S.id,similarity:C})}catch{}return J.sort((S,V)=>V.similarity-S.similarity).slice(0,_)}insertVecEmbedding(E,M){let N=new Float32Array(M);this.db.run("BEGIN");try{this.db.run("DELETE FROM observation_embeddings WHERE observation_id = ?",[E]),this.db.run("INSERT INTO observation_embeddings (observation_id, embedding) VALUES (?, ?)",[E,N]),this.db.run("COMMIT")}catch(_){throw this.db.run("ROLLBACK"),_}}migrateExistingEmbeddings(E){let M=this.db.all("SELECT id, embedding FROM observations WHERE embedding IS NOT NULL"),N=0,_=0;for(let O of M)try{let J=JSON.parse(O.embedding);if(!Array.isArray(J)||J.length!==E){_++;continue}this.insertVecEmbedding(O.id,J),N++}catch{_++}return{migrated:N,skipped:_}}getVecEmbeddingMatches(E,M){try{let N=new Float32Array(E);return this.db.all(`SELECT observation_id, distance
99
+ LIMIT 200`,[M]),J=[];for(let S of O)try{let V=JSON.parse(S.embedding);if(!Array.isArray(V)||V.length!==E.length)continue;let C=k(E,V);if(C>=N)J.push({id:S.id,similarity:C})}catch{}return J.sort((S,V)=>V.similarity-S.similarity).slice(0,_)}insertVecEmbedding(E,M){let N=new Float32Array(M);this.db.run("BEGIN");try{this.db.run("DELETE FROM observation_embeddings WHERE observation_id = ?",[E]),this.db.run("INSERT INTO observation_embeddings (observation_id, embedding) VALUES (?, ?)",[E,N]),this.db.run("COMMIT")}catch(_){throw this.db.run("ROLLBACK"),_}}migrateExistingEmbeddings(E){let M=this.db.all("SELECT id, embedding FROM observations WHERE embedding IS NOT NULL"),N=0,_=0;for(let O of M)try{let J=JSON.parse(O.embedding);if(!Array.isArray(J)||J.length!==E){_++;continue}this.insertVecEmbedding(O.id,J),N++}catch{_++}return{migrated:N,skipped:_}}getVecEmbeddingMatches(E,M){try{let N=new Float32Array(E);return this.db.all(`SELECT observation_id, distance
100
100
  FROM observation_embeddings
101
101
  WHERE embedding MATCH ? AND k = ?`,[N,M]).map((_)=>({observationId:_.observation_id,distance:_.distance}))}catch{return[]}}searchVecSubset(E,M,N){if(M.length===0)return[];try{let _=new Float32Array(E),O=Math.max(N*5,M.length),J=this.db.all(`SELECT observation_id, distance
102
102
  FROM observation_embeddings
103
- WHERE embedding MATCH ? AND k = ?`,[_,O]),S=new Set(M);return J.filter((V)=>S.has(V.observation_id)).slice(0,N).map((V)=>({observationId:V.observation_id,distance:V.distance}))}catch{return[]}}update(E,M){let N=this.getById(E);if(!N)return null;if(Object.keys(M).length===0)return N;let _=this.create({sessionId:N.sessionId,scope:N.scope??"project",type:M.type??N.type,title:M.title??N.title,subtitle:M.subtitle??N.subtitle,facts:M.facts??N.facts,narrative:M.narrative??N.narrative,concepts:M.concepts??N.concepts,filesRead:M.filesRead??N.filesRead,filesModified:M.filesModified??N.filesModified,rawToolOutput:N.rawToolOutput,toolName:"memory.revise",tokenCount:N.tokenCount,discoveryTokens:N.discoveryTokens,importance:M.importance??N.importance});return this.db.run("UPDATE observations SET revision_of = ? WHERE id = ?",[E,_.id]),this.supersede(E,_.id),this.getById(_.id)}supersede(E,M){let N=new Date().toISOString();this.db.run("UPDATE observations SET superseded_by = ?, superseded_at = ? WHERE id = ?",[M,N,E])}delete(E){if(this.db.all("SELECT id FROM observations WHERE id = ?",[E]).length===0)return!1;let N=new Date().toISOString();return this.db.run("UPDATE observations SET deleted_at = ? WHERE id = ?",[N,E]),this.deleteEmbeddingsForObservations([E]),!0}getLineage(E){let M=this.getByIdIncludingArchived(E);if(!M)return[];let N=new Set([M.id]),_=[M];while(_[0].revisionOf){let O=this.getByIdIncludingArchived(_[0].revisionOf);if(!O||N.has(O.id))break;_.unshift(O),N.add(O.id)}while(_[_.length-1].supersededBy){let O=_[_.length-1].supersededBy;if(!O)break;let J=this.getByIdIncludingArchived(O);if(!J||N.has(J.id))break;_.push(J),N.add(J.id)}return _}deleteOlderThan(E){return this.db.all(`DELETE FROM observations
103
+ WHERE embedding MATCH ? AND k = ?`,[_,O]),S=new Set(M);return J.filter((V)=>S.has(V.observation_id)).slice(0,N).map((V)=>({observationId:V.observation_id,distance:V.distance}))}catch{return[]}}update(E,M){let N=this.getById(E);if(!N)return null;if(Object.keys(M).length===0)return N;let _=this.create({sessionId:N.sessionId,scope:N.scope??"project",type:M.type??N.type,title:M.title??N.title,subtitle:M.subtitle??N.subtitle,facts:M.facts??N.facts,narrative:M.narrative??N.narrative,concepts:M.concepts??N.concepts,filesRead:M.filesRead??N.filesRead,filesModified:M.filesModified??N.filesModified,rawToolOutput:N.rawToolOutput,toolName:"mem-revise",tokenCount:N.tokenCount,discoveryTokens:N.discoveryTokens,importance:M.importance??N.importance});return this.db.run("UPDATE observations SET revision_of = ? WHERE id = ?",[E,_.id]),this.supersede(E,_.id),this.getById(_.id)}supersede(E,M){let N=new Date().toISOString();this.db.run("UPDATE observations SET superseded_by = ?, superseded_at = ? WHERE id = ?",[M,N,E])}delete(E){if(this.db.all("SELECT id FROM observations WHERE id = ?",[E]).length===0)return!1;let N=new Date().toISOString();return this.db.run("UPDATE observations SET deleted_at = ? WHERE id = ?",[N,E]),this.deleteEmbeddingsForObservations([E]),!0}getLineage(E){let M=this.getByIdIncludingArchived(E);if(!M)return[];let N=new Set([M.id]),_=[M];while(_[0].revisionOf){let O=this.getByIdIncludingArchived(_[0].revisionOf);if(!O||N.has(O.id))break;_.unshift(O),N.add(O.id)}while(_[_.length-1].supersededBy){let O=_[_.length-1].supersededBy;if(!O)break;let J=this.getByIdIncludingArchived(O);if(!J||N.has(J.id))break;_.push(J),N.add(J.id)}return _}deleteOlderThan(E){return this.db.all(`DELETE FROM observations
104
104
  WHERE (created_at < datetime('now', '-' || ? || ' days') OR deleted_at IS NOT NULL)
105
105
  AND session_id NOT IN (SELECT id FROM sessions WHERE status != 'completed')
106
106
  RETURNING id`,[E]).length}deleteEmbeddingsForObservations(E){if(E.length===0)return;let M=E.map(()=>"?").join(",");try{this.db.run(`DELETE FROM observation_embeddings WHERE observation_id IN (${M})`,E)}catch{}this.db.run(`UPDATE observations SET embedding = NULL WHERE id IN (${M})`,E)}mapRow(E){return{id:E.id,sessionId:E.session_id,scope:E.scope??"project",type:E.type,title:E.title,subtitle:E.subtitle,facts:JSON.parse(E.facts),narrative:E.narrative,concepts:JSON.parse(E.concepts),filesRead:JSON.parse(E.files_read),filesModified:JSON.parse(E.files_modified),rawToolOutput:E.raw_tool_output,toolName:E.tool_name,createdAt:E.created_at,tokenCount:E.token_count,discoveryTokens:E.discovery_tokens??0,importance:E.importance??3,revisionOf:E.revision_of??null,deletedAt:E.deleted_at??null,supersededBy:E.superseded_by??null,supersededAt:E.superseded_at??null}}}var Y0=[{version:1,name:"create-schema",up:`
@@ -495,7 +495,7 @@ ${$}`}return A}guide(){return["open-mem workflow:","1) Use memory.find to find c
495
495
  JOIN user_observations_fts fts ON o._rowid = fts.rowid
496
496
  WHERE user_observations_fts MATCH ?
497
497
  `,N=[E.query];if(E.sourceProject)M+=" AND o.source_project = ?",N.push(E.sourceProject);return M+=" ORDER BY rank LIMIT ?",N.push(E.limit??10),this.db.all(M,N).map((_)=>({observation:this.mapRow(_),rank:_.rank}))}catch{return[]}}getIndex(E,M){let N=`SELECT id, type, title, token_count, created_at, importance, source_project
498
- FROM user_observations`,_=[];if(M)N+=" WHERE source_project = ?",_.push(M);return N+=" ORDER BY created_at DESC LIMIT ?",_.push(E??20),this.db.all(N,_).map((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(E){let M=this.db.get("SELECT * FROM user_observations WHERE id = ?",[E]);return M?this.mapRow(M):null}delete(E){return this.db.all("DELETE FROM user_observations WHERE id = ? RETURNING id",[E]).length>0}mapRow(E){return{id:E.id,type:E.type,title:E.title,subtitle:E.subtitle,facts:JSON.parse(E.facts),narrative:E.narrative,concepts:JSON.parse(E.concepts),filesRead:JSON.parse(E.files_read),filesModified:JSON.parse(E.files_modified),toolName:E.tool_name,createdAt:E.created_at,tokenCount:E.token_count,importance:E.importance??3,sourceProject:E.source_project}}}function D0(E){if(E.startsWith("~/")){let M=process.env.HOME||process.env.USERPROFILE||"";if(!M)throw Error("Cannot resolve user DB path: HOME environment variable is not set");let N=`${M}${E.slice(1)}`,_=N.substring(0,N.lastIndexOf("/"));return U("fs").mkdirSync(_,{recursive:!0}),N}return E}function k(E,M){if(M.type&&E.type!==M.type)return!1;if(M.importanceMin!==void 0&&E.importance<M.importanceMin)return!1;if(M.importanceMax!==void 0&&E.importance>M.importanceMax)return!1;if(M.createdAfter&&E.createdAt<M.createdAfter)return!1;if(M.createdBefore&&E.createdAt>M.createdBefore)return!1;if(M.concepts&&M.concepts.length>0){if(!M.concepts.some((_)=>E.concepts.some((O)=>O.toLowerCase().includes(_.toLowerCase()))))return!1}if(M.files&&M.files.length>0){let N=[...E.filesRead,...E.filesModified];if(!M.files.some((O)=>N.some((J)=>J.toLowerCase().includes(O.toLowerCase()))))return!1}return!0}async function nE(E,M,N,_,O){if(!E.trim())return M;let J=y0(E),S=new Set;for(let A of J){let $=N.findByName(A);for(let H of $){let Y=N.traverseRelations(H.id,1);for(let B of Y){let D=N.getObservationsForEntity(B);for(let b of D)S.add(b)}}}if(S.size===0)return M;let V=new Set(M.map((A)=>A.observation.id)),C=[];for(let A of S){if(V.has(A))continue;let $=_.getById(A);if(!$)continue;if($.supersededBy)continue;C.push({observation:$,rank:0,snippet:$.title,source:"project",rankingSource:"graph",explain:{strategy:"hybrid",matchedBy:["graph"]}})}return[...M,...C].slice(0,O)}function y0(E){let M=E.split(/\s+/).filter((_)=>_.length>=2),N=[];for(let _ of M)N.push(_);for(let _=0;_<M.length-1;_++)N.push(`${M[_]} ${M[_+1]}`);return N}var dE=60;async function iE(E,M,N,_){let O=_.limit??10,J=j0(M,E,_,O);if(!N)return J;let S=await l(N,E);if(!S)return J;let V=J.map((A)=>A.observation.id),C=k0(M,S,_.projectPath,_,O,_.hasVectorExtension??!1,V);if(C.length===0)return J;return m0(J,C,O)}function j0(E,M,N,_){try{return E.search({query:M,type:N.type,limit:_,projectPath:N.projectPath,importanceMin:N.importanceMin,importanceMax:N.importanceMax,createdAfter:N.createdAfter,createdBefore:N.createdBefore,concepts:N.concepts,files:N.files})}catch{return[]}}function k0(E,M,N,_,O,J,S){if(J)return f0(E,M,_,O,S);return P0(E,M,N,_,O)}function f0(E,M,N,_,O){try{let J;if(O.length>0){if(J=E.searchVecSubset(M,O,_*3),J.length===0)J=E.getVecEmbeddingMatches(M,_*3)}else J=E.getVecEmbeddingMatches(M,_*3);if(J.length===0)return[];let S=[];for(let{observationId:V,distance:C}of J){if(S.length>=_)break;let A=E.getById(V);if(!A)continue;if(!k(A,N))continue;S.push({observation:A,rank:C-1,snippet:A.title,rankingSource:"vector",explain:{strategy:"hybrid",matchedBy:["vector"],vectorDistance:C}})}return S}catch{return[]}}function P0(E,M,N,_,O){let J=E.getWithEmbeddings(N,O*10);if(J.length===0)return[];let S=J.map((C)=>({id:C.id,similarity:j(M,C.embedding)})).filter(({similarity:C})=>C>=0.3).sort((C,A)=>A.similarity-C.similarity),V=[];for(let{id:C,similarity:A}of S){if(V.length>=O)break;let $=E.getById(C);if(!$)continue;if(!k($,_))continue;V.push({observation:$,rank:-A,snippet:$.title,rankingSource:"vector",explain:{strategy:"hybrid",matchedBy:["vector"],vectorSimilarity:A}})}return V}function m0(E,M,N){let _=new Map;for(let O=0;O<E.length;O++){let J=E[O],S=1/(dE+O+1);_.set(J.observation.id,{score:S,result:{...J,rankingSource:"fts",explain:{strategy:"hybrid",matchedBy:["fts"],ftsRank:J.rank}}})}for(let O=0;O<M.length;O++){let J=M[O],S=1/(dE+O+1),V=_.get(J.observation.id);if(V)V.score+=S,V.result={...V.result,explain:{strategy:"hybrid",matchedBy:["fts","vector"],ftsRank:V.result.explain?.ftsRank??V.result.rank,vectorDistance:J.explain?.vectorDistance,vectorSimilarity:J.explain?.vectorSimilarity}};else _.set(J.observation.id,{score:S,result:{...J,explain:{strategy:"hybrid",matchedBy:["vector"],vectorDistance:J.explain?.vectorDistance,vectorSimilarity:J.explain?.vectorSimilarity}}})}return[..._.values()].sort((O,J)=>J.score-O.score).slice(0,N).map(({score:O,result:J})=>({...J,explain:{...J.explain??{strategy:"hybrid",matchedBy:[]},strategy:"hybrid",matchedBy:J.explain?.matchedBy??[],rrfScore:O,ftsRank:J.explain?.ftsRank,vectorDistance:J.explain?.vectorDistance,vectorSimilarity:J.explain?.vectorSimilarity}}))}class AE{observations;embeddingModel;hasVectorExtension;reranker;userObservationRepo;entityRepo;constructor(E,M,N,_=null,O=null,J=null){this.observations=E;this.embeddingModel=M;this.hasVectorExtension=N;this.reranker=_;this.userObservationRepo=O;this.entityRepo=J}async search(E,M){let N=M.strategy??"hybrid",_=M.limit??10,O;switch(N){case"filter-only":O=this.filterOnlySearch(E,M,_);break;case"semantic":O=await this.semanticSearch(E,M,_);break;case"hybrid":O=await this.hybridSearchStrategy(E,M,_);break}for(let J of O)J.source="project";if(this.entityRepo&&E.trim())O=await nE(E,O,this.entityRepo,this.observations,_);if(this.userObservationRepo){let J=this.searchUserMemory(E,M,_);O=this.mergeResults(O,J,_)}if(this.reranker&&O.length>1)return this.reranker.rerank(E,O,_);return O}filterOnlySearch(E,M,N){if(M.concept)return this.observations.searchByConcept(M.concept,N,M.projectPath).map((O)=>({observation:O,rank:0,snippet:O.title,rankingSource:"graph",explain:{strategy:"filter-only",matchedBy:["concept-filter"]}}));if(M.file)return this.observations.searchByFile(M.file,N,M.projectPath).map((O)=>({observation:O,rank:0,snippet:O.title,rankingSource:"graph",explain:{strategy:"filter-only",matchedBy:["file-filter"]}}));return this.observations.search({query:E,type:M.type,limit:N,projectPath:M.projectPath,importanceMin:M.importanceMin,importanceMax:M.importanceMax,createdAfter:M.createdAfter,createdBefore:M.createdBefore,concepts:M.concepts,files:M.files})}async semanticSearch(E,M,N){if(!this.embeddingModel)return this.filterOnlySearch(E,M,N);let _=await l(this.embeddingModel,E);if(!_)return this.filterOnlySearch(E,M,N);if(this.hasVectorExtension)return this.nativeVectorSearch(_,M,N);return this.jsFallbackVectorSearch(_,M,N)}async hybridSearchStrategy(E,M,N){return iE(E,this.observations,this.embeddingModel,{type:M.type,limit:N,projectPath:M.projectPath,hasVectorExtension:this.hasVectorExtension,importanceMin:M.importanceMin,importanceMax:M.importanceMax,createdAfter:M.createdAfter,createdBefore:M.createdBefore,concepts:M.concepts,files:M.files})}nativeVectorSearch(E,M,N){try{let _=this.observations.getVecEmbeddingMatches(E,N*3);if(_.length===0)return[];let O=[];for(let{observationId:J,distance:S}of _){if(O.length>=N)break;let V=this.observations.getById(J);if(!V)continue;if(!k(V,M))continue;O.push({observation:V,rank:S-1,snippet:V.title,rankingSource:"vector",explain:{strategy:"semantic",matchedBy:["vector"],vectorDistance:S}})}return O}catch{return[]}}jsFallbackVectorSearch(E,M,N){let _=this.observations.getWithEmbeddings(M.projectPath,N*10);if(_.length===0)return[];let O=_.map((S)=>({id:S.id,similarity:j(E,S.embedding)})).filter(({similarity:S})=>S>=0.3).sort((S,V)=>V.similarity-S.similarity),J=[];for(let{id:S,similarity:V}of O){if(J.length>=N)break;let C=this.observations.getById(S);if(!C)continue;if(!k(C,M))continue;J.push({observation:C,rank:-V,snippet:C.title,rankingSource:"vector",explain:{strategy:"semantic",matchedBy:["vector"],vectorSimilarity:V}})}return J}searchUserMemory(E,M,N){if(!this.userObservationRepo)return[];try{return this.userObservationRepo.search({query:E,limit:N}).map(({observation:O,rank:J})=>({observation:T0(O),rank:J,snippet:O.title,source:"user",rankingSource:"user-memory",explain:{strategy:"filter-only",matchedBy:["user-memory"]}}))}catch{return[]}}mergeResults(E,M,N){let _=new Set(E.map((S)=>S.observation.id)),O=new Set(E.map((S)=>`${S.observation.title}::${S.observation.narrative}`)),J=M.filter((S)=>{if(_.has(S.observation.id))return!1;let V=`${S.observation.title}::${S.observation.narrative}`;if(O.has(V))return!1;return O.add(V),!0});return[...E,...J].slice(0,N)}}function T0(E){return{id:E.id,sessionId:"",type:E.type,title:E.title,subtitle:E.subtitle,facts:E.facts,narrative:E.narrative,concepts:E.concepts,filesRead:E.filesRead,filesModified:E.filesModified,rawToolOutput:"",toolName:E.toolName,createdAt:E.createdAt,tokenCount:E.tokenCount,discoveryTokens:0,importance:E.importance}}import{generateText as v0}from"ai";function rE(E,M){let N=M.map((_,O)=>` <candidate index="${O}"><title>${_.title}</title><narrative>${_.narrative}</narrative></candidate>`).join(`
498
+ FROM user_observations`,_=[];if(M)N+=" WHERE source_project = ?",_.push(M);return N+=" ORDER BY created_at DESC LIMIT ?",_.push(E??20),this.db.all(N,_).map((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(E){let M=this.db.get("SELECT * FROM user_observations WHERE id = ?",[E]);return M?this.mapRow(M):null}delete(E){return this.db.all("DELETE FROM user_observations WHERE id = ? RETURNING id",[E]).length>0}mapRow(E){return{id:E.id,type:E.type,title:E.title,subtitle:E.subtitle,facts:JSON.parse(E.facts),narrative:E.narrative,concepts:JSON.parse(E.concepts),filesRead:JSON.parse(E.files_read),filesModified:JSON.parse(E.files_modified),toolName:E.tool_name,createdAt:E.created_at,tokenCount:E.token_count,importance:E.importance??3,sourceProject:E.source_project}}}function D0(E){if(E.startsWith("~/")){let M=process.env.HOME||process.env.USERPROFILE||"";if(!M)throw Error("Cannot resolve user DB path: HOME environment variable is not set");let N=`${M}${E.slice(1)}`,_=N.substring(0,N.lastIndexOf("/"));return U("fs").mkdirSync(_,{recursive:!0}),N}return E}function f(E,M){if(M.type&&E.type!==M.type)return!1;if(M.importanceMin!==void 0&&E.importance<M.importanceMin)return!1;if(M.importanceMax!==void 0&&E.importance>M.importanceMax)return!1;if(M.createdAfter&&E.createdAt<M.createdAfter)return!1;if(M.createdBefore&&E.createdAt>M.createdBefore)return!1;if(M.concepts&&M.concepts.length>0){if(!M.concepts.some((_)=>E.concepts.some((O)=>O.toLowerCase().includes(_.toLowerCase()))))return!1}if(M.files&&M.files.length>0){let N=[...E.filesRead,...E.filesModified];if(!M.files.some((O)=>N.some((J)=>J.toLowerCase().includes(O.toLowerCase()))))return!1}return!0}async function nE(E,M,N,_,O){if(!E.trim())return M;let J=j0(E),S=new Set;for(let A of J){let $=N.findByName(A);for(let H of $){let Y=N.traverseRelations(H.id,1);for(let B of Y){let D=N.getObservationsForEntity(B);for(let b of D)S.add(b)}}}if(S.size===0)return M;let V=new Set(M.map((A)=>A.observation.id)),C=[];for(let A of S){if(V.has(A))continue;let $=_.getById(A);if(!$)continue;if($.supersededBy)continue;C.push({observation:$,rank:0,snippet:$.title,source:"project",rankingSource:"graph",explain:{strategy:"hybrid",matchedBy:["graph"]}})}return[...M,...C].slice(0,O)}function j0(E){let M=E.split(/\s+/).filter((_)=>_.length>=2),N=[];for(let _ of M)N.push(_);for(let _=0;_<M.length-1;_++)N.push(`${M[_]} ${M[_+1]}`);return N}var dE=60;async function iE(E,M,N,_){let O=_.limit??10,J=k0(M,E,_,O);if(!N)return J;let S=await l(N,E);if(!S)return J;let V=J.map((A)=>A.observation.id),C=f0(M,S,_.projectPath,_,O,_.hasVectorExtension??!1,V);if(C.length===0)return J;return m0(J,C,O)}function k0(E,M,N,_){try{return E.search({query:M,type:N.type,limit:_,projectPath:N.projectPath,importanceMin:N.importanceMin,importanceMax:N.importanceMax,createdAfter:N.createdAfter,createdBefore:N.createdBefore,concepts:N.concepts,files:N.files})}catch{return[]}}function f0(E,M,N,_,O,J,S){if(J)return y0(E,M,_,O,S);return P0(E,M,N,_,O)}function y0(E,M,N,_,O){try{let J;if(O.length>0){if(J=E.searchVecSubset(M,O,_*3),J.length===0)J=E.getVecEmbeddingMatches(M,_*3)}else J=E.getVecEmbeddingMatches(M,_*3);if(J.length===0)return[];let S=[];for(let{observationId:V,distance:C}of J){if(S.length>=_)break;let A=E.getById(V);if(!A)continue;if(!f(A,N))continue;S.push({observation:A,rank:C-1,snippet:A.title,rankingSource:"vector",explain:{strategy:"hybrid",matchedBy:["vector"],vectorDistance:C}})}return S}catch{return[]}}function P0(E,M,N,_,O){let J=E.getWithEmbeddings(N,O*10);if(J.length===0)return[];let S=J.map((C)=>({id:C.id,similarity:k(M,C.embedding)})).filter(({similarity:C})=>C>=0.3).sort((C,A)=>A.similarity-C.similarity),V=[];for(let{id:C,similarity:A}of S){if(V.length>=O)break;let $=E.getById(C);if(!$)continue;if(!f($,_))continue;V.push({observation:$,rank:-A,snippet:$.title,rankingSource:"vector",explain:{strategy:"hybrid",matchedBy:["vector"],vectorSimilarity:A}})}return V}function m0(E,M,N){let _=new Map;for(let O=0;O<E.length;O++){let J=E[O],S=1/(dE+O+1);_.set(J.observation.id,{score:S,result:{...J,rankingSource:"fts",explain:{strategy:"hybrid",matchedBy:["fts"],ftsRank:J.rank}}})}for(let O=0;O<M.length;O++){let J=M[O],S=1/(dE+O+1),V=_.get(J.observation.id);if(V)V.score+=S,V.result={...V.result,explain:{strategy:"hybrid",matchedBy:["fts","vector"],ftsRank:V.result.explain?.ftsRank??V.result.rank,vectorDistance:J.explain?.vectorDistance,vectorSimilarity:J.explain?.vectorSimilarity}};else _.set(J.observation.id,{score:S,result:{...J,explain:{strategy:"hybrid",matchedBy:["vector"],vectorDistance:J.explain?.vectorDistance,vectorSimilarity:J.explain?.vectorSimilarity}}})}return[..._.values()].sort((O,J)=>J.score-O.score).slice(0,N).map(({score:O,result:J})=>({...J,explain:{...J.explain??{strategy:"hybrid",matchedBy:[]},strategy:"hybrid",matchedBy:J.explain?.matchedBy??[],rrfScore:O,ftsRank:J.explain?.ftsRank,vectorDistance:J.explain?.vectorDistance,vectorSimilarity:J.explain?.vectorSimilarity}}))}class AE{observations;embeddingModel;hasVectorExtension;reranker;userObservationRepo;entityRepo;constructor(E,M,N,_=null,O=null,J=null){this.observations=E;this.embeddingModel=M;this.hasVectorExtension=N;this.reranker=_;this.userObservationRepo=O;this.entityRepo=J}async search(E,M){let N=M.strategy??"hybrid",_=M.limit??10,O;switch(N){case"filter-only":O=this.filterOnlySearch(E,M,_);break;case"semantic":O=await this.semanticSearch(E,M,_);break;case"hybrid":O=await this.hybridSearchStrategy(E,M,_);break}for(let J of O)J.source="project";if(this.entityRepo&&E.trim())O=await nE(E,O,this.entityRepo,this.observations,_);if(this.userObservationRepo){let J=this.searchUserMemory(E,M,_);O=this.mergeResults(O,J,_)}if(this.reranker&&O.length>1)return this.reranker.rerank(E,O,_);return O}filterOnlySearch(E,M,N){if(M.concept)return this.observations.searchByConcept(M.concept,N,M.projectPath).map((O)=>({observation:O,rank:0,snippet:O.title,rankingSource:"graph",explain:{strategy:"filter-only",matchedBy:["concept-filter"]}}));if(M.file)return this.observations.searchByFile(M.file,N,M.projectPath).map((O)=>({observation:O,rank:0,snippet:O.title,rankingSource:"graph",explain:{strategy:"filter-only",matchedBy:["file-filter"]}}));return this.observations.search({query:E,type:M.type,limit:N,projectPath:M.projectPath,importanceMin:M.importanceMin,importanceMax:M.importanceMax,createdAfter:M.createdAfter,createdBefore:M.createdBefore,concepts:M.concepts,files:M.files})}async semanticSearch(E,M,N){if(!this.embeddingModel)return this.filterOnlySearch(E,M,N);let _=await l(this.embeddingModel,E);if(!_)return this.filterOnlySearch(E,M,N);if(this.hasVectorExtension)return this.nativeVectorSearch(_,M,N);return this.jsFallbackVectorSearch(_,M,N)}async hybridSearchStrategy(E,M,N){return iE(E,this.observations,this.embeddingModel,{type:M.type,limit:N,projectPath:M.projectPath,hasVectorExtension:this.hasVectorExtension,importanceMin:M.importanceMin,importanceMax:M.importanceMax,createdAfter:M.createdAfter,createdBefore:M.createdBefore,concepts:M.concepts,files:M.files})}nativeVectorSearch(E,M,N){try{let _=this.observations.getVecEmbeddingMatches(E,N*3);if(_.length===0)return[];let O=[];for(let{observationId:J,distance:S}of _){if(O.length>=N)break;let V=this.observations.getById(J);if(!V)continue;if(!f(V,M))continue;O.push({observation:V,rank:S-1,snippet:V.title,rankingSource:"vector",explain:{strategy:"semantic",matchedBy:["vector"],vectorDistance:S}})}return O}catch{return[]}}jsFallbackVectorSearch(E,M,N){let _=this.observations.getWithEmbeddings(M.projectPath,N*10);if(_.length===0)return[];let O=_.map((S)=>({id:S.id,similarity:k(E,S.embedding)})).filter(({similarity:S})=>S>=0.3).sort((S,V)=>V.similarity-S.similarity),J=[];for(let{id:S,similarity:V}of O){if(J.length>=N)break;let C=this.observations.getById(S);if(!C)continue;if(!f(C,M))continue;J.push({observation:C,rank:-V,snippet:C.title,rankingSource:"vector",explain:{strategy:"semantic",matchedBy:["vector"],vectorSimilarity:V}})}return J}searchUserMemory(E,M,N){if(!this.userObservationRepo)return[];try{return this.userObservationRepo.search({query:E,limit:N}).map(({observation:O,rank:J})=>({observation:T0(O),rank:J,snippet:O.title,source:"user",rankingSource:"user-memory",explain:{strategy:"filter-only",matchedBy:["user-memory"]}}))}catch{return[]}}mergeResults(E,M,N){let _=new Set(E.map((S)=>S.observation.id)),O=new Set(E.map((S)=>`${S.observation.title}::${S.observation.narrative}`)),J=M.filter((S)=>{if(_.has(S.observation.id))return!1;let V=`${S.observation.title}::${S.observation.narrative}`;if(O.has(V))return!1;return O.add(V),!0});return[...E,...J].slice(0,N)}}function T0(E){return{id:E.id,sessionId:"",type:E.type,title:E.title,subtitle:E.subtitle,facts:E.facts,narrative:E.narrative,concepts:E.concepts,filesRead:E.filesRead,filesModified:E.filesModified,rawToolOutput:"",toolName:E.toolName,createdAt:E.createdAt,tokenCount:E.tokenCount,discoveryTokens:0,importance:E.importance}}import{generateText as v0}from"ai";function rE(E,M){let N=M.map((_,O)=>` <candidate index="${O}"><title>${_.title}</title><narrative>${_.narrative}</narrative></candidate>`).join(`
499
499
  `);return`<rerank_request>
500
500
  <query>${E}</query>
501
501
  <candidates>
@@ -510,4 +510,4 @@ Respond with EXACTLY this XML format:
510
510
  <index>0</index>
511
511
  </reranked>
512
512
  </instructions>
513
- </rerank_request>`}var p0={"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},oE=0;async function aE(E,M){if(!M)return;let N=p0[E]||5,_=Math.ceil(60000/N)+100,J=Date.now()-oE;if(J<_){let S=_-J;await new Promise((V)=>setTimeout(V,S))}oE=Date.now()}class eE{languageModel;maxCandidates;provider;modelName;rateLimitingEnabled;_generate=v0;constructor(E,M){this.languageModel=E,this.maxCandidates=M.rerankingMaxCandidates,this.provider=M.provider??"",this.modelName=M.model??"",this.rateLimitingEnabled=M.rateLimitingEnabled??!0}async rerank(E,M,N){if(M.length<=1)return M;let _=M.slice(0,this.maxCandidates),O=M.slice(this.maxCandidates),J=rE(E,_.map((V)=>({title:V.observation.title,narrative:V.observation.narrative}))),S=2;for(let V=0;V<=S;V++)try{if(this.provider==="google")await aE(this.modelName,this.rateLimitingEnabled);let{text:C}=await this._generate({model:this.languageModel,maxOutputTokens:512,prompt:J}),A=QE(C);if(!A)return M.slice(0,N);let $=this.applyReranking(_,A,N);for(let H of O){if($.length>=N)break;$.push(H)}return $}catch(C){if(g0(C)&&V<S){await I0(2**V*1000);continue}return M.slice(0,N)}return M.slice(0,N)}applyReranking(E,M,N){let _=[],O=new Set;for(let J of M)if(J>=0&&J<E.length&&!O.has(J)){if(O.add(J),_.push(E[J]),_.length>=N)break}if(_.length<N){for(let J=0;J<E.length&&_.length<N;J++)if(!O.has(J))_.push(E[J])}return _}}class tE{async rerank(E,M,N){if(M.length<=1)return M.slice(0,N);let _=$E(E),O=M.map((J)=>({result:J,score:this.scoreCandidate(J,_)}));return O.sort((J,S)=>S.score-J.score),O.slice(0,N).map((J)=>J.result)}scoreCandidate(E,M){let N=E.observation,_=$E(N.title),O=$E(N.narrative),J=new Set(N.concepts.map((P)=>P.toLowerCase())),S=0,V=0,C=0;for(let P of M){if(_.has(P))S++;if(O.has(P))V++;if(J.has(P))C++}let A=M.size||1,$=S/A*0.4,H=V/A*0.3,Y=C/A*0.15,D=(Date.now()-new Date(N.createdAt).getTime())/86400000,b=D<1?0.1:D<7?0.05:0,ZM=N.importance/5*0.05;return $+H+Y+b+ZM}}function sE(E,M){if(!E.rerankingEnabled)return null;if(M)return new eE(M,E);return new tE}function $E(E){return new Set(E.toLowerCase().split(/[\s\-_./\\,;:!?()[\]{}'"]+/).filter((M)=>M.length>1))}function g0(E){if(typeof E!=="object"||E===null)return!1;let M=E,N=M.status;if(N===429||N===500||N===503)return!0;let _=M.error;if(typeof _==="object"&&_!==null&&_.type==="overloaded_error")return!0;return!1}function I0(E){return new Promise((M)=>setTimeout(M,E))}function EM(E){return E}function MM(E){return E}function NM(E){return E}function _M(E){if(!E)return null;return E}import{spawnSync as OM}from"child_process";import{dirname as h0,resolve as JM}from"path";function q0(E){try{let M=OM("git",["rev-parse","--git-common-dir"],{cwd:E,encoding:"utf-8",timeout:5000});if(M.status!==0||!M.stdout)return null;let N=M.stdout.trim();if(N===".git")return null;let _=OM("git",["rev-parse","--git-dir"],{cwd:E,encoding:"utf-8",timeout:5000});if(_.status!==0||!_.stdout)return null;let O=_.stdout.trim(),J=JM(E,N),S=JM(E,O);if(J===S)return null;let V=h0(J);if(V===J||V==="/")return null;return V}catch{return null}}function SM(E){return q0(E)??E}var __dirname="/Users/clopca/dev/github/open-mem/src",{values:VM}=w0({options:{project:{type:"string",short:"p"}},strict:!1}),l0=typeof VM.project==="string"?VM.project:process.cwd(),CM=SM(l0),R=m(CM);u.enableExtensionSupport();var L=w(R.dbPath);bE(L,{hasVectorExtension:L.hasVectorExtension,embeddingDimension:R.embeddingDimension});var c0=new JE(L),AM=new OE(L),b0=new SE(L),n0=new EE(L),d0=new _E(L),f=null,XE=null;if(R.userMemoryEnabled)try{f=new VE(R.userMemoryDbPath),XE=new CE(f.database)}catch(E){console.error(`[open-mem-mcp] Failed to initialize user-level memory: ${E}`)}var $M=R.provider!=="bedrock",i0=R.compressionEnabled&&(!$M||R.apiKey)?KE({provider:R.provider,model:R.model,apiKey:R.apiKey}):null,r0=sE(R,R.rerankingEnabled&&(!$M||R.apiKey)?HE({provider:R.provider,model:R.model,apiKey:R.apiKey}):null),o0=new NE(L),a0=new AE(AM,i0,L.hasVectorExtension,r0,XE,o0),e0=JSON.parse(x0(u0(__dirname,"..","package.json"),"utf-8")),t0=new n({memoryEngine:new s({observations:EM(AM),sessions:MM(c0),summaries:NM(b0),searchOrchestrator:a0,projectPath:CM,config:R,userObservationRepo:_M(XE),configAuditStore:n0,maintenanceHistoryStore:d0}),version:e0.version,compatibilityMode:R.mcpCompatibilityMode,protocolVersion:R.mcpProtocolVersion,supportedProtocolVersions:R.mcpSupportedProtocolVersions}),c=!1,XM=()=>{if(!c){if(c=!0,f)f.close();L.close()}process.exit(0)};process.on("SIGINT",XM);process.on("SIGTERM",XM);process.on("beforeExit",()=>{if(!c){if(c=!0,f)f.close();L.close()}});t0.start();
513
+ </rerank_request>`}var p0={"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},aE=0;async function oE(E,M){if(!M)return;let N=p0[E]||5,_=Math.ceil(60000/N)+100,J=Date.now()-aE;if(J<_){let S=_-J;await new Promise((V)=>setTimeout(V,S))}aE=Date.now()}class eE{languageModel;maxCandidates;provider;modelName;rateLimitingEnabled;_generate=v0;constructor(E,M){this.languageModel=E,this.maxCandidates=M.rerankingMaxCandidates,this.provider=M.provider??"",this.modelName=M.model??"",this.rateLimitingEnabled=M.rateLimitingEnabled??!0}async rerank(E,M,N){if(M.length<=1)return M;let _=M.slice(0,this.maxCandidates),O=M.slice(this.maxCandidates),J=rE(E,_.map((V)=>({title:V.observation.title,narrative:V.observation.narrative}))),S=2;for(let V=0;V<=S;V++)try{if(this.provider==="google")await oE(this.modelName,this.rateLimitingEnabled);let{text:C}=await this._generate({model:this.languageModel,maxOutputTokens:512,prompt:J}),A=QE(C);if(!A)return M.slice(0,N);let $=this.applyReranking(_,A,N);for(let H of O){if($.length>=N)break;$.push(H)}return $}catch(C){if(g0(C)&&V<S){await I0(2**V*1000);continue}return M.slice(0,N)}return M.slice(0,N)}applyReranking(E,M,N){let _=[],O=new Set;for(let J of M)if(J>=0&&J<E.length&&!O.has(J)){if(O.add(J),_.push(E[J]),_.length>=N)break}if(_.length<N){for(let J=0;J<E.length&&_.length<N;J++)if(!O.has(J))_.push(E[J])}return _}}class tE{async rerank(E,M,N){if(M.length<=1)return M.slice(0,N);let _=$E(E),O=M.map((J)=>({result:J,score:this.scoreCandidate(J,_)}));return O.sort((J,S)=>S.score-J.score),O.slice(0,N).map((J)=>J.result)}scoreCandidate(E,M){let N=E.observation,_=$E(N.title),O=$E(N.narrative),J=new Set(N.concepts.map((P)=>P.toLowerCase())),S=0,V=0,C=0;for(let P of M){if(_.has(P))S++;if(O.has(P))V++;if(J.has(P))C++}let A=M.size||1,$=S/A*0.4,H=V/A*0.3,Y=C/A*0.15,D=(Date.now()-new Date(N.createdAt).getTime())/86400000,b=D<1?0.1:D<7?0.05:0,ZM=N.importance/5*0.05;return $+H+Y+b+ZM}}function sE(E,M){if(!E.rerankingEnabled)return null;if(M)return new eE(M,E);return new tE}function $E(E){return new Set(E.toLowerCase().split(/[\s\-_./\\,;:!?()[\]{}'"]+/).filter((M)=>M.length>1))}function g0(E){if(typeof E!=="object"||E===null)return!1;let M=E,N=M.status;if(N===429||N===500||N===503)return!0;let _=M.error;if(typeof _==="object"&&_!==null&&_.type==="overloaded_error")return!0;return!1}function I0(E){return new Promise((M)=>setTimeout(M,E))}function EM(E){return E}function MM(E){return E}function NM(E){return E}function _M(E){if(!E)return null;return E}import{spawnSync as OM}from"child_process";import{dirname as h0,resolve as JM}from"path";function q0(E){try{let M=OM("git",["rev-parse","--git-common-dir"],{cwd:E,encoding:"utf-8",timeout:5000});if(M.status!==0||!M.stdout)return null;let N=M.stdout.trim();if(N===".git")return null;let _=OM("git",["rev-parse","--git-dir"],{cwd:E,encoding:"utf-8",timeout:5000});if(_.status!==0||!_.stdout)return null;let O=_.stdout.trim(),J=JM(E,N),S=JM(E,O);if(J===S)return null;let V=h0(J);if(V===J||V==="/")return null;return V}catch{return null}}function SM(E){return q0(E)??E}var __dirname="/Users/clopca/dev/github/open-mem/src",{values:VM}=w0({options:{project:{type:"string",short:"p"}},strict:!1}),l0=typeof VM.project==="string"?VM.project:process.cwd(),CM=SM(l0),R=m(CM);u.enableExtensionSupport();var L=w(R.dbPath);bE(L,{hasVectorExtension:L.hasVectorExtension,embeddingDimension:R.embeddingDimension});var c0=new JE(L),AM=new OE(L),b0=new SE(L),n0=new EE(L),d0=new _E(L),y=null,XE=null;if(R.userMemoryEnabled)try{y=new VE(R.userMemoryDbPath),XE=new CE(y.database)}catch(E){console.error(`[open-mem-mcp] Failed to initialize user-level memory: ${E}`)}var $M=R.provider!=="bedrock",i0=R.compressionEnabled&&(!$M||R.apiKey)?KE({provider:R.provider,model:R.model,apiKey:R.apiKey}):null,r0=sE(R,R.rerankingEnabled&&(!$M||R.apiKey)?HE({provider:R.provider,model:R.model,apiKey:R.apiKey}):null),a0=new NE(L),o0=new AE(AM,i0,L.hasVectorExtension,r0,XE,a0),e0=JSON.parse(x0(u0(__dirname,"..","package.json"),"utf-8")),t0=new n({memoryEngine:new s({observations:EM(AM),sessions:MM(c0),summaries:NM(b0),searchOrchestrator:o0,projectPath:CM,config:R,userObservationRepo:_M(XE),configAuditStore:n0,maintenanceHistoryStore:d0}),version:e0.version,compatibilityMode:R.mcpCompatibilityMode,protocolVersion:R.mcpProtocolVersion,supportedProtocolVersions:R.mcpSupportedProtocolVersions}),c=!1,XM=()=>{if(!c){if(c=!0,y)y.close();L.close()}process.exit(0)};process.on("SIGINT",XM);process.on("SIGTERM",XM);process.on("beforeExit",()=>{if(!c){if(c=!0,y)y.close();L.close()}});t0.start();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-mem",
3
- "version": "0.7.2",
3
+ "version": "0.8.0",
4
4
  "description": "Persistent memory plugin for OpenCode — captures, compresses, and recalls context across coding sessions",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",